From f595df4569c1a1650ad9d077e2f2e819e9f1dddb Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Thu, 14 May 2026 11:27:05 +0100 Subject: [PATCH 01/38] ssl: propagate transcript-hash computation failures Signed-off-by: Ben Taylor --- library/ssl_tls.c | 1 + library/ssl_tls13_server.c | 1 + 2 files changed, 2 insertions(+) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 88aaf85d29..f6fcf63526 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -7092,6 +7092,7 @@ static int ssl_compute_master(mbedtls_ssl_handshake_params *handshake, ret = handshake->calc_verify(ssl, session_hash, &seed_len); if (ret != 0) { MBEDTLS_SSL_DEBUG_RET(1, "calc_verify", ret); + return ret; } MBEDTLS_SSL_DEBUG_BUF(3, "session hash for extended master secret", diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 11b97d06bf..0021c3fd88 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -3098,6 +3098,7 @@ static int ssl_tls13_process_client_finished(mbedtls_ssl_context *ssl) if (ret != 0) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_compute_resumption_master_secret", ret); + return ret; } mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP); From 710d5efac9fc6214402d7de614198a335fdb0474 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Thu, 14 May 2026 11:27:15 +0100 Subject: [PATCH 02/38] tests: ssl: add regression tests for EMS/RMS error propagation Signed-off-by: Ben Taylor Backport note: adapted from upstream commit e1241ef8bb5890dd47753f888cf6b3d18c9df8c4; not a direct cherry-pick. --- tests/suites/test_suite_ssl.data | 6 + tests/suites/test_suite_ssl.function | 187 ++++++++++++++++++++++++++- 2 files changed, 192 insertions(+), 1 deletion(-) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index fe4f9034d1..8fb289d187 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3378,6 +3378,12 @@ elliptic_curve_get_properties TLS 1.3 resume session with ticket tls13_resume_session_with_ticket +TLS 1.3 server propagates RMS computation error +tls13_server_propagates_rms_error + +TLS 1.2 server propagates EMS computation error +tls12_server_propagates_ems_error + TLS 1.3 read early data, early data accepted tls13_read_early_data:TEST_EARLY_DATA_ACCEPTED diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 5f61f71236..444e695fdb 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -53,6 +53,163 @@ static int failing_ticket_write_unset_lifetime( MBEDTLS_ECP_HAVE_SECP384R1 && MBEDTLS_MD_CAN_SHA256 && MBEDTLS_PK_HAVE_ECC_KEYS && MBEDTLS_CAN_HANDLE_RSA_TEST_KEY */ +#if defined(MBEDTLS_SSL_CLI_C) && \ + defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_DEBUG_C) && \ + defined(PSA_HAVE_ALG_SOME_RSA_SIGN) && \ + ((defined(MBEDTLS_SSL_PROTO_TLS1_3) && \ + defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) && \ + defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED) && \ + defined(MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE) && \ + defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED) && \ + defined(PSA_WANT_ALG_SHA_256) && \ + defined(PSA_WANT_ECC_SECP_R1_256) && \ + defined(PSA_WANT_ECC_SECP_R1_384) && \ + defined(PSA_HAVE_ALG_ECDSA_VERIFY) && \ + defined(MBEDTLS_SSL_SESSION_TICKETS)) || \ + (defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \ + defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) && \ + defined(PSA_WANT_ALG_SHA_256) && \ + defined(PSA_WANT_ECC_SECP_R1_384) && \ + defined(PSA_HAVE_ALG_ECDSA_VERIFY))) +typedef struct { + mbedtls_ssl_context *ssl; + const char *trigger; + int triggered; +} tls_abort_transcript_context; + +static void tls_abort_transcript(void *ctx, int level, + const char *file, int line, + const char *str) +{ + tls_abort_transcript_context *abort_ctx = ctx; + + (void) level; + (void) file; + (void) line; + + if (abort_ctx->triggered || abort_ctx->ssl == NULL || + abort_ctx->ssl->handshake == NULL || + abort_ctx->trigger == NULL || + strstr(str, abort_ctx->trigger) == NULL) { + return; + } + + abort_ctx->triggered = 1; + psa_hash_abort(&abort_ctx->ssl->handshake->fin_sha256_psa); +#if defined(PSA_WANT_ALG_SHA_384) + psa_hash_abort(&abort_ctx->ssl->handshake->fin_sha384_psa); +#endif +} + +static void tls_server_error(mbedtls_ssl_protocol_version tls_version, + const char *trigger, + int server_state, + int client_state) +{ + int ret = -1; + int max_steps = 100; + mbedtls_test_ssl_endpoint client_ep, server_ep; + mbedtls_test_handshake_test_options client_options; + mbedtls_test_handshake_test_options server_options; + tls_abort_transcript_context abort_ctx; + +#if defined(MBEDTLS_SSL_PROTO_TLS1_3) + unsigned char psk[] = "abcdefghijklmnop"; + data_t psk_data = { psk, sizeof(psk) - 1 }; +#endif + + memset(&client_ep, 0, sizeof(client_ep)); + memset(&server_ep, 0, sizeof(server_ep)); + memset(&abort_ctx, 0, sizeof(abort_ctx)); + mbedtls_test_init_handshake_options(&client_options); + mbedtls_test_init_handshake_options(&server_options); + + PSA_INIT(); + + client_options.client_min_version = tls_version; + client_options.client_max_version = tls_version; + server_options.server_min_version = tls_version; + server_options.server_max_version = tls_version; + + abort_ctx.trigger = trigger; + server_options.srv_log_obj = &abort_ctx; + server_options.srv_log_fun = tls_abort_transcript; + +#if defined(MBEDTLS_SSL_PROTO_TLS1_3) + if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { + client_options.psk_str = &psk_data; + } +#endif + + mbedtls_debug_set_threshold(4); + + TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT, + &client_options), 0); + TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER, + &server_options), 0); + +#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS) + if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { + TEST_EQUAL(mbedtls_ssl_conf_psk(&server_ep.conf, psk, sizeof(psk) - 1, + (const unsigned char *) "foo", + strlen("foo")), 0); + mbedtls_ssl_conf_tls13_key_exchange_modes( + &client_ep.conf, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK); + mbedtls_ssl_conf_tls13_key_exchange_modes( + &server_ep.conf, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK); + mbedtls_ssl_conf_session_tickets_cb(&server_ep.conf, + mbedtls_test_ticket_write, + mbedtls_test_ticket_parse, + NULL); + } +#endif + + TEST_EQUAL(mbedtls_test_mock_socket_connect(&(client_ep.socket), + &(server_ep.socket), 1024), 0); + + abort_ctx.ssl = &server_ep.ssl; + + TEST_EQUAL(mbedtls_test_move_handshake_to_state( + &(server_ep.ssl), &(client_ep.ssl), + server_state), 0); + + TEST_EQUAL(mbedtls_ssl_flush_output(&(server_ep.ssl)), 0); + + TEST_EQUAL(server_ep.ssl.state, server_state); + + TEST_EQUAL(abort_ctx.triggered, 0); + + while (client_ep.ssl.state != client_state && + --max_steps >= 0) { + ret = mbedtls_ssl_handshake_step(&(client_ep.ssl)); + TEST_ASSERT(ret == 0 || ret == MBEDTLS_ERR_SSL_WANT_READ || + ret == MBEDTLS_ERR_SSL_WANT_WRITE); + } + + TEST_ASSERT(max_steps >= 0); + + TEST_EQUAL(client_ep.ssl.state, client_state); + TEST_EQUAL(server_ep.ssl.state, server_state); + + TEST_EQUAL(abort_ctx.triggered, 0); + + ret = mbedtls_ssl_handshake_step(&(server_ep.ssl)); + TEST_ASSERT(abort_ctx.triggered); + TEST_ASSERT(ret != 0); + + TEST_EQUAL(server_ep.ssl.state, server_state); + +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_debug_set_threshold(0); + PSA_DONE(); +} +#endif + #if (!defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \ defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) && \ defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_DEBUG_C) && \ @@ -4365,7 +4522,35 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */ +/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED:PSA_WANT_ALG_SHA_256:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_HAVE_ALG_SOME_RSA_SIGN:MBEDTLS_SSL_SESSION_TICKETS */ +void tls13_server_propagates_rms_error() +{ + tls_server_error(MBEDTLS_SSL_VERSION_TLS1_3, + "<= parse finished message", + MBEDTLS_SSL_CLIENT_FINISHED, + MBEDTLS_SSL_FLUSH_BUFFERS); + goto exit; + +exit: + ; +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_SSL_EXTENDED_MASTER_SECRET:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:PSA_WANT_ALG_SHA_256:PSA_WANT_ECC_SECP_R1_384:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_HAVE_ALG_SOME_RSA_SIGN:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ +void tls12_server_propagates_ems_error() +{ + tls_server_error(MBEDTLS_SSL_VERSION_TLS1_2, + "=> derive keys", + MBEDTLS_SSL_CLIENT_KEY_EXCHANGE, + MBEDTLS_SSL_CERTIFICATE_VERIFY); + goto exit; + +exit: + ; +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE: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 */ void tls13_resume_session_with_ticket() { int ret = -1; From d0e7136ec307707fc41ab5fb387eed04c9f112b4 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 15 May 2026 18:42:45 +0200 Subject: [PATCH 03/38] Improve dependencies and error handling Signed-off-by: Ben Taylor Backport note: adapted from upstream commit 24e67fd9039dcd57d65d1c043baa80697ce05fe8; not a direct cherry-pick. --- tests/suites/test_suite_ssl.data | 6 +- tests/suites/test_suite_ssl.function | 215 +++++++++------------------ 2 files changed, 72 insertions(+), 149 deletions(-) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 8fb289d187..2cb11c026c 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3379,10 +3379,12 @@ TLS 1.3 resume session with ticket tls13_resume_session_with_ticket TLS 1.3 server propagates RMS computation error -tls13_server_propagates_rms_error +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_X509_RSASSA_PSS_SUPPORT:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT +tls_transcript_error_propagation:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_3:"<= parse finished message":MBEDTLS_SSL_CLIENT_FINISHED:MBEDTLS_SSL_FLUSH_BUFFERS TLS 1.2 server propagates EMS computation error -tls12_server_propagates_ems_error +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED +tls_transcript_error_propagation:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_2:"=> derive keys":MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:MBEDTLS_SSL_CERTIFICATE_VERIFY TLS 1.3 read early data, early data accepted tls13_read_early_data:TEST_EARLY_DATA_ACCEPTED diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 444e695fdb..200a018571 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -53,25 +53,11 @@ static int failing_ticket_write_unset_lifetime( MBEDTLS_ECP_HAVE_SECP384R1 && MBEDTLS_MD_CAN_SHA256 && MBEDTLS_PK_HAVE_ECC_KEYS && MBEDTLS_CAN_HANDLE_RSA_TEST_KEY */ -#if defined(MBEDTLS_SSL_CLI_C) && \ - defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_DEBUG_C) && \ - defined(PSA_HAVE_ALG_SOME_RSA_SIGN) && \ - ((defined(MBEDTLS_SSL_PROTO_TLS1_3) && \ +#if defined(MBEDTLS_SSL_TLS_C) && defined(MBEDTLS_DEBUG_C) && \ + defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_SRV_C) && \ defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) && \ - defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED) && \ - defined(MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE) && \ - defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED) && \ - defined(PSA_WANT_ALG_SHA_256) && \ - defined(PSA_WANT_ECC_SECP_R1_256) && \ - defined(PSA_WANT_ECC_SECP_R1_384) && \ - defined(PSA_HAVE_ALG_ECDSA_VERIFY) && \ - defined(MBEDTLS_SSL_SESSION_TICKETS)) || \ - (defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \ - defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) && \ - defined(PSA_WANT_ALG_SHA_256) && \ - defined(PSA_WANT_ECC_SECP_R1_384) && \ - defined(PSA_HAVE_ALG_ECDSA_VERIFY))) + defined(MBEDTLS_TEST_HAS_DEFAULT_EC_GROUP) && \ + defined(PSA_WANT_ALG_SHA_256) typedef struct { mbedtls_ssl_context *ssl; const char *trigger; @@ -101,113 +87,6 @@ static void tls_abort_transcript(void *ctx, int level, psa_hash_abort(&abort_ctx->ssl->handshake->fin_sha384_psa); #endif } - -static void tls_server_error(mbedtls_ssl_protocol_version tls_version, - const char *trigger, - int server_state, - int client_state) -{ - int ret = -1; - int max_steps = 100; - mbedtls_test_ssl_endpoint client_ep, server_ep; - mbedtls_test_handshake_test_options client_options; - mbedtls_test_handshake_test_options server_options; - tls_abort_transcript_context abort_ctx; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - unsigned char psk[] = "abcdefghijklmnop"; - data_t psk_data = { psk, sizeof(psk) - 1 }; -#endif - - memset(&client_ep, 0, sizeof(client_ep)); - memset(&server_ep, 0, sizeof(server_ep)); - memset(&abort_ctx, 0, sizeof(abort_ctx)); - mbedtls_test_init_handshake_options(&client_options); - mbedtls_test_init_handshake_options(&server_options); - - PSA_INIT(); - - client_options.client_min_version = tls_version; - client_options.client_max_version = tls_version; - server_options.server_min_version = tls_version; - server_options.server_max_version = tls_version; - - abort_ctx.trigger = trigger; - server_options.srv_log_obj = &abort_ctx; - server_options.srv_log_fun = tls_abort_transcript; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { - client_options.psk_str = &psk_data; - } -#endif - - mbedtls_debug_set_threshold(4); - - TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT, - &client_options), 0); - TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER, - &server_options), 0); - -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS) - if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { - TEST_EQUAL(mbedtls_ssl_conf_psk(&server_ep.conf, psk, sizeof(psk) - 1, - (const unsigned char *) "foo", - strlen("foo")), 0); - mbedtls_ssl_conf_tls13_key_exchange_modes( - &client_ep.conf, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK); - mbedtls_ssl_conf_tls13_key_exchange_modes( - &server_ep.conf, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK); - mbedtls_ssl_conf_session_tickets_cb(&server_ep.conf, - mbedtls_test_ticket_write, - mbedtls_test_ticket_parse, - NULL); - } -#endif - - TEST_EQUAL(mbedtls_test_mock_socket_connect(&(client_ep.socket), - &(server_ep.socket), 1024), 0); - - abort_ctx.ssl = &server_ep.ssl; - - TEST_EQUAL(mbedtls_test_move_handshake_to_state( - &(server_ep.ssl), &(client_ep.ssl), - server_state), 0); - - TEST_EQUAL(mbedtls_ssl_flush_output(&(server_ep.ssl)), 0); - - TEST_EQUAL(server_ep.ssl.state, server_state); - - TEST_EQUAL(abort_ctx.triggered, 0); - - while (client_ep.ssl.state != client_state && - --max_steps >= 0) { - ret = mbedtls_ssl_handshake_step(&(client_ep.ssl)); - TEST_ASSERT(ret == 0 || ret == MBEDTLS_ERR_SSL_WANT_READ || - ret == MBEDTLS_ERR_SSL_WANT_WRITE); - } - - TEST_ASSERT(max_steps >= 0); - - TEST_EQUAL(client_ep.ssl.state, client_state); - TEST_EQUAL(server_ep.ssl.state, server_state); - - TEST_EQUAL(abort_ctx.triggered, 0); - - ret = mbedtls_ssl_handshake_step(&(server_ep.ssl)); - TEST_ASSERT(abort_ctx.triggered); - TEST_ASSERT(ret != 0); - - TEST_EQUAL(server_ep.ssl.state, server_state); - -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_debug_set_threshold(0); - PSA_DONE(); -} #endif #if (!defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \ @@ -4522,31 +4401,73 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED:PSA_WANT_ALG_SHA_256:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_HAVE_ALG_SOME_RSA_SIGN:MBEDTLS_SSL_SESSION_TICKETS */ -void tls13_server_propagates_rms_error() +/* BEGIN_CASE depends_on:MBEDTLS_SSL_TLS_C:MBEDTLS_DEBUG_C:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:MBEDTLS_TEST_HAS_DEFAULT_EC_GROUP:PSA_WANT_ALG_SHA_256 */ +void tls_transcript_error_propagation(int endpoint, + int tls_version, + const char *trigger, + int server_state, + int client_state) { - tls_server_error(MBEDTLS_SSL_VERSION_TLS1_3, - "<= parse finished message", - MBEDTLS_SSL_CLIENT_FINISHED, - MBEDTLS_SSL_FLUSH_BUFFERS); - goto exit; + int ret = -1; + mbedtls_test_ssl_endpoint client_ep, server_ep; + mbedtls_test_handshake_test_options client_options; + mbedtls_test_handshake_test_options server_options; + tls_abort_transcript_context abort_ctx; + + mbedtls_test_init_handshake_options(&client_options); + mbedtls_test_init_handshake_options(&server_options); + memset(&abort_ctx, 0, sizeof(abort_ctx)); + + PSA_INIT(); + + client_options.client_min_version = tls_version; + client_options.client_max_version = tls_version; + server_options.server_min_version = tls_version; + server_options.server_max_version = tls_version; + + abort_ctx.trigger = trigger; + + if (endpoint == MBEDTLS_SSL_IS_CLIENT) { + client_options.cli_log_obj = &abort_ctx; + client_options.cli_log_fun = tls_abort_transcript; + } else { + server_options.srv_log_obj = &abort_ctx; + server_options.srv_log_fun = tls_abort_transcript; + } + + mbedtls_debug_set_threshold(4); + + TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT, + &client_options), 0); + TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER, + &server_options), 0); + + TEST_EQUAL(mbedtls_test_mock_socket_connect(&(client_ep.socket), + &(server_ep.socket), 1024), 0); + + abort_ctx.ssl = &server_ep.ssl; + + TEST_EQUAL(mbedtls_test_move_handshake_to_state( + &(server_ep.ssl), &(client_ep.ssl), + server_state), 0); + + TEST_EQUAL(mbedtls_test_move_handshake_to_state( + &(client_ep.ssl), &(server_ep.ssl), + client_state), 0); + + TEST_EQUAL(abort_ctx.triggered, 0); + + ret = mbedtls_ssl_handshake_step(&(server_ep.ssl)); + TEST_ASSERT(abort_ctx.triggered); + TEST_ASSERT(ret != 0); exit: - ; -} -/* END_CASE */ - -/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_SSL_EXTENDED_MASTER_SECRET:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:PSA_WANT_ALG_SHA_256:PSA_WANT_ECC_SECP_R1_384:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_HAVE_ALG_SOME_RSA_SIGN:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ -void tls12_server_propagates_ems_error() -{ - tls_server_error(MBEDTLS_SSL_VERSION_TLS1_2, - "=> derive keys", - MBEDTLS_SSL_CLIENT_KEY_EXCHANGE, - MBEDTLS_SSL_CERTIFICATE_VERIFY); - goto exit; - -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_debug_set_threshold(0); + PSA_DONE(); } /* END_CASE */ From 84de9770cf8effee7973b3b530ff8508b4765822 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Wed, 27 May 2026 07:56:31 +0100 Subject: [PATCH 04/38] Add ChangeLog Signed-off-by: Ben Taylor --- ChangeLog.d/1583-1584-ssl-transcript-errors.txt | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 ChangeLog.d/1583-1584-ssl-transcript-errors.txt diff --git a/ChangeLog.d/1583-1584-ssl-transcript-errors.txt b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt new file mode 100644 index 0000000000..921b40b11d --- /dev/null +++ b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt @@ -0,0 +1,5 @@ +Bugfix + * Fix a bug where errors during transcript-hash computation for TLS 1.2 + extended master secret and TLS 1.3 resumption master secret could be + ignored instead of causing the handshake to fail. Fixes #1583 and #1584. + From ca8eab3d69e68bb0ed9172da3b3d90e439d464f1 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Thu, 28 May 2026 15:07:08 +0100 Subject: [PATCH 05/38] Update ChangeLog Signed-off-by: Ben Taylor --- ChangeLog.d/1583-1584-ssl-transcript-errors.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog.d/1583-1584-ssl-transcript-errors.txt b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt index 921b40b11d..062a788788 100644 --- a/ChangeLog.d/1583-1584-ssl-transcript-errors.txt +++ b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt @@ -1,5 +1,5 @@ -Bugfix +Security * Fix a bug where errors during transcript-hash computation for TLS 1.2 extended master secret and TLS 1.3 resumption master secret could be - ignored instead of causing the handshake to fail. Fixes #1583 and #1584. + ignored instead of causing the handshake to fail. From 8d083042a4156287dc44e2eae551dbb71b874842 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Thu, 28 May 2026 15:18:19 +0100 Subject: [PATCH 06/38] Add security impact Signed-off-by: Ben Taylor --- ChangeLog.d/1583-1584-ssl-transcript-errors.txt | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/ChangeLog.d/1583-1584-ssl-transcript-errors.txt b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt index 062a788788..4b5db144c3 100644 --- a/ChangeLog.d/1583-1584-ssl-transcript-errors.txt +++ b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt @@ -1,5 +1,12 @@ Security - * Fix a bug where errors during transcript-hash computation for TLS 1.2 - extended master secret and TLS 1.3 resumption master secret could be - ignored instead of causing the handshake to fail. - + * Fix a bug where transcript-hash computation errors during TLS 1.2 + extended master secret calculation could be ignored instead of causing the + handshake to fail. This could allow a handshake to continue with a master + secret that was not correctly bound to the handshake transcript, + undermining the security guarantees of the extended master secret + extension. + * Fix a bug where TLS 1.3 servers could ignore errors when computing the + resumption master secret instead of causing the handshake to fail. This + could allow a server to issue resumption tickets derived from an invalid + resumption secret, weakening authentication of future resumptions made + with those tickets. From 167a754c0d9d175bbe3df3bd25508d4b942d3e75 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Fri, 29 May 2026 14:48:44 +0100 Subject: [PATCH 07/38] Improve layout of the code for debugging with breakpoints Signed-off-by: Ben Taylor --- tests/suites/test_suite_ssl.function | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 200a018571..f3cd7117ed 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -74,10 +74,19 @@ static void tls_abort_transcript(void *ctx, int level, (void) file; (void) line; - if (abort_ctx->triggered || abort_ctx->ssl == NULL || - abort_ctx->ssl->handshake == NULL || - abort_ctx->trigger == NULL || - strstr(str, abort_ctx->trigger) == NULL) { + if (abort_ctx->triggered){ + return; + } + if (abort_ctx->ssl == NULL) { + return; + } + if (abort_ctx->ssl->handshake == NULL) { + return; + } + if (abort_ctx->trigger == NULL) { + return; + } + if (strstr(str, abort_ctx->trigger) == NULL) { return; } From 9c3cd1a5d42a185bbdf8f71d2ac5ad53229cb91e Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Fri, 29 May 2026 15:09:34 +0100 Subject: [PATCH 08/38] Add additional guard for sha256 in tests Signed-off-by: Ben Taylor --- tests/suites/test_suite_ssl.function | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index f3cd7117ed..abacb07e51 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -91,7 +91,9 @@ static void tls_abort_transcript(void *ctx, int level, } abort_ctx->triggered = 1; +#if defined(PSA_WANT_ALG_SHA_256) psa_hash_abort(&abort_ctx->ssl->handshake->fin_sha256_psa); +#endif #if defined(PSA_WANT_ALG_SHA_384) psa_hash_abort(&abort_ctx->ssl->handshake->fin_sha384_psa); #endif From f0f708eade5014af09658a3e32c63ed94e7bee16 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Fri, 29 May 2026 15:12:28 +0100 Subject: [PATCH 09/38] refactor initialisation in tls_transcript_error_propagation, so that the variables are initialised straight after they are declared Signed-off-by: Ben Taylor --- tests/suites/test_suite_ssl.function | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index abacb07e51..f109f6db18 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4422,11 +4422,10 @@ void tls_transcript_error_propagation(int endpoint, int ret = -1; mbedtls_test_ssl_endpoint client_ep, server_ep; mbedtls_test_handshake_test_options client_options; - mbedtls_test_handshake_test_options server_options; - tls_abort_transcript_context abort_ctx; - mbedtls_test_init_handshake_options(&client_options); + mbedtls_test_handshake_test_options server_options; mbedtls_test_init_handshake_options(&server_options); + tls_abort_transcript_context abort_ctx; memset(&abort_ctx, 0, sizeof(abort_ctx)); PSA_INIT(); From 3d6379aa61083fd4d0319bf8ef8ab069f97d828f Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Mon, 1 Jun 2026 07:43:48 +0100 Subject: [PATCH 10/38] Fixed code style Signed-off-by: Ben Taylor --- tests/suites/test_suite_ssl.function | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index f109f6db18..5535379d88 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -74,7 +74,7 @@ static void tls_abort_transcript(void *ctx, int level, (void) file; (void) line; - if (abort_ctx->triggered){ + if (abort_ctx->triggered) { return; } if (abort_ctx->ssl == NULL) { From bc250f0bbaf6a92f85a87eefd27c2a664f45da4a Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Mon, 1 Jun 2026 07:59:06 +0100 Subject: [PATCH 11/38] Fix issues with hanging seed length Signed-off-by: Ben Taylor --- library/ssl_tls.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index f6fcf63526..19c82f039d 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -7088,12 +7088,16 @@ static int ssl_compute_master(mbedtls_ssl_handshake_params *handshake, #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) if (handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED) { lbl = "extended master secret"; - seed = session_hash; ret = handshake->calc_verify(ssl, session_hash, &seed_len); if (ret != 0) { MBEDTLS_SSL_DEBUG_RET(1, "calc_verify", ret); return ret; } + if (seed_len > sizeof(session_hash)) { + MBEDTLS_SSL_DEBUG_MSG(1, ("bad session hash length")); + return MBEDTLS_ERR_SSL_INTERNAL_ERROR; + } + seed = session_hash; MBEDTLS_SSL_DEBUG_BUF(3, "session hash for extended master secret", session_hash, seed_len); From 1aeb46adb9a1e23f5b83b7a362bdef8a49ea5fb8 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Mon, 1 Jun 2026 08:03:58 +0100 Subject: [PATCH 12/38] Add further documentation to tls_abort_transcript_context Signed-off-by: Ben Taylor --- tests/suites/test_suite_ssl.function | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 5535379d88..01aee7a2ae 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -59,6 +59,9 @@ static int failing_ticket_write_unset_lifetime( defined(MBEDTLS_TEST_HAS_DEFAULT_EC_GROUP) && \ defined(PSA_WANT_ALG_SHA_256) typedef struct { + /* Context for tls_abort_transcript(). The debug callback watches for + * trigger in the SSL debug trace, then aborts this connection's transcript + * hash operation exactly once so the test can check error propagation. */ mbedtls_ssl_context *ssl; const char *trigger; int triggered; From 355eae4d9cc075cc11b5bf67c049e5e20410f2ca Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Mon, 1 Jun 2026 08:12:23 +0100 Subject: [PATCH 13/38] Add unsupported trigger check Signed-off-by: Ben Taylor --- tests/suites/test_suite_ssl.function | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 01aee7a2ae..d3458beef2 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -86,9 +86,6 @@ static void tls_abort_transcript(void *ctx, int level, if (abort_ctx->ssl->handshake == NULL) { return; } - if (abort_ctx->trigger == NULL) { - return; - } if (strstr(str, abort_ctx->trigger) == NULL) { return; } @@ -4439,6 +4436,7 @@ void tls_transcript_error_propagation(int endpoint, server_options.server_max_version = tls_version; abort_ctx.trigger = trigger; + TEST_ASSERT(abort_ctx.trigger != NULL); if (endpoint == MBEDTLS_SSL_IS_CLIENT) { client_options.cli_log_obj = &abort_ctx; From 2c4d8ad682e5a60624f715897963ccfd6f401b99 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Mon, 1 Jun 2026 08:26:50 +0100 Subject: [PATCH 14/38] Add client tests for RMS computation error Signed-off-by: Ben Taylor --- tests/suites/test_suite_ssl.data | 8 +++++++ tests/suites/test_suite_ssl.function | 32 ++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 2cb11c026c..c8e257952b 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3382,10 +3382,18 @@ TLS 1.3 server propagates RMS computation error depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_X509_RSASSA_PSS_SUPPORT:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT tls_transcript_error_propagation:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_3:"<= parse finished message":MBEDTLS_SSL_CLIENT_FINISHED:MBEDTLS_SSL_FLUSH_BUFFERS +TLS 1.3 client propagates RMS computation error +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_X509_RSASSA_PSS_SUPPORT:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT +tls_transcript_error_propagation:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_VERSION_TLS1_3:"<= write finished message":MBEDTLS_SSL_CLIENT_FINISHED:MBEDTLS_SSL_CLIENT_FINISHED + TLS 1.2 server propagates EMS computation error depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED tls_transcript_error_propagation:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_2:"=> derive keys":MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:MBEDTLS_SSL_CERTIFICATE_VERIFY +TLS 1.2 client propagates EMS computation error +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED +tls_transcript_error_propagation:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_VERSION_TLS1_2:"=> derive keys":MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:MBEDTLS_SSL_CERTIFICATE_VERIFY + TLS 1.3 read early data, early data accepted tls13_read_early_data:TEST_EARLY_DATA_ACCEPTED diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index d3458beef2..d92a7cb72c 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4453,22 +4453,36 @@ void tls_transcript_error_propagation(int endpoint, TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER, &server_options), 0); + /* Keep enough socket capacity for setup traffic so the final step below + * exercises the target state instead of only flushing previous messages. */ TEST_EQUAL(mbedtls_test_mock_socket_connect(&(client_ep.socket), - &(server_ep.socket), 1024), 0); + &(server_ep.socket), 4096), 0); - abort_ctx.ssl = &server_ep.ssl; + if (endpoint == MBEDTLS_SSL_IS_CLIENT) { + /* Moving the client to its target state drives the server as needed. + * Moving the server afterwards can advance the client past that state. */ + TEST_EQUAL(mbedtls_test_move_handshake_to_state( + &(client_ep.ssl), &(server_ep.ssl), + client_state), 0); - TEST_EQUAL(mbedtls_test_move_handshake_to_state( - &(server_ep.ssl), &(client_ep.ssl), - server_state), 0); + abort_ctx.ssl = &client_ep.ssl; + } else { + TEST_EQUAL(mbedtls_test_move_handshake_to_state( + &(server_ep.ssl), &(client_ep.ssl), + server_state), 0); - TEST_EQUAL(mbedtls_test_move_handshake_to_state( - &(client_ep.ssl), &(server_ep.ssl), - client_state), 0); + TEST_EQUAL(mbedtls_test_move_handshake_to_state( + &(client_ep.ssl), &(server_ep.ssl), + client_state), 0); + abort_ctx.ssl = &server_ep.ssl; + } + TEST_EQUAL(mbedtls_ssl_flush_output(abort_ctx.ssl), 0); + TEST_EQUAL(abort_ctx.ssl->state, + endpoint == MBEDTLS_SSL_IS_CLIENT ? client_state : server_state); TEST_EQUAL(abort_ctx.triggered, 0); - ret = mbedtls_ssl_handshake_step(&(server_ep.ssl)); + ret = mbedtls_ssl_handshake_step(abort_ctx.ssl); TEST_ASSERT(abort_ctx.triggered); TEST_ASSERT(ret != 0); From 0ef63355f18aa0c74c5168e3580e644f6c5fca1a Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Mon, 1 Jun 2026 09:03:29 +0100 Subject: [PATCH 15/38] Add additional fix for return with error Signed-off-by: Ben Taylor --- library/ssl_tls13_client.c | 1 + 1 file changed, 1 insertion(+) diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 0d20db2023..6171f7c6da 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -2810,6 +2810,7 @@ static int ssl_tls13_parse_new_session_ticket_exts(mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls13_parse_new_session_ticket_early_data_ext", ret); + return ret; } break; #endif /* MBEDTLS_SSL_EARLY_DATA */ From 61087eb79d4f647859bf8aaffeb77c7e1fd5e473 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Mon, 1 Jun 2026 09:19:29 +0100 Subject: [PATCH 16/38] Add fix for missing return from ssl_write_ecjpake_kkpp_ext Signed-off-by: Ben Taylor Backport note: adapted from upstream commit dc45235ca3faa5b1fe1df2b8967b019ccef2839d; not a direct cherry-pick. --- library/ssl_tls12_server.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index ebe6884f20..29a5774433 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -1790,7 +1790,7 @@ static void ssl_write_supported_point_formats_ext(mbedtls_ssl_context *ssl, MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static void ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context *ssl, +static int ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen) { @@ -1804,14 +1804,14 @@ static void ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context *ssl, /* Skip costly computation if not needed */ if (ssl->handshake->ciphersuite_info->key_exchange != MBEDTLS_KEY_EXCHANGE_ECJPAKE) { - return; + return 0; } MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, ecjpake kkpp extension")); if (end - p < 4) { MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small")); - return; + return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; } MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0); @@ -1825,7 +1825,7 @@ static void ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context *ssl, psa_destroy_key(ssl->handshake->psa_pake_password); psa_pake_abort(&ssl->handshake->psa_pake_ctx); MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret); - return; + return ret; } #else ret = mbedtls_ecjpake_write_round_one(&ssl->handshake->ecjpake_ctx, @@ -1841,6 +1841,7 @@ static void ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context *ssl, p += 2; *olen = kkpp_len + 4; + return 0; } #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ @@ -2223,7 +2224,10 @@ static int ssl_write_server_hello(mbedtls_ssl_context *ssl) #endif #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - ssl_write_ecjpake_kkpp_ext(ssl, p + 2 + ext_len, &olen); + if ((ret = ssl_write_ecjpake_kkpp_ext(ssl, p + 2 + ext_len, &olen)) != 0) { + MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_ecjpake_kkpp_ext", ret); + return ret; + } ext_len += olen; #endif From b4981f3e9c8a80bfe8d0b28be71615dae40db3d0 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Mon, 1 Jun 2026 14:48:09 +0100 Subject: [PATCH 17/38] Fix code style issues Signed-off-by: Ben Taylor --- library/ssl_tls12_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index 29a5774433..f6f5cb5f93 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -1791,8 +1791,8 @@ static void ssl_write_supported_point_formats_ext(mbedtls_ssl_context *ssl, #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) static int ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen) + unsigned char *buf, + size_t *olen) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char *p = buf; From eb01ebddab58015303cef8796c4315b2f3c4cdf9 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Thu, 4 Jun 2026 10:29:43 +0100 Subject: [PATCH 18/38] Add Reported by to ChangeLog Signed-off-by: Ben Taylor --- ChangeLog.d/1583-1584-ssl-transcript-errors.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog.d/1583-1584-ssl-transcript-errors.txt b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt index 4b5db144c3..75d6969501 100644 --- a/ChangeLog.d/1583-1584-ssl-transcript-errors.txt +++ b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt @@ -10,3 +10,4 @@ Security could allow a server to issue resumption tickets derived from an invalid resumption secret, weakening authentication of future resumptions made with those tickets. + * Reported by jjfz123 / https://github.com/jjfz123 / https://www.linkedin.com/in/jjfdzcastro1/ From 84e9ec5339ae0c5213e6f938d231ab5b5596c1aa Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Thu, 4 Jun 2026 10:32:03 +0100 Subject: [PATCH 19/38] Tidy up ChangeLog Signed-off-by: Ben Taylor --- ChangeLog.d/1583-1584-ssl-transcript-errors.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog.d/1583-1584-ssl-transcript-errors.txt b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt index 75d6969501..6d20d958b2 100644 --- a/ChangeLog.d/1583-1584-ssl-transcript-errors.txt +++ b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt @@ -4,10 +4,10 @@ Security handshake to fail. This could allow a handshake to continue with a master secret that was not correctly bound to the handshake transcript, undermining the security guarantees of the extended master secret - extension. + extension. Reported by jjfz123 / https://github.com/jjfz123 / + https://www.linkedin.com/in/jjfdzcastro1/ * Fix a bug where TLS 1.3 servers could ignore errors when computing the resumption master secret instead of causing the handshake to fail. This could allow a server to issue resumption tickets derived from an invalid resumption secret, weakening authentication of future resumptions made with those tickets. - * Reported by jjfz123 / https://github.com/jjfz123 / https://www.linkedin.com/in/jjfdzcastro1/ From 7d0e7f889e35383aa6431ff85fa731957eb1e572 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Thu, 4 Jun 2026 10:33:07 +0100 Subject: [PATCH 20/38] Remove check for NULL pointer Signed-off-by: Ben Taylor --- tests/suites/test_suite_ssl.function | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index d92a7cb72c..e88b9d5d96 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4436,7 +4436,6 @@ void tls_transcript_error_propagation(int endpoint, server_options.server_max_version = tls_version; abort_ctx.trigger = trigger; - TEST_ASSERT(abort_ctx.trigger != NULL); if (endpoint == MBEDTLS_SSL_IS_CLIENT) { client_options.cli_log_obj = &abort_ctx; From b8ed7d81c7b936316caf3bc99263092e9d0c9ca4 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Thu, 4 Jun 2026 12:12:00 +0100 Subject: [PATCH 21/38] Fix reporters in ChangeLog Signed-off-by: Ben Taylor --- ChangeLog.d/1583-1584-ssl-transcript-errors.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ChangeLog.d/1583-1584-ssl-transcript-errors.txt b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt index 6d20d958b2..c8b6aa696c 100644 --- a/ChangeLog.d/1583-1584-ssl-transcript-errors.txt +++ b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt @@ -4,10 +4,10 @@ Security handshake to fail. This could allow a handshake to continue with a master secret that was not correctly bound to the handshake transcript, undermining the security guarantees of the extended master secret - extension. Reported by jjfz123 / https://github.com/jjfz123 / - https://www.linkedin.com/in/jjfdzcastro1/ + extension. Report by Mathew Gretton-Dann * Fix a bug where TLS 1.3 servers could ignore errors when computing the resumption master secret instead of causing the handshake to fail. This could allow a server to issue resumption tickets derived from an invalid resumption secret, weakening authentication of future resumptions made - with those tickets. + with those tickets. Reported by jjfz123 / https://github.com/jjfz123 / + https://www.linkedin.com/in/jjfdzcastro1/ From f1bac693c61539b530b7e8513482e6480b0bbdb3 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Fri, 5 Jun 2026 07:54:38 +0100 Subject: [PATCH 22/38] Update ChangeLog Signed-off-by: Ben Taylor --- ChangeLog.d/1583-1584-ssl-transcript-errors.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ChangeLog.d/1583-1584-ssl-transcript-errors.txt b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt index c8b6aa696c..e21c52cfde 100644 --- a/ChangeLog.d/1583-1584-ssl-transcript-errors.txt +++ b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt @@ -4,10 +4,9 @@ Security handshake to fail. This could allow a handshake to continue with a master secret that was not correctly bound to the handshake transcript, undermining the security guarantees of the extended master secret - extension. Report by Mathew Gretton-Dann + extension. Report by Mathew Gretton-Dann. * Fix a bug where TLS 1.3 servers could ignore errors when computing the resumption master secret instead of causing the handshake to fail. This could allow a server to issue resumption tickets derived from an invalid resumption secret, weakening authentication of future resumptions made - with those tickets. Reported by jjfz123 / https://github.com/jjfz123 / - https://www.linkedin.com/in/jjfdzcastro1/ + with those tickets. Reported by jjfz123. From d55089507512d5cb3434c54d399a39604f3b67a1 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Fri, 5 Jun 2026 08:33:11 +0100 Subject: [PATCH 23/38] Improve testing Signed-off-by: Ben Taylor --- tests/suites/test_suite_ssl.data | 22 ++-- tests/suites/test_suite_ssl.function | 150 +++++++++++++-------------- 2 files changed, 86 insertions(+), 86 deletions(-) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index c8e257952b..14fad7a571 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3378,21 +3378,21 @@ elliptic_curve_get_properties TLS 1.3 resume session with ticket tls13_resume_session_with_ticket -TLS 1.3 server propagates RMS computation error +TLS 1.3 server propagates RMS computation error depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_X509_RSASSA_PSS_SUPPORT:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT tls_transcript_error_propagation:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_3:"<= parse finished message":MBEDTLS_SSL_CLIENT_FINISHED:MBEDTLS_SSL_FLUSH_BUFFERS - -TLS 1.3 client propagates RMS computation error + +TLS 1.3 client propagates RMS computation error depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_X509_RSASSA_PSS_SUPPORT:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT -tls_transcript_error_propagation:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_VERSION_TLS1_3:"<= write finished message":MBEDTLS_SSL_CLIENT_FINISHED:MBEDTLS_SSL_CLIENT_FINISHED - -TLS 1.2 server propagates EMS computation error -depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED +tls_transcript_error_propagation:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_VERSION_TLS1_3:"<= write finished message":MBEDTLS_SSL_CLIENT_FINISHED:-1 + +TLS 1.2 server propagates EMS computation error +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED tls_transcript_error_propagation:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_2:"=> derive keys":MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:MBEDTLS_SSL_CERTIFICATE_VERIFY - -TLS 1.2 client propagates EMS computation error -depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED -tls_transcript_error_propagation:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_VERSION_TLS1_2:"=> derive keys":MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:MBEDTLS_SSL_CERTIFICATE_VERIFY + +TLS 1.2 client propagates EMS computation error +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED +tls_transcript_error_propagation:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_VERSION_TLS1_2:"=> derive keys":MBEDTLS_SSL_CERTIFICATE_VERIFY:-1 TLS 1.3 read early data, early data accepted tls13_read_early_data:TEST_EARLY_DATA_ACCEPTED diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index e88b9d5d96..b4ea7ff97b 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4413,85 +4413,85 @@ exit: /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_SSL_TLS_C:MBEDTLS_DEBUG_C:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:MBEDTLS_TEST_HAS_DEFAULT_EC_GROUP:PSA_WANT_ALG_SHA_256 */ -void tls_transcript_error_propagation(int endpoint, - int tls_version, - const char *trigger, - int server_state, - int client_state) -{ - int ret = -1; - mbedtls_test_ssl_endpoint client_ep, server_ep; - mbedtls_test_handshake_test_options client_options; - mbedtls_test_init_handshake_options(&client_options); - mbedtls_test_handshake_test_options server_options; - mbedtls_test_init_handshake_options(&server_options); - tls_abort_transcript_context abort_ctx; - memset(&abort_ctx, 0, sizeof(abort_ctx)); - - PSA_INIT(); - - client_options.client_min_version = tls_version; - client_options.client_max_version = tls_version; - server_options.server_min_version = tls_version; - server_options.server_max_version = tls_version; - - abort_ctx.trigger = trigger; - - if (endpoint == MBEDTLS_SSL_IS_CLIENT) { - client_options.cli_log_obj = &abort_ctx; - client_options.cli_log_fun = tls_abort_transcript; - } else { - server_options.srv_log_obj = &abort_ctx; - server_options.srv_log_fun = tls_abort_transcript; - } - - mbedtls_debug_set_threshold(4); - +void tls_transcript_error_propagation(int endpoint, + int tls_version, + const char *trigger, + int target_state, + int peer_target_state) +{ + int ret = -1; + mbedtls_test_ssl_endpoint client_ep, server_ep; + mbedtls_test_handshake_test_options client_options; + mbedtls_test_init_handshake_options(&client_options); + mbedtls_test_handshake_test_options server_options; + mbedtls_test_init_handshake_options(&server_options); + tls_abort_transcript_context abort_ctx; + memset(&abort_ctx, 0, sizeof(abort_ctx)); + mbedtls_ssl_context *peer_ssl_context = NULL; + + PSA_INIT(); + + client_options.client_min_version = tls_version; + client_options.client_max_version = tls_version; + server_options.server_min_version = tls_version; + server_options.server_max_version = tls_version; + + abort_ctx.trigger = trigger; + TEST_ASSERT(abort_ctx.trigger != NULL); + + if (endpoint == MBEDTLS_SSL_IS_CLIENT) { + client_options.cli_log_obj = &abort_ctx; + client_options.cli_log_fun = tls_abort_transcript; + abort_ctx.ssl = &client_ep.ssl; + peer_ssl_context = &server_ep.ssl; + } else { + server_options.srv_log_obj = &abort_ctx; + server_options.srv_log_fun = tls_abort_transcript; + abort_ctx.ssl = &server_ep.ssl; + peer_ssl_context = &client_ep.ssl; + } + + mbedtls_debug_set_threshold(4); + TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT, - &client_options), 0); + &client_options), 0); TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER, &server_options), 0); - - /* Keep enough socket capacity for setup traffic so the final step below + + /* Keep enough socket capacity for setup traffic so the final step below * exercises the target state instead of only flushing previous messages. */ - TEST_EQUAL(mbedtls_test_mock_socket_connect(&(client_ep.socket), - &(server_ep.socket), 4096), 0); - - if (endpoint == MBEDTLS_SSL_IS_CLIENT) { - /* Moving the client to its target state drives the server as needed. - * Moving the server afterwards can advance the client past that state. */ - TEST_EQUAL(mbedtls_test_move_handshake_to_state( - &(client_ep.ssl), &(server_ep.ssl), - client_state), 0); - - abort_ctx.ssl = &client_ep.ssl; - } else { - TEST_EQUAL(mbedtls_test_move_handshake_to_state( - &(server_ep.ssl), &(client_ep.ssl), - server_state), 0); - - TEST_EQUAL(mbedtls_test_move_handshake_to_state( - &(client_ep.ssl), &(server_ep.ssl), - client_state), 0); - abort_ctx.ssl = &server_ep.ssl; - } - - TEST_EQUAL(mbedtls_ssl_flush_output(abort_ctx.ssl), 0); - TEST_EQUAL(abort_ctx.ssl->state, - endpoint == MBEDTLS_SSL_IS_CLIENT ? client_state : server_state); - TEST_EQUAL(abort_ctx.triggered, 0); - - ret = mbedtls_ssl_handshake_step(abort_ctx.ssl); - TEST_ASSERT(abort_ctx.triggered); - TEST_ASSERT(ret != 0); - -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_debug_set_threshold(0); - PSA_DONE(); + TEST_EQUAL(mbedtls_test_mock_socket_connect(&(client_ep.socket), + &(server_ep.socket), 4096), 0); + + TEST_EQUAL(mbedtls_test_move_handshake_to_state( + abort_ctx.ssl, peer_ssl_context, + target_state), 0); + /* + * Advance the peer further through the handshake so that it emits the + * messages needed by the endpoint under test to proceed through its next + * step. + */ + if (peer_target_state != -1) { + TEST_EQUAL(mbedtls_test_move_handshake_to_state( + peer_ssl_context, abort_ctx.ssl, + peer_target_state), 0); + } + + TEST_EQUAL(mbedtls_ssl_flush_output(abort_ctx.ssl), 0); + TEST_EQUAL(abort_ctx.ssl->state, target_state); + TEST_EQUAL(abort_ctx.triggered, 0); + + ret = mbedtls_ssl_handshake_step(abort_ctx.ssl); + TEST_ASSERT(abort_ctx.triggered); + TEST_ASSERT(ret != 0); + +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_debug_set_threshold(0); + PSA_DONE(); } /* END_CASE */ From 491243442a303e3553e9e79f75a6364dbcedf22c Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Fri, 5 Jun 2026 08:39:39 +0100 Subject: [PATCH 24/38] Update error handling of return from ssl_write_ecjpake_kkpp_ext Signed-off-by: Ben Taylor --- library/ssl_tls12_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index f6f5cb5f93..634b4511e3 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -2224,11 +2224,11 @@ static int ssl_write_server_hello(mbedtls_ssl_context *ssl) #endif #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if ((ret = ssl_write_ecjpake_kkpp_ext(ssl, p + 2 + ext_len, &olen)) != 0) { + ret = ssl_write_ecjpake_kkpp_ext(ssl, p + 2 + ext_len, &olen); + if (ret != 0) { MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_ecjpake_kkpp_ext", ret); return ret; } - ext_len += olen; #endif #if defined(MBEDTLS_SSL_ALPN) From 17160e402e97fdc896184bf7e38b16556ecfc31f Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Fri, 5 Jun 2026 08:42:19 +0100 Subject: [PATCH 25/38] Improve ChangeLog Signed-off-by: Ben Taylor --- ChangeLog.d/1583-1584-ssl-transcript-errors.txt | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/ChangeLog.d/1583-1584-ssl-transcript-errors.txt b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt index e21c52cfde..3a18c76df9 100644 --- a/ChangeLog.d/1583-1584-ssl-transcript-errors.txt +++ b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt @@ -5,8 +5,12 @@ Security secret that was not correctly bound to the handshake transcript, undermining the security guarantees of the extended master secret extension. Report by Mathew Gretton-Dann. - * Fix a bug where TLS 1.3 servers could ignore errors when computing the - resumption master secret instead of causing the handshake to fail. This - could allow a server to issue resumption tickets derived from an invalid - resumption secret, weakening authentication of future resumptions made - with those tickets. Reported by jjfz123. + * Fix a TLS 1.3 server-side error-handling bug affecting session ticket + generation. Under rare conditions, such as memory allocation failures + while computing the resumption master secret, the server could issue + invalid session tickets instead of failing the handshake. Clients + presented with such tickets would fail session resumption and fall back to + a full handshake. In deployments relying on session resumption, repeated + occurrences could increase the frequency of full handshakes and amplify + resource consumption during periods of resource exhaustion or other + transient failures. Reported by jjfz123. From 54d7ac4d3a85d817d478e90dd1581b90f590b0c7 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Fri, 5 Jun 2026 09:21:09 +0100 Subject: [PATCH 26/38] fix code style Signed-off-by: Ben Taylor --- tests/suites/test_suite_ssl.function | 150 +++++++++++++-------------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index b4ea7ff97b..f6b479d8bd 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4413,85 +4413,85 @@ exit: /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_SSL_TLS_C:MBEDTLS_DEBUG_C:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:MBEDTLS_TEST_HAS_DEFAULT_EC_GROUP:PSA_WANT_ALG_SHA_256 */ -void tls_transcript_error_propagation(int endpoint, - int tls_version, - const char *trigger, - int target_state, - int peer_target_state) -{ - int ret = -1; - mbedtls_test_ssl_endpoint client_ep, server_ep; - mbedtls_test_handshake_test_options client_options; - mbedtls_test_init_handshake_options(&client_options); - mbedtls_test_handshake_test_options server_options; - mbedtls_test_init_handshake_options(&server_options); - tls_abort_transcript_context abort_ctx; - memset(&abort_ctx, 0, sizeof(abort_ctx)); - mbedtls_ssl_context *peer_ssl_context = NULL; - - PSA_INIT(); - - client_options.client_min_version = tls_version; - client_options.client_max_version = tls_version; - server_options.server_min_version = tls_version; - server_options.server_max_version = tls_version; - - abort_ctx.trigger = trigger; - TEST_ASSERT(abort_ctx.trigger != NULL); - - if (endpoint == MBEDTLS_SSL_IS_CLIENT) { - client_options.cli_log_obj = &abort_ctx; - client_options.cli_log_fun = tls_abort_transcript; - abort_ctx.ssl = &client_ep.ssl; - peer_ssl_context = &server_ep.ssl; - } else { - server_options.srv_log_obj = &abort_ctx; - server_options.srv_log_fun = tls_abort_transcript; - abort_ctx.ssl = &server_ep.ssl; - peer_ssl_context = &client_ep.ssl; - } - - mbedtls_debug_set_threshold(4); - +void tls_transcript_error_propagation(int endpoint, + int tls_version, + const char *trigger, + int target_state, + int peer_target_state) +{ + int ret = -1; + mbedtls_test_ssl_endpoint client_ep, server_ep; + mbedtls_test_handshake_test_options client_options; + mbedtls_test_init_handshake_options(&client_options); + mbedtls_test_handshake_test_options server_options; + mbedtls_test_init_handshake_options(&server_options); + tls_abort_transcript_context abort_ctx; + memset(&abort_ctx, 0, sizeof(abort_ctx)); + mbedtls_ssl_context *peer_ssl_context = NULL; + + PSA_INIT(); + + client_options.client_min_version = tls_version; + client_options.client_max_version = tls_version; + server_options.server_min_version = tls_version; + server_options.server_max_version = tls_version; + + abort_ctx.trigger = trigger; + TEST_ASSERT(abort_ctx.trigger != NULL); + + if (endpoint == MBEDTLS_SSL_IS_CLIENT) { + client_options.cli_log_obj = &abort_ctx; + client_options.cli_log_fun = tls_abort_transcript; + abort_ctx.ssl = &client_ep.ssl; + peer_ssl_context = &server_ep.ssl; + } else { + server_options.srv_log_obj = &abort_ctx; + server_options.srv_log_fun = tls_abort_transcript; + abort_ctx.ssl = &server_ep.ssl; + peer_ssl_context = &client_ep.ssl; + } + + mbedtls_debug_set_threshold(4); + TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT, - &client_options), 0); + &client_options), 0); TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER, &server_options), 0); - - /* Keep enough socket capacity for setup traffic so the final step below + + /* Keep enough socket capacity for setup traffic so the final step below * exercises the target state instead of only flushing previous messages. */ - TEST_EQUAL(mbedtls_test_mock_socket_connect(&(client_ep.socket), - &(server_ep.socket), 4096), 0); - - TEST_EQUAL(mbedtls_test_move_handshake_to_state( - abort_ctx.ssl, peer_ssl_context, - target_state), 0); - /* - * Advance the peer further through the handshake so that it emits the - * messages needed by the endpoint under test to proceed through its next - * step. - */ - if (peer_target_state != -1) { - TEST_EQUAL(mbedtls_test_move_handshake_to_state( - peer_ssl_context, abort_ctx.ssl, - peer_target_state), 0); - } - - TEST_EQUAL(mbedtls_ssl_flush_output(abort_ctx.ssl), 0); - TEST_EQUAL(abort_ctx.ssl->state, target_state); - TEST_EQUAL(abort_ctx.triggered, 0); - - ret = mbedtls_ssl_handshake_step(abort_ctx.ssl); - TEST_ASSERT(abort_ctx.triggered); - TEST_ASSERT(ret != 0); - -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_debug_set_threshold(0); - PSA_DONE(); + TEST_EQUAL(mbedtls_test_mock_socket_connect(&(client_ep.socket), + &(server_ep.socket), 4096), 0); + + TEST_EQUAL(mbedtls_test_move_handshake_to_state( + abort_ctx.ssl, peer_ssl_context, + target_state), 0); + /* + * Advance the peer further through the handshake so that it emits the + * messages needed by the endpoint under test to proceed through its next + * step. + */ + if (peer_target_state != -1) { + TEST_EQUAL(mbedtls_test_move_handshake_to_state( + peer_ssl_context, abort_ctx.ssl, + peer_target_state), 0); + } + + TEST_EQUAL(mbedtls_ssl_flush_output(abort_ctx.ssl), 0); + TEST_EQUAL(abort_ctx.ssl->state, target_state); + TEST_EQUAL(abort_ctx.triggered, 0); + + ret = mbedtls_ssl_handshake_step(abort_ctx.ssl); + TEST_ASSERT(abort_ctx.triggered); + TEST_ASSERT(ret != 0); + +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_debug_set_threshold(0); + PSA_DONE(); } /* END_CASE */ From 814732a600514206d0188b7b76591693cc24ae03 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Mon, 8 Jun 2026 13:26:35 +0100 Subject: [PATCH 27/38] Update dependencies for skipped test Signed-off-by: Ben Taylor --- tests/suites/test_suite_ssl.data | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 14fad7a571..75c40f1a7c 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3379,11 +3379,11 @@ TLS 1.3 resume session with ticket tls13_resume_session_with_ticket TLS 1.3 server propagates RMS computation error -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_X509_RSASSA_PSS_SUPPORT:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_X509_RSASSA_PSS_SUPPORT:PSA_WANT_ALG_RSA_PKCS1V15_SIGN tls_transcript_error_propagation:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_3:"<= parse finished message":MBEDTLS_SSL_CLIENT_FINISHED:MBEDTLS_SSL_FLUSH_BUFFERS TLS 1.3 client propagates RMS computation error -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_X509_RSASSA_PSS_SUPPORT:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_X509_RSASSA_PSS_SUPPORT:PSA_WANT_ALG_RSA_PKCS1V15_SIGN tls_transcript_error_propagation:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_VERSION_TLS1_3:"<= write finished message":MBEDTLS_SSL_CLIENT_FINISHED:-1 TLS 1.2 server propagates EMS computation error From a893b52bad45403febb5987d054c4e16b2d29aa8 Mon Sep 17 00:00:00 2001 From: Ben Taylor <32939606+bjwtaylor@users.noreply.github.com> Date: Mon, 8 Jun 2026 13:28:07 +0100 Subject: [PATCH 28/38] Update ChangeLog to add CVE Co-authored-by: Gilles Peskine Signed-off-by: Ben Taylor <32939606+bjwtaylor@users.noreply.github.com> --- ChangeLog.d/1583-1584-ssl-transcript-errors.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog.d/1583-1584-ssl-transcript-errors.txt b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt index 3a18c76df9..ef092386a9 100644 --- a/ChangeLog.d/1583-1584-ssl-transcript-errors.txt +++ b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt @@ -4,7 +4,7 @@ Security handshake to fail. This could allow a handshake to continue with a master secret that was not correctly bound to the handshake transcript, undermining the security guarantees of the extended master secret - extension. Report by Mathew Gretton-Dann. + extension. Report by Mathew Gretton-Dann. CVE-2026-50581 * Fix a TLS 1.3 server-side error-handling bug affecting session ticket generation. Under rare conditions, such as memory allocation failures while computing the resumption master secret, the server could issue From 9b1549a0cb8a640764652d7c26b058a6c122ec63 Mon Sep 17 00:00:00 2001 From: Ben Taylor <32939606+bjwtaylor@users.noreply.github.com> Date: Mon, 8 Jun 2026 13:28:42 +0100 Subject: [PATCH 29/38] Update ChangeLog with CVE number Co-authored-by: Ronald Cron Signed-off-by: Ben Taylor <32939606+bjwtaylor@users.noreply.github.com> --- ChangeLog.d/1583-1584-ssl-transcript-errors.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog.d/1583-1584-ssl-transcript-errors.txt b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt index ef092386a9..f259bd711e 100644 --- a/ChangeLog.d/1583-1584-ssl-transcript-errors.txt +++ b/ChangeLog.d/1583-1584-ssl-transcript-errors.txt @@ -14,3 +14,4 @@ Security occurrences could increase the frequency of full handshakes and amplify resource consumption during periods of resource exhaustion or other transient failures. Reported by jjfz123. + CVE-2026-50640 From 76c60fe60310b96c719a45660634d242b7fa4105 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Mon, 8 Jun 2026 14:19:23 +0100 Subject: [PATCH 30/38] remove trailing whitespace Signed-off-by: Ben Taylor --- tests/suites/test_suite_ssl.data | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 75c40f1a7c..8eedeafb02 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3378,20 +3378,20 @@ elliptic_curve_get_properties TLS 1.3 resume session with ticket tls13_resume_session_with_ticket -TLS 1.3 server propagates RMS computation error +TLS 1.3 server propagates RMS computation error depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_X509_RSASSA_PSS_SUPPORT:PSA_WANT_ALG_RSA_PKCS1V15_SIGN tls_transcript_error_propagation:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_3:"<= parse finished message":MBEDTLS_SSL_CLIENT_FINISHED:MBEDTLS_SSL_FLUSH_BUFFERS - -TLS 1.3 client propagates RMS computation error + +TLS 1.3 client propagates RMS computation error depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_X509_RSASSA_PSS_SUPPORT:PSA_WANT_ALG_RSA_PKCS1V15_SIGN tls_transcript_error_propagation:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_VERSION_TLS1_3:"<= write finished message":MBEDTLS_SSL_CLIENT_FINISHED:-1 - -TLS 1.2 server propagates EMS computation error -depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED + +TLS 1.2 server propagates EMS computation error +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED tls_transcript_error_propagation:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_2:"=> derive keys":MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:MBEDTLS_SSL_CERTIFICATE_VERIFY - -TLS 1.2 client propagates EMS computation error -depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED + +TLS 1.2 client propagates EMS computation error +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED tls_transcript_error_propagation:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_VERSION_TLS1_2:"=> derive keys":MBEDTLS_SSL_CERTIFICATE_VERIFY:-1 TLS 1.3 read early data, early data accepted From e4e52d233e80c88e8c9559cabdc054506415c0c8 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Wed, 10 Jun 2026 08:11:37 +0100 Subject: [PATCH 31/38] restore missing ext_len set Signed-off-by: Ben Taylor --- library/ssl_tls12_server.c | 1 + 1 file changed, 1 insertion(+) diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index 634b4511e3..9aa009726c 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -2229,6 +2229,7 @@ static int ssl_write_server_hello(mbedtls_ssl_context *ssl) MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_ecjpake_kkpp_ext", ret); return ret; } + ext_len += olen; #endif #if defined(MBEDTLS_SSL_ALPN) From 34338f9aa99f20d2aaebd4cdb05410caabb1936c Mon Sep 17 00:00:00 2001 From: Ben Taylor <32939606+bjwtaylor@users.noreply.github.com> Date: Thu, 11 Jun 2026 09:43:59 +0100 Subject: [PATCH 32/38] Update regression test Co-authored-by: Ronald Cron Signed-off-by: Ben Taylor <32939606+bjwtaylor@users.noreply.github.com> --- tests/suites/test_suite_ssl.function | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index f6b479d8bd..502a045a02 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4475,6 +4475,7 @@ void tls_transcript_error_propagation(int endpoint, TEST_EQUAL(mbedtls_test_move_handshake_to_state( peer_ssl_context, abort_ctx.ssl, peer_target_state), 0); + TEST_EQUAL(mbedtls_ssl_flush_output(peer_ssl_context), 0); } TEST_EQUAL(mbedtls_ssl_flush_output(abort_ctx.ssl), 0); From e100cbcc2dced1470f4208626a536bc58a44b353 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Thu, 11 Jun 2026 10:30:44 +0100 Subject: [PATCH 33/38] Improve tls_transcript_error_propagation testing to check for error codes Signed-off-by: Ben Taylor --- tests/suites/test_suite_ssl.data | 8 ++++---- tests/suites/test_suite_ssl.function | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 8eedeafb02..71c43d6e17 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3380,19 +3380,19 @@ tls13_resume_session_with_ticket TLS 1.3 server propagates RMS computation error depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_X509_RSASSA_PSS_SUPPORT:PSA_WANT_ALG_RSA_PKCS1V15_SIGN -tls_transcript_error_propagation:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_3:"<= parse finished message":MBEDTLS_SSL_CLIENT_FINISHED:MBEDTLS_SSL_FLUSH_BUFFERS +tls_transcript_error_propagation:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_3:"<= parse finished message":MBEDTLS_SSL_CLIENT_FINISHED:MBEDTLS_SSL_FLUSH_BUFFERS:MBEDTLS_ERR_SSL_WANT_READ TLS 1.3 client propagates RMS computation error depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_X509_RSASSA_PSS_SUPPORT:PSA_WANT_ALG_RSA_PKCS1V15_SIGN -tls_transcript_error_propagation:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_VERSION_TLS1_3:"<= write finished message":MBEDTLS_SSL_CLIENT_FINISHED:-1 +tls_transcript_error_propagation:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_VERSION_TLS1_3:"<= write finished message":MBEDTLS_SSL_CLIENT_FINISHED:-1:MBEDTLS_ERR_SSL_INTERNAL_ERROR TLS 1.2 server propagates EMS computation error depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED -tls_transcript_error_propagation:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_2:"=> derive keys":MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:MBEDTLS_SSL_CERTIFICATE_VERIFY +tls_transcript_error_propagation:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_2:"=> derive keys":MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:MBEDTLS_SSL_CERTIFICATE_VERIFY:PSA_ERROR_GENERIC_ERROR TLS 1.2 client propagates EMS computation error depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED -tls_transcript_error_propagation:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_VERSION_TLS1_2:"=> derive keys":MBEDTLS_SSL_CERTIFICATE_VERIFY:-1 +tls_transcript_error_propagation:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_VERSION_TLS1_2:"=> derive keys":MBEDTLS_SSL_CERTIFICATE_VERIFY:-1:PSA_ERROR_GENERIC_ERROR TLS 1.3 read early data, early data accepted tls13_read_early_data:TEST_EARLY_DATA_ACCEPTED diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 502a045a02..a13f522536 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4417,7 +4417,8 @@ void tls_transcript_error_propagation(int endpoint, int tls_version, const char *trigger, int target_state, - int peer_target_state) + int peer_target_state, + int expected_ret) { int ret = -1; mbedtls_test_ssl_endpoint client_ep, server_ep; @@ -4485,6 +4486,7 @@ void tls_transcript_error_propagation(int endpoint, ret = mbedtls_ssl_handshake_step(abort_ctx.ssl); TEST_ASSERT(abort_ctx.triggered); TEST_ASSERT(ret != 0); + TEST_EQUAL(ret, expected_ret); exit: mbedtls_test_ssl_endpoint_free(&client_ep); From 6cb957324e1bb3fef1190d0aa06a29e43cedd81c Mon Sep 17 00:00:00 2001 From: Ben Taylor <32939606+bjwtaylor@users.noreply.github.com> Date: Thu, 11 Jun 2026 10:37:00 +0100 Subject: [PATCH 34/38] Fix error codes for tls_transcript_error_propagation Co-authored-by: Ronald Cron Signed-off-by: Ben Taylor <32939606+bjwtaylor@users.noreply.github.com> --- tests/suites/test_suite_ssl.data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 71c43d6e17..f0f84a05f1 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3380,7 +3380,7 @@ tls13_resume_session_with_ticket TLS 1.3 server propagates RMS computation error depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_X509_RSASSA_PSS_SUPPORT:PSA_WANT_ALG_RSA_PKCS1V15_SIGN -tls_transcript_error_propagation:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_3:"<= parse finished message":MBEDTLS_SSL_CLIENT_FINISHED:MBEDTLS_SSL_FLUSH_BUFFERS:MBEDTLS_ERR_SSL_WANT_READ +tls_transcript_error_propagation:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_3:"<= parse finished message":MBEDTLS_SSL_CLIENT_FINISHED:MBEDTLS_SSL_FLUSH_BUFFERS:MBEDTLS_ERR_SSL_INTERNAL_ERROR TLS 1.3 client propagates RMS computation error depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_X509_RSASSA_PSS_SUPPORT:PSA_WANT_ALG_RSA_PKCS1V15_SIGN From 7c007f49f76c3ca4b5b79f4f29f769df91ee1846 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Thu, 11 Jun 2026 11:12:10 +0100 Subject: [PATCH 35/38] Correct error handling in mbedtls_ssl_reset_checksum Signed-off-by: Ben Taylor Backport note: adapted from upstream commit 35da56b4c749cb066bddfd328731fb1c493228dc; not a direct cherry-pick. --- library/ssl_tls.c | 15 +++++++-------- library/ssl_tls12_server.c | 2 +- tests/suites/test_suite_ssl.data | 8 ++++---- tests/suites/test_suite_ssl.function | 21 ++++++++++++--------- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 19c82f039d..20529cd732 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -32,7 +32,6 @@ #if defined(MBEDTLS_USE_PSA_CRYPTO) #include "mbedtls/psa_util.h" #include "md_psa.h" -#include "psa_util_internal.h" #include "psa/crypto.h" #endif @@ -857,11 +856,11 @@ int mbedtls_ssl_reset_checksum(mbedtls_ssl_context *ssl) #if defined(MBEDTLS_USE_PSA_CRYPTO) status = psa_hash_abort(&ssl->handshake->fin_sha256_psa); if (status != PSA_SUCCESS) { - return mbedtls_md_error_from_psa(status); + return PSA_TO_MBEDTLS_ERR(status); } status = psa_hash_setup(&ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256); if (status != PSA_SUCCESS) { - return mbedtls_md_error_from_psa(status); + return PSA_TO_MBEDTLS_ERR(status); } #else mbedtls_md_free(&ssl->handshake->fin_sha256); @@ -882,11 +881,11 @@ int mbedtls_ssl_reset_checksum(mbedtls_ssl_context *ssl) #if defined(MBEDTLS_USE_PSA_CRYPTO) status = psa_hash_abort(&ssl->handshake->fin_sha384_psa); if (status != PSA_SUCCESS) { - return mbedtls_md_error_from_psa(status); + return PSA_TO_MBEDTLS_ERR(status); } status = psa_hash_setup(&ssl->handshake->fin_sha384_psa, PSA_ALG_SHA_384); if (status != PSA_SUCCESS) { - return mbedtls_md_error_from_psa(status); + return PSA_TO_MBEDTLS_ERR(status); } #else mbedtls_md_free(&ssl->handshake->fin_sha384); @@ -924,7 +923,7 @@ static int ssl_update_checksum_start(mbedtls_ssl_context *ssl, #if defined(MBEDTLS_USE_PSA_CRYPTO) status = psa_hash_update(&ssl->handshake->fin_sha256_psa, buf, len); if (status != PSA_SUCCESS) { - return mbedtls_md_error_from_psa(status); + return PSA_TO_MBEDTLS_ERR(status); } #else ret = mbedtls_md_update(&ssl->handshake->fin_sha256, buf, len); @@ -937,7 +936,7 @@ static int ssl_update_checksum_start(mbedtls_ssl_context *ssl, #if defined(MBEDTLS_USE_PSA_CRYPTO) status = psa_hash_update(&ssl->handshake->fin_sha384_psa, buf, len); if (status != PSA_SUCCESS) { - return mbedtls_md_error_from_psa(status); + return PSA_TO_MBEDTLS_ERR(status); } #else ret = mbedtls_md_update(&ssl->handshake->fin_sha384, buf, len); @@ -7353,7 +7352,7 @@ static int ssl_calc_verify_tls_psa(const mbedtls_ssl_context *ssl, exit: psa_hash_abort(&cloned_op); - return mbedtls_md_error_from_psa(status); + return PSA_TO_MBEDTLS_ERR(status); } #else static int ssl_calc_verify_tls_legacy(const mbedtls_ssl_context *ssl, diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index 9aa009726c..2a323dd759 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -1833,7 +1833,7 @@ static int ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context *ssl, ssl->conf->f_rng, ssl->conf->p_rng); if (ret != 0) { MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_write_round_one", ret); - return; + return ret; } #endif /* MBEDTLS_USE_PSA_CRYPTO */ diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index f0f84a05f1..49ea2a81f5 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3379,20 +3379,20 @@ TLS 1.3 resume session with ticket tls13_resume_session_with_ticket TLS 1.3 server propagates RMS computation error -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_X509_RSASSA_PSS_SUPPORT:PSA_WANT_ALG_RSA_PKCS1V15_SIGN +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_X509_RSASSA_PSS_SUPPORT:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 tls_transcript_error_propagation:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_3:"<= parse finished message":MBEDTLS_SSL_CLIENT_FINISHED:MBEDTLS_SSL_FLUSH_BUFFERS:MBEDTLS_ERR_SSL_INTERNAL_ERROR TLS 1.3 client propagates RMS computation error -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_X509_RSASSA_PSS_SUPPORT:PSA_WANT_ALG_RSA_PKCS1V15_SIGN +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_X509_RSASSA_PSS_SUPPORT:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 tls_transcript_error_propagation:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_VERSION_TLS1_3:"<= write finished message":MBEDTLS_SSL_CLIENT_FINISHED:-1:MBEDTLS_ERR_SSL_INTERNAL_ERROR TLS 1.2 server propagates EMS computation error depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED -tls_transcript_error_propagation:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_2:"=> derive keys":MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:MBEDTLS_SSL_CERTIFICATE_VERIFY:PSA_ERROR_GENERIC_ERROR +tls_transcript_error_propagation:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_2:"=> derive keys":MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:MBEDTLS_SSL_CERTIFICATE_VERIFY:MBEDTLS_ERR_SSL_INTERNAL_ERROR TLS 1.2 client propagates EMS computation error depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED -tls_transcript_error_propagation:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_VERSION_TLS1_2:"=> derive keys":MBEDTLS_SSL_CERTIFICATE_VERIFY:-1:PSA_ERROR_GENERIC_ERROR +tls_transcript_error_propagation:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_VERSION_TLS1_2:"=> derive keys":MBEDTLS_SSL_CERTIFICATE_VERIFY:-1:MBEDTLS_ERR_SSL_INTERNAL_ERROR TLS 1.3 read early data, early data accepted tls13_read_early_data:TEST_EARLY_DATA_ACCEPTED diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index a13f522536..43749cd622 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -57,7 +57,8 @@ static int failing_ticket_write_unset_lifetime( defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_SRV_C) && \ defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) && \ defined(MBEDTLS_TEST_HAS_DEFAULT_EC_GROUP) && \ - defined(PSA_WANT_ALG_SHA_256) + defined(MBEDTLS_USE_PSA_CRYPTO) && \ + defined(MBEDTLS_MD_CAN_SHA256) typedef struct { /* Context for tls_abort_transcript(). The debug callback watches for * trigger in the SSL debug trace, then aborts this connection's transcript @@ -91,10 +92,10 @@ static void tls_abort_transcript(void *ctx, int level, } abort_ctx->triggered = 1; -#if defined(PSA_WANT_ALG_SHA_256) +#if defined(MBEDTLS_MD_CAN_SHA256) psa_hash_abort(&abort_ctx->ssl->handshake->fin_sha256_psa); #endif -#if defined(PSA_WANT_ALG_SHA_384) +#if defined(MBEDTLS_MD_CAN_SHA384) psa_hash_abort(&abort_ctx->ssl->handshake->fin_sha384_psa); #endif } @@ -4412,7 +4413,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_SSL_TLS_C:MBEDTLS_DEBUG_C:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:MBEDTLS_TEST_HAS_DEFAULT_EC_GROUP:PSA_WANT_ALG_SHA_256 */ +/* BEGIN_CASE depends_on:MBEDTLS_SSL_TLS_C:MBEDTLS_DEBUG_C:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:MBEDTLS_TEST_HAS_DEFAULT_EC_GROUP:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_MD_CAN_SHA256 */ void tls_transcript_error_propagation(int endpoint, int tls_version, const char *trigger, @@ -4422,6 +4423,8 @@ void tls_transcript_error_propagation(int endpoint, { 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_init_handshake_options(&client_options); mbedtls_test_handshake_test_options server_options; @@ -4455,9 +4458,9 @@ void tls_transcript_error_propagation(int endpoint, mbedtls_debug_set_threshold(4); TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT, - &client_options), 0); + &client_options, NULL, NULL, NULL), 0); TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER, - &server_options), 0); + &server_options, NULL, NULL, NULL), 0); /* Keep enough socket capacity for setup traffic so the final step below * exercises the target state instead of only flushing previous messages. */ @@ -4489,8 +4492,8 @@ void tls_transcript_error_propagation(int endpoint, TEST_EQUAL(ret, expected_ret); exit: - mbedtls_test_ssl_endpoint_free(&client_ep); - mbedtls_test_ssl_endpoint_free(&server_ep); + mbedtls_test_ssl_endpoint_free(&client_ep, NULL); + mbedtls_test_ssl_endpoint_free(&server_ep, NULL); mbedtls_test_free_handshake_options(&client_options); mbedtls_test_free_handshake_options(&server_options); mbedtls_debug_set_threshold(0); @@ -4498,7 +4501,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE: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 */ +/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */ void tls13_resume_session_with_ticket() { int ret = -1; From ea00a9ee70a4d5060bb1cba1b9d46c830b799e81 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Tue, 23 Jun 2026 15:25:59 +0100 Subject: [PATCH 36/38] replace mbedtls_md_error_from_psa with PSA_TO_MBEDTLS_ERR Signed-off-by: Ben Taylor --- library/ssl_tls.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 20529cd732..fe7700e1d9 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -953,7 +953,7 @@ static int ssl_update_checksum_sha256(mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len) { #if defined(MBEDTLS_USE_PSA_CRYPTO) - return mbedtls_md_error_from_psa(psa_hash_update( + return PSA_TO_MBEDTLS_ERR(psa_hash_update( &ssl->handshake->fin_sha256_psa, buf, len)); #else return mbedtls_md_update(&ssl->handshake->fin_sha256, buf, len); @@ -966,7 +966,7 @@ static int ssl_update_checksum_sha384(mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len) { #if defined(MBEDTLS_USE_PSA_CRYPTO) - return mbedtls_md_error_from_psa(psa_hash_update( + return PSA_TO_MBEDTLS_ERR(psa_hash_update( &ssl->handshake->fin_sha384_psa, buf, len)); #else return mbedtls_md_update(&ssl->handshake->fin_sha384, buf, len); @@ -8251,7 +8251,7 @@ static int ssl_calc_finished_tls_generic(mbedtls_ssl_context *ssl, void *ctx, exit: #if defined(MBEDTLS_USE_PSA_CRYPTO) psa_hash_abort(&cloned_op); - return mbedtls_md_error_from_psa(status); + return PSA_TO_MBEDTLS_ERR(status); #else mbedtls_md_free(&cloned_ctx); return ret; From 8e756e3ee3a55743f72b8cb558ac306a39d011a8 Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Tue, 23 Jun 2026 15:27:40 +0100 Subject: [PATCH 37/38] remove md_psa.h Signed-off-by: Ben Taylor --- library/ssl_tls.c | 1 - 1 file changed, 1 deletion(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index fe7700e1d9..060852eb05 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -31,7 +31,6 @@ #if defined(MBEDTLS_USE_PSA_CRYPTO) #include "mbedtls/psa_util.h" -#include "md_psa.h" #include "psa/crypto.h" #endif From 27065ceb643a4266888ba1f200e4f20845e801cf Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Wed, 24 Jun 2026 07:29:52 +0100 Subject: [PATCH 38/38] Fix code style Signed-off-by: Ben Taylor --- library/ssl_tls.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 060852eb05..a9436fbfba 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -953,7 +953,7 @@ static int ssl_update_checksum_sha256(mbedtls_ssl_context *ssl, { #if defined(MBEDTLS_USE_PSA_CRYPTO) return PSA_TO_MBEDTLS_ERR(psa_hash_update( - &ssl->handshake->fin_sha256_psa, buf, len)); + &ssl->handshake->fin_sha256_psa, buf, len)); #else return mbedtls_md_update(&ssl->handshake->fin_sha256, buf, len); #endif @@ -966,7 +966,7 @@ static int ssl_update_checksum_sha384(mbedtls_ssl_context *ssl, { #if defined(MBEDTLS_USE_PSA_CRYPTO) return PSA_TO_MBEDTLS_ERR(psa_hash_update( - &ssl->handshake->fin_sha384_psa, buf, len)); + &ssl->handshake->fin_sha384_psa, buf, len)); #else return mbedtls_md_update(&ssl->handshake->fin_sha384, buf, len); #endif