diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index d024abf180..93b063278c 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,20 @@ 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_set_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_set_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 +1255,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 6559bc91c1..dd6677ddf1 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" @@ -1510,4 +1511,58 @@ int mbedtls_ssl_tls13_generate_application_keys( return( ret ); } +int mbedtls_ssl_tls13_set_handshake_transform( mbedtls_ssl_context *ssl ) +{ + int ret; + 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 d56067cef7..62bd6c005b 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 secrtet must have been + * computed. + * + * \returns \c 0 on success. + * \returns A negative error code on failure. + */ +int mbedtls_ssl_tls13_set_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 0deeb76015..d6c1f5edcc 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -1026,6 +1026,25 @@ 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_set_handshake_transform( ssl ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_set_handshake_transform", + ret ); + return( ret ); + } + + mbedtls_ssl_set_outbound_transform( ssl, + ssl->handshake->transform_handshake ); + MBEDTLS_SSL_DEBUG_MSG( + 3, ( "switching to new transform spec for outbound data" ) ); + + return( ret ); +} + static int ssl_tls13_write_server_hello( mbedtls_ssl_context *ssl ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; @@ -1049,7 +1068,10 @@ 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" ) ); @@ -1059,55 +1081,6 @@ cleanup: /* * Handler for MBEDTLS_SSL_ENCRYPTED_EXTENSIONS */ -static int ssl_tls13_prepare_encrypted_extensions( mbedtls_ssl_context *ssl ) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_ssl_key_set traffic_keys; - mbedtls_ssl_transform *transform_handshake = NULL; - - /* Compute handshake secret */ - ret = mbedtls_ssl_tls13_key_schedule_stage_handshake( ssl ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( - 1, "mbedtls_ssl_tls13_key_schedule_stage_handshake", ret ); - return( ret ); - } - - /* Derive handshake 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 ); - return( ret ); - } - - transform_handshake = mbedtls_calloc( 1, sizeof( mbedtls_ssl_transform ) ); - if( transform_handshake == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - /* Setup transform from handshake key material */ - 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 ); - mbedtls_free( transform_handshake ); - return( ret ); - } - - ssl->handshake->transform_handshake = transform_handshake; - mbedtls_ssl_set_outbound_transform( ssl, ssl->handshake->transform_handshake ); - MBEDTLS_SSL_DEBUG_MSG( - 3, ( "switching to new transform spec for outbound data" ) ); - - return( 0 ); -} /* * struct { @@ -1150,8 +1123,6 @@ static int ssl_tls13_write_encrypted_extensions( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write encrypted extensions" ) ); - MBEDTLS_SSL_PROC_CHK( ssl_tls13_prepare_encrypted_extensions( ssl ) ); - MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_start_handshake_msg( ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, &buf, &buf_len ) );