diff --git a/BRANCHES.md b/BRANCHES.md index c781704977..8abb39cefb 100644 --- a/BRANCHES.md +++ b/BRANCHES.md @@ -11,6 +11,7 @@ At any point in time, we have a number of maintained branches, currently consist - One or more long-time support (LTS) branches: these only get bug fixes and security fixes. Currently, the supported LTS branches are: - [`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). @@ -22,11 +23,11 @@ the API of 4.(x+1) is backward compatible with 4.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 @@ -87,6 +88,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 - . + . +- [`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 d5d0a98b8d..c6d076346c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,10 +37,10 @@ cmake_policy(SET CMP0011 NEW) # is deprecated and will be removed in future versions. cmake_policy(SET CMP0012 NEW) -set(MBEDTLS_VERSION 4.0.0) -set(MBEDTLS_CRYPTO_SOVERSION 17) -set(MBEDTLS_X509_SOVERSION 8) -set(MBEDTLS_TLS_SOVERSION 22) +set(MBEDTLS_VERSION 4.1.0) +set(MBEDTLS_CRYPTO_SOVERSION 18) +set(MBEDTLS_X509_SOVERSION 9) +set(MBEDTLS_TLS_SOVERSION 23) if(TEST_CPP) project("Mbed TLS" diff --git a/ChangeLog b/ChangeLog index 4dc0941fee..12191e1116 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,82 @@ Mbed TLS ChangeLog (Sorted per branch, date) += Mbed TLS 4.1.0 branch released 2026-03-31 + +API changes + * MBEDTLS_TIMING_C now requires MBEDTLS_HAVE_TIME to be enabled in the + TF-PSA-Crypto configuration, unless MBEDTLS_TIMING_ALT is enabled. + As a benefit, platforms where the default implementation is not + supported now only need to implement MBEDTLS_PLATFORM_MS_TIME_ALT. + * When MBEDTLS_TIMING_ALT is enabled, the function + mbedtls_timing_get_timer() now returns unsigned long long instead + of unsigned long. + +Features + * Add the function mbedtls_ssl_get_fatal_alert(), which returns the type of + the last received fatal alert. This allows callers to retrieve more + detailed information when mbedtls_ssl_handshake(), + mbedtls_ssl_handshake_step(), or mbedtls_ssl_read() returns the generic + MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE error code. + * Function mbedtls_ssl_get_supported_group_list() is added to return the list + of supported groups IDs (curves and finite fields). + * MBEDTLS_SSL_IANA_TLS_GROUPS_INFO is added to allow defining the list of + mbedtls_ssl_iana_tls_group_info_t items which represent known TLS groups + with corresponding informations. + If MBEDTLS_DEBUG_C is also enabled then mbedtls_ssl_iana_tls_group_info is + also available as implementation of such list. + +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. + * 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 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 + * 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 + * CMake now installs headers to `CMAKE_INSTALL_INCLUDEDIR` instead of the + hard-coded `include` directory. + * Fix CMake failure on Windows because of a native directory separator. + Fixes #10502. + * mbedtls_timing_get_delay() now correctly treats a timer as expired + after more than 2^32 ms (about 49 days) on platforms where long is + a 32-bit type. Fixes #10613. + * 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. + +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 4.0.0 branch released 2025-10-15 API changes diff --git a/ChangeLog.d/alert-getter.txt b/ChangeLog.d/alert-getter.txt deleted file mode 100644 index da90cf31d7..0000000000 --- a/ChangeLog.d/alert-getter.txt +++ /dev/null @@ -1,6 +0,0 @@ -Features - * Add the function mbedtls_ssl_get_fatal_alert(), which returns the type of - the last received fatal alert. This allows callers to retrieve more - detailed information when mbedtls_ssl_handshake(), - mbedtls_ssl_handshake_step(), or mbedtls_ssl_read() returns the generic - MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE error code. diff --git a/ChangeLog.d/config_checks_generator-fix-windows-path.txt b/ChangeLog.d/config_checks_generator-fix-windows-path.txt deleted file mode 100644 index e5726cf77b..0000000000 --- a/ChangeLog.d/config_checks_generator-fix-windows-path.txt +++ /dev/null @@ -1,3 +0,0 @@ -Bugfix - * Fix CMake failure on Windows because of a native directory separator. - Fixes #10502. 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/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/issue10349.txt b/ChangeLog.d/issue10349.txt deleted file mode 100644 index ab47659ed8..0000000000 --- a/ChangeLog.d/issue10349.txt +++ /dev/null @@ -1,8 +0,0 @@ -Features - * Function mbedtls_ssl_get_supported_group_list() is added to return the list - of supported groups IDs (curves and finite fields). - * MBEDTLS_SSL_IANA_TLS_GROUPS_INFO is added to allow defining the list of - mbedtls_ssl_iana_tls_group_info_t items which represent known TLS groups - with corresponding informations. - If MBEDTLS_DEBUG_C is also enabled then mbedtls_ssl_iana_tls_group_info is - also available as implementation of such list. diff --git a/ChangeLog.d/timing.txt b/ChangeLog.d/timing.txt deleted file mode 100644 index b3943cdcf2..0000000000 --- a/ChangeLog.d/timing.txt +++ /dev/null @@ -1,13 +0,0 @@ -API changes - * MBEDTLS_TIMING_C now requires MBEDTLS_HAVE_TIME to be enabled in the - TF-PSA-Crypto configuration, unless MBEDTLS_TIMING_ALT is enabled. - As a benefit, platforms where the default implementation is not - supported now only need to implement MBEDTLS_PLATFORM_MS_TIME_ALT. - * When MBEDTLS_TIMING_ALT is enabled, the function - mbedtls_timing_get_timer() now returns unsigned long long instead - of unsigned long. - -Bugfix - * mbedtls_timing_get_delay() now correctly treats a timer as expired - after more than 2^32 ms (about 49 days) on platforms where long is - a 32-bit type. Fixes #10613. diff --git a/ChangeLog.d/unistd.txt b/ChangeLog.d/unistd.txt deleted file mode 100644 index d2e4d4301a..0000000000 --- a/ChangeLog.d/unistd.txt +++ /dev/null @@ -1,3 +0,0 @@ -Changes - * Tweak the detection of Unix-like platforms, which makes more system - interfaces (timing, threading) available on Haiku, QNX and Midipix. 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/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h index 4eda5ba2aa..b28b82b851 100644 --- a/doxygen/input/doc_mainpage.h +++ b/doxygen/input/doc_mainpage.h @@ -10,7 +10,7 @@ */ /** - * @mainpage Mbed TLS v4.0.0 API Documentation + * @mainpage Mbed TLS v4.1.0 API Documentation * * This documentation describes the application programming interface (API) * of Mbed TLS. diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile index 80e459cc72..c6a5e4f4fd 100644 --- a/doxygen/mbedtls.doxyfile +++ b/doxygen/mbedtls.doxyfile @@ -1,4 +1,4 @@ -PROJECT_NAME = "Mbed TLS v4.0.0" +PROJECT_NAME = "Mbed TLS v4.1.0" OUTPUT_DIRECTORY = ../apidoc/ FULL_PATH_NAMES = NO OPTIMIZE_OUTPUT_FOR_C = YES diff --git a/framework b/framework index c3d6599465..dff9da0443 160000 --- a/framework +++ b/framework @@ -1 +1 @@ -Subproject commit c3d659946503c3ef259bc424e1c3fd10d55df543 +Subproject commit dff9da04438d712f7647fd995bc90fadd0c0e2ce diff --git a/include/mbedtls/build_info.h b/include/mbedtls/build_info.h index 7b7ff49f5a..e077bbce40 100644 --- a/include/mbedtls/build_info.h +++ b/include/mbedtls/build_info.h @@ -27,7 +27,7 @@ * Major, Minor, Patchlevel */ #define MBEDTLS_VERSION_MAJOR 4 -#define MBEDTLS_VERSION_MINOR 0 +#define MBEDTLS_VERSION_MINOR 1 #define MBEDTLS_VERSION_PATCH 0 /** @@ -35,9 +35,9 @@ * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x04000000 -#define MBEDTLS_VERSION_STRING "4.0.0" -#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 4.0.0" +#define MBEDTLS_VERSION_NUMBER 0x04010000 +#define MBEDTLS_VERSION_STRING "4.1.0" +#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 4.1.0" #if defined(MBEDTLS_CONFIG_FILES_READ) #error "Something went wrong: MBEDTLS_CONFIG_FILES_READ defined before reading the config files!" diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index c4cbaaf4e0..3a69df5466 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -3174,6 +3174,27 @@ int mbedtls_ssl_set_session(mbedtls_ssl_context *ssl, const mbedtls_ssl_session * On server, this can be used for alternative implementations * of session cache or session tickets. * + * \warning The serialized data contains highly sensitive material, + * including a resumption key (TLS 1.3) or the master secret + * (TLS 1.2) from which the session's traffic keys are derived. + * + * The serialized data is not cryptographically protected. + * It is the responsibility of the user of the + * mbedtls_ssl_session_save() and + * mbedtls_ssl_session_load() APIs to ensure both its + * confidentiality and integrity while stored or transported. + * + * A breach of confidentiality could result in full compromise + * of the associated TLS session, including loss of + * confidentiality and integrity of past and future + * application data protected under that session. + * + * A breach of integrity may allow modification of the + * serialized data prior to restoration. As it represents + * trusted internal context, tampering could potentially result + * in arbitrary code execution or other severe compromise of + * the hosting process. + * * \warning If a peer certificate chain is associated with the session, * the serialized state will only contain the peer's * end-entity certificate and the result of the chain @@ -3212,6 +3233,19 @@ int mbedtls_ssl_session_load(mbedtls_ssl_session *session, * * \see mbedtls_ssl_session_load() * + * \warning The serialized data contains highly sensitive material, + * including a resumption key (TLS 1.3) or the master secret + * (TLS 1.2) from which the session's traffic keys are derived. + * + * The serialized data is not cryptographically protected. + * It is the responsibility of the user of the + * mbedtls_ssl_session_save() and + * mbedtls_ssl_session_load() APIs to ensure both its + * confidentiality and integrity while stored or transported. + * + * See the mbedtls_ssl_session_load() documentation for + * additional information. + * * \param session The session structure to be saved. * \param buf The buffer to write the serialized data to. It must be a * writeable buffer of at least \p buf_len bytes, or may be \c @@ -5293,6 +5327,19 @@ void mbedtls_ssl_free(mbedtls_ssl_context *ssl); * * \see mbedtls_ssl_context_load() * + * \warning The serialized data contains highly sensitive material, + * including the master secret from which the session's traffic + * keys are derived. + * + * The serialized data is not cryptographically protected. + * It is the responsibility of the user of the + * mbedtls_ssl_context_save() and + * mbedtls_ssl_context_load() APIs to ensure both its + * confidentiality and integrity while stored or transported. + * + * See the mbedtls_ssl_context_load() documentation for + * additional information. + * * \note The serialized data only contains the data that is * necessary to resume the connection: negotiated protocol * options, session identifier, keys, etc. @@ -5359,6 +5406,27 @@ int mbedtls_ssl_context_save(mbedtls_ssl_context *ssl, * more than one context would cause severe security failures * including but not limited to loss of confidentiality. * + * \warning The serialized data contains highly sensitive material, + * including the master secret from which the session's traffic + * keys are derived. + * + * The serialized data is not cryptographically protected. + * It is the responsibility of the user of the + * mbedtls_ssl_context_save() and + * mbedtls_ssl_context_load() APIs to ensure both its + * confidentiality and integrity while stored or transported. + * + * A breach of confidentiality could result in full compromise + * of the associated TLS session, including loss of + * confidentiality and integrity of past and future + * application data protected under that session. + * + * A breach of integrity may allow modification of the + * serialized data prior to restoration. As it represents + * trusted internal context, tampering could potentially result + * in arbitrary code execution or other severe compromise of + * the hosting process. + * * \note Before calling this function, the SSL context must be * prepared in one of the two following ways. The first way is * to take a context freshly initialised with diff --git a/library/Makefile b/library/Makefile index ad2854ad3a..cb6a99cc6c 100644 --- a/library/Makefile +++ b/library/Makefile @@ -72,9 +72,9 @@ LOCAL_CFLAGS += -fPIC -fpic endif endif -SOEXT_TLS?=so.21 -SOEXT_X509?=so.8 -SOEXT_CRYPTO?=so.16 +SOEXT_TLS?=so.23 +SOEXT_X509?=so.9 +SOEXT_CRYPTO?=so.18 ARFLAGS = $(AR_DASH)src ifdef APPLE_BUILD diff --git a/library/ssl_msg.c b/library/ssl_msg.c index abb5a5696f..87d64788bd 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -275,6 +275,7 @@ exit: /* Forward declarations for functions related to message buffering. */ static void ssl_buffering_free_slot(mbedtls_ssl_context *ssl, uint8_t slot); +static void ssl_buffering_shift_slots(mbedtls_ssl_context *ssl, unsigned shift); static void ssl_free_buffered_record(mbedtls_ssl_context *ssl); MBEDTLS_CHECK_RETURN_CRITICAL static int ssl_load_buffered_message(mbedtls_ssl_context *ssl); @@ -2985,8 +2986,12 @@ int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl) * expected `message_seq` for the incoming and outgoing * handshake messages. */ - ssl->handshake->in_msg_seq = recv_msg_seq; - ssl->handshake->out_msg_seq = recv_msg_seq; + if ((ssl->handshake->in_msg_seq == 0) && (recv_msg_seq > 0)) { + MBEDTLS_SSL_DEBUG_MSG(3, ("shift slots by %u", recv_msg_seq)); + ssl_buffering_shift_slots(ssl, recv_msg_seq); + ssl->handshake->in_msg_seq = recv_msg_seq; + ssl->handshake->out_msg_seq = recv_msg_seq; + } /* Epoch should be 0 for initial handshakes */ if (ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0) { @@ -2996,6 +3001,7 @@ int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl) memcpy(&ssl->cur_out_ctr[2], ssl->in_ctr + 2, sizeof(ssl->cur_out_ctr) - 2); + } else if (mbedtls_ssl_is_handshake_over(ssl) == 1) { /* In case of a post-handshake ClientHello that initiates a * renegotiation check that the handshake message sequence @@ -3180,28 +3186,10 @@ int mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl) #if defined(MBEDTLS_SSL_PROTO_DTLS) if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && ssl->handshake != NULL) { - unsigned offset; - mbedtls_ssl_hs_buffer *hs_buf; /* Increment handshake sequence number */ hs->in_msg_seq++; - - /* - * Clear up handshake buffering and reassembly structure. - */ - - /* Free first entry */ - ssl_buffering_free_slot(ssl, 0); - - /* Shift all other entries */ - for (offset = 0, hs_buf = &hs->buffering.hs[0]; - offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS; - offset++, hs_buf++) { - *hs_buf = *(hs_buf + 1); - } - - /* Create a fresh last entry */ - memset(hs_buf, 0, sizeof(mbedtls_ssl_hs_buffer)); + ssl_buffering_shift_slots(ssl, 1); } #endif return 0; @@ -3618,7 +3606,7 @@ static int ssl_parse_record_header(mbedtls_ssl_context const *ssl, ( "datagram of length %u too small to hold DTLS record header of length %u", (unsigned) len, - (unsigned) (rec_hdr_len_len + rec_hdr_len_len))); + (unsigned) (rec_hdr_len_offset + rec_hdr_len_len))); return MBEDTLS_ERR_SSL_INVALID_RECORD; } @@ -4750,6 +4738,31 @@ static int ssl_get_next_record(mbedtls_ssl_context *ssl) ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; } +#if defined(MBEDTLS_SSL_SRV_C) + /* + * In DTLS, invalid records are usually ignored because it is easy + * for an attacker to inject UDP datagrams, and we do not want such + * packets to disrupt the entire connection. + * + * However, when expecting the ClientHello, we reject invalid or + * unexpected records. This avoids waiting for further records + * before receiving at least one valid message. Such records could + * be leftover messages from a previous connection, accidental + * input, or part of a DoS attempt. + * + * Since no valid message has been received yet, immediately + * closing the connection does not result in any loss. + */ + if ((ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) && + (ssl->state == MBEDTLS_SSL_CLIENT_HELLO) +#if defined(MBEDTLS_SSL_RENEGOTIATION) + && (ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE) +#endif + ) { + return ret; + } +#endif /* MBEDTLS_SSL_SRV_C */ + if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) { #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) /* Reset in pointers to default state for TLS/DTLS records, @@ -6134,6 +6147,42 @@ static void ssl_buffering_free_slot(mbedtls_ssl_context *ssl, } } +/* + * Shift the buffering slots to the left by `shift` positions. + * After the operation, slot i contains the previous slot i + shift. + */ +static void ssl_buffering_shift_slots(mbedtls_ssl_context *ssl, + unsigned shift) +{ + mbedtls_ssl_handshake_params * const hs = ssl->handshake; + unsigned offset; + + if (shift == 0) { + return; + } + + if (shift >= MBEDTLS_SSL_MAX_BUFFERED_HS) { + shift = MBEDTLS_SSL_MAX_BUFFERED_HS; + } + + /* Free discarded entries */ + for (offset = 0; offset < shift; offset++) { + ssl_buffering_free_slot(ssl, offset); + } + + /* Shift remaining entries left */ + for (offset = 0; offset + shift < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++) { + hs->buffering.hs[offset] = hs->buffering.hs[offset + shift]; + } + + /* Reset the remaining entries at the end. Some may already have been + * cleared by the loop freeing the discarded entries, but resetting all + * of them is simpler and avoids tracking which ones were already handled. + */ + for (; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++) { + memset(&hs->buffering.hs[offset], 0, sizeof(hs->buffering.hs[offset])); + } +} #endif /* MBEDTLS_SSL_PROTO_DTLS */ /* diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index ebcc0d56bb..a0170d51f6 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -1732,6 +1732,48 @@ static int ssl_parse_server_psk_hint(mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +MBEDTLS_CHECK_RETURN_CRITICAL +static int ssl_parse_signature_algorithm(mbedtls_ssl_context *ssl, + uint16_t sig_alg, + mbedtls_md_type_t *md_alg, + mbedtls_pk_sigalg_t *pk_alg) +{ + if (mbedtls_ssl_get_pk_sigalg_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)); + 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. + */ + 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; + } + + /* + * 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)); + 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)); + + return 0; +} +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ + MBEDTLS_CHECK_RETURN_CRITICAL static int ssl_parse_server_key_exchange(mbedtls_ssl_context *ssl) { @@ -1889,7 +1931,6 @@ start_processing: unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl); size_t params_len = (size_t) (p - params); void *rs_ctx = NULL; - uint16_t sig_alg; mbedtls_pk_context *peer_pk; @@ -1908,11 +1949,8 @@ start_processing: * Handle the digitally-signed structure */ MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - sig_alg = MBEDTLS_GET_UINT16_BE(p, 0); - if (mbedtls_ssl_get_pk_sigalg_and_md_alg_from_sig_alg( - sig_alg, &pk_alg, &md_alg) != 0 && - !mbedtls_ssl_sig_alg_is_offered(ssl, sig_alg) && - !mbedtls_ssl_sig_alg_is_supported(ssl, sig_alg)) { + uint16_t sig_alg = MBEDTLS_GET_UINT16_BE(p, 0); + if (ssl_parse_signature_algorithm(ssl, sig_alg, &md_alg, &pk_alg) != 0) { MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); mbedtls_ssl_send_alert_message( diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index e7b24c05c8..884c8fd4a4 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -879,6 +879,39 @@ static int ssl_parse_client_hello(mbedtls_ssl_context *ssl) */ if ((ret = mbedtls_ssl_read_record(ssl, 0)) != 0) { MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record ", ret); + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + /* + * In the case of an alert message corresponding to the termination of + * a previous connection, `ssl_parse_record_header()` and then + * `mbedtls_ssl_read_record()` may return + * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD because of a non zero epoch. + * + * Historically, the library has returned + * MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE in this situation. + * The sample program dtls_server.c relies on this behavior + * (see + * https://github.com/Mbed-TLS/mbedtls/blob/d5e35a376bee23fad0b17f2e3e94a32ce4017c64/programs/ssl/dtls_server.c#L295), + * and user applications may rely on it as well. + * + * For compatibility, map MBEDTLS_ERR_SSL_UNEXPECTED_RECORD + * to MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE here. + * + * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD does not appear to be + * used to detect a specific error condition, so this mapping + * should not remove any meaningful distinction. + */ + if ((ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) +#if defined(MBEDTLS_SSL_RENEGOTIATION) + && (ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE) +#endif + ) { + if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) { + ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; + } + } +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + return ret; } diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 270dcd0e6e..dc7c776830 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -1755,6 +1755,11 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; } + if (handshake->key_exchange_mode != + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) { + hrr_required = (no_usable_share_for_key_agreement != 0); + } + #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) if (handshake->key_exchange_mode & MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL) { @@ -1765,17 +1770,12 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, ((unsigned) psk.ciphersuite_info->id), psk.ciphersuite_info->name)); - if (psk.type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) { + if (psk.type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION && (!hrr_required)) { handshake->resume = 1; } } #endif - if (handshake->key_exchange_mode != - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) { - hrr_required = (no_usable_share_for_key_agreement != 0); - } - mbedtls_ssl_optimize_checksum(ssl, handshake->ciphersuite_info); return hrr_required ? SSL_CLIENT_HELLO_HRR_REQUIRED : SSL_CLIENT_HELLO_OK; @@ -1948,6 +1948,9 @@ static int ssl_tls13_process_client_hello(mbedtls_ssl_context *ssl) /* * Version 1.2 of the protocol has to be used for the handshake. + * If we have sent an HRR, then the second ClientHello is inconsistent + * with the first one and we abort the handshake with an `illegal_parameter` + * fatal alert. * If TLS 1.2 is not supported, abort the handshake. Otherwise, set the * ssl->keep_current_message flag for the ClientHello to be kept and parsed * as a TLS 1.2 ClientHello. We also change ssl->tls_version to @@ -1955,7 +1958,12 @@ static int ssl_tls13_process_client_hello(mbedtls_ssl_context *ssl) * will dispatch to the TLS 1.2 state machine. */ if (SSL_CLIENT_HELLO_TLS1_2 == parse_client_hello_ret) { - /* Check if server supports TLS 1.2 */ + if (ssl->handshake->hello_retry_request_flag) { + MBEDTLS_SSL_DEBUG_MSG(1, ("Non compliant 2nd ClientHello, TLS 1.2 version")); + MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, + MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); + return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; + } if (!mbedtls_ssl_conf_is_tls12_enabled(ssl->conf)) { MBEDTLS_SSL_DEBUG_MSG( 1, ("TLS 1.2 not supported.")); diff --git a/library/x509_create.c b/library/x509_create.c index 370eb9b2e1..e424cbb47c 100644 --- a/library/x509_create.c +++ b/library/x509_create.c @@ -487,6 +487,9 @@ int mbedtls_x509_string_to_names(mbedtls_asn1_named_data **head, const char *nam } else { oid.len = strlen(attr_descr->oid); oid.p = mbedtls_calloc(1, oid.len); + if (oid.p == NULL) { + return MBEDTLS_ERR_X509_ALLOC_FAILED; + } memcpy(oid.p, attr_descr->oid, oid.len); numericoid = 0; } diff --git a/library/x509_crt.c b/library/x509_crt.c index 8fea9bf925..3232760ea2 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -2719,22 +2719,25 @@ static int x509_inet_pton_ipv6(const char *src, void *dst) if (*p == '\0') { break; } else if (*p == '.') { - /* Don't accept IPv4 too early or late */ - if ((nonzero_groups == 0 && zero_group_start == -1) || + /* Don't accept IPv4 too early or late: + * - The first 6 nonzero groups must be 16 bit pieces of address delimited by ':' + * - This might be fully or partially represented with compressed syntax (a zero + * group "::") + */ + if ((nonzero_groups < 6 && zero_group_start == -1) || nonzero_groups >= 7) { break; } - /* Walk back to prior ':', then parse as IPv4-mapped */ - int steps = 4; + /* Walk back to prior ':', then parse as IPv4-mapped. + * At this point nonzero_groups == 6 or zero_group_start >= 0. Either way we have a + * ':' before the current position and still inside the buffer. Thus it is safe to + * search back for that ':' without any further checks. + */ do { p--; - steps--; - } while (*p != ':' && steps > 0); + } while (*p != ':'); - if (*p != ':') { - break; - } p++; nonzero_groups--; if (x509_inet_pton_ipv4((const char *) p, diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index f2e8eff47a..79cbad877d 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -4131,55 +4131,7 @@ close_notify: } while (ret == MBEDTLS_ERR_SSL_WANT_WRITE); ret = 0; - /* - * In the DTLS case, attempt to read a possible response to the close - * notification. This avoids reconnecting to the same client when we - * reset and later receive its close-notification response during - * step 3 (waiting for a client to connect). - * - * Stop waiting for the response if the connection has already ended. - * - * The waiting loop below relies on mbedtls_ssl_read() returning regularly - * in order to keep the total waiting time approximately bounded to 1s. If - * no read timeout is configured (see the read_timeout option), or if the - * configured timeout is close to or larger than 1s, the total waiting time - * may exceed 1s by a significant margin. - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) && defined(MBEDTLS_HAVE_TIME) - if (opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - mbedtls_ms_time_t start = mbedtls_ms_time(); - for (;;) { - ret = mbedtls_ssl_read(&ssl, buf, opt.buffer_size); - /* - * mbedtls_ssl_read() returned some data or timed out, loop if we - * have not spent already too much time, quite arbitrarily 1s. - */ - if ((ret > 0) || (ret == MBEDTLS_ERR_SSL_TIMEOUT)) { - if ((mbedtls_ms_time() - start) < 1000) { - continue; - } - } - - if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { - mbedtls_printf(" done, received client close notification.\n"); - } else { - /* ret = 0, silent transport EOF or ret < 0 except - * MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY. Note that we do not - * handle specifically the non-fatal error codes like - * MBEDTLS_ERR_SSL_WANT_READ as we do not really expect them - * here. - */ - mbedtls_printf(" done\n"); - } - break; - } - ret = 0; - } else -#endif /* MBEDTLS_SSL_PROTO_DTLS && MBEDTLS_HAVE_TIME */ - { - mbedtls_printf(" done\n"); - } - fflush(stdout); + mbedtls_printf(" done\n"); #if defined(MBEDTLS_SSL_CACHE_C) if (opt.cache_remove > 0) { diff --git a/tests/compat.sh b/tests/compat.sh index 3f44c984fb..2b6f454127 100755 --- a/tests/compat.sh +++ b/tests/compat.sh @@ -557,7 +557,6 @@ setup_arguments() # with OpenSSL 1.0.1h, -www, -WWW and -HTTP break DTLS handshakes if is_dtls "$MODE"; then O_SERVER_ARGS="$O_SERVER_ARGS" - M_SERVER_ARGS="$M_SERVER_ARGS read_timeout=1000" else O_SERVER_ARGS="$O_SERVER_ARGS -www" fi diff --git a/tests/include/test/ssl_helpers.h b/tests/include/test/ssl_helpers.h index d019c5065e..a653c9643e 100644 --- a/tests/include/test/ssl_helpers.h +++ b/tests/include/test/ssl_helpers.h @@ -68,12 +68,44 @@ #define MBEDTLS_CAN_HANDLE_RSA_TEST_KEY #endif +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ + defined(PSA_WANT_ECC_SECP_R1_384) && \ + defined(PSA_WANT_ALG_SHA_384) +#define MBEDTLS_CAN_HANDLE_ECDSA_TEST_KEY +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ + defined(PSA_WANT_ECC_SECP_R1_256) && \ + defined(PSA_WANT_ALG_SHA_256) +#define MBEDTLS_CAN_HANDLE_ECDSA_CLIENT_TEST_KEY +#endif + +#if defined(PSA_WANT_ECC_MONTGOMERY_255) || \ + defined(PSA_WANT_ECC_SECP_R1_256) || \ + defined(PSA_WANT_ECC_SECP_R1_384) || \ + defined(PSA_WANT_ECC_MONTGOMERY_448) || \ + defined(PSA_WANT_ECC_SECP_R1_521) || \ + defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256) || \ + defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384) || \ + defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512) +#define MBEDTLS_TEST_HAS_DEFAULT_EC_GROUP +#endif + #if defined(PSA_WANT_ALG_GCM) || \ defined(PSA_WANT_ALG_CCM) || \ defined(PSA_WANT_ALG_CHACHA20_POLY1305) #define MBEDTLS_TEST_HAS_AEAD_ALG #endif +/* + * To use the test keys we need PSA_WANT_ALG_SHA_256. Some test cases need an additional hash that + * is configured by default (see mbedtls_ssl_config_defaults()), but it doesn't matter which one. + */ +#if defined(PSA_WANT_ALG_SHA_512) || \ + defined(PSA_WANT_ALG_SHA_384) +#define MBEDTLS_TEST_HAS_ADDITIONAL_HASH +#endif + enum { #define MBEDTLS_SSL_TLS1_3_LABEL(name, string) \ tls13_label_ ## name, diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py index 2bd4bd8162..b6f18c5b88 100755 --- a/tests/scripts/analyze_outcomes.py +++ b/tests/scripts/analyze_outcomes.py @@ -50,6 +50,15 @@ class CoverageTask(outcome_analysis.CoverageTask): # TLS doesn't use restartable ECDH yet. # https://github.com/Mbed-TLS/mbedtls/issues/7294 re.compile(r'EC restart:.*no USE_PSA.*'), + # The following test fails intermittently on the CI with a frequency + # that significantly impacts CI throughput. They are thus disabled + # for the time being. See + # https://github.com/Mbed-TLS/mbedtls/issues/10652 for more + # information. + 'DTLS proxy: 3d, openssl client, fragmentation', + 'DTLS proxy: 3d, openssl client, fragmentation, nbio', + 'DTLS proxy: 3d, gnutls client, fragmentation', + 'DTLS proxy: 3d, gnutls client, fragmentation, nbio=2', ], 'test_suite_config.mbedtls_boolean': [ # Missing coverage of test configurations. diff --git a/tests/scripts/components-configuration-tls.sh b/tests/scripts/components-configuration-tls.sh index d017eef182..5a77c4defc 100644 --- a/tests/scripts/components-configuration-tls.sh +++ b/tests/scripts/components-configuration-tls.sh @@ -165,7 +165,6 @@ component_test_tls1_2_ccm_psk_dtls () { msg "build: configs/config-ccm-psk-dtls1_2.h" MBEDTLS_CONFIG="configs/config-ccm-psk-dtls1_2.h" CRYPTO_CONFIG="configs/crypto-config-ccm-psk-tls1_2.h" - tf-psa-crypto/scripts/config.py -f "$CRYPTO_CONFIG" set MBEDTLS_HAVE_TIME CC=$ASAN_CC cmake -DMBEDTLS_CONFIG_FILE="$MBEDTLS_CONFIG" -DTF_PSA_CRYPTO_CONFIG_FILE="$CRYPTO_CONFIG" -D CMAKE_BUILD_TYPE:String=Asan . make diff --git a/tests/scripts/components-configuration-x509.sh b/tests/scripts/components-configuration-x509.sh index 8010a2a2e6..66e9b16da8 100644 --- a/tests/scripts/components-configuration-x509.sh +++ b/tests/scripts/components-configuration-x509.sh @@ -28,8 +28,9 @@ component_test_sw_inet_pton () { # MBEDTLS_TEST_HOOKS required for x509_crt_parse_cn_inet_pton scripts/config.py set MBEDTLS_TEST_HOOKS - $MAKE_COMMAND CFLAGS="-DMBEDTLS_TEST_SW_INET_PTON" + CC=$ASAN_CC CFLAGS="-DMBEDTLS_TEST_SW_INET_PTON" cmake -D CMAKE_BUILD_TYPE:String=Asan . + make msg "test: default plus MBEDTLS_TEST_SW_INET_PTON" - $MAKE_COMMAND test + make test } diff --git a/tests/src/certs.c b/tests/src/certs.c index c45f0628c0..b9ba13b7ee 100644 --- a/tests/src/certs.c +++ b/tests/src/certs.c @@ -443,7 +443,7 @@ const unsigned char *mbedtls_test_cas_der[] = { mbedtls_test_ca_crt_rsa_sha1_der, #endif /* PSA_WANT_ALG_SHA_1 */ #endif /* MBEDTLS_RSA_C */ -#if defined(PSA_HAVE_ALG_SOME_ECDSA) +#if defined(PSA_HAVE_ALG_SOME_ECDSA) && defined(PSA_WANT_ECC_SECP_R1_384) mbedtls_test_ca_crt_ec_der, #endif /* PSA_HAVE_ALG_SOME_ECDSA */ NULL @@ -458,7 +458,7 @@ const size_t mbedtls_test_cas_der_len[] = { sizeof(mbedtls_test_ca_crt_rsa_sha1_der), #endif /* PSA_WANT_ALG_SHA_1 */ #endif /* MBEDTLS_RSA_C */ -#if defined(PSA_HAVE_ALG_SOME_ECDSA) +#if defined(PSA_HAVE_ALG_SOME_ECDSA) && defined(PSA_WANT_ECC_SECP_R1_384) sizeof(mbedtls_test_ca_crt_ec_der), #endif /* PSA_HAVE_ALG_SOME_ECDSA */ 0 diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index 83dac17419..db29413de6 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -99,8 +99,10 @@ void mbedtls_test_free_handshake_options( mbedtls_test_handshake_test_options *opts) { #if defined(MBEDTLS_SSL_CACHE_C) - mbedtls_ssl_cache_free(opts->cache); - mbedtls_free(opts->cache); + if (opts->cache != NULL) { + mbedtls_ssl_cache_free(opts->cache); + mbedtls_free(opts->cache); + } #else (void) opts; #endif diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 370a988791..47ff800ed1 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -9992,7 +9992,7 @@ run_test "DTLS reassembly: no fragmentation (gnutls client)" \ "$G_NEXT_CLI -u --mtu 2048 --insecure 127.0.0.1" \ 0 \ -S "found fragmented DTLS handshake message" \ - -S "error" + -s "HTTP/1.0 200 OK" requires_gnutls requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 @@ -10002,7 +10002,7 @@ run_test "DTLS reassembly: some fragmentation (gnutls client)" \ 0 \ -s "found fragmented DTLS handshake message" \ -s "Certificate handshake message has been buffered and reassembled" \ - -S "error" + -s "HTTP/1.0 200 OK" # Set the MTU to 128 bytes. The minimum size of a DTLS 1.2 record # containing a ClientHello handshake message is 69 bytes, without any cookie, @@ -10017,7 +10017,7 @@ run_test "DTLS reassembly: more fragmentation (gnutls client)" \ "$G_NEXT_CLI -u --mtu 103 --insecure 127.0.0.1" \ 0 \ -s "ClientHello handshake message has been buffered and reassembled" \ - -S "error" + -s "HTTP/1.0 200 OK" requires_gnutls requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 @@ -10026,7 +10026,7 @@ run_test "DTLS reassembly: more fragmentation, nbio (gnutls client)" \ "$G_NEXT_CLI -u --mtu 103 --insecure 127.0.0.1" \ 0 \ -s "ClientHello handshake message has been buffered and reassembled" \ - -S "error" + -s "HTTP/1.0 200 OK" # No fragmentation and renegotiation tests with GnuTLS client as the feature # does not work properly. @@ -10067,7 +10067,7 @@ run_test "DTLS reassembly: no fragmentation (openssl client)" \ "$O_NEXT_CLI -dtls -mtu 2048 -cert $DATA_FILES_PATH/server5.crt -key $DATA_FILES_PATH/server5.key" \ 0 \ -S "found fragmented DTLS handshake message" \ - -S "error" + -s "HTTP/1.0 200 OK" # Minimum possible MTU for OpenSSL server: 256 bytes. # We expect the client Certificate handshake message to be fragmented and @@ -10082,7 +10082,7 @@ run_test "DTLS reassembly: some fragmentation (openssl client)" \ 0 \ -s "found fragmented DTLS handshake message" \ -s "Certificate handshake message has been buffered and reassembled" \ - -S "error" + -s "HTTP/1.0 200 OK" requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 run_test "DTLS reassembly: fragmentation, nbio (openssl client)" \ @@ -10091,7 +10091,7 @@ run_test "DTLS reassembly: fragmentation, nbio (openssl client)" \ 0 \ -s "found fragmented DTLS handshake message" \ -s "Certificate handshake message has been buffered and reassembled" \ - -S "error" + -s "HTTP/1.0 200 OK" # Tests for sending fragmented handshake messages with DTLS # @@ -12183,6 +12183,10 @@ run_test "DTLS proxy: 3d, openssl client" \ 0 \ -s "HTTP/1.0 200 OK" +# The following test fails intermittently on the CI with a frequency that +# significantly impacts CI throughput. Disable it for the time being. +# See https://github.com/Mbed-TLS/mbedtls/issues/10652 for more information. +skip_next_test requires_openssl_next client_needs_more_time 8 not_with_valgrind # risk of non-mbedtls peer timing out @@ -12196,6 +12200,10 @@ run_test "DTLS proxy: 3d, openssl client, fragmentation" \ -s "found fragmented DTLS handshake message" \ -s "Certificate handshake message has been buffered and reassembled" +# The following test fails intermittently on the CI with a frequency that +# significantly impacts CI throughput. Disable it for the time being. +# See https://github.com/Mbed-TLS/mbedtls/issues/10652 for more information. +skip_next_test requires_openssl_next client_needs_more_time 8 not_with_valgrind # risk of non-mbedtls peer timing out @@ -12264,6 +12272,11 @@ run_test "DTLS proxy: 3d, gnutls client" \ # fragmentation to remain the case across GnuTLS version updates. Avoid using a # smaller MTU, as the smaller the MTU, the more likely the handshake is to fail # in this very unreliable connection emulation. + +# The following test fails intermittently on the CI with a frequency that +# significantly impacts CI throughput. Disable it for the time being. +# See https://github.com/Mbed-TLS/mbedtls/issues/10652 for more information. +skip_next_test requires_gnutls client_needs_more_time 8 not_with_valgrind # risk of non-mbedtls peer timing out @@ -12276,6 +12289,10 @@ run_test "DTLS proxy: 3d, gnutls client, fragmentation" \ -s "HTTP/1.0 200 OK" \ -s "ClientHello handshake message has been buffered and reassembled" +# The following test fails intermittently on the CI with a frequency that +# significantly impacts CI throughput. Disable it for the time being. +# See https://github.com/Mbed-TLS/mbedtls/issues/10652 for more information. +skip_next_test requires_gnutls client_needs_more_time 8 not_with_valgrind # risk of non-mbedtls peer timing out diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 0d635ee6c8..881d502ed5 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3530,3 +3530,22 @@ ssl_get_alert_after_fatal Default verify_result before doing a handshake verify_result_without_handshake + +TLS 1.3 - HRR then TLS 1.2 second ClientHello +tls13_hrr_then_tls12_second_client_hello + +Baseline for: Server using sig_alg not offered by the client - RSA with SHA256 +depends_on:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY:PSA_WANT_ALG_SHA_256 +send_invalid_sig_alg:MBEDTLS_SSL_SIG_RSA:MBEDTLS_SSL_HASH_SHA256:0 + +Negative Test: Server using sig_alg not offered by the client - RSA with SHA256 +depends_on:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY:PSA_WANT_ALG_SHA_256 +send_invalid_sig_alg:MBEDTLS_SSL_SIG_RSA:MBEDTLS_SSL_HASH_SHA256:MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER + +Baseline for: Server using sig_alg not offered by the client - ECDSA with SHA512 +depends_on:MBEDTLS_CAN_HANDLE_ECDSA_TEST_KEY:MBEDTLS_CAN_HANDLE_ECDSA_CLIENT_TEST_KEY:PSA_WANT_ALG_SHA_512 +send_invalid_sig_alg:MBEDTLS_SSL_SIG_ECDSA:MBEDTLS_SSL_HASH_SHA512:0 + +Negative Test: Server using sig_alg not offered by the client - ECDSA with SHA512 +depends_on:MBEDTLS_CAN_HANDLE_ECDSA_TEST_KEY:MBEDTLS_CAN_HANDLE_ECDSA_CLIENT_TEST_KEY:PSA_WANT_ALG_SHA_512 +send_invalid_sig_alg:MBEDTLS_SSL_SIG_ECDSA:MBEDTLS_SSL_HASH_SHA512:MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index cb9c2fbeeb..39457c9047 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -5725,6 +5725,134 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_ALG_SHA_256:MBEDTLS_TEST_HAS_ADDITIONAL_HASH:MBEDTLS_TEST_HAS_DEFAULT_EC_GROUP*/ +void send_invalid_sig_alg(int sig, int hash, int expected_ret) +{ + // This is a test about the client behaviour in case it receives a key exchange signed with a + // sig_alg it didn't specify in the client hello. The input specifies a target_sig_alg, which we + // make sure that the client does not offer but the server does. Then we make the server believe + // that target_sig_alg is the only one the client offered. + + // Remark: We need an additional hash algorithm offered, because if we don't have it, the server + // realises too early that there is no common ground and we don't get the chance to manipulate + // it. This is why we need MBEDTLS_TEST_HAS_ADDITIONAL_HASH in the requirements. + + enum { BUFFSIZE = 16384 }; + uint16_t *client_sig_algs = NULL; + mbedtls_test_ssl_endpoint server, client; + memset(&server, 0, sizeof(server)); + memset(&client, 0, sizeof(client)); + mbedtls_test_handshake_test_options options; + memset(&options, 0, sizeof(options)); + + uint16_t target_sig_alg = ((hash << 8) | sig); + + mbedtls_test_init_handshake_options(&options); + + // Make sure the server has credentials for target_sig_alg + if (sig == MBEDTLS_SSL_SIG_ECDSA) { + options.pk_alg = MBEDTLS_PK_ECDSA; + } else { + options.pk_alg = MBEDTLS_PK_RSA; + } + + // Force a ciphersuite where target_sig_alg is relevant + if (sig == MBEDTLS_SSL_SIG_ECDSA) { + options.cipher = "TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256"; + } else { + options.cipher = "TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256"; + } + + // Force TLS 1.2 as this test is a non-regression test for a bug in TLS 1.2 client and TLS 1.3 + // behaviour in this regard is substantially different. + options.client_max_version = MBEDTLS_SSL_VERSION_TLS1_2; + options.server_max_version = MBEDTLS_SSL_VERSION_TLS1_2; + +#if defined(MBEDTLS_DEBUG_C) + mbedtls_test_ssl_log_pattern cli_pattern; + cli_pattern.pattern = "that was not offered"; + cli_pattern.counter = 0; + options.cli_log_obj = &cli_pattern; + options.cli_log_fun = mbedtls_test_ssl_log_analyzer; + // Add loggers for easier debugging - we are not looking for any patterns in the server logs. + // To turn on debug output, uncomment the threshold line and set the macro in the definition + // of mbedtls_test_ssl_log_analyzer(). + options.srv_log_obj = NULL; + options.srv_log_fun = mbedtls_test_ssl_log_analyzer; + mbedtls_debug_set_threshold(3); +#endif + + int ret = -1; + + PSA_INIT(); + + ret = mbedtls_test_ssl_endpoint_init_conf(&client, MBEDTLS_SSL_IS_CLIENT, &options); + TEST_EQUAL(ret, 0); + + // Remove the target signature algorithm from the client's list + size_t client_sig_algs_len = 0; + while (client.conf.sig_algs[client_sig_algs_len++] != MBEDTLS_TLS1_3_SIG_NONE) { + ; + } + client_sig_algs_len--; + + TEST_CALLOC(client_sig_algs, client_sig_algs_len); + size_t j = 0; + for (size_t i = 0; client.conf.sig_algs[i] != MBEDTLS_TLS1_3_SIG_NONE; i++) { + if (client.conf.sig_algs[i] != target_sig_alg) { + client_sig_algs[j++] = client.conf.sig_algs[i]; + } + } + TEST_ASSERT(j < client_sig_algs_len); + client_sig_algs[j] = MBEDTLS_TLS1_3_SIG_NONE; + mbedtls_ssl_conf_sig_algs(&client.conf, client_sig_algs); + + ret = mbedtls_test_ssl_endpoint_init_ssl(&client, &options); + TEST_EQUAL(ret, 0); + + ret = mbedtls_test_ssl_endpoint_init(&server, MBEDTLS_SSL_IS_SERVER, + &options); + TEST_EQUAL(ret, 0); + + ret = mbedtls_test_mock_socket_connect(&server.socket, &client.socket, + BUFFSIZE); + TEST_EQUAL(ret, 0); + + // Move the connection to the point before the server sending the key exchange message + ret = mbedtls_test_move_handshake_to_state(&server.ssl, &client.ssl, + MBEDTLS_SSL_SERVER_KEY_EXCHANGE); + TEST_EQUAL(ret, 0); + + if (expected_ret != 0) { + // Make the server believe that the only sig_alg the client accepts is target_sig_alg + server.ssl.handshake->received_sig_algs[0] = target_sig_alg; + server.ssl.handshake->received_sig_algs[1] = MBEDTLS_TLS1_3_SIG_NONE; + } + + // Move the connection to a state where it is certain that the client has parsed the server key + // exchange + ret = mbedtls_test_move_handshake_to_state(&client.ssl, &server.ssl, + MBEDTLS_SSL_CERTIFICATE_REQUEST); + TEST_EQUAL(ret, expected_ret); + +#if defined(MBEDTLS_DEBUG_C) + if (expected_ret != 0) { + TEST_EQUAL(cli_pattern.counter, 1); + } +#endif + +exit: +#if defined(MBEDTLS_DEBUG_C) + mbedtls_debug_set_threshold(0); +#endif + mbedtls_test_free_handshake_options(&options); + mbedtls_test_ssl_endpoint_free(&server); + mbedtls_test_ssl_endpoint_free(&client); + mbedtls_free(client_sig_algs); + PSA_DONE(); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:PSA_WANT_ECC_SECP_R1_384:PSA_WANT_ALG_SHA_256 */ void ssl_tls_exporter_consistent_result(int proto, int exported_key_length, int use_context) { @@ -6083,3 +6211,142 @@ exit: PSA_DONE(); } /* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_TEST_HAS_TLS1_3_CHACHA20_POLY1305_SHA256:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:PSA_WANT_ALG_SHA_256:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384:PSA_HAVE_ALG_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_DEBUG_C */ +void tls13_hrr_then_tls12_second_client_hello() +{ + int ret = -1; + mbedtls_test_ssl_endpoint client_ep, server_ep; + memset(&client_ep, 0, sizeof(client_ep)); + memset(&server_ep, 0, sizeof(server_ep)); + mbedtls_test_handshake_test_options client_options; + mbedtls_test_handshake_test_options server_options; + mbedtls_ssl_session saved_session; + mbedtls_test_ssl_log_pattern server_pattern = + { "Non compliant 2nd ClientHello, TLS 1.2 version", 0 }; + uint16_t group_list[3] = { + MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1, + MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1, + MBEDTLS_SSL_IANA_TLS_GROUP_NONE + }; + const int tls12_ciphersuite_list[2] = { + MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + 0 + }; + + mbedtls_test_init_handshake_options(&client_options); + mbedtls_test_init_handshake_options(&server_options); + mbedtls_ssl_session_init(&saved_session); + + PSA_INIT(); + + /* + * Run first handshake to get a ticket from the server. + */ + client_options.pk_alg = MBEDTLS_PK_ECDSA; + client_options.group_list = group_list; + client_options.cipher = "TLS1-3-CHACHA20-POLY1305-SHA256"; + server_options.pk_alg = MBEDTLS_PK_ECDSA; + server_options.group_list = group_list; + + ret = mbedtls_test_get_tls13_ticket(&client_options, &server_options, + &saved_session); + TEST_EQUAL(ret, 0); + + /* + * Prepare for handshake with the ticket. + */ + /* Remove the group SECP256R1 from the list of groups supported by the + * server. Since it is the client's preferred group, the client will + * send a key share only for SECP256R1, forcing the server to send a HRR. + */ + server_options.group_list = group_list + 1; + + ret = mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT, + &client_options); + TEST_EQUAL(ret, 0); + + server_options.srv_log_fun = mbedtls_test_ssl_log_analyzer; + server_options.srv_log_obj = &server_pattern; + ret = mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER, + &server_options); + TEST_EQUAL(ret, 0); + + mbedtls_ssl_conf_session_tickets_cb(&server_ep.conf, + mbedtls_test_ticket_write, + mbedtls_test_ticket_parse, + NULL); + + ret = mbedtls_test_mock_socket_connect(&(client_ep.socket), + &(server_ep.socket), 1024); + TEST_EQUAL(ret, 0); + + ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session); + TEST_EQUAL(ret, 0); + + /* + * Progress the handshake up to the point where the server has sent the + * HRR and the client has received and processed the server HRR but not + * written the second ClientHello in response to the HRR. + */ + ret = mbedtls_test_move_handshake_to_state( + &(server_ep.ssl), &(client_ep.ssl), + MBEDTLS_SSL_HELLO_RETRY_REQUEST); + TEST_EQUAL(ret, 0); + TEST_EQUAL(client_ep.ssl.state, MBEDTLS_SSL_SERVER_HELLO); + + ret = mbedtls_test_move_handshake_to_state( + &(client_ep.ssl), &(server_ep.ssl), + MBEDTLS_SSL_CLIENT_HELLO); + TEST_EQUAL(ret, 0); + TEST_EQUAL(server_ep.ssl.state, MBEDTLS_SSL_CLIENT_HELLO); + + #if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) + /* If the compatibility mode is enabled, filter the dummy change_cipher_spec + * record sent by the server after the HRR. Otherwise, as we have switched + * the client to TLS 1.2 it would fail when reading this record. + */ + ret = mbedtls_ssl_read_record(&(client_ep.ssl), 0); + TEST_EQUAL(ret, MBEDTLS_ERR_SSL_WANT_READ); + #endif + + /* + * The client has just received the server's HRR and is expected to send a + * second ClientHello. Instead of sending a compliant second TLS 1.3 + * ClientHello, we want it to send a TLS 1.2-only ClientHello. To achieve + * this, we reset the client with a TLS 1.2-only configuration before + * resuming the handshake with the server. + */ + client_ep.ssl.tls_version = MBEDTLS_SSL_VERSION_TLS1_2; + mbedtls_ssl_conf_min_tls_version(&client_ep.conf, MBEDTLS_SSL_VERSION_TLS1_2); + mbedtls_ssl_conf_max_tls_version(&client_ep.conf, MBEDTLS_SSL_VERSION_TLS1_2); + mbedtls_ssl_conf_ciphersuites(&client_ep.conf, tls12_ciphersuite_list); + + ret = mbedtls_ssl_session_reset(&(client_ep.ssl)); + TEST_EQUAL(ret, 0); + + /* + * Restart and try to complete the handshake on server side which is + * expected to fail early. + */ + + mbedtls_debug_set_threshold(1); + ret = mbedtls_test_move_handshake_to_state( + &(server_ep.ssl), &(client_ep.ssl), + MBEDTLS_SSL_HANDSHAKE_OVER); + TEST_EQUAL(ret, MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); + + TEST_EQUAL(server_pattern.counter, 1); + TEST_EQUAL(client_ep.ssl.state, MBEDTLS_SSL_SERVER_HELLO); + TEST_EQUAL(server_ep.ssl.state, MBEDTLS_SSL_CLIENT_HELLO); + +exit: + mbedtls_test_ssl_endpoint_free(&client_ep); + mbedtls_test_ssl_endpoint_free(&server_ep); + mbedtls_test_free_handshake_options(&client_options); + mbedtls_test_free_handshake_options(&server_options); + mbedtls_ssl_session_free(&saved_session); + mbedtls_debug_set_threshold(0); + PSA_DONE(); +} +/* END_CASE */ diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data index 3c818583fd..5ffdfe71f9 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:"4.0.0" +check_compiletime_version:"4.1.0" Check runtime library version -check_runtime_version:"4.0.0" +check_runtime_version:"4.1.0" Check for MBEDTLS_VERSION_C check_feature:"MBEDTLS_VERSION_C":0 diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index 688c0e5b84..5e91df9107 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -1170,6 +1170,9 @@ x509_crt_parse_cn_inet_pton:"\:\:ffff\:1111.2.3.4":"":0 X509 CRT parse CN: IPv6 invalid address IPv4-mapped #3 x509_crt_parse_cn_inet_pton:"\:\:1.2.3.4\:ffff":"":0 +X509 CRT parse CN: IPv6 invalid address IPv4-mapped #4 +x509_crt_parse_cn_inet_pton:"1.2.3.4\:":"":0 + X509 CRT verification with ca callback: failure depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_1:PSA_HAVE_ALG_SOME_RSA_VERIFY:MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK x509_verify_ca_cb_failure:"../framework/data_files/server1.crt":"../framework/data_files/test-ca.crt":"NULL":MBEDTLS_ERR_X509_FATAL_ERROR diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function index e892ab9a9e..25d229d6f1 100644 --- a/tests/suites/test_suite_x509parse.function +++ b/tests/suites/test_suite_x509parse.function @@ -488,12 +488,22 @@ exit: void x509_crt_parse_cn_inet_pton(const char *cn, data_t *exp, int ref_ret) { uint32_t addr[4]; - size_t addrlen = mbedtls_x509_crt_parse_cn_inet_pton(cn, addr); + + char *cn_local = NULL; + size_t cn_local_len = strlen(cn) + 1; + TEST_CALLOC(cn_local, cn_local_len); + memcpy(cn_local, cn, cn_local_len); + + size_t addrlen = mbedtls_x509_crt_parse_cn_inet_pton(cn_local, addr); TEST_EQUAL(addrlen, (size_t) ref_ret); if (addrlen) { TEST_MEMORY_COMPARE(exp->x, exp->len, addr, addrlen); } + +exit: + mbedtls_free(cn_local); + } /* END_CASE */ diff --git a/tf-psa-crypto b/tf-psa-crypto index ed3c7d281e..29160dd877 160000 --- a/tf-psa-crypto +++ b/tf-psa-crypto @@ -1 +1 @@ -Subproject commit ed3c7d281e710ef44264d29f3157fd572165a74d +Subproject commit 29160dd877d29658279fd683b2ae57b320ddcf09