diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index d024abf18..59e42c868 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -1189,8 +1189,6 @@ cleanup: static int ssl_tls13_postprocess_server_hello( mbedtls_ssl_context *ssl ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_key_set traffic_keys; - mbedtls_ssl_transform *transform_handshake = NULL; mbedtls_ssl_handshake_params *handshake = ssl->handshake; /* Determine the key exchange mode: @@ -1234,50 +1232,21 @@ static int ssl_tls13_postprocess_server_hello( mbedtls_ssl_context *ssl ) ret = mbedtls_ssl_tls13_key_schedule_stage_early( ssl ); if( ret != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_key_schedule_stage_early_data", + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_key_schedule_stage_early", ret ); goto cleanup; } - /* Compute handshake secret */ - ret = mbedtls_ssl_tls13_key_schedule_stage_handshake( ssl ); + ret = mbedtls_ssl_tls13_compute_handshake_transform( ssl ); if( ret != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_derive_master_secret", ret ); - goto cleanup; - } - - /* Next evolution in key schedule: Establish handshake secret and - * key material. */ - ret = mbedtls_ssl_tls13_generate_handshake_keys( ssl, &traffic_keys ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_generate_handshake_keys", + MBEDTLS_SSL_DEBUG_RET( 1, + "mbedtls_ssl_tls13_compute_handshake_transform", ret ); goto cleanup; } - transform_handshake = mbedtls_calloc( 1, sizeof( mbedtls_ssl_transform ) ); - if( transform_handshake == NULL ) - { - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto cleanup; - } - - ret = mbedtls_ssl_tls13_populate_transform( transform_handshake, - ssl->conf->endpoint, - ssl->session_negotiate->ciphersuite, - &traffic_keys, - ssl ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_populate_transform", ret ); - goto cleanup; - } - - handshake->transform_handshake = transform_handshake; - mbedtls_ssl_set_inbound_transform( ssl, transform_handshake ); - + mbedtls_ssl_set_inbound_transform( ssl, handshake->transform_handshake ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "Switch to handshake keys for inbound traffic" ) ); ssl->session_in = ssl->session_negotiate; @@ -1287,16 +1256,13 @@ static int ssl_tls13_postprocess_server_hello( mbedtls_ssl_context *ssl ) mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS ); cleanup: - - mbedtls_platform_zeroize( &traffic_keys, sizeof( traffic_keys ) ); if( ret != 0 ) { - mbedtls_free( transform_handshake ); - MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE, MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE ); } + return( ret ); } diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c index 6559bc91c..8ffd9a1a0 100644 --- a/library/ssl_tls13_keys.c +++ b/library/ssl_tls13_keys.c @@ -27,6 +27,7 @@ #include "mbedtls/hkdf.h" #include "mbedtls/debug.h" #include "mbedtls/error.h" +#include "mbedtls/platform.h" #include "ssl_misc.h" #include "ssl_tls13_keys.h" @@ -1506,8 +1507,62 @@ int mbedtls_ssl_tls13_generate_application_keys( /* randbytes is not used again */ mbedtls_platform_zeroize( ssl->handshake->randbytes, sizeof( ssl->handshake->randbytes ) ); + mbedtls_platform_zeroize( transcript, sizeof( transcript ) ); return( ret ); } +int mbedtls_ssl_tls13_compute_handshake_transform( mbedtls_ssl_context *ssl ) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_ssl_key_set traffic_keys; + mbedtls_ssl_transform *transform_handshake = NULL; + mbedtls_ssl_handshake_params *handshake = ssl->handshake; + + /* Compute handshake secret */ + ret = mbedtls_ssl_tls13_key_schedule_stage_handshake( ssl ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_derive_master_secret", ret ); + goto cleanup; + } + + /* Next evolution in key schedule: Establish handshake secret and + * key material. */ + ret = mbedtls_ssl_tls13_generate_handshake_keys( ssl, &traffic_keys ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_generate_handshake_keys", + ret ); + goto cleanup; + } + + transform_handshake = mbedtls_calloc( 1, sizeof( mbedtls_ssl_transform ) ); + if( transform_handshake == NULL ) + { + ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; + goto cleanup; + } + + ret = mbedtls_ssl_tls13_populate_transform( + transform_handshake, + ssl->conf->endpoint, + ssl->session_negotiate->ciphersuite, + &traffic_keys, + ssl ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_populate_transform", ret ); + goto cleanup; + } + handshake->transform_handshake = transform_handshake; + +cleanup: + mbedtls_platform_zeroize( &traffic_keys, sizeof( traffic_keys ) ); + if( ret != 0 ) + mbedtls_free( transform_handshake ); + + return( ret ); +} + #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ diff --git a/library/ssl_tls13_keys.h b/library/ssl_tls13_keys.h index d56067cef..676ebae8d 100644 --- a/library/ssl_tls13_keys.h +++ b/library/ssl_tls13_keys.h @@ -638,6 +638,17 @@ int mbedtls_ssl_tls13_calculate_verify_data( mbedtls_ssl_context *ssl, size_t *actual_len, int which ); +/** + * \brief Compute TLS 1.3 handshake transform + * + * \param ssl The SSL context to operate on. The early secret must have been + * computed. + * + * \returns \c 0 on success. + * \returns A negative error code on failure. + */ +int mbedtls_ssl_tls13_compute_handshake_transform( mbedtls_ssl_context *ssl ); + #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ #endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */ diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index d06b9a88e..b2a5cfcf5 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -22,10 +22,8 @@ #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3) #include "mbedtls/debug.h" - -#include "ssl_misc.h" -#include "ssl_tls13_keys.h" -#include "ssl_debug_helpers.h" +#include "mbedtls/error.h" +#include "mbedtls/platform.h" #if defined(MBEDTLS_ECP_C) #include "mbedtls/ecp.h" @@ -39,6 +37,10 @@ #define mbedtls_free free #endif /* MBEDTLS_PLATFORM_C */ +#include "ssl_misc.h" +#include "ssl_tls13_keys.h" +#include "ssl_debug_helpers.h" + /* From RFC 8446: * struct { * ProtocolVersion versions<2..254>; @@ -1024,6 +1026,26 @@ static int ssl_tls13_write_server_hello_body( mbedtls_ssl_context *ssl, return( ret ); } +static int ssl_tls13_finalize_write_server_hello( mbedtls_ssl_context *ssl ) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + ret = mbedtls_ssl_tls13_compute_handshake_transform( ssl ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, + "mbedtls_ssl_tls13_compute_handshake_transform", + ret ); + return( ret ); + } + + mbedtls_ssl_set_outbound_transform( ssl, + ssl->handshake->transform_handshake ); + MBEDTLS_SSL_DEBUG_MSG( + 3, ( "switching to handshake transform for outbound data" ) ); + + return( ret ); +} + static int ssl_tls13_write_server_hello( mbedtls_ssl_context *ssl ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; @@ -1047,13 +1069,88 @@ static int ssl_tls13_write_server_hello( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_finish_handshake_msg( ssl, buf_len, msg_len ) ); + MBEDTLS_SSL_PROC_CHK( ssl_tls13_finalize_write_server_hello( ssl ) ); + mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS ); + cleanup: MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello" ) ); return( ret ); } +/* + * Handler for MBEDTLS_SSL_ENCRYPTED_EXTENSIONS + */ + +/* + * struct { + * Extension extensions<0..2 ^ 16 - 1>; + * } EncryptedExtensions; + * + */ +static int ssl_tls13_write_encrypted_extensions_body( mbedtls_ssl_context *ssl, + unsigned char *buf, + unsigned char *end, + size_t *out_len ) +{ + unsigned char *p = buf; + size_t extensions_len = 0; + unsigned char *p_extensions_len; + + *out_len = 0; + + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 ); + p_extensions_len = p; + p += 2; + + ((void) ssl); + + extensions_len = ( p - p_extensions_len ) - 2; + MBEDTLS_PUT_UINT16_BE( extensions_len, p_extensions_len, 0 ); + + *out_len = p - buf; + + MBEDTLS_SSL_DEBUG_BUF( 4, "encrypted extensions", buf, *out_len ); + + return( 0 ); +} + +static int ssl_tls13_write_encrypted_extensions( mbedtls_ssl_context *ssl ) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char *buf; + size_t buf_len, msg_len; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write encrypted extensions" ) ); + + MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_start_handshake_msg( ssl, + MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, &buf, &buf_len ) ); + + MBEDTLS_SSL_PROC_CHK( ssl_tls13_write_encrypted_extensions_body( + ssl, buf, buf + buf_len, &msg_len ) ); + + mbedtls_ssl_add_hs_msg_to_checksum( + ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, buf, msg_len ); + + MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_finish_handshake_msg( + ssl, buf_len, msg_len ) ); + +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) + if( mbedtls_ssl_tls13_some_psk_enabled( ssl ) ) + mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_FINISHED ); + else + mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_CERTIFICATE ); +#else + mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_FINISHED ); +#endif + +cleanup: + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write encrypted extensions" ) ); + return( ret ); +} + /* * TLS 1.3 State Machine -- server side */ @@ -1089,6 +1186,15 @@ int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl ) ret = ssl_tls13_write_server_hello( ssl ); break; + case MBEDTLS_SSL_ENCRYPTED_EXTENSIONS: + ret = ssl_tls13_write_encrypted_extensions( ssl ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls13_write_encrypted_extensions", ret ); + return( ret ); + } + break; + default: MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) ); return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index dcee5df60..07ad1b3fd 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -11307,6 +11307,7 @@ run_test "TLS 1.3: Server side check - openssl" \ -s "tls13 server state: MBEDTLS_SSL_CLIENT_HELLO" \ -s "tls13 server state: MBEDTLS_SSL_SERVER_HELLO" \ -s "tls13 server state: MBEDTLS_SSL_ENCRYPTED_EXTENSIONS" \ + -s "tls13 server state: MBEDTLS_SSL_SERVER_CERTIFICATE" \ -s "SSL - The requested feature is not available" \ -s "=> parse client hello" \ -s "<= parse client hello" @@ -11323,6 +11324,7 @@ run_test "TLS 1.3: Server side check - gnutls" \ -s "tls13 server state: MBEDTLS_SSL_CLIENT_HELLO" \ -s "tls13 server state: MBEDTLS_SSL_SERVER_HELLO" \ -s "tls13 server state: MBEDTLS_SSL_ENCRYPTED_EXTENSIONS" \ + -s "tls13 server state: MBEDTLS_SSL_SERVER_CERTIFICATE" \ -s "SSL - The requested feature is not available" \ -s "=> parse client hello" \ -s "<= parse client hello" @@ -11338,7 +11340,8 @@ run_test "TLS 1.3: Server side check - mbedtls" \ -s "tls13 server state: MBEDTLS_SSL_CLIENT_HELLO" \ -s "tls13 server state: MBEDTLS_SSL_SERVER_HELLO" \ -s "tls13 server state: MBEDTLS_SSL_ENCRYPTED_EXTENSIONS" \ - -c "client state: MBEDTLS_SSL_ENCRYPTED_EXTENSIONS" \ + -s "tls13 server state: MBEDTLS_SSL_SERVER_CERTIFICATE" \ + -c "client state: MBEDTLS_SSL_CERTIFICATE_REQUEST" \ -s "SSL - The requested feature is not available" \ -s "=> parse client hello" \ -s "<= parse client hello"