From 09d236419e79638eda2aa575a75aaddbf0ef663c Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 22 Jul 2019 17:18:18 +0100 Subject: [PATCH] Share code between In-CliKeyExch and Out-CliKeyExch The postprocessing code for the server-side incoming client key exchange and the client-side outgoing client key exchange both contain the same code-paths for building the premaster secret depending on the chosen ciphersuite (e.g., for ECDHE-PSK, concatenating the ECDHE secret with the chosen PSK). This commit moves this common code to ssl_tls.c, allowing client- and server-side to share it. --- include/mbedtls/ssl_internal.h | 2 + library/ssl_cli.c | 103 +++----------------------------- library/ssl_srv.c | 86 +-------------------------- library/ssl_tls.c | 105 +++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 178 deletions(-) diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index c16a238cc..25ded986b 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -987,6 +987,8 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ); void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl, mbedtls_ssl_ciphersuite_handle_t ciphersuite_info ); +int mbedtls_ssl_build_pms( mbedtls_ssl_context *ssl ); + #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex ); #endif diff --git a/library/ssl_cli.c b/library/ssl_cli.c index ded93a666..56ce907a3 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -3599,107 +3599,20 @@ static int ssl_client_key_exchange_write( mbedtls_ssl_context *ssl, static int ssl_client_key_exchange_postprocess( mbedtls_ssl_context *ssl ) { int ret; -/* size_t i, n; */ - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_DHE_RSA ) + if( ( ret = mbedtls_ssl_build_pms( ssl ) ) != 0 ) { - if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, - ssl->handshake->premaster, - MBEDTLS_PREMASTER_SIZE, - &ssl->handshake->pmslen, - mbedtls_ssl_conf_get_frng( ssl->conf ), - ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); - return( ret ); - } + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_build_pms", ret ); - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) - { #if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled ) + if( ssl->handshake->ecrs_enabled && + ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) + { + ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; ssl->handshake->ecrs_state = ssl_ecrs_cke_ecdh_calc_secret; + } #endif /* MBEDTLS_SSL__ECP_RESTARTABLE */ - - if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, - &ssl->handshake->pmslen, - ssl->handshake->premaster, - MBEDTLS_MPI_MAX_SIZE, - mbedtls_ssl_conf_get_frng( ssl->conf ), - ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - if( mbedtls_ssl_ciphersuite_uses_psk( ciphersuite_info ) ) - { - if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == - MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx, - ssl->handshake->premaster, 32, &ssl->handshake->pmslen, - mbedtls_ssl_conf_get_frng( ssl->conf ), - ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) - { - ((void) ret); - /* The premaster secret has already been by - * ssl_rsa_generate_partial_pms(). Only the - * PMS length needs to be set. */ - ssl->handshake->pmslen = 48; - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + return( ret ); } ssl->state = MBEDTLS_SSL_CERTIFICATE_VERIFY; diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 559024458..63760c5e6 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -4305,91 +4305,11 @@ static int ssl_client_key_exchange_parse( mbedtls_ssl_context *ssl, static int ssl_client_key_exchange_postprocess( mbedtls_ssl_context *ssl ) { int ret; - mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = - mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) ); - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_DHE_RSA ) + if( ( ret = mbedtls_ssl_build_pms( ssl ) ) != 0 ) { - if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, - ssl->handshake->premaster, - MBEDTLS_PREMASTER_SIZE, - &ssl->handshake->pmslen, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS ); - } - - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) - == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) - { - if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, - &ssl->handshake->pmslen, - ssl->handshake->premaster, - MBEDTLS_MPI_MAX_SIZE, - mbedtls_ssl_conf_get_frng( ssl->conf ), - ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS ); - } - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Z ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - if( mbedtls_ssl_ciphersuite_uses_psk( ciphersuite_info ) ) - { - if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, - mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx, - ssl->handshake->premaster, 32, &ssl->handshake->pmslen, - mbedtls_ssl_conf_get_frng( ssl->conf ), - ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_build_pms", ret ); + return( ret ); } if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 6187eb01a..e651f29c1 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1653,6 +1653,111 @@ void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SHA512_C */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ +int mbedtls_ssl_build_pms( mbedtls_ssl_context *ssl ) +{ + int ret; + + mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = + mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) + if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) + == MBEDTLS_KEY_EXCHANGE_DHE_RSA ) + { + if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, + ssl->handshake->premaster, + MBEDTLS_PREMASTER_SIZE, + &ssl->handshake->pmslen, + mbedtls_ssl_conf_get_frng( ssl->conf ), + ssl->conf->p_rng ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) + == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || + mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) + == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || + mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) + == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || + mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) + == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) + { + if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, + &ssl->handshake->pmslen, + ssl->handshake->premaster, + MBEDTLS_MPI_MAX_SIZE, + mbedtls_ssl_conf_get_frng( ssl->conf ), + ssl->conf->p_rng ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z ); + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) + if( mbedtls_ssl_ciphersuite_uses_psk( ciphersuite_info ) ) + { + if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, + mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); + return( ret ); + } + } + else +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) == + MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + { + ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx, + ssl->handshake->premaster, 32, &ssl->handshake->pmslen, + mbedtls_ssl_conf_get_frng( ssl->conf ), + ssl->conf->p_rng ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret ); + return( ret ); + } + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) + if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) + == MBEDTLS_KEY_EXCHANGE_RSA ) + { + ((void) ret); + /* The premaster secret has already been by + * ssl_rsa_generate_partial_pms(). Only the + * PMS length needs to be set. */ + ssl->handshake->pmslen = 48; + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + return( 0 ); +} + #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex ) {