From be883e19f50d9cb66d881598bb02102eabf3a957 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 22 Jun 2026 14:28:22 +0200 Subject: [PATCH 01/17] include: ssl: add a typedef for unused data in mbedtls_ssl_config and mbedtls_ssl_context Add mbedtls_ssl_unused_data_t type instead of embedding the union inside both structures. Signed-off-by: Valerio Setti --- include/mbedtls/ssl.h | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 2a6d98ab1c..c2f9507a78 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1324,6 +1324,15 @@ typedef union { void *p; /* typically a pointer to extra data */ } mbedtls_ssl_user_data_t; +/** + * Added at the end of "struct mbedtls_ssl_config" and "struct mbedtls_ssl_context" + * to reserve a field for future use. + */ +typedef union { + size_t number; + void *ptr; +} mbedtls_ssl_unused_data_t; + /** * SSL/TLS configuration to be shared between mbedtls_ssl_context structures. */ @@ -1572,13 +1581,20 @@ struct mbedtls_ssl_config { const mbedtls_x509_crt *MBEDTLS_PRIVATE(dn_hints);/*!< acceptable client cert issuers */ #endif - /* Unused field reserved for future use */ - union { - size_t number; - void *ptr; - } MBEDTLS_PRIVATE(unused); + mbedtls_ssl_unused_data_t MBEDTLS_PRIVATE(unused); }; +/* + * Warning: whenever a change is applied to "mbedtls_ssl_context" please re-run + * the script "tests/scripts/generate_ssl_session_reset_check.py". + * Please note that this script has some limitation that should be considered + * when modifing "mbedtls_ssl_context": + * - Parsed structure must start with struct "mbedtls_ssl_context {" + * (not "typedef struct {"). + * - It must end with "}}" in column 0. + * - Must not contain "#else" or "#elif" conditionals. + * - Must not contain nested struct/union/enum definitions. + */ struct mbedtls_ssl_context { const mbedtls_ssl_config *MBEDTLS_PRIVATE(conf); /*!< configuration information */ @@ -1861,11 +1877,7 @@ struct mbedtls_ssl_context { */ mbedtls_ssl_user_data_t MBEDTLS_PRIVATE(user_data); - /* Unused field reserved for future use */ - union { - size_t number; - void *ptr; - } MBEDTLS_PRIVATE(unused); + mbedtls_ssl_unused_data_t MBEDTLS_PRIVATE(unused); }; /** From 150f1c7b403887b33f71335eae22daa08e1aad14 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 22 Jun 2026 14:37:41 +0200 Subject: [PATCH 02/17] tests: ssl: split ssl_helpers between public and internal functions Move functions in "ssl_helpers.h" that depend on internal headers to "ssl_helpers_internal.h". This allows to include "ssl_helpers.h" also in programs (which do not have access to internal headers). Signed-off-by: Valerio Setti --- tests/include/test/ssl_helpers.h | 92 ---------------- tests/include/test/ssl_helpers_internal.h | 110 +++++++++++++++++++ tests/src/test_helpers/ssl_helpers.c | 2 + tests/suites/test_suite_ssl.function | 1 + tests/suites/test_suite_ssl_decrypt.function | 1 + 5 files changed, 114 insertions(+), 92 deletions(-) create mode 100644 tests/include/test/ssl_helpers_internal.h diff --git a/tests/include/test/ssl_helpers.h b/tests/include/test/ssl_helpers.h index 467a27f342..c416f32eff 100644 --- a/tests/include/test/ssl_helpers.h +++ b/tests/include/test/ssl_helpers.h @@ -16,12 +16,10 @@ #include #include -#include #include #include #if defined(MBEDTLS_SSL_TLS_C) -#include #include #include @@ -31,10 +29,6 @@ #include "mbedtls/ssl_cache.h" #endif -#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ - psa_to_ssl_errors, \ - psa_generic_status_to_mbedtls) - #if defined(MBEDTLS_SSL_PROTO_TLS1_3) #if defined(PSA_WANT_KEY_TYPE_AES) #if defined(PSA_WANT_ALG_GCM) @@ -106,13 +100,6 @@ #define MBEDTLS_TEST_HAS_ADDITIONAL_HASH #endif -enum { -#define MBEDTLS_SSL_TLS1_3_LABEL(name, string) \ - tls13_label_ ## name, - MBEDTLS_SSL_TLS1_3_LABEL_LIST -#undef MBEDTLS_SSL_TLS1_3_LABEL -}; - #if defined(MBEDTLS_SSL_ALPN) #define MBEDTLS_TEST_MAX_ALPN_LIST_SIZE 10 #endif @@ -614,68 +601,6 @@ int mbedtls_test_move_handshake_to_state(mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ -/* - * Helper function setting up inverse record transformations - * using given cipher, hash, EtM mode, authentication tag length, - * and version. - */ -#define CHK(x) \ - do \ - { \ - if (!(x)) \ - { \ - ret = -1; \ - goto cleanup; \ - } \ - } while (0) - -#if MBEDTLS_SSL_CID_OUT_LEN_MAX > MBEDTLS_SSL_CID_IN_LEN_MAX -#define SSL_CID_LEN_MIN MBEDTLS_SSL_CID_IN_LEN_MAX -#else -#define SSL_CID_LEN_MIN MBEDTLS_SSL_CID_OUT_LEN_MAX -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(PSA_WANT_ALG_CBC_NO_PADDING) && defined(PSA_WANT_KEY_TYPE_AES) -int mbedtls_test_psa_cipher_encrypt_helper(mbedtls_ssl_transform *transform, - const unsigned char *iv, - size_t iv_len, - const unsigned char *input, - size_t ilen, - unsigned char *output, - size_t *olen); -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && PSA_WANT_ALG_CBC_NO_PADDING && - PSA_WANT_KEY_TYPE_AES */ - -int mbedtls_test_ssl_build_transforms(mbedtls_ssl_transform *t_in, - mbedtls_ssl_transform *t_out, - int cipher_type, int hash_id, - int etm, int tag_mode, - mbedtls_ssl_protocol_version tls_version, - size_t cid0_len, - size_t cid1_len); - -#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) -/** - * \param[in,out] record The record to prepare. - * It must contain the data to MAC at offset - * `record->data_offset`, of length - * `record->data_length`. - * On success, write the MAC immediately - * after the data and increment - * `record->data_length` accordingly. - * \param[in,out] transform_out The out transform, typically prepared by - * mbedtls_test_ssl_build_transforms(). - * Its HMAC context may be used. Other than that - * it is treated as an input parameter. - * - * \return 0 on success, an `MBEDTLS_ERR_xxx` error code - * or -1 on error. - */ -int mbedtls_test_ssl_prepare_record_mac(mbedtls_record *record, - mbedtls_ssl_transform *transform_out); -#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ - /* * Populate a session structure for serialization tests. * Choose dummy values, mostly non-0 to distinguish from the init default. @@ -775,23 +700,6 @@ void mbedtls_test_ssl_perform_handshake( const mbedtls_test_handshake_test_options *options); #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ -#if defined(MBEDTLS_TEST_HOOKS) -/* - * Tweak vector lengths in a TLS 1.3 Certificate message - * - * \param[in] buf Buffer containing the Certificate message to tweak - * \param[in]]out] end End of the buffer to parse - * \param tweak Tweak identifier (from 1 to the number of tweaks). - * \param[out] expected_result Error code expected from the parsing function - * \param[out] args Arguments of the MBEDTLS_SSL_CHK_BUF_READ_PTR call that - * is expected to fail. All zeroes if no - * MBEDTLS_SSL_CHK_BUF_READ_PTR failure is expected. - */ -int mbedtls_test_tweak_tls13_certificate_msg_vector_len( - unsigned char *buf, unsigned char **end, int tweak, - int *expected_result, mbedtls_ssl_chk_buf_ptr_args *args); -#endif /* MBEDTLS_TEST_HOOKS */ - #if defined(MBEDTLS_SSL_SESSION_TICKETS) int mbedtls_test_ticket_write( void *p_ticket, const mbedtls_ssl_session *session, diff --git a/tests/include/test/ssl_helpers_internal.h b/tests/include/test/ssl_helpers_internal.h new file mode 100644 index 0000000000..7180534f79 --- /dev/null +++ b/tests/include/test/ssl_helpers_internal.h @@ -0,0 +1,110 @@ +/** \file ssl_helpers.h + * + * \brief This file contains helper functions for TLS that rely on private + * headers. + */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef SSL_HELPERS_INTERNAL_H +#define SSL_HELPERS_INTERNAL_H + +#if defined(MBEDTLS_SSL_TLS_C) +#include + +#define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ + psa_to_ssl_errors, \ + psa_generic_status_to_mbedtls) + +enum { +#define MBEDTLS_SSL_TLS1_3_LABEL(name, string) \ + tls13_label_ ## name, + MBEDTLS_SSL_TLS1_3_LABEL_LIST +#undef MBEDTLS_SSL_TLS1_3_LABEL +}; + +/* + * Helper function setting up inverse record transformations + * using given cipher, hash, EtM mode, authentication tag length, + * and version. + */ +#define CHK(x) \ + do \ + { \ + if (!(x)) \ + { \ + ret = -1; \ + goto cleanup; \ + } \ + } while (0) + +#if MBEDTLS_SSL_CID_OUT_LEN_MAX > MBEDTLS_SSL_CID_IN_LEN_MAX +#define SSL_CID_LEN_MIN MBEDTLS_SSL_CID_IN_LEN_MAX +#else +#define SSL_CID_LEN_MIN MBEDTLS_SSL_CID_OUT_LEN_MAX +#endif + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + defined(PSA_WANT_ALG_CBC_NO_PADDING) && defined(PSA_WANT_KEY_TYPE_AES) +int mbedtls_test_psa_cipher_encrypt_helper(mbedtls_ssl_transform *transform, + const unsigned char *iv, + size_t iv_len, + const unsigned char *input, + size_t ilen, + unsigned char *output, + size_t *olen); +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && PSA_WANT_ALG_CBC_NO_PADDING && + PSA_WANT_KEY_TYPE_AES */ + +int mbedtls_test_ssl_build_transforms(mbedtls_ssl_transform *t_in, + mbedtls_ssl_transform *t_out, + int cipher_type, int hash_id, + int etm, int tag_mode, + mbedtls_ssl_protocol_version tls_version, + size_t cid0_len, + size_t cid1_len); + +#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) +/** + * \param[in,out] record The record to prepare. + * It must contain the data to MAC at offset + * `record->data_offset`, of length + * `record->data_length`. + * On success, write the MAC immediately + * after the data and increment + * `record->data_length` accordingly. + * \param[in,out] transform_out The out transform, typically prepared by + * mbedtls_test_ssl_build_transforms(). + * Its HMAC context may be used. Other than that + * it is treated as an input parameter. + * + * \return 0 on success, an `MBEDTLS_ERR_xxx` error code + * or -1 on error. + */ +int mbedtls_test_ssl_prepare_record_mac(mbedtls_record *record, + mbedtls_ssl_transform *transform_out); +#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ + +#if defined(MBEDTLS_TEST_HOOKS) +/* + * Tweak vector lengths in a TLS 1.3 Certificate message + * + * \param[in] buf Buffer containing the Certificate message to tweak + * \param[in]]out] end End of the buffer to parse + * \param tweak Tweak identifier (from 1 to the number of tweaks). + * \param[out] expected_result Error code expected from the parsing function + * \param[out] args Arguments of the MBEDTLS_SSL_CHK_BUF_READ_PTR call that + * is expected to fail. All zeroes if no + * MBEDTLS_SSL_CHK_BUF_READ_PTR failure is expected. + */ +int mbedtls_test_tweak_tls13_certificate_msg_vector_len( + unsigned char *buf, unsigned char **end, int tweak, + int *expected_result, mbedtls_ssl_chk_buf_ptr_args *args); +#endif /* MBEDTLS_TEST_HOOKS */ + +#endif /* MBEDTLS_SSL_TLS_C */ + +#endif /* SSL_HELPERS_INTERNAL_H */ diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index 08cfe252af..780c4f319b 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -9,6 +9,8 @@ */ #include +#include +#include #include "mbedtls/psa_util.h" #include diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index cc73f49aaf..e05cf72bcb 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/tests/suites/test_suite_ssl_decrypt.function b/tests/suites/test_suite_ssl_decrypt.function index 7a22939eb4..dd26537127 100644 --- a/tests/suites/test_suite_ssl_decrypt.function +++ b/tests/suites/test_suite_ssl_decrypt.function @@ -5,6 +5,7 @@ #include #include #include +#include /* END_HEADER */ From 0ff7a2e8b7ac2348fd70d307fcb614ea779d3bf9 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 22 Jun 2026 14:39:15 +0200 Subject: [PATCH 03/17] tests: scripts: add generate_ssl_session_reset_check.py Togethere with the framework counterpart ('ssl_session_reset_check.py') this script is used to automatically generate the function 'mbedtls_test_ssl_check_context_after_session_reset()'. The goal of this function is to verify that 'mbedtls_ssl_session_reset()' properly handled (reset or keep) all the fields of the 'mbedtls_ssl_context' structure. Signed-off-by: Valerio Setti --- .../generate_ssl_session_reset_check.py | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100755 tests/scripts/generate_ssl_session_reset_check.py diff --git a/tests/scripts/generate_ssl_session_reset_check.py b/tests/scripts/generate_ssl_session_reset_check.py new file mode 100755 index 0000000000..fa67134ca4 --- /dev/null +++ b/tests/scripts/generate_ssl_session_reset_check.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python3 +"""Generate test code to validate mbedtls_ssl_session_reset(). +""" + +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + +import scripts_path # pylint: disable=unused-import +from mbedtls_framework import ssl_session_reset_check + +RULES = { + # Fields that are reset + 'state': ssl_session_reset_check.ResetBehavior.RESET, + 'renego_status': ssl_session_reset_check.ResetBehavior.RESET, + 'renego_records_seen': ssl_session_reset_check.ResetBehavior.RESET, + 'early_data_state': ssl_session_reset_check.ResetBehavior.RESET, + 'badmac_seen': ssl_session_reset_check.ResetBehavior.RESET, + 'session_in': ssl_session_reset_check.ResetBehavior.RESET, + 'session_out': ssl_session_reset_check.ResetBehavior.RESET, + 'session': ssl_session_reset_check.ResetBehavior.RESET, + 'transform_in': ssl_session_reset_check.ResetBehavior.RESET, + 'transform_out': ssl_session_reset_check.ResetBehavior.RESET, + 'transform': ssl_session_reset_check.ResetBehavior.RESET, + 'transform_application': ssl_session_reset_check.ResetBehavior.RESET, + 'in_offt': ssl_session_reset_check.ResetBehavior.RESET, + 'in_msgtype': ssl_session_reset_check.ResetBehavior.RESET, + 'in_msglen': ssl_session_reset_check.ResetBehavior.RESET, + 'in_left': ssl_session_reset_check.ResetBehavior.RESET, + 'in_epoch': ssl_session_reset_check.ResetBehavior.RESET, + 'next_record_offset': ssl_session_reset_check.ResetBehavior.RESET, + 'in_window_top': ssl_session_reset_check.ResetBehavior.RESET, + 'in_window': ssl_session_reset_check.ResetBehavior.RESET, + 'in_hslen': ssl_session_reset_check.ResetBehavior.RESET, + 'in_hsfraglen': ssl_session_reset_check.ResetBehavior.RESET, + 'nb_zero': ssl_session_reset_check.ResetBehavior.RESET, + 'keep_current_message': ssl_session_reset_check.ResetBehavior.RESET, + 'in_fatal_alert_recv': ssl_session_reset_check.ResetBehavior.RESET, + 'in_fatal_alert_type': ssl_session_reset_check.ResetBehavior.RESET, + 'send_alert': ssl_session_reset_check.ResetBehavior.RESET, + 'alert_type': ssl_session_reset_check.ResetBehavior.RESET, + 'alert_reason': ssl_session_reset_check.ResetBehavior.RESET, + 'discard_early_data_record': ssl_session_reset_check.ResetBehavior.RESET, + 'total_early_data_size': ssl_session_reset_check.ResetBehavior.RESET, + 'out_msgtype': ssl_session_reset_check.ResetBehavior.RESET, + 'out_msglen': ssl_session_reset_check.ResetBehavior.RESET, + 'out_left': ssl_session_reset_check.ResetBehavior.RESET, + 'cur_out_ctr': ssl_session_reset_check.ResetBehavior.RESET, + 'alpn_chosen': ssl_session_reset_check.ResetBehavior.RESET, + 'dtls_srtp_info': ssl_session_reset_check.ResetBehavior.RESET, + 'cli_id': ssl_session_reset_check.ResetBehavior.RESET, + 'cli_id_len': ssl_session_reset_check.ResetBehavior.RESET, + 'secure_renegotiation': ssl_session_reset_check.ResetBehavior.RESET, + 'verify_data_len': ssl_session_reset_check.ResetBehavior.RESET, + 'own_verify_data': ssl_session_reset_check.ResetBehavior.RESET, + 'peer_verify_data': ssl_session_reset_check.ResetBehavior.RESET, + + # Fields that are preserved during reset + 'conf': ssl_session_reset_check.ResetBehavior.KEEP, + 'f_vrfy': ssl_session_reset_check.ResetBehavior.KEEP, + 'p_vrfy': ssl_session_reset_check.ResetBehavior.KEEP, + 'f_send': ssl_session_reset_check.ResetBehavior.KEEP, + 'f_recv': ssl_session_reset_check.ResetBehavior.KEEP, + 'f_recv_timeout': ssl_session_reset_check.ResetBehavior.KEEP, + 'p_bio': ssl_session_reset_check.ResetBehavior.KEEP, + 'p_timer': ssl_session_reset_check.ResetBehavior.KEEP, + 'f_set_timer': ssl_session_reset_check.ResetBehavior.KEEP, + 'f_get_timer': ssl_session_reset_check.ResetBehavior.KEEP, + 'disable_datagram_packing': ssl_session_reset_check.ResetBehavior.KEEP, + 'mtu': ssl_session_reset_check.ResetBehavior.KEEP, + 'hostname': ssl_session_reset_check.ResetBehavior.KEEP, + 'own_cid': ssl_session_reset_check.ResetBehavior.KEEP, + 'own_cid_len': ssl_session_reset_check.ResetBehavior.KEEP, + 'negotiate_cid': ssl_session_reset_check.ResetBehavior.KEEP, + 'f_export_keys': ssl_session_reset_check.ResetBehavior.KEEP, + 'p_export_keys': ssl_session_reset_check.ResetBehavior.KEEP, + + # Fields which are intentionally not checked. + 'unused': ssl_session_reset_check.ResetBehavior.IGNORE, + + # Pointers which might be reallocated during reset + 'in_buf': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'in_ctr': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'in_hdr': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'in_cid': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'in_len': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'in_iv': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'in_msg': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'out_buf': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'out_ctr': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'out_hdr': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'out_cid': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'out_len': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'out_iv': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'out_msg': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'session_negotiate': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'handshake': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'transform_negotiate': ssl_session_reset_check.ResetBehavior.REALLOCATE, + + # Fields with custom check rules. Rules must be defined in the + # SPECIAL_BEHAVIORS dictionary below. + 'flags': ssl_session_reset_check.ResetBehavior.SPECIAL, + 'tls_version': ssl_session_reset_check.ResetBehavior.SPECIAL, + 'user_data': ssl_session_reset_check.ResetBehavior.SPECIAL, + 'in_buf_len': ssl_session_reset_check.ResetBehavior.SPECIAL, + 'out_buf_len': ssl_session_reset_check.ResetBehavior.SPECIAL, +} + +SPECIAL_BEHAVIORS = { + 'flags': ['TEST_EQUAL((after->flags & ~(MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION)), ' + 'initial.flags)', + 'TEST_EQUAL((before->flags & MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION), ' + + '(after->flags & MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION));'], + 'tls_version': ['TEST_ASSERT(after->tls_version == after->conf->max_tls_version);'], + 'user_data': ['TEST_ASSERT(before->user_data.n == after->user_data.n);'], + 'in_buf_len': ['TEST_ASSERT(after->in_buf_len == MBEDTLS_SSL_IN_BUFFER_LEN);'], + 'out_buf_len': ['TEST_ASSERT(after->out_buf_len == MBEDTLS_SSL_OUT_BUFFER_LEN);'], +} + +NAMED_STRUCTURES = [ + 'dtls_srtp_info', +] + +FIELDS_INFO = ssl_session_reset_check.FieldsInfo(RULES, + SPECIAL_BEHAVIORS, + NAMED_STRUCTURES) + +if __name__ == '__main__': + ssl_session_reset_check.main(FIELDS_INFO) From e19a4cfd8085bd91a3bb59df82e403d0fdd6729a Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 22 Jun 2026 14:49:38 +0200 Subject: [PATCH 04/17] tests: add prototype and implementation of mbedtls_test_ssl_check_context_after_session_reset Ideally the implementation shouldn't be checked in git, but for the time being there is no support in building source code for tests from the binary folder, so it's accepted as a temporary solution. Signed-off-by: Valerio Setti --- tests/include/test/ssl_helpers.h | 17 +++ tests/src/ssl_context_reset_verifier.c | 190 +++++++++++++++++++++++++ 2 files changed, 207 insertions(+) create mode 100644 tests/src/ssl_context_reset_verifier.c diff --git a/tests/include/test/ssl_helpers.h b/tests/include/test/ssl_helpers.h index c416f32eff..6a86937df4 100644 --- a/tests/include/test/ssl_helpers.h +++ b/tests/include/test/ssl_helpers.h @@ -746,6 +746,23 @@ int mbedtls_test_get_tls13_ticket( &psa_type, &psa_bits), \ PSA_ERROR_NOT_SUPPORTED); +/** + * Verify that mbedtls_ssl_session_reset() properly managed fields of the + * mbedtls_ssl_context structure. The expected action on reset depends on the + * specific field. + * + * Note: the code is automatically generated from the python script + * "tests/scripts/generate_ssl_session_reset_check.py". + * + * \param[in] before The SSL context before mbedtls_ssl_session_reset() + * is called on it. This is used for fields that + * should be kept untouched during the reset. + * \param[in] after The SSL context after mbedtls_ssl_session_reset() + * is called on it. + */ +int mbedtls_test_ssl_check_context_after_session_reset(const mbedtls_ssl_context *before, + const mbedtls_ssl_context *after); + #endif /* MBEDTLS_SSL_TLS_C */ #endif /* SSL_HELPERS_H */ diff --git a/tests/src/ssl_context_reset_verifier.c b/tests/src/ssl_context_reset_verifier.c new file mode 100644 index 0000000000..2f106e9067 --- /dev/null +++ b/tests/src/ssl_context_reset_verifier.c @@ -0,0 +1,190 @@ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +/* + * The following function was automatically generated through the script + * ./tests/scripts/generate_ssl_session_reset_check.py. + */ + +#include +#include +#include "mbedtls/psa_util.h" +#include + +#include + +#if defined(MBEDTLS_SSL_TLS_C) + +int mbedtls_test_ssl_check_context_after_session_reset(const mbedtls_ssl_context *before, + const mbedtls_ssl_context *after) +{ + mbedtls_ssl_context initial; + int ret = -1; + + /* Create a freshly initialized SSL context*/ + memset(&initial, 0, sizeof(initial)); + mbedtls_ssl_init(&initial); + TEST_EQUAL(mbedtls_ssl_setup(&initial, after->conf), 0); + + /* *INDENT-OFF* */ + TEST_ASSERT(before->conf == after->conf); + TEST_ASSERT(after->state == initial.state); + TEST_EQUAL((after->flags & ~(MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION)), initial.flags) + TEST_EQUAL((before->flags & MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION), (after->flags & MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION)); +#if defined(MBEDTLS_SSL_RENEGOTIATION) + TEST_ASSERT(after->renego_status == initial.renego_status); +#endif +#if defined(MBEDTLS_SSL_RENEGOTIATION) + TEST_ASSERT(after->renego_records_seen == initial.renego_records_seen); +#endif + TEST_ASSERT(after->tls_version == after->conf->max_tls_version); +#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) + TEST_ASSERT(after->early_data_state == initial.early_data_state); +#endif + TEST_ASSERT(after->badmac_seen == initial.badmac_seen); +#if defined(MBEDTLS_X509_CRT_PARSE_C) + TEST_ASSERT(before->f_vrfy == after->f_vrfy); +#endif +#if defined(MBEDTLS_X509_CRT_PARSE_C) + TEST_ASSERT(before->p_vrfy == after->p_vrfy); +#endif + TEST_ASSERT(before->f_send == after->f_send); + TEST_ASSERT(before->f_recv == after->f_recv); + TEST_ASSERT(before->f_recv_timeout == after->f_recv_timeout); + TEST_ASSERT(before->p_bio == after->p_bio); + TEST_ASSERT(after->session_in == initial.session_in); + TEST_ASSERT(after->session_out == initial.session_out); + TEST_ASSERT(after->session == initial.session); + TEST_ASSERT(after->session_negotiate != NULL); + TEST_ASSERT(after->handshake != NULL); + TEST_ASSERT(after->transform_in == initial.transform_in); + TEST_ASSERT(after->transform_out == initial.transform_out); + TEST_ASSERT(after->transform == initial.transform); +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + TEST_ASSERT(after->transform_negotiate != NULL); +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_3) + TEST_ASSERT(after->transform_application == initial.transform_application); +#endif + TEST_ASSERT(before->p_timer == after->p_timer); + TEST_ASSERT(before->f_set_timer == after->f_set_timer); + TEST_ASSERT(before->f_get_timer == after->f_get_timer); + TEST_ASSERT(after->in_buf != NULL); + TEST_ASSERT(after->in_ctr != NULL); + TEST_ASSERT(after->in_hdr != NULL); +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + TEST_ASSERT(after->in_cid != NULL); +#endif + TEST_ASSERT(after->in_len != NULL); + TEST_ASSERT(after->in_iv != NULL); + TEST_ASSERT(after->in_msg != NULL); + TEST_ASSERT(after->in_offt == initial.in_offt); + TEST_ASSERT(after->in_msgtype == initial.in_msgtype); + TEST_ASSERT(after->in_msglen == initial.in_msglen); + TEST_ASSERT(after->in_left == initial.in_left); +#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) + TEST_ASSERT(after->in_buf_len == MBEDTLS_SSL_IN_BUFFER_LEN); +#endif +#if defined(MBEDTLS_SSL_PROTO_DTLS) + TEST_ASSERT(after->in_epoch == initial.in_epoch); +#endif +#if defined(MBEDTLS_SSL_PROTO_DTLS) + TEST_ASSERT(after->next_record_offset == initial.next_record_offset); +#endif +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) + TEST_ASSERT(after->in_window_top == initial.in_window_top); +#endif +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) + TEST_ASSERT(after->in_window == initial.in_window); +#endif + TEST_ASSERT(after->in_hslen == initial.in_hslen); + TEST_ASSERT(after->in_hsfraglen == initial.in_hsfraglen); + TEST_ASSERT(after->nb_zero == initial.nb_zero); + TEST_ASSERT(after->keep_current_message == initial.keep_current_message); + TEST_ASSERT(after->in_fatal_alert_recv == initial.in_fatal_alert_recv); + TEST_ASSERT(after->in_fatal_alert_type == initial.in_fatal_alert_type); + TEST_ASSERT(after->send_alert == initial.send_alert); + TEST_ASSERT(after->alert_type == initial.alert_type); + TEST_ASSERT(after->alert_reason == initial.alert_reason); +#if defined(MBEDTLS_SSL_PROTO_DTLS) + TEST_EQUAL(before->disable_datagram_packing, after->disable_datagram_packing); +#endif +#if defined(MBEDTLS_SSL_EARLY_DATA) + +#if defined(MBEDTLS_SSL_SRV_C) + TEST_ASSERT(after->discard_early_data_record == initial.discard_early_data_record); +#endif +#endif +#if defined(MBEDTLS_SSL_EARLY_DATA) + TEST_ASSERT(after->total_early_data_size == initial.total_early_data_size); +#endif + TEST_ASSERT(after->out_buf != NULL); + TEST_ASSERT(after->out_ctr != NULL); + TEST_ASSERT(after->out_hdr != NULL); +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + TEST_ASSERT(after->out_cid != NULL); +#endif + TEST_ASSERT(after->out_len != NULL); + TEST_ASSERT(after->out_iv != NULL); + TEST_ASSERT(after->out_msg != NULL); + TEST_ASSERT(after->out_msgtype == initial.out_msgtype); + TEST_ASSERT(after->out_msglen == initial.out_msglen); + TEST_ASSERT(after->out_left == initial.out_left); +#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) + TEST_ASSERT(after->out_buf_len == MBEDTLS_SSL_OUT_BUFFER_LEN); +#endif + TEST_MEMORY_COMPARE(after->cur_out_ctr, sizeof(after->cur_out_ctr), initial.cur_out_ctr, sizeof(initial.cur_out_ctr)); +#if defined(MBEDTLS_SSL_PROTO_DTLS) + TEST_EQUAL(before->mtu, after->mtu); +#endif +#if defined(MBEDTLS_X509_CRT_PARSE_C) + TEST_ASSERT(before->hostname == after->hostname); +#endif +#if defined(MBEDTLS_SSL_ALPN) + TEST_ASSERT(after->alpn_chosen == initial.alpn_chosen); +#endif +#if defined(MBEDTLS_SSL_DTLS_SRTP) + TEST_MEMORY_COMPARE(&(after->dtls_srtp_info), sizeof(after->dtls_srtp_info), &(initial.dtls_srtp_info), sizeof(initial.dtls_srtp_info)); +#endif +#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) + TEST_ASSERT(after->cli_id == initial.cli_id); +#endif +#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) + TEST_ASSERT(after->cli_id_len == initial.cli_id_len); +#endif + TEST_ASSERT(after->secure_renegotiation == initial.secure_renegotiation); +#if defined(MBEDTLS_SSL_RENEGOTIATION) + TEST_ASSERT(after->verify_data_len == initial.verify_data_len); +#endif +#if defined(MBEDTLS_SSL_RENEGOTIATION) + TEST_MEMORY_COMPARE(after->own_verify_data, sizeof(after->own_verify_data), initial.own_verify_data, sizeof(initial.own_verify_data)); +#endif +#if defined(MBEDTLS_SSL_RENEGOTIATION) + TEST_MEMORY_COMPARE(after->peer_verify_data, sizeof(after->peer_verify_data), initial.peer_verify_data, sizeof(initial.peer_verify_data)); +#endif +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + TEST_MEMORY_COMPARE(before->own_cid, sizeof(before->own_cid), after->own_cid, sizeof(after->own_cid)); +#endif +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + TEST_EQUAL(before->own_cid_len, after->own_cid_len); +#endif +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + TEST_EQUAL(before->negotiate_cid, after->negotiate_cid); +#endif + TEST_ASSERT(before->f_export_keys == after->f_export_keys); + TEST_ASSERT(before->p_export_keys == after->p_export_keys); + TEST_ASSERT(before->user_data.n == after->user_data.n); + /* unused is ignored */ + /* *INDENT-ON* */ + + ret = 0; + +exit: + mbedtls_ssl_free(&initial); + + return ret; +} + +#endif /* MBEDTLS_SSL_TLS_C */ From 0e357891576768a03d1b0e519bf38eb8c978835d Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 22 Jun 2026 14:51:24 +0200 Subject: [PATCH 05/17] tests|programs: call check_context_after_session_reset whenever mbedtls_ssl_session_reset Call mbedtls_test_ssl_check_context_after_session_reset both in programs (ssl_client2 and ssl_server2) and tests to ensure that the SSL context has been properly handled when mbedtls_ssl_session_reset was called. Signed-off-by: Valerio Setti --- programs/ssl/ssl_client2.c | 10 ++++++++++ programs/ssl/ssl_server2.c | 9 +++++++++ tests/src/test_helpers/ssl_helpers.c | 8 ++++++++ 3 files changed, 27 insertions(+) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 9dc99c3e0b..ad87e225da 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -22,6 +22,7 @@ int main(void) #else /* !MBEDTLS_SSL_TEST_IMPOSSIBLE && MBEDTLS_SSL_CLI_C */ #include "test/psa_crypto_helpers.h" +#include "test/ssl_helpers.h" /* Size of memory to be allocated for the heap, when using the library's memory * management and MBEDTLS_MEMORY_BUFFER_ALLOC_C is enabled. */ @@ -2800,12 +2801,21 @@ send_request: memset(peer_crt_info, 0, sizeof(peer_crt_info)); #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ + /* Dump the SSL context before resetting it. This will be used below + * to check if the reset function worked properly. */ + mbedtls_ssl_context ssl_before = ssl; if ((ret = mbedtls_ssl_session_reset(&ssl)) != 0) { mbedtls_printf(" failed\n ! mbedtls_ssl_session_reset returned -0x%x\n\n", (unsigned int) -ret); goto exit; } + if (mbedtls_test_ssl_check_context_after_session_reset(&ssl_before, &ssl) != 0) { + mbedtls_printf( + " failed\n ! mbedtls_ssl_session_reset didn't properly reset ssl context\n\n"); + goto exit; + } + while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) { if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 541c6a6b43..b5cdc817b8 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -52,6 +52,7 @@ int main(void) #endif #include "test/psa_crypto_helpers.h" +#include "test/ssl_helpers.h" #include "mbedtls/pk.h" #if defined(MBEDTLS_PK_HAVE_PRIVATE_HEADER) @@ -3271,7 +3272,15 @@ reset: mbedtls_net_free(&client_fd); + /* Dump the SSL context before resetting it. This will be used below + * to check if the reset function worked properly. */ + mbedtls_ssl_context ssl_before = ssl; mbedtls_ssl_session_reset(&ssl); + if (mbedtls_test_ssl_check_context_after_session_reset(&ssl_before, &ssl) != 0) { + mbedtls_printf( + " failed\n ! mbedtls_ssl_session_reset didn't properly reset ssl context\n\n"); + goto exit; + } /* * 3. Wait until a client connects diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index 780c4f319b..0d2687e795 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -1035,6 +1035,14 @@ int mbedtls_test_ssl_endpoint_init( void mbedtls_test_ssl_endpoint_free( mbedtls_test_ssl_endpoint *ep) { + mbedtls_ssl_context ssl_before; + + /* Dump the SSL context before resetting it */ + memcpy(&ssl_before, &(ep->ssl), sizeof(mbedtls_ssl_context)); + + mbedtls_ssl_session_reset(&(ep->ssl)); + /* Check that required fields were properly reset */ + mbedtls_test_ssl_check_context_after_session_reset(&ssl_before, &(ep->ssl)); mbedtls_ssl_free(&(ep->ssl)); mbedtls_ssl_config_free(&(ep->conf)); From 4b086ed04e12a0d621cee6dfbc30ee6f2e74d0bf Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 22 Jun 2026 14:53:21 +0200 Subject: [PATCH 06/17] library: ssl: reset some SSL context's fields in mbedtls_ssl_session_reset Following fields were not properly reset when mbedtls_ssl_session_reset was called: - badmac_seen - dtls_srtp_info - alert_reason - alert_type Signed-off-by: Valerio Setti --- library/ssl_tls.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index e8a44f834c..b1c6c22de1 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1309,6 +1309,8 @@ void mbedtls_ssl_session_reset_msg_layer(mbedtls_ssl_context *ssl, ssl->in_fatal_alert_recv = 0; ssl->in_fatal_alert_type = 0; ssl->send_alert = 0; + ssl->alert_reason = 0; + ssl->alert_type = 0; /* Reset outgoing message writing */ ssl->out_msgtype = 0; @@ -1358,6 +1360,8 @@ int mbedtls_ssl_session_reset_int(mbedtls_ssl_context *ssl, int partial) ssl->flags &= MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION; ssl->tls_version = ssl->conf->max_tls_version; + ssl->badmac_seen = 0; + mbedtls_ssl_session_reset_msg_layer(ssl, partial); /* Reset renegotiation state */ @@ -1383,6 +1387,10 @@ int mbedtls_ssl_session_reset_int(mbedtls_ssl_context *ssl, int partial) ssl->alpn_chosen = NULL; #endif +#if defined(MBEDTLS_SSL_DTLS_SRTP) + memset(&ssl->dtls_srtp_info, 0, sizeof(ssl->dtls_srtp_info)); +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) int free_cli_id = 1; #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) From f8a7d87fe1e7c73fff839c25bab135f389b04fa5 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 22 Jun 2026 14:55:31 +0200 Subject: [PATCH 07/17] changelog: add reset for some fields of the SSL context structure Signed-off-by: Valerio Setti --- ChangeLog.d/security1585.txt | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ChangeLog.d/security1585.txt diff --git a/ChangeLog.d/security1585.txt b/ChangeLog.d/security1585.txt new file mode 100644 index 0000000000..f9f21691db --- /dev/null +++ b/ChangeLog.d/security1585.txt @@ -0,0 +1,6 @@ +Security + * Ensure 'badmac_seen' and 'dtls_srtp_info' fields from 'mbedtls_ssl_context' + are properly zeroized when mbedtls_ssl_session_reset() is called. This + could cause premature DTLS connection failure or incorrect DTLS-SRTP + parameter inheritance for applications reusing an SSL context. + Reported by jjfz123. CVE-2026-50585. From aa6c52b6cd7f992958daef9432946ba09fb29d01 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 23 Jun 2026 18:14:15 +0200 Subject: [PATCH 08/17] include: ssl: fix documentation of mbedtls_ssl_set_cid Specify that the configured CID will apply to all subsequent handshakes not just to the next one. Signed-off-by: Valerio Setti --- include/mbedtls/ssl.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index c2f9507a78..00e28442d6 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -2181,7 +2181,7 @@ void mbedtls_ssl_set_bio(mbedtls_ssl_context *ssl, /** * \brief Configure the use of the Connection ID (CID) - * extension in the next handshake. + * extension in subsequent handshakes. * * Reference: RFC 9146 (or draft-ietf-tls-dtls-connection-id-05 * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05 @@ -2202,7 +2202,7 @@ void mbedtls_ssl_set_bio(mbedtls_ssl_context *ssl, * headers of outgoing messages. * * This API enables or disables the use of the CID extension - * in the next handshake and sets the value of the CID to + * in subsequent handshakes and sets the value of the CID to * be used for incoming messages. * * \param ssl The SSL context to configure. This must be initialized. @@ -2233,11 +2233,11 @@ void mbedtls_ssl_set_bio(mbedtls_ssl_context *ssl, * successful call to this function to run the handshake. * * \note This call cannot guarantee that the use of the CID - * will be successfully negotiated in the next handshake, + * will be successfully negotiated in subsequent handshakes, * because the peer might not support it. Specifically: * - On the Client, enabling the use of the CID through - * this call implies that the `ClientHello` in the next - * handshake will include the CID extension, thereby + * this call implies that the `ClientHello` in subsequent + * handshakes will include the CID extension, thereby * offering the use of the CID to the server. Only if * the `ServerHello` contains the CID extension, too, * the CID extension will actually be put to use. @@ -2260,7 +2260,7 @@ void mbedtls_ssl_set_bio(mbedtls_ssl_context *ssl, * Mbed TLS. * * \return \c 0 on success. In this case, the CID configuration - * applies to the next handshake. + * applies to subsequent handshakes. * \return A negative error code on failure. */ int mbedtls_ssl_set_cid(mbedtls_ssl_context *ssl, From f4dcb5c692e1b2adcc1434cc82e5ceab4bbcef2f Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 23 Jun 2026 22:36:04 +0200 Subject: [PATCH 09/17] changelog: add note for documentation fix for mbedtls_ssl_set_cid Signed-off-by: Valerio Setti --- ChangeLog.d/mbedtls_ssl_set_cid-documentation.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 ChangeLog.d/mbedtls_ssl_set_cid-documentation.txt diff --git a/ChangeLog.d/mbedtls_ssl_set_cid-documentation.txt b/ChangeLog.d/mbedtls_ssl_set_cid-documentation.txt new file mode 100644 index 0000000000..1ad970fdfb --- /dev/null +++ b/ChangeLog.d/mbedtls_ssl_set_cid-documentation.txt @@ -0,0 +1,3 @@ +Bugfix + * Fixed documentation of mbedtls_ssl_set_cid(): the set CID configuration + is applied to all subsequent handshakes, not just to the next one. From 673568a6a16f0e1f4946634fc4edbe90c64ee069 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 23 Jun 2026 22:37:54 +0200 Subject: [PATCH 10/17] tests: generate_ssl_session_reset_check: add missing semicolon in generated file Signed-off-by: Valerio Setti --- tests/scripts/generate_ssl_session_reset_check.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/generate_ssl_session_reset_check.py b/tests/scripts/generate_ssl_session_reset_check.py index fa67134ca4..303f27e251 100755 --- a/tests/scripts/generate_ssl_session_reset_check.py +++ b/tests/scripts/generate_ssl_session_reset_check.py @@ -107,7 +107,7 @@ RULES = { SPECIAL_BEHAVIORS = { 'flags': ['TEST_EQUAL((after->flags & ~(MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION)), ' - 'initial.flags)', + 'initial.flags);', 'TEST_EQUAL((before->flags & MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION), ' + '(after->flags & MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION));'], 'tls_version': ['TEST_ASSERT(after->tls_version == after->conf->max_tls_version);'], From b291d599279c743f1d97018566ae84170d5fa257 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 23 Jun 2026 22:38:41 +0200 Subject: [PATCH 11/17] tests: ssl_context_reset_verifier: add missing semicolon in generated file Signed-off-by: Valerio Setti --- tests/src/ssl_context_reset_verifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/ssl_context_reset_verifier.c b/tests/src/ssl_context_reset_verifier.c index 2f106e9067..a0fda308ec 100644 --- a/tests/src/ssl_context_reset_verifier.c +++ b/tests/src/ssl_context_reset_verifier.c @@ -31,7 +31,7 @@ int mbedtls_test_ssl_check_context_after_session_reset(const mbedtls_ssl_context /* *INDENT-OFF* */ TEST_ASSERT(before->conf == after->conf); TEST_ASSERT(after->state == initial.state); - TEST_EQUAL((after->flags & ~(MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION)), initial.flags) + TEST_EQUAL((after->flags & ~(MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION)), initial.flags); TEST_EQUAL((before->flags & MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION), (after->flags & MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION)); #if defined(MBEDTLS_SSL_RENEGOTIATION) TEST_ASSERT(after->renego_status == initial.renego_status); From 57b2f5d4aa9cc96f8f6db254febe6439218b23a2 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 23 Jun 2026 22:39:41 +0200 Subject: [PATCH 12/17] tests: ssl_helpers: fix documentation of mbedtls_test_ssl_check_context_after_session_reset Signed-off-by: Valerio Setti --- tests/include/test/ssl_helpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/include/test/ssl_helpers.h b/tests/include/test/ssl_helpers.h index 6a86937df4..21965b0c9a 100644 --- a/tests/include/test/ssl_helpers.h +++ b/tests/include/test/ssl_helpers.h @@ -758,7 +758,7 @@ int mbedtls_test_get_tls13_ticket( * is called on it. This is used for fields that * should be kept untouched during the reset. * \param[in] after The SSL context after mbedtls_ssl_session_reset() - * is called on it. + * has been called on it. */ int mbedtls_test_ssl_check_context_after_session_reset(const mbedtls_ssl_context *before, const mbedtls_ssl_context *after); From fd072d7103c0b45a6f016fd89c2e51fe527f6520 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 23 Jun 2026 22:49:11 +0200 Subject: [PATCH 13/17] tests: generate_ssl_session_reset_check: order rules as fields in the struct Signed-off-by: Valerio Setti --- .../generate_ssl_session_reset_check.py | 80 ++++++++----------- 1 file changed, 35 insertions(+), 45 deletions(-) diff --git a/tests/scripts/generate_ssl_session_reset_check.py b/tests/scripts/generate_ssl_session_reset_check.py index 303f27e251..96a5d3b078 100755 --- a/tests/scripts/generate_ssl_session_reset_check.py +++ b/tests/scripts/generate_ssl_session_reset_check.py @@ -9,23 +9,45 @@ import scripts_path # pylint: disable=unused-import from mbedtls_framework import ssl_session_reset_check RULES = { - # Fields that are reset + 'conf': ssl_session_reset_check.ResetBehavior.KEEP, 'state': ssl_session_reset_check.ResetBehavior.RESET, + 'flags': ssl_session_reset_check.ResetBehavior.SPECIAL, 'renego_status': ssl_session_reset_check.ResetBehavior.RESET, 'renego_records_seen': ssl_session_reset_check.ResetBehavior.RESET, + 'tls_version': ssl_session_reset_check.ResetBehavior.SPECIAL, 'early_data_state': ssl_session_reset_check.ResetBehavior.RESET, 'badmac_seen': ssl_session_reset_check.ResetBehavior.RESET, + 'f_vrfy': ssl_session_reset_check.ResetBehavior.KEEP, + 'p_vrfy': ssl_session_reset_check.ResetBehavior.KEEP, + 'f_send': ssl_session_reset_check.ResetBehavior.KEEP, + 'f_recv': ssl_session_reset_check.ResetBehavior.KEEP, + 'f_recv_timeout': ssl_session_reset_check.ResetBehavior.KEEP, + 'p_bio': ssl_session_reset_check.ResetBehavior.KEEP, 'session_in': ssl_session_reset_check.ResetBehavior.RESET, 'session_out': ssl_session_reset_check.ResetBehavior.RESET, 'session': ssl_session_reset_check.ResetBehavior.RESET, + 'session_negotiate': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'handshake': ssl_session_reset_check.ResetBehavior.REALLOCATE, 'transform_in': ssl_session_reset_check.ResetBehavior.RESET, 'transform_out': ssl_session_reset_check.ResetBehavior.RESET, 'transform': ssl_session_reset_check.ResetBehavior.RESET, + 'transform_negotiate': ssl_session_reset_check.ResetBehavior.REALLOCATE, 'transform_application': ssl_session_reset_check.ResetBehavior.RESET, + 'p_timer': ssl_session_reset_check.ResetBehavior.KEEP, + 'f_set_timer': ssl_session_reset_check.ResetBehavior.KEEP, + 'f_get_timer': ssl_session_reset_check.ResetBehavior.KEEP, + 'in_buf': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'in_ctr': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'in_hdr': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'in_cid': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'in_len': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'in_iv': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'in_msg': ssl_session_reset_check.ResetBehavior.REALLOCATE, 'in_offt': ssl_session_reset_check.ResetBehavior.RESET, 'in_msgtype': ssl_session_reset_check.ResetBehavior.RESET, 'in_msglen': ssl_session_reset_check.ResetBehavior.RESET, 'in_left': ssl_session_reset_check.ResetBehavior.RESET, + 'in_buf_len': ssl_session_reset_check.ResetBehavior.SPECIAL, 'in_epoch': ssl_session_reset_check.ResetBehavior.RESET, 'next_record_offset': ssl_session_reset_check.ResetBehavior.RESET, 'in_window_top': ssl_session_reset_check.ResetBehavior.RESET, @@ -39,12 +61,23 @@ RULES = { 'send_alert': ssl_session_reset_check.ResetBehavior.RESET, 'alert_type': ssl_session_reset_check.ResetBehavior.RESET, 'alert_reason': ssl_session_reset_check.ResetBehavior.RESET, + 'disable_datagram_packing': ssl_session_reset_check.ResetBehavior.KEEP, 'discard_early_data_record': ssl_session_reset_check.ResetBehavior.RESET, 'total_early_data_size': ssl_session_reset_check.ResetBehavior.RESET, + 'out_buf': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'out_ctr': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'out_hdr': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'out_cid': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'out_len': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'out_iv': ssl_session_reset_check.ResetBehavior.REALLOCATE, + 'out_msg': ssl_session_reset_check.ResetBehavior.REALLOCATE, 'out_msgtype': ssl_session_reset_check.ResetBehavior.RESET, 'out_msglen': ssl_session_reset_check.ResetBehavior.RESET, 'out_left': ssl_session_reset_check.ResetBehavior.RESET, + 'out_buf_len': ssl_session_reset_check.ResetBehavior.SPECIAL, 'cur_out_ctr': ssl_session_reset_check.ResetBehavior.RESET, + 'mtu': ssl_session_reset_check.ResetBehavior.KEEP, + 'hostname': ssl_session_reset_check.ResetBehavior.KEEP, 'alpn_chosen': ssl_session_reset_check.ResetBehavior.RESET, 'dtls_srtp_info': ssl_session_reset_check.ResetBehavior.RESET, 'cli_id': ssl_session_reset_check.ResetBehavior.RESET, @@ -53,56 +86,13 @@ RULES = { 'verify_data_len': ssl_session_reset_check.ResetBehavior.RESET, 'own_verify_data': ssl_session_reset_check.ResetBehavior.RESET, 'peer_verify_data': ssl_session_reset_check.ResetBehavior.RESET, - - # Fields that are preserved during reset - 'conf': ssl_session_reset_check.ResetBehavior.KEEP, - 'f_vrfy': ssl_session_reset_check.ResetBehavior.KEEP, - 'p_vrfy': ssl_session_reset_check.ResetBehavior.KEEP, - 'f_send': ssl_session_reset_check.ResetBehavior.KEEP, - 'f_recv': ssl_session_reset_check.ResetBehavior.KEEP, - 'f_recv_timeout': ssl_session_reset_check.ResetBehavior.KEEP, - 'p_bio': ssl_session_reset_check.ResetBehavior.KEEP, - 'p_timer': ssl_session_reset_check.ResetBehavior.KEEP, - 'f_set_timer': ssl_session_reset_check.ResetBehavior.KEEP, - 'f_get_timer': ssl_session_reset_check.ResetBehavior.KEEP, - 'disable_datagram_packing': ssl_session_reset_check.ResetBehavior.KEEP, - 'mtu': ssl_session_reset_check.ResetBehavior.KEEP, - 'hostname': ssl_session_reset_check.ResetBehavior.KEEP, 'own_cid': ssl_session_reset_check.ResetBehavior.KEEP, 'own_cid_len': ssl_session_reset_check.ResetBehavior.KEEP, 'negotiate_cid': ssl_session_reset_check.ResetBehavior.KEEP, 'f_export_keys': ssl_session_reset_check.ResetBehavior.KEEP, 'p_export_keys': ssl_session_reset_check.ResetBehavior.KEEP, - - # Fields which are intentionally not checked. - 'unused': ssl_session_reset_check.ResetBehavior.IGNORE, - - # Pointers which might be reallocated during reset - 'in_buf': ssl_session_reset_check.ResetBehavior.REALLOCATE, - 'in_ctr': ssl_session_reset_check.ResetBehavior.REALLOCATE, - 'in_hdr': ssl_session_reset_check.ResetBehavior.REALLOCATE, - 'in_cid': ssl_session_reset_check.ResetBehavior.REALLOCATE, - 'in_len': ssl_session_reset_check.ResetBehavior.REALLOCATE, - 'in_iv': ssl_session_reset_check.ResetBehavior.REALLOCATE, - 'in_msg': ssl_session_reset_check.ResetBehavior.REALLOCATE, - 'out_buf': ssl_session_reset_check.ResetBehavior.REALLOCATE, - 'out_ctr': ssl_session_reset_check.ResetBehavior.REALLOCATE, - 'out_hdr': ssl_session_reset_check.ResetBehavior.REALLOCATE, - 'out_cid': ssl_session_reset_check.ResetBehavior.REALLOCATE, - 'out_len': ssl_session_reset_check.ResetBehavior.REALLOCATE, - 'out_iv': ssl_session_reset_check.ResetBehavior.REALLOCATE, - 'out_msg': ssl_session_reset_check.ResetBehavior.REALLOCATE, - 'session_negotiate': ssl_session_reset_check.ResetBehavior.REALLOCATE, - 'handshake': ssl_session_reset_check.ResetBehavior.REALLOCATE, - 'transform_negotiate': ssl_session_reset_check.ResetBehavior.REALLOCATE, - - # Fields with custom check rules. Rules must be defined in the - # SPECIAL_BEHAVIORS dictionary below. - 'flags': ssl_session_reset_check.ResetBehavior.SPECIAL, - 'tls_version': ssl_session_reset_check.ResetBehavior.SPECIAL, 'user_data': ssl_session_reset_check.ResetBehavior.SPECIAL, - 'in_buf_len': ssl_session_reset_check.ResetBehavior.SPECIAL, - 'out_buf_len': ssl_session_reset_check.ResetBehavior.SPECIAL, + 'unused': ssl_session_reset_check.ResetBehavior.IGNORE, } SPECIAL_BEHAVIORS = { From 7a2a3179e2a25f757e0dd2a05076f992c5edb4c9 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 23 Jun 2026 23:34:01 +0200 Subject: [PATCH 14/17] tests: generate_ssl_session_reset_check: pacify pylint Signed-off-by: Valerio Setti --- tests/scripts/generate_ssl_session_reset_check.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/scripts/generate_ssl_session_reset_check.py b/tests/scripts/generate_ssl_session_reset_check.py index 96a5d3b078..78e0b6921f 100755 --- a/tests/scripts/generate_ssl_session_reset_check.py +++ b/tests/scripts/generate_ssl_session_reset_check.py @@ -96,7 +96,7 @@ RULES = { } SPECIAL_BEHAVIORS = { - 'flags': ['TEST_EQUAL((after->flags & ~(MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION)), ' + 'flags': ['TEST_EQUAL((after->flags & ~(MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION)), ' + 'initial.flags);', 'TEST_EQUAL((before->flags & MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION), ' + '(after->flags & MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION));'], @@ -106,9 +106,9 @@ SPECIAL_BEHAVIORS = { 'out_buf_len': ['TEST_ASSERT(after->out_buf_len == MBEDTLS_SSL_OUT_BUFFER_LEN);'], } -NAMED_STRUCTURES = [ +NAMED_STRUCTURES = frozenset([ 'dtls_srtp_info', -] +]) FIELDS_INFO = ssl_session_reset_check.FieldsInfo(RULES, SPECIAL_BEHAVIORS, From de1f7218d55395ec8c522e03d358b71c71ef2561 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 24 Jun 2026 09:04:15 +0200 Subject: [PATCH 15/17] tests: generate_ssl_session_reset_check: remove trailing whitespace Signed-off-by: Valerio Setti --- tests/scripts/generate_ssl_session_reset_check.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/generate_ssl_session_reset_check.py b/tests/scripts/generate_ssl_session_reset_check.py index 78e0b6921f..8e26d9ee1a 100755 --- a/tests/scripts/generate_ssl_session_reset_check.py +++ b/tests/scripts/generate_ssl_session_reset_check.py @@ -106,7 +106,7 @@ SPECIAL_BEHAVIORS = { 'out_buf_len': ['TEST_ASSERT(after->out_buf_len == MBEDTLS_SSL_OUT_BUFFER_LEN);'], } -NAMED_STRUCTURES = frozenset([ +NAMED_STRUCTURES = frozenset([ 'dtls_srtp_info', ]) From 8ef4559dfa8cb89d24893af160e62d6aee4aa051 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 24 Jun 2026 14:31:20 +0200 Subject: [PATCH 16/17] framework: update reference Signed-off-by: Valerio Setti --- framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework b/framework index d6dec17adf..dde0c4a0e4 160000 --- a/framework +++ b/framework @@ -1 +1 @@ -Subproject commit d6dec17adfb5bf283c6a7a5bb6c451ecdc0b8201 +Subproject commit dde0c4a0e448a0552f18817dcea633bb851fd288 From 3b84f44c7fb2e987ad3a878e5d8abfaf549408be Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 24 Jun 2026 15:37:00 +0200 Subject: [PATCH 17/17] tests: ssl_helpers: run ssl_context reset check only when the SSL context is setup Signed-off-by: Valerio Setti --- tests/src/test_helpers/ssl_helpers.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index 0d2687e795..ebb9103de9 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -1035,14 +1035,17 @@ int mbedtls_test_ssl_endpoint_init( void mbedtls_test_ssl_endpoint_free( mbedtls_test_ssl_endpoint *ep) { - mbedtls_ssl_context ssl_before; + // mbedtls_ssl_session_reset() requires the SSL to be setup. + if (ep->ssl.conf != NULL) { + mbedtls_ssl_context ssl_before; - /* Dump the SSL context before resetting it */ - memcpy(&ssl_before, &(ep->ssl), sizeof(mbedtls_ssl_context)); + /* Dump the SSL context before resetting it */ + memcpy(&ssl_before, &(ep->ssl), sizeof(mbedtls_ssl_context)); - mbedtls_ssl_session_reset(&(ep->ssl)); - /* Check that required fields were properly reset */ - mbedtls_test_ssl_check_context_after_session_reset(&ssl_before, &(ep->ssl)); + mbedtls_ssl_session_reset(&(ep->ssl)); + /* Check that required fields were properly reset */ + mbedtls_test_ssl_check_context_after_session_reset(&ssl_before, &(ep->ssl)); + } mbedtls_ssl_free(&(ep->ssl)); mbedtls_ssl_config_free(&(ep->conf));