diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 5d04a115f..45e05447b 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -605,6 +605,8 @@ union mbedtls_ssl_premaster_secret #define MBEDTLS_PREMASTER_SIZE sizeof( union mbedtls_ssl_premaster_secret ) +#define MBEDTLS_TLS1_3_MD_MAX_SIZE MBEDTLS_MD_MAX_SIZE + /* Length in number of bytes of the TLS sequence number */ #define MBEDTLS_SSL_SEQUENCE_NUMBER_LEN 8 @@ -1050,6 +1052,14 @@ typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl ); #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED && !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ +typedef struct +{ + unsigned char client_application_traffic_secret_N[ MBEDTLS_TLS1_3_MD_MAX_SIZE ]; + unsigned char server_application_traffic_secret_N[ MBEDTLS_TLS1_3_MD_MAX_SIZE ]; + unsigned char exporter_master_secret [ MBEDTLS_TLS1_3_MD_MAX_SIZE ]; + unsigned char resumption_master_secret [ MBEDTLS_TLS1_3_MD_MAX_SIZE ]; +} mbedtls_ssl_tls1_3_application_secrets; + #if defined(MBEDTLS_SSL_DTLS_SRTP) #define MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH 255 @@ -1140,6 +1150,10 @@ struct mbedtls_ssl_session #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) int MBEDTLS_PRIVATE(encrypt_then_mac); /*!< flag for EtM activation */ #endif + +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + mbedtls_ssl_tls1_3_application_secrets MBEDTLS_PRIVATE(app_secrets); +#endif }; /* diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 23d5970d9..362117fd9 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -307,8 +307,6 @@ + ( MBEDTLS_SSL_CID_OUT_LEN_MAX ) ) #endif -#define MBEDTLS_TLS1_3_MD_MAX_SIZE MBEDTLS_MD_MAX_SIZE - #define MBEDTLS_CLIENT_HELLO_RANDOM_LEN 32 #define MBEDTLS_SERVER_HELLO_RANDOM_LEN 32 @@ -522,14 +520,6 @@ typedef struct unsigned char server_handshake_traffic_secret[ MBEDTLS_TLS1_3_MD_MAX_SIZE ]; } mbedtls_ssl_tls1_3_handshake_secrets; -typedef struct -{ - unsigned char client_application_traffic_secret_N[ MBEDTLS_TLS1_3_MD_MAX_SIZE ]; - unsigned char server_application_traffic_secret_N[ MBEDTLS_TLS1_3_MD_MAX_SIZE ]; - unsigned char exporter_master_secret [ MBEDTLS_TLS1_3_MD_MAX_SIZE ]; - unsigned char resumption_master_secret [ MBEDTLS_TLS1_3_MD_MAX_SIZE ]; -} mbedtls_ssl_tls1_3_application_secrets; - /* * This structure contains the parameters only needed during handshake. */ @@ -719,6 +709,38 @@ struct mbedtls_ssl_handshake_params * but can be overwritten by the HRR. */ #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + /* + * State-local variables used during the processing + * of a specific handshake state. + */ + union + { + /* Outgoing Finished message */ + struct + { + uint8_t preparation_done; + + /* Buffer holding digest of the handshake up to + * but excluding the outgoing finished message. */ + unsigned char digest[MBEDTLS_TLS1_3_MD_MAX_SIZE]; + size_t digest_len; + } finished_out; + + /* Incoming Finished message */ + struct + { + uint8_t preparation_done; + + /* Buffer holding digest of the handshake up to but + * excluding the peer's incoming finished message. */ + unsigned char digest[MBEDTLS_TLS1_3_MD_MAX_SIZE]; + size_t digest_len; + } finished_in; + + } state_local; + + /* End of state-local variables. */ + mbedtls_ssl_ciphersuite_t const *ciphersuite_info; size_t pmslen; /*!< premaster length */ @@ -1162,6 +1184,8 @@ static inline int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl ) int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ); int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_tls13_process_finished_message( mbedtls_ssl_context *ssl ); + int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ); int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ); diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index e36e28d9d..6deab2a8c 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -1605,27 +1605,12 @@ static int ssl_tls1_3_process_certificate_verify( mbedtls_ssl_context *ssl ) */ static int ssl_tls1_3_process_server_finished( mbedtls_ssl_context *ssl ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) ); - mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE ); - return( 0 ); -} + int ret; -/* - * Handler for MBEDTLS_SSL_CLIENT_CERTIFICATE - */ -static int ssl_tls1_3_write_client_certificate( mbedtls_ssl_context *ssl ) -{ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) ); - mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY ); - return( 0 ); -} + ret = mbedtls_ssl_tls13_process_finished_message( ssl ); + if( ret != 0 ) + return( ret ); -/* - * Handler for MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY - */ -static int ssl_tls1_3_write_client_certificate_verify( mbedtls_ssl_context *ssl ) -{ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) ); mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_FINISHED ); return( 0 ); } @@ -1703,14 +1688,6 @@ int mbedtls_ssl_tls13_handshake_client_step( mbedtls_ssl_context *ssl ) ret = ssl_tls1_3_process_server_finished( ssl ); break; - case MBEDTLS_SSL_CLIENT_CERTIFICATE: - ret = ssl_tls1_3_write_client_certificate( ssl ); - break; - - case MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY: - ret = ssl_tls1_3_write_client_certificate_verify( ssl ); - break; - case MBEDTLS_SSL_CLIENT_FINISHED: ret = ssl_tls1_3_write_client_finished( ssl ); break; diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index 75b11c93a..b2a70f3cd 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -845,6 +845,176 @@ cleanup: return( ret ); } +/* + * + * STATE HANDLING: Incoming Finished message. + */ +/* + * Implementation + */ + +static int ssl_tls13_preprocess_finished_message( mbedtls_ssl_context *ssl ) +{ + int ret; + + ret = mbedtls_ssl_tls13_calculate_verify_data( ssl, + ssl->handshake->state_local.finished_in.digest, + sizeof( ssl->handshake->state_local.finished_in.digest ), + &ssl->handshake->state_local.finished_in.digest_len, + ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ? + MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_calculate_verify_data", ret ); + return( ret ); + } + + return( 0 ); +} + +static int ssl_tls13_parse_finished_message( mbedtls_ssl_context *ssl, + const unsigned char *buf, + const unsigned char *end ) +{ + /* + * struct { + * opaque verify_data[Hash.length]; + * } Finished; + */ + const unsigned char *expected_verify_data = + ssl->handshake->state_local.finished_in.digest; + size_t expected_verify_data_len = + ssl->handshake->state_local.finished_in.digest_len; + /* Structural validation */ + if( (size_t)( end - buf ) != expected_verify_data_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); + + MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, + MBEDTLS_ERR_SSL_DECODE_ERROR ); + return( MBEDTLS_ERR_SSL_DECODE_ERROR ); + } + + MBEDTLS_SSL_DEBUG_BUF( 4, "verify_data (self-computed):", + expected_verify_data, + expected_verify_data_len ); + MBEDTLS_SSL_DEBUG_BUF( 4, "verify_data (received message):", buf, + expected_verify_data_len ); + + /* Semantic validation */ + if( mbedtls_ssl_safer_memcmp( buf, + expected_verify_data, + expected_verify_data_len ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); + + MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR, + MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE ); + return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE ); + } + return( 0 ); +} + +#if defined(MBEDTLS_SSL_CLI_C) +static int ssl_tls13_postprocess_server_finished_message( mbedtls_ssl_context *ssl ) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_ssl_key_set traffic_keys; + mbedtls_ssl_transform *transform_application = NULL; + + ret = mbedtls_ssl_tls13_key_schedule_stage_application( ssl ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, + "mbedtls_ssl_tls13_key_schedule_stage_application", ret ); + goto cleanup; + } + + ret = mbedtls_ssl_tls13_generate_application_keys( ssl, &traffic_keys ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, + "mbedtls_ssl_tls13_generate_application_keys", ret ); + goto cleanup; + } + + transform_application = + mbedtls_calloc( 1, sizeof( mbedtls_ssl_transform ) ); + if( transform_application == NULL ) + { + ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; + goto cleanup; + } + + ret = mbedtls_ssl_tls13_populate_transform( + transform_application, + 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; + } + + ssl->transform_application = transform_application; + +cleanup: + + mbedtls_platform_zeroize( &traffic_keys, sizeof( traffic_keys ) ); + if( ret != 0 ) + { + mbedtls_free( transform_application ); + MBEDTLS_SSL_PEND_FATAL_ALERT( + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE, + MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE ); + } + return( ret ); +} +#endif /* MBEDTLS_SSL_CLI_C */ + +static int ssl_tls13_postprocess_finished_message( mbedtls_ssl_context* ssl ) +{ + +#if defined(MBEDTLS_SSL_CLI_C) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) + { + return( ssl_tls13_postprocess_server_finished_message( ssl ) ); + } +#else + ((void) ssl); +#endif /* MBEDTLS_SSL_CLI_C */ + + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); +} + +int mbedtls_ssl_tls13_process_finished_message( mbedtls_ssl_context *ssl ) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char *buf; + size_t buflen; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse finished message" ) ); + + /* Preprocessing step: Compute handshake digest */ + MBEDTLS_SSL_PROC_CHK( ssl_tls13_preprocess_finished_message( ssl ) ); + + MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_tls1_3_fetch_handshake_msg( ssl, + MBEDTLS_SSL_HS_FINISHED, + &buf, &buflen ) ); + MBEDTLS_SSL_PROC_CHK( ssl_tls13_parse_finished_message( ssl, buf, buf + buflen ) ); + mbedtls_ssl_tls1_3_add_hs_msg_to_checksum( + ssl, MBEDTLS_SSL_HS_FINISHED, buf, buflen ); + MBEDTLS_SSL_PROC_CHK( ssl_tls13_postprocess_finished_message( ssl ) ); + +cleanup: + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse finished message" ) ); + return( ret ); +} + + #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ #endif /* MBEDTLS_SSL_TLS_C */ diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c index 96f531079..3ca28d56e 100644 --- a/library/ssl_tls13_keys.c +++ b/library/ssl_tls13_keys.c @@ -564,6 +564,35 @@ int mbedtls_ssl_tls1_3_derive_resumption_master_secret( return( 0 ); } +int mbedtls_ssl_tls13_key_schedule_stage_application( mbedtls_ssl_context *ssl ) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_ssl_handshake_params *handshake = ssl->handshake; + mbedtls_md_type_t const md_type = handshake->ciphersuite_info->mac; +#if defined(MBEDTLS_DEBUG_C) + mbedtls_md_info_t const * const md_info = mbedtls_md_info_from_type( md_type ); + size_t const md_size = mbedtls_md_get_size( md_info ); +#endif /* MBEDTLS_DEBUG_C */ + + /* + * Compute MasterSecret + */ + ret = mbedtls_ssl_tls1_3_evolve_secret( md_type, + handshake->tls1_3_master_secrets.handshake, + NULL, 0, + handshake->tls1_3_master_secrets.app ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls1_3_evolve_secret", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_BUF( 4, "Master secret", + handshake->tls1_3_master_secrets.app, md_size ); + + return( 0 ); +} + static int ssl_tls1_3_calc_finished_core( mbedtls_md_type_t md_type, unsigned char const *base_key, unsigned char const *transcript, @@ -614,6 +643,57 @@ exit: return( ret ); } +int mbedtls_ssl_tls13_calculate_verify_data( mbedtls_ssl_context* ssl, + unsigned char* dst, + size_t dst_len, + size_t *actual_len, + int from ) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE]; + size_t transcript_len; + + unsigned char const *base_key = NULL; + + mbedtls_md_type_t const md_type = ssl->handshake->ciphersuite_info->mac; + const mbedtls_md_info_t* const md = mbedtls_md_info_from_type( md_type ); + size_t const md_size = mbedtls_md_get_size( md ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_tls13_calculate_verify_data" ) ); + + if( dst_len < md_size ) + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + + ret = mbedtls_ssl_get_handshake_transcript( ssl, md_type, + transcript, sizeof( transcript ), + &transcript_len ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_get_handshake_transcript", ret ); + goto exit; + } + MBEDTLS_SSL_DEBUG_BUF( 4, "handshake hash", transcript, transcript_len ); + + if( from == MBEDTLS_SSL_IS_CLIENT ) + base_key = ssl->handshake->tls13_hs_secrets.client_handshake_traffic_secret; + else + base_key = ssl->handshake->tls13_hs_secrets.server_handshake_traffic_secret; + + ret = ssl_tls1_3_calc_finished_core( md_type, base_key, transcript, dst ); + if( ret != 0 ) + goto exit; + *actual_len = md_size; + + MBEDTLS_SSL_DEBUG_BUF( 3, "verify_data for finished message", dst, md_size ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_tls13_calculate_verify_data" ) ); + +exit: + + mbedtls_platform_zeroize( transcript, sizeof( transcript ) ); + return( ret ); +} + int mbedtls_ssl_tls1_3_create_psk_binder( mbedtls_ssl_context *ssl, const mbedtls_md_type_t md_type, unsigned char const *psk, size_t psk_len, @@ -1028,4 +1108,125 @@ int mbedtls_ssl_tls13_key_schedule_stage_handshake( mbedtls_ssl_context *ssl ) return( 0 ); } +/* Generate application traffic keys since any records following a 1-RTT Finished message + * MUST be encrypted under the application traffic key. + */ +int mbedtls_ssl_tls13_generate_application_keys( + mbedtls_ssl_context *ssl, + mbedtls_ssl_key_set *traffic_keys ) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_ssl_handshake_params *handshake = ssl->handshake; + + /* Address at which to store the application secrets */ + mbedtls_ssl_tls1_3_application_secrets * const app_secrets = + &ssl->session_negotiate->app_secrets; + + /* Holding the transcript up to and including the ServerFinished */ + unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE]; + size_t transcript_len; + + /* Variables relating to the hash for the chosen ciphersuite. */ + mbedtls_md_type_t md_type; + mbedtls_md_info_t const *md_info; + size_t md_size; + + /* Variables relating to the cipher for the chosen ciphersuite. */ + mbedtls_cipher_info_t const *cipher_info; + size_t keylen, ivlen; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive application traffic keys" ) ); + + /* Extract basic information about hash and ciphersuite */ + + cipher_info = mbedtls_cipher_info_from_type( + handshake->ciphersuite_info->cipher ); + keylen = cipher_info->key_bitlen / 8; + ivlen = cipher_info->iv_size; + + md_type = handshake->ciphersuite_info->mac; + md_info = mbedtls_md_info_from_type( md_type ); + md_size = mbedtls_md_get_size( md_info ); + + /* Compute current handshake transcript. It's the caller's responsiblity + * to call this at the right time, that is, after the ServerFinished. */ + + ret = mbedtls_ssl_get_handshake_transcript( ssl, md_type, + transcript, sizeof( transcript ), + &transcript_len ); + if( ret != 0 ) + goto cleanup; + + /* Compute application secrets from master secret and transcript hash. */ + + ret = mbedtls_ssl_tls1_3_derive_application_secrets( md_type, + handshake->tls1_3_master_secrets.app, + transcript, transcript_len, + app_secrets ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, + "mbedtls_ssl_tls1_3_derive_application_secrets", ret ); + goto cleanup; + } + + /* Derive first epoch of IV + Key for application traffic. */ + + ret = mbedtls_ssl_tls1_3_make_traffic_keys( md_type, + app_secrets->client_application_traffic_secret_N, + app_secrets->server_application_traffic_secret_N, + md_size, keylen, ivlen, traffic_keys ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls1_3_make_traffic_keys", ret ); + goto cleanup; + } + + MBEDTLS_SSL_DEBUG_BUF( 4, "Client application traffic secret", + app_secrets->client_application_traffic_secret_N, + md_size ); + + MBEDTLS_SSL_DEBUG_BUF( 4, "Server application traffic secret", + app_secrets->server_application_traffic_secret_N, + md_size ); + + /* + * Export client/server application traffic secret 0 + */ + if( ssl->f_export_keys != NULL ) + { + ssl->f_export_keys( ssl->p_export_keys, + MBEDTLS_SSL_KEY_EXPORT_TLS13_CLIENT_APPLICATION_TRAFFIC_SECRET, + app_secrets->client_application_traffic_secret_N, md_size, + handshake->randbytes + 32, + handshake->randbytes, + MBEDTLS_SSL_TLS_PRF_NONE /* TODO: this should be replaced by + a new constant for TLS 1.3! */ ); + + ssl->f_export_keys( ssl->p_export_keys, + MBEDTLS_SSL_KEY_EXPORT_TLS13_SERVER_APPLICATION_TRAFFIC_SECRET, + app_secrets->server_application_traffic_secret_N, md_size, + handshake->randbytes + 32, + handshake->randbytes, + MBEDTLS_SSL_TLS_PRF_NONE /* TODO: this should be replaced by + a new constant for TLS 1.3! */ ); + } + + MBEDTLS_SSL_DEBUG_BUF( 4, "client application_write_key:", + traffic_keys->client_write_key, keylen ); + MBEDTLS_SSL_DEBUG_BUF( 4, "server application write key", + traffic_keys->server_write_key, keylen ); + MBEDTLS_SSL_DEBUG_BUF( 4, "client application write IV", + traffic_keys->client_write_iv, ivlen ); + MBEDTLS_SSL_DEBUG_BUF( 4, "server application write IV", + traffic_keys->server_write_iv, ivlen ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= derive application traffic keys" ) ); + + cleanup: + + mbedtls_platform_zeroize( transcript, sizeof( transcript ) ); + return( ret ); +} + #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ diff --git a/library/ssl_tls13_keys.h b/library/ssl_tls13_keys.h index 165b58a2d..d598448b5 100644 --- a/library/ssl_tls13_keys.h +++ b/library/ssl_tls13_keys.h @@ -570,4 +570,65 @@ int mbedtls_ssl_tls13_key_schedule_stage_handshake( mbedtls_ssl_context *ssl ); int mbedtls_ssl_tls13_generate_handshake_keys( mbedtls_ssl_context *ssl, mbedtls_ssl_key_set *traffic_keys ); +/** + * \brief Transition into application stage of TLS 1.3 key schedule. + * + * The TLS 1.3 key schedule can be viewed as a simple state machine + * with states Initial -> Early -> Handshake -> Application, and + * this function represents the Handshake -> Application transition. + * + * In the handshake stage, mbedtls_ssl_tls13_generate_application_keys() + * can be used to derive the handshake traffic keys. + * + * \param ssl The SSL context to operate on. This must be in key schedule + * stage \c Handshake. + * + * \returns \c 0 on success. + * \returns A negative error code on failure. + */ +int mbedtls_ssl_tls13_key_schedule_stage_application( mbedtls_ssl_context *ssl ); + +/** + * \brief Compute TLS 1.3 application traffic keys. + * + * \param ssl The SSL context to operate on. This must be in + * key schedule stage \c Application, see + * mbedtls_ssl_tls13_key_schedule_stage_application(). + * \param traffic_keys The address at which to store the application traffic key + * keys. This must be writable but may be uninitialized. + * + * \returns \c 0 on success. + * \returns A negative error code on failure. + */ +int mbedtls_ssl_tls13_generate_application_keys( + mbedtls_ssl_context* ssl, mbedtls_ssl_key_set *traffic_keys ); + +/** + * \brief Calculate the verify_data value for the client or server TLS 1.3 + * Finished message. + * + * \param ssl The SSL context to operate on. This must be in + * key schedule stage \c Handshake, see + * mbedtls_ssl_tls13_key_schedule_stage_application(). + * \param dst The address at which to write the verify_data value. + * \param dst_len The size of \p dst in bytes. + * \param actual_len The address at which to store the amount of data + * actually written to \p dst upon success. + * \param which The message to calculate the `verify_data` for: + * - #MBEDTLS_SSL_IS_CLIENT for the Client's Finished message + * - #MBEDTLS_SSL_IS_SERVER for the Server's Finished message + * + * \note Both client and server call this function twice, once to + * generate their own Finished message, and once to verify the + * peer's Finished message. + + * \returns \c 0 on success. + * \returns A negative error code on failure. + */ +int mbedtls_ssl_tls13_calculate_verify_data( mbedtls_ssl_context *ssl, + unsigned char *dst, + size_t dst_len, + size_t *actual_len, + int which ); + #endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */ diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 0e78356bc..43759c59e 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -8822,8 +8822,6 @@ run_test "TLS1.3: Test client hello msg work - openssl" \ -c "tls1_3 client state: 3" \ -c "tls1_3 client state: 9" \ -c "tls1_3 client state: 13" \ - -c "tls1_3 client state: 7" \ - -c "tls1_3 client state: 20" \ -c "tls1_3 client state: 11" \ -c "tls1_3 client state: 14" \ -c "tls1_3 client state: 15" \ @@ -8835,7 +8833,8 @@ run_test "TLS1.3: Test client hello msg work - openssl" \ -c "Certificate verification flags clear" \ -c "=> parse certificate verify" \ -c "<= parse certificate verify" \ - -c "mbedtls_ssl_tls13_process_certificate_verify() returned 0" + -c "mbedtls_ssl_tls13_process_certificate_verify() returned 0" \ + -c "<= parse finished message" requires_gnutls_tls1_3 requires_gnutls_next_no_ticket @@ -8855,8 +8854,6 @@ run_test "TLS1.3: Test client hello msg work - gnutls" \ -c "tls1_3 client state: 3" \ -c "tls1_3 client state: 9" \ -c "tls1_3 client state: 13" \ - -c "tls1_3 client state: 7" \ - -c "tls1_3 client state: 20" \ -c "tls1_3 client state: 11" \ -c "tls1_3 client state: 14" \ -c "tls1_3 client state: 15" \ @@ -8868,7 +8865,9 @@ run_test "TLS1.3: Test client hello msg work - gnutls" \ -c "Certificate verification flags clear" \ -c "=> parse certificate verify" \ -c "<= parse certificate verify" \ - -c "mbedtls_ssl_tls13_process_certificate_verify() returned 0" + -c "mbedtls_ssl_tls13_process_certificate_verify() returned 0" \ + -c "<= parse finished message" + # Test heap memory usage after handshake requires_config_enabled MBEDTLS_MEMORY_DEBUG