mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-02-26 12:39:55 +00:00
Merge pull request #1012 from paul-elliott-arm/mbedtls-3.4.0_mergeback
Mbedtls 3.4.0 merge back
This commit is contained in:
commit
da018175de
@ -79,6 +79,7 @@ jobs:
|
||||
# Logs appear out of sequence on Windows. Give time to catch up.
|
||||
- sleep 5
|
||||
- scripts/windows_msbuild.bat v141 # Visual Studio 2017
|
||||
- visualc/VS2013/x64/Release/selftest.exe
|
||||
|
||||
- name: full configuration on arm64
|
||||
os: linux
|
||||
|
@ -101,6 +101,6 @@ The following branches are currently maintained:
|
||||
- [`development`](https://github.com/Mbed-TLS/mbedtls/)
|
||||
- [`mbedtls-2.28`](https://github.com/Mbed-TLS/mbedtls/tree/mbedtls-2.28)
|
||||
maintained until at least the end of 2024, see
|
||||
<https://github.com/Mbed-TLS/mbedtls/releases/tag/v2.28.2>.
|
||||
<https://github.com/Mbed-TLS/mbedtls/releases/tag/v2.28.3>.
|
||||
|
||||
Users are urged to always use the latest version of a maintained branch.
|
||||
|
@ -354,7 +354,7 @@ if(NOT DISABLE_PACKAGE_CONFIG_AND_INSTALL)
|
||||
write_basic_package_version_file(
|
||||
"cmake/MbedTLSConfigVersion.cmake"
|
||||
COMPATIBILITY SameMajorVersion
|
||||
VERSION 3.3.0)
|
||||
VERSION 3.4.0)
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfig.cmake"
|
||||
|
211
ChangeLog
211
ChangeLog
@ -1,5 +1,216 @@
|
||||
Mbed TLS ChangeLog (Sorted per branch, date)
|
||||
|
||||
= Mbed TLS 3.4.0 branch released 2023-03-28
|
||||
|
||||
Default behavior changes
|
||||
* The default priority order of TLS 1.3 cipher suites has been modified to
|
||||
follow the same rules as the TLS 1.2 cipher suites (see
|
||||
ssl_ciphersuites.c). The preferred cipher suite is now
|
||||
TLS_CHACHA20_POLY1305_SHA256.
|
||||
|
||||
New deprecations
|
||||
* mbedtls_x509write_crt_set_serial() is now being deprecated in favor of
|
||||
mbedtls_x509write_crt_set_serial_raw(). The goal here is to remove any
|
||||
direct dependency of X509 on BIGNUM_C.
|
||||
* PSA to mbedtls error translation is now unified in psa_util.h,
|
||||
deprecating mbedtls_md_error_from_psa. Each file that performs error
|
||||
translation should define its own version of PSA_TO_MBEDTLS_ERR,
|
||||
optionally providing file-specific error pairs. Please see psa_util.h for
|
||||
more details.
|
||||
|
||||
Features
|
||||
* Added partial support for parsing the PKCS #7 Cryptographic Message
|
||||
Syntax, as defined in RFC 2315. Currently, support is limited to the
|
||||
following:
|
||||
- Only the signed-data content type, version 1 is supported.
|
||||
- Only DER encoding is supported.
|
||||
- Only a single digest algorithm per message is supported.
|
||||
- Certificates must be in X.509 format. A message must have either 0
|
||||
or 1 certificates.
|
||||
- There is no support for certificate revocation lists.
|
||||
- The authenticated and unauthenticated attribute fields of SignerInfo
|
||||
must be empty.
|
||||
Many thanks to Daniel Axtens, Nayna Jain, and Nick Child from IBM for
|
||||
contributing this feature, and to Demi-Marie Obenour for contributing
|
||||
various improvements, tests and bug fixes.
|
||||
* General performance improvements by accessing multiple bytes at a time.
|
||||
Fixes #1666.
|
||||
* Improvements to use of unaligned and byte-swapped memory, reducing code
|
||||
size and improving performance (depending on compiler and target
|
||||
architecture).
|
||||
* Add support for reading points in compressed format
|
||||
(MBEDTLS_ECP_PF_COMPRESSED) with mbedtls_ecp_point_read_binary()
|
||||
(and callers) for Short Weierstrass curves with prime p where p = 3 mod 4
|
||||
(all mbedtls MBEDTLS_ECP_DP_SECP* and MBEDTLS_ECP_DP_BP* curves
|
||||
except MBEDTLS_ECP_DP_SECP224R1 and MBEDTLS_ECP_DP_SECP224K1)
|
||||
* SHA224_C/SHA384_C are now independent from SHA384_C/SHA512_C respectively.
|
||||
This helps in saving code size when some of the above hashes are not
|
||||
required.
|
||||
* Add parsing of V3 extensions (key usage, Netscape cert-type,
|
||||
Subject Alternative Names) in x509 Certificate Sign Requests.
|
||||
* Use HOSTCC (if it is set) when compiling C code during generation of the
|
||||
configuration-independent files. This allows them to be generated when
|
||||
CC is set for cross compilation.
|
||||
* Add parsing of uniformResourceIdentifier subtype for subjectAltName
|
||||
extension in x509 certificates.
|
||||
* Add an interruptible version of sign and verify hash to the PSA interface,
|
||||
backed by internal library support for ECDSA signing and verification.
|
||||
* Add parsing of rfc822Name subtype for subjectAltName
|
||||
extension in x509 certificates.
|
||||
* The configuration macros MBEDTLS_PSA_CRYPTO_PLATFORM_FILE and
|
||||
MBEDTLS_PSA_CRYPTO_STRUCT_FILE specify alternative locations for
|
||||
the headers "psa/crypto_platform.h" and "psa/crypto_struct.h".
|
||||
* When a PSA driver for ECDSA is present, it is now possible to disable
|
||||
MBEDTLS_ECDSA_C in the build in order to save code size. For PK, X.509
|
||||
and TLS to fully work, this requires MBEDTLS_USE_PSA_CRYPTO to be enabled.
|
||||
Restartable/interruptible ECDSA operations in PK, X.509 and TLS are not
|
||||
supported in those builds yet, as driver support for interruptible ECDSA
|
||||
operations is not present yet.
|
||||
* Add a driver dispatch layer for EC J-PAKE, enabling alternative
|
||||
implementations of EC J-PAKE through the driver entry points.
|
||||
* Add new API mbedtls_ssl_cache_remove for cache entry removal by
|
||||
its session id.
|
||||
* Add support to include the SubjectAltName extension to a CSR.
|
||||
* Add support for AES with the Armv8-A Cryptographic Extension on
|
||||
64-bit Arm. A new configuration option, MBEDTLS_AESCE_C, can
|
||||
be used to enable this feature. Run-time detection is supported
|
||||
under Linux only.
|
||||
* When a PSA driver for EC J-PAKE is present, it is now possible to disable
|
||||
MBEDTLS_ECJPAKE_C in the build in order to save code size. For the
|
||||
corresponding TLS 1.2 key exchange to work, MBEDTLS_USE_PSA_CRYPTO needs
|
||||
to be enabled.
|
||||
* Add functions mbedtls_rsa_get_padding_mode() and mbedtls_rsa_get_md_alg()
|
||||
to read non-public fields for padding mode and hash id from
|
||||
an mbedtls_rsa_context, as requested in #6917.
|
||||
* AES-NI is now supported with Visual Studio.
|
||||
* AES-NI is now supported in 32-bit builds, or when MBEDTLS_HAVE_ASM
|
||||
is disabled, when compiling with GCC or Clang or a compatible compiler
|
||||
for a target CPU that supports the requisite instructions (for example
|
||||
gcc -m32 -msse2 -maes -mpclmul). (Generic x86 builds with GCC-like
|
||||
compilers still require MBEDTLS_HAVE_ASM and a 64-bit target.)
|
||||
* It is now possible to use a PSA-held (opaque) password with the TLS 1.2
|
||||
ECJPAKE key exchange, using the new API function
|
||||
mbedtls_ssl_set_hs_ecjpake_password_opaque().
|
||||
|
||||
Security
|
||||
* Use platform-provided secure zeroization function where possible, such as
|
||||
explicit_bzero().
|
||||
* Zeroize SSL cache entries when they are freed.
|
||||
* Fix a potential heap buffer overread in TLS 1.3 client-side when
|
||||
MBEDTLS_DEBUG_C is enabled. This may result in an application crash.
|
||||
* Add support for AES with the Armv8-A Cryptographic Extension on 64-bit
|
||||
Arm, so that these systems are no longer vulnerable to timing side-channel
|
||||
attacks. This is configured by MBEDTLS_AESCE_C, which is on by default.
|
||||
Reported by Demi Marie Obenour.
|
||||
* MBEDTLS_AESNI_C, which is enabled by default, was silently ignored on
|
||||
builds that couldn't compile the GCC-style assembly implementation
|
||||
(most notably builds with Visual Studio), leaving them vulnerable to
|
||||
timing side-channel attacks. There is now an intrinsics-based AES-NI
|
||||
implementation as a fallback for when the assembly one cannot be used.
|
||||
|
||||
Bugfix
|
||||
* Fix possible integer overflow in mbedtls_timing_hardclock(), which
|
||||
could cause a crash in programs/test/benchmark.
|
||||
* Fix IAR compiler warnings. Fixes #6924.
|
||||
* Fix a bug in the build where directory names containing spaces were
|
||||
causing generate_errors.pl to error out resulting in a build failure.
|
||||
Fixes issue #6879.
|
||||
* In TLS 1.3, when using a ticket for session resumption, tweak its age
|
||||
calculation on the client side. It prevents a server with more accurate
|
||||
ticket timestamps (typically timestamps in milliseconds) compared to the
|
||||
Mbed TLS ticket timestamps (in seconds) to compute a ticket age smaller
|
||||
than the age computed and transmitted by the client and thus potentially
|
||||
reject the ticket. Fix #6623.
|
||||
* Fix compile error where MBEDTLS_RSA_C and MBEDTLS_X509_CRT_WRITE_C are
|
||||
defined, but MBEDTLS_PK_RSA_ALT_SUPPORT is not defined. Fixes #3174.
|
||||
* List PSA_WANT_ALG_CCM_STAR_NO_TAG in psa/crypto_config.h so that it can
|
||||
be toggled with config.py.
|
||||
* The key derivation algorithm PSA_ALG_TLS12_ECJPAKE_TO_PMS cannot be
|
||||
used on a shared secret from a key agreement since its input must be
|
||||
an ECC public key. Reject this properly.
|
||||
* mbedtls_x509write_crt_set_serial() now explicitly rejects serial numbers
|
||||
whose binary representation is longer than 20 bytes. This was already
|
||||
forbidden by the standard (RFC5280 - section 4.1.2.2) and now it's being
|
||||
enforced also at code level.
|
||||
* Fix potential undefined behavior in mbedtls_mpi_sub_abs(). Reported by
|
||||
Pascal Cuoq using TrustInSoft Analyzer in #6701; observed independently by
|
||||
Aaron Ucko under Valgrind.
|
||||
* Fix behavior of certain sample programs which could, when run with no
|
||||
arguments, access uninitialized memory in some cases. Fixes #6700 (which
|
||||
was found by TrustInSoft Analyzer during REDOCS'22) and #1120.
|
||||
* Fix parsing of X.509 SubjectAlternativeName extension. Previously,
|
||||
malformed alternative name components were not caught during initial
|
||||
certificate parsing, but only on subsequent calls to
|
||||
mbedtls_x509_parse_subject_alt_name(). Fixes #2838.
|
||||
* Make the fields of mbedtls_pk_rsassa_pss_options public. This makes it
|
||||
possible to verify RSA PSS signatures with the pk module, which was
|
||||
inadvertently broken since Mbed TLS 3.0.
|
||||
* Fix bug in conversion from OID to string in
|
||||
mbedtls_oid_get_numeric_string(). OIDs such as 2.40.0.25 are now printed
|
||||
correctly.
|
||||
* Reject OIDs with overlong-encoded subidentifiers when converting
|
||||
them to a string.
|
||||
* Reject OIDs with subidentifier values exceeding UINT_MAX. Such
|
||||
subidentifiers can be valid, but Mbed TLS cannot currently handle them.
|
||||
* Reject OIDs that have unterminated subidentifiers, or (equivalently)
|
||||
have the most-significant bit set in their last byte.
|
||||
* Silence warnings from clang -Wdocumentation about empty \retval
|
||||
descriptions, which started appearing with Clang 15. Fixes #6960.
|
||||
* Fix the handling of renegotiation attempts in TLS 1.3. They are now
|
||||
systematically rejected.
|
||||
* Fix an unused-variable warning in TLS 1.3-only builds if
|
||||
MBEDTLS_SSL_RENEGOTIATION was enabled. Fixes #6200.
|
||||
* Fix undefined behavior in mbedtls_ssl_read() and mbedtls_ssl_write() if
|
||||
len argument is 0 and buffer is NULL.
|
||||
* Allow setting user and peer identifiers for EC J-PAKE operation
|
||||
instead of role in PAKE PSA Crypto API as described in the specification.
|
||||
This is a partial fix that allows only "client" and "server" identifiers.
|
||||
* Fix a compilation error when PSA Crypto is built with support for
|
||||
TLS12_PRF but not TLS12_PSK_TO_MS. Reported by joerchan in #7125.
|
||||
* In the TLS 1.3 server, select the preferred client cipher suite, not the
|
||||
least preferred. The selection error was introduced in Mbed TLS 3.3.0.
|
||||
* Fix TLS 1.3 session resumption when the established pre-shared key is
|
||||
384 bits long. That is the length of pre-shared keys created under a
|
||||
session where the cipher suite is TLS_AES_256_GCM_SHA384.
|
||||
* Fix an issue when compiling with MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT
|
||||
enabled, which required specifying compiler flags enabling SHA3 Crypto
|
||||
Extensions, where some compilers would emit EOR3 instructions in other
|
||||
modules, which would then fail if run on a CPU without the SHA3
|
||||
extensions. Fixes #5758.
|
||||
|
||||
Changes
|
||||
* Install the .cmake files into CMAKE_INSTALL_LIBDIR/cmake/MbedTLS,
|
||||
typically /usr/lib/cmake/MbedTLS.
|
||||
* Mixed-endian systems are explicitly not supported any more.
|
||||
* When MBEDTLS_USE_PSA_CRYPTO and MBEDTLS_ECDSA_DETERMINISTIC are both
|
||||
defined, mbedtls_pk_sign() now use deterministic ECDSA for ECDSA
|
||||
signatures. This aligns the behaviour with MBEDTLS_USE_PSA_CRYPTO to
|
||||
the behaviour without it, where deterministic ECDSA was already used.
|
||||
* Visual Studio: Rename the directory containing Visual Studio files from
|
||||
visualc/VS2010 to visualc/VS2013 as we do not support building with versions
|
||||
older than 2013. Update the solution file to specify VS2013 as a minimum.
|
||||
* programs/x509/cert_write:
|
||||
- now it accepts the serial number in 2 different formats: decimal and
|
||||
hex. They cannot be used simultaneously
|
||||
- "serial" is used for the decimal format and it's limted in size to
|
||||
unsigned long long int
|
||||
- "serial_hex" is used for the hex format; max length here is
|
||||
MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN*2
|
||||
* The C code follows a new coding style. This is transparent for users but
|
||||
affects contributors and maintainers of local patches. For more
|
||||
information, see
|
||||
https://mbed-tls.readthedocs.io/en/latest/kb/how-to/rewrite-branch-for-coding-style/
|
||||
* Changed the default MBEDTLS_ECP_WINDOW_SIZE from 6 to 2.
|
||||
As tested in issue 6790, the correlation between this define and
|
||||
RSA decryption performance has changed lately due to security fixes.
|
||||
To fix the performance degradation when using default values the
|
||||
window was reduced from 6 to 2, a value that gives the best or close
|
||||
to best results when tested on Cortex-M4 and Intel i7.
|
||||
* When enabling MBEDTLS_SHA256_USE_A64_CRYPTO_* or
|
||||
MBEDTLS_SHA512_USE_A64_CRYPTO_*, it is no longer necessary to specify
|
||||
compiler target flags on the command line; the library now sets target
|
||||
options within the appropriate modules.
|
||||
|
||||
= Mbed TLS 3.3.0 branch released 2022-12-14
|
||||
|
||||
Default behavior changes
|
||||
|
@ -1,5 +0,0 @@
|
||||
Features
|
||||
* Add new API mbedtls_ssl_cache_remove for cache entry removal by
|
||||
its session id.
|
||||
Security
|
||||
* Zeroize SSL cache entries when they are freed.
|
@ -1,3 +0,0 @@
|
||||
Features
|
||||
* Add parsing of uniformResourceIdentifier subtype for subjectAltName
|
||||
extension in x509 certificates.
|
@ -1,5 +0,0 @@
|
||||
Features
|
||||
* Add an interruptible version of sign and verify hash to the PSA interface,
|
||||
backed by internal library support for ECDSA signing and verification.
|
||||
|
||||
|
@ -1,8 +0,0 @@
|
||||
Features
|
||||
* General performance improvements by accessing multiple bytes at a time.
|
||||
Fixes #1666.
|
||||
* Improvements to use of unaligned and byte-swapped memory, reducing code
|
||||
size and improving performance (depending on compiler and target
|
||||
architecture).
|
||||
Changes
|
||||
* Mixed-endian systems are explicitly not supported any more.
|
@ -1,5 +0,0 @@
|
||||
Features
|
||||
* Add support for the Armv8-A Cryptographic Extension in AES on
|
||||
64-bit Arm. A new configuration option, MBEDTLS_AESCE_C, can
|
||||
be used to enable this feature. Run-time detection is supported
|
||||
under Linux only.
|
@ -1,4 +0,0 @@
|
||||
Features
|
||||
* Use HOSTCC (if it is set) when compiling C code during generation of the
|
||||
configuration-independent files. This allows them to be generated when
|
||||
CC is set for cross compilation.
|
@ -1,3 +0,0 @@
|
||||
Bugfix
|
||||
* Fix a compilation error when PSA Crypto is built with support for
|
||||
TLS12_PRF but not TLS12_PSK_TO_MS. Reported by joerchan in #7125.
|
@ -1,3 +0,0 @@
|
||||
Changes
|
||||
* Install the .cmake files into CMAKE_INSTALL_LIBDIR/cmake/MbedTLS,
|
||||
typically /usr/lib/cmake/MbedTLS.
|
@ -1,5 +0,0 @@
|
||||
Changes
|
||||
* The C code follows a new coding style. This is transparent for users but
|
||||
affects contributors and maintainers of local patches. For more
|
||||
information, see
|
||||
https://mbed-tls.readthedocs.io/en/latest/kb/how-to/rewrite-branch-for-coding-style/
|
@ -1,4 +0,0 @@
|
||||
Bugfix
|
||||
* Fix potential undefined behavior in mbedtls_mpi_sub_abs(). Reported by
|
||||
Pascal Cuoq using TrustInSoft Analyzer in #6701; observed independently by
|
||||
Aaron Ucko under Valgrind.
|
@ -1,3 +0,0 @@
|
||||
Bugfix
|
||||
* List PSA_WANT_ALG_CCM_STAR_NO_TAG in psa/crypto_config.h so that it can
|
||||
be toggled with config.py.
|
@ -1,3 +0,0 @@
|
||||
Features
|
||||
* Add parsing of V3 extensions (key usage, Netscape cert-type,
|
||||
Subject Alternative Names) in x509 Certificate Sign Requests.
|
@ -1,7 +0,0 @@
|
||||
Features
|
||||
* When a PSA driver for ECDSA is present, it is now possible to disable
|
||||
MBEDTLS_ECDSA_C in the build in order to save code size. For PK, X.509
|
||||
and TLS to fully work, this requires MBEDTLS_USE_PSA_CRYPTO to be enabled.
|
||||
Restartable/interruptible ECDSA operations in PK, X.509 and TLS are not
|
||||
supported in those builds yet, as driver support for interruptible ECDSA
|
||||
operations is not present yet.
|
@ -1,5 +0,0 @@
|
||||
Features
|
||||
* When a PSA driver for EC J-PAKE is present, it is now possible to disable
|
||||
MBEDTLS_ECJPAKE_C in the build in order to save code size. For the
|
||||
corresponding TLS 1.2 key exchange to work, MBEDTLS_USE_PSA_CRYPTO needs
|
||||
to be enabled.
|
@ -1,3 +0,0 @@
|
||||
Features
|
||||
* Add a driver dispatch layer for EC J-PAKE, enabling alternative
|
||||
implementations of EC J-PAKE through the driver entry points.
|
@ -1,3 +0,0 @@
|
||||
Bugfix
|
||||
* Silence warnings from clang -Wdocumentation about empty \retval
|
||||
descriptions, which started appearing with Clang 15. Fixes #6960.
|
@ -1,4 +0,0 @@
|
||||
Bugfix
|
||||
* Fix behavior of certain sample programs which could, when run with no
|
||||
arguments, access uninitialized memory in some cases. Fixes #6700 (which
|
||||
was found by TrustInSoft Analyzer during REDOCS'22) and #1120.
|
@ -1,3 +0,0 @@
|
||||
Bugfix
|
||||
* Fix possible integer overflow in mbedtls_timing_hardclock(), which
|
||||
could cause a crash in programs/test/benchmark.
|
@ -1,2 +0,0 @@
|
||||
Bugfix
|
||||
* Fix IAR compiler warnings. Fixes #6924.
|
@ -1,4 +0,0 @@
|
||||
Bugfix
|
||||
* Allow setting user and peer identifiers for EC J-PAKE operation
|
||||
instead of role in PAKE PSA Crypto API as described in the specification.
|
||||
This is a partial fix that allows only "client" and "server" identifiers.
|
@ -1,10 +0,0 @@
|
||||
Bugfix
|
||||
* Fix bug in conversion from OID to string in
|
||||
mbedtls_oid_get_numeric_string(). OIDs such as 2.40.0.25 are now printed
|
||||
correctly.
|
||||
* Reject OIDs with overlong-encoded subidentifiers when converting
|
||||
them to a string.
|
||||
* Reject OIDs with subidentifier values exceeding UINT_MAX. Such
|
||||
subidentifiers can be valid, but Mbed TLS cannot currently handle them.
|
||||
* Reject OIDs that have unterminated subidentifiers, or (equivalently)
|
||||
have the most-significant bit set in their last byte.
|
@ -1,3 +0,0 @@
|
||||
Bugfix
|
||||
* Fix compile error where MBEDTLS_RSA_C and MBEDTLS_X509_CRT_WRITE_C are
|
||||
defined, but MBEDTLS_PK_RSA_ALT_SUPPORT is not defined. Fixes #3174.
|
@ -1,4 +0,0 @@
|
||||
Bugfix
|
||||
* Fix a bug in the build where directory names containing spaces were
|
||||
causing generate_errors.pl to error out resulting in a build failure.
|
||||
Fixes issue #6879.
|
@ -1,19 +0,0 @@
|
||||
Bugfix
|
||||
* mbedtls_x509write_crt_set_serial() now explicitly rejects serial numbers
|
||||
whose binary representation is longer than 20 bytes. This was already
|
||||
forbidden by the standard (RFC5280 - section 4.1.2.2) and now it's being
|
||||
enforced also at code level.
|
||||
|
||||
New deprecations
|
||||
* mbedtls_x509write_crt_set_serial() is now being deprecated in favor of
|
||||
mbedtls_x509write_crt_set_serial_raw(). The goal here is to remove any
|
||||
direct dependency of X509 on BIGNUM_C.
|
||||
|
||||
Changes
|
||||
* programs/x509/cert_write:
|
||||
- now it accepts the serial number in 2 different formats: decimal and
|
||||
hex. They cannot be used simultaneously
|
||||
- "serial" is used for the decimal format and it's limted in size to
|
||||
unsigned long long int
|
||||
- "serial_hex" is used for the hex format; max length here is
|
||||
MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN*2
|
@ -1,4 +0,0 @@
|
||||
Features
|
||||
* SHA224_C/SHA384_C are now independent from SHA384_C/SHA512_C respectively.
|
||||
This helps in saving code size when some of the above hashes are not
|
||||
required.
|
@ -1,6 +0,0 @@
|
||||
Features
|
||||
* Add support for reading points in compressed format
|
||||
(MBEDTLS_ECP_PF_COMPRESSED) with mbedtls_ecp_point_read_binary()
|
||||
(and callers) for Short Weierstrass curves with prime p where p = 3 mod 4
|
||||
(all mbedtls MBEDTLS_ECP_DP_SECP* and MBEDTLS_ECP_DP_BP* curves
|
||||
except MBEDTLS_ECP_DP_SECP224R1 and MBEDTLS_ECP_DP_SECP224K1)
|
@ -1,3 +0,0 @@
|
||||
Bugfix
|
||||
* Fix undefined behavior in mbedtls_ssl_read() and mbedtls_ssl_write() if
|
||||
len argument is 0 and buffer is NULL.
|
@ -1,7 +0,0 @@
|
||||
Changes
|
||||
* Changed the default MBEDTLS_ECP_WINDOW_SIZE from 6 to 2.
|
||||
As tested in issue 6790, the correlation between this define and
|
||||
RSA decryption performance has changed lately due to security fixes.
|
||||
To fix the performance degradation when using default values the
|
||||
window was reduced from 6 to 2, a value that gives the best or close
|
||||
to best results when tested on Cortex-M4 and Intel i7.
|
@ -1,5 +0,0 @@
|
||||
Changes
|
||||
* When MBEDTLS_USE_PSA_CRYPTO and MBEDTLS_ECDSA_DETERMINISTIC are both
|
||||
defined, mbedtls_pk_sign() now use deterministic ECDSA for ECDSA
|
||||
signatures. This aligns the behaviour with MBEDTLS_USE_PSA_CRYPTO to
|
||||
the behaviour without it, where deterministic ECDSA was already used.
|
@ -1,4 +0,0 @@
|
||||
Bugfix
|
||||
* Make the fields of mbedtls_pk_rsassa_pss_options public. This makes it
|
||||
possible to verify RSA PSS signatures with the pk module, which was
|
||||
inadvertently broken since Mbed TLS 3.0.
|
@ -1,15 +0,0 @@
|
||||
Features
|
||||
* Added partial support for parsing the PKCS #7 Cryptographic Message
|
||||
Syntax, as defined in RFC 2315. Currently, support is limited to the
|
||||
following:
|
||||
- Only the signed-data content type, version 1 is supported.
|
||||
- Only DER encoding is supported.
|
||||
- Only a single digest algorithm per message is supported.
|
||||
- Certificates must be in X.509 format. A message must have either 0
|
||||
or 1 certificates.
|
||||
- There is no support for certificate revocation lists.
|
||||
- The authenticated and unauthenticated attribute fields of SignerInfo
|
||||
must be empty.
|
||||
Many thanks to Daniel Axtens, Nayna Jain, and Nick Child from IBM for
|
||||
contributing this feature, and to Demi-Marie Obenour for contributing
|
||||
various improvements, tests and bug fixes.
|
@ -1,3 +0,0 @@
|
||||
Security
|
||||
* Use platform-provided secure zeroization function where possible, such as
|
||||
explicit_bzero().
|
@ -1,4 +0,0 @@
|
||||
Features
|
||||
* The configuration macros MBEDTLS_PSA_CRYPTO_PLATFORM_FILE and
|
||||
MBEDTLS_PSA_CRYPTO_STRUCT_FILE specify alternative locations for
|
||||
the headers "psa/crypto_platform.h" and "psa/crypto_struct.h".
|
@ -1,4 +0,0 @@
|
||||
Bugfix
|
||||
* The key derivation algorithm PSA_ALG_TLS12_ECJPAKE_TO_PMS cannot be
|
||||
used on a shared secret from a key agreement since its input must be
|
||||
an ECC public key. Reject this properly.
|
@ -1,4 +0,0 @@
|
||||
Features
|
||||
* Add functions mbedtls_rsa_get_padding_mode() and mbedtls_rsa_get_md_alg()
|
||||
to read non-public fields for padding mode and hash id from
|
||||
an mbedtls_rsa_context, as requested in #6917.
|
@ -1,2 +0,0 @@
|
||||
Features
|
||||
* Add support to include the SubjectAltName extension to a CSR.
|
@ -1,3 +0,0 @@
|
||||
Features
|
||||
* Add parsing of rfc822Name subtype for subjectAltName
|
||||
extension in x509 certificates.
|
@ -1,5 +0,0 @@
|
||||
Bugfix
|
||||
* Fix the handling of renegotiation attempts in TLS 1.3. They are now
|
||||
systematically rejected.
|
||||
* Fix an unused-variable warning in TLS 1.3-only builds if
|
||||
MBEDTLS_SSL_RENEGOTIATION was enabled. Fixes #6200.
|
@ -1,4 +0,0 @@
|
||||
Changes
|
||||
* Visual Studio: Rename the directory containing Visual Studio files from
|
||||
visualc/VS2010 to visualc/VS2013 as we do not support building with versions
|
||||
older than 2013. Update the solution file to specify VS2013 as a minimum.
|
@ -1,7 +0,0 @@
|
||||
Bugfix
|
||||
* In TLS 1.3, when using a ticket for session resumption, tweak its age
|
||||
calculation on the client side. It prevents a server with more accurate
|
||||
ticket timestamps (typically timestamps in milliseconds) compared to the
|
||||
Mbed TLS ticket timestamps (in seconds) to compute a ticket age smaller
|
||||
than the age computed and transmitted by the client and thus potentially
|
||||
reject the ticket. Fix #6623.
|
@ -1,5 +0,0 @@
|
||||
Bugfix
|
||||
* Fix parsing of X.509 SubjectAlternativeName extension. Previously,
|
||||
malformed alternative name components were not caught during initial
|
||||
certificate parsing, but only on subsequent calls to
|
||||
mbedtls_x509_parse_subject_alt_name(). Fixes #2838.
|
117
SECURITY.md
117
SECURITY.md
@ -18,3 +18,120 @@ goes public.
|
||||
Only the maintained branches, as listed in [`BRANCHES.md`](BRANCHES.md),
|
||||
get security fixes.
|
||||
Users are urged to always use the latest version of a maintained branch.
|
||||
|
||||
## Threat model
|
||||
|
||||
We classify attacks based on the capabilities of the attacker.
|
||||
|
||||
### Remote attacks
|
||||
|
||||
In this section, we consider an attacker who can observe and modify data sent
|
||||
over the network. This includes observing the content and timing of individual
|
||||
packets, as well as suppressing or delaying legitimate messages, and injecting
|
||||
messages.
|
||||
|
||||
Mbed TLS aims to fully protect against remote attacks and to enable the user
|
||||
application in providing full protection against remote attacks. Said
|
||||
protection is limited to providing security guarantees offered by the protocol
|
||||
being implemented. (For example Mbed TLS alone won't guarantee that the
|
||||
messages will arrive without delay, as the TLS protocol doesn't guarantee that
|
||||
either.)
|
||||
|
||||
**Warning!** Block ciphers do not yet achieve full protection against attackers
|
||||
who can measure the timing of packets with sufficient precision. For details
|
||||
and workarounds see the [Block Ciphers](#block-ciphers) section.
|
||||
|
||||
### Local attacks
|
||||
|
||||
In this section, we consider an attacker who can run software on the same
|
||||
machine. The attacker has insufficient privileges to directly access Mbed TLS
|
||||
assets such as memory and files.
|
||||
|
||||
#### Timing attacks
|
||||
|
||||
The attacker is able to observe the timing of instructions executed by Mbed TLS
|
||||
by leveraging shared hardware that both Mbed TLS and the attacker have access
|
||||
to. Typical attack vectors include cache timings, memory bus contention and
|
||||
branch prediction.
|
||||
|
||||
Mbed TLS provides limited protection against timing attacks. The cost of
|
||||
protecting against timing attacks widely varies depending on the granularity of
|
||||
the measurements and the noise present. Therefore the protection in Mbed TLS is
|
||||
limited. We are only aiming to provide protection against **publicly
|
||||
documented attack techniques**.
|
||||
|
||||
As attacks keep improving, so does Mbed TLS's protection. Mbed TLS is moving
|
||||
towards a model of fully timing-invariant code, but has not reached this point
|
||||
yet.
|
||||
|
||||
**Remark:** Timing information can be observed over the network or through
|
||||
physical side channels as well. Remote and physical timing attacks are covered
|
||||
in the [Remote attacks](remote-attacks) and [Physical
|
||||
attacks](physical-attacks) sections respectively.
|
||||
|
||||
**Warning!** Block ciphers do not yet achieve full protection. For
|
||||
details and workarounds see the [Block Ciphers](#block-ciphers) section.
|
||||
|
||||
#### Local non-timing side channels
|
||||
|
||||
The attacker code running on the platform has access to some sensor capable of
|
||||
picking up information on the physical state of the hardware while Mbed TLS is
|
||||
running. This could for example be an analogue-to-digital converter on the
|
||||
platform that is located unfortunately enough to pick up the CPU noise.
|
||||
|
||||
Mbed TLS doesn't make any security guarantees against local non-timing-based
|
||||
side channel attacks. If local non-timing attacks are present in a use case or
|
||||
a user application's threat model, they need to be mitigated by the platform.
|
||||
|
||||
#### Local fault injection attacks
|
||||
|
||||
Software running on the same hardware can affect the physical state of the
|
||||
device and introduce faults.
|
||||
|
||||
Mbed TLS doesn't make any security guarantees against local fault injection
|
||||
attacks. If local fault injection attacks are present in a use case or a user
|
||||
application's threat model, they need to be mitigated by the platform.
|
||||
|
||||
### Physical attacks
|
||||
|
||||
In this section, we consider an attacker who has access to physical information
|
||||
about the hardware Mbed TLS is running on and/or can alter the physical state
|
||||
of the hardware (e.g. power analysis, radio emissions or fault injection).
|
||||
|
||||
Mbed TLS doesn't make any security guarantees against physical attacks. If
|
||||
physical attacks are present in a use case or a user application's threat
|
||||
model, they need to be mitigated by physical countermeasures.
|
||||
|
||||
### Caveats
|
||||
|
||||
#### Out-of-scope countermeasures
|
||||
|
||||
Mbed TLS has evolved organically and a well defined threat model hasn't always
|
||||
been present. Therefore, Mbed TLS might have countermeasures against attacks
|
||||
outside the above defined threat model.
|
||||
|
||||
The presence of such countermeasures don't mean that Mbed TLS provides
|
||||
protection against a class of attacks outside of the above described threat
|
||||
model. Neither does it mean that the failure of such a countermeasure is
|
||||
considered a vulnerability.
|
||||
|
||||
#### Block ciphers
|
||||
|
||||
Currently there are four block ciphers in Mbed TLS: AES, CAMELLIA, ARIA and
|
||||
DES. The pure software implementation in Mbed TLS implementation uses lookup
|
||||
tables, which are vulnerable to timing attacks.
|
||||
|
||||
These timing attacks can be physical, local or depending on network latency
|
||||
even a remote. The attacks can result in key recovery.
|
||||
|
||||
**Workarounds:**
|
||||
|
||||
- Turn on hardware acceleration for AES. This is supported only on selected
|
||||
architectures and currently only available for AES. See configuration options
|
||||
`MBEDTLS_AESCE_C`, `MBEDTLS_AESNI_C` and `MBEDTLS_PADLOCK_C` for details.
|
||||
- Add a secure alternative implementation (typically hardware acceleration) for
|
||||
the vulnerable cipher. See the [Alternative Implementations
|
||||
Guide](docs/architecture/alternative-implementations.md) for more information.
|
||||
- Use cryptographic mechanisms that are not based on block ciphers. In
|
||||
particular, for authenticated encryption, use ChaCha20/Poly1305 instead of
|
||||
block cipher modes. For random generation, use HMAC\_DRBG instead of CTR\_DRBG.
|
||||
|
@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @mainpage mbed TLS v3.3.0 source code documentation
|
||||
* @mainpage mbed TLS v3.4.0 source code documentation
|
||||
*
|
||||
* This documentation describes the internal structure of mbed TLS. It was
|
||||
* automatically generated from specially formatted comment blocks in
|
||||
|
@ -1,4 +1,4 @@
|
||||
PROJECT_NAME = "mbed TLS v3.3.0"
|
||||
PROJECT_NAME = "mbed TLS v3.4.0"
|
||||
OUTPUT_DIRECTORY = ../apidoc/
|
||||
FULL_PATH_NAMES = NO
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
|
@ -37,7 +37,7 @@
|
||||
* Major, Minor, Patchlevel
|
||||
*/
|
||||
#define MBEDTLS_VERSION_MAJOR 3
|
||||
#define MBEDTLS_VERSION_MINOR 3
|
||||
#define MBEDTLS_VERSION_MINOR 4
|
||||
#define MBEDTLS_VERSION_PATCH 0
|
||||
|
||||
/**
|
||||
@ -45,9 +45,9 @@
|
||||
* MMNNPP00
|
||||
* Major version | Minor version | Patch version
|
||||
*/
|
||||
#define MBEDTLS_VERSION_NUMBER 0x03030000
|
||||
#define MBEDTLS_VERSION_STRING "3.3.0"
|
||||
#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 3.3.0"
|
||||
#define MBEDTLS_VERSION_NUMBER 0x03040000
|
||||
#define MBEDTLS_VERSION_STRING "3.4.0"
|
||||
#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 3.4.0"
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
|
||||
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||
|
@ -66,10 +66,6 @@
|
||||
#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_AESNI_C) && !defined(MBEDTLS_HAVE_ASM)
|
||||
#error "MBEDTLS_AESNI_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(__aarch64__) && defined(__GNUC__)
|
||||
/* We don't do anything with MBEDTLS_AESCE_C on systems without ^ these two */
|
||||
#if defined(MBEDTLS_AESCE_C) && !defined(MBEDTLS_HAVE_ASM)
|
||||
|
@ -56,7 +56,7 @@
|
||||
*
|
||||
* Required by:
|
||||
* MBEDTLS_AESCE_C
|
||||
* MBEDTLS_AESNI_C
|
||||
* MBEDTLS_AESNI_C (on some platforms)
|
||||
* MBEDTLS_PADLOCK_C
|
||||
*
|
||||
* Comment to disable the use of assembly code.
|
||||
@ -2036,14 +2036,32 @@
|
||||
/**
|
||||
* \def MBEDTLS_AESNI_C
|
||||
*
|
||||
* Enable AES-NI support on x86-64.
|
||||
* Enable AES-NI support on x86-64 or x86-32.
|
||||
*
|
||||
* \note AESNI is only supported with certain compilers and target options:
|
||||
* - Visual Studio 2013: supported.
|
||||
* - GCC, x86-64, target not explicitly supporting AESNI:
|
||||
* requires MBEDTLS_HAVE_ASM.
|
||||
* - GCC, x86-32, target not explicitly supporting AESNI:
|
||||
* not supported.
|
||||
* - GCC, x86-64 or x86-32, target supporting AESNI: supported.
|
||||
* For this assembly-less implementation, you must currently compile
|
||||
* `library/aesni.c` and `library/aes.c` with machine options to enable
|
||||
* SSE2 and AESNI instructions: `gcc -msse2 -maes -mpclmul` or
|
||||
* `clang -maes -mpclmul`.
|
||||
* - Non-x86 targets: this option is silently ignored.
|
||||
* - Other compilers: this option is silently ignored.
|
||||
*
|
||||
* \note
|
||||
* Above, "GCC" includes compatible compilers such as Clang.
|
||||
* The limitations on target support are likely to be relaxed in the future.
|
||||
*
|
||||
* Module: library/aesni.c
|
||||
* Caller: library/aes.c
|
||||
*
|
||||
* Requires: MBEDTLS_HAVE_ASM
|
||||
* Requires: MBEDTLS_HAVE_ASM (on some platforms, see note)
|
||||
*
|
||||
* This module adds support for the AES-NI instructions on x86-64
|
||||
* This modules adds support for the AES-NI instructions on x86.
|
||||
*/
|
||||
#define MBEDTLS_AESNI_C
|
||||
|
||||
@ -3785,7 +3803,7 @@
|
||||
*/
|
||||
//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768
|
||||
|
||||
//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
|
||||
//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 or 384 bits) */
|
||||
//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
|
||||
|
||||
/**
|
||||
|
@ -388,8 +388,10 @@ int psa_status_to_mbedtls(psa_status_t status,
|
||||
int psa_pk_status_to_mbedtls(psa_status_t status);
|
||||
|
||||
/* Utility macro to shorten the defines of error translator in modules. */
|
||||
#define PSA_TO_MBEDTLS_ERR_LIST(status, error_list, fallback_f) \
|
||||
psa_status_to_mbedtls(status, error_list, sizeof(error_list), fallback_f)
|
||||
#define PSA_TO_MBEDTLS_ERR_LIST(status, error_list, fallback_f) \
|
||||
psa_status_to_mbedtls(status, error_list, \
|
||||
sizeof(error_list)/sizeof(error_list[0]), \
|
||||
fallback_f)
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
#endif /* MBEDTLS_PSA_UTIL_H */
|
||||
|
@ -601,8 +601,22 @@
|
||||
* Size defines
|
||||
*/
|
||||
#if !defined(MBEDTLS_PSK_MAX_LEN)
|
||||
#define MBEDTLS_PSK_MAX_LEN 32 /* 256 bits */
|
||||
/*
|
||||
* If the library supports TLS 1.3 tickets and the cipher suite
|
||||
* TLS1-3-AES-256-GCM-SHA384, set the PSK maximum length to 48 instead of 32.
|
||||
* That way, the TLS 1.3 client and server are able to resume sessions where
|
||||
* the cipher suite is TLS1-3-AES-256-GCM-SHA384 (pre-shared keys are 48
|
||||
* bytes long in that case).
|
||||
*/
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
|
||||
defined(MBEDTLS_SSL_SESSION_TICKETS) && \
|
||||
defined(MBEDTLS_AES_C) && defined(MBEDTLS_GCM_C) && \
|
||||
defined(MBEDTLS_MD_CAN_SHA384)
|
||||
#define MBEDTLS_PSK_MAX_LEN 48 /* 384 bits */
|
||||
#else
|
||||
#define MBEDTLS_PSK_MAX_LEN 32 /* 256 bits */
|
||||
#endif
|
||||
#endif /* !MBEDTLS_PSK_MAX_LEN */
|
||||
|
||||
/* Dummy type used only for its size */
|
||||
union mbedtls_ssl_premaster_secret {
|
||||
|
@ -284,7 +284,7 @@ endif(USE_STATIC_MBEDTLS_LIBRARY)
|
||||
if(USE_SHARED_MBEDTLS_LIBRARY)
|
||||
set(CMAKE_LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR})
|
||||
add_library(${mbedcrypto_target} SHARED ${src_crypto})
|
||||
set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 3.3.0 SOVERSION 13)
|
||||
set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 3.4.0 SOVERSION 14)
|
||||
target_link_libraries(${mbedcrypto_target} PUBLIC ${libs})
|
||||
|
||||
if(TARGET everest)
|
||||
@ -292,11 +292,11 @@ if(USE_SHARED_MBEDTLS_LIBRARY)
|
||||
endif()
|
||||
|
||||
add_library(${mbedx509_target} SHARED ${src_x509})
|
||||
set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.3.0 SOVERSION 4)
|
||||
set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.4.0 SOVERSION 5)
|
||||
target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target})
|
||||
|
||||
add_library(${mbedtls_target} SHARED ${src_tls})
|
||||
set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.3.0 SOVERSION 19)
|
||||
set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.4.0 SOVERSION 19)
|
||||
target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target})
|
||||
endif(USE_SHARED_MBEDTLS_LIBRARY)
|
||||
|
||||
|
@ -48,8 +48,8 @@ endif
|
||||
endif
|
||||
|
||||
SOEXT_TLS?=so.19
|
||||
SOEXT_X509?=so.4
|
||||
SOEXT_CRYPTO?=so.13
|
||||
SOEXT_X509?=so.5
|
||||
SOEXT_CRYPTO?=so.14
|
||||
|
||||
# Set AR_DASH= (empty string) to use an ar implementation that does not accept
|
||||
# the - prefix for command line options (e.g. llvm-ar)
|
||||
|
133
library/aes.c
133
library/aes.c
@ -47,8 +47,7 @@
|
||||
|
||||
#if !defined(MBEDTLS_AES_ALT)
|
||||
|
||||
#if defined(MBEDTLS_PADLOCK_C) && \
|
||||
(defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16))
|
||||
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
|
||||
static int aes_padlock_ace = -1;
|
||||
#endif
|
||||
|
||||
@ -505,6 +504,53 @@ void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
|
||||
}
|
||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
||||
|
||||
/* Some implementations need the round keys to be aligned.
|
||||
* Return an offset to be added to buf, such that (buf + offset) is
|
||||
* correctly aligned.
|
||||
* Note that the offset is in units of elements of buf, i.e. 32-bit words,
|
||||
* i.e. an offset of 1 means 4 bytes and so on.
|
||||
*/
|
||||
#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
|
||||
(defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
|
||||
#define MAY_NEED_TO_ALIGN
|
||||
#endif
|
||||
static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
|
||||
{
|
||||
#if defined(MAY_NEED_TO_ALIGN)
|
||||
int align_16_bytes = 0;
|
||||
|
||||
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
|
||||
if (aes_padlock_ace == -1) {
|
||||
aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
|
||||
}
|
||||
if (aes_padlock_ace) {
|
||||
align_16_bytes = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
|
||||
if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
|
||||
align_16_bytes = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (align_16_bytes) {
|
||||
/* These implementations needs 16-byte alignment
|
||||
* for the round key array. */
|
||||
unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
|
||||
if (delta == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return 4 - delta; // 16 bytes = 4 uint32_t
|
||||
}
|
||||
}
|
||||
#else /* MAY_NEED_TO_ALIGN */
|
||||
(void) buf;
|
||||
#endif /* MAY_NEED_TO_ALIGN */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* AES key schedule (encryption)
|
||||
*/
|
||||
@ -529,19 +575,10 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
}
|
||||
#endif
|
||||
|
||||
ctx->rk_offset = 0;
|
||||
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
|
||||
if (aes_padlock_ace == -1) {
|
||||
aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
|
||||
}
|
||||
|
||||
if (aes_padlock_ace) {
|
||||
ctx->rk_offset = MBEDTLS_PADLOCK_ALIGN16(ctx->buf) - ctx->buf;
|
||||
}
|
||||
#endif
|
||||
ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
|
||||
RK = ctx->buf + ctx->rk_offset;
|
||||
|
||||
#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
|
||||
#if defined(MBEDTLS_AESNI_HAVE_CODE)
|
||||
if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
|
||||
return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
|
||||
}
|
||||
@ -634,16 +671,7 @@ int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
|
||||
mbedtls_aes_init(&cty);
|
||||
|
||||
ctx->rk_offset = 0;
|
||||
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
|
||||
if (aes_padlock_ace == -1) {
|
||||
aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
|
||||
}
|
||||
|
||||
if (aes_padlock_ace) {
|
||||
ctx->rk_offset = MBEDTLS_PADLOCK_ALIGN16(ctx->buf) - ctx->buf;
|
||||
}
|
||||
#endif
|
||||
ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
|
||||
RK = ctx->buf + ctx->rk_offset;
|
||||
|
||||
/* Also checks keybits */
|
||||
@ -653,7 +681,7 @@ int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
|
||||
ctx->nr = cty.nr;
|
||||
|
||||
#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
|
||||
#if defined(MBEDTLS_AESNI_HAVE_CODE)
|
||||
if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
|
||||
mbedtls_aesni_inverse_key((unsigned char *) RK,
|
||||
(const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
|
||||
@ -945,6 +973,26 @@ int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
|
||||
}
|
||||
#endif /* !MBEDTLS_AES_DECRYPT_ALT */
|
||||
|
||||
#if defined(MAY_NEED_TO_ALIGN)
|
||||
/* VIA Padlock and our intrinsics-based implementation of AESNI require
|
||||
* the round keys to be aligned on a 16-byte boundary. We take care of this
|
||||
* before creating them, but the AES context may have moved (this can happen
|
||||
* if the library is called from a language with managed memory), and in later
|
||||
* calls it might have a different alignment with respect to 16-byte memory.
|
||||
* So we may need to realign.
|
||||
*/
|
||||
static void aes_maybe_realign(mbedtls_aes_context *ctx)
|
||||
{
|
||||
unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
|
||||
if (new_offset != ctx->rk_offset) {
|
||||
memmove(ctx->buf + new_offset, // new address
|
||||
ctx->buf + ctx->rk_offset, // current address
|
||||
(ctx->nr + 1) * 16); // number of round keys * bytes per rk
|
||||
ctx->rk_offset = new_offset;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AES-ECB block encryption/decryption
|
||||
*/
|
||||
@ -957,7 +1005,11 @@ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
|
||||
return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
|
||||
#if defined(MAY_NEED_TO_ALIGN)
|
||||
aes_maybe_realign(ctx);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_AESNI_HAVE_CODE)
|
||||
if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
|
||||
return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
|
||||
}
|
||||
@ -971,13 +1023,7 @@ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
|
||||
|
||||
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
|
||||
if (aes_padlock_ace > 0) {
|
||||
if (mbedtls_padlock_xcryptecb(ctx, mode, input, output) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If padlock data misaligned, we just fall back to
|
||||
// unaccelerated mode
|
||||
//
|
||||
return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1729,6 +1775,29 @@ int mbedtls_aes_self_test(int verbose)
|
||||
memset(key, 0, 32);
|
||||
mbedtls_aes_init(&ctx);
|
||||
|
||||
if (verbose != 0) {
|
||||
#if defined(MBEDTLS_AES_ALT)
|
||||
mbedtls_printf(" AES note: alternative implementation.\n");
|
||||
#else /* MBEDTLS_AES_ALT */
|
||||
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
|
||||
if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
|
||||
mbedtls_printf(" AES note: using VIA Padlock.\n");
|
||||
} else
|
||||
#endif
|
||||
#if defined(MBEDTLS_AESNI_HAVE_CODE)
|
||||
if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
|
||||
mbedtls_printf(" AES note: using AESNI.\n");
|
||||
} else
|
||||
#endif
|
||||
#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
|
||||
if (mbedtls_aesce_has_support()) {
|
||||
mbedtls_printf(" AES note: using AESCE.\n");
|
||||
} else
|
||||
#endif
|
||||
mbedtls_printf(" AES note: built-in implementation.\n");
|
||||
#endif /* MBEDTLS_AES_ALT */
|
||||
}
|
||||
|
||||
/*
|
||||
* ECB mode
|
||||
*/
|
||||
|
604
library/aesni.c
604
library/aesni.c
@ -18,26 +18,26 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* [AES-WP] http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-aes-instructions-set
|
||||
* [CLMUL-WP] http://software.intel.com/en-us/articles/intel-carry-less-multiplication-instruction-and-its-usage-for-computing-the-gcm-mode/
|
||||
* [AES-WP] https://www.intel.com/content/www/us/en/developer/articles/tool/intel-advanced-encryption-standard-aes-instructions-set.html
|
||||
* [CLMUL-WP] https://www.intel.com/content/www/us/en/develop/download/intel-carry-less-multiplication-instruction-and-its-usage-for-computing-the-gcm-mode.html
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_AESNI_C)
|
||||
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(memory_sanitizer)
|
||||
#warning \
|
||||
"MBEDTLS_AESNI_C is known to cause spurious error reports with some memory sanitizers as they do not understand the assembly code."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "aesni.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_HAVE_X86_64)
|
||||
#if defined(MBEDTLS_AESNI_HAVE_CODE)
|
||||
|
||||
#if MBEDTLS_AESNI_HAVE_CODE == 2
|
||||
#if !defined(_WIN32)
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AES-NI support detection routine
|
||||
@ -48,17 +48,355 @@ int mbedtls_aesni_has_support(unsigned int what)
|
||||
static unsigned int c = 0;
|
||||
|
||||
if (!done) {
|
||||
#if MBEDTLS_AESNI_HAVE_CODE == 2
|
||||
static unsigned info[4] = { 0, 0, 0, 0 };
|
||||
#if defined(_MSC_VER)
|
||||
__cpuid(info, 1);
|
||||
#else
|
||||
__cpuid(1, info[0], info[1], info[2], info[3]);
|
||||
#endif
|
||||
c = info[2];
|
||||
#else /* AESNI using asm */
|
||||
asm ("movl $1, %%eax \n\t"
|
||||
"cpuid \n\t"
|
||||
: "=c" (c)
|
||||
:
|
||||
: "eax", "ebx", "edx");
|
||||
#endif /* MBEDTLS_AESNI_HAVE_CODE */
|
||||
done = 1;
|
||||
}
|
||||
|
||||
return (c & what) != 0;
|
||||
}
|
||||
|
||||
#if MBEDTLS_AESNI_HAVE_CODE == 2
|
||||
|
||||
/*
|
||||
* AES-NI AES-ECB block en(de)cryption
|
||||
*/
|
||||
int mbedtls_aesni_crypt_ecb(mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16])
|
||||
{
|
||||
const __m128i *rk = (const __m128i *) (ctx->buf + ctx->rk_offset);
|
||||
unsigned nr = ctx->nr; // Number of remaining rounds
|
||||
|
||||
// Load round key 0
|
||||
__m128i state;
|
||||
memcpy(&state, input, 16);
|
||||
state = _mm_xor_si128(state, rk[0]); // state ^= *rk;
|
||||
++rk;
|
||||
--nr;
|
||||
|
||||
if (mode == 0) {
|
||||
while (nr != 0) {
|
||||
state = _mm_aesdec_si128(state, *rk);
|
||||
++rk;
|
||||
--nr;
|
||||
}
|
||||
state = _mm_aesdeclast_si128(state, *rk);
|
||||
} else {
|
||||
while (nr != 0) {
|
||||
state = _mm_aesenc_si128(state, *rk);
|
||||
++rk;
|
||||
--nr;
|
||||
}
|
||||
state = _mm_aesenclast_si128(state, *rk);
|
||||
}
|
||||
|
||||
memcpy(output, &state, 16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* GCM multiplication: c = a times b in GF(2^128)
|
||||
* Based on [CLMUL-WP] algorithms 1 (with equation 27) and 5.
|
||||
*/
|
||||
|
||||
static void gcm_clmul(const __m128i aa, const __m128i bb,
|
||||
__m128i *cc, __m128i *dd)
|
||||
{
|
||||
/*
|
||||
* Caryless multiplication dd:cc = aa * bb
|
||||
* using [CLMUL-WP] algorithm 1 (p. 12).
|
||||
*/
|
||||
*cc = _mm_clmulepi64_si128(aa, bb, 0x00); // a0*b0 = c1:c0
|
||||
*dd = _mm_clmulepi64_si128(aa, bb, 0x11); // a1*b1 = d1:d0
|
||||
__m128i ee = _mm_clmulepi64_si128(aa, bb, 0x10); // a0*b1 = e1:e0
|
||||
__m128i ff = _mm_clmulepi64_si128(aa, bb, 0x01); // a1*b0 = f1:f0
|
||||
ff = _mm_xor_si128(ff, ee); // e1+f1:e0+f0
|
||||
ee = ff; // e1+f1:e0+f0
|
||||
ff = _mm_srli_si128(ff, 8); // 0:e1+f1
|
||||
ee = _mm_slli_si128(ee, 8); // e0+f0:0
|
||||
*dd = _mm_xor_si128(*dd, ff); // d1:d0+e1+f1
|
||||
*cc = _mm_xor_si128(*cc, ee); // c1+e0+f0:c0
|
||||
}
|
||||
|
||||
static void gcm_shift(__m128i *cc, __m128i *dd)
|
||||
{
|
||||
/* [CMUCL-WP] Algorithm 5 Step 1: shift cc:dd one bit to the left,
|
||||
* taking advantage of [CLMUL-WP] eq 27 (p. 18). */
|
||||
// // *cc = r1:r0
|
||||
// // *dd = r3:r2
|
||||
__m128i cc_lo = _mm_slli_epi64(*cc, 1); // r1<<1:r0<<1
|
||||
__m128i dd_lo = _mm_slli_epi64(*dd, 1); // r3<<1:r2<<1
|
||||
__m128i cc_hi = _mm_srli_epi64(*cc, 63); // r1>>63:r0>>63
|
||||
__m128i dd_hi = _mm_srli_epi64(*dd, 63); // r3>>63:r2>>63
|
||||
__m128i xmm5 = _mm_srli_si128(cc_hi, 8); // 0:r1>>63
|
||||
cc_hi = _mm_slli_si128(cc_hi, 8); // r0>>63:0
|
||||
dd_hi = _mm_slli_si128(dd_hi, 8); // 0:r1>>63
|
||||
|
||||
*cc = _mm_or_si128(cc_lo, cc_hi); // r1<<1|r0>>63:r0<<1
|
||||
*dd = _mm_or_si128(_mm_or_si128(dd_lo, dd_hi), xmm5); // r3<<1|r2>>62:r2<<1|r1>>63
|
||||
}
|
||||
|
||||
static __m128i gcm_reduce(__m128i xx)
|
||||
{
|
||||
// // xx = x1:x0
|
||||
/* [CLMUL-WP] Algorithm 5 Step 2 */
|
||||
__m128i aa = _mm_slli_epi64(xx, 63); // x1<<63:x0<<63 = stuff:a
|
||||
__m128i bb = _mm_slli_epi64(xx, 62); // x1<<62:x0<<62 = stuff:b
|
||||
__m128i cc = _mm_slli_epi64(xx, 57); // x1<<57:x0<<57 = stuff:c
|
||||
__m128i dd = _mm_slli_si128(_mm_xor_si128(_mm_xor_si128(aa, bb), cc), 8); // a+b+c:0
|
||||
return _mm_xor_si128(dd, xx); // x1+a+b+c:x0 = d:x0
|
||||
}
|
||||
|
||||
static __m128i gcm_mix(__m128i dx)
|
||||
{
|
||||
/* [CLMUL-WP] Algorithm 5 Steps 3 and 4 */
|
||||
__m128i ee = _mm_srli_epi64(dx, 1); // e1:x0>>1 = e1:e0'
|
||||
__m128i ff = _mm_srli_epi64(dx, 2); // f1:x0>>2 = f1:f0'
|
||||
__m128i gg = _mm_srli_epi64(dx, 7); // g1:x0>>7 = g1:g0'
|
||||
|
||||
// e0'+f0'+g0' is almost e0+f0+g0, except for some missing
|
||||
// bits carried from d. Now get those bits back in.
|
||||
__m128i eh = _mm_slli_epi64(dx, 63); // d<<63:stuff
|
||||
__m128i fh = _mm_slli_epi64(dx, 62); // d<<62:stuff
|
||||
__m128i gh = _mm_slli_epi64(dx, 57); // d<<57:stuff
|
||||
__m128i hh = _mm_srli_si128(_mm_xor_si128(_mm_xor_si128(eh, fh), gh), 8); // 0:missing bits of d
|
||||
|
||||
return _mm_xor_si128(_mm_xor_si128(_mm_xor_si128(_mm_xor_si128(ee, ff), gg), hh), dx);
|
||||
}
|
||||
|
||||
void mbedtls_aesni_gcm_mult(unsigned char c[16],
|
||||
const unsigned char a[16],
|
||||
const unsigned char b[16])
|
||||
{
|
||||
__m128i aa, bb, cc, dd;
|
||||
|
||||
/* The inputs are in big-endian order, so byte-reverse them */
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
((uint8_t *) &aa)[i] = a[15 - i];
|
||||
((uint8_t *) &bb)[i] = b[15 - i];
|
||||
}
|
||||
|
||||
gcm_clmul(aa, bb, &cc, &dd);
|
||||
gcm_shift(&cc, &dd);
|
||||
/*
|
||||
* Now reduce modulo the GCM polynomial x^128 + x^7 + x^2 + x + 1
|
||||
* using [CLMUL-WP] algorithm 5 (p. 18).
|
||||
* Currently dd:cc holds x3:x2:x1:x0 (already shifted).
|
||||
*/
|
||||
__m128i dx = gcm_reduce(cc);
|
||||
__m128i xh = gcm_mix(dx);
|
||||
cc = _mm_xor_si128(xh, dd); // x3+h1:x2+h0
|
||||
|
||||
/* Now byte-reverse the outputs */
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
c[i] = ((uint8_t *) &cc)[15 - i];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute decryption round keys from encryption round keys
|
||||
*/
|
||||
void mbedtls_aesni_inverse_key(unsigned char *invkey,
|
||||
const unsigned char *fwdkey, int nr)
|
||||
{
|
||||
__m128i *ik = (__m128i *) invkey;
|
||||
const __m128i *fk = (const __m128i *) fwdkey + nr;
|
||||
|
||||
*ik = *fk;
|
||||
for (--fk, ++ik; fk > (const __m128i *) fwdkey; --fk, ++ik) {
|
||||
*ik = _mm_aesimc_si128(*fk);
|
||||
}
|
||||
*ik = *fk;
|
||||
}
|
||||
|
||||
/*
|
||||
* Key expansion, 128-bit case
|
||||
*/
|
||||
static __m128i aesni_set_rk_128(__m128i state, __m128i xword)
|
||||
{
|
||||
/*
|
||||
* Finish generating the next round key.
|
||||
*
|
||||
* On entry state is r3:r2:r1:r0 and xword is X:stuff:stuff:stuff
|
||||
* with X = rot( sub( r3 ) ) ^ RCON (obtained with AESKEYGENASSIST).
|
||||
*
|
||||
* On exit, xword is r7:r6:r5:r4
|
||||
* with r4 = X + r0, r5 = r4 + r1, r6 = r5 + r2, r7 = r6 + r3
|
||||
* and this is returned, to be written to the round key buffer.
|
||||
*/
|
||||
xword = _mm_shuffle_epi32(xword, 0xff); // X:X:X:X
|
||||
xword = _mm_xor_si128(xword, state); // X+r3:X+r2:X+r1:r4
|
||||
state = _mm_slli_si128(state, 4); // r2:r1:r0:0
|
||||
xword = _mm_xor_si128(xword, state); // X+r3+r2:X+r2+r1:r5:r4
|
||||
state = _mm_slli_si128(state, 4); // r1:r0:0:0
|
||||
xword = _mm_xor_si128(xword, state); // X+r3+r2+r1:r6:r5:r4
|
||||
state = _mm_slli_si128(state, 4); // r0:0:0:0
|
||||
state = _mm_xor_si128(xword, state); // r7:r6:r5:r4
|
||||
return state;
|
||||
}
|
||||
|
||||
static void aesni_setkey_enc_128(unsigned char *rk_bytes,
|
||||
const unsigned char *key)
|
||||
{
|
||||
__m128i *rk = (__m128i *) rk_bytes;
|
||||
|
||||
memcpy(&rk[0], key, 16);
|
||||
rk[1] = aesni_set_rk_128(rk[0], _mm_aeskeygenassist_si128(rk[0], 0x01));
|
||||
rk[2] = aesni_set_rk_128(rk[1], _mm_aeskeygenassist_si128(rk[1], 0x02));
|
||||
rk[3] = aesni_set_rk_128(rk[2], _mm_aeskeygenassist_si128(rk[2], 0x04));
|
||||
rk[4] = aesni_set_rk_128(rk[3], _mm_aeskeygenassist_si128(rk[3], 0x08));
|
||||
rk[5] = aesni_set_rk_128(rk[4], _mm_aeskeygenassist_si128(rk[4], 0x10));
|
||||
rk[6] = aesni_set_rk_128(rk[5], _mm_aeskeygenassist_si128(rk[5], 0x20));
|
||||
rk[7] = aesni_set_rk_128(rk[6], _mm_aeskeygenassist_si128(rk[6], 0x40));
|
||||
rk[8] = aesni_set_rk_128(rk[7], _mm_aeskeygenassist_si128(rk[7], 0x80));
|
||||
rk[9] = aesni_set_rk_128(rk[8], _mm_aeskeygenassist_si128(rk[8], 0x1B));
|
||||
rk[10] = aesni_set_rk_128(rk[9], _mm_aeskeygenassist_si128(rk[9], 0x36));
|
||||
}
|
||||
|
||||
/*
|
||||
* Key expansion, 192-bit case
|
||||
*/
|
||||
static void aesni_set_rk_192(__m128i *state0, __m128i *state1, __m128i xword,
|
||||
unsigned char *rk)
|
||||
{
|
||||
/*
|
||||
* Finish generating the next 6 quarter-keys.
|
||||
*
|
||||
* On entry state0 is r3:r2:r1:r0, state1 is stuff:stuff:r5:r4
|
||||
* and xword is stuff:stuff:X:stuff with X = rot( sub( r3 ) ) ^ RCON
|
||||
* (obtained with AESKEYGENASSIST).
|
||||
*
|
||||
* On exit, state0 is r9:r8:r7:r6 and state1 is stuff:stuff:r11:r10
|
||||
* and those are written to the round key buffer.
|
||||
*/
|
||||
xword = _mm_shuffle_epi32(xword, 0x55); // X:X:X:X
|
||||
xword = _mm_xor_si128(xword, *state0); // X+r3:X+r2:X+r1:X+r0
|
||||
*state0 = _mm_slli_si128(*state0, 4); // r2:r1:r0:0
|
||||
xword = _mm_xor_si128(xword, *state0); // X+r3+r2:X+r2+r1:X+r1+r0:X+r0
|
||||
*state0 = _mm_slli_si128(*state0, 4); // r1:r0:0:0
|
||||
xword = _mm_xor_si128(xword, *state0); // X+r3+r2+r1:X+r2+r1+r0:X+r1+r0:X+r0
|
||||
*state0 = _mm_slli_si128(*state0, 4); // r0:0:0:0
|
||||
xword = _mm_xor_si128(xword, *state0); // X+r3+r2+r1+r0:X+r2+r1+r0:X+r1+r0:X+r0
|
||||
*state0 = xword; // = r9:r8:r7:r6
|
||||
|
||||
xword = _mm_shuffle_epi32(xword, 0xff); // r9:r9:r9:r9
|
||||
xword = _mm_xor_si128(xword, *state1); // stuff:stuff:r9+r5:r9+r4
|
||||
*state1 = _mm_slli_si128(*state1, 4); // stuff:stuff:r4:0
|
||||
xword = _mm_xor_si128(xword, *state1); // stuff:stuff:r9+r5+r4:r9+r4
|
||||
*state1 = xword; // = stuff:stuff:r11:r10
|
||||
|
||||
/* Store state0 and the low half of state1 into rk, which is conceptually
|
||||
* an array of 24-byte elements. Since 24 is not a multiple of 16,
|
||||
* rk is not necessarily aligned so just `*rk = *state0` doesn't work. */
|
||||
memcpy(rk, state0, 16);
|
||||
memcpy(rk + 16, state1, 8);
|
||||
}
|
||||
|
||||
static void aesni_setkey_enc_192(unsigned char *rk,
|
||||
const unsigned char *key)
|
||||
{
|
||||
/* First round: use original key */
|
||||
memcpy(rk, key, 24);
|
||||
/* aes.c guarantees that rk is aligned on a 16-byte boundary. */
|
||||
__m128i state0 = ((__m128i *) rk)[0];
|
||||
__m128i state1 = _mm_loadl_epi64(((__m128i *) rk) + 1);
|
||||
|
||||
aesni_set_rk_192(&state0, &state1, _mm_aeskeygenassist_si128(state1, 0x01), rk + 24 * 1);
|
||||
aesni_set_rk_192(&state0, &state1, _mm_aeskeygenassist_si128(state1, 0x02), rk + 24 * 2);
|
||||
aesni_set_rk_192(&state0, &state1, _mm_aeskeygenassist_si128(state1, 0x04), rk + 24 * 3);
|
||||
aesni_set_rk_192(&state0, &state1, _mm_aeskeygenassist_si128(state1, 0x08), rk + 24 * 4);
|
||||
aesni_set_rk_192(&state0, &state1, _mm_aeskeygenassist_si128(state1, 0x10), rk + 24 * 5);
|
||||
aesni_set_rk_192(&state0, &state1, _mm_aeskeygenassist_si128(state1, 0x20), rk + 24 * 6);
|
||||
aesni_set_rk_192(&state0, &state1, _mm_aeskeygenassist_si128(state1, 0x40), rk + 24 * 7);
|
||||
aesni_set_rk_192(&state0, &state1, _mm_aeskeygenassist_si128(state1, 0x80), rk + 24 * 8);
|
||||
}
|
||||
|
||||
/*
|
||||
* Key expansion, 256-bit case
|
||||
*/
|
||||
static void aesni_set_rk_256(__m128i state0, __m128i state1, __m128i xword,
|
||||
__m128i *rk0, __m128i *rk1)
|
||||
{
|
||||
/*
|
||||
* Finish generating the next two round keys.
|
||||
*
|
||||
* On entry state0 is r3:r2:r1:r0, state1 is r7:r6:r5:r4 and
|
||||
* xword is X:stuff:stuff:stuff with X = rot( sub( r7 )) ^ RCON
|
||||
* (obtained with AESKEYGENASSIST).
|
||||
*
|
||||
* On exit, *rk0 is r11:r10:r9:r8 and *rk1 is r15:r14:r13:r12
|
||||
*/
|
||||
xword = _mm_shuffle_epi32(xword, 0xff);
|
||||
xword = _mm_xor_si128(xword, state0);
|
||||
state0 = _mm_slli_si128(state0, 4);
|
||||
xword = _mm_xor_si128(xword, state0);
|
||||
state0 = _mm_slli_si128(state0, 4);
|
||||
xword = _mm_xor_si128(xword, state0);
|
||||
state0 = _mm_slli_si128(state0, 4);
|
||||
state0 = _mm_xor_si128(state0, xword);
|
||||
*rk0 = state0;
|
||||
|
||||
/* Set xword to stuff:Y:stuff:stuff with Y = subword( r11 )
|
||||
* and proceed to generate next round key from there */
|
||||
xword = _mm_aeskeygenassist_si128(state0, 0x00);
|
||||
xword = _mm_shuffle_epi32(xword, 0xaa);
|
||||
xword = _mm_xor_si128(xword, state1);
|
||||
state1 = _mm_slli_si128(state1, 4);
|
||||
xword = _mm_xor_si128(xword, state1);
|
||||
state1 = _mm_slli_si128(state1, 4);
|
||||
xword = _mm_xor_si128(xword, state1);
|
||||
state1 = _mm_slli_si128(state1, 4);
|
||||
state1 = _mm_xor_si128(state1, xword);
|
||||
*rk1 = state1;
|
||||
}
|
||||
|
||||
static void aesni_setkey_enc_256(unsigned char *rk_bytes,
|
||||
const unsigned char *key)
|
||||
{
|
||||
__m128i *rk = (__m128i *) rk_bytes;
|
||||
|
||||
memcpy(&rk[0], key, 16);
|
||||
memcpy(&rk[1], key + 16, 16);
|
||||
|
||||
/*
|
||||
* Main "loop" - Generating one more key than necessary,
|
||||
* see definition of mbedtls_aes_context.buf
|
||||
*/
|
||||
aesni_set_rk_256(rk[0], rk[1], _mm_aeskeygenassist_si128(rk[1], 0x01), &rk[2], &rk[3]);
|
||||
aesni_set_rk_256(rk[2], rk[3], _mm_aeskeygenassist_si128(rk[3], 0x02), &rk[4], &rk[5]);
|
||||
aesni_set_rk_256(rk[4], rk[5], _mm_aeskeygenassist_si128(rk[5], 0x04), &rk[6], &rk[7]);
|
||||
aesni_set_rk_256(rk[6], rk[7], _mm_aeskeygenassist_si128(rk[7], 0x08), &rk[8], &rk[9]);
|
||||
aesni_set_rk_256(rk[8], rk[9], _mm_aeskeygenassist_si128(rk[9], 0x10), &rk[10], &rk[11]);
|
||||
aesni_set_rk_256(rk[10], rk[11], _mm_aeskeygenassist_si128(rk[11], 0x20), &rk[12], &rk[13]);
|
||||
aesni_set_rk_256(rk[12], rk[13], _mm_aeskeygenassist_si128(rk[13], 0x40), &rk[14], &rk[15]);
|
||||
}
|
||||
|
||||
#else /* MBEDTLS_AESNI_HAVE_CODE == 1 */
|
||||
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(memory_sanitizer)
|
||||
#warning \
|
||||
"MBEDTLS_AESNI_C is known to cause spurious error reports with some memory sanitizers as they do not understand the assembly code."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Binutils needs to be at least 2.19 to support AES-NI instructions.
|
||||
* Unfortunately, a lot of users have a lower version now (2014-04).
|
||||
@ -69,13 +407,13 @@ int mbedtls_aesni_has_support(unsigned int what)
|
||||
* Operand macros are in gas order (src, dst) as opposed to Intel order
|
||||
* (dst, src) in order to blend better into the surrounding assembly code.
|
||||
*/
|
||||
#define AESDEC ".byte 0x66,0x0F,0x38,0xDE,"
|
||||
#define AESDECLAST ".byte 0x66,0x0F,0x38,0xDF,"
|
||||
#define AESENC ".byte 0x66,0x0F,0x38,0xDC,"
|
||||
#define AESENCLAST ".byte 0x66,0x0F,0x38,0xDD,"
|
||||
#define AESIMC ".byte 0x66,0x0F,0x38,0xDB,"
|
||||
#define AESKEYGENA ".byte 0x66,0x0F,0x3A,0xDF,"
|
||||
#define PCLMULQDQ ".byte 0x66,0x0F,0x3A,0x44,"
|
||||
#define AESDEC(regs) ".byte 0x66,0x0F,0x38,0xDE," regs "\n\t"
|
||||
#define AESDECLAST(regs) ".byte 0x66,0x0F,0x38,0xDF," regs "\n\t"
|
||||
#define AESENC(regs) ".byte 0x66,0x0F,0x38,0xDC," regs "\n\t"
|
||||
#define AESENCLAST(regs) ".byte 0x66,0x0F,0x38,0xDD," regs "\n\t"
|
||||
#define AESIMC(regs) ".byte 0x66,0x0F,0x38,0xDB," regs "\n\t"
|
||||
#define AESKEYGENA(regs, imm) ".byte 0x66,0x0F,0x3A,0xDF," regs "," imm "\n\t"
|
||||
#define PCLMULQDQ(regs, imm) ".byte 0x66,0x0F,0x3A,0x44," regs "," imm "\n\t"
|
||||
|
||||
#define xmm0_xmm0 "0xC0"
|
||||
#define xmm0_xmm1 "0xC8"
|
||||
@ -103,25 +441,25 @@ int mbedtls_aesni_crypt_ecb(mbedtls_aes_context *ctx,
|
||||
|
||||
"1: \n\t" // encryption loop
|
||||
"movdqu (%1), %%xmm1 \n\t" // load round key
|
||||
AESENC xmm1_xmm0 "\n\t" // do round
|
||||
"add $16, %1 \n\t" // point to next round key
|
||||
"subl $1, %0 \n\t" // loop
|
||||
"jnz 1b \n\t"
|
||||
"movdqu (%1), %%xmm1 \n\t" // load round key
|
||||
AESENCLAST xmm1_xmm0 "\n\t" // last round
|
||||
"jmp 3f \n\t"
|
||||
AESENC(xmm1_xmm0) // do round
|
||||
"add $16, %1 \n\t" // point to next round key
|
||||
"subl $1, %0 \n\t" // loop
|
||||
"jnz 1b \n\t"
|
||||
"movdqu (%1), %%xmm1 \n\t" // load round key
|
||||
AESENCLAST(xmm1_xmm0) // last round
|
||||
"jmp 3f \n\t"
|
||||
|
||||
"2: \n\t" // decryption loop
|
||||
"movdqu (%1), %%xmm1 \n\t"
|
||||
AESDEC xmm1_xmm0 "\n\t" // do round
|
||||
"add $16, %1 \n\t"
|
||||
"subl $1, %0 \n\t"
|
||||
"jnz 2b \n\t"
|
||||
"movdqu (%1), %%xmm1 \n\t" // load round key
|
||||
AESDECLAST xmm1_xmm0 "\n\t" // last round
|
||||
"2: \n\t" // decryption loop
|
||||
"movdqu (%1), %%xmm1 \n\t"
|
||||
AESDEC(xmm1_xmm0) // do round
|
||||
"add $16, %1 \n\t"
|
||||
"subl $1, %0 \n\t"
|
||||
"jnz 2b \n\t"
|
||||
"movdqu (%1), %%xmm1 \n\t" // load round key
|
||||
AESDECLAST(xmm1_xmm0) // last round
|
||||
|
||||
"3: \n\t"
|
||||
"movdqu %%xmm0, (%4) \n\t" // export output
|
||||
"3: \n\t"
|
||||
"movdqu %%xmm0, (%4) \n\t" // export output
|
||||
:
|
||||
: "r" (ctx->nr), "r" (ctx->buf + ctx->rk_offset), "r" (mode), "r" (input), "r" (output)
|
||||
: "memory", "cc", "xmm0", "xmm1");
|
||||
@ -152,84 +490,84 @@ void mbedtls_aesni_gcm_mult(unsigned char c[16],
|
||||
|
||||
/*
|
||||
* Caryless multiplication xmm2:xmm1 = xmm0 * xmm1
|
||||
* using [CLMUL-WP] algorithm 1 (p. 13).
|
||||
* using [CLMUL-WP] algorithm 1 (p. 12).
|
||||
*/
|
||||
"movdqa %%xmm1, %%xmm2 \n\t" // copy of b1:b0
|
||||
"movdqa %%xmm1, %%xmm3 \n\t" // same
|
||||
"movdqa %%xmm1, %%xmm4 \n\t" // same
|
||||
PCLMULQDQ xmm0_xmm1 ",0x00 \n\t" // a0*b0 = c1:c0
|
||||
PCLMULQDQ xmm0_xmm2 ",0x11 \n\t" // a1*b1 = d1:d0
|
||||
PCLMULQDQ xmm0_xmm3 ",0x10 \n\t" // a0*b1 = e1:e0
|
||||
PCLMULQDQ xmm0_xmm4 ",0x01 \n\t" // a1*b0 = f1:f0
|
||||
"pxor %%xmm3, %%xmm4 \n\t" // e1+f1:e0+f0
|
||||
"movdqa %%xmm4, %%xmm3 \n\t" // same
|
||||
"psrldq $8, %%xmm4 \n\t" // 0:e1+f1
|
||||
"pslldq $8, %%xmm3 \n\t" // e0+f0:0
|
||||
"pxor %%xmm4, %%xmm2 \n\t" // d1:d0+e1+f1
|
||||
"pxor %%xmm3, %%xmm1 \n\t" // c1+e0+f1:c0
|
||||
PCLMULQDQ(xmm0_xmm1, "0x00") // a0*b0 = c1:c0
|
||||
PCLMULQDQ(xmm0_xmm2, "0x11") // a1*b1 = d1:d0
|
||||
PCLMULQDQ(xmm0_xmm3, "0x10") // a0*b1 = e1:e0
|
||||
PCLMULQDQ(xmm0_xmm4, "0x01") // a1*b0 = f1:f0
|
||||
"pxor %%xmm3, %%xmm4 \n\t" // e1+f1:e0+f0
|
||||
"movdqa %%xmm4, %%xmm3 \n\t" // same
|
||||
"psrldq $8, %%xmm4 \n\t" // 0:e1+f1
|
||||
"pslldq $8, %%xmm3 \n\t" // e0+f0:0
|
||||
"pxor %%xmm4, %%xmm2 \n\t" // d1:d0+e1+f1
|
||||
"pxor %%xmm3, %%xmm1 \n\t" // c1+e0+f1:c0
|
||||
|
||||
/*
|
||||
* Now shift the result one bit to the left,
|
||||
* taking advantage of [CLMUL-WP] eq 27 (p. 20)
|
||||
* taking advantage of [CLMUL-WP] eq 27 (p. 18)
|
||||
*/
|
||||
"movdqa %%xmm1, %%xmm3 \n\t" // r1:r0
|
||||
"movdqa %%xmm2, %%xmm4 \n\t" // r3:r2
|
||||
"psllq $1, %%xmm1 \n\t" // r1<<1:r0<<1
|
||||
"psllq $1, %%xmm2 \n\t" // r3<<1:r2<<1
|
||||
"psrlq $63, %%xmm3 \n\t" // r1>>63:r0>>63
|
||||
"psrlq $63, %%xmm4 \n\t" // r3>>63:r2>>63
|
||||
"movdqa %%xmm3, %%xmm5 \n\t" // r1>>63:r0>>63
|
||||
"pslldq $8, %%xmm3 \n\t" // r0>>63:0
|
||||
"pslldq $8, %%xmm4 \n\t" // r2>>63:0
|
||||
"psrldq $8, %%xmm5 \n\t" // 0:r1>>63
|
||||
"por %%xmm3, %%xmm1 \n\t" // r1<<1|r0>>63:r0<<1
|
||||
"por %%xmm4, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1
|
||||
"por %%xmm5, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1|r1>>63
|
||||
"movdqa %%xmm1, %%xmm3 \n\t" // r1:r0
|
||||
"movdqa %%xmm2, %%xmm4 \n\t" // r3:r2
|
||||
"psllq $1, %%xmm1 \n\t" // r1<<1:r0<<1
|
||||
"psllq $1, %%xmm2 \n\t" // r3<<1:r2<<1
|
||||
"psrlq $63, %%xmm3 \n\t" // r1>>63:r0>>63
|
||||
"psrlq $63, %%xmm4 \n\t" // r3>>63:r2>>63
|
||||
"movdqa %%xmm3, %%xmm5 \n\t" // r1>>63:r0>>63
|
||||
"pslldq $8, %%xmm3 \n\t" // r0>>63:0
|
||||
"pslldq $8, %%xmm4 \n\t" // r2>>63:0
|
||||
"psrldq $8, %%xmm5 \n\t" // 0:r1>>63
|
||||
"por %%xmm3, %%xmm1 \n\t" // r1<<1|r0>>63:r0<<1
|
||||
"por %%xmm4, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1
|
||||
"por %%xmm5, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1|r1>>63
|
||||
|
||||
/*
|
||||
* Now reduce modulo the GCM polynomial x^128 + x^7 + x^2 + x + 1
|
||||
* using [CLMUL-WP] algorithm 5 (p. 20).
|
||||
* using [CLMUL-WP] algorithm 5 (p. 18).
|
||||
* Currently xmm2:xmm1 holds x3:x2:x1:x0 (already shifted).
|
||||
*/
|
||||
/* Step 2 (1) */
|
||||
"movdqa %%xmm1, %%xmm3 \n\t" // x1:x0
|
||||
"movdqa %%xmm1, %%xmm4 \n\t" // same
|
||||
"movdqa %%xmm1, %%xmm5 \n\t" // same
|
||||
"psllq $63, %%xmm3 \n\t" // x1<<63:x0<<63 = stuff:a
|
||||
"psllq $62, %%xmm4 \n\t" // x1<<62:x0<<62 = stuff:b
|
||||
"psllq $57, %%xmm5 \n\t" // x1<<57:x0<<57 = stuff:c
|
||||
"movdqa %%xmm1, %%xmm3 \n\t" // x1:x0
|
||||
"movdqa %%xmm1, %%xmm4 \n\t" // same
|
||||
"movdqa %%xmm1, %%xmm5 \n\t" // same
|
||||
"psllq $63, %%xmm3 \n\t" // x1<<63:x0<<63 = stuff:a
|
||||
"psllq $62, %%xmm4 \n\t" // x1<<62:x0<<62 = stuff:b
|
||||
"psllq $57, %%xmm5 \n\t" // x1<<57:x0<<57 = stuff:c
|
||||
|
||||
/* Step 2 (2) */
|
||||
"pxor %%xmm4, %%xmm3 \n\t" // stuff:a+b
|
||||
"pxor %%xmm5, %%xmm3 \n\t" // stuff:a+b+c
|
||||
"pslldq $8, %%xmm3 \n\t" // a+b+c:0
|
||||
"pxor %%xmm3, %%xmm1 \n\t" // x1+a+b+c:x0 = d:x0
|
||||
"pxor %%xmm4, %%xmm3 \n\t" // stuff:a+b
|
||||
"pxor %%xmm5, %%xmm3 \n\t" // stuff:a+b+c
|
||||
"pslldq $8, %%xmm3 \n\t" // a+b+c:0
|
||||
"pxor %%xmm3, %%xmm1 \n\t" // x1+a+b+c:x0 = d:x0
|
||||
|
||||
/* Steps 3 and 4 */
|
||||
"movdqa %%xmm1,%%xmm0 \n\t" // d:x0
|
||||
"movdqa %%xmm1,%%xmm4 \n\t" // same
|
||||
"movdqa %%xmm1,%%xmm5 \n\t" // same
|
||||
"psrlq $1, %%xmm0 \n\t" // e1:x0>>1 = e1:e0'
|
||||
"psrlq $2, %%xmm4 \n\t" // f1:x0>>2 = f1:f0'
|
||||
"psrlq $7, %%xmm5 \n\t" // g1:x0>>7 = g1:g0'
|
||||
"pxor %%xmm4, %%xmm0 \n\t" // e1+f1:e0'+f0'
|
||||
"pxor %%xmm5, %%xmm0 \n\t" // e1+f1+g1:e0'+f0'+g0'
|
||||
"movdqa %%xmm1,%%xmm0 \n\t" // d:x0
|
||||
"movdqa %%xmm1,%%xmm4 \n\t" // same
|
||||
"movdqa %%xmm1,%%xmm5 \n\t" // same
|
||||
"psrlq $1, %%xmm0 \n\t" // e1:x0>>1 = e1:e0'
|
||||
"psrlq $2, %%xmm4 \n\t" // f1:x0>>2 = f1:f0'
|
||||
"psrlq $7, %%xmm5 \n\t" // g1:x0>>7 = g1:g0'
|
||||
"pxor %%xmm4, %%xmm0 \n\t" // e1+f1:e0'+f0'
|
||||
"pxor %%xmm5, %%xmm0 \n\t" // e1+f1+g1:e0'+f0'+g0'
|
||||
// e0'+f0'+g0' is almost e0+f0+g0, ex\tcept for some missing
|
||||
// bits carried from d. Now get those\t bits back in.
|
||||
"movdqa %%xmm1,%%xmm3 \n\t" // d:x0
|
||||
"movdqa %%xmm1,%%xmm4 \n\t" // same
|
||||
"movdqa %%xmm1,%%xmm5 \n\t" // same
|
||||
"psllq $63, %%xmm3 \n\t" // d<<63:stuff
|
||||
"psllq $62, %%xmm4 \n\t" // d<<62:stuff
|
||||
"psllq $57, %%xmm5 \n\t" // d<<57:stuff
|
||||
"pxor %%xmm4, %%xmm3 \n\t" // d<<63+d<<62:stuff
|
||||
"pxor %%xmm5, %%xmm3 \n\t" // missing bits of d:stuff
|
||||
"psrldq $8, %%xmm3 \n\t" // 0:missing bits of d
|
||||
"pxor %%xmm3, %%xmm0 \n\t" // e1+f1+g1:e0+f0+g0
|
||||
"pxor %%xmm1, %%xmm0 \n\t" // h1:h0
|
||||
"pxor %%xmm2, %%xmm0 \n\t" // x3+h1:x2+h0
|
||||
"movdqa %%xmm1,%%xmm3 \n\t" // d:x0
|
||||
"movdqa %%xmm1,%%xmm4 \n\t" // same
|
||||
"movdqa %%xmm1,%%xmm5 \n\t" // same
|
||||
"psllq $63, %%xmm3 \n\t" // d<<63:stuff
|
||||
"psllq $62, %%xmm4 \n\t" // d<<62:stuff
|
||||
"psllq $57, %%xmm5 \n\t" // d<<57:stuff
|
||||
"pxor %%xmm4, %%xmm3 \n\t" // d<<63+d<<62:stuff
|
||||
"pxor %%xmm5, %%xmm3 \n\t" // missing bits of d:stuff
|
||||
"psrldq $8, %%xmm3 \n\t" // 0:missing bits of d
|
||||
"pxor %%xmm3, %%xmm0 \n\t" // e1+f1+g1:e0+f0+g0
|
||||
"pxor %%xmm1, %%xmm0 \n\t" // h1:h0
|
||||
"pxor %%xmm2, %%xmm0 \n\t" // x3+h1:x2+h0
|
||||
|
||||
"movdqu %%xmm0, (%2) \n\t" // done
|
||||
"movdqu %%xmm0, (%2) \n\t" // done
|
||||
:
|
||||
: "r" (aa), "r" (bb), "r" (cc)
|
||||
: "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5");
|
||||
@ -255,8 +593,8 @@ void mbedtls_aesni_inverse_key(unsigned char *invkey,
|
||||
|
||||
for (fk -= 16, ik += 16; fk > fwdkey; fk -= 16, ik += 16) {
|
||||
asm ("movdqu (%0), %%xmm0 \n\t"
|
||||
AESIMC xmm0_xmm0 "\n\t"
|
||||
"movdqu %%xmm0, (%1) \n\t"
|
||||
AESIMC(xmm0_xmm0)
|
||||
"movdqu %%xmm0, (%1) \n\t"
|
||||
:
|
||||
: "r" (fk), "r" (ik)
|
||||
: "memory", "xmm0");
|
||||
@ -300,16 +638,16 @@ static void aesni_setkey_enc_128(unsigned char *rk,
|
||||
|
||||
/* Main "loop" */
|
||||
"2: \n\t"
|
||||
AESKEYGENA xmm0_xmm1 ",0x01 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm0_xmm1 ",0x02 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm0_xmm1 ",0x04 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm0_xmm1 ",0x08 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm0_xmm1 ",0x10 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm0_xmm1 ",0x20 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm0_xmm1 ",0x40 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm0_xmm1 ",0x80 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm0_xmm1 ",0x1B \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm0_xmm1 ",0x36 \n\tcall 1b \n\t"
|
||||
AESKEYGENA(xmm0_xmm1, "0x01") "call 1b \n\t"
|
||||
AESKEYGENA(xmm0_xmm1, "0x02") "call 1b \n\t"
|
||||
AESKEYGENA(xmm0_xmm1, "0x04") "call 1b \n\t"
|
||||
AESKEYGENA(xmm0_xmm1, "0x08") "call 1b \n\t"
|
||||
AESKEYGENA(xmm0_xmm1, "0x10") "call 1b \n\t"
|
||||
AESKEYGENA(xmm0_xmm1, "0x20") "call 1b \n\t"
|
||||
AESKEYGENA(xmm0_xmm1, "0x40") "call 1b \n\t"
|
||||
AESKEYGENA(xmm0_xmm1, "0x80") "call 1b \n\t"
|
||||
AESKEYGENA(xmm0_xmm1, "0x1B") "call 1b \n\t"
|
||||
AESKEYGENA(xmm0_xmm1, "0x36") "call 1b \n\t"
|
||||
:
|
||||
: "r" (rk), "r" (key)
|
||||
: "memory", "cc", "0");
|
||||
@ -358,14 +696,14 @@ static void aesni_setkey_enc_192(unsigned char *rk,
|
||||
"ret \n\t"
|
||||
|
||||
"2: \n\t"
|
||||
AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm1_xmm2 ",0x80 \n\tcall 1b \n\t"
|
||||
AESKEYGENA(xmm1_xmm2, "0x01") "call 1b \n\t"
|
||||
AESKEYGENA(xmm1_xmm2, "0x02") "call 1b \n\t"
|
||||
AESKEYGENA(xmm1_xmm2, "0x04") "call 1b \n\t"
|
||||
AESKEYGENA(xmm1_xmm2, "0x08") "call 1b \n\t"
|
||||
AESKEYGENA(xmm1_xmm2, "0x10") "call 1b \n\t"
|
||||
AESKEYGENA(xmm1_xmm2, "0x20") "call 1b \n\t"
|
||||
AESKEYGENA(xmm1_xmm2, "0x40") "call 1b \n\t"
|
||||
AESKEYGENA(xmm1_xmm2, "0x80") "call 1b \n\t"
|
||||
|
||||
:
|
||||
: "r" (rk), "r" (key)
|
||||
@ -408,36 +746,38 @@ static void aesni_setkey_enc_256(unsigned char *rk,
|
||||
|
||||
/* Set xmm2 to stuff:Y:stuff:stuff with Y = subword( r11 )
|
||||
* and proceed to generate next round key from there */
|
||||
AESKEYGENA xmm0_xmm2 ",0x00 \n\t"
|
||||
"pshufd $0xaa, %%xmm2, %%xmm2 \n\t"
|
||||
"pxor %%xmm1, %%xmm2 \n\t"
|
||||
"pslldq $4, %%xmm1 \n\t"
|
||||
"pxor %%xmm1, %%xmm2 \n\t"
|
||||
"pslldq $4, %%xmm1 \n\t"
|
||||
"pxor %%xmm1, %%xmm2 \n\t"
|
||||
"pslldq $4, %%xmm1 \n\t"
|
||||
"pxor %%xmm2, %%xmm1 \n\t"
|
||||
"add $16, %0 \n\t"
|
||||
"movdqu %%xmm1, (%0) \n\t"
|
||||
"ret \n\t"
|
||||
AESKEYGENA(xmm0_xmm2, "0x00")
|
||||
"pshufd $0xaa, %%xmm2, %%xmm2 \n\t"
|
||||
"pxor %%xmm1, %%xmm2 \n\t"
|
||||
"pslldq $4, %%xmm1 \n\t"
|
||||
"pxor %%xmm1, %%xmm2 \n\t"
|
||||
"pslldq $4, %%xmm1 \n\t"
|
||||
"pxor %%xmm1, %%xmm2 \n\t"
|
||||
"pslldq $4, %%xmm1 \n\t"
|
||||
"pxor %%xmm2, %%xmm1 \n\t"
|
||||
"add $16, %0 \n\t"
|
||||
"movdqu %%xmm1, (%0) \n\t"
|
||||
"ret \n\t"
|
||||
|
||||
/*
|
||||
* Main "loop" - Generating one more key than necessary,
|
||||
* see definition of mbedtls_aes_context.buf
|
||||
*/
|
||||
"2: \n\t"
|
||||
AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t"
|
||||
AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t"
|
||||
"2: \n\t"
|
||||
AESKEYGENA(xmm1_xmm2, "0x01") "call 1b \n\t"
|
||||
AESKEYGENA(xmm1_xmm2, "0x02") "call 1b \n\t"
|
||||
AESKEYGENA(xmm1_xmm2, "0x04") "call 1b \n\t"
|
||||
AESKEYGENA(xmm1_xmm2, "0x08") "call 1b \n\t"
|
||||
AESKEYGENA(xmm1_xmm2, "0x10") "call 1b \n\t"
|
||||
AESKEYGENA(xmm1_xmm2, "0x20") "call 1b \n\t"
|
||||
AESKEYGENA(xmm1_xmm2, "0x40") "call 1b \n\t"
|
||||
:
|
||||
: "r" (rk), "r" (key)
|
||||
: "memory", "cc", "0");
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_AESNI_HAVE_CODE */
|
||||
|
||||
/*
|
||||
* Key expansion, wrapper
|
||||
*/
|
||||
@ -455,6 +795,6 @@ int mbedtls_aesni_setkey_enc(unsigned char *rk,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_HAVE_X86_64 */
|
||||
#endif /* MBEDTLS_AESNI_HAVE_CODE */
|
||||
|
||||
#endif /* MBEDTLS_AESNI_C */
|
||||
|
@ -32,13 +32,46 @@
|
||||
#define MBEDTLS_AESNI_AES 0x02000000u
|
||||
#define MBEDTLS_AESNI_CLMUL 0x00000002u
|
||||
|
||||
#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \
|
||||
/* Can we do AESNI with inline assembly?
|
||||
* (Only implemented with gas syntax, only for 64-bit.)
|
||||
*/
|
||||
#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \
|
||||
(defined(__amd64__) || defined(__x86_64__)) && \
|
||||
!defined(MBEDTLS_HAVE_X86_64)
|
||||
#define MBEDTLS_HAVE_X86_64
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_AESNI_C)
|
||||
|
||||
/* Can we do AESNI with intrinsics?
|
||||
* (Only implemented with certain compilers, only for certain targets.)
|
||||
*/
|
||||
#undef MBEDTLS_AESNI_HAVE_INTRINSICS
|
||||
#if defined(_MSC_VER)
|
||||
/* Visual Studio supports AESNI intrinsics since VS 2008 SP1. We only support
|
||||
* VS 2013 and up for other reasons anyway, so no need to check the version. */
|
||||
#define MBEDTLS_AESNI_HAVE_INTRINSICS
|
||||
#endif
|
||||
/* GCC-like compilers: currently, we only support intrinsics if the requisite
|
||||
* target flag is enabled when building the library (e.g. `gcc -mpclmul -msse2`
|
||||
* or `clang -maes -mpclmul`). */
|
||||
#if defined(__GNUC__) && defined(__AES__) && defined(__PCLMUL__)
|
||||
#define MBEDTLS_AESNI_HAVE_INTRINSICS
|
||||
#endif
|
||||
|
||||
/* Choose the implementation of AESNI, if one is available. */
|
||||
#undef MBEDTLS_AESNI_HAVE_CODE
|
||||
/* To minimize disruption when releasing the intrinsics-based implementation,
|
||||
* favor the assembly-based implementation if it's available. We intend to
|
||||
* revise this in a later release of Mbed TLS 3.x. In the long run, we will
|
||||
* likely remove the assembly implementation. */
|
||||
#if defined(MBEDTLS_HAVE_X86_64)
|
||||
#define MBEDTLS_AESNI_HAVE_CODE 1 // via assembly
|
||||
#elif defined(MBEDTLS_AESNI_HAVE_INTRINSICS)
|
||||
#define MBEDTLS_AESNI_HAVE_CODE 2 // via intrinsics
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_AESNI_HAVE_CODE)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -127,6 +160,7 @@ int mbedtls_aesni_setkey_enc(unsigned char *rk,
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_HAVE_X86_64 */
|
||||
#endif /* MBEDTLS_AESNI_HAVE_CODE */
|
||||
#endif /* MBEDTLS_AESNI_C */
|
||||
|
||||
#endif /* MBEDTLS_AESNI_H */
|
||||
|
@ -90,7 +90,7 @@ static int gcm_gen_table(mbedtls_gcm_context *ctx)
|
||||
ctx->HL[8] = vl;
|
||||
ctx->HH[8] = vh;
|
||||
|
||||
#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
|
||||
#if defined(MBEDTLS_AESNI_HAVE_CODE)
|
||||
/* With CLMUL support, we need only h, not the rest of the table */
|
||||
if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
|
||||
return 0;
|
||||
@ -193,7 +193,7 @@ static void gcm_mult(mbedtls_gcm_context *ctx, const unsigned char x[16],
|
||||
unsigned char lo, hi, rem;
|
||||
uint64_t zh, zl;
|
||||
|
||||
#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
|
||||
#if defined(MBEDTLS_AESNI_HAVE_CODE)
|
||||
if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
|
||||
unsigned char h[16];
|
||||
|
||||
@ -206,7 +206,7 @@ static void gcm_mult(mbedtls_gcm_context *ctx, const unsigned char x[16],
|
||||
mbedtls_aesni_gcm_mult(output, x, h);
|
||||
return;
|
||||
}
|
||||
#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
|
||||
#endif /* MBEDTLS_AESNI_HAVE_CODE */
|
||||
|
||||
#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
|
||||
if (mbedtls_aesce_has_support()) {
|
||||
@ -871,6 +871,19 @@ int mbedtls_gcm_self_test(int verbose)
|
||||
mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
|
||||
size_t olen;
|
||||
|
||||
if (verbose != 0) {
|
||||
#if defined(MBEDTLS_GCM_ALT)
|
||||
mbedtls_printf(" GCM note: alternative implementation.\n");
|
||||
#else /* MBEDTLS_GCM_ALT */
|
||||
#if defined(MBEDTLS_AESNI_HAVE_CODE)
|
||||
if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) {
|
||||
mbedtls_printf(" GCM note: using AESNI.\n");
|
||||
} else
|
||||
#endif
|
||||
mbedtls_printf(" GCM note: built-in implementation.\n");
|
||||
#endif /* MBEDTLS_GCM_ALT */
|
||||
}
|
||||
|
||||
for (j = 0; j < 3; j++) {
|
||||
int key_len = 128 + 64 * j;
|
||||
|
||||
|
@ -112,10 +112,9 @@ int psa_generic_status_to_mbedtls(psa_status_t status)
|
||||
|
||||
int psa_status_to_mbedtls(psa_status_t status,
|
||||
const mbedtls_error_pair_t *local_translations,
|
||||
size_t local_errors_size,
|
||||
size_t local_errors_num,
|
||||
int (*fallback_f)(psa_status_t))
|
||||
{
|
||||
size_t local_errors_num = (size_t) local_errors_size / 2;
|
||||
for (size_t i = 0; i < local_errors_num; i++) {
|
||||
if (status == local_translations[i].psa_status) {
|
||||
return local_translations[i].mbedtls_error;
|
||||
|
@ -50,9 +50,9 @@ static const int ciphersuite_preference[] =
|
||||
#else
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
/* TLS 1.3 ciphersuites */
|
||||
MBEDTLS_TLS1_3_AES_128_GCM_SHA256,
|
||||
MBEDTLS_TLS1_3_AES_256_GCM_SHA384,
|
||||
MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256,
|
||||
MBEDTLS_TLS1_3_AES_256_GCM_SHA384,
|
||||
MBEDTLS_TLS1_3_AES_128_GCM_SHA256,
|
||||
MBEDTLS_TLS1_3_AES_128_CCM_SHA256,
|
||||
MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256,
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
@ -258,6 +258,8 @@ static int ssl_tls13_offered_psks_check_identity_match(
|
||||
int *psk_type,
|
||||
mbedtls_ssl_session *session)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
((void) session);
|
||||
((void) obfuscated_ticket_age);
|
||||
*psk_type = MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL;
|
||||
@ -271,9 +273,13 @@ static int ssl_tls13_offered_psks_check_identity_match(
|
||||
session) == SSL_TLS1_3_OFFERED_PSK_MATCH) {
|
||||
ssl->handshake->resume = 1;
|
||||
*psk_type = MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION;
|
||||
mbedtls_ssl_set_hs_psk(ssl,
|
||||
session->resumption_key,
|
||||
session->resumption_key_len);
|
||||
ret = mbedtls_ssl_set_hs_psk(ssl,
|
||||
session->resumption_key,
|
||||
session->resumption_key_len);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_set_hs_psk", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF(4, "Ticket-resumed PSK:",
|
||||
session->resumption_key,
|
||||
@ -299,7 +305,11 @@ static int ssl_tls13_offered_psks_check_identity_match(
|
||||
identity_len == ssl->conf->psk_identity_len &&
|
||||
mbedtls_ct_memcmp(ssl->conf->psk_identity,
|
||||
identity, identity_len) == 0) {
|
||||
mbedtls_ssl_set_hs_psk(ssl, ssl->conf->psk, ssl->conf->psk_len);
|
||||
ret = mbedtls_ssl_set_hs_psk(ssl, ssl->conf->psk, ssl->conf->psk_len);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_set_hs_psk", ret);
|
||||
return ret;
|
||||
}
|
||||
return SSL_TLS1_3_OFFERED_PSK_MATCH;
|
||||
}
|
||||
|
||||
@ -1331,6 +1341,15 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
||||
cipher_suites_len = MBEDTLS_GET_UINT16_BE(p, 0);
|
||||
p += 2;
|
||||
|
||||
/*
|
||||
* The length of the ciphersuite list has to be even.
|
||||
*/
|
||||
if (cipher_suites_len & 1) {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
|
||||
MBEDTLS_ERR_SSL_DECODE_ERROR);
|
||||
return MBEDTLS_ERR_SSL_DECODE_ERROR;
|
||||
}
|
||||
|
||||
/* Check we have enough data for the ciphersuite list, the legacy
|
||||
* compression methods and the length of the extensions.
|
||||
*
|
||||
@ -1360,8 +1379,11 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
||||
uint16_t cipher_suite;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR(p, cipher_suites_end, 2);
|
||||
|
||||
/*
|
||||
* "cipher_suite_end - p is even" is an invariant of the loop. As
|
||||
* cipher_suites_end - p > 0, we have cipher_suites_end - p >= 2 and
|
||||
* it is thus safe to read two bytes.
|
||||
*/
|
||||
cipher_suite = MBEDTLS_GET_UINT16_BE(p, 0);
|
||||
ciphersuite_info = ssl_tls13_validate_peer_ciphersuite(
|
||||
ssl, cipher_suite);
|
||||
@ -1374,6 +1396,7 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
||||
MBEDTLS_SSL_DEBUG_MSG(2, ("selected ciphersuite: %04x - %s",
|
||||
cipher_suite,
|
||||
ciphersuite_info->name));
|
||||
break;
|
||||
}
|
||||
|
||||
if (handshake->ciphersuite_info == NULL) {
|
||||
@ -1381,6 +1404,7 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl,
|
||||
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
|
||||
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
|
||||
}
|
||||
p = cipher_suites_end;
|
||||
|
||||
/* ...
|
||||
* opaque legacy_compression_methods<1..2^8-1>;
|
||||
|
@ -11527,6 +11527,20 @@ run_test "TLS 1.3: Test gnutls tls1_3 feature" \
|
||||
-c "Version: TLS1.3"
|
||||
|
||||
# TLS1.3 test cases
|
||||
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
|
||||
requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
|
||||
requires_ciphersuite_enabled TLS1-3-CHACHA20-POLY1305-SHA256
|
||||
requires_config_enabled MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
run_test "TLS 1.3: Default" \
|
||||
"$P_SRV allow_sha1=0 debug_level=3 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13" \
|
||||
"$P_CLI allow_sha1=0" \
|
||||
0 \
|
||||
-s "Protocol is TLSv1.3" \
|
||||
-s "Ciphersuite is TLS1-3-CHACHA20-POLY1305-SHA256" \
|
||||
-s "ECDH group: x25519" \
|
||||
-s "selected signature algorithm ecdsa_secp256r1_sha256"
|
||||
|
||||
requires_openssl_tls1_3
|
||||
requires_config_enabled MBEDTLS_DEBUG_C
|
||||
requires_config_enabled MBEDTLS_SSL_CLI_C
|
||||
@ -11547,7 +11561,7 @@ run_test "TLS 1.3: minimal feature sets - openssl" \
|
||||
-c "client state: MBEDTLS_SSL_FLUSH_BUFFERS" \
|
||||
-c "client state: MBEDTLS_SSL_HANDSHAKE_WRAPUP" \
|
||||
-c "<= ssl_tls13_process_server_hello" \
|
||||
-c "server hello, chosen ciphersuite: ( 1301 ) - TLS1-3-AES-128-GCM-SHA256" \
|
||||
-c "server hello, chosen ciphersuite: ( 1303 ) - TLS1-3-CHACHA20-POLY1305-SHA256" \
|
||||
-c "ECDH curve: x25519" \
|
||||
-c "=> ssl_tls13_process_server_hello" \
|
||||
-c "<= parse encrypted extensions" \
|
||||
@ -11581,7 +11595,7 @@ run_test "TLS 1.3: minimal feature sets - gnutls" \
|
||||
-c "client state: MBEDTLS_SSL_FLUSH_BUFFERS" \
|
||||
-c "client state: MBEDTLS_SSL_HANDSHAKE_WRAPUP" \
|
||||
-c "<= ssl_tls13_process_server_hello" \
|
||||
-c "server hello, chosen ciphersuite: ( 1301 ) - TLS1-3-AES-128-GCM-SHA256" \
|
||||
-c "server hello, chosen ciphersuite: ( 1303 ) - TLS1-3-CHACHA20-POLY1305-SHA256" \
|
||||
-c "ECDH curve: x25519" \
|
||||
-c "=> ssl_tls13_process_server_hello" \
|
||||
-c "<= parse encrypted extensions" \
|
||||
@ -11614,7 +11628,7 @@ run_test "TLS 1.3: alpn - openssl" \
|
||||
-c "client state: MBEDTLS_SSL_FLUSH_BUFFERS" \
|
||||
-c "client state: MBEDTLS_SSL_HANDSHAKE_WRAPUP" \
|
||||
-c "<= ssl_tls13_process_server_hello" \
|
||||
-c "server hello, chosen ciphersuite: ( 1301 ) - TLS1-3-AES-128-GCM-SHA256" \
|
||||
-c "server hello, chosen ciphersuite: ( 1303 ) - TLS1-3-CHACHA20-POLY1305-SHA256" \
|
||||
-c "ECDH curve: x25519" \
|
||||
-c "=> ssl_tls13_process_server_hello" \
|
||||
-c "<= parse encrypted extensions" \
|
||||
@ -11650,7 +11664,7 @@ run_test "TLS 1.3: alpn - gnutls" \
|
||||
-c "client state: MBEDTLS_SSL_FLUSH_BUFFERS" \
|
||||
-c "client state: MBEDTLS_SSL_HANDSHAKE_WRAPUP" \
|
||||
-c "<= ssl_tls13_process_server_hello" \
|
||||
-c "server hello, chosen ciphersuite: ( 1301 ) - TLS1-3-AES-128-GCM-SHA256" \
|
||||
-c "server hello, chosen ciphersuite: ( 1303 ) - TLS1-3-CHACHA20-POLY1305-SHA256" \
|
||||
-c "ECDH curve: x25519" \
|
||||
-c "=> ssl_tls13_process_server_hello" \
|
||||
-c "<= parse encrypted extensions" \
|
||||
@ -13294,6 +13308,31 @@ run_test "TLS 1.3: NewSessionTicket: Basic check, G->m" \
|
||||
-s "key exchange mode: psk_ephemeral" \
|
||||
-s "found pre_shared_key extension"
|
||||
|
||||
requires_gnutls_tls1_3
|
||||
requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS
|
||||
requires_config_enabled MBEDTLS_SSL_SRV_C
|
||||
requires_config_enabled MBEDTLS_DEBUG_C
|
||||
requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
|
||||
# Test the session resumption when the cipher suite for the original session is
|
||||
# TLS1-3-AES-256-GCM-SHA384. In that case, the PSK is 384 bits long and not
|
||||
# 256 bits long as with all the other TLS 1.3 cipher suites.
|
||||
requires_ciphersuite_enabled TLS1-3-AES-256-GCM-SHA384
|
||||
run_test "TLS 1.3: NewSessionTicket: Basic check with AES-256-GCM only, G->m" \
|
||||
"$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=4" \
|
||||
"$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-256-GCM -V -r" \
|
||||
0 \
|
||||
-c "Connecting again- trying to resume previous session" \
|
||||
-c "NEW SESSION TICKET (4) was received" \
|
||||
-s "Ciphersuite is TLS1-3-AES-256-GCM-SHA384" \
|
||||
-s "=> write NewSessionTicket msg" \
|
||||
-s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \
|
||||
-s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \
|
||||
-s "key exchange mode: ephemeral" \
|
||||
-s "key exchange mode: psk_ephemeral" \
|
||||
-s "found pre_shared_key extension"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS
|
||||
requires_config_enabled MBEDTLS_SSL_SRV_C
|
||||
requires_config_enabled MBEDTLS_SSL_CLI_C
|
||||
|
@ -229,5 +229,11 @@ aes_decrypt_ecb:"000000000000000000000000000000000000000000000000000000000000000
|
||||
AES-256-ECB Decrypt NIST KAT #12
|
||||
aes_decrypt_ecb:"0000000000000000000000000000000000000000000000000000000000000000":"9b80eefb7ebe2d2b16247aa0efc72f5d":"e0000000000000000000000000000000":0
|
||||
|
||||
AES-256-ECB Copy Context NIST KAT #1
|
||||
aes_ecb_copy_context:"c1cc358b449909a19436cfbb3f852ef8bcb5ed12ac7058325f56e6099aab1a1c":"00000000000000000000000000000000"
|
||||
AES-128-ECB Copy context
|
||||
aes_ecb_copy_context:"000102030405060708090a0b0c0d0e0f"
|
||||
|
||||
AES-192-ECB Copy context
|
||||
aes_ecb_copy_context:"000102030405060708090a0b0c0d0e0f1011121314151617"
|
||||
|
||||
AES-256-ECB Copy context
|
||||
aes_ecb_copy_context:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
|
||||
|
@ -1,5 +1,61 @@
|
||||
/* BEGIN_HEADER */
|
||||
#include "mbedtls/aes.h"
|
||||
|
||||
/* Test AES with a copied context.
|
||||
*
|
||||
* master, enc and dec must be AES context objects. They don't need to
|
||||
* be initialized, and are left freed.
|
||||
*/
|
||||
static int test_copy(const data_t *key,
|
||||
mbedtls_aes_context *master,
|
||||
mbedtls_aes_context *enc,
|
||||
mbedtls_aes_context *dec)
|
||||
{
|
||||
unsigned char plaintext[16] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
};
|
||||
unsigned char ciphertext[16];
|
||||
unsigned char output[16];
|
||||
|
||||
// Set key and encrypt with original context
|
||||
mbedtls_aes_init(master);
|
||||
TEST_ASSERT(mbedtls_aes_setkey_enc(master, key->x,
|
||||
key->len * 8) == 0);
|
||||
TEST_ASSERT(mbedtls_aes_crypt_ecb(master, MBEDTLS_AES_ENCRYPT,
|
||||
plaintext, ciphertext) == 0);
|
||||
*enc = *master;
|
||||
|
||||
// Set key for decryption with original context
|
||||
mbedtls_aes_init(master);
|
||||
TEST_ASSERT(mbedtls_aes_setkey_dec(master, key->x,
|
||||
key->len * 8) == 0);
|
||||
*dec = *master;
|
||||
|
||||
// Wipe the original context to make sure nothing from it is used
|
||||
memset(master, 0, sizeof(*master));
|
||||
|
||||
// Encrypt with copied context
|
||||
TEST_ASSERT(mbedtls_aes_crypt_ecb(enc, MBEDTLS_AES_ENCRYPT,
|
||||
plaintext, output) == 0);
|
||||
ASSERT_COMPARE(ciphertext, 16, output, 16);
|
||||
mbedtls_aes_free(enc);
|
||||
|
||||
// Decrypt with copied context
|
||||
TEST_ASSERT(mbedtls_aes_crypt_ecb(dec, MBEDTLS_AES_DECRYPT,
|
||||
ciphertext, output) == 0);
|
||||
ASSERT_COMPARE(plaintext, 16, output, 16);
|
||||
mbedtls_aes_free(dec);
|
||||
|
||||
return 1;
|
||||
|
||||
exit:
|
||||
/* Bug: we may be leaving something unfreed. This is harmless
|
||||
* in our built-in implementations, but might cause a memory leak
|
||||
* with alternative implementations. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* END_HEADER */
|
||||
|
||||
/* BEGIN_DEPENDENCIES
|
||||
@ -468,32 +524,89 @@ void aes_misc_params()
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void aes_ecb_copy_context(data_t *key_str, data_t *src_str)
|
||||
void aes_ecb_copy_context(data_t *key)
|
||||
{
|
||||
unsigned char output1[16], output2[16], plain[16];
|
||||
mbedtls_aes_context ctx1, ctx2, ctx3;
|
||||
/* We test context copying multiple times, with different alignments
|
||||
* of the original and of the copies. */
|
||||
|
||||
// Set key and encrypt with original context
|
||||
mbedtls_aes_init(&ctx1);
|
||||
TEST_ASSERT(mbedtls_aes_setkey_enc(&ctx1, key_str->x,
|
||||
key_str->len * 8) == 0);
|
||||
TEST_ASSERT(mbedtls_aes_crypt_ecb(&ctx1, MBEDTLS_AES_ENCRYPT,
|
||||
src_str->x, output1) == 0);
|
||||
struct align0 {
|
||||
mbedtls_aes_context ctx;
|
||||
};
|
||||
struct align0 *src0 = NULL;
|
||||
struct align0 *enc0 = NULL;
|
||||
struct align0 *dec0 = NULL;
|
||||
|
||||
ctx2 = ctx1;
|
||||
TEST_ASSERT(mbedtls_aes_setkey_dec(&ctx1, key_str->x,
|
||||
key_str->len * 8) == 0);
|
||||
ctx3 = ctx1;
|
||||
memset(&ctx1, 0, sizeof(ctx1));
|
||||
struct align1 {
|
||||
char bump;
|
||||
mbedtls_aes_context ctx;
|
||||
};
|
||||
struct align1 *src1 = NULL;
|
||||
struct align1 *enc1 = NULL;
|
||||
struct align1 *dec1 = NULL;
|
||||
|
||||
// Encrypt and decrypt with copied context
|
||||
TEST_ASSERT(mbedtls_aes_crypt_ecb(&ctx2, MBEDTLS_AES_ENCRYPT,
|
||||
src_str->x, output2) == 0);
|
||||
TEST_ASSERT(mbedtls_aes_crypt_ecb(&ctx3, MBEDTLS_AES_DECRYPT,
|
||||
output1, plain) == 0);
|
||||
/* All peak alignment */
|
||||
ASSERT_ALLOC(src0, 1);
|
||||
ASSERT_ALLOC(enc0, 1);
|
||||
ASSERT_ALLOC(dec0, 1);
|
||||
if (!test_copy(key, &src0->ctx, &enc0->ctx, &dec0->ctx)) {
|
||||
goto exit;
|
||||
}
|
||||
mbedtls_free(src0);
|
||||
src0 = NULL;
|
||||
mbedtls_free(enc0);
|
||||
enc0 = NULL;
|
||||
mbedtls_free(dec0);
|
||||
dec0 = NULL;
|
||||
|
||||
TEST_ASSERT(mbedtls_test_hexcmp(output1, output2, 16, 16) == 0);
|
||||
TEST_ASSERT(mbedtls_test_hexcmp(src_str->x, plain, src_str->len, 16) == 0);
|
||||
/* Original shifted */
|
||||
ASSERT_ALLOC(src1, 1);
|
||||
ASSERT_ALLOC(enc0, 1);
|
||||
ASSERT_ALLOC(dec0, 1);
|
||||
if (!test_copy(key, &src1->ctx, &enc0->ctx, &dec0->ctx)) {
|
||||
goto exit;
|
||||
}
|
||||
mbedtls_free(src1);
|
||||
src1 = NULL;
|
||||
mbedtls_free(enc0);
|
||||
enc0 = NULL;
|
||||
mbedtls_free(dec0);
|
||||
dec0 = NULL;
|
||||
|
||||
/* Copies shifted */
|
||||
ASSERT_ALLOC(src0, 1);
|
||||
ASSERT_ALLOC(enc1, 1);
|
||||
ASSERT_ALLOC(dec1, 1);
|
||||
if (!test_copy(key, &src0->ctx, &enc1->ctx, &dec1->ctx)) {
|
||||
goto exit;
|
||||
}
|
||||
mbedtls_free(src0);
|
||||
src0 = NULL;
|
||||
mbedtls_free(enc1);
|
||||
enc1 = NULL;
|
||||
mbedtls_free(dec1);
|
||||
dec1 = NULL;
|
||||
|
||||
/* Source and copies shifted */
|
||||
ASSERT_ALLOC(src1, 1);
|
||||
ASSERT_ALLOC(enc1, 1);
|
||||
ASSERT_ALLOC(dec1, 1);
|
||||
if (!test_copy(key, &src1->ctx, &enc1->ctx, &dec1->ctx)) {
|
||||
goto exit;
|
||||
}
|
||||
mbedtls_free(src1);
|
||||
src1 = NULL;
|
||||
mbedtls_free(enc1);
|
||||
enc1 = NULL;
|
||||
mbedtls_free(dec1);
|
||||
dec1 = NULL;
|
||||
|
||||
exit:
|
||||
mbedtls_free(src0);
|
||||
mbedtls_free(enc0);
|
||||
mbedtls_free(dec0);
|
||||
mbedtls_free(src1);
|
||||
mbedtls_free(enc1);
|
||||
mbedtls_free(dec1);
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
Check compile time library version
|
||||
check_compiletime_version:"3.3.0"
|
||||
check_compiletime_version:"3.4.0"
|
||||
|
||||
Check runtime library version
|
||||
check_runtime_version:"3.3.0"
|
||||
check_runtime_version:"3.4.0"
|
||||
|
||||
Check for MBEDTLS_VERSION_C
|
||||
check_feature:"MBEDTLS_VERSION_C":0
|
||||
|
Loading…
x
Reference in New Issue
Block a user