From f670ba5e522f0ed116bf6951faebeb3a62493495 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 7 Mar 2025 15:09:32 +0100 Subject: [PATCH 01/21] Always call mbedtls_ssl_handshake_set_state Call a single function for all handshake state changes, for easier tracing. Signed-off-by: Gilles Peskine --- library/ssl_misc.h | 6 ++++++ library/ssl_msg.c | 4 ++-- library/ssl_tls.c | 34 +++++++++++++++++----------------- library/ssl_tls12_client.c | 36 ++++++++++++++++++------------------ library/ssl_tls12_server.c | 34 +++++++++++++++++----------------- 5 files changed, 60 insertions(+), 54 deletions(-) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index de8e0dae23..ce62c2c987 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -1304,12 +1304,18 @@ int mbedtls_ssl_handshake_client_step(mbedtls_ssl_context *ssl); MBEDTLS_CHECK_RETURN_CRITICAL int mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl); void mbedtls_ssl_handshake_wrapup(mbedtls_ssl_context *ssl); + static inline void mbedtls_ssl_handshake_set_state(mbedtls_ssl_context *ssl, mbedtls_ssl_states state) { ssl->state = (int) state; } +static inline void mbedtls_ssl_handshake_increment_state(mbedtls_ssl_context *ssl) +{ + mbedtls_ssl_handshake_set_state(ssl, ssl->state + 1); +} + MBEDTLS_CHECK_RETURN_CRITICAL int mbedtls_ssl_send_fatal_handshake_failure(mbedtls_ssl_context *ssl); diff --git a/library/ssl_msg.c b/library/ssl_msg.c index be0dc92720..f1fe0ec8e5 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -5044,7 +5044,7 @@ int mbedtls_ssl_write_change_cipher_spec(mbedtls_ssl_context *ssl) ssl->out_msglen = 1; ssl->out_msg[0] = 1; - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); @@ -5106,7 +5106,7 @@ int mbedtls_ssl_parse_change_cipher_spec(mbedtls_ssl_context *ssl) mbedtls_ssl_update_in_pointers(ssl); - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse change cipher spec")); diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 5a668a4660..75dde2b8ee 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1409,7 +1409,7 @@ int mbedtls_ssl_session_reset_int(mbedtls_ssl_context *ssl, int partial) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - ssl->state = MBEDTLS_SSL_HELLO_REQUEST; + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HELLO_REQUEST); ssl->flags &= MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION; ssl->tls_version = ssl->conf->max_tls_version; @@ -4235,7 +4235,7 @@ int mbedtls_ssl_handshake_step(mbedtls_ssl_context *ssl) switch (ssl->state) { case MBEDTLS_SSL_HELLO_REQUEST: - ssl->state = MBEDTLS_SSL_CLIENT_HELLO; + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO); ret = 0; break; @@ -4386,7 +4386,7 @@ int mbedtls_ssl_start_renegotiation(mbedtls_ssl_context *ssl) } #endif - ssl->state = MBEDTLS_SSL_HELLO_REQUEST; + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HELLO_REQUEST); ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS; if ((ret = mbedtls_ssl_handshake(ssl)) != 0) { @@ -5144,7 +5144,7 @@ static int ssl_context_load(mbedtls_ssl_context *ssl, * Most of them already set to the correct value by mbedtls_ssl_init() and * mbedtls_ssl_reset(), so we only need to set the remaining ones. */ - ssl->state = MBEDTLS_SSL_HANDSHAKE_OVER; + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER); ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_2; /* Adjust pointers for header fields of outgoing records to @@ -6726,7 +6726,7 @@ int mbedtls_ssl_write_certificate(mbedtls_ssl_context *ssl) if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) { MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate")); - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); return 0; } @@ -6743,7 +6743,7 @@ int mbedtls_ssl_parse_certificate(mbedtls_ssl_context *ssl) if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) { MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate")); - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); return 0; } @@ -6766,7 +6766,7 @@ int mbedtls_ssl_write_certificate(mbedtls_ssl_context *ssl) if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) { MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate")); - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); return 0; } @@ -6774,7 +6774,7 @@ int mbedtls_ssl_write_certificate(mbedtls_ssl_context *ssl) if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) { if (ssl->handshake->client_auth == 0) { MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate")); - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); return 0; } } @@ -6828,7 +6828,7 @@ int mbedtls_ssl_write_certificate(mbedtls_ssl_context *ssl) ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE; - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); @@ -7282,7 +7282,7 @@ crt_verify: exit: if (ret == 0) { - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); } #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) @@ -7460,7 +7460,7 @@ void mbedtls_ssl_handshake_wrapup(mbedtls_ssl_context *ssl) #endif mbedtls_ssl_handshake_wrapup_free_hs_transform(ssl); - ssl->state = MBEDTLS_SSL_HANDSHAKE_OVER; + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER); MBEDTLS_SSL_DEBUG_MSG(3, ("<= handshake wrapup")); } @@ -7504,16 +7504,16 @@ int mbedtls_ssl_write_finished(mbedtls_ssl_context *ssl) if (ssl->handshake->resume != 0) { #if defined(MBEDTLS_SSL_CLI_C) if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) { - ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP); } #endif #if defined(MBEDTLS_SSL_SRV_C) if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) { - ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC); } #endif } else { - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); } /* @@ -7639,16 +7639,16 @@ int mbedtls_ssl_parse_finished(mbedtls_ssl_context *ssl) if (ssl->handshake->resume != 0) { #if defined(MBEDTLS_SSL_CLI_C) if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) { - ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC); } #endif #if defined(MBEDTLS_SSL_SRV_C) if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) { - ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP); } #endif } else { - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); } #if defined(MBEDTLS_SSL_PROTO_DTLS) diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index e0743e1a6a..df7dfbfa61 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -1118,7 +1118,7 @@ static int ssl_parse_hello_verify_request(mbedtls_ssl_context *ssl) ssl->handshake->cookie_len = cookie_len; /* Start over at ClientHello */ - ssl->state = MBEDTLS_SSL_CLIENT_HELLO; + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO); ret = mbedtls_ssl_reset_checksum(ssl); if (0 != ret) { MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_reset_checksum"), ret); @@ -1327,7 +1327,7 @@ static int ssl_parse_server_hello(mbedtls_ssl_context *ssl) ssl->session_negotiate->ciphersuite != i || ssl->session_negotiate->id_len != n || memcmp(ssl->session_negotiate->id, buf + 35, n) != 0) { - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); ssl->handshake->resume = 0; #if defined(MBEDTLS_HAVE_TIME) ssl->session_negotiate->start = mbedtls_time(NULL); @@ -1336,7 +1336,7 @@ static int ssl_parse_server_hello(mbedtls_ssl_context *ssl) ssl->session_negotiate->id_len = n; memcpy(ssl->session_negotiate->id, buf + 35, n); } else { - ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC); } MBEDTLS_SSL_DEBUG_MSG(3, ("%s session has been resumed", @@ -1839,7 +1839,7 @@ static int ssl_parse_server_key_exchange(mbedtls_ssl_context *ssl) } MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse server key exchange")); - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); return 0; } ((void) p); @@ -2147,7 +2147,7 @@ start_processing: #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ exit: - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server key exchange")); @@ -2165,7 +2165,7 @@ static int ssl_parse_certificate_request(mbedtls_ssl_context *ssl) if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate request")); - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); return 0; } @@ -2192,7 +2192,7 @@ static int ssl_parse_certificate_request(mbedtls_ssl_context *ssl) if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate request")); - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); return 0; } @@ -2210,7 +2210,7 @@ static int ssl_parse_certificate_request(mbedtls_ssl_context *ssl) return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; } - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); ssl->handshake->client_auth = (ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST); @@ -2381,7 +2381,7 @@ static int ssl_parse_server_hello_done(mbedtls_ssl_context *ssl) return MBEDTLS_ERR_SSL_DECODE_ERROR; } - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); #if defined(MBEDTLS_SSL_PROTO_DTLS) if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { @@ -2683,7 +2683,7 @@ static int ssl_write_client_key_exchange(mbedtls_ssl_context *ssl) ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE; - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); @@ -2712,7 +2712,7 @@ static int ssl_write_certificate_verify(mbedtls_ssl_context *ssl) if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify")); - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); return 0; } @@ -2754,14 +2754,14 @@ static int ssl_write_certificate_verify(mbedtls_ssl_context *ssl) if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify")); - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); return 0; } if (ssl->handshake->client_auth == 0 || mbedtls_ssl_own_cert(ssl) == NULL) { MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify")); - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); return 0; } @@ -2843,7 +2843,7 @@ sign: ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY; - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); @@ -2917,7 +2917,7 @@ static int ssl_parse_new_session_ticket(mbedtls_ssl_context *ssl) /* We're not waiting for a NewSessionTicket message any more */ ssl->handshake->new_session_ticket = 0; - ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC); /* * Zero-length ticket means the server changed his mind and doesn't want @@ -2978,13 +2978,13 @@ int mbedtls_ssl_handshake_client_step(mbedtls_ssl_context *ssl) #if defined(MBEDTLS_SSL_SESSION_TICKETS) if (ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC && ssl->handshake->new_session_ticket != 0) { - ssl->state = MBEDTLS_SSL_NEW_SESSION_TICKET; + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_NEW_SESSION_TICKET); } #endif switch (ssl->state) { case MBEDTLS_SSL_HELLO_REQUEST: - ssl->state = MBEDTLS_SSL_CLIENT_HELLO; + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO); break; /* @@ -3069,7 +3069,7 @@ int mbedtls_ssl_handshake_client_step(mbedtls_ssl_context *ssl) case MBEDTLS_SSL_FLUSH_BUFFERS: MBEDTLS_SSL_DEBUG_MSG(2, ("handshake: done")); - ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP); break; case MBEDTLS_SSL_HANDSHAKE_WRAPUP: diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index e1785504b6..2b2b49f2b0 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -1597,7 +1597,7 @@ have_ciphersuite: ssl->session_negotiate->ciphersuite = ciphersuites[i]; ssl->handshake->ciphersuite_info = ciphersuite_info; - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); #if defined(MBEDTLS_SSL_PROTO_DTLS) if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { @@ -2015,7 +2015,7 @@ static int ssl_write_hello_verify_request(mbedtls_ssl_context *ssl) ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST; - ssl->state = MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT; + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT); if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); @@ -2183,7 +2183,7 @@ static int ssl_write_server_hello(mbedtls_ssl_context *ssl) * New session, create a new session id, * unless we're about to issue a session ticket */ - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); #if defined(MBEDTLS_HAVE_TIME) ssl->session_negotiate->start = mbedtls_time(NULL); @@ -2207,7 +2207,7 @@ static int ssl_write_server_hello(mbedtls_ssl_context *ssl) * Resuming a session */ n = ssl->session_negotiate->id_len; - ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC); if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) { MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret); @@ -2333,7 +2333,7 @@ static int ssl_write_certificate_request(mbedtls_ssl_context *ssl) if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate request")); - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); return 0; } @@ -2356,7 +2356,7 @@ static int ssl_write_certificate_request(mbedtls_ssl_context *ssl) MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate request")); - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) if (ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET) { @@ -3080,7 +3080,7 @@ static int ssl_write_server_key_exchange(mbedtls_ssl_context *ssl) /* Key exchanges not involving ephemeral keys don't use * ServerKeyExchange, so end here. */ MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write server key exchange")); - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); return 0; } #endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */ @@ -3134,7 +3134,7 @@ static int ssl_write_server_key_exchange(mbedtls_ssl_context *ssl) ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE; - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); @@ -3156,7 +3156,7 @@ static int ssl_write_server_hello_done(mbedtls_ssl_context *ssl) ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO_DONE; - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); #if defined(MBEDTLS_SSL_PROTO_DTLS) if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { @@ -3461,7 +3461,7 @@ static int ssl_parse_client_key_exchange(mbedtls_ssl_context *ssl) return ret; } - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse client key exchange")); @@ -3479,7 +3479,7 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl) if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify")); - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); return 0; } @@ -3505,20 +3505,20 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl) if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify")); - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); return 0; } #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) if (ssl->session_negotiate->peer_cert == NULL) { MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify")); - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); return 0; } #else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ if (ssl->session_negotiate->peer_cert_digest == NULL) { MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify")); - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); return 0; } #endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ @@ -3530,7 +3530,7 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl) return ret; } - ssl->state++; + mbedtls_ssl_handshake_increment_state(ssl); /* Process the message contents */ if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE || @@ -3714,7 +3714,7 @@ int mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl) switch (ssl->state) { case MBEDTLS_SSL_HELLO_REQUEST: - ssl->state = MBEDTLS_SSL_CLIENT_HELLO; + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO); break; /* @@ -3803,7 +3803,7 @@ int mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl) case MBEDTLS_SSL_FLUSH_BUFFERS: MBEDTLS_SSL_DEBUG_MSG(2, ("handshake: done")); - ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; + mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP); break; case MBEDTLS_SSL_HANDSHAKE_WRAPUP: From c67befee6afb6e22f7f506ef6110041f62071319 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 7 Mar 2025 20:45:29 +0100 Subject: [PATCH 02/21] Add a log message on every SSL state transition Signed-off-by: Gilles Peskine --- library/ssl_misc.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index ce62c2c987..e82c6250e4 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -16,6 +16,9 @@ #include "mbedtls/error.h" #include "mbedtls/ssl.h" +#include "mbedtls/debug.h" +#include "debug_internal.h" + #include "mbedtls/cipher.h" #include "psa/crypto.h" @@ -1305,9 +1308,21 @@ MBEDTLS_CHECK_RETURN_CRITICAL int mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl); void mbedtls_ssl_handshake_wrapup(mbedtls_ssl_context *ssl); +#if defined(MBEDTLS_DEBUG_C) +/* Declared in "ssl_debug_helpers.h". We can't include this file from + * "ssl_misc.h" because it includes "ssl_misc.h" because it needs some + * type definitions. TODO: split the type definitions and the helper + * functions into different headers. + */ +const char *mbedtls_ssl_states_str(mbedtls_ssl_states state); +#endif + static inline void mbedtls_ssl_handshake_set_state(mbedtls_ssl_context *ssl, mbedtls_ssl_states state) { + MBEDTLS_SSL_DEBUG_MSG(3, ("handshake state: %d (%s) -> %d (%s)", + ssl->state, mbedtls_ssl_states_str(ssl->state), + state, mbedtls_ssl_states_str(state))); ssl->state = (int) state; } From a4bf00227f5d534fc8dfaa85e3c4f447e138ff64 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 7 Mar 2025 20:37:49 +0100 Subject: [PATCH 03/21] Document gotcha of move_handshake_to_state A single call to move_handshake_to_state() can't do a full handshake. Signed-off-by: Gilles Peskine --- tests/include/test/ssl_helpers.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/include/test/ssl_helpers.h b/tests/include/test/ssl_helpers.h index 3ba314f832..0ca02700a6 100644 --- a/tests/include/test/ssl_helpers.h +++ b/tests/include/test/ssl_helpers.h @@ -476,6 +476,18 @@ void mbedtls_test_ssl_endpoint_free( * /p second_ssl is used as second endpoint and their sockets have to be * connected before calling this function. * + * For example, to perform a full handshake: + * ``` + * mbedtls_test_move_handshake_to_state( + * &server.ssl, &client.ssl, + * MBEDTLS_SSL_HANDSHAKE_OVER); + * mbedtls_test_move_handshake_to_state( + * &client.ssl, &client.ssl, + * MBEDTLS_SSL_HANDSHAKE_OVER); + * ``` + * Note that you need both calls to reach the handshake-over state on + * both sides. + * * \retval 0 on success, otherwise error code. */ int mbedtls_test_move_handshake_to_state(mbedtls_ssl_context *ssl, From 92122edf4b8d0b5dda73379fa895cdca51021910 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 7 Mar 2025 20:40:50 +0100 Subject: [PATCH 04/21] Create handshake record coalescing tests Create tests that coalesce the handshake messages in the first flight from the server. This lets us test the behavior of the library when a handshake record contains multiple handshake messages. Only non-protected (non-encrypted, non-authenticated) handshake messages are supported. The test code works for all protocol versions, but it is only effective in TLS 1.2. In TLS 1.3, there is only a single non-encrypted handshake record, so we can't test records containing more than one handshake message without a lot more work. Signed-off-by: Gilles Peskine --- tests/suites/test_suite_ssl.function | 232 +++++++++++++++++++++++ tests/suites/test_suite_ssl.records.data | 26 +++ 2 files changed, 258 insertions(+) create mode 100644 tests/suites/test_suite_ssl.records.data diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 743b53c007..278656c194 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -106,6 +106,98 @@ static void resize_buffers(int mfl, int renegotiation, int legacy_renegotiation, #define TEST_GCM_OR_CHACHAPOLY_ENABLED #endif +typedef enum { + RECOMBINE_NOMINAL, /* param: ignored */ + RECOMBINE_COALESCE, /* param: min number of records */ +} recombine_records_instruction_t; + +/* Coalesce TLS handshake records. + * DTLS is not supported. + * Encrypted or authenticated handshake records are not supported. + * Assume the buffer content is a valid sequence of records. + */ +static int recombine_coalesce_handshake_records(mbedtls_test_ssl_buffer *buf, + int max) +{ + const size_t header_length = 5; + TEST_LE_U(header_length, buf->content_length); + if (buf->buffer[0] != MBEDTLS_SSL_MSG_HANDSHAKE) { + return 0; + } + + size_t record_length = MBEDTLS_GET_UINT16_BE(buf->buffer, header_length - 2); + TEST_LE_U(header_length + record_length, buf->content_length); + + int count; + for (count = 1; count < max; count++) { + size_t next_start = header_length + record_length; + if (next_start >= buf->content_length) { + /* We've already reached the last record. */ + break; + } + + TEST_LE_U(next_start + header_length, buf->content_length); + if (buf->buffer[next_start] != MBEDTLS_SSL_MSG_HANDSHAKE) { + /* There's another record, but it isn't a handshake record. */ + break; + } + size_t next_length = + MBEDTLS_GET_UINT16_BE(buf->buffer, next_start + header_length - 2); + TEST_LE_U(next_start + header_length + next_length, buf->content_length); + + /* Erase the next record header */ + memmove(buf->buffer + next_start, + buf->buffer + next_start + header_length, + buf->content_length - next_start); + buf->content_length -= header_length; + /* Update the first record length */ + record_length += next_length; + TEST_LE_U(record_length, 0xffff); + MBEDTLS_PUT_UINT16_BE(record_length, buf->buffer, header_length - 2); + } + + return count; + +exit: + return -1; +} + +static int recombine_records(mbedtls_test_ssl_endpoint *server, + recombine_records_instruction_t instruction, + int param) +{ + mbedtls_test_ssl_buffer *buf = server->socket.output; + int ret; + + /* buf is a circular buffer. For simplicity, this code assumes that + * the data is located at the beginning. This should be ok since + * this function is only meant to be used on the first flight + * emitted by a server. */ + TEST_EQUAL(buf->start, 0); + + switch (instruction) { + case RECOMBINE_NOMINAL: + break; + + case RECOMBINE_COALESCE: + ret = recombine_coalesce_handshake_records(buf, param); + if (param == INT_MAX) { + TEST_LE_S(1, ret); + } else { + TEST_EQUAL(ret, param); + } + break; + + default: + TEST_FAIL("Instructions not understood"); + } + + return 1; + +exit: + return 0; +} + /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -2840,6 +2932,146 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void recombine_server_first_flight(int version, + int instruction, int param, + char *client_log, char *server_log, + int goal_state, int expected_ret) +{ + enum { BUFFSIZE = 17000 }; + mbedtls_test_ssl_endpoint client = { 0 }; + mbedtls_test_ssl_endpoint server = { 0 }; + 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); +#if defined(MBEDTLS_DEBUG_C) + mbedtls_test_ssl_log_pattern cli_pattern = { .pattern = client_log }; + mbedtls_test_ssl_log_pattern srv_pattern = { .pattern = server_log }; +#endif + int ret = 0; + + MD_OR_USE_PSA_INIT(); +#if defined(MBEDTLS_DEBUG_C) + mbedtls_debug_set_threshold(3); +#endif + + client_options.client_min_version = version; + client_options.client_max_version = version; +#if defined(MBEDTLS_DEBUG_C) + client_options.cli_log_obj = &cli_pattern; + client_options.cli_log_fun = mbedtls_test_ssl_log_analyzer; +#else + (void) cli_pattern; +#endif + TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&client, MBEDTLS_SSL_IS_CLIENT, + &client_options, NULL, NULL, + NULL), 0); +#if defined(MBEDTLS_DEBUG_C) + mbedtls_ssl_conf_dbg(&client.conf, client_options.cli_log_fun, + client_options.cli_log_obj); +#endif + + server_options.server_min_version = version; + server_options.server_max_version = version; +#if defined(MBEDTLS_DEBUG_C) + server_options.srv_log_obj = &srv_pattern; + server_options.srv_log_fun = mbedtls_test_ssl_log_analyzer; +#else + (void) srv_pattern; +#endif + TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&server, MBEDTLS_SSL_IS_SERVER, + &server_options, NULL, NULL, + NULL), 0); +#if defined(MBEDTLS_DEBUG_C) + mbedtls_ssl_conf_dbg(&server.conf, server_options.srv_log_fun, + server_options.srv_log_obj); +#endif + + TEST_EQUAL(mbedtls_test_mock_socket_connect(&client.socket, + &server.socket, + BUFFSIZE), 0); + + /* Client: emit the first flight from the client */ + while (ret == 0) { + mbedtls_test_set_step(client.ssl.state); + ret = mbedtls_ssl_handshake_step(&client.ssl); + } + TEST_EQUAL(ret, MBEDTLS_ERR_SSL_WANT_READ); + ret = 0; + TEST_EQUAL(client.ssl.state, MBEDTLS_SSL_SERVER_HELLO); + + /* Server: parse the first flight from the client + * and emit the first flight from the server */ + while (ret == 0) { + mbedtls_test_set_step(1000 + server.ssl.state); + ret = mbedtls_ssl_handshake_step(&server.ssl); + } + TEST_EQUAL(ret, MBEDTLS_ERR_SSL_WANT_READ); + ret = 0; + TEST_EQUAL(server.ssl.state, MBEDTLS_SSL_SERVER_HELLO_DONE + 1); + + /* Recombine the first flight from the server */ + TEST_ASSERT(recombine_records(&server, instruction, param)); + + /* Client: parse the first flight from the server + * and emit the second flight from the client */ + while (ret == 0 && !mbedtls_ssl_is_handshake_over(&client.ssl)) { + mbedtls_test_set_step(client.ssl.state); + ret = mbedtls_ssl_handshake_step(&client.ssl); + if (client.ssl.state == goal_state && ret != 0) { + TEST_EQUAL(ret, expected_ret); + goto goal_reached; + } + } +#if defined(MBEDTLS_SSL_PROTO_TLS1_3) + if (version >= MBEDTLS_SSL_VERSION_TLS1_3 && + goal_state >= MBEDTLS_SSL_HANDSHAKE_OVER) { + TEST_EQUAL(ret, 0); + } else +#endif + { + TEST_EQUAL(ret, MBEDTLS_ERR_SSL_WANT_READ); + } + ret = 0; + + /* Server: parse the first flight from the client + * and emit the second flight from the server */ + while (ret == 0 && !mbedtls_ssl_is_handshake_over(&server.ssl)) { + mbedtls_test_set_step(1000 + server.ssl.state); + ret = mbedtls_ssl_handshake_step(&server.ssl); + } + TEST_EQUAL(ret, 0); + + /* Client: parse the second flight from the server */ + while (ret == 0 && !mbedtls_ssl_is_handshake_over(&client.ssl)) { + mbedtls_test_set_step(client.ssl.state); + ret = mbedtls_ssl_handshake_step(&client.ssl); + } + if (client.ssl.state == goal_state) { + TEST_EQUAL(ret, expected_ret); + } else { + TEST_EQUAL(ret, 0); + } + +goal_reached: +#if defined(MBEDTLS_DEBUG_C) + TEST_ASSERT(cli_pattern.counter >= 1); + TEST_ASSERT(srv_pattern.counter >= 1); +#endif + +exit: + mbedtls_test_ssl_endpoint_free(&client, NULL); + mbedtls_test_ssl_endpoint_free(&server, NULL); + mbedtls_test_free_handshake_options(&client_options); + mbedtls_test_free_handshake_options(&server_options); + MD_OR_USE_PSA_DONE(); +#if defined(MBEDTLS_DEBUG_C) + mbedtls_debug_set_threshold(0); +#endif +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:!MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:PSA_WANT_ECC_SECP_R1_384:MBEDTLS_SSL_PROTO_DTLS:MBEDTLS_SSL_RENEGOTIATION:PSA_WANT_ALG_SHA_256:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY */ void renegotiation(int legacy_renegotiation) { diff --git a/tests/suites/test_suite_ssl.records.data b/tests/suites/test_suite_ssl.records.data new file mode 100644 index 0000000000..e31fbbd23a --- /dev/null +++ b/tests/suites/test_suite_ssl.records.data @@ -0,0 +1,26 @@ +Recombine server flight 1: TLS 1.2, nominal +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_NOMINAL:0:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 + +Recombine server flight 1: TLS 1.3, nominal +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_NOMINAL:0:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH:0 + +Recombine server flight 1: TLS 1.2, coalesce 2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE:2:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 + +Recombine server flight 1: TLS 1.2, coalesce 3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE:3:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 + +Recombine server flight 1: TLS 1.2, coalesce all +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE:INT_MAX:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 + +# TLS 1.3 has a single non-encrypted handshake record, so this doesn't +# actually perform any coalescing. Run the test case anyway, but this does +# very little beyond exercising the test code itself a little. +Recombine server flight 1: TLS 1.3, coalesce all +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_COALESCE:INT_MAX:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH:0 From 7c1dbeff4908b23dbced56694bc17263fd7e0eb7 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 7 Mar 2025 20:48:01 +0100 Subject: [PATCH 05/21] Test split, coalesced-split and empty handshake records Signed-off-by: Gilles Peskine --- library/ssl_msg.c | 1 + tests/suites/test_suite_ssl.function | 122 +++++++++++++++++++++++ tests/suites/test_suite_ssl.records.data | 88 ++++++++++++++++ 3 files changed, 211 insertions(+) diff --git a/library/ssl_msg.c b/library/ssl_msg.c index f1fe0ec8e5..dba8d74ba1 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -3699,6 +3699,7 @@ static int ssl_parse_record_header(mbedtls_ssl_context const *ssl, rec->buf_len = rec->data_offset + rec->data_len; if (rec->data_len == 0) { + MBEDTLS_SSL_DEBUG_MSG(1, ("rejecting empty record")); return MBEDTLS_ERR_SSL_INVALID_RECORD; } diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 278656c194..577249c1d8 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -108,9 +108,100 @@ static void resize_buffers(int mfl, int renegotiation, int legacy_renegotiation, typedef enum { RECOMBINE_NOMINAL, /* param: ignored */ + RECOMBINE_SPLIT_FIRST, /* param: offset of split (<=0 means from end) */ + RECOMBINE_INSERT_EMPTY, /* param: offset (<0 means from end) */ RECOMBINE_COALESCE, /* param: min number of records */ + RECOMBINE_COALESCE_SPLIT_ONCE, /* param: offset of split (<=0 means from end) */ + RECOMBINE_COALESCE_SPLIT_ENDS, /* the hairiest one? param: offset, must be >0 */ } recombine_records_instruction_t; +/* Split the first record into two pieces of lengths offset and + * record_length-offset. If offset is zero or negative, count from the end of + * the record. */ +static int recombine_split_first_record(mbedtls_test_ssl_buffer *buf, + int offset) +{ + const size_t header_length = 5; + TEST_LE_U(header_length, buf->content_length); + size_t record_length = MBEDTLS_GET_UINT16_BE(buf->buffer, header_length - 2); + + if (offset > 0) { + TEST_LE_S(offset, record_length); + } else { + TEST_LE_S(-offset, record_length); + offset = record_length + offset; + } + + /* Check that we have room to insert a record header */ + TEST_LE_U(buf->content_length + header_length, buf->capacity); + + /* Make room for a record header */ + size_t new_record_start = header_length + offset; + size_t new_content_start = new_record_start + header_length; + memmove(buf->buffer + new_content_start, + buf->buffer + new_record_start, + buf->content_length - new_record_start); + buf->content_length += header_length; + + /* Construct a header for the new record based on the existing one */ + memcpy(buf->buffer + new_record_start, buf->buffer, header_length); + MBEDTLS_PUT_UINT16_BE(record_length - offset, + buf->buffer, new_content_start - 2); + + /* Adjust the length of the first record */ + MBEDTLS_PUT_UINT16_BE(offset, buf->buffer, header_length - 2); + + return 0; + +exit: + return -1; +} + +/* Insert an empty record at the given offset. If offset is negative, + * count from the end of the first record. */ +static int recombine_insert_empty_record(mbedtls_test_ssl_buffer *buf, + int offset) +{ + const size_t header_length = 5; + TEST_LE_U(header_length, buf->content_length); + size_t record_length = MBEDTLS_GET_UINT16_BE(buf->buffer, header_length - 2); + + if (offset >= 0) { + TEST_LE_S(offset, record_length); + } else { + TEST_LE_S(-offset, record_length); + offset = record_length + offset; + } + + /* Check that we have room to insert two record headers */ + TEST_LE_U(buf->content_length + 2 * header_length, buf->capacity); + + /* Make room for an empty record and a record header */ + size_t empty_record_start = header_length + offset; + size_t empty_content_start = empty_record_start + header_length; + size_t tail_record_start = empty_content_start; + size_t tail_content_start = tail_record_start + header_length; + memmove(buf->buffer + tail_content_start, + buf->buffer + tail_record_start, + buf->content_length - tail_record_start); + buf->content_length += 2 * header_length; + + /* Construct headers for the new records based on the existing one */ + memcpy(buf->buffer + empty_record_start, buf->buffer, header_length); + MBEDTLS_PUT_UINT16_BE(0, buf->buffer, empty_content_start - 2); + memcpy(buf->buffer + tail_record_start, buf->buffer, header_length); + MBEDTLS_PUT_UINT16_BE(record_length - offset, + buf->buffer, tail_content_start - 2); + + /* Adjust the length of the first record */ + MBEDTLS_PUT_UINT16_BE(offset, buf->buffer, header_length - 2); + + return 0; + +exit: + return -1; +} + /* Coalesce TLS handshake records. * DTLS is not supported. * Encrypted or authenticated handshake records are not supported. @@ -179,6 +270,16 @@ static int recombine_records(mbedtls_test_ssl_endpoint *server, case RECOMBINE_NOMINAL: break; + case RECOMBINE_SPLIT_FIRST: + ret = recombine_split_first_record(buf, param); + TEST_LE_S(0, ret); + break; + + case RECOMBINE_INSERT_EMPTY: + ret = recombine_insert_empty_record(buf, param); + TEST_LE_S(0, ret); + break; + case RECOMBINE_COALESCE: ret = recombine_coalesce_handshake_records(buf, param); if (param == INT_MAX) { @@ -188,6 +289,27 @@ static int recombine_records(mbedtls_test_ssl_endpoint *server, } break; + case RECOMBINE_COALESCE_SPLIT_ONCE: + ret = recombine_coalesce_handshake_records(buf, INT_MAX); + /* Require at least two coalesced records, otherwise this + * doesn't lead to a meaningful test (use + * RECOMBINE_SPLIT_FIRST instead). */ + TEST_LE_S(2, ret); + ret = recombine_split_first_record(buf, param); + TEST_LE_S(0, ret); + break; + + case RECOMBINE_COALESCE_SPLIT_ENDS: + ret = recombine_coalesce_handshake_records(buf, INT_MAX); + /* Accept a single record, which will be split at both ends */ + TEST_LE_S(1, ret); + TEST_LE_S(1, param); + ret = recombine_split_first_record(buf, -param); + TEST_LE_S(0, ret); + ret = recombine_split_first_record(buf, param); + TEST_LE_S(0, ret); + break; + default: TEST_FAIL("Instructions not understood"); } diff --git a/tests/suites/test_suite_ssl.records.data b/tests/suites/test_suite_ssl.records.data index e31fbbd23a..ca19393fd5 100644 --- a/tests/suites/test_suite_ssl.records.data +++ b/tests/suites/test_suite_ssl.records.data @@ -24,3 +24,91 @@ recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE:INT_ Recombine server flight 1: TLS 1.3, coalesce all depends_on:MBEDTLS_SSL_PROTO_TLS1_3 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_COALESCE:INT_MAX:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH:0 + +Recombine server flight 1: TLS 1.2, split first at 4 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:4:"initial handshake fragment\: 4, 0..4 of":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 + +Recombine server flight 1: TLS 1.3, split first at 4 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:4:"initial handshake fragment\: 4, 0..4 of":"<= handshake wrapup":MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH:0 + +Recombine server flight 1: TLS 1.2, split first at end-1 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:-1:"subsequent handshake fragment\: 1,":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 + +Recombine server flight 1: TLS 1.3, split first at end-1 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:-1:"subsequent handshake fragment\: 1,":"<= handshake wrapup":MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH:0 + +# The library doesn't support an initial handshake fragment that doesn't +# contain the full 4-byte handshake header. +Recombine server flight 1: TLS 1.2, split first at 3 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:3:"handshake message too short\: 3":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD + +Recombine server flight 1: TLS 1.3, split first at 3 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:3:"handshake message too short\: 3":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD + +Recombine server flight 1: TLS 1.2, split first at 2 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:2:"handshake message too short\: 2":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD + +Recombine server flight 1: TLS 1.3, split first at 2 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:2:"handshake message too short\: 2":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD + +Recombine server flight 1: TLS 1.2, split first at 1 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:1:"handshake message too short\: 1":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD + +Recombine server flight 1: TLS 1.3, split first at 1 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:1:"handshake message too short\: 1":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD + +Recombine server flight 1: TLS 1.2, insert empty record after first (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:0:"rejecting empty record":"":MBEDTLS_SSL_SERVER_CERTIFICATE:MBEDTLS_ERR_SSL_INVALID_RECORD + +Recombine server flight 1: TLS 1.3, insert empty record after first (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:0:"rejecting empty record":"":MBEDTLS_SSL_ENCRYPTED_EXTENSIONS:MBEDTLS_ERR_SSL_INVALID_RECORD + +Recombine server flight 1: TLS 1.2, insert empty record at start (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_EMPTY:0:"rejecting empty record":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD + +Recombine server flight 1: TLS 1.3, insert empty record at start (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_EMPTY:0:"rejecting empty record":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD + +Recombine server flight 1: TLS 1.2, insert empty record at 42 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_EMPTY:42:"rejecting empty record":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD + +Recombine server flight 1: TLS 1.3, insert empty record at 42 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_EMPTY:42:"rejecting empty record":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD + +# Since there is a single unencrypted handshake message in the first flight +# from the server, and the test code that recombines handshake records can only +# handle plaintext records, we can't have TLS 1.3 tests with coalesced +# handshake messages. Hence most coalesce-and-split test cases are 1.2-only. + +Recombine server flight 1: TLS 1.2, coalesce and split at 4 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE_SPLIT_ONCE:4:"initial handshake fragment\: 4, 0..4 of":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 + +# The last message of the first flight from the server is ServerHelloDone, +# which is an empty handshake message, i.e. of length 4. The library doesn't +# support fragmentation of a handshake message, so the last place where we +# can split the flight is 4+1 = 5 bytes before it ends, with 1 byte in the +# previous handshake message and 4 bytes of ServerHelloDone including header. +Recombine server flight 1: TLS 1.2, coalesce and split at end-5 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE_SPLIT_ONCE:-5:"subsequent handshake fragment\: 5,":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 + +Recombine server flight 1: TLS 1.2, coalesce and split at both ends +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE_SPLIT_ENDS:5:"subsequent handshake fragment\: 5,":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 From 7ab9fb6d147e5afab97882b8bd612c66f9094189 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 7 Mar 2025 22:26:36 +0100 Subject: [PATCH 06/21] Pacify ancient clang -Wmissing-initializer Signed-off-by: Gilles Peskine --- tests/suites/test_suite_ssl.function | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 577249c1d8..91ffe35ee8 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -3061,8 +3061,10 @@ void recombine_server_first_flight(int version, int goal_state, int expected_ret) { enum { BUFFSIZE = 17000 }; - mbedtls_test_ssl_endpoint client = { 0 }; - mbedtls_test_ssl_endpoint server = { 0 }; + mbedtls_test_ssl_endpoint client; + memset(&client, 0, sizeof(client)); + mbedtls_test_ssl_endpoint server; + memset(&server, 0, sizeof(server)); mbedtls_test_handshake_test_options client_options; mbedtls_test_init_handshake_options(&client_options); mbedtls_test_handshake_test_options server_options; From bc694b3cbdcafdc4c750906523bf802b273cb4c1 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 7 Mar 2025 22:28:23 +0100 Subject: [PATCH 07/21] Fix printf of enum The enum is promoted to `int`, so `%d` is a correct format, but `gcc -Wformat` complains. Signed-off-by: Gilles Peskine --- library/ssl_misc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index e82c6250e4..f52f784476 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -1322,7 +1322,7 @@ static inline void mbedtls_ssl_handshake_set_state(mbedtls_ssl_context *ssl, { MBEDTLS_SSL_DEBUG_MSG(3, ("handshake state: %d (%s) -> %d (%s)", ssl->state, mbedtls_ssl_states_str(ssl->state), - state, mbedtls_ssl_states_str(state))); + (int) state, mbedtls_ssl_states_str(state))); ssl->state = (int) state; } From 074267282f266e6baf88a71bd836f1fb9434ac16 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 7 Mar 2025 23:01:42 +0100 Subject: [PATCH 08/21] Fix the build in PSK-only configurations Signed-off-by: Gilles Peskine --- tests/suites/test_suite_ssl.function | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 91ffe35ee8..ca85578b5b 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -115,6 +115,8 @@ typedef enum { RECOMBINE_COALESCE_SPLIT_ENDS, /* the hairiest one? param: offset, must be >0 */ } recombine_records_instruction_t; +#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) + /* Split the first record into two pieces of lengths offset and * record_length-offset. If offset is zero or negative, count from the end of * the record. */ @@ -320,6 +322,8 @@ exit: return 0; } +#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ + /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -3054,7 +3058,9 @@ exit: } /* END_CASE */ -/* BEGIN_CASE */ +/* This test case doesn't actually depend on certificates, + * but our helper code for mbedtls_test_ssl_endpoint does. */ +/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ void recombine_server_first_flight(int version, int instruction, int param, char *client_log, char *server_log, From c34ea472fb96531d7277823b620ec262472689e2 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 7 Mar 2025 23:04:23 +0100 Subject: [PATCH 09/21] Fix the build without MBEDTLS_DEBUG_C Signed-off-by: Gilles Peskine --- tests/suites/test_suite_ssl.function | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index ca85578b5b..061adba762 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -3078,6 +3078,9 @@ void recombine_server_first_flight(int version, #if defined(MBEDTLS_DEBUG_C) mbedtls_test_ssl_log_pattern cli_pattern = { .pattern = client_log }; mbedtls_test_ssl_log_pattern srv_pattern = { .pattern = server_log }; +#else + (void) client_log; + (void) server_log; #endif int ret = 0; @@ -3091,8 +3094,6 @@ void recombine_server_first_flight(int version, #if defined(MBEDTLS_DEBUG_C) client_options.cli_log_obj = &cli_pattern; client_options.cli_log_fun = mbedtls_test_ssl_log_analyzer; -#else - (void) cli_pattern; #endif TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&client, MBEDTLS_SSL_IS_CLIENT, &client_options, NULL, NULL, @@ -3107,8 +3108,6 @@ void recombine_server_first_flight(int version, #if defined(MBEDTLS_DEBUG_C) server_options.srv_log_obj = &srv_pattern; server_options.srv_log_fun = mbedtls_test_ssl_log_analyzer; -#else - (void) srv_pattern; #endif TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&server, MBEDTLS_SSL_IS_SERVER, &server_options, NULL, NULL, From 5e3c0bd82bcb14742b168d0a3621935d5949a300 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 10 Mar 2025 14:02:42 +0100 Subject: [PATCH 10/21] Also test inserting non-empty, non-handshake records Signed-off-by: Gilles Peskine --- tests/suites/test_suite_ssl.function | 60 +++++++++++++++++++----- tests/suites/test_suite_ssl.records.data | 40 ++++++++++++++++ 2 files changed, 89 insertions(+), 11 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 061adba762..52e887af6d 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -110,6 +110,7 @@ typedef enum { RECOMBINE_NOMINAL, /* param: ignored */ RECOMBINE_SPLIT_FIRST, /* param: offset of split (<=0 means from end) */ RECOMBINE_INSERT_EMPTY, /* param: offset (<0 means from end) */ + RECOMBINE_INSERT_RECORD, /* param: record type */ RECOMBINE_COALESCE, /* param: min number of records */ RECOMBINE_COALESCE_SPLIT_ONCE, /* param: offset of split (<=0 means from end) */ RECOMBINE_COALESCE_SPLIT_ENDS, /* the hairiest one? param: offset, must be >0 */ @@ -161,8 +162,9 @@ exit: /* Insert an empty record at the given offset. If offset is negative, * count from the end of the first record. */ -static int recombine_insert_empty_record(mbedtls_test_ssl_buffer *buf, - int offset) +static int recombine_insert_record(mbedtls_test_ssl_buffer *buf, + int offset, + uint8_t inserted_record_type) { const size_t header_length = 5; TEST_LE_U(header_length, buf->content_length); @@ -175,22 +177,50 @@ static int recombine_insert_empty_record(mbedtls_test_ssl_buffer *buf, offset = record_length + offset; } - /* Check that we have room to insert two record headers */ - TEST_LE_U(buf->content_length + 2 * header_length, buf->capacity); + uint8_t inserted_content[42] = { 0 }; + size_t inserted_content_length = 0; + switch (inserted_record_type) { + case MBEDTLS_SSL_MSG_ALERT: + inserted_content[0] = MBEDTLS_SSL_ALERT_LEVEL_WARNING; + inserted_content[1] = MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION; + inserted_content_length = 2; + break; + case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC: + inserted_content[0] = 0x01; + inserted_content_length = 1; + break; + case MBEDTLS_SSL_MSG_APPLICATION_DATA: + inserted_content_length = sizeof(inserted_content); + break; + default: + /* Leave the content empty */ + break; + } + + /* Check that we have room to insert two record headers plus the new + * content. */ + TEST_LE_U(buf->content_length + 2 * header_length + inserted_content_length, + buf->capacity); /* Make room for an empty record and a record header */ - size_t empty_record_start = header_length + offset; - size_t empty_content_start = empty_record_start + header_length; - size_t tail_record_start = empty_content_start; + size_t inserted_record_start = header_length + offset; + size_t inserted_content_start = inserted_record_start + header_length; + size_t tail_record_start = inserted_content_start + inserted_content_length; size_t tail_content_start = tail_record_start + header_length; memmove(buf->buffer + tail_content_start, buf->buffer + tail_record_start, buf->content_length - tail_record_start); buf->content_length += 2 * header_length; - /* Construct headers for the new records based on the existing one */ - memcpy(buf->buffer + empty_record_start, buf->buffer, header_length); - MBEDTLS_PUT_UINT16_BE(0, buf->buffer, empty_content_start - 2); + /* Construct the inserted record based on the existing one */ + memcpy(buf->buffer + inserted_record_start, buf->buffer, header_length); + buf->buffer[inserted_record_start] = inserted_record_type; + MBEDTLS_PUT_UINT16_BE(inserted_content_length, + buf->buffer, inserted_content_start - 2); + memcpy(buf->buffer + inserted_content_start, + inserted_content, inserted_content_length); + + /* Construct header for the last fragment based on the existing one */ memcpy(buf->buffer + tail_record_start, buf->buffer, header_length); MBEDTLS_PUT_UINT16_BE(record_length - offset, buf->buffer, tail_content_start - 2); @@ -278,7 +308,15 @@ static int recombine_records(mbedtls_test_ssl_endpoint *server, break; case RECOMBINE_INSERT_EMPTY: - ret = recombine_insert_empty_record(buf, param); + /* Insert an empty handshake record. */ + ret = recombine_insert_record(buf, param, MBEDTLS_SSL_MSG_HANDSHAKE); + TEST_LE_S(0, ret); + break; + + case RECOMBINE_INSERT_RECORD: + /* Insert an extra record at a position where splitting + * would be ok. */ + ret = recombine_insert_record(buf, 5, param); TEST_LE_S(0, ret); break; diff --git a/tests/suites/test_suite_ssl.records.data b/tests/suites/test_suite_ssl.records.data index ca19393fd5..2acbbe9f4f 100644 --- a/tests/suites/test_suite_ssl.records.data +++ b/tests/suites/test_suite_ssl.records.data @@ -91,6 +91,46 @@ Recombine server flight 1: TLS 1.3, insert empty record at 42 (bad) depends_on:MBEDTLS_SSL_PROTO_TLS1_3 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_EMPTY:42:"rejecting empty record":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD +Recombine server flight 1: TLS 1.2, insert ChangeCipherSpec record at 5 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC:"non-handshake message in the middle of a fragmented handshake message":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE + +Recombine server flight 1: TLS 1.3, insert ChangeCipherSpec record at 5 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC:"non-handshake message in the middle of a fragmented handshake message":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE + +Recombine server flight 1: TLS 1.2, insert alert record at 5 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_ALERT:"non-handshake message in the middle of a fragmented handshake message":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE + +Recombine server flight 1: TLS 1.3, insert alert record at 5 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_ALERT:"non-handshake message in the middle of a fragmented handshake message":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE + +Recombine server flight 1: TLS 1.2, insert data record at 5 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_APPLICATION_DATA:"non-handshake message in the middle of a fragmented handshake message":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE + +Recombine server flight 1: TLS 1.3, insert data record at 5 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_APPLICATION_DATA:"non-handshake message in the middle of a fragmented handshake message":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE + +Recombine server flight 1: TLS 1.2, insert CID record at 5 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_CID:"unknown record type":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD + +Recombine server flight 1: TLS 1.3, insert CID record at 5 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_CID:"unknown record type":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD + +Recombine server flight 1: TLS 1.2, insert unknown record at 5 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_RECORD:255:"unknown record type 255":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD + +Recombine server flight 1: TLS 1.3, insert unknown record at 5 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_RECORD:255:"unknown record type 255":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD + # Since there is a single unencrypted handshake message in the first flight # from the server, and the test code that recombines handshake records can only # handle plaintext records, we can't have TLS 1.3 tests with coalesced From 84ccbd800206db97f2334704b3d0e01be82c49fb Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 10 Mar 2025 14:16:46 +0100 Subject: [PATCH 11/21] Simulate closing the connection mid-message Simulate the server closing the connection after a partial handshake message. These test cases don't send a close_notify alert. The test cases "insert alert record" exercise what happens if the server sends an alert. Signed-off-by: Gilles Peskine --- tests/suites/test_suite_ssl.function | 47 ++++++++++++++++++++++++ tests/suites/test_suite_ssl.records.data | 8 ++++ 2 files changed, 55 insertions(+) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 52e887af6d..3081257cb8 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -109,6 +109,7 @@ static void resize_buffers(int mfl, int renegotiation, int legacy_renegotiation, typedef enum { RECOMBINE_NOMINAL, /* param: ignored */ RECOMBINE_SPLIT_FIRST, /* param: offset of split (<=0 means from end) */ + RECOMBINE_TRUNCATE_FIRST, /* param: offset of truncation (<=0 means from end) */ RECOMBINE_INSERT_EMPTY, /* param: offset (<0 means from end) */ RECOMBINE_INSERT_RECORD, /* param: record type */ RECOMBINE_COALESCE, /* param: min number of records */ @@ -160,6 +161,39 @@ exit: return -1; } +/* Truncate the first record, keeping only the first offset bytes. + * If offset is zero or negative, count from the end of the record. + * Remove the subsequent records. + */ +static int recombine_truncate_first_record(mbedtls_test_ssl_buffer *buf, + int offset) +{ + const size_t header_length = 5; + TEST_LE_U(header_length, buf->content_length); + size_t record_length = MBEDTLS_GET_UINT16_BE(buf->buffer, header_length - 2); + + if (offset > 0) { + TEST_LE_S(offset, record_length); + } else { + TEST_LE_S(-offset, record_length); + offset = record_length + offset; + } + + /* Adjust the length of the first record */ + MBEDTLS_PUT_UINT16_BE(offset, buf->buffer, header_length - 2); + + /* Wipe the rest */ + size_t truncated_end = header_length + offset; + memset(buf->buffer + truncated_end, '!', + buf->content_length - truncated_end); + buf->content_length = truncated_end; + + return 0; + +exit: + return -1; +} + /* Insert an empty record at the given offset. If offset is negative, * count from the end of the first record. */ static int recombine_insert_record(mbedtls_test_ssl_buffer *buf, @@ -307,6 +341,11 @@ static int recombine_records(mbedtls_test_ssl_endpoint *server, TEST_LE_S(0, ret); break; + case RECOMBINE_TRUNCATE_FIRST: + ret = recombine_truncate_first_record(buf, param); + TEST_LE_S(0, ret); + break; + case RECOMBINE_INSERT_EMPTY: /* Insert an empty handshake record. */ ret = recombine_insert_record(buf, param, MBEDTLS_SSL_MSG_HANDSHAKE); @@ -3204,6 +3243,14 @@ void recombine_server_first_flight(int version, /* Server: parse the first flight from the client * and emit the second flight from the server */ + if (instruction == RECOMBINE_TRUNCATE_FIRST) { + /* Close without a notification. The case of closing with a + * notification is tested via RECOMBINE_INSERT_RECORD to insert + * an alert record (which we reject, making the client SSL + * context become invalid). */ + mbedtls_test_mock_socket_close(&server.socket); + goto goal_reached; + } while (ret == 0 && !mbedtls_ssl_is_handshake_over(&server.ssl)) { mbedtls_test_set_step(1000 + server.ssl.state); ret = mbedtls_ssl_handshake_step(&server.ssl); diff --git a/tests/suites/test_suite_ssl.records.data b/tests/suites/test_suite_ssl.records.data index 2acbbe9f4f..e94f554c69 100644 --- a/tests/suites/test_suite_ssl.records.data +++ b/tests/suites/test_suite_ssl.records.data @@ -67,6 +67,14 @@ Recombine server flight 1: TLS 1.3, split first at 1 (bad) depends_on:MBEDTLS_SSL_PROTO_TLS1_3 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:1:"handshake message too short\: 1":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD +Recombine server flight 1: TLS 1.2, truncate at 4 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_TRUNCATE_FIRST:4:"initial handshake fragment\: 4, 0..4 of":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_WANT_READ + +Recombine server flight 1: TLS 1.3, truncate at 4 (bad) +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_TRUNCATE_FIRST:4:"initial handshake fragment\: 4, 0..4 of":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_WANT_READ + Recombine server flight 1: TLS 1.2, insert empty record after first (bad) depends_on:MBEDTLS_SSL_PROTO_TLS1_2 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:0:"rejecting empty record":"":MBEDTLS_SSL_SERVER_CERTIFICATE:MBEDTLS_ERR_SSL_INVALID_RECORD From 161cadd1cc6097a7324bb65024e4bfc9f10236df Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 10 Mar 2025 14:24:22 +0100 Subject: [PATCH 12/21] Fix copypasta Signed-off-by: Gilles Peskine --- 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 0ca02700a6..c0c110105d 100644 --- a/tests/include/test/ssl_helpers.h +++ b/tests/include/test/ssl_helpers.h @@ -482,7 +482,7 @@ void mbedtls_test_ssl_endpoint_free( * &server.ssl, &client.ssl, * MBEDTLS_SSL_HANDSHAKE_OVER); * mbedtls_test_move_handshake_to_state( - * &client.ssl, &client.ssl, + * &client.ssl, &server.ssl, * MBEDTLS_SSL_HANDSHAKE_OVER); * ``` * Note that you need both calls to reach the handshake-over state on From eb48890bd5bdecf988ef1726895a7f6d0e94ff75 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 10 Mar 2025 14:29:59 +0100 Subject: [PATCH 13/21] Remove redundant setup mbedtls_test_ssl_endpoint_init() already takes care of setting up debugging. Signed-off-by: Gilles Peskine --- tests/suites/test_suite_ssl.function | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 3081257cb8..85c252492c 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -3175,10 +3175,6 @@ void recombine_server_first_flight(int version, TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&client, MBEDTLS_SSL_IS_CLIENT, &client_options, NULL, NULL, NULL), 0); -#if defined(MBEDTLS_DEBUG_C) - mbedtls_ssl_conf_dbg(&client.conf, client_options.cli_log_fun, - client_options.cli_log_obj); -#endif server_options.server_min_version = version; server_options.server_max_version = version; @@ -3189,10 +3185,6 @@ void recombine_server_first_flight(int version, TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&server, MBEDTLS_SSL_IS_SERVER, &server_options, NULL, NULL, NULL), 0); -#if defined(MBEDTLS_DEBUG_C) - mbedtls_ssl_conf_dbg(&server.conf, server_options.srv_log_fun, - server_options.srv_log_obj); -#endif TEST_EQUAL(mbedtls_test_mock_socket_connect(&client.socket, &server.socket, From c0721e0e8ecfa49567c2ffd2df1019ea65a2e96a Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 10 Mar 2025 14:53:16 +0100 Subject: [PATCH 14/21] Improve documentation Signed-off-by: Gilles Peskine --- tests/suites/test_suite_ssl.function | 19 ++++++++++++++++--- tests/suites/test_suite_ssl.records.data | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 85c252492c..8a77df5edf 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -112,9 +112,9 @@ typedef enum { RECOMBINE_TRUNCATE_FIRST, /* param: offset of truncation (<=0 means from end) */ RECOMBINE_INSERT_EMPTY, /* param: offset (<0 means from end) */ RECOMBINE_INSERT_RECORD, /* param: record type */ - RECOMBINE_COALESCE, /* param: min number of records */ + RECOMBINE_COALESCE, /* param: number of records (INT_MAX=all) */ RECOMBINE_COALESCE_SPLIT_ONCE, /* param: offset of split (<=0 means from end) */ - RECOMBINE_COALESCE_SPLIT_ENDS, /* the hairiest one? param: offset, must be >0 */ + RECOMBINE_COALESCE_SPLIT_BOTH_ENDS, /* param: offset, must be >0 */ } recombine_records_instruction_t; #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) @@ -272,6 +272,10 @@ exit: * DTLS is not supported. * Encrypted or authenticated handshake records are not supported. * Assume the buffer content is a valid sequence of records. + * + * Coalesce only the first max records, or all the records if there are + * fewer than max. + * Return the number of coalesced records, or -1 on error. */ static int recombine_coalesce_handshake_records(mbedtls_test_ssl_buffer *buf, int max) @@ -361,6 +365,9 @@ static int recombine_records(mbedtls_test_ssl_endpoint *server, case RECOMBINE_COALESCE: ret = recombine_coalesce_handshake_records(buf, param); + /* If param != INT_MAX, enforce that there were that many + * records to coalesce. In particular, 1 < param < INT_MAX + * ensures that library will see some coalesced records. */ if (param == INT_MAX) { TEST_LE_S(1, ret); } else { @@ -378,7 +385,7 @@ static int recombine_records(mbedtls_test_ssl_endpoint *server, TEST_LE_S(0, ret); break; - case RECOMBINE_COALESCE_SPLIT_ENDS: + case RECOMBINE_COALESCE_SPLIT_BOTH_ENDS: ret = recombine_coalesce_handshake_records(buf, INT_MAX); /* Accept a single record, which will be split at both ends */ TEST_LE_S(1, ret); @@ -3143,6 +3150,12 @@ void recombine_server_first_flight(int version, char *client_log, char *server_log, int goal_state, int expected_ret) { + /* Make sure we have a buffer that's large enough for the longest + * data that the library might ever send, plus a bit extra so that + * we can inject more content. The library won't ever send more than + * 2^14 bytes of handshake messages, so we round that up. In practice + * we could surely get away with a much smaller buffer. The main + * variable part is the server certificate. */ enum { BUFFSIZE = 17000 }; mbedtls_test_ssl_endpoint client; memset(&client, 0, sizeof(client)); diff --git a/tests/suites/test_suite_ssl.records.data b/tests/suites/test_suite_ssl.records.data index e94f554c69..edc2754356 100644 --- a/tests/suites/test_suite_ssl.records.data +++ b/tests/suites/test_suite_ssl.records.data @@ -159,4 +159,4 @@ recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE_SPLI Recombine server flight 1: TLS 1.2, coalesce and split at both ends depends_on:MBEDTLS_SSL_PROTO_TLS1_2 -recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE_SPLIT_ENDS:5:"subsequent handshake fragment\: 5,":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE_SPLIT_BOTH_ENDS:5:"subsequent handshake fragment\: 5,":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 From 0a1996f8eea4907393ef73c27528e12033ad3ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 26 Mar 2025 12:41:19 +0100 Subject: [PATCH 15/21] Tighten dependency declarations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are not optimal. For example, the tests should in principle be able to run in builds without ECDSA, by using RSA certs instead. Ideally PSK should work too. However, getting optimal dependencies would be a lot of work that's largely orthogonal to the purpose of this PR, so we'll settle for good enough. Signed-off-by: Manuel Pégourié-Gonnard --- tests/suites/test_suite_ssl.function | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 8a77df5edf..78f48e5b57 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -3144,7 +3144,7 @@ exit: /* This test case doesn't actually depend on certificates, * but our helper code for mbedtls_test_ssl_endpoint does. */ -/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ +/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:PSA_WANT_ALG_SHA_256:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_ALG_ECDSA_ANY */ void recombine_server_first_flight(int version, int instruction, int param, char *client_log, char *server_log, @@ -3179,6 +3179,10 @@ void recombine_server_first_flight(int version, mbedtls_debug_set_threshold(3); #endif + // Does't really matter but we want to know to declare dependencies. + client_options.pk_alg = MBEDTLS_PK_ECDSA; + server_options.pk_alg = MBEDTLS_PK_ECDSA; + client_options.client_min_version = version; client_options.client_max_version = version; #if defined(MBEDTLS_DEBUG_C) From 921a2acf8bf8366eb2f4b1fe80437289b42850cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 27 Mar 2025 11:47:13 +0100 Subject: [PATCH 16/21] Improve dependency declarations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function depends on MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED which is basically MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED || MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED The individual test cases depend on the specific TLS version. This is not precise enough. In a build with both TLS versions enabled, we could have cert-based key exchange in one version but not in the other. So, we need the 1.3 tests to depend on the 1.3 cert-based key exchange and similarly for 1.2. For 1.2, cert-based key exchange means ECDHE-{RSA,ECDSA} or ECDH-{RSA,ECDSA}. Since the test function sets an ECC cert for the server, we want one of the ECDSA ones. So, the minimal dependency would be ECDH_ECDSA || ECDHE_ECDSA. Since dependencies with || are inconvenient to express, and anyway ECDH_ECDSA (static ECDH) is something we'd like to remove in 4.0 if we can find the time, I chose to just depend on ECDHE_ECDSA. Signed-off-by: Manuel Pégourié-Gonnard --- tests/suites/test_suite_ssl.records.data | 74 ++++++++++++------------ 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/tests/suites/test_suite_ssl.records.data b/tests/suites/test_suite_ssl.records.data index edc2754356..3ec79183ba 100644 --- a/tests/suites/test_suite_ssl.records.data +++ b/tests/suites/test_suite_ssl.records.data @@ -1,142 +1,142 @@ Recombine server flight 1: TLS 1.2, nominal -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_NOMINAL:0:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 Recombine server flight 1: TLS 1.3, nominal -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_NOMINAL:0:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH:0 Recombine server flight 1: TLS 1.2, coalesce 2 -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE:2:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 Recombine server flight 1: TLS 1.2, coalesce 3 -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE:3:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 Recombine server flight 1: TLS 1.2, coalesce all -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE:INT_MAX:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 # TLS 1.3 has a single non-encrypted handshake record, so this doesn't # actually perform any coalescing. Run the test case anyway, but this does # very little beyond exercising the test code itself a little. Recombine server flight 1: TLS 1.3, coalesce all -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_COALESCE:INT_MAX:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH:0 Recombine server flight 1: TLS 1.2, split first at 4 -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:4:"initial handshake fragment\: 4, 0..4 of":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 Recombine server flight 1: TLS 1.3, split first at 4 -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:4:"initial handshake fragment\: 4, 0..4 of":"<= handshake wrapup":MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH:0 Recombine server flight 1: TLS 1.2, split first at end-1 -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:-1:"subsequent handshake fragment\: 1,":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 Recombine server flight 1: TLS 1.3, split first at end-1 -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:-1:"subsequent handshake fragment\: 1,":"<= handshake wrapup":MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH:0 # The library doesn't support an initial handshake fragment that doesn't # contain the full 4-byte handshake header. Recombine server flight 1: TLS 1.2, split first at 3 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:3:"handshake message too short\: 3":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.3, split first at 3 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:3:"handshake message too short\: 3":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.2, split first at 2 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:2:"handshake message too short\: 2":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.3, split first at 2 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:2:"handshake message too short\: 2":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.2, split first at 1 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:1:"handshake message too short\: 1":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.3, split first at 1 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:1:"handshake message too short\: 1":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.2, truncate at 4 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_TRUNCATE_FIRST:4:"initial handshake fragment\: 4, 0..4 of":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_WANT_READ Recombine server flight 1: TLS 1.3, truncate at 4 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_TRUNCATE_FIRST:4:"initial handshake fragment\: 4, 0..4 of":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_WANT_READ Recombine server flight 1: TLS 1.2, insert empty record after first (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:0:"rejecting empty record":"":MBEDTLS_SSL_SERVER_CERTIFICATE:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.3, insert empty record after first (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:0:"rejecting empty record":"":MBEDTLS_SSL_ENCRYPTED_EXTENSIONS:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.2, insert empty record at start (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_EMPTY:0:"rejecting empty record":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.3, insert empty record at start (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_EMPTY:0:"rejecting empty record":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.2, insert empty record at 42 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_EMPTY:42:"rejecting empty record":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.3, insert empty record at 42 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_EMPTY:42:"rejecting empty record":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.2, insert ChangeCipherSpec record at 5 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC:"non-handshake message in the middle of a fragmented handshake message":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE Recombine server flight 1: TLS 1.3, insert ChangeCipherSpec record at 5 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC:"non-handshake message in the middle of a fragmented handshake message":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE Recombine server flight 1: TLS 1.2, insert alert record at 5 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_ALERT:"non-handshake message in the middle of a fragmented handshake message":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE Recombine server flight 1: TLS 1.3, insert alert record at 5 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_ALERT:"non-handshake message in the middle of a fragmented handshake message":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE Recombine server flight 1: TLS 1.2, insert data record at 5 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_APPLICATION_DATA:"non-handshake message in the middle of a fragmented handshake message":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE Recombine server flight 1: TLS 1.3, insert data record at 5 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_APPLICATION_DATA:"non-handshake message in the middle of a fragmented handshake message":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE Recombine server flight 1: TLS 1.2, insert CID record at 5 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_CID:"unknown record type":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.3, insert CID record at 5 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_CID:"unknown record type":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.2, insert unknown record at 5 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_RECORD:255:"unknown record type 255":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.3, insert unknown record at 5 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_RECORD:255:"unknown record type 255":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD # Since there is a single unencrypted handshake message in the first flight @@ -145,7 +145,7 @@ recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_RECORD # handshake messages. Hence most coalesce-and-split test cases are 1.2-only. Recombine server flight 1: TLS 1.2, coalesce and split at 4 -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE_SPLIT_ONCE:4:"initial handshake fragment\: 4, 0..4 of":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 # The last message of the first flight from the server is ServerHelloDone, @@ -154,9 +154,9 @@ recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE_SPLI # can split the flight is 4+1 = 5 bytes before it ends, with 1 byte in the # previous handshake message and 4 bytes of ServerHelloDone including header. Recombine server flight 1: TLS 1.2, coalesce and split at end-5 -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE_SPLIT_ONCE:-5:"subsequent handshake fragment\: 5,":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 Recombine server flight 1: TLS 1.2, coalesce and split at both ends -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE_SPLIT_BOTH_ENDS:5:"subsequent handshake fragment\: 5,":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 From 1f471a1f38a4e4abcaf379ad7c9ca293693f2dd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 27 Mar 2025 12:44:32 +0100 Subject: [PATCH 17/21] Tighten dependencies again MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This one is overly tight: TLS 1.3 actually only depends on ChachaPoly || (AES && (GCM || CCM)) Furthermore, this should really be reflected in check_config.h. Individual test cases should be able to just request PROTO_TLS1_3 and know that there is ciphersuite that works. However, resolving that seems out of scope for this PR. (It would also involve updating depends.py for example.) So, use a dependency that's stricted than necessary. IMO it's still good enough as most configs we test will have ChachaPoly. However it would be good to revisit this when a cleaner solution is implemented. Signed-off-by: Manuel Pégourié-Gonnard --- tests/suites/test_suite_ssl.records.data | 32 ++++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/suites/test_suite_ssl.records.data b/tests/suites/test_suite_ssl.records.data index 3ec79183ba..c54458cf4b 100644 --- a/tests/suites/test_suite_ssl.records.data +++ b/tests/suites/test_suite_ssl.records.data @@ -3,7 +3,7 @@ depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_NOMINAL:0:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 Recombine server flight 1: TLS 1.3, nominal -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_NOMINAL:0:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH:0 Recombine server flight 1: TLS 1.2, coalesce 2 @@ -22,7 +22,7 @@ recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE:INT_ # actually perform any coalescing. Run the test case anyway, but this does # very little beyond exercising the test code itself a little. Recombine server flight 1: TLS 1.3, coalesce all -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_COALESCE:INT_MAX:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH:0 Recombine server flight 1: TLS 1.2, split first at 4 @@ -30,7 +30,7 @@ depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:4:"initial handshake fragment\: 4, 0..4 of":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 Recombine server flight 1: TLS 1.3, split first at 4 -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:4:"initial handshake fragment\: 4, 0..4 of":"<= handshake wrapup":MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH:0 Recombine server flight 1: TLS 1.2, split first at end-1 @@ -38,7 +38,7 @@ depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:-1:"subsequent handshake fragment\: 1,":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 Recombine server flight 1: TLS 1.3, split first at end-1 -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:-1:"subsequent handshake fragment\: 1,":"<= handshake wrapup":MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH:0 # The library doesn't support an initial handshake fragment that doesn't @@ -48,7 +48,7 @@ depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:3:"handshake message too short\: 3":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.3, split first at 3 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:3:"handshake message too short\: 3":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.2, split first at 2 (bad) @@ -56,7 +56,7 @@ depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:2:"handshake message too short\: 2":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.3, split first at 2 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:2:"handshake message too short\: 2":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.2, split first at 1 (bad) @@ -64,7 +64,7 @@ depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:1:"handshake message too short\: 1":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.3, split first at 1 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:1:"handshake message too short\: 1":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.2, truncate at 4 (bad) @@ -72,7 +72,7 @@ depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_TRUNCATE_FIRST:4:"initial handshake fragment\: 4, 0..4 of":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_WANT_READ Recombine server flight 1: TLS 1.3, truncate at 4 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_TRUNCATE_FIRST:4:"initial handshake fragment\: 4, 0..4 of":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_WANT_READ Recombine server flight 1: TLS 1.2, insert empty record after first (bad) @@ -80,7 +80,7 @@ depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:0:"rejecting empty record":"":MBEDTLS_SSL_SERVER_CERTIFICATE:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.3, insert empty record after first (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:0:"rejecting empty record":"":MBEDTLS_SSL_ENCRYPTED_EXTENSIONS:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.2, insert empty record at start (bad) @@ -88,7 +88,7 @@ depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_EMPTY:0:"rejecting empty record":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.3, insert empty record at start (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_EMPTY:0:"rejecting empty record":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.2, insert empty record at 42 (bad) @@ -96,7 +96,7 @@ depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_EMPTY:42:"rejecting empty record":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.3, insert empty record at 42 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_EMPTY:42:"rejecting empty record":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.2, insert ChangeCipherSpec record at 5 (bad) @@ -104,7 +104,7 @@ depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC:"non-handshake message in the middle of a fragmented handshake message":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE Recombine server flight 1: TLS 1.3, insert ChangeCipherSpec record at 5 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC:"non-handshake message in the middle of a fragmented handshake message":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE Recombine server flight 1: TLS 1.2, insert alert record at 5 (bad) @@ -112,7 +112,7 @@ depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_ALERT:"non-handshake message in the middle of a fragmented handshake message":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE Recombine server flight 1: TLS 1.3, insert alert record at 5 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_ALERT:"non-handshake message in the middle of a fragmented handshake message":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE Recombine server flight 1: TLS 1.2, insert data record at 5 (bad) @@ -120,7 +120,7 @@ depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_APPLICATION_DATA:"non-handshake message in the middle of a fragmented handshake message":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE Recombine server flight 1: TLS 1.3, insert data record at 5 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_APPLICATION_DATA:"non-handshake message in the middle of a fragmented handshake message":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE Recombine server flight 1: TLS 1.2, insert CID record at 5 (bad) @@ -128,7 +128,7 @@ depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_CID:"unknown record type":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.3, insert CID record at 5 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_RECORD:MBEDTLS_SSL_MSG_CID:"unknown record type":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.2, insert unknown record at 5 (bad) @@ -136,7 +136,7 @@ depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_INSERT_RECORD:255:"unknown record type 255":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD Recombine server flight 1: TLS 1.3, insert unknown record at 5 (bad) -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_INSERT_RECORD:255:"unknown record type 255":"":MBEDTLS_SSL_SERVER_HELLO:MBEDTLS_ERR_SSL_INVALID_RECORD # Since there is a single unencrypted handshake message in the first flight From 132f5b99c83c1e16ad4289eb0393f2effeb97cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Fri, 28 Mar 2025 09:33:38 +0100 Subject: [PATCH 18/21] Use same dependencies for helper functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- tests/suites/test_suite_ssl.function | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 78f48e5b57..0aa9f39ec0 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -117,7 +117,14 @@ typedef enum { RECOMBINE_COALESCE_SPLIT_BOTH_ENDS, /* param: offset, must be >0 */ } recombine_records_instruction_t; -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) +/* Keep this in sync with the recombine_server_first_flight() + * See comment there. */ +#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) && \ + defined(PSA_WANT_ALG_SHA_256) && \ + defined(PSA_WANT_ECC_SECP_R1_256) && \ + defined(PSA_WANT_ECC_SECP_R1_384) && \ + defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) && \ + defined(PSA_WANT_ALG_ECDSA_ANY) /* Split the first record into two pieces of lengths offset and * record_length-offset. If offset is zero or negative, count from the end of @@ -406,7 +413,7 @@ exit: return 0; } -#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ +#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED etc */ /* END_HEADER */ @@ -3143,7 +3150,11 @@ exit: /* END_CASE */ /* This test case doesn't actually depend on certificates, - * but our helper code for mbedtls_test_ssl_endpoint does. */ + * but our helper code for mbedtls_test_ssl_endpoint does. + * Also, it needs specific hashes, algs and curves for the + * hardcoded test certificates. In principle both RSA and ECDSA + * can be used, but we hardcode ECDSA in order to avoid having + * to express dependencies like "RSA or ECDSA with those curves". */ /* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:PSA_WANT_ALG_SHA_256:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_ALG_ECDSA_ANY */ void recombine_server_first_flight(int version, int instruction, int param, From 8d73bdc679d54112513160c5757bb4042c29071d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 10 Apr 2025 09:38:53 +0200 Subject: [PATCH 19/21] Improve comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- tests/suites/test_suite_ssl.function | 4 +++- tests/suites/test_suite_ssl.records.data | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 0aa9f39ec0..8964adc75b 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -201,7 +201,7 @@ exit: return -1; } -/* Insert an empty record at the given offset. If offset is negative, +/* Insert a (dummy) record at the given offset. If offset is negative, * count from the end of the first record. */ static int recombine_insert_record(mbedtls_test_ssl_buffer *buf, int offset, @@ -3251,6 +3251,8 @@ void recombine_server_first_flight(int version, } } #if defined(MBEDTLS_SSL_PROTO_TLS1_3) + /* A default TLS 1.3 handshake has only 1 flight from the server, + * while the default (non-resumption) 1.2 handshake has two. */ if (version >= MBEDTLS_SSL_VERSION_TLS1_3 && goal_state >= MBEDTLS_SSL_HANDSHAKE_OVER) { TEST_EQUAL(ret, 0); diff --git a/tests/suites/test_suite_ssl.records.data b/tests/suites/test_suite_ssl.records.data index c54458cf4b..a4bae89756 100644 --- a/tests/suites/test_suite_ssl.records.data +++ b/tests/suites/test_suite_ssl.records.data @@ -150,7 +150,7 @@ recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE_SPLI # The last message of the first flight from the server is ServerHelloDone, # which is an empty handshake message, i.e. of length 4. The library doesn't -# support fragmentation of a handshake message, so the last place where we +# support fragmentation of a handshake header, so the last place where we # can split the flight is 4+1 = 5 bytes before it ends, with 1 byte in the # previous handshake message and 4 bytes of ServerHelloDone including header. Recombine server flight 1: TLS 1.2, coalesce and split at end-5 From 7af97b60e54c3f35b8ff4b63fccb8d86bdd2285e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 10 Apr 2025 10:18:44 +0200 Subject: [PATCH 20/21] Use HANDSHAKE_OVER in nominal test cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- tests/suites/test_suite_ssl.records.data | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/suites/test_suite_ssl.records.data b/tests/suites/test_suite_ssl.records.data index a4bae89756..8220cb0b92 100644 --- a/tests/suites/test_suite_ssl.records.data +++ b/tests/suites/test_suite_ssl.records.data @@ -4,7 +4,7 @@ recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_NOMINAL:0:"<= Recombine server flight 1: TLS 1.3, nominal depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 -recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_NOMINAL:0:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH:0 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_NOMINAL:0:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 Recombine server flight 1: TLS 1.2, coalesce 2 depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED @@ -23,7 +23,7 @@ recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_COALESCE:INT_ # very little beyond exercising the test code itself a little. Recombine server flight 1: TLS 1.3, coalesce all depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 -recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_COALESCE:INT_MAX:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH:0 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_COALESCE:INT_MAX:"<= handshake wrapup":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 Recombine server flight 1: TLS 1.2, split first at 4 depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED @@ -31,7 +31,7 @@ recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:4 Recombine server flight 1: TLS 1.3, split first at 4 depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 -recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:4:"initial handshake fragment\: 4, 0..4 of":"<= handshake wrapup":MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH:0 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:4:"initial handshake fragment\: 4, 0..4 of":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 Recombine server flight 1: TLS 1.2, split first at end-1 depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED @@ -39,7 +39,7 @@ recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_2:RECOMBINE_SPLIT_FIRST:- Recombine server flight 1: TLS 1.3, split first at end-1 depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_CHACHA20_POLY1305 -recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:-1:"subsequent handshake fragment\: 1,":"<= handshake wrapup":MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH:0 +recombine_server_first_flight:MBEDTLS_SSL_VERSION_TLS1_3:RECOMBINE_SPLIT_FIRST:-1:"subsequent handshake fragment\: 1,":"<= handshake wrapup":MBEDTLS_SSL_HANDSHAKE_OVER:0 # The library doesn't support an initial handshake fragment that doesn't # contain the full 4-byte handshake header. From a5db6c14fd45fd91de495cac914e187ffbca99ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 10 Apr 2025 12:35:58 +0200 Subject: [PATCH 21/21] Fix record insertion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We were not making enough room. We want to move everything from the place where we are going to insert the new record. This was not causing failures because the code does not look at the content after the inserted record, because it correctly returns an error when seeing the inserted record. But as a matter on principle, the test code should be doing what it says: just insert a new record but leave a valid fragment after it. Signed-off-by: Manuel Pégourié-Gonnard --- tests/suites/test_suite_ssl.function | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 8964adc75b..11648a3341 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -243,14 +243,14 @@ static int recombine_insert_record(mbedtls_test_ssl_buffer *buf, TEST_LE_U(buf->content_length + 2 * header_length + inserted_content_length, buf->capacity); - /* Make room for an empty record and a record header */ + /* Make room for the inserted record and a record header for the fragment */ size_t inserted_record_start = header_length + offset; size_t inserted_content_start = inserted_record_start + header_length; size_t tail_record_start = inserted_content_start + inserted_content_length; size_t tail_content_start = tail_record_start + header_length; memmove(buf->buffer + tail_content_start, - buf->buffer + tail_record_start, - buf->content_length - tail_record_start); + buf->buffer + inserted_record_start, + buf->content_length - inserted_record_start); buf->content_length += 2 * header_length; /* Construct the inserted record based on the existing one */