diff --git a/BRANCHES.md b/BRANCHES.md index fb2194e1fc..f960e6fa5d 100644 --- a/BRANCHES.md +++ b/BRANCHES.md @@ -11,8 +11,8 @@ At any point in time, we have a number of maintained branches, currently consist as well as all the new features and bug fixes and security fixes. - One or more long-time support (LTS) branches: these only get bug fixes and security fixes. Currently, the supported LTS branches are: -- [`mbedtls-2.28`](https://github.com/Mbed-TLS/mbedtls/tree/mbedtls-2.28). - [`mbedtls-3.6`](https://github.com/Mbed-TLS/mbedtls/tree/mbedtls-3.6). +- [`mbedtls-4.1`](https://github.com/Mbed-TLS/mbedtls/tree/mbedtls-4.1). We retain a number of historical branches, whose names are prefixed by `archive/`, such as [`archive/mbedtls-2.7`](https://github.com/Mbed-TLS/mbedtls/tree/archive/mbedtls-2.7). @@ -24,11 +24,11 @@ the API of 3.(x+1) is backward compatible with 3.x). We only break API compatibility on major version changes (e.g. from 3.x to 4.0). We also maintain ABI compatibility within LTS branches; see the next section for details. -We will make regular LTS releases on an 18-month cycle, each of which will have -a 3 year support lifetime. On this basis, 3.6 LTS (released March 2024) will be -supported until March 2027. The next LTS release will be a 4.x release. Due to -the size and scope of the 4.0 release, the release date of the first 4.x LTS is -yet to be determined. +We plan to make regular LTS releases on an 18-month cycle, each with a support +lifetime of three years.On this basis, Mbed TLS 3.6 LTS (released in March 2024) +will be supported until March 2027. Due to the size and scope of the 4.0 release, +the first 4.x LTS, version 4.1, was released two years after 3.6, in March 2026, +and will be supported until March 2029. ## Backwards Compatibility for application code @@ -108,10 +108,9 @@ The following branches are currently maintained: - [`development`](https://github.com/Mbed-TLS/mbedtls/) - [`mbedtls-3.6`](https://github.com/Mbed-TLS/mbedtls/tree/mbedtls-3.6) maintained until March 2027, see - . - -> Note: [**`mbedtls-2.28.10`**](https://github.com/Mbed-TLS/mbedtls/releases/tag/v2.28.10) -is the last release of the 2.28 LTS and won't receive bug fixes or security fixes anymore. -Users are advised to upgrade to a maintained version. + . +- [`mbedtls-4.1`](https://github.com/Mbed-TLS/mbedtls/tree/mbedtls-4.1) + maintained until March 2029, see + . Users are urged to always use the latest version of a maintained branch. diff --git a/CMakeLists.txt b/CMakeLists.txt index 1600756782..4eb0a60381 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,12 +40,12 @@ cmake_policy(SET CMP0012 NEW) if(TEST_CPP) project("Mbed TLS" LANGUAGES C CXX - VERSION 3.6.5 + VERSION 3.6.6 ) else() project("Mbed TLS" LANGUAGES C - VERSION 3.6.5 + VERSION 3.6.6 ) endif() @@ -501,7 +501,7 @@ if(NOT DISABLE_PACKAGE_CONFIG_AND_INSTALL) write_basic_package_version_file( "cmake/MbedTLSConfigVersion.cmake" COMPATIBILITY SameMajorVersion - VERSION 3.6.5) + VERSION 3.6.6) install( FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfig.cmake" diff --git a/ChangeLog b/ChangeLog index 59a9604394..17f09ac24f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,119 @@ Mbed TLS ChangeLog (Sorted per branch, date) += Mbed TLS 3.6.6 branch released 2026-03-31 + +Features + * The automatic computation of MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE has + been improved to take into account the following key types: + asymmetric keys, ciphers, AEADs, CMAC and HMAC. + * The device for reading entropy on platforms without a dedicated system + call can now be configured with MBEDTLS_PLATFORM_DEV_RANDOM or + mbedtls_platform_dev_random. + * Applications can use the new functions psa_random_reseed() to + request an immediate reseed of the PSA random generator, or + psa_random_deplete() to force a reseed on the next random generator call. + * Applications can call psa_random_set_prediction_resistance() to toggle + prediction resistance in the PSA random generator. + +Security + * The documentation of mbedtls_ssl_session_save(), + mbedtls_ssl_session_load(), mbedtls_ssl_context_save(), and + mbedtls_ssl_context_load() has been updated to clarify the responsibility + of the application to preserve the confidentiality and integrity of + serialized data, mitigating the risk of misuse of these APIs. + Credit to Haruto Kimura (Stella) and Eva Crystal (0xiviel) for + highlighting risks associated with tampered serialized data. + * The default device for reading entropy on platforms without a dedicated + system call is now /dev/random instead of /dev/urandom. This is safer + on Linux in case the application runs early after the kernel boots, + but may block needlessly on Linux <= 5.6. Reported by supers1ngular + (BayLibre). + * Fix missing validation of the peer's key in key agreement operations using + PSA_ALG_FFDH: low-order elements were not rejected as they should be. This + is a problem for protocols using FFDH that expect contributory behaviour, + that is, where neither party should be able to force the shared secret + into a small set. Reported independently by Eva Crystal (0xiviel) and ++ another reporter. + * Add tag length validation in mbedtls_ccm_finish() to prevent + out-of-bounds reads and mitigate potential application buffer + overflows where applications relied on the library to enforce + tag length constraints. + Reported by Eva Crystal (0xiviel). + * Fix a NULL pointer dereference in mbedtls_x509_string_to_names() when + mbedtls_calloc() fails to allocate memory. This was caused by failing to + check whether mbedtls_calloc() returned NULL. Found and reported by + Haruto Kimura (Stella). + * Fix a buffer overflow in psa_export_public_key() for FFDH keys when the + output buffer is too small. Found by Haruto Kimura (Stella). + * Fix a limited buffer underflow in x509_inet_pton_ipv6(). In rare cases + (e.g. on platforms with memory protection when the overread crosses page + boundary) this could lead to DoS. Found and reported by Haruto Kimura + (Stella). CVE-2026-25833 + * If an application called psa_crypto_init() then fork() and continued to + use cryptography APIs (possibly indirectly, e.g. for TLS), the random + generator states were duplicated. Fix this by forcing a RNG reseed in + the child process. CVE-2026-25835 + * Applications running in environments where the application state is + cloned (for example due to resuming a frozen system state multiple + times, or due to cloning a virtual machine image) should arrange to + reseed the random generator using one of the new functions + psa_random_reseed() or psa_random_deplete(). CVE-2026-25835 + * Fix a bug in the TLS 1.2 client's signature algorithm check, which caused + the client to accept server key exchange messages signed with a signature + algorithm explicitly disallowed by the client. Found and reported by + EFR-GmbH and M. Heuft of Security-Research-Consulting GmbH. CVE-2026-25834 + * Fixed an issue in TLS 1.3 server handling of the second ClientHello, after + sending a HelloRetryRequest message. A man-in-the-middle attacker could + force a TLS 1.3 session resumption using a ticket to fall back to an + unintended TLS 1.2 session resumption with an all-zero master secret. + This could result in client authentication being bypassed and allow client + impersonation. + Found and reported by Jaehun Lee, Pohang University of Science and + Technology (POSTECH). + +Bugfix + * Appease GCC 14.3's array bounds checker by inserting checks in mbedtls_xor + that bail before the byte-at-a-time loop when the array size is a constant + (using MBEDTLS_HAS_BUILTIN) and an exact multiple of the larger loop size. + * CMake now installs headers to `CMAKE_INSTALL_INCLUDEDIR` instead of the + hard-coded `include` directory. + * Prevent loading of peristent keys whose key ID belong to the volatile + range. + * Partially fix a performance regression in RSA operations introduced by a + security fix in 3.6.5, by improving the performance of RSA private key + operations when MBEDTLS_RSA_NO_CRT is disabled, which is the default. + * Fix compilation errors in `aesce.c` in some Visual Studio builds. + Fixes Mbed-TLS/TF-PSA-Crypto#548. + * Fix a build failure with MinGW when the __USE_MINGW_ANSI_STDIO option + is set. This was caused by the wrong format specifier being used to + print long long values (MBEDTLS_PRINTF_LONGLONG). + * Fix a bug that caused GCM tag calculations to fail, so that data was + correctly encrypted but could not be authenticated. The bug was only + observed with GCC 10.0 to 14.2 inclusive, when compiling with -O3, and + running without AESNI or AESCE. + Fixes Mbed-TLS/TF-PSA-Crypto#665. + * Fix a build failure with dietlibc. + * Support re-assembly of fragmented DTLS 1.2 ClientHello in Mbed TLS server. + * Support re-assembly of fragmented TLS 1.2 ClientHello in Mbed TLS server + even if TLS 1.3 support is disabled. This removes the main limitation on + support for re-assembly of fragmented handshake messages in TLS 1.2. + * Some functions in PK were using large buffers (around 2KB in the default + configuration) on the stack, which was a problem in environments with a + small stack. Those buffers are now allocated on the heap, except in + configurations where ECC is the only supported key type in PK, making PK + still independent of the heap in such configurations (if the ECC driver + itself is not using the heap). Fixes Mbed-TLS/TF-PSA-Crypto#476. + +Changes + * Add casts to some Enums to remove compiler errors thrown by IAR 6.5. + Removes Warning "mixed ENUM with other type". + * Tweak the detection of Unix-like platforms, which makes more system + interfaces (timing, threading) available on Haiku, QNX and Midipix. + * Harden mbedtls_ssl_get_verify_result() against misuse. + If the handshake has not yet been attempted, return -1u to indicate + that the result is not available. Previously the result of verification + was zero-initialized so the function would return 0 (indicating success). + = Mbed TLS 3.6.5 branch released 2025-10-15 API changes diff --git a/ChangeLog.d/aesce-include.txt b/ChangeLog.d/aesce-include.txt deleted file mode 100644 index bda1188bea..0000000000 --- a/ChangeLog.d/aesce-include.txt +++ /dev/null @@ -1,3 +0,0 @@ -Bugfix - * Fix compilation errors in `aesce.c` in some Visual Studio builds. - Fixes Mbed-TLS/TF-PSA-Crypto#548. diff --git a/ChangeLog.d/context_load_and_session_load_documentation.txt b/ChangeLog.d/context_load_and_session_load_documentation.txt deleted file mode 100644 index dbbbda1fea..0000000000 --- a/ChangeLog.d/context_load_and_session_load_documentation.txt +++ /dev/null @@ -1,8 +0,0 @@ -Security - * The documentation of mbedtls_ssl_session_save(), - mbedtls_ssl_session_load(), mbedtls_ssl_context_save(), and - mbedtls_ssl_context_load() has been updated to clarify the responsibility - of the application to preserve the confidentiality and integrity of - serialized data, mitigating the risk of misuse of these APIs. - Credit to Haruto Kimura (Stella) and Eva Crystal (0xiviel) for - highlighting risks associated with tampered serialized data. diff --git a/ChangeLog.d/dev-random.txt b/ChangeLog.d/dev-random.txt deleted file mode 100644 index eff1352354..0000000000 --- a/ChangeLog.d/dev-random.txt +++ /dev/null @@ -1,11 +0,0 @@ -Features - * The device for reading entropy on platforms without a dedicated system - call can now be configured with MBEDTLS_PLATFORM_DEV_RANDOM or - mbedtls_platform_dev_random. - -Security - * The default device for reading entropy on platforms without a dedicated - system call is now /dev/random instead of /dev/urandom. This is safer - on Linux in case the application runs early after the kernel boots, - but may block needlessly on Linux <= 5.6. Reported by supers1ngular - (BayLibre). diff --git a/ChangeLog.d/dtls-client-hello-defragmentation.txt b/ChangeLog.d/dtls-client-hello-defragmentation.txt deleted file mode 100644 index f5ff0b754c..0000000000 --- a/ChangeLog.d/dtls-client-hello-defragmentation.txt +++ /dev/null @@ -1,5 +0,0 @@ -Bugfix - * Support re-assembly of fragmented DTLS 1.2 ClientHello in Mbed TLS server. - * Support re-assembly of fragmented TLS 1.2 ClientHello in Mbed TLS server - even if TLS 1.3 support is disabled. This removes the main limitation on - support for re-assembly of fragmented handshake messages in TLS 1.2. diff --git a/ChangeLog.d/ffdh-peerkey-check.txt b/ChangeLog.d/ffdh-peerkey-check.txt deleted file mode 100644 index 2c0c9c2fab..0000000000 --- a/ChangeLog.d/ffdh-peerkey-check.txt +++ /dev/null @@ -1,7 +0,0 @@ -Security - * Fix missing validation of the peer's key in key agreement operations using - PSA_ALG_FFDH: low-order elements were not rejected as they should be. This - is a problem for protocols using FFDH that expect contributory behaviour, - that is, where neither party should be able to force the shared secret - into a small set. Reported independently by Eva Crystal (0xiviel) and -+ another reporter. diff --git a/ChangeLog.d/fix-ccm-finish.txt b/ChangeLog.d/fix-ccm-finish.txt deleted file mode 100644 index cee7cc5e06..0000000000 --- a/ChangeLog.d/fix-ccm-finish.txt +++ /dev/null @@ -1,6 +0,0 @@ -Security - * Add tag length validation in mbedtls_ccm_finish() to prevent - out-of-bounds reads and mitigate potential application buffer - overflows where applications relied on the library to enforce - tag length constraints. - Reported by Eva Crystal (0xiviel). diff --git a/ChangeLog.d/fix-mingw-ansi-stdio.txt b/ChangeLog.d/fix-mingw-ansi-stdio.txt deleted file mode 100644 index d9293d95ca..0000000000 --- a/ChangeLog.d/fix-mingw-ansi-stdio.txt +++ /dev/null @@ -1,4 +0,0 @@ -Bugfix - * Fix a build failure with MinGW when the __USE_MINGW_ANSI_STDIO option - is set. This was caused by the wrong format specifier being used to - print long long values (MBEDTLS_PRINTF_LONGLONG). diff --git a/ChangeLog.d/fix-null-pointer-dereference.txt b/ChangeLog.d/fix-null-pointer-dereference.txt deleted file mode 100644 index 1dd7d61905..0000000000 --- a/ChangeLog.d/fix-null-pointer-dereference.txt +++ /dev/null @@ -1,5 +0,0 @@ -Security - * Fix a NULL pointer dereference in mbedtls_x509_string_to_names() when - mbedtls_calloc() fails to allocate memory. This was caused by failing to - check whether mbedtls_calloc() returned NULL. Found and reported by - Haruto Kimura (Stella). diff --git a/ChangeLog.d/fix-psa-ffdh-buffer-overflow.txt b/ChangeLog.d/fix-psa-ffdh-buffer-overflow.txt deleted file mode 100644 index 5a0536575a..0000000000 --- a/ChangeLog.d/fix-psa-ffdh-buffer-overflow.txt +++ /dev/null @@ -1,3 +0,0 @@ -Security - * Fix a buffer overflow in psa_export_public_key() for FFDH keys when the - output buffer is too small. Found by Haruto Kimura (Stella). diff --git a/ChangeLog.d/fix-static-key-slot-buffer-size-computation.txt b/ChangeLog.d/fix-static-key-slot-buffer-size-computation.txt deleted file mode 100644 index bb04efcf2b..0000000000 --- a/ChangeLog.d/fix-static-key-slot-buffer-size-computation.txt +++ /dev/null @@ -1,4 +0,0 @@ -Features - * The automatic computation of MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE has - been improved to take into account the following key types: - asymmetric keys, ciphers, AEADs, CMAC and HMAC. diff --git a/ChangeLog.d/fix-tls12-rsa-pss-sigalgs.txt b/ChangeLog.d/fix-tls12-rsa-pss-sigalgs.txt new file mode 100644 index 0000000000..34296b602e --- /dev/null +++ b/ChangeLog.d/fix-tls12-rsa-pss-sigalgs.txt @@ -0,0 +1,4 @@ +Bugfix + * Fix a TLS 1.2 regression that caused clients to reject valid + ServerKeyExchange signatures using RSA-PSS signature algorithms. + Fixes #10668. diff --git a/ChangeLog.d/gcc-14.3.txt b/ChangeLog.d/gcc-14.3.txt deleted file mode 100644 index b82d67e51c..0000000000 --- a/ChangeLog.d/gcc-14.3.txt +++ /dev/null @@ -1,4 +0,0 @@ -Bugfix - * Appease GCC 14.3's array bounds checker by inserting checks in mbedtls_xor - that bail before the byte-at-a-time loop when the array size is a constant - (using MBEDTLS_HAS_BUILTIN) and an exact multiple of the larger loop size. diff --git a/ChangeLog.d/gnuinstalldirs_include.txt b/ChangeLog.d/gnuinstalldirs_include.txt deleted file mode 100644 index 7e0782d1e1..0000000000 --- a/ChangeLog.d/gnuinstalldirs_include.txt +++ /dev/null @@ -1,3 +0,0 @@ -Bugfix - * CMake now installs headers to `CMAKE_INSTALL_INCLUDEDIR` instead of the - hard-coded `include` directory. diff --git a/ChangeLog.d/iar-6.5fs.txt b/ChangeLog.d/iar-6.5fs.txt deleted file mode 100644 index 63e903b9c3..0000000000 --- a/ChangeLog.d/iar-6.5fs.txt +++ /dev/null @@ -1,3 +0,0 @@ -Changes - * Add casts to some Enums to remove compiler errors thrown by IAR 6.5. - Removes Warning "mixed ENUM with other type". diff --git a/ChangeLog.d/iar-alignment-fix.txt b/ChangeLog.d/iar-alignment-fix.txt new file mode 100644 index 0000000000..dde839f16f --- /dev/null +++ b/ChangeLog.d/iar-alignment-fix.txt @@ -0,0 +1,6 @@ +Bugfix + * Fix a problem in library/alignment.h where the Zephyr Project use + a pre-defined macro '__packed' which collides with the IAR keyword + '__packed', causing the typedefs of unaligned types to remain aligned. + Fixes mbedtls issue #10334 + diff --git a/ChangeLog.d/inet_pton.txt b/ChangeLog.d/inet_pton.txt deleted file mode 100644 index 73b9aa6b19..0000000000 --- a/ChangeLog.d/inet_pton.txt +++ /dev/null @@ -1,5 +0,0 @@ -Security - * Fix a limited buffer underflow in x509_inet_pton_ipv6(). In rare cases - (e.g. on platforms with memory protection when the overread crosses page - boundary) this could lead to DoS. Found and reported by Haruto Kimura - (Stella). CVE-2026-25833 diff --git a/ChangeLog.d/issue488.txt b/ChangeLog.d/issue488.txt deleted file mode 100644 index 77cbe2d5e3..0000000000 --- a/ChangeLog.d/issue488.txt +++ /dev/null @@ -1,3 +0,0 @@ -Bugfix - * Prevent loading of peristent keys whose key ID belong to the volatile - range. diff --git a/ChangeLog.d/issue665.txt b/ChangeLog.d/issue665.txt deleted file mode 100644 index 7d3da9ebce..0000000000 --- a/ChangeLog.d/issue665.txt +++ /dev/null @@ -1,6 +0,0 @@ -Bugfix - * Fix a bug that caused GCM tag calculations to fail, so that data was - correctly encrypted but could not be authenticated. The bug was only - observed with GCC 10.0 to 14.2 inclusive, when compiling with -O3, and - running without AESNI or AESCE. - Fixes #665. diff --git a/ChangeLog.d/pk-large-stack-buffers.txt b/ChangeLog.d/pk-large-stack-buffers.txt deleted file mode 100644 index 78a66a4519..0000000000 --- a/ChangeLog.d/pk-large-stack-buffers.txt +++ /dev/null @@ -1,7 +0,0 @@ -Bugfix - * Some functions in PK were using large buffers (around 2KB in the default - configuration) on the stack, which was a problem in environments with a - small stack. Those buffers are now allocated on the heap, except in - configurations where ECC is the only supported key type in PK, making PK - still independent of the heap in such configurations (if the ECC driver - itself is not using the heap). Fixes #476. diff --git a/ChangeLog.d/rng-cloning.txt b/ChangeLog.d/rng-cloning.txt deleted file mode 100644 index 6f68d26bb8..0000000000 --- a/ChangeLog.d/rng-cloning.txt +++ /dev/null @@ -1,18 +0,0 @@ -Features - * Applications can use the new functions psa_random_reseed() to - request an immediate reseed of the PSA random generator, or - psa_random_deplete() to force a reseed on the next random generator call. - * Applications can call psa_random_set_prediction_resistance() to toggle - prediction resistance in the PSA random generator. - -Security - * If an application called psa_crypto_init() then fork() and continued to - use cryptography APIs (possibly indirectly, e.g. for TLS), the random - generator states were duplicated. Fix this by forcing a RNG reseed in - the child process. CVE-2026-25835 - * Applications running in environments where the application state is - cloned (for example due to resuming a frozen system state multiple - times, or due to cloning a virtual machine image) should arrange to - reseed the random generator using one of the new functions - psa_random_reseed() or psa_random_deplete(). CVE-2026-25835 - diff --git a/ChangeLog.d/rsa-private-perf.txt b/ChangeLog.d/rsa-private-perf.txt deleted file mode 100644 index c7893032c6..0000000000 --- a/ChangeLog.d/rsa-private-perf.txt +++ /dev/null @@ -1,4 +0,0 @@ -Bugfix - * Partially fix a performance regression in RSA operations introduced by a - security fix in 3.6.5, by improving the performance of RSA private key - operations when MBEDTLS_RSA_NO_CRT is disabled, which is the default. diff --git a/ChangeLog.d/security-advice.txt b/ChangeLog.d/security-advice.txt new file mode 100644 index 0000000000..1f7677a882 --- /dev/null +++ b/ChangeLog.d/security-advice.txt @@ -0,0 +1,2 @@ +Security + * Added advice about compiler options in SECURITY.md. diff --git a/ChangeLog.d/sig_algs_check.txt b/ChangeLog.d/sig_algs_check.txt deleted file mode 100644 index b0aed6dfd3..0000000000 --- a/ChangeLog.d/sig_algs_check.txt +++ /dev/null @@ -1,5 +0,0 @@ -Security - * Fix a bug in the TLS 1.2 client's signature algorithm check, which caused - the client to accept server key exchange messages signed with a signature - algorithm explicitly disallowed by the client. Found and reported by - EFR-GmbH and M. Heuft of Security-Research-Consulting GmbH. CVE-2026-25834 diff --git a/ChangeLog.d/tls12-2nd-client-hello.txt b/ChangeLog.d/tls12-2nd-client-hello.txt deleted file mode 100644 index 7513e0b945..0000000000 --- a/ChangeLog.d/tls12-2nd-client-hello.txt +++ /dev/null @@ -1,9 +0,0 @@ -Security - * Fixed an issue in TLS 1.3 server handling of the second ClientHello, after - sending a HelloRetryRequest message. A man-in-the-middle attacker could - force a TLS 1.3 session resumption using a ticket to fall back to an - unintended TLS 1.2 session resumption with an all-zero master secret. - This could result in client authentication being bypassed and allow client - impersonation. - Found and reported by Jaehun Lee, Pohang University of Science and - Technology (POSTECH). diff --git a/ChangeLog.d/unistd.txt b/ChangeLog.d/unistd.txt deleted file mode 100644 index 84afdc315f..0000000000 --- a/ChangeLog.d/unistd.txt +++ /dev/null @@ -1,6 +0,0 @@ -Changes - * Tweak the detection of Unix-like platforms, which makes more system - interfaces (timing, threading) available on Haiku, QNX and Midipix. - -Bugfix - * Fix a build failure with dietlibc. diff --git a/ChangeLog.d/verify-result-default-value.txt b/ChangeLog.d/verify-result-default-value.txt deleted file mode 100644 index 2cf3f0c21b..0000000000 --- a/ChangeLog.d/verify-result-default-value.txt +++ /dev/null @@ -1,5 +0,0 @@ -Changes - * Harden mbedtls_ssl_get_verify_result() against misuse. - If the handshake has not yet been attempted, return -1u to indicate - that the result is not available. Previously the result of verification - was zero-initialized so the function would return 0 (indicating success). diff --git a/SECURITY.md b/SECURITY.md index 114dce6a69..edd0a115c3 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -104,6 +104,12 @@ model, they need to be mitigated by physical countermeasures. ### Caveats +#### Compiler-induced side channels + +Mbed TLS is mostly written in C. We use standard C except with known compilers, so we do not expect compilers to introduce direct vulnerabilities. However, compilers can introduce [timing side channels](#timing-attacks) in code that was intended to be constant-time. Mbed TLS includes countermeasures to try to prevent this. But given the diversity of compilers, compiler options and target platforms, this prevention may not be complete. + +We recommend compiling Mbed TLS with commonly used levels of optimizations, such as `-O2` or `-Os`. We will generally treat exploitable timing side channels as a vulnerability if they appear with a common compiler at a common level of optimization. Higher levels of optimization such as `-O3` or `-Oz` are still likely to be safe but are less scrutinized. We do not recommend using individual options that might introduce data-dependent timing, and we will not try to work around such optimizations if they are not part of a commonly used level. + #### Out-of-scope countermeasures Mbed TLS has evolved organically and a well defined threat model hasn't always diff --git a/docs/architecture/psa-shared-memory.md b/docs/architecture/psa-shared-memory.md index 89f9eede7a..a4eacc3c68 100644 --- a/docs/architecture/psa-shared-memory.md +++ b/docs/architecture/psa-shared-memory.md @@ -682,4 +682,4 @@ To make sure that we can correctly detect functions that access their input/outp Then, we could write a test that uses this function with memory poisoning and ensure that it fails. Since we are expecting a failure due to memory-poisoning, we would run this test separately from the rest of the memory-poisoning testing. -This testing is implemented in `programs/test/metatest.c`, which is a program designed to check that test failures happen correctly. It may be run via the script `tests/scripts/run-metatests.sh`. +This testing is implemented in `programs/test/metatest.c`, which is a program designed to check that test failures happen correctly. It may be run via the script `framework/scripts/run-metatests.sh`. diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h index 4325e09464..f0d2ca8459 100644 --- a/doxygen/input/doc_mainpage.h +++ b/doxygen/input/doc_mainpage.h @@ -10,7 +10,7 @@ */ /** - * @mainpage Mbed TLS v3.6.5 API Documentation + * @mainpage Mbed TLS v3.6.6 API Documentation * * This documentation describes the internal structure of Mbed TLS. It was * automatically generated from specially formatted comment blocks in diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile index 3ed45fd40e..008edd0526 100644 --- a/doxygen/mbedtls.doxyfile +++ b/doxygen/mbedtls.doxyfile @@ -1,4 +1,4 @@ -PROJECT_NAME = "Mbed TLS v3.6.5" +PROJECT_NAME = "Mbed TLS v3.6.6" OUTPUT_DIRECTORY = ../apidoc/ FULL_PATH_NAMES = NO OPTIMIZE_OUTPUT_FOR_C = YES diff --git a/framework b/framework index 3d57272bbc..80a0ea93f0 160000 --- a/framework +++ b/framework @@ -1 +1 @@ -Subproject commit 3d57272bbc67fb576a7737155835d2db700cc469 +Subproject commit 80a0ea93f0215bcd9030734904b4b54fb8306f07 diff --git a/include/mbedtls/build_info.h b/include/mbedtls/build_info.h index 3d867aa1b1..b5e8066b88 100644 --- a/include/mbedtls/build_info.h +++ b/include/mbedtls/build_info.h @@ -26,16 +26,16 @@ */ #define MBEDTLS_VERSION_MAJOR 3 #define MBEDTLS_VERSION_MINOR 6 -#define MBEDTLS_VERSION_PATCH 5 +#define MBEDTLS_VERSION_PATCH 6 /** * The single version number has the following structure: * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x03060500 -#define MBEDTLS_VERSION_STRING "3.6.5" -#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 3.6.5" +#define MBEDTLS_VERSION_NUMBER 0x03060600 +#define MBEDTLS_VERSION_STRING "3.6.6" +#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 3.6.6" /* Macros for build-time platform detection */ diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 2ec0381a49..193593f753 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -314,7 +314,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.6.5 SOVERSION 16) + set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 3.6.6 SOVERSION 16) target_link_libraries(${mbedcrypto_target} PUBLIC ${libs}) if(TARGET ${everest_target}) @@ -326,11 +326,11 @@ if(USE_SHARED_MBEDTLS_LIBRARY) endif() add_library(${mbedx509_target} SHARED ${src_x509}) - set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.6.5 SOVERSION 7) + set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.6.6 SOVERSION 7) target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target}) add_library(${mbedtls_target} SHARED ${src_tls}) - set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.6.5 SOVERSION 21) + set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.6.6 SOVERSION 21) target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target}) if(GEN_FILES) diff --git a/library/alignment.h b/library/alignment.h index d304133382..456629abf1 100644 --- a/library/alignment.h +++ b/library/alignment.h @@ -47,14 +47,31 @@ #pragma language=extended #define MBEDTLS_POP_IAR_LANGUAGE_PRAGMA /* IAR recommend this technique for accessing unaligned data in - * https://www.iar.com/knowledge/support/technical-notes/compiler/accessing-unaligned-data + * https://mypages.iar.com/s/article/Accessing-Unaligned-Data * This results in a single load / store instruction (if unaligned access is supported). * According to that document, this is only supported on certain architectures. */ - #define UINT_UNALIGNED +#define UINT_UNALIGNED + +/* Some products, like Zephyr, defines __packed as a macro for attribute(packed) and + * that does not work with typedefs, so if __packed is defined, undef it for the + * typedefs and restore it afterwards. + */ +#ifdef __packed +#pragma push_macro("__packed") +#undef __packed +#define MBEDTLS_IAR_PACKED_MACRO_USED +#endif + typedef uint16_t __packed mbedtls_uint16_unaligned_t; typedef uint32_t __packed mbedtls_uint32_unaligned_t; typedef uint64_t __packed mbedtls_uint64_unaligned_t; + +#ifdef MBEDTLS_IAR_PACKED_MACRO_USED +#undef MBEDTLS_IAR_PACKED_MACRO_USED +#pragma pop_macro("__packed") +#endif + #elif defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 40504) && \ ((MBEDTLS_GCC_VERSION < 60300) || (!defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS))) /* diff --git a/library/memory_buffer_alloc.c b/library/memory_buffer_alloc.c index 79b0a8b8fa..4ec3535643 100644 --- a/library/memory_buffer_alloc.c +++ b/library/memory_buffer_alloc.c @@ -294,7 +294,9 @@ static void *buffer_alloc_calloc(size_t n, size_t size) } p = ((unsigned char *) cur) + sizeof(memory_header) + len; - new = (memory_header *) p; + /* Double casting is required to prevent compilation warning on Clang-based + * compilers when "-Wcast-align" is used. */ + new = (memory_header *) (void *) p; new->size = cur->size - len - sizeof(memory_header); new->alloc = 0; @@ -375,7 +377,9 @@ static void buffer_alloc_free(void *ptr) } p -= sizeof(memory_header); - hdr = (memory_header *) p; + /* Double casting is required to prevent compilation warning on Clang-based + * compilers when "-Wcast-align" is used. */ + hdr = (memory_header *) (void *) p; if (verify_header(hdr) != 0) { mbedtls_exit(1); @@ -586,7 +590,9 @@ void mbedtls_memory_buffer_alloc_init(unsigned char *buf, size_t len) heap.buf = buf; heap.len = len; - heap.first = (memory_header *) buf; + /* Double casting is required to prevent compilation warning on Clang-based + * compilers when "-Wcast-align" is used. */ + heap.first = (memory_header *) (void *) buf; heap.first->size = len - sizeof(memory_header); heap.first->magic1 = MAGIC1; heap.first->magic2 = MAGIC2; diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 63b16f9284..0dfd71d540 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -6939,7 +6939,9 @@ static int psa_key_derivation_allows_free_form_secret_input( psa_status_t psa_key_derivation_setup(psa_key_derivation_operation_t *operation, psa_algorithm_t alg) { +#if defined(AT_LEAST_ONE_BUILTIN_KDF) psa_status_t status; +#endif if (operation->alg != 0) { return PSA_ERROR_BAD_STATE; @@ -6972,10 +6974,12 @@ psa_status_t psa_key_derivation_setup(psa_key_derivation_operation_t *operation, return PSA_ERROR_INVALID_ARGUMENT; } +#if defined(AT_LEAST_ONE_BUILTIN_KDF) if (status == PSA_SUCCESS) { operation->alg = alg; } return status; +#endif /* AT_LEAST_ONE_BUILTIN_KDF */ } #if defined(BUILTIN_ALG_ANY_HKDF) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 1185b0b283..88aaf85d29 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -2803,8 +2803,14 @@ static int mbedtls_ssl_has_set_hostname_been_called( } #endif -/* Micro-optimization: don't export this function if it isn't needed outside - * of this source file. */ +/* + * Exported for ssl_client.c when SNI is enabled. When SNI is off the only + * in-file caller is get_hostname_for_verification() which is guarded by + * MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED, so compile the function out + * entirely when neither macro is defined. + */ +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) || \ + defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) #if !defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) static #endif @@ -2815,6 +2821,7 @@ const char *mbedtls_ssl_get_hostname_pointer(const mbedtls_ssl_context *ssl) } return ssl->hostname; } +#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION || MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ static void mbedtls_ssl_free_hostname(mbedtls_ssl_context *ssl) { diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index a56e8cd11c..555ce31f9a 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -13,6 +13,7 @@ #include "mbedtls/ssl.h" #include "ssl_client.h" +#include "ssl_debug_helpers.h" #include "ssl_misc.h" #include "debug_internal.h" #include "mbedtls/error.h" @@ -2087,32 +2088,73 @@ static int ssl_parse_signature_algorithm(mbedtls_ssl_context *ssl, { if (mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg(sig_alg, pk_alg, md_alg) != 0) { MBEDTLS_SSL_DEBUG_MSG(1, - ("Server used unsupported value in SigAlg extension 0x%04x", - sig_alg)); + ("Server used unsupported %s signature algorithm", + mbedtls_ssl_sig_alg_to_str(sig_alg))); return MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER; } /* - * mbedtls_ssl_get_pk_sigalg_and_md_alg_from_sig_alg() understands sig_alg code points across - * TLS versions. Make sure that the received sig_alg extension is valid in TLS 1.2. + * mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg() understands + * signature algorithm code points from both TLS 1.2 and TLS 1.3. Make sure + * that the selected signature algorithm is acceptable when TLS 1.2 is + * negotiated. + * + * In TLS 1.2, RSA-PSS signature algorithms (rsa_pss_rsae_*) are not + * defined by RFC 5246. However, RFC 8446 Section 4.2.3 requires that + * implementations which advertise support for RSASSA-PSS must be + * prepared to accept such signatures even when TLS 1.2 is negotiated, + * provided they were offered in the signature_algorithms extension. + * + * Therefore, we allow rsa_pss_rsae_* here if: + * - the implementation supports them, and + * - they were offered in the signature_algorithms extension (checked by + * `mbedtls_ssl_sig_alg_is_offered()` below). + * + * If we were to add full support for rsa_pss_rsae_* signature algorithms + * in TLS 1.2, we should then integrate RSA-PSS into the TLS 1.2 signature + * algorithm support logic (`mbedtls_ssl_tls12_sig_alg_is_supported()`) + * instead of handling it as a special case here. */ if (!mbedtls_ssl_sig_alg_is_supported(ssl, sig_alg)) { - MBEDTLS_SSL_DEBUG_MSG(1, - ("Server used unsupported value in SigAlg extension 0x%04x", - sig_alg)); - return MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER; + switch (sig_alg) { +#if defined(PSA_WANT_ALG_RSA_PSS) +#if defined(PSA_WANT_ALG_SHA_256) + case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256: +#endif +#if defined(PSA_WANT_ALG_SHA_384) + case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384: +#endif +#if defined(PSA_WANT_ALG_SHA_512) + case MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512: +#endif +#if defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA_384) || defined(PSA_WANT_ALG_SHA_512) + MBEDTLS_SSL_DEBUG_MSG(3, + ( + "Accepting TLS 1.2 RSA-PSS signature algorithm %s via compatibility exception", + mbedtls_ssl_sig_alg_to_str(sig_alg))); + break; +#endif +#endif /* PSA_WANT_ALG_RSA_PSS */ + default: + MBEDTLS_SSL_DEBUG_MSG(1, + ("Server used unsupported %s signature algorithm", + mbedtls_ssl_sig_alg_to_str(sig_alg))); + return MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER; + } } /* * Check if the signature algorithm is acceptable */ if (!mbedtls_ssl_sig_alg_is_offered(ssl, sig_alg)) { - MBEDTLS_SSL_DEBUG_MSG(1, ("Server used SigAlg value 0x%04x that was not offered", sig_alg)); + MBEDTLS_SSL_DEBUG_MSG(1, + ("Server used the signature algorithm %s that was not offered", + mbedtls_ssl_sig_alg_to_str(sig_alg))); return MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER; } - MBEDTLS_SSL_DEBUG_MSG(2, ("Server used SignatureAlgorithm %d", sig_alg & 0x00FF)); - MBEDTLS_SSL_DEBUG_MSG(2, ("Server used HashAlgorithm %d", sig_alg >> 8)); + MBEDTLS_SSL_DEBUG_MSG(2, ("Server used the signature algorithm %s", + mbedtls_ssl_sig_alg_to_str(sig_alg))); return 0; } diff --git a/library/x509_crl.c b/library/x509_crl.c index 7901992e20..0f5b5d842c 100644 --- a/library/x509_crl.c +++ b/library/x509_crl.c @@ -583,11 +583,6 @@ int mbedtls_x509_crl_parse_file(mbedtls_x509_crl *chain, const char *path) #endif /* MBEDTLS_FS_IO */ #if !defined(MBEDTLS_X509_REMOVE_INFO) -/* - * Return an informational string about the certificate. - */ -#define BEFORE_COLON 14 -#define BC "14" /* * Return an informational string about the CRL. */ diff --git a/library/x509_crt.c b/library/x509_crt.c index f15aa99d5d..d3aa954894 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -1746,15 +1746,15 @@ static int x509_info_cert_policies(char **buf, size_t *size, /* * Return an informational string about the certificate. */ -#define BEFORE_COLON 18 -#define BC "18" +#define MBEDTLS_BEFORE_COLON 18 +#define MBEDTLS_BEFORE_COLON_STR "18" int mbedtls_x509_crt_info(char *buf, size_t size, const char *prefix, const mbedtls_x509_crt *crt) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t n; char *p; - char key_size_str[BEFORE_COLON]; + char key_size_str[MBEDTLS_BEFORE_COLON]; p = buf; n = size; @@ -1808,13 +1808,13 @@ int mbedtls_x509_crt_info(char *buf, size_t size, const char *prefix, MBEDTLS_X509_SAFE_SNPRINTF; /* Key size */ - if ((ret = mbedtls_x509_key_size_helper(key_size_str, BEFORE_COLON, + if ((ret = mbedtls_x509_key_size_helper(key_size_str, MBEDTLS_BEFORE_COLON, mbedtls_pk_get_name(&crt->pk))) != 0) { return ret; } - ret = mbedtls_snprintf(p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str, - (int) mbedtls_pk_get_bitlen(&crt->pk)); + ret = mbedtls_snprintf(p, n, "\n%s%-" MBEDTLS_BEFORE_COLON_STR "s: %d bits", + prefix, key_size_str, (int) mbedtls_pk_get_bitlen(&crt->pk)); MBEDTLS_X509_SAFE_SNPRINTF; /* diff --git a/library/x509_csr.c b/library/x509_csr.c index 813d64466c..174ca6ffc3 100644 --- a/library/x509_csr.c +++ b/library/x509_csr.c @@ -520,8 +520,8 @@ int mbedtls_x509_csr_parse_file(mbedtls_x509_csr *csr, const char *path) #endif /* MBEDTLS_FS_IO */ #if !defined(MBEDTLS_X509_REMOVE_INFO) -#define BEFORE_COLON 14 -#define BC "14" +#define MBEDTLS_BEFORE_COLON 14 +#define MBEDTLS_BEFORE_COLON_STR "14" /* * Return an informational string about the CSR. */ @@ -531,7 +531,7 @@ int mbedtls_x509_csr_info(char *buf, size_t size, const char *prefix, int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t n; char *p; - char key_size_str[BEFORE_COLON]; + char key_size_str[MBEDTLS_BEFORE_COLON]; p = buf; n = size; @@ -552,13 +552,13 @@ int mbedtls_x509_csr_info(char *buf, size_t size, const char *prefix, csr->sig_opts); MBEDTLS_X509_SAFE_SNPRINTF; - if ((ret = mbedtls_x509_key_size_helper(key_size_str, BEFORE_COLON, + if ((ret = mbedtls_x509_key_size_helper(key_size_str, MBEDTLS_BEFORE_COLON, mbedtls_pk_get_name(&csr->pk))) != 0) { return ret; } - ret = mbedtls_snprintf(p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str, - (int) mbedtls_pk_get_bitlen(&csr->pk)); + ret = mbedtls_snprintf(p, n, "\n%s%-" MBEDTLS_BEFORE_COLON_STR "s: %d bits\n", + prefix, key_size_str, (int) mbedtls_pk_get_bitlen(&csr->pk)); MBEDTLS_X509_SAFE_SNPRINTF; /* diff --git a/scripts/ci.requirements.txt b/scripts/ci.requirements.txt index 2ab7ba98da..7525036441 100644 --- a/scripts/ci.requirements.txt +++ b/scripts/ci.requirements.txt @@ -1,6 +1,7 @@ # Python package requirements for Mbed TLS testing. -r driver.requirements.txt +-r ../framework/scripts/ci.requirements.txt # The dependencies below are only used in scripts that we run on the Linux CI. @@ -16,13 +17,3 @@ pylint == 2.4.4; platform_system == 'Linux' # https://github.com/Mbed-TLS/mbedtls-framework/issues/50 # mypy 0.942 is the version in Ubuntu 22.04. mypy == 0.942; platform_system == 'Linux' - -# At the time of writing, only needed for tests/scripts/audit-validity-dates.py. -# It needs >=35.0.0 for correct operation, and that requires Python >=3.6. -# >=35.0.0 also requires Rust to build from source, which we are forced to do on -# FreeBSD, since PyPI doesn't carry binary wheels for the BSDs. -cryptography >= 35.0.0; platform_system == 'Linux' - -# For building `framework/data_files/server9-bad-saltlen.crt` and check python -# files. -asn1crypto; platform_system == 'Linux' diff --git a/scripts/ecp_comb_table.py b/scripts/ecp_comb_table.py deleted file mode 100755 index 6146e881c9..0000000000 --- a/scripts/ecp_comb_table.py +++ /dev/null @@ -1,237 +0,0 @@ -#!/usr/bin/env python3 -""" -Purpose - -This script dumps comb table of ec curve. When you add a new ec curve, you -can use this script to generate codes to define `_T` in ecp_curves.c -""" - -# Copyright The Mbed TLS Contributors -# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - -import os -import subprocess -import sys -import tempfile - -HOW_TO_ADD_NEW_CURVE = """ -If you are trying to add new curve, you can follow these steps: - -1. Define curve parameters (_p, _gx, etc...) in ecp_curves.c. -2. Add a macro to define _T to NULL following these parameters. -3. Build mbedcrypto -4. Run this script with an argument of new curve -5. Copy the output of this script into ecp_curves.c and replace the macro added - in Step 2 -6. Rebuild and test if everything is ok - -Replace the in the above with the name of the curve you want to add.""" - -CC = os.getenv('CC', 'cc') -MBEDTLS_LIBRARY_PATH = os.getenv('MBEDTLS_LIBRARY_PATH', "library") - -SRC_DUMP_COMB_TABLE = r''' -#include -#include -#include "mbedtls/ecp.h" -#include "mbedtls/error.h" - -static void dump_mpi_initialize( const char *name, const mbedtls_mpi *d ) -{ - uint8_t buf[128] = {0}; - size_t olen; - uint8_t *p; - - olen = mbedtls_mpi_size( d ); - mbedtls_mpi_write_binary_le( d, buf, olen ); - printf("static const mbedtls_mpi_uint %s[] = {\n", name); - for (p = buf; p < buf + olen; p += 8) { - printf( " BYTES_TO_T_UINT_8( 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X ),\n", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7] ); - } - printf("};\n"); -} - -static void dump_T( const mbedtls_ecp_group *grp ) -{ - char name[128]; - - printf( "#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1\n" ); - - for (size_t i = 0; i < grp->T_size; ++i) { - snprintf( name, sizeof(name), "%s_T_%zu_X", CURVE_NAME, i ); - dump_mpi_initialize( name, &grp->T[i].X ); - - snprintf( name, sizeof(name), "%s_T_%zu_Y", CURVE_NAME, i ); - dump_mpi_initialize( name, &grp->T[i].Y ); - } - printf( "static const mbedtls_ecp_point %s_T[%zu] = {\n", CURVE_NAME, grp->T_size ); - size_t olen; - for (size_t i = 0; i < grp->T_size; ++i) { - int z; - if ( mbedtls_mpi_cmp_int(&grp->T[i].Z, 0) == 0 ) { - z = 0; - } else if ( mbedtls_mpi_cmp_int(&grp->T[i].Z, 1) == 0 ) { - z = 1; - } else { - fprintf( stderr, "Unexpected value of Z (i = %d)\n", (int)i ); - exit( 1 ); - } - printf( " ECP_POINT_INIT_XY_Z%d(%s_T_%zu_X, %s_T_%zu_Y),\n", - z, - CURVE_NAME, i, - CURVE_NAME, i - ); - } - printf("};\n#endif\n\n"); -} - -int main() -{ - int rc; - mbedtls_mpi m; - mbedtls_ecp_point R; - mbedtls_ecp_group grp; - - mbedtls_ecp_group_init( &grp ); - rc = mbedtls_ecp_group_load( &grp, CURVE_ID ); - if (rc != 0) { - char buf[100]; - mbedtls_strerror( rc, buf, sizeof(buf) ); - fprintf( stderr, "mbedtls_ecp_group_load: %s (-0x%x)\n", buf, -rc ); - return 1; - } - grp.T = NULL; - mbedtls_ecp_point_init( &R ); - mbedtls_mpi_init( &m); - mbedtls_mpi_lset( &m, 1 ); - rc = mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ); - if ( rc != 0 ) { - char buf[100]; - mbedtls_strerror( rc, buf, sizeof(buf) ); - fprintf( stderr, "mbedtls_ecp_mul: %s (-0x%x)\n", buf, -rc ); - return 1; - } - if ( grp.T == NULL ) { - fprintf( stderr, "grp.T is not generated. Please make sure" - "MBEDTLS_ECP_FIXED_POINT_OPTIM is enabled in mbedtls_config.h\n" ); - return 1; - } - dump_T( &grp ); - return 0; -} -''' - -SRC_DUMP_KNOWN_CURVE = r''' -#include -#include -#include "mbedtls/ecp.h" - -int main() { - const mbedtls_ecp_curve_info *info = mbedtls_ecp_curve_list(); - mbedtls_ecp_group grp; - - mbedtls_ecp_group_init( &grp ); - while ( info->name != NULL ) { - mbedtls_ecp_group_load( &grp, info->grp_id ); - if ( mbedtls_ecp_get_type(&grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ) { - printf( " %s", info->name ); - } - info++; - } - printf( "\n" ); - return 0; -} -''' - - -def join_src_path(*args): - return os.path.normpath(os.path.join(os.path.dirname(__file__), "..", *args)) - - -def run_c_source(src, cflags): - """ - Compile and run C source code - :param src: the c language code to run - :param cflags: additional cflags passing to compiler - :return: - """ - binname = tempfile.mktemp(prefix="mbedtls") - fd, srcname = tempfile.mkstemp(prefix="mbedtls", suffix=".c") - srcfile = os.fdopen(fd, mode="w") - srcfile.write(src) - srcfile.close() - args = [CC, - *cflags, - '-I' + join_src_path("include"), - "-o", binname, - '-L' + MBEDTLS_LIBRARY_PATH, - srcname, - '-lmbedcrypto'] - - p = subprocess.run(args=args, check=False) - if p.returncode != 0: - return False - p = subprocess.run(args=[binname], check=False, env={ - 'LD_LIBRARY_PATH': MBEDTLS_LIBRARY_PATH - }) - if p.returncode != 0: - return False - os.unlink(srcname) - os.unlink(binname) - return True - - -def compute_curve(curve): - """compute comb table for curve""" - r = run_c_source( - SRC_DUMP_COMB_TABLE, - [ - '-g', - '-DCURVE_ID=MBEDTLS_ECP_DP_%s' % curve.upper(), - '-DCURVE_NAME="%s"' % curve.lower(), - ]) - if not r: - print("""\ -Unable to compile and run utility.""", file=sys.stderr) - sys.exit(1) - - -def usage(): - print(""" -Usage: python %s ... - -Arguments: - curve Specify one or more curve names (e.g secp256r1) - -All possible curves: """ % sys.argv[0]) - run_c_source(SRC_DUMP_KNOWN_CURVE, []) - print(""" -Environment Variable: - CC Specify which c compile to use to compile utility. - MBEDTLS_LIBRARY_PATH - Specify the path to mbedcrypto library. (e.g. build/library/) - -How to add a new curve: %s""" % HOW_TO_ADD_NEW_CURVE) - - -def run_main(): - shared_lib_path = os.path.normpath(os.path.join(MBEDTLS_LIBRARY_PATH, "libmbedcrypto.so")) - static_lib_path = os.path.normpath(os.path.join(MBEDTLS_LIBRARY_PATH, "libmbedcrypto.a")) - if not os.path.exists(shared_lib_path) and not os.path.exists(static_lib_path): - print("Warning: both '%s' and '%s' are not exists. This script will use " - "the library from your system instead of the library compiled by " - "this source directory.\n" - "You can specify library path using environment variable " - "'MBEDTLS_LIBRARY_PATH'." % (shared_lib_path, static_lib_path), - file=sys.stderr) - - if len(sys.argv) <= 1: - usage() - else: - for curve in sys.argv[1:]: - compute_curve(curve) - - -if __name__ == '__main__': - run_main() diff --git a/scripts/maintainer/maintainer_scripts_path.py b/scripts/maintainer/maintainer_scripts_path.py new file mode 100644 index 0000000000..0ea13110cc --- /dev/null +++ b/scripts/maintainer/maintainer_scripts_path.py @@ -0,0 +1,20 @@ +"""Add our Python library directories for maintainer scripts to the module search path. + +Usage: + + import maintainer_scripts_path # pylint: disable=unused-import +""" + +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +# + +import os +import sys + +sys.path.append(os.path.join(os.path.dirname(__file__), + os.path.pardir, os.path.pardir, + 'framework', 'scripts')) +sys.path.append(os.path.join(os.path.dirname(__file__), + os.path.pardir, os.path.pardir, + 'framework', 'util')) diff --git a/scripts/massif_max.pl b/scripts/massif_max.pl deleted file mode 100755 index 52ca606b52..0000000000 --- a/scripts/massif_max.pl +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env perl - -# Parse a massif.out.xxx file and output peak total memory usage -# -# Copyright The Mbed TLS Contributors -# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - -use warnings; -use strict; - -use utf8; -use open qw(:std utf8); - -die unless @ARGV == 1; - -my @snaps; -open my $fh, '<', $ARGV[0] or die; -{ local $/ = 'snapshot='; @snaps = <$fh>; } -close $fh or die; - -my ($max, $max_heap, $max_he, $max_stack) = (0, 0, 0, 0); -for (@snaps) -{ - my ($heap, $heap_extra, $stack) = m{ - mem_heap_B=(\d+)\n - mem_heap_extra_B=(\d+)\n - mem_stacks_B=(\d+) - }xm; - next unless defined $heap; - my $total = $heap + $heap_extra + $stack; - if( $total > $max ) { - ($max, $max_heap, $max_he, $max_stack) = ($total, $heap, $heap_extra, $stack); - } -} - -printf "$max (heap $max_heap+$max_he, stack $max_stack)\n"; diff --git a/scripts/memory.sh b/scripts/memory.sh index d119374d54..71cf597ad8 100755 --- a/scripts/memory.sh +++ b/scripts/memory.sh @@ -90,7 +90,7 @@ do_config() kill $SRV_PID wait $SRV_PID - scripts/massif_max.pl massif.out.* + framework/scripts/massif_max.pl massif.out.* mv massif.out.* massif-$NAME.$$ } diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py index f6921d5238..9bf01248ae 100755 --- a/tests/scripts/analyze_outcomes.py +++ b/tests/scripts/analyze_outcomes.py @@ -33,7 +33,7 @@ class CoverageTask(outcome_analysis.CoverageTask): r'.*\b(?:' + r'|'.join(words) + r')\b.*', re.DOTALL) - IGNORED_TESTS = { + UNCOVERED_TESTS = { 'ssl-opt': [ # We don't run ssl-opt.sh with Valgrind on the CI because # it's extremely slow. We don't intend to change this. diff --git a/tests/scripts/audit-validity-dates.py b/tests/scripts/audit-validity-dates.py deleted file mode 100755 index 3d0924602c..0000000000 --- a/tests/scripts/audit-validity-dates.py +++ /dev/null @@ -1,469 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright The Mbed TLS Contributors -# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - -"""Audit validity date of X509 crt/crl/csr. - -This script is used to audit the validity date of crt/crl/csr used for testing. -It prints the information about X.509 objects excluding the objects that -are valid throughout the desired validity period. The data are collected -from framework/data_files/ and tests/suites/*.data files by default. -""" - -import os -import re -import typing -import argparse -import datetime -import glob -import logging -import hashlib -from enum import Enum - -# The script requires cryptography >= 35.0.0 which is only available -# for Python >= 3.6. -import cryptography -from cryptography import x509 - -from generate_test_code import FileWrapper - -import scripts_path # pylint: disable=unused-import -from mbedtls_framework import build_tree -from mbedtls_framework import logging_util - -def check_cryptography_version(): - match = re.match(r'^[0-9]+', cryptography.__version__) - if match is None or int(match.group(0)) < 35: - raise Exception("audit-validity-dates requires cryptography >= 35.0.0" - + "({} is too old)".format(cryptography.__version__)) - -class DataType(Enum): - CRT = 1 # Certificate - CRL = 2 # Certificate Revocation List - CSR = 3 # Certificate Signing Request - - -class DataFormat(Enum): - PEM = 1 # Privacy-Enhanced Mail - DER = 2 # Distinguished Encoding Rules - - -class AuditData: - """Store data location, type and validity period of X.509 objects.""" - #pylint: disable=too-few-public-methods - def __init__(self, data_type: DataType, x509_obj): - self.data_type = data_type - # the locations that the x509 object could be found - self.locations = [] # type: typing.List[str] - self.fill_validity_duration(x509_obj) - self._obj = x509_obj - encoding = cryptography.hazmat.primitives.serialization.Encoding.DER - self._identifier = hashlib.sha1(self._obj.public_bytes(encoding)).hexdigest() - - @property - def identifier(self): - """ - Identifier of the underlying X.509 object, which is consistent across - different runs. - """ - return self._identifier - - def fill_validity_duration(self, x509_obj): - """Read validity period from an X.509 object.""" - # Certificate expires after "not_valid_after" - # Certificate is invalid before "not_valid_before" - if self.data_type == DataType.CRT: - self.not_valid_after = x509_obj.not_valid_after - self.not_valid_before = x509_obj.not_valid_before - # CertificateRevocationList expires after "next_update" - # CertificateRevocationList is invalid before "last_update" - elif self.data_type == DataType.CRL: - self.not_valid_after = x509_obj.next_update - self.not_valid_before = x509_obj.last_update - # CertificateSigningRequest is always valid. - elif self.data_type == DataType.CSR: - self.not_valid_after = datetime.datetime.max - self.not_valid_before = datetime.datetime.min - else: - raise ValueError("Unsupported file_type: {}".format(self.data_type)) - - -class X509Parser: - """A parser class to parse crt/crl/csr file or data in PEM/DER format.""" - PEM_REGEX = br'-{5}BEGIN (?P.*?)-{5}(?P.*?)-{5}END (?P=type)-{5}' - PEM_TAG_REGEX = br'-{5}BEGIN (?P.*?)-{5}\n' - PEM_TAGS = { - DataType.CRT: 'CERTIFICATE', - DataType.CRL: 'X509 CRL', - DataType.CSR: 'CERTIFICATE REQUEST' - } - - def __init__(self, - backends: - typing.Dict[DataType, - typing.Dict[DataFormat, - typing.Callable[[bytes], object]]]) \ - -> None: - self.backends = backends - self.__generate_parsers() - - def __generate_parser(self, data_type: DataType): - """Parser generator for a specific DataType""" - tag = self.PEM_TAGS[data_type] - pem_loader = self.backends[data_type][DataFormat.PEM] - der_loader = self.backends[data_type][DataFormat.DER] - def wrapper(data: bytes): - pem_type = X509Parser.pem_data_type(data) - # It is in PEM format with target tag - if pem_type == tag: - return pem_loader(data) - # It is in PEM format without target tag - if pem_type: - return None - # It might be in DER format - try: - result = der_loader(data) - except ValueError: - result = None - return result - wrapper.__name__ = "{}.parser[{}]".format(type(self).__name__, tag) - return wrapper - - def __generate_parsers(self): - """Generate parsers for all support DataType""" - self.parsers = {} - for data_type, _ in self.PEM_TAGS.items(): - self.parsers[data_type] = self.__generate_parser(data_type) - - def __getitem__(self, item): - return self.parsers[item] - - @staticmethod - def pem_data_type(data: bytes) -> typing.Optional[str]: - """Get the tag from the data in PEM format - - :param data: data to be checked in binary mode. - :return: PEM tag or "" when no tag detected. - """ - m = re.search(X509Parser.PEM_TAG_REGEX, data) - if m is not None: - return m.group('type').decode('UTF-8') - else: - return None - - @staticmethod - def check_hex_string(hex_str: str) -> bool: - """Check if the hex string is possibly DER data.""" - hex_len = len(hex_str) - # At least 6 hex char for 3 bytes: Type + Length + Content - if hex_len < 6: - return False - # Check if Type (1 byte) is SEQUENCE. - if hex_str[0:2] != '30': - return False - # Check LENGTH (1 byte) value - content_len = int(hex_str[2:4], base=16) - consumed = 4 - if content_len in (128, 255): - # Indefinite or Reserved - return False - elif content_len > 127: - # Definite, Long - length_len = (content_len - 128) * 2 - content_len = int(hex_str[consumed:consumed+length_len], base=16) - consumed += length_len - # Check LENGTH - if hex_len != content_len * 2 + consumed: - return False - return True - - -class Auditor: - """ - A base class that uses X509Parser to parse files to a list of AuditData. - - A subclass must implement the following methods: - - collect_default_files: Return a list of file names that are defaultly - used for parsing (auditing). The list will be stored in - Auditor.default_files. - - parse_file: Method that parses a single file to a list of AuditData. - - A subclass may override the following methods: - - parse_bytes: Defaultly, it parses `bytes` that contains only one valid - X.509 data(DER/PEM format) to an X.509 object. - - walk_all: Defaultly, it iterates over all the files in the provided - file name list, calls `parse_file` for each file and stores the results - by extending the `results` passed to the function. - """ - def __init__(self, logger): - self.logger = logger - self.default_files = self.collect_default_files() - self.parser = X509Parser({ - DataType.CRT: { - DataFormat.PEM: x509.load_pem_x509_certificate, - DataFormat.DER: x509.load_der_x509_certificate - }, - DataType.CRL: { - DataFormat.PEM: x509.load_pem_x509_crl, - DataFormat.DER: x509.load_der_x509_crl - }, - DataType.CSR: { - DataFormat.PEM: x509.load_pem_x509_csr, - DataFormat.DER: x509.load_der_x509_csr - }, - }) - - def collect_default_files(self) -> typing.List[str]: - """Collect the default files for parsing.""" - raise NotImplementedError - - def parse_file(self, filename: str) -> typing.List[AuditData]: - """ - Parse a list of AuditData from file. - - :param filename: name of the file to parse. - :return list of AuditData parsed from the file. - """ - raise NotImplementedError - - def parse_bytes(self, data: bytes): - """Parse AuditData from bytes.""" - for data_type in list(DataType): - try: - result = self.parser[data_type](data) - except ValueError as val_error: - result = None - self.logger.warning(val_error) - if result is not None: - audit_data = AuditData(data_type, result) - return audit_data - return None - - def walk_all(self, - results: typing.Dict[str, AuditData], - file_list: typing.Optional[typing.List[str]] = None) \ - -> None: - """ - Iterate over all the files in the list and get audit data. The - results will be written to `results` passed to this function. - - :param results: The dictionary used to store the parsed - AuditData. The keys of this dictionary should - be the identifier of the AuditData. - """ - if file_list is None: - file_list = self.default_files - for filename in file_list: - data_list = self.parse_file(filename) - for d in data_list: - if d.identifier in results: - results[d.identifier].locations.extend(d.locations) - else: - results[d.identifier] = d - - @staticmethod - def find_test_dir(): - """Get the relative path for the Mbed TLS test directory.""" - return os.path.relpath(build_tree.guess_mbedtls_root() + '/tests') - - -class TestDataAuditor(Auditor): - """Class for auditing files in `framework/data_files/`""" - - def collect_default_files(self): - """Collect all files in `framework/data_files/`""" - test_data_glob = os.path.join(build_tree.guess_mbedtls_root(), - 'framework', 'data_files/**') - data_files = [f for f in glob.glob(test_data_glob, recursive=True) - if os.path.isfile(f)] - return data_files - - def parse_file(self, filename: str) -> typing.List[AuditData]: - """ - Parse a list of AuditData from data file. - - :param filename: name of the file to parse. - :return list of AuditData parsed from the file. - """ - with open(filename, 'rb') as f: - data = f.read() - - results = [] - # Try to parse all PEM blocks. - is_pem = False - for idx, m in enumerate(re.finditer(X509Parser.PEM_REGEX, data, flags=re.S), 1): - is_pem = True - result = self.parse_bytes(data[m.start():m.end()]) - if result is not None: - result.locations.append("{}#{}".format(filename, idx)) - results.append(result) - - # Might be DER format. - if not is_pem: - result = self.parse_bytes(data) - if result is not None: - result.locations.append("{}".format(filename)) - results.append(result) - - return results - - -def parse_suite_data(data_f): - """ - Parses .data file for test arguments that possiblly have a - valid X.509 data. If you need a more precise parser, please - use generate_test_code.parse_test_data instead. - - :param data_f: file object of the data file. - :return: Generator that yields test function argument list. - """ - for line in data_f: - line = line.strip() - # Skip comments - if line.startswith('#'): - continue - - # Check parameters line - match = re.search(r'\A\w+(.*:)?\"', line) - if match: - # Read test vectors - parts = re.split(r'(?[0-9a-fA-F]+)"', test_arg) - if not match: - continue - if not X509Parser.check_hex_string(match.group('data')): - continue - audit_data = self.parse_bytes(bytes.fromhex(match.group('data'))) - if audit_data is None: - continue - audit_data.locations.append("{}:{}:#{}".format(filename, - data_f.line_no, - idx + 1)) - audit_data_list.append(audit_data) - - return audit_data_list - - -def list_all(audit_data: AuditData): - for loc in audit_data.locations: - print("{}\t{:20}\t{:20}\t{:3}\t{}".format( - audit_data.identifier, - audit_data.not_valid_before.isoformat(timespec='seconds'), - audit_data.not_valid_after.isoformat(timespec='seconds'), - audit_data.data_type.name, - loc)) - - -def main(): - """ - Perform argument parsing. - """ - parser = argparse.ArgumentParser(description=__doc__) - - parser.add_argument('-a', '--all', - action='store_true', - help='list the information of all the files') - parser.add_argument('-v', '--verbose', - action='store_true', dest='verbose', - help='show logs') - parser.add_argument('--from', dest='start_date', - help=('Start of desired validity period (UTC, YYYY-MM-DD). ' - 'Default: today'), - metavar='DATE') - parser.add_argument('--to', dest='end_date', - help=('End of desired validity period (UTC, YYYY-MM-DD). ' - 'Default: --from'), - metavar='DATE') - parser.add_argument('--data-files', action='append', nargs='*', - help='data files to audit', - metavar='FILE') - parser.add_argument('--suite-data-files', action='append', nargs='*', - help='suite data files to audit', - metavar='FILE') - - args = parser.parse_args() - - # start main routine - # setup logger - logger = logging.getLogger() - logging_util.configure_logger(logger) - logger.setLevel(logging.DEBUG if args.verbose else logging.ERROR) - - td_auditor = TestDataAuditor(logger) - sd_auditor = SuiteDataAuditor(logger) - - data_files = [] - suite_data_files = [] - if args.data_files is None and args.suite_data_files is None: - data_files = td_auditor.default_files - suite_data_files = sd_auditor.default_files - else: - if args.data_files is not None: - data_files = [x for l in args.data_files for x in l] - if args.suite_data_files is not None: - suite_data_files = [x for l in args.suite_data_files for x in l] - - # validity period start date - if args.start_date: - start_date = datetime.datetime.fromisoformat(args.start_date) - else: - start_date = datetime.datetime.today() - # validity period end date - if args.end_date: - end_date = datetime.datetime.fromisoformat(args.end_date) - else: - end_date = start_date - - # go through all the files - audit_results = {} - td_auditor.walk_all(audit_results, data_files) - sd_auditor.walk_all(audit_results, suite_data_files) - - logger.info("Total: {} objects found!".format(len(audit_results))) - - # we filter out the files whose validity duration covers the provided - # duration. - filter_func = lambda d: (start_date < d.not_valid_before) or \ - (d.not_valid_after < end_date) - - sortby_end = lambda d: d.not_valid_after - - if args.all: - filter_func = None - - # filter and output the results - for d in sorted(filter(filter_func, audit_results.values()), key=sortby_end): - list_all(d) - - logger.debug("Done!") - -check_cryptography_version() -if __name__ == "__main__": - main() diff --git a/tests/scripts/components-build-system.sh b/tests/scripts/components-build-system.sh index c6f29d6ec1..0cdc51a625 100644 --- a/tests/scripts/components-build-system.sh +++ b/tests/scripts/components-build-system.sh @@ -203,6 +203,60 @@ support_test_cmake_as_package_install () { support_test_cmake_out_of_source } +component_test_cmake_install_with_destdir () { + # Remove existing generated files so that we use the ones CMake + # generates + $MAKE_COMMAND neat + + msg "install: cmake with DESTDIR staging" + MBEDTLS_ROOT_DIR="$PWD" + mkdir "$OUT_OF_SOURCE_DIR" + cd "$OUT_OF_SOURCE_DIR" + cmake -DGEN_FILES=ON -DENABLE_PROGRAMS=OFF -DENABLE_TESTING=OFF -DUSE_SHARED_MBEDTLS_LIBRARY=ON -DCMAKE_INSTALL_PREFIX:PATH=/usr "$MBEDTLS_ROOT_DIR" + make + + DESTDIR="$OUT_OF_SOURCE_DIR/stage" make install + + install_lib_subdir="$(sed -n 's/^CMAKE_INSTALL_LIBDIR:PATH=//p' CMakeCache.txt)" + [ -n "$install_lib_subdir" ] # Failed to read CMAKE_INSTALL_LIBDIR from CMakeCache.txt + + install_lib_path="$OUT_OF_SOURCE_DIR/stage/usr/${install_lib_subdir}" + + if [[ "$OSTYPE" == darwin* ]]; then + # On macOS the custom install logic installs libmbedcrypto.dylib + # directly without a versioned symlink chain. + for lib in mbedcrypto mbedx509 mbedtls; do + [ -f "$install_lib_path/lib${lib}.a" ] + [ -e "$install_lib_path/lib${lib}.dylib" ] + done + else + # library/CMakeLists.txt installs libmbedcrypto.so with a versioned + # symlink chain on Linux. + for lib in mbedcrypto mbedx509 mbedtls; do + if [ "$QUIET" -eq 0 ]; then + echo "Checking lib=$lib" + fi + [ -f "$install_lib_path/lib${lib}.a" ] + [ -L "$install_lib_path/lib${lib}.so" ] + [ -e "$install_lib_path/lib${lib}.so" ] + + # Match ABI-version names such as libxxx.so.17 + # and check that symlink. + versioned=( "$install_lib_path/lib${lib}.so".+([0-9]) ) + if [ "$QUIET" -eq 0 ]; then + declare -p versioned + fi + [ "${#versioned[@]}" -eq 1 ] + [ -L "${versioned[0]}" ] + [ -e "${versioned[0]}" ] + done + fi +} + +support_test_cmake_install_with_destdir () { + support_test_cmake_out_of_source +} + component_build_cmake_custom_config_file () { # Make a copy of config file to use for the in-tree test cp "$CONFIG_H" include/mbedtls_config_in_tree_copy.h diff --git a/tests/scripts/components-configuration-crypto.sh b/tests/scripts/components-configuration-crypto.sh index 47dd20450e..d013de85d5 100644 --- a/tests/scripts/components-configuration-crypto.sh +++ b/tests/scripts/components-configuration-crypto.sh @@ -792,7 +792,7 @@ component_test_everest () { make test msg "test: metatests (clang, ASan)" - tests/scripts/run-metatests.sh any asan poison + framework/scripts/run-metatests.sh any asan poison msg "test: Everest ECDH context - ECDH-related part of ssl-opt.sh (ASan build)" # ~ 5s tests/ssl-opt.sh -f ECDH diff --git a/tests/scripts/components-configuration.sh b/tests/scripts/components-configuration.sh index db9b5740e4..f9904f6b0f 100644 --- a/tests/scripts/components-configuration.sh +++ b/tests/scripts/components-configuration.sh @@ -22,7 +22,7 @@ component_test_default_out_of_box () { programs/test/selftest msg "program demos: make, default config (out-of-box)" # ~10s - tests/scripts/run_demos.py + framework/scripts/run_demos.py } component_test_default_cmake_gcc_asan () { @@ -34,13 +34,13 @@ component_test_default_cmake_gcc_asan () { make test msg "program demos (ASan build)" # ~10s - tests/scripts/run_demos.py + framework/scripts/run_demos.py msg "test: selftest (ASan build)" # ~ 10s programs/test/selftest msg "test: metatests (GCC, ASan build)" - tests/scripts/run-metatests.sh any asan poison + framework/scripts/run-metatests.sh any asan poison msg "test: ssl-opt.sh (ASan build)" # ~ 1 min tests/ssl-opt.sh @@ -142,10 +142,10 @@ component_test_full_cmake_clang () { programs/test/cpp_dummy_build msg "test: metatests (clang)" - tests/scripts/run-metatests.sh any pthread + framework/scripts/run-metatests.sh any pthread msg "program demos (full config, clang)" # ~10s - tests/scripts/run_demos.py + framework/scripts/run_demos.py msg "test: psa_constant_names (full config, clang)" # ~ 1s $FRAMEWORK/scripts/test_psa_constant_names.py @@ -216,7 +216,7 @@ component_test_full_deprecated_warning () { make test msg "program demos: full config + MBEDTLS_TEST_DEPRECATED" # ~10s - tests/scripts/run_demos.py + framework/scripts/run_demos.py } component_build_baremetal () { diff --git a/tests/scripts/components-platform.sh b/tests/scripts/components-platform.sh index a9f108fe47..77c216fd67 100644 --- a/tests/scripts/components-platform.sh +++ b/tests/scripts/components-platform.sh @@ -353,7 +353,7 @@ component_test_arm_linux_gnueabi_gcc_arm5vte () { programs/test/selftest msg "program demos: make, default config (out-of-box)" # ~0s - tests/scripts/run_demos.py + framework/scripts/run_demos.py } support_test_arm_linux_gnueabi_gcc_arm5vte () { @@ -373,7 +373,7 @@ component_test_arm_linux_gnueabi_gcc_thumb_1_opt_0 () { programs/test/selftest msg "program demos: make, default config (out-of-box)" # ~0s - tests/scripts/run_demos.py + framework/scripts/run_demos.py } support_test_arm_linux_gnueabi_gcc_thumb_1_opt_0 () { @@ -391,7 +391,7 @@ component_test_arm_linux_gnueabi_gcc_thumb_1_opt_s () { programs/test/selftest msg "program demos: make, default config (out-of-box)" # ~0s - tests/scripts/run_demos.py + framework/scripts/run_demos.py } support_test_arm_linux_gnueabi_gcc_thumb_1_opt_s () { @@ -409,7 +409,7 @@ component_test_arm_linux_gnueabihf_gcc_armv7 () { programs/test/selftest msg "program demos: make, default config (out-of-box)" # ~0s - tests/scripts/run_demos.py + framework/scripts/run_demos.py } support_test_arm_linux_gnueabihf_gcc_armv7 () { @@ -427,7 +427,7 @@ component_test_arm_linux_gnueabihf_gcc_thumb_2 () { programs/test/selftest msg "program demos: make, default config (out-of-box)" # ~0s - tests/scripts/run_demos.py + framework/scripts/run_demos.py } support_test_arm_linux_gnueabihf_gcc_thumb_2 () { @@ -445,7 +445,7 @@ component_test_aarch64_linux_gnu_gcc () { programs/test/selftest msg "program demos: make, default config (out-of-box)" # ~0s - tests/scripts/run_demos.py + framework/scripts/run_demos.py } support_test_aarch64_linux_gnu_gcc () { diff --git a/tests/scripts/components-sanitizers.sh b/tests/scripts/components-sanitizers.sh index 6f97096efb..84acd5d876 100644 --- a/tests/scripts/components-sanitizers.sh +++ b/tests/scripts/components-sanitizers.sh @@ -180,10 +180,10 @@ component_test_memsan () { make test msg "test: metatests (MSan)" - tests/scripts/run-metatests.sh any msan + framework/scripts/run-metatests.sh any msan msg "program demos (MSan)" # ~20s - tests/scripts/run_demos.py + framework/scripts/run_demos.py msg "test: ssl-opt.sh (MSan)" # ~ 1 min tests/ssl-opt.sh diff --git a/tests/scripts/gen_ctr_drbg.pl b/tests/scripts/gen_ctr_drbg.pl deleted file mode 100755 index ec5e5d8915..0000000000 --- a/tests/scripts/gen_ctr_drbg.pl +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env perl -# -# Based on NIST CTR_DRBG.rsp validation file -# Only uses AES-256-CTR cases that use a Derivation function -# and concats nonce and personalization for initialization. -# -# Copyright The Mbed TLS Contributors -# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - -use strict; - -my $file = shift; - -open(TEST_DATA, "$file") or die "Opening test cases '$file': $!"; - -sub get_suite_val($) -{ - my $name = shift; - my $val = ""; - - my $line = ; - ($val) = ($line =~ /\[$name\s\=\s(\w+)\]/); - - return $val; -} - -sub get_val($) -{ - my $name = shift; - my $val = ""; - my $line; - - while($line = ) - { - next if($line !~ /=/); - last; - } - - ($val) = ($line =~ /^$name = (\w+)/); - - return $val; -} - -my $cnt = 1;; -while (my $line = ) -{ - next if ($line !~ /^\[AES-256 use df/); - - my $PredictionResistanceStr = get_suite_val("PredictionResistance"); - my $PredictionResistance = 0; - $PredictionResistance = 1 if ($PredictionResistanceStr eq 'True'); - my $EntropyInputLen = get_suite_val("EntropyInputLen"); - my $NonceLen = get_suite_val("NonceLen"); - my $PersonalizationStringLen = get_suite_val("PersonalizationStringLen"); - my $AdditionalInputLen = get_suite_val("AdditionalInputLen"); - - for ($cnt = 0; $cnt < 15; $cnt++) - { - my $Count = get_val("COUNT"); - my $EntropyInput = get_val("EntropyInput"); - my $Nonce = get_val("Nonce"); - my $PersonalizationString = get_val("PersonalizationString"); - my $AdditionalInput1 = get_val("AdditionalInput"); - my $EntropyInputPR1 = get_val("EntropyInputPR") if ($PredictionResistance == 1); - my $EntropyInputReseed = get_val("EntropyInputReseed") if ($PredictionResistance == 0); - my $AdditionalInputReseed = get_val("AdditionalInputReseed") if ($PredictionResistance == 0); - my $AdditionalInput2 = get_val("AdditionalInput"); - my $EntropyInputPR2 = get_val("EntropyInputPR") if ($PredictionResistance == 1); - my $ReturnedBits = get_val("ReturnedBits"); - - if ($PredictionResistance == 1) - { - print("CTR_DRBG NIST Validation (AES-256 use df,$PredictionResistanceStr,$EntropyInputLen,$NonceLen,$PersonalizationStringLen,$AdditionalInputLen) #$Count\n"); - print("ctr_drbg_validate_pr"); - print(":\"$Nonce$PersonalizationString\""); - print(":\"$EntropyInput$EntropyInputPR1$EntropyInputPR2\""); - print(":\"$AdditionalInput1\""); - print(":\"$AdditionalInput2\""); - print(":\"$ReturnedBits\""); - print("\n\n"); - } - else - { - print("CTR_DRBG NIST Validation (AES-256 use df,$PredictionResistanceStr,$EntropyInputLen,$NonceLen,$PersonalizationStringLen,$AdditionalInputLen) #$Count\n"); - print("ctr_drbg_validate_nopr"); - print(":\"$Nonce$PersonalizationString\""); - print(":\"$EntropyInput$EntropyInputReseed\""); - print(":\"$AdditionalInput1\""); - print(":\"$AdditionalInputReseed\""); - print(":\"$AdditionalInput2\""); - print(":\"$ReturnedBits\""); - print("\n\n"); - } - } -} -close(TEST_DATA); diff --git a/tests/scripts/gen_gcm_decrypt.pl b/tests/scripts/gen_gcm_decrypt.pl deleted file mode 100755 index 30d45c307d..0000000000 --- a/tests/scripts/gen_gcm_decrypt.pl +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env perl -# -# Based on NIST gcmDecryptxxx.rsp validation files -# Only first 3 of every set used for compile time saving -# -# Copyright The Mbed TLS Contributors -# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - -use strict; - -my $file = shift; - -open(TEST_DATA, "$file") or die "Opening test cases '$file': $!"; - -sub get_suite_val($) -{ - my $name = shift; - my $val = ""; - - while(my $line = ) - { - next if ($line !~ /^\[/); - ($val) = ($line =~ /\[$name\s\=\s(\w+)\]/); - last; - } - - return $val; -} - -sub get_val($) -{ - my $name = shift; - my $val = ""; - my $line; - - while($line = ) - { - next if($line !~ /=/); - last; - } - - ($val) = ($line =~ /^$name = (\w+)/); - - return $val; -} - -sub get_val_or_fail($) -{ - my $name = shift; - my $val = "FAIL"; - my $line; - - while($line = ) - { - next if($line !~ /=/ && $line !~ /FAIL/); - last; - } - - ($val) = ($line =~ /^$name = (\w+)/) if ($line =~ /=/); - - return $val; -} - -my $cnt = 1;; -while (my $line = ) -{ - my $key_len = get_suite_val("Keylen"); - next if ($key_len !~ /\d+/); - my $iv_len = get_suite_val("IVlen"); - my $pt_len = get_suite_val("PTlen"); - my $add_len = get_suite_val("AADlen"); - my $tag_len = get_suite_val("Taglen"); - - for ($cnt = 0; $cnt < 3; $cnt++) - { - my $Count = get_val("Count"); - my $key = get_val("Key"); - my $iv = get_val("IV"); - my $ct = get_val("CT"); - my $add = get_val("AAD"); - my $tag = get_val("Tag"); - my $pt = get_val_or_fail("PT"); - - print("GCM NIST Validation (AES-$key_len,$iv_len,$pt_len,$add_len,$tag_len) #$Count\n"); - print("gcm_decrypt_and_verify"); - print(":\"$key\""); - print(":\"$ct\""); - print(":\"$iv\""); - print(":\"$add\""); - print(":$tag_len"); - print(":\"$tag\""); - print(":\"$pt\""); - print(":0"); - print("\n\n"); - } -} - -print("GCM Selftest\n"); -print("gcm_selftest:\n\n"); - -close(TEST_DATA); diff --git a/tests/scripts/gen_gcm_encrypt.pl b/tests/scripts/gen_gcm_encrypt.pl deleted file mode 100755 index b4f08494c0..0000000000 --- a/tests/scripts/gen_gcm_encrypt.pl +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env perl -# -# Based on NIST gcmEncryptIntIVxxx.rsp validation files -# Only first 3 of every set used for compile time saving -# -# Copyright The Mbed TLS Contributors -# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - -use strict; - -my $file = shift; - -open(TEST_DATA, "$file") or die "Opening test cases '$file': $!"; - -sub get_suite_val($) -{ - my $name = shift; - my $val = ""; - - while(my $line = ) - { - next if ($line !~ /^\[/); - ($val) = ($line =~ /\[$name\s\=\s(\w+)\]/); - last; - } - - return $val; -} - -sub get_val($) -{ - my $name = shift; - my $val = ""; - my $line; - - while($line = ) - { - next if($line !~ /=/); - last; - } - - ($val) = ($line =~ /^$name = (\w+)/); - - return $val; -} - -my $cnt = 1;; -while (my $line = ) -{ - my $key_len = get_suite_val("Keylen"); - next if ($key_len !~ /\d+/); - my $iv_len = get_suite_val("IVlen"); - my $pt_len = get_suite_val("PTlen"); - my $add_len = get_suite_val("AADlen"); - my $tag_len = get_suite_val("Taglen"); - - for ($cnt = 0; $cnt < 3; $cnt++) - { - my $Count = get_val("Count"); - my $key = get_val("Key"); - my $pt = get_val("PT"); - my $add = get_val("AAD"); - my $iv = get_val("IV"); - my $ct = get_val("CT"); - my $tag = get_val("Tag"); - - print("GCM NIST Validation (AES-$key_len,$iv_len,$pt_len,$add_len,$tag_len) #$Count\n"); - print("gcm_encrypt_and_tag"); - print(":\"$key\""); - print(":\"$pt\""); - print(":\"$iv\""); - print(":\"$add\""); - print(":\"$ct\""); - print(":$tag_len"); - print(":\"$tag\""); - print(":0"); - print("\n\n"); - } -} - -print("GCM Selftest\n"); -print("gcm_selftest:\n\n"); - -close(TEST_DATA); diff --git a/tests/scripts/gen_pkcs1_v21_sign_verify.pl b/tests/scripts/gen_pkcs1_v21_sign_verify.pl deleted file mode 100755 index fe2d3f5d37..0000000000 --- a/tests/scripts/gen_pkcs1_v21_sign_verify.pl +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env perl -# -# Copyright The Mbed TLS Contributors -# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - -use strict; - -my $file = shift; - -open(TEST_DATA, "$file") or die "Opening test cases '$file': $!"; - -sub get_val($$) -{ - my $str = shift; - my $name = shift; - my $val = ""; - - while(my $line = ) - { - next if($line !~ /^# $str/); - last; - } - - while(my $line = ) - { - last if($line eq "\r\n"); - $val .= $line; - } - - $val =~ s/[ \r\n]//g; - - return $val; -} - -my $state = 0; -my $val_n = ""; -my $val_e = ""; -my $val_p = ""; -my $val_q = ""; -my $mod = 0; -my $cnt = 1; -while (my $line = ) -{ - next if ($line !~ /^# Example/); - - ( $mod ) = ($line =~ /A (\d+)/); - $val_n = get_val("RSA modulus n", "N"); - $val_e = get_val("RSA public exponent e", "E"); - $val_p = get_val("Prime p", "P"); - $val_q = get_val("Prime q", "Q"); - - for(my $i = 1; $i <= 6; $i++) - { - my $val_m = get_val("Message to be", "M"); - my $val_salt = get_val("Salt", "Salt"); - my $val_sig = get_val("Signature", "Sig"); - - print("RSASSA-PSS Signature Example ${cnt}_${i}\n"); - print("pkcs1_rsassa_pss_sign:$mod:16:\"$val_p\":16:\"$val_q\":16:\"$val_n\":16:\"$val_e\":SIG_RSA_SHA1:MBEDTLS_MD_SHA1"); - print(":\"$val_m\""); - print(":\"$val_salt\""); - print(":\"$val_sig\":0"); - print("\n\n"); - - print("RSASSA-PSS Signature Example ${cnt}_${i} (verify)\n"); - print("pkcs1_rsassa_pss_verify:$mod:16:\"$val_n\":16:\"$val_e\":SIG_RSA_SHA1:MBEDTLS_MD_SHA1"); - print(":\"$val_m\""); - print(":\"$val_salt\""); - print(":\"$val_sig\":0"); - print("\n\n"); - } - $cnt++; -} -close(TEST_DATA); diff --git a/tests/scripts/generate-afl-tests.sh b/tests/scripts/generate-afl-tests.sh deleted file mode 100755 index d4ef0f3af1..0000000000 --- a/tests/scripts/generate-afl-tests.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/bin/sh - -# This script splits the data test files containing the test cases into -# individual files (one test case per file) suitable for use with afl -# (American Fuzzy Lop). http://lcamtuf.coredump.cx/afl/ -# -# Usage: generate-afl-tests.sh -# - should be the path to one of the test suite files -# such as 'test_suite_rsa.data' -# -# Copyright The Mbed TLS Contributors -# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - -# Abort on errors -set -e - -if [ -z $1 ] -then - echo " [!] No test file specified" >&2 - echo "Usage: $0 " >&2 - exit 1 -fi - -SRC_FILEPATH=$(dirname $1)/$(basename $1) -TESTSUITE=$(basename $1 .data) - -THIS_DIR=$(basename $PWD) - -if [ -d ../library -a -d ../include -a -d ../tests -a $THIS_DIR == "tests" ]; -then :; -else - echo " [!] Must be run from Mbed TLS tests directory" >&2 - exit 1 -fi - -DEST_TESTCASE_DIR=$TESTSUITE-afl-tests -DEST_OUTPUT_DIR=$TESTSUITE-afl-out - -echo " [+] Creating output directories" >&2 - -if [ -e $DEST_OUTPUT_DIR/* ]; -then : - echo " [!] Test output files already exist." >&2 - exit 1 -else - mkdir -p $DEST_OUTPUT_DIR -fi - -if [ -e $DEST_TESTCASE_DIR/* ]; -then : - echo " [!] Test output files already exist." >&2 -else - mkdir -p $DEST_TESTCASE_DIR -fi - -echo " [+] Creating test cases" >&2 -cd $DEST_TESTCASE_DIR - -split -p '^\s*$' ../$SRC_FILEPATH - -for f in *; -do - # Strip out any blank lines (no trim on OS X) - sed '/^\s*$/d' $f >testcase_$f - rm $f -done - -cd .. - -echo " [+] Test cases in $DEST_TESTCASE_DIR" >&2 - diff --git a/tests/scripts/generate_server9_bad_saltlen.py b/tests/scripts/generate_server9_bad_saltlen.py deleted file mode 100755 index 9af4dd3b6d..0000000000 --- a/tests/scripts/generate_server9_bad_saltlen.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env python3 -"""Generate server9-bad-saltlen.crt - -Generate a certificate signed with RSA-PSS, with an incorrect salt length. -""" - -# Copyright The Mbed TLS Contributors -# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - -import subprocess -import argparse -from asn1crypto import pem, x509, core #type: ignore #pylint: disable=import-error - -OPENSSL_RSA_PSS_CERT_COMMAND = r''' -openssl x509 -req -CA {ca_name}.crt -CAkey {ca_name}.key -set_serial 24 {ca_password} \ - {openssl_extfile} -days 3650 -outform DER -in {csr} \ - -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:{anounce_saltlen} \ - -sigopt rsa_mgf1_md:sha256 -''' -SIG_OPT = \ - r'-sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:{saltlen} -sigopt rsa_mgf1_md:sha256' -OPENSSL_RSA_PSS_DGST_COMMAND = r'''openssl dgst -sign {ca_name}.key {ca_password} \ - -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:{actual_saltlen} \ - -sigopt rsa_mgf1_md:sha256''' - - -def auto_int(x): - return int(x, 0) - - -def build_argparser(parser): - """Build argument parser""" - parser.description = __doc__ - parser.add_argument('--ca-name', type=str, required=True, - help='Basename of CA files') - parser.add_argument('--ca-password', type=str, - required=True, help='CA key file password') - parser.add_argument('--csr', type=str, required=True, - help='CSR file for generating certificate') - parser.add_argument('--openssl-extfile', type=str, - required=True, help='X905 v3 extension config file') - parser.add_argument('--anounce_saltlen', type=auto_int, - required=True, help='Announced salt length') - parser.add_argument('--actual_saltlen', type=auto_int, - required=True, help='Actual salt length') - parser.add_argument('--output', type=str, required=True) - - -def main(): - parser = argparse.ArgumentParser() - build_argparser(parser) - args = parser.parse_args() - - return generate(**vars(args)) - -def generate(**kwargs): - """Generate different salt length certificate file.""" - ca_password = kwargs.get('ca_password', '') - if ca_password: - kwargs['ca_password'] = r'-passin "pass:{ca_password}"'.format( - **kwargs) - else: - kwargs['ca_password'] = '' - extfile = kwargs.get('openssl_extfile', '') - if extfile: - kwargs['openssl_extfile'] = '-extfile {openssl_extfile}'.format( - **kwargs) - else: - kwargs['openssl_extfile'] = '' - - cmd = OPENSSL_RSA_PSS_CERT_COMMAND.format(**kwargs) - der_bytes = subprocess.check_output(cmd, shell=True) - target_certificate = x509.Certificate.load(der_bytes) - - cmd = OPENSSL_RSA_PSS_DGST_COMMAND.format(**kwargs) - #pylint: disable=unexpected-keyword-arg - der_bytes = subprocess.check_output(cmd, - input=target_certificate['tbs_certificate'].dump(), - shell=True) - - with open(kwargs.get('output'), 'wb') as f: - target_certificate['signature_value'] = core.OctetBitString(der_bytes) - f.write(pem.armor('CERTIFICATE', target_certificate.dump())) - - -if __name__ == '__main__': - main() diff --git a/tests/scripts/run-metatests.sh b/tests/scripts/run-metatests.sh deleted file mode 100755 index 22a302c62f..0000000000 --- a/tests/scripts/run-metatests.sh +++ /dev/null @@ -1,89 +0,0 @@ -#!/bin/sh - -help () { - cat <&2 "$0: FATAL: programs/test/metatest not found" - exit 120 -fi - -LIST_ONLY= -while getopts hl OPTLET; do - case $OPTLET in - h) help; exit;; - l) LIST_ONLY=1;; - \?) help >&2; exit 120;; - esac -done -shift $((OPTIND - 1)) - -list_matches () { - while read name platform junk; do - for pattern in "$@"; do - case $platform in - $pattern) echo "$name"; break;; - esac - done - done -} - -count=0 -errors=0 -run_metatest () { - ret=0 - "$METATEST_PROGRAM" "$1" || ret=$? - if [ $ret -eq 0 ]; then - echo >&2 "$0: Unexpected success: $1" - errors=$((errors + 1)) - fi - count=$((count + 1)) -} - -# Don't pipe the output of metatest so that if it fails, this script exits -# immediately with a failure status. -full_list=$("$METATEST_PROGRAM" list) -matching_list=$(printf '%s\n' "$full_list" | list_matches "$@") - -if [ -n "$LIST_ONLY" ]; then - printf '%s\n' $matching_list - exit -fi - -for name in $matching_list; do - run_metatest "$name" -done - -if [ $errors -eq 0 ]; then - echo "Ran $count metatests, all good." - exit 0 -else - echo "Ran $count metatests, $errors unexpected successes." - exit 1 -fi diff --git a/tests/scripts/run_demos.py b/tests/scripts/run_demos.py deleted file mode 100755 index 6a63d232fe..0000000000 --- a/tests/scripts/run_demos.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python3 -"""Run the Mbed TLS demo scripts. -""" -import argparse -import glob -import subprocess -import sys - -def run_demo(demo, quiet=False): - """Run the specified demo script. Return True if it succeeds.""" - args = {} - if quiet: - args['stdout'] = subprocess.DEVNULL - args['stderr'] = subprocess.DEVNULL - returncode = subprocess.call([demo], **args) - return returncode == 0 - -def run_demos(demos, quiet=False): - """Run the specified demos and print summary information about failures. - - Return True if all demos passed and False if a demo fails. - """ - failures = [] - for demo in demos: - if not quiet: - print('#### {} ####'.format(demo)) - success = run_demo(demo, quiet=quiet) - if not success: - failures.append(demo) - if not quiet: - print('{}: FAIL'.format(demo)) - if quiet: - print('{}: {}'.format(demo, 'PASS' if success else 'FAIL')) - else: - print('') - successes = len(demos) - len(failures) - print('{}/{} demos passed'.format(successes, len(demos))) - if failures and not quiet: - print('Failures:', *failures) - return not failures - -def run_all_demos(quiet=False): - """Run all the available demos. - - Return True if all demos passed and False if a demo fails. - """ - all_demos = glob.glob('programs/*/*_demo.sh') - if not all_demos: - # Keep the message on one line. pylint: disable=line-too-long - raise Exception('No demos found. run_demos needs to operate from the Mbed TLS toplevel directory.') - return run_demos(all_demos, quiet=quiet) - -def main(): - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument('--quiet', '-q', - action='store_true', - help="suppress the output of demos") - options = parser.parse_args() - success = run_all_demos(quiet=options.quiet) - sys.exit(0 if success else 1) - -if __name__ == '__main__': - main() diff --git a/tests/scripts/test_config_script.py b/tests/scripts/test_config_script.py deleted file mode 100755 index e500b3362f..0000000000 --- a/tests/scripts/test_config_script.py +++ /dev/null @@ -1,175 +0,0 @@ -#!/usr/bin/env python3 - -"""Test helper for the Mbed TLS configuration file tool - -Run config.py with various parameters and write the results to files. - -This is a harness to help regression testing, not a functional tester. -Sample usage: - - test_config_script.py -d old - ## Modify config.py and/or mbedtls_config.h ## - test_config_script.py -d new - diff -ru old new -""" - -## Copyright The Mbed TLS Contributors -## SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later -## - -import argparse -import glob -import os -import re -import shutil -import subprocess - -OUTPUT_FILE_PREFIX = 'config-' - -def output_file_name(directory, stem, extension): - return os.path.join(directory, - '{}{}.{}'.format(OUTPUT_FILE_PREFIX, - stem, extension)) - -def cleanup_directory(directory): - """Remove old output files.""" - for extension in []: - pattern = output_file_name(directory, '*', extension) - filenames = glob.glob(pattern) - for filename in filenames: - os.remove(filename) - -def prepare_directory(directory): - """Create the output directory if it doesn't exist yet. - - If there are old output files, remove them. - """ - if os.path.exists(directory): - cleanup_directory(directory) - else: - os.makedirs(directory) - -def guess_presets_from_help(help_text): - """Figure out what presets the script supports. - - help_text should be the output from running the script with --help. - """ - # Try the output format from config.py - hits = re.findall(r'\{([-\w,]+)\}', help_text) - for hit in hits: - words = set(hit.split(',')) - if 'get' in words and 'set' in words and 'unset' in words: - words.remove('get') - words.remove('set') - words.remove('unset') - return words - # Try the output format from config.pl - hits = re.findall(r'\n +([-\w]+) +- ', help_text) - if hits: - return hits - raise Exception("Unable to figure out supported presets. Pass the '-p' option.") - -def list_presets(options): - """Return the list of presets to test. - - The list is taken from the command line if present, otherwise it is - extracted from running the config script with --help. - """ - if options.presets: - return re.split(r'[ ,]+', options.presets) - else: - help_text = subprocess.run([options.script, '--help'], - check=False, # config.pl --help returns 255 - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT).stdout - return guess_presets_from_help(help_text.decode('ascii')) - -def run_one(options, args, stem_prefix='', input_file=None): - """Run the config script with the given arguments. - - Take the original content from input_file if specified, defaulting - to options.input_file if input_file is None. - - Write the following files, where xxx contains stem_prefix followed by - a filename-friendly encoding of args: - * config-xxx.h: modified file. - * config-xxx.out: standard output. - * config-xxx.err: standard output. - * config-xxx.status: exit code. - - Return ("xxx+", "path/to/config-xxx.h") which can be used as - stem_prefix and input_file to call this function again with new args. - """ - if input_file is None: - input_file = options.input_file - stem = stem_prefix + '-'.join(args) - data_filename = output_file_name(options.output_directory, stem, 'h') - stdout_filename = output_file_name(options.output_directory, stem, 'out') - stderr_filename = output_file_name(options.output_directory, stem, 'err') - status_filename = output_file_name(options.output_directory, stem, 'status') - shutil.copy(input_file, data_filename) - # Pass only the file basename, not the full path, to avoid getting the - # directory name in error messages, which would make comparisons - # between output directories more difficult. - cmd = [os.path.abspath(options.script), - '-f', os.path.basename(data_filename)] - with open(stdout_filename, 'wb') as out: - with open(stderr_filename, 'wb') as err: - status = subprocess.call(cmd + args, - cwd=options.output_directory, - stdin=subprocess.DEVNULL, - stdout=out, stderr=err) - with open(status_filename, 'w') as status_file: - status_file.write('{}\n'.format(status)) - return stem + "+", data_filename - -### A list of symbols to test with. -### This script currently tests what happens when you change a symbol from -### having a value to not having a value or vice versa. This is not -### necessarily useful behavior, and we may not consider it a bug if -### config.py stops handling that case correctly. -TEST_SYMBOLS = [ - 'CUSTOM_SYMBOL', # does not exist - 'MBEDTLS_AES_C', # set, no value - 'MBEDTLS_MPI_MAX_SIZE', # unset, has a value - 'MBEDTLS_NO_UDBL_DIVISION', # unset, in "System support" - 'MBEDTLS_PLATFORM_ZEROIZE_ALT', # unset, in "Customisation configuration options" -] - -def run_all(options): - """Run all the command lines to test.""" - presets = list_presets(options) - for preset in presets: - run_one(options, [preset]) - for symbol in TEST_SYMBOLS: - run_one(options, ['get', symbol]) - (stem, filename) = run_one(options, ['set', symbol]) - run_one(options, ['get', symbol], stem_prefix=stem, input_file=filename) - run_one(options, ['--force', 'set', symbol]) - (stem, filename) = run_one(options, ['set', symbol, 'value']) - run_one(options, ['get', symbol], stem_prefix=stem, input_file=filename) - run_one(options, ['--force', 'set', symbol, 'value']) - run_one(options, ['unset', symbol]) - -def main(): - """Command line entry point.""" - parser = argparse.ArgumentParser(description=__doc__, - formatter_class=argparse.RawDescriptionHelpFormatter) - parser.add_argument('-d', metavar='DIR', - dest='output_directory', required=True, - help="""Output directory.""") - parser.add_argument('-f', metavar='FILE', - dest='input_file', default='include/mbedtls/mbedtls_config.h', - help="""Config file (default: %(default)s).""") - parser.add_argument('-p', metavar='PRESET,...', - dest='presets', - help="""Presets to test (default: guessed from --help).""") - parser.add_argument('-s', metavar='FILE', - dest='script', default='scripts/config.py', - help="""Configuration script (default: %(default)s).""") - options = parser.parse_args() - prepare_directory(options.output_directory) - run_all(options) - -if __name__ == '__main__': - main() diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 6ea8db1e01..73515b4a92 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -14948,7 +14948,6 @@ run_test "TLS 1.2: Check rsa_pss_rsae compatibility issue, m->O" \ -c "Protocol is TLSv1.2" \ -c "HTTP/1.0 200 [Oo][Kk]" - requires_gnutls_tls1_3 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 requires_config_enabled MBEDTLS_DEBUG_C @@ -14964,6 +14963,43 @@ run_test "TLS 1.2: Check rsa_pss_rsae compatibility issue, m->G" \ -c "Protocol is TLSv1.2" \ -c "HTTP/1.0 200 [Oo][Kk]" +requires_openssl_tls1_3_with_compatible_ephemeral +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_config_enabled PSA_WANT_ALG_RSA_PSS +requires_config_enabled PSA_WANT_ALG_SHA_256 +run_test "TLS 1.2: Server forces TLS 1.2 and rsa_pss_rsae_sha256, m->O" \ + "$O_NEXT_SRV_NO_CERT -cert $DATA_FILES_PATH/server2-sha256.crt -key $DATA_FILES_PATH/server2.key + -tls1_2 -sigalgs rsa_pss_rsae_sha256 " \ + "$P_CLI debug_level=3" \ + 0 \ + -c "sent signature scheme \\[804\\] rsa_pss_rsae_sha256" \ + -c "Perform .* computation of digest of ServerKeyExchange" \ + -c "Server used the signature algorithm rsa_pss_rsae_sha256" \ + -c "Protocol is TLSv1.2" \ + -c "HTTP/1.0 200 [Oo][Kk]" + +requires_gnutls_tls1_3 +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_config_enabled PSA_WANT_ALG_RSA_PSS +requires_config_enabled PSA_WANT_ALG_SHA_256 +run_test "TLS 1.2: Server forces TLS 1.2 and rsa_pss_rsae_sha256, m->G" \ + "$G_NEXT_SRV_NO_CERT --x509certfile $DATA_FILES_PATH/server2-sha256.crt --x509keyfile $DATA_FILES_PATH/server2.key + --disable-client-cert + --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256" \ + "$P_CLI debug_level=3" \ + 0 \ + -c "sent signature scheme \\[804\\] rsa_pss_rsae_sha256" \ + -c "Perform .* computation of digest of ServerKeyExchange" \ + -c "Server used the signature algorithm rsa_pss_rsae_sha256" \ + -c "Protocol is TLSv1.2" \ + -c "HTTP/1.0 200 [Oo][Kk]" + requires_config_enabled MBEDTLS_SSL_SRV_C requires_config_enabled MBEDTLS_DEBUG_C requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index a8cf711098..9bfbb37bc9 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -781,7 +781,7 @@ void pk_can_do_ext(int opaque_key, int key_type, int key_usage, int key_alg, exit: psa_reset_key_attributes(&attributes); - PSA_ASSERT(psa_destroy_key(key)); + psa_destroy_key(key); mbedtls_pk_free(&pk); USE_PSA_DONE(); } diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index fb278ddbda..6d560928b9 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -2411,7 +2411,7 @@ void aead_key_policy(int policy_usage_arg, } exit: - PSA_ASSERT(psa_aead_abort(&operation)); + psa_aead_abort(&operation); psa_destroy_key(key); PSA_DONE(); } @@ -3030,7 +3030,7 @@ void hash_compute_fail(int alg_arg, data_t *input, } exit: - PSA_ASSERT(psa_hash_abort(&operation)); + psa_hash_abort(&operation); mbedtls_free(output); PSA_DONE(); } @@ -3069,7 +3069,7 @@ void hash_compare_fail(int alg_arg, data_t *input, } exit: - PSA_ASSERT(psa_hash_abort(&operation)); + psa_hash_abort(&operation); PSA_DONE(); } /* END_CASE */ @@ -3173,7 +3173,7 @@ void hash_compute_compare(int alg_arg, data_t *input, } exit: - PSA_ASSERT(psa_hash_abort(&operation)); + psa_hash_abort(&operation); PSA_DONE(); } /* END_CASE */ @@ -4345,7 +4345,7 @@ void cipher_alg_without_iv(int alg_arg, int key_type_arg, data_t *key_data, output, output_length); exit: - PSA_ASSERT(psa_cipher_abort(&operation)); + psa_cipher_abort(&operation); mbedtls_free(output); psa_cipher_abort(&operation); psa_destroy_key(key); @@ -10967,8 +10967,8 @@ void ecjpake_setup(int alg_arg, int key_type_pw_arg, int key_usage_pw_arg, } exit: - PSA_ASSERT(psa_destroy_key(key)); - PSA_ASSERT(psa_pake_abort(&operation)); + psa_destroy_key(key); + psa_pake_abort(&operation); mbedtls_free(output_buffer); PSA_DONE(); } diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function index f5bed37c85..91b1ff60e5 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function @@ -2899,7 +2899,7 @@ void aead_encrypt_setup(int key_type_arg, data_t *key_data, exit: /* Cleanup */ - PSA_ASSERT(psa_destroy_key(key)); + psa_destroy_key(key); mbedtls_free(output_data); PSA_DONE(); mbedtls_test_driver_aead_hooks = mbedtls_test_driver_aead_hooks_init(); @@ -3001,7 +3001,7 @@ void aead_decrypt_setup(int key_type_arg, data_t *key_data, } exit: - PSA_ASSERT(psa_destroy_key(key)); + psa_destroy_key(key); mbedtls_free(output_data); PSA_DONE(); } diff --git a/tests/suites/test_suite_psa_crypto_pake.function b/tests/suites/test_suite_psa_crypto_pake.function index 08c88a1d6e..303ef0deaf 100644 --- a/tests/suites/test_suite_psa_crypto_pake.function +++ b/tests/suites/test_suite_psa_crypto_pake.function @@ -593,7 +593,7 @@ void ecjpake_setup(int alg_arg, int key_type_pw_arg, int key_usage_pw_arg, int expected_error_arg) { psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); - psa_pake_operation_t operation = psa_pake_operation_init(); + psa_pake_operation_t operation = psa_pake_operation_init_short(); psa_algorithm_t alg = alg_arg; psa_pake_primitive_t primitive = primitive_arg; psa_key_type_t key_type_pw = key_type_pw_arg; @@ -763,8 +763,8 @@ void ecjpake_setup(int alg_arg, int key_type_pw_arg, int key_usage_pw_arg, } exit: - PSA_ASSERT(psa_destroy_key(key)); - PSA_ASSERT(psa_pake_abort(&operation)); + psa_destroy_key(key); + psa_pake_abort(&operation); mbedtls_free(output_buffer); PSA_DONE(); } @@ -779,8 +779,8 @@ void ecjpake_rounds_inject(int alg_arg, int primitive_arg, int hash_arg, int inject_in_second_round) { psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); - psa_pake_operation_t server = psa_pake_operation_init(); - psa_pake_operation_t client = psa_pake_operation_init(); + psa_pake_operation_t server = psa_pake_operation_init_short(); + psa_pake_operation_t client = psa_pake_operation_init_short(); psa_algorithm_t alg = alg_arg; psa_algorithm_t hash_alg = hash_arg; mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; @@ -839,8 +839,8 @@ void ecjpake_rounds(int alg_arg, int primitive_arg, int hash_arg, int err_stage_arg) { psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); - psa_pake_operation_t server = psa_pake_operation_init(); - psa_pake_operation_t client = psa_pake_operation_init(); + psa_pake_operation_t server = psa_pake_operation_init_short(); + psa_pake_operation_t client = psa_pake_operation_init_short(); psa_algorithm_t alg = alg_arg; psa_algorithm_t hash_alg = hash_arg; psa_algorithm_t derive_alg = derive_alg_arg; @@ -980,7 +980,7 @@ void ecjpake_size_macros() void pake_input_getters_password() { psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); - psa_pake_operation_t operation = psa_pake_operation_init(); + psa_pake_operation_t operation = psa_pake_operation_init_short(); mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; const char *password = "password"; @@ -1035,8 +1035,8 @@ void pake_input_getters_password() TEST_MEMORY_COMPARE(password_ret, buffer_len_ret, password, strlen(password)); exit: - PSA_ASSERT(psa_destroy_key(key)); - PSA_ASSERT(psa_pake_abort(&operation)); + psa_destroy_key(key); + psa_pake_abort(&operation); PSA_DONE(); } /* END_CASE */ @@ -1045,7 +1045,7 @@ exit: void pake_input_getters_cipher_suite() { psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); - psa_pake_operation_t operation = psa_pake_operation_init(); + psa_pake_operation_t operation = psa_pake_operation_init_short(); psa_pake_cipher_suite_t cipher_suite_ret = psa_pake_cipher_suite_init(); psa_pake_primitive_t primitive = PSA_PAKE_PRIMITIVE( @@ -1058,9 +1058,6 @@ void pake_input_getters_cipher_suite() psa_pake_cs_set_primitive(&cipher_suite, primitive); psa_pake_cs_set_hash(&cipher_suite, PSA_ALG_SHA_256); - TEST_EQUAL(psa_crypto_driver_pake_get_cipher_suite(&operation.data.inputs, &cipher_suite_ret), - PSA_ERROR_BAD_STATE); - PSA_ASSERT(psa_pake_setup(&operation, &cipher_suite)); TEST_EQUAL(psa_crypto_driver_pake_get_cipher_suite(&operation.data.inputs, &cipher_suite_ret), @@ -1069,8 +1066,12 @@ void pake_input_getters_cipher_suite() TEST_MEMORY_COMPARE(&cipher_suite_ret, sizeof(cipher_suite_ret), &cipher_suite, sizeof(cipher_suite)); -exit: PSA_ASSERT(psa_pake_abort(&operation)); + TEST_EQUAL(psa_crypto_driver_pake_get_cipher_suite(&operation.data.inputs, &cipher_suite_ret), + PSA_ERROR_BAD_STATE); + +exit: + psa_pake_abort(&operation); PSA_DONE(); } /* END_CASE */ @@ -1079,7 +1080,7 @@ exit: void pake_input_getters_user() { psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); - psa_pake_operation_t operation = psa_pake_operation_init(); + psa_pake_operation_t operation = psa_pake_operation_init_short(); const char *users[] = { "client", "server", "other" }; uint8_t user_ret[20] = { 0 }; // max user length is 20 bytes size_t user_len_ret = 0; @@ -1132,8 +1133,9 @@ void pake_input_getters_user() TEST_MEMORY_COMPARE(user_ret, buffer_len_ret, user, user_len); } + exit: - PSA_ASSERT(psa_pake_abort(&operation)); + psa_pake_abort(&operation); PSA_DONE(); } /* END_CASE */ @@ -1142,7 +1144,7 @@ exit: void pake_input_getters_peer() { psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); - psa_pake_operation_t operation = psa_pake_operation_init(); + psa_pake_operation_t operation = psa_pake_operation_init_short(); const char *peers[] = { "client", "server", "other" }; uint8_t peer_ret[20] = { 0 }; // max peer length is 20 bytes size_t peer_len_ret = 0; @@ -1195,8 +1197,9 @@ void pake_input_getters_peer() TEST_MEMORY_COMPARE(peer_ret, buffer_len_ret, peer, peer_len); } + exit: - PSA_ASSERT(psa_pake_abort(&operation)); + psa_pake_abort(&operation); PSA_DONE(); } /* END_CASE */ diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data index 5e711e565d..400dfe99fa 100644 --- a/tests/suites/test_suite_version.data +++ b/tests/suites/test_suite_version.data @@ -1,8 +1,8 @@ Check compile time library version -check_compiletime_version:"3.6.5" +check_compiletime_version:"3.6.6" Check runtime library version -check_runtime_version:"3.6.5" +check_runtime_version:"3.6.6" Check for MBEDTLS_VERSION_C check_feature:"MBEDTLS_VERSION_C":0