diff --git a/ChangeLog.d/ssl-get-session-tls13-app-secrets.txt b/ChangeLog.d/ssl-get-session-tls13-app-secrets.txt new file mode 100644 index 0000000000..28bafb6cf0 --- /dev/null +++ b/ChangeLog.d/ssl-get-session-tls13-app-secrets.txt @@ -0,0 +1,6 @@ +Security + * Clear the TLS 1.3 application traffic secrets, exporter master secret and + resumption master secret from the session exported by + mbedtls_ssl_get_session(). These secrets are not needed to resume the + session and previously remained in the exported session object. Fixes + #10916. diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 1f44fc71a7..2289cb782e 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3053,6 +3053,14 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, return ret; } +#if defined(MBEDTLS_SSL_PROTO_TLS1_3) + /* These belong to the connection, not the exported session, and are not + * needed to resume. Clear them. */ + if (dst->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { + mbedtls_platform_zeroize(&dst->app_secrets, sizeof(dst->app_secrets)); + } +#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ + /* Remember that we've exported the session. */ ssl->session->exported = 1; return 0; diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 3415c80c90..8ed7140798 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3420,6 +3420,9 @@ ssl_ecjpake_set_password:1 Test Elliptic curves' info parsing elliptic_curve_get_properties +TLS 1.3 export session clears application secrets +tls13_export_session_clears_app_secrets + TLS 1.3 resume session with ticket tls13_resume_session_with_ticket diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 7a9a03adcd..e256505598 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4998,6 +4998,43 @@ 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_export_session_clears_app_secrets() +{ + int ret = -1; + mbedtls_test_handshake_test_options client_options; + mbedtls_test_handshake_test_options server_options; + mbedtls_ssl_session exported_session; + mbedtls_ssl_tls13_application_secrets zero_secrets; + + mbedtls_test_init_handshake_options(&client_options); + mbedtls_test_init_handshake_options(&server_options); + mbedtls_ssl_session_init(&exported_session); + memset(&zero_secrets, 0, sizeof(zero_secrets)); + + PSA_INIT(); + + client_options.pk_alg = MBEDTLS_PK_ECDSA; + server_options.pk_alg = MBEDTLS_PK_ECDSA; + + /* Full TLS 1.3 handshake with a ticket, then export the session. */ + ret = mbedtls_test_get_tls13_ticket(&client_options, &server_options, + &exported_session); + TEST_EQUAL(ret, 0); + + /* The exported session must not carry the connection's secrets. */ + TEST_MEMORY_COMPARE(&exported_session.app_secrets, + sizeof(exported_session.app_secrets), + &zero_secrets, sizeof(zero_secrets)); + +exit: + mbedtls_ssl_session_free(&exported_session); + mbedtls_test_free_handshake_options(&client_options); + mbedtls_test_free_handshake_options(&server_options); + PSA_DONE(); +} +/* 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() {