diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 6171f7c6da..aab0f63c29 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -2022,6 +2022,19 @@ static int ssl_tls13_process_server_hello(mbedtls_ssl_context *ssl) goto cleanup; } + /* + * TLS 1.3 is negotiated. Check that ServerHello/HRR ends at a record + * boundary. For HRR, which does not trigger a key update, this checks + * that HRR terminates the server flight. + */ + if (ssl->in_hslen != ssl->in_msglen) { + MBEDTLS_SSL_DEBUG_MSG(1, ("ServerHello end not aligned with a record boundary")); + ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; + MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE, + MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE); + goto cleanup; + } + MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_server_hello(ssl, buf, buf + buf_len, is_hrr)); diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index fca25892a4..7e4c909562 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -74,10 +74,20 @@ int mbedtls_ssl_tls13_fetch_handshake_msg(mbedtls_ssl_context *ssl, case MBEDTLS_SSL_HS_CERTIFICATE: case MBEDTLS_SSL_HS_CERTIFICATE_REQUEST: case MBEDTLS_SSL_HS_CERTIFICATE_VERIFY: + /* + * For TLS 1.3, ServerHello (including HelloRetryRequest) must end at a + * record boundary, but not for TLS 1.2. At this point the ServerHello + * has not yet been processed, so we do not know whether it negotiates + * TLS 1.3 or TLS 1.2. Defer the boundary check until the protocol + * version is known to be TLS 1.3. + */ + case MBEDTLS_SSL_HS_SERVER_HELLO: require_record_boundary = 0; break; default: + /* ClientHello, EndOfEarlyData, Finished, and KeyUpdate. + */ require_record_boundary = 1; }