From ca7d5065562b90210374fb2cf9c08c400879d8e1 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 31 May 2022 14:43:23 +0200 Subject: [PATCH 01/69] Use PSA PAKE API when MBEDTLS_USE_PSA_CRYPTO is selected Signed-off-by: Neil Armstrong Signed-off-by: Valerio Setti --- library/ssl_misc.h | 9 +- library/ssl_tls.c | 131 ++++++++++++++++++++++++ library/ssl_tls12_client.c | 195 +++++++++++++++++++++++++++++++++++- library/ssl_tls12_server.c | 197 ++++++++++++++++++++++++++++++++++++- 4 files changed, 527 insertions(+), 5 deletions(-) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 41bb9c514..8b9624350 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -50,7 +50,8 @@ #include "mbedtls/sha512.h" #endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ + !defined(MBEDTLS_USE_PSA_CRYPTO) #include "mbedtls/ecjpake.h" #endif @@ -663,7 +664,13 @@ struct mbedtls_ssl_handshake_params #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#if defined(MBEDTLS_USE_PSA_CRYPTO) + psa_pake_operation_t psa_pake_ctx; /*!< EC J-PAKE key exchange */ + mbedtls_svc_key_id_t psa_pake_password; + uint8_t psa_pake_ctx_is_ok; +#else mbedtls_ecjpake_context ecjpake_ctx; /*!< EC J-PAKE key exchange */ +#endif /* MBEDTLS_USE_PSA_CRYPTO */ #if defined(MBEDTLS_SSL_CLI_C) unsigned char *ecjpake_cache; /*!< Cache for ClientHello ext */ size_t ecjpake_cache_len; /*!< Length of cached data */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 5200d9044..ebada7a39 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -668,7 +668,12 @@ static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake ) mbedtls_ecdh_init( &handshake->ecdh_ctx ); #endif #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#if defined(MBEDTLS_USE_PSA_CRYPTO) + handshake->psa_pake_ctx = psa_pake_operation_init(); + handshake->psa_pake_password = MBEDTLS_SVC_KEY_ID_INIT; +#else mbedtls_ecjpake_init( &handshake->ecjpake_ctx ); +#endif /* MBEDTLS_USE_PSA_CRYPTO */ #if defined(MBEDTLS_SSL_CLI_C) handshake->ecjpake_cache = NULL; handshake->ecjpake_cache_len = 0; @@ -1615,11 +1620,75 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, const unsigned char *pw, size_t pw_len ) { +#if defined(MBEDTLS_USE_PSA_CRYPTO) + psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_pake_role_t psa_role; + psa_status_t status; +#else mbedtls_ecjpake_role role; +#endif /* MBEDTLS_USE_PSA_CRYPTO */ if( ssl->handshake == NULL || ssl->conf == NULL ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) + psa_role = PSA_PAKE_ROLE_SERVER; + else + psa_role = PSA_PAKE_ROLE_CLIENT; + + + if( pw_len > 0 ) + { + psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE ); + psa_set_key_algorithm( &attributes, PSA_ALG_JPAKE ); + psa_set_key_type( &attributes, PSA_KEY_TYPE_PASSWORD ); + + status = psa_import_key( &attributes, pw, pw_len, + &ssl->handshake->psa_pake_password ); + if( status != PSA_SUCCESS ) + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + } + + psa_pake_cs_set_algorithm( &cipher_suite, PSA_ALG_JPAKE ); + psa_pake_cs_set_primitive( &cipher_suite, + PSA_PAKE_PRIMITIVE( PSA_PAKE_PRIMITIVE_TYPE_ECC, + PSA_ECC_FAMILY_SECP_R1, + 256) ); + psa_pake_cs_set_hash( &cipher_suite, PSA_ALG_SHA_256 ); + + status = psa_pake_setup( &ssl->handshake->psa_pake_ctx, &cipher_suite ); + if( status != PSA_SUCCESS ) + { + psa_destroy_key( ssl->handshake->psa_pake_password ); + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + } + + status = psa_pake_set_role( &ssl->handshake->psa_pake_ctx, psa_role ); + if( status != PSA_SUCCESS ) + { + psa_destroy_key( ssl->handshake->psa_pake_password ); + psa_pake_abort( &ssl->handshake->psa_pake_ctx ); + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + } + + if( pw_len > 0 ) + { + psa_pake_set_password_key( &ssl->handshake->psa_pake_ctx, + ssl->handshake->psa_pake_password ); + if( status != PSA_SUCCESS ) + { + psa_destroy_key( ssl->handshake->psa_pake_password ); + psa_pake_abort( &ssl->handshake->psa_pake_ctx ); + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + } + } + + ssl->handshake->psa_pake_ctx_is_ok = 1; + + return( 0 ); +#else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) role = MBEDTLS_ECJPAKE_SERVER; else @@ -1630,6 +1699,7 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, pw, pw_len ) ); +#endif /* MBEDTLS_USE_PSA_CRYPTO */ } #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ @@ -3665,7 +3735,13 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ) mbedtls_ecdh_free( &handshake->ecdh_ctx ); #endif #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#if defined(MBEDTLS_USE_PSA_CRYPTO) + psa_pake_abort( &handshake->psa_pake_ctx ); + psa_destroy_key( handshake->psa_pake_password ); + handshake->psa_pake_password = MBEDTLS_SVC_KEY_ID_INIT; +#else mbedtls_ecjpake_free( &handshake->ecjpake_ctx ); +#endif /* MBEDTLS_USE_PSA_CRYPTO */ #if defined(MBEDTLS_SSL_CLI_C) mbedtls_free( handshake->ecjpake_cache ); handshake->ecjpake_cache = NULL; @@ -5879,6 +5955,55 @@ static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake, else #endif { +#if defined(MBEDTLS_USE_PSA_CRYPTO) && \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + if( handshake->ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + { + psa_status_t status; + psa_algorithm_t alg = PSA_ALG_TLS12_ECJPAKE_TO_PMS; + psa_key_derivation_operation_t derivation = + PSA_KEY_DERIVATION_OPERATION_INIT; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "perform PSA-based PMS KDF for ECJPAKE" ) ); + + handshake->pmslen = PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE; + + status = psa_key_derivation_setup( &derivation, alg ); + if( status != PSA_SUCCESS ) + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + + status = psa_key_derivation_set_capacity( &derivation, + PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE ); + if( status != PSA_SUCCESS ) + { + psa_key_derivation_abort( &derivation ); + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + } + + status = psa_pake_get_implicit_key( &handshake->psa_pake_ctx, + &derivation ); + if( status != PSA_SUCCESS ) + { + psa_key_derivation_abort( &derivation ); + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + } + + status = psa_key_derivation_output_bytes( &derivation, + handshake->premaster, + handshake->pmslen ); + if( status != PSA_SUCCESS ) + { + psa_key_derivation_abort( &derivation ); + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + } + + status = psa_key_derivation_abort( &derivation ); + if( status != PSA_SUCCESS ) + { + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + } + } +#endif ret = handshake->tls_prf( handshake->premaster, handshake->pmslen, lbl, seed, seed_len, master, @@ -5917,6 +6042,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) return( ret ); } + /* Compute master secret if needed */ ret = ssl_compute_master( ssl->handshake, ssl->session_negotiate->master, @@ -8620,8 +8746,13 @@ int mbedtls_ssl_validate_ciphersuite( #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_CLI_C) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE && + ssl->handshake->psa_pake_ctx_is_ok != 1 ) +#else if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE && mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) +#endif /* MBEDTLS_USE_PSA_CRYPTO */ { return( -1 ); } diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index 5360b3cb7..3d25e4003 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -130,15 +130,24 @@ static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, const unsigned char *end, size_t *olen ) { +#if defined(MBEDTLS_USE_PSA_CRYPTO) + psa_status_t status; +#else int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; +#endif /* MBEDTLS_USE_PSA_CRYPTO */ unsigned char *p = buf; size_t kkpp_len; *olen = 0; /* Skip costly extension if we can't use EC J-PAKE anyway */ +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if( ssl->handshake->psa_pake_ctx_is_ok != 1 ) + return( 0 ); +#else if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) return( 0 ); +#endif /* MBEDTLS_USE_PSA_CRYPTO */ MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding ecjpake_kkpp extension" ) ); @@ -158,6 +167,43 @@ static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, { MBEDTLS_SSL_DEBUG_MSG( 3, ( "generating new ecjpake parameters" ) ); +#if defined(MBEDTLS_USE_PSA_CRYPTO) + size_t output_offset = 0; + size_t output_len; + + /* Repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice */ + for( unsigned int x = 1 ; x <= 2 ; ++x ) + { + for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; + step <= PSA_PAKE_STEP_ZK_PROOF ; + ++step ) + { + /* For each step, prepend 1 byte with the length of the data */ + if (step != PSA_PAKE_STEP_ZK_PROOF) { + *(p + 2 + output_offset) = 65; + } else { + *(p + 2 + output_offset) = 32; + } + output_offset += 1; + + status = psa_pake_output( &ssl->handshake->psa_pake_ctx, + step, p + 2 + output_offset, + end - p - output_offset - 2, + &output_len ); + if( status != PSA_SUCCESS ) + { + psa_destroy_key( ssl->handshake->psa_pake_password ); + psa_pake_abort( &ssl->handshake->psa_pake_ctx ); + MBEDTLS_SSL_DEBUG_RET( 1 , "psa_pake_output", status ); + return( psa_ssl_status_to_mbedtls( status ) ); + } + + output_offset += output_len; + } + } + + kkpp_len = output_offset; +#else ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx, p + 2, end - p - 2, &kkpp_len, ssl->conf->f_rng, ssl->conf->p_rng ); @@ -167,6 +213,7 @@ static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, "mbedtls_ecjpake_write_round_one", ret ); return( ret ); } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ ssl->handshake->ecjpake_cache = mbedtls_calloc( 1, kkpp_len ); if( ssl->handshake->ecjpake_cache == NULL ) @@ -849,10 +896,11 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl, ssl->handshake->ecdh_ctx.point_format = p[0]; #endif /* !MBEDTLS_USE_PSA_CRYPTO && ( MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ) */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) mbedtls_ecjpake_set_point_format( &ssl->handshake->ecjpake_ctx, p[0] ); -#endif +#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) ); return( 0 ); } @@ -876,6 +924,9 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, size_t len ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; +#if defined(MBEDTLS_USE_PSA_CRYPTO) + psa_status_t status; +#endif /* MBEDTLS_USE_PSA_CRYPTO */ if( ssl->handshake->ciphersuite_info->key_exchange != MBEDTLS_KEY_EXCHANGE_ECJPAKE ) @@ -889,6 +940,52 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, ssl->handshake->ecjpake_cache = NULL; ssl->handshake->ecjpake_cache_len = 0; +#if defined(MBEDTLS_USE_PSA_CRYPTO) + size_t input_offset = 0; + + /* Repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice */ + for( unsigned int x = 1 ; x <= 2 ; ++x ) + { + for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; + step <= PSA_PAKE_STEP_ZK_PROOF ; + ++step ) + { + /* Length is stored at the first byte */ + size_t length = buf[input_offset]; + input_offset += 1; + + if( input_offset + length > len ) + { + ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; + goto psa_pake_error; + } + + status = psa_pake_input( &ssl->handshake->psa_pake_ctx, step, + buf + input_offset, length ); + if( status != PSA_SUCCESS) + { + ret = psa_ssl_status_to_mbedtls( status ); + goto psa_pake_error; + } + + input_offset += length; + } + } + + return( 0 ); + +psa_pake_error: + psa_destroy_key( ssl->handshake->psa_pake_password ); + psa_pake_abort( &ssl->handshake->psa_pake_ctx ); + + MBEDTLS_SSL_DEBUG_RET( 1, "psa_pake_input round one", ret ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + + return( ret ); +#else if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx, buf, len ) ) != 0 ) { @@ -901,6 +998,7 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, } return( 0 ); +#endif /* MBEDTLS_USE_PSA_CRYPTO */ } #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ @@ -2296,6 +2394,61 @@ start_processing: #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { +#if defined(MBEDTLS_USE_PSA_CRYPTO) + psa_status_t status; + size_t len = end - p; + size_t input_offset = 0; + + for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; + step <= PSA_PAKE_STEP_ZK_PROOF ; + ++step ) + { + size_t length; + + if( step == PSA_PAKE_STEP_KEY_SHARE ) + { + /* Length is stored after 3bytes curve */ + length = p[input_offset + 3]; + input_offset += 3 + 1; + } + else + { + /* Length is stored at the first byte */ + length = p[input_offset]; + input_offset += 1; + } + + if( input_offset + length > len ) + { + ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + goto psa_pake_out; + } + + status = psa_pake_input( &ssl->handshake->psa_pake_ctx, step, + p + input_offset, length ); + if( status != PSA_SUCCESS) + { + ret = psa_ssl_status_to_mbedtls( status ); + goto psa_pake_out; + } + + input_offset += length; + } + +psa_pake_out: + if( ret != 0 ) + { + psa_destroy_key( ssl->handshake->psa_pake_password ); + psa_pake_abort( &ssl->handshake->psa_pake_ctx ); + + MBEDTLS_SSL_DEBUG_RET( 1, "psa_pake_input round two", ret ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE ); + } +#else ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx, p, end - p ); if( ret != 0 ) @@ -2307,6 +2460,7 @@ start_processing: MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE ); } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ } else #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ @@ -3235,6 +3389,42 @@ ecdh_calc_secret: { header_len = 4; +#if defined(MBEDTLS_USE_PSA_CRYPTO) + unsigned char *out_p = ssl->out_msg + header_len; + unsigned char *end_p = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN - + header_len; + psa_status_t status; + size_t output_offset = 0; + size_t output_len; + + for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; + step <= PSA_PAKE_STEP_ZK_PROOF ; + ++step ) + { + /* For each step, prepend 1 byte with the length of the data */ + if (step != PSA_PAKE_STEP_ZK_PROOF) { + *(out_p + output_offset) = 65; + } else { + *(out_p + output_offset) = 32; + } + output_offset += 1; + status = psa_pake_output( &ssl->handshake->psa_pake_ctx, + step, out_p + output_offset, + end_p - out_p - output_offset, + &output_len ); + if( status != PSA_SUCCESS ) + { + psa_destroy_key( ssl->handshake->psa_pake_password ); + psa_pake_abort( &ssl->handshake->psa_pake_ctx ); + MBEDTLS_SSL_DEBUG_RET( 1 , "psa_pake_output", status ); + return( psa_ssl_status_to_mbedtls( status ) ); + } + + output_offset += output_len; + } + + content_len = output_offset; +#else ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx, ssl->out_msg + header_len, MBEDTLS_SSL_OUT_CONTENT_LEN - header_len, @@ -3254,6 +3444,7 @@ ecdh_calc_secret: MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret ); return( ret ); } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ } else #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index 71f703c7f..68b4d0988 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -268,10 +268,11 @@ static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl, ssl->handshake->ecdh_ctx.point_format = p[0]; #endif /* !MBEDTLS_USE_PSA_CRYPTO && ( MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ) */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) mbedtls_ecjpake_set_point_format( &ssl->handshake->ecjpake_ctx, p[0] ); -#endif +#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) ); return( 0 ); } @@ -292,13 +293,52 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, size_t len ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; +#if defined(MBEDTLS_USE_PSA_CRYPTO) + psa_status_t status; +#endif /* MBEDTLS_USE_PSA_CRYPTO */ +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if( ssl->handshake->psa_pake_ctx_is_ok != 1 ) +#else if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) +#endif /* MBEDTLS_USE_PSA_CRYPTO */ { MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) ); return( 0 ); } +#if defined(MBEDTLS_USE_PSA_CRYPTO) + size_t input_offset = 0; + + /* Repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice */ + for( unsigned int x = 1 ; x <= 2 ; ++x ) + { + for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; + step <= PSA_PAKE_STEP_ZK_PROOF ; + ++step ) + { + /* Length is stored at the first byte */ + size_t length = buf[input_offset]; + input_offset += 1; + + if( input_offset + length > len ) + { + ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; + goto psa_pake_error; + } + + status = psa_pake_input( &ssl->handshake->psa_pake_ctx, step, + buf + input_offset, length ); + if( status != PSA_SUCCESS) + { + ret = psa_ssl_status_to_mbedtls( status ); + goto psa_pake_error; + } + + input_offset += length; + } + } +#else if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx, buf, len ) ) != 0 ) { @@ -307,11 +347,26 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( ret ); } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ /* Only mark the extension as OK when we're sure it is */ ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK; return( 0 ); + +#if defined(MBEDTLS_USE_PSA_CRYPTO) +psa_pake_error: + psa_destroy_key( ssl->handshake->psa_pake_password ); + psa_pake_abort( &ssl->handshake->psa_pake_ctx ); + + MBEDTLS_SSL_DEBUG_RET( 1, "psa_pake_input round one", ret ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + + return( ret ); +#endif /* MBEDTLS_USE_PSA_CRYPTO */ } #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ @@ -1973,7 +2028,11 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { +#if defined(MBEDTLS_USE_PSA_CRYPTO) + psa_status_t status; +#else int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; +#endif /* MBEDTLS_USE_PSA_CRYPTO */ unsigned char *p = buf; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; size_t kkpp_len; @@ -1996,6 +2055,42 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0 ); p += 2; +#if defined(MBEDTLS_USE_PSA_CRYPTO) + size_t output_offset = 0; + size_t output_len; + + /* Repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice */ + for( unsigned int x = 1 ; x <= 2 ; ++x ) + { + for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; + step <= PSA_PAKE_STEP_ZK_PROOF ; + ++step ) + { + /* For each step, prepend 1 byte with the length of the data */ + if (step != PSA_PAKE_STEP_ZK_PROOF) { + *(p + 2 + output_offset) = 65; + } else { + *(p + 2 + output_offset) = 32; + } + output_offset += 1; + status = psa_pake_output( &ssl->handshake->psa_pake_ctx, + step, p + 2 + output_offset, + end - p - output_offset - 2, + &output_len ); + if( status != PSA_SUCCESS ) + { + psa_destroy_key( ssl->handshake->psa_pake_password ); + psa_pake_abort( &ssl->handshake->psa_pake_ctx ); + MBEDTLS_SSL_DEBUG_RET( 1 , "psa_pake_output", status ); + return; + } + + output_offset += output_len; + } + } + + kkpp_len = output_offset; +#else ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx, p + 2, end - p - 2, &kkpp_len, ssl->conf->f_rng, ssl->conf->p_rng ); @@ -2004,6 +2099,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret ); return; } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ MBEDTLS_PUT_UINT16_BE( kkpp_len, p, 0 ); p += 2; @@ -2807,6 +2903,61 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { +#if defined(MBEDTLS_USE_PSA_CRYPTO) + unsigned char *out_p = ssl->out_msg + ssl->out_msglen; + unsigned char *end_p = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN - + ssl->out_msglen; + psa_status_t status; + size_t output_offset = 0; + size_t output_len; + size_t ec_len; + +#if !defined(MBEDTLS_ECJPAKE_ALT) + psa_pake_operation_t* pake_op = &(ssl->handshake->psa_pake_ctx); + + mbedtls_ecp_tls_write_group( &(pake_op->ctx.ecjpake.grp), + &ec_len, out_p + output_offset, + end_p - out_p); +#else + const mbedtls_ecp_curve_info *curve_info; + + if( ( curve_info = mbedtls_ecp_curve_info_from_grp_id( MBEDTLS_ECP_DP_SECP256R1 ) ) == NULL ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + *out_p = MBEDTLS_ECP_TLS_NAMED_CURVE; + + MBEDTLS_PUT_UINT16_BE( curve_info->tls_id, out_p + 1, 0 ); + ec_len = 3; +#endif //MBEDTLS_PSA_BUILTIN_ALG_JPAKE + output_offset += ec_len; + + for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; + step <= PSA_PAKE_STEP_ZK_PROOF ; + ++step ) + { + if (step != PSA_PAKE_STEP_ZK_PROOF) { + *(out_p + output_offset) = 65; + } else { + *(out_p + output_offset) = 32; + } + output_offset += 1; + status = psa_pake_output( &ssl->handshake->psa_pake_ctx, + step, out_p + output_offset, + end_p - out_p - output_offset, + &output_len ); + if( status != PSA_SUCCESS ) + { + psa_destroy_key( ssl->handshake->psa_pake_password ); + psa_pake_abort( &ssl->handshake->psa_pake_ctx ); + MBEDTLS_SSL_DEBUG_RET( 1 , "psa_pake_output", status ); + return( psa_ssl_status_to_mbedtls( status ) ); + } + + output_offset += output_len; + } + + ssl->out_msglen += output_offset; +#else int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t len = 0; @@ -2822,6 +2973,7 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, } ssl->out_msglen += len; +#endif /* MBEDTLS_USE_PSA_CRYPTO */ } #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ @@ -4039,6 +4191,46 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { +#if defined(MBEDTLS_USE_PSA_CRYPTO) + size_t len = end - p; + psa_status_t status; + size_t input_offset = 0; + + for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; + step <= PSA_PAKE_STEP_ZK_PROOF ; + ++step ) + { + /* Length is stored at the first byte */ + size_t length = p[input_offset]; + input_offset += 1; + + if( input_offset + length > len ) + { + ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; + goto psa_pake_out; + } + + status = psa_pake_input( &ssl->handshake->psa_pake_ctx, step, + p + input_offset, length ); + if( status != PSA_SUCCESS) + { + ret = psa_ssl_status_to_mbedtls( status ); + goto psa_pake_out; + } + + input_offset += length; + } + +psa_pake_out: + if( ret != 0 ) + { + psa_destroy_key( ssl->handshake->psa_pake_password ); + psa_pake_abort( &ssl->handshake->psa_pake_ctx ); + + MBEDTLS_SSL_DEBUG_RET( 1, "psa_pake_input round two", ret ); + return( ret ); + } +#else ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx, p, end - p ); if( ret != 0 ) @@ -4055,6 +4247,7 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret ); return( ret ); } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ } else #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ From e2977b690187ff848b1a0f26db6c35f5620104c8 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 13 Sep 2022 14:30:57 +0200 Subject: [PATCH 02/69] Remove TLS 1.2 exception about EC J-PAKE and PSA Crypto Signed-off-by: Neil Armstrong --- docs/use-psa-crypto.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/use-psa-crypto.md b/docs/use-psa-crypto.md index b22d37f65..11442ed66 100644 --- a/docs/use-psa-crypto.md +++ b/docs/use-psa-crypto.md @@ -86,7 +86,6 @@ is enabled, no change required on the application side. Current exceptions: -- EC J-PAKE (when `MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED` is defined) - finite-field (non-EC) Diffie-Hellman (used in key exchanges: DHE-RSA, DHE-PSK) From 9f0ec53c4c876c02dd75f89c3c0ab0eb7917d560 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 8 Nov 2022 13:03:24 +0100 Subject: [PATCH 03/69] add a test for EC-JPAKE compatibility in TLS1.2 This is to ensure that the MbedTLS based implementation of EC-JPAKE is compatible with the PSA crypto one Signed-off-by: Valerio Setti --- tests/scripts/all.sh | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 9295c9d00..b2af01c38 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -1437,6 +1437,31 @@ component_test_tls1_2_default_cbc_legacy_cbc_etm_cipher_only_use_psa () { tests/ssl-opt.sh -f "TLS 1.2" } +# We're not aware of any other (open source) implementation of EC J-PAKE in TLS +# that we could use for interop testing. However, we now have sort of two +# implementations ourselves: one using PSA, the other not. At least test that +# these two interoperate with each other. +component_test_tls1_2_ecjpake_compatibility() { + msg "build: TLS1.2 server+client w/ EC-JPAKE w/o USE_PSA" + scripts/config.py set MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED + make -C programs ssl/ssl_server2 ssl/ssl_client2 + cp programs/ssl/ssl_server2 s2_no_use_psa + cp programs/ssl/ssl_client2 c2_no_use_psa + + msg "build: TLS1.2 server+client w/ EC-JPAKE w/ USE_PSA" + scripts/config.py set MBEDTLS_USE_PSA_CRYPTO + make clean + make -C programs ssl/ssl_server2 ssl/ssl_client2 + make -C programs test/udp_proxy test/query_compile_time_config + + msg "test: server w/o USE_PSA - client w/ USE_PSA" + P_SRV=../s2_no_use_psa tests/ssl-opt.sh -f ECJPAKE + msg "test: client w/o USE_PSA - server w/ USE_PSA" + P_CLI=../c2_no_use_psa tests/ssl-opt.sh -f ECJPAKE + + rm s2_no_use_psa c2_no_use_psa +} + component_test_psa_external_rng_use_psa_crypto () { msg "build: full + PSA_CRYPTO_EXTERNAL_RNG + USE_PSA_CRYPTO minus CTR_DRBG" scripts/config.py full From 02c25b5f83f6f607007133b1f49931fe7c2630f5 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 15 Nov 2022 14:08:42 +0100 Subject: [PATCH 04/69] tls12: psa_pake: use common code for parsing/writing round one and round two data Share a common parsing code for both server and client for parsing round one and two. Signed-off-by: Valerio Setti --- library/ssl_misc.h | 212 +++++++++++++++++++++++++++++++++++++ library/ssl_tls.c | 22 ++-- library/ssl_tls12_client.c | 179 +++++-------------------------- library/ssl_tls12_server.c | 125 +++++----------------- 4 files changed, 279 insertions(+), 259 deletions(-) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 8b9624350..d4ce35c5a 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2364,6 +2364,218 @@ static inline int psa_ssl_status_to_mbedtls( psa_status_t status ) } #endif /* MBEDTLS_USE_PSA_CRYPTO || MBEDTLS_SSL_PROTO_TLS1_3 */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ + defined(MBEDTLS_USE_PSA_CRYPTO) +/** + * \brief Parse the provided input buffer for getting the first round + * of key exchange. This code is common between server and client + * + * \param pake_ctx [in] the PAKE's operation/context structure + * \param buf [in] input buffer to parse + * \param len [in] length of the input buffer + * + * \return 0 on success or a negative error code in case of failure + */ +static inline int psa_tls12_parse_ecjpake_round_one( + psa_pake_operation_t *pake_ctx, + const unsigned char *buf, + size_t len ) +{ + psa_status_t status; + size_t input_offset = 0; + + /* Repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice */ + for( unsigned int x = 1; x <= 2; ++x ) + { + for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE; + step <= PSA_PAKE_STEP_ZK_PROOF; + ++step ) + { + /* Length is stored at the first byte */ + size_t length = buf[input_offset]; + input_offset += 1; + + if( input_offset + length > len ) + { + return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; + } + + status = psa_pake_input( pake_ctx, step, + buf + input_offset, length ); + if( status != PSA_SUCCESS) + { + return psa_ssl_status_to_mbedtls( status ); + } + + input_offset += length; + } + } + + return( 0 ); +} + +/** + * \brief Parse the provided input buffer for getting the second round + * of key exchange. This code is common between server and client + * + * \param pake_ctx [in] the PAKE's operation/context structure + * \param buf [in] input buffer to parse + * \param len [in] length of the input buffer + * + * \return 0 on success or a negative error code in case of failure + */ +static inline int psa_tls12_parse_ecjpake_round_two( + psa_pake_operation_t *pake_ctx, + const unsigned char *buf, + size_t len, int role ) +{ + psa_status_t status; + size_t input_offset = 0; + + for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; + step <= PSA_PAKE_STEP_ZK_PROOF ; + ++step ) + { + size_t length; + + /* + * On its 2nd round, the server sends 3 extra bytes which identify the + * curve. Therefore we should skip them only on the client side + */ + if( ( step == PSA_PAKE_STEP_KEY_SHARE ) && + ( role == MBEDTLS_SSL_IS_CLIENT ) ) + { + /* Length is stored after the 3 bytes for the curve */ + length = buf[input_offset + 3]; + input_offset += 3 + 1; + } + else + { + /* Length is stored at the first byte */ + length = buf[input_offset]; + input_offset += 1; + } + + if( input_offset + length > len ) + { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + status = psa_pake_input( pake_ctx, step, + buf + input_offset, length ); + if( status != PSA_SUCCESS) + { + return psa_ssl_status_to_mbedtls( status ); + } + + input_offset += length; + } + + return( 0 ); +} + +/** + * \brief Write the first round of key exchange into the provided output + * buffer. This code is common between server and client + * + * \param pake_ctx [in] the PAKE's operation/context structure + * \param buf [out] the output buffer in which data will be written to + * \param len [in] length of the output buffer + * \param olen [out] the length of the data really written on the buffer + * + * \return 0 on success or a negative error code in case of failure + */ +static inline int psa_tls12_write_ecjpake_round_one( + psa_pake_operation_t *pake_ctx, + unsigned char *buf, + size_t len, size_t *olen ) +{ + psa_status_t status; + size_t output_offset = 0; + size_t output_len; + + /* Repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice */ + for( unsigned int x = 1 ; x <= 2 ; ++x ) + { + for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; + step <= PSA_PAKE_STEP_ZK_PROOF ; + ++step ) + { + /* For each step, prepend 1 byte with the length of the data */ + if (step != PSA_PAKE_STEP_ZK_PROOF) { + *(buf + output_offset) = 65; + } else { + *(buf + output_offset) = 32; + } + output_offset += 1; + + status = psa_pake_output( pake_ctx, step, + buf + output_offset, + len - output_offset, + &output_len ); + if( status != PSA_SUCCESS ) + { + return( psa_ssl_status_to_mbedtls( status ) ); + } + + output_offset += output_len; + } + } + + *olen = output_offset; + + return( 0 ); +} + +/** + * \brief Write the second round of key exchange into the provided output + * buffer. This code is common between server and client + * + * \param pake_ctx [in] the PAKE's operation/context structure + * \param buf [out] the output buffer in which data will be written to + * \param len [in] length of the output buffer + * \param olen [out] the length of the data really written on the buffer + * + * \return 0 on success or a negative error code in case of failure + */ +static inline int psa_tls12_write_ecjpake_round_two( + psa_pake_operation_t *pake_ctx, + unsigned char *buf, + size_t len, size_t *olen ) +{ + psa_status_t status; + size_t output_offset = 0; + size_t output_len; + + for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; + step <= PSA_PAKE_STEP_ZK_PROOF ; + ++step ) + { + /* For each step, prepend 1 byte with the length of the data */ + if (step != PSA_PAKE_STEP_ZK_PROOF) { + *(buf + output_offset) = 65; + } else { + *(buf + output_offset) = 32; + } + output_offset += 1; + status = psa_pake_output( pake_ctx, + step, buf + output_offset, + len - output_offset, + &output_len ); + if( status != PSA_SUCCESS ) + { + return( psa_ssl_status_to_mbedtls( status ) ); + } + + output_offset += output_len; + } + + *olen = output_offset; + + return( 0 ); +} +#endif //MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO + /** * \brief TLS record protection modes */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index ebada7a39..8771c595b 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1616,23 +1616,19 @@ void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl, /* * Set EC J-PAKE password for current handshake */ +#if defined(MBEDTLS_USE_PSA_CRYPTO) int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, const unsigned char *pw, size_t pw_len ) { -#if defined(MBEDTLS_USE_PSA_CRYPTO) psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_pake_role_t psa_role; psa_status_t status; -#else - mbedtls_ecjpake_role role; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ if( ssl->handshake == NULL || ssl->conf == NULL ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); -#if defined(MBEDTLS_USE_PSA_CRYPTO) if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) psa_role = PSA_PAKE_ROLE_SERVER; else @@ -1688,7 +1684,17 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, ssl->handshake->psa_pake_ctx_is_ok = 1; return( 0 ); -#else +} +#else /* MBEDTLS_USE_PSA_CRYPTO */ +int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, + const unsigned char *pw, + size_t pw_len ) +{ + mbedtls_ecjpake_role role; + + if( ssl->handshake == NULL || ssl->conf == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) role = MBEDTLS_ECJPAKE_SERVER; else @@ -1699,8 +1705,8 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, pw, pw_len ) ); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED) @@ -3734,6 +3740,7 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ) #if !defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_ECDH_C) mbedtls_ecdh_free( &handshake->ecdh_ctx ); #endif + #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) #if defined(MBEDTLS_USE_PSA_CRYPTO) psa_pake_abort( &handshake->psa_pake_ctx ); @@ -6042,7 +6049,6 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) return( ret ); } - /* Compute master secret if needed */ ret = ssl_compute_master( ssl->handshake, ssl->session_negotiate->master, diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index 3d25e4003..c90ed2e46 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -130,13 +130,9 @@ static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, const unsigned char *end, size_t *olen ) { -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status; -#else int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ unsigned char *p = buf; - size_t kkpp_len; + size_t kkpp_len = 0; *olen = 0; @@ -168,41 +164,15 @@ static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "generating new ecjpake parameters" ) ); #if defined(MBEDTLS_USE_PSA_CRYPTO) - size_t output_offset = 0; - size_t output_len; - - /* Repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice */ - for( unsigned int x = 1 ; x <= 2 ; ++x ) + ret = psa_tls12_write_ecjpake_round_one(&ssl->handshake->psa_pake_ctx, + p + 2, end - p - 2, &kkpp_len ); + if ( ret != 0 ) { - for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; - step <= PSA_PAKE_STEP_ZK_PROOF ; - ++step ) - { - /* For each step, prepend 1 byte with the length of the data */ - if (step != PSA_PAKE_STEP_ZK_PROOF) { - *(p + 2 + output_offset) = 65; - } else { - *(p + 2 + output_offset) = 32; - } - output_offset += 1; - - status = psa_pake_output( &ssl->handshake->psa_pake_ctx, - step, p + 2 + output_offset, - end - p - output_offset - 2, - &output_len ); - if( status != PSA_SUCCESS ) - { - psa_destroy_key( ssl->handshake->psa_pake_password ); - psa_pake_abort( &ssl->handshake->psa_pake_ctx ); - MBEDTLS_SSL_DEBUG_RET( 1 , "psa_pake_output", status ); - return( psa_ssl_status_to_mbedtls( status ) ); - } - - output_offset += output_len; - } + psa_destroy_key( ssl->handshake->psa_pake_password ); + psa_pake_abort( &ssl->handshake->psa_pake_ctx ); + MBEDTLS_SSL_DEBUG_RET( 1 , "psa_pake_output", ret ); + return( ret ); } - - kkpp_len = output_offset; #else ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx, p + 2, end - p - 2, &kkpp_len, @@ -924,9 +894,6 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, size_t len ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ if( ssl->handshake->ciphersuite_info->key_exchange != MBEDTLS_KEY_EXCHANGE_ECJPAKE ) @@ -941,50 +908,21 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, ssl->handshake->ecjpake_cache_len = 0; #if defined(MBEDTLS_USE_PSA_CRYPTO) - size_t input_offset = 0; - - /* Repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice */ - for( unsigned int x = 1 ; x <= 2 ; ++x ) + if( ( ret = psa_tls12_parse_ecjpake_round_one( + &ssl->handshake->psa_pake_ctx, buf, len ) ) != 0 ) { - for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; - step <= PSA_PAKE_STEP_ZK_PROOF ; - ++step ) - { - /* Length is stored at the first byte */ - size_t length = buf[input_offset]; - input_offset += 1; + psa_destroy_key( ssl->handshake->psa_pake_password ); + psa_pake_abort( &ssl->handshake->psa_pake_ctx ); - if( input_offset + length > len ) - { - ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - goto psa_pake_error; - } - - status = psa_pake_input( &ssl->handshake->psa_pake_ctx, step, - buf + input_offset, length ); - if( status != PSA_SUCCESS) - { - ret = psa_ssl_status_to_mbedtls( status ); - goto psa_pake_error; - } - - input_offset += length; - } + MBEDTLS_SSL_DEBUG_RET( 1, "psa_pake_input round one", ret ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + return( ret ); } return( 0 ); - -psa_pake_error: - psa_destroy_key( ssl->handshake->psa_pake_password ); - psa_pake_abort( &ssl->handshake->psa_pake_ctx ); - - MBEDTLS_SSL_DEBUG_RET( 1, "psa_pake_input round one", ret ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - - return( ret ); #else if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx, buf, len ) ) != 0 ) @@ -2395,48 +2333,9 @@ start_processing: if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { #if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status; - size_t len = end - p; - size_t input_offset = 0; - - for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; - step <= PSA_PAKE_STEP_ZK_PROOF ; - ++step ) - { - size_t length; - - if( step == PSA_PAKE_STEP_KEY_SHARE ) - { - /* Length is stored after 3bytes curve */ - length = p[input_offset + 3]; - input_offset += 3 + 1; - } - else - { - /* Length is stored at the first byte */ - length = p[input_offset]; - input_offset += 1; - } - - if( input_offset + length > len ) - { - ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - goto psa_pake_out; - } - - status = psa_pake_input( &ssl->handshake->psa_pake_ctx, step, - p + input_offset, length ); - if( status != PSA_SUCCESS) - { - ret = psa_ssl_status_to_mbedtls( status ); - goto psa_pake_out; - } - - input_offset += length; - } - -psa_pake_out: - if( ret != 0 ) + if( ( ret = psa_tls12_parse_ecjpake_round_two( + &ssl->handshake->psa_pake_ctx, p, end - p, + ssl->conf->endpoint ) ) != 0 ) { psa_destroy_key( ssl->handshake->psa_pake_password ); psa_pake_abort( &ssl->handshake->psa_pake_ctx ); @@ -3393,37 +3292,15 @@ ecdh_calc_secret: unsigned char *out_p = ssl->out_msg + header_len; unsigned char *end_p = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN - header_len; - psa_status_t status; - size_t output_offset = 0; - size_t output_len; - - for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; - step <= PSA_PAKE_STEP_ZK_PROOF ; - ++step ) + ret = psa_tls12_write_ecjpake_round_two( &ssl->handshake->psa_pake_ctx, + out_p, end_p - out_p, &content_len ); + if ( ret != 0 ) { - /* For each step, prepend 1 byte with the length of the data */ - if (step != PSA_PAKE_STEP_ZK_PROOF) { - *(out_p + output_offset) = 65; - } else { - *(out_p + output_offset) = 32; - } - output_offset += 1; - status = psa_pake_output( &ssl->handshake->psa_pake_ctx, - step, out_p + output_offset, - end_p - out_p - output_offset, - &output_len ); - if( status != PSA_SUCCESS ) - { - psa_destroy_key( ssl->handshake->psa_pake_password ); - psa_pake_abort( &ssl->handshake->psa_pake_ctx ); - MBEDTLS_SSL_DEBUG_RET( 1 , "psa_pake_output", status ); - return( psa_ssl_status_to_mbedtls( status ) ); - } - - output_offset += output_len; + psa_destroy_key( ssl->handshake->psa_pake_password ); + psa_pake_abort( &ssl->handshake->psa_pake_ctx ); + MBEDTLS_SSL_DEBUG_RET( 1 , "psa_pake_output", ret ); + return( ret ); } - - content_len = output_offset; #else ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx, ssl->out_msg + header_len, diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index 68b4d0988..806efd21b 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -290,12 +290,9 @@ static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl, MBEDTLS_CHECK_RETURN_CRITICAL static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, const unsigned char *buf, - size_t len ) + size_t len) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ #if defined(MBEDTLS_USE_PSA_CRYPTO) if( ssl->handshake->psa_pake_ctx_is_ok != 1 ) @@ -308,35 +305,19 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, } #if defined(MBEDTLS_USE_PSA_CRYPTO) - size_t input_offset = 0; - - /* Repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice */ - for( unsigned int x = 1 ; x <= 2 ; ++x ) + if ( ( ret = psa_tls12_parse_ecjpake_round_one( + &ssl->handshake->psa_pake_ctx, buf, len ) ) != 0 ) { - for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; - step <= PSA_PAKE_STEP_ZK_PROOF ; - ++step ) - { - /* Length is stored at the first byte */ - size_t length = buf[input_offset]; - input_offset += 1; + psa_destroy_key( ssl->handshake->psa_pake_password ); + psa_pake_abort( &ssl->handshake->psa_pake_ctx ); - if( input_offset + length > len ) - { - ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - goto psa_pake_error; - } + MBEDTLS_SSL_DEBUG_RET( 1, "psa_pake_input round one", ret ); + mbedtls_ssl_send_alert_message( + ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - status = psa_pake_input( &ssl->handshake->psa_pake_ctx, step, - buf + input_offset, length ); - if( status != PSA_SUCCESS) - { - ret = psa_ssl_status_to_mbedtls( status ); - goto psa_pake_error; - } - - input_offset += length; - } + return( ret ); } #else if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx, @@ -353,20 +334,6 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK; return( 0 ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -psa_pake_error: - psa_destroy_key( ssl->handshake->psa_pake_password ); - psa_pake_abort( &ssl->handshake->psa_pake_ctx ); - - MBEDTLS_SSL_DEBUG_RET( 1, "psa_pake_input round one", ret ); - mbedtls_ssl_send_alert_message( - ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - - return( ret ); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ } #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ @@ -2903,13 +2870,13 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; #if defined(MBEDTLS_USE_PSA_CRYPTO) unsigned char *out_p = ssl->out_msg + ssl->out_msglen; unsigned char *end_p = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen; - psa_status_t status; size_t output_offset = 0; - size_t output_len; + size_t output_len = 0; size_t ec_len; #if !defined(MBEDTLS_ECJPAKE_ALT) @@ -2931,34 +2898,20 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, #endif //MBEDTLS_PSA_BUILTIN_ALG_JPAKE output_offset += ec_len; - for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; - step <= PSA_PAKE_STEP_ZK_PROOF ; - ++step ) + ret = psa_tls12_write_ecjpake_round_two( &ssl->handshake->psa_pake_ctx, + out_p + output_offset, + end_p - out_p - output_offset, &output_len ); + if( ret != 0 ) { - if (step != PSA_PAKE_STEP_ZK_PROOF) { - *(out_p + output_offset) = 65; - } else { - *(out_p + output_offset) = 32; - } - output_offset += 1; - status = psa_pake_output( &ssl->handshake->psa_pake_ctx, - step, out_p + output_offset, - end_p - out_p - output_offset, - &output_len ); - if( status != PSA_SUCCESS ) - { - psa_destroy_key( ssl->handshake->psa_pake_password ); - psa_pake_abort( &ssl->handshake->psa_pake_ctx ); - MBEDTLS_SSL_DEBUG_RET( 1 , "psa_pake_output", status ); - return( psa_ssl_status_to_mbedtls( status ) ); - } - - output_offset += output_len; + psa_destroy_key( ssl->handshake->psa_pake_password ); + psa_pake_abort( &ssl->handshake->psa_pake_ctx ); + MBEDTLS_SSL_DEBUG_RET( 1 , "psa_pake_output", ret ); + return( ret ); } + output_offset += output_len; ssl->out_msglen += output_offset; #else - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t len = 0; ret = mbedtls_ecjpake_write_round_two( @@ -4192,37 +4145,9 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { #if defined(MBEDTLS_USE_PSA_CRYPTO) - size_t len = end - p; - psa_status_t status; - size_t input_offset = 0; - - for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; - step <= PSA_PAKE_STEP_ZK_PROOF ; - ++step ) - { - /* Length is stored at the first byte */ - size_t length = p[input_offset]; - input_offset += 1; - - if( input_offset + length > len ) - { - ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - goto psa_pake_out; - } - - status = psa_pake_input( &ssl->handshake->psa_pake_ctx, step, - p + input_offset, length ); - if( status != PSA_SUCCESS) - { - ret = psa_ssl_status_to_mbedtls( status ); - goto psa_pake_out; - } - - input_offset += length; - } - -psa_pake_out: - if( ret != 0 ) + if( ( ret = psa_tls12_parse_ecjpake_round_two( + &ssl->handshake->psa_pake_ctx, p, end - p, + ssl->conf->endpoint ) ) != 0 ) { psa_destroy_key( ssl->handshake->psa_pake_password ); psa_pake_abort( &ssl->handshake->psa_pake_ctx ); From fbbc1f3812cd13ccf86c2e8d090f62ef6a27705a Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 15 Nov 2022 16:39:55 +0100 Subject: [PATCH 05/69] tls12: psa_pake: use proper defines for the output size of each step in ECJPAKE Signed-off-by: Valerio Setti --- library/ssl_misc.h | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index d4ce35c5a..34879a18c 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2366,6 +2366,18 @@ static inline int psa_ssl_status_to_mbedtls( psa_status_t status ) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ defined(MBEDTLS_USE_PSA_CRYPTO) + +/* Currently JPAKE only supports elliptic curve secp256r1 */ +#define MBEDTLS_SSL_ECJPAKE_PSA_PRIMITIVE \ + PSA_PAKE_PRIMITIVE( PSA_PAKE_PRIMITIVE_TYPE_ECC, \ + PSA_ECC_FAMILY_SECP_R1, 256 ) + +/* Expected output data size for each "step" of EC-JPAKE key echange */ +#define MBEDTLS_SSL_ECJPAKE_OUTPUT_SIZE( step ) \ + PSA_PAKE_OUTPUT_SIZE( PSA_ALG_JPAKE, \ + MBEDTLS_SSL_ECJPAKE_PSA_PRIMITIVE, \ + step ) + /** * \brief Parse the provided input buffer for getting the first round * of key exchange. This code is common between server and client @@ -2376,7 +2388,7 @@ static inline int psa_ssl_status_to_mbedtls( psa_status_t status ) * * \return 0 on success or a negative error code in case of failure */ -static inline int psa_tls12_parse_ecjpake_round_one( +static inline int psa_tls12_parse_ecjpake_round_one( psa_pake_operation_t *pake_ctx, const unsigned char *buf, size_t len ) @@ -2502,11 +2514,7 @@ static inline int psa_tls12_write_ecjpake_round_one( ++step ) { /* For each step, prepend 1 byte with the length of the data */ - if (step != PSA_PAKE_STEP_ZK_PROOF) { - *(buf + output_offset) = 65; - } else { - *(buf + output_offset) = 32; - } + *(buf + output_offset) = MBEDTLS_SSL_ECJPAKE_OUTPUT_SIZE( step ); output_offset += 1; status = psa_pake_output( pake_ctx, step, @@ -2552,11 +2560,7 @@ static inline int psa_tls12_write_ecjpake_round_two( ++step ) { /* For each step, prepend 1 byte with the length of the data */ - if (step != PSA_PAKE_STEP_ZK_PROOF) { - *(buf + output_offset) = 65; - } else { - *(buf + output_offset) = 32; - } + *(buf + output_offset) = MBEDTLS_SSL_ECJPAKE_OUTPUT_SIZE( step ); output_offset += 1; status = psa_pake_output( pake_ctx, step, buf + output_offset, From 4a9caaa0c9cae90d5cc4a7e08f92752698cee6cc Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 16 Nov 2022 08:17:09 +0100 Subject: [PATCH 06/69] tls12: psa_pake: check elliptic curve's TLS ID on handshake Signed-off-by: Valerio Setti --- library/ssl_misc.h | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 34879a18c..807e7811d 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2452,22 +2452,27 @@ static inline int psa_tls12_parse_ecjpake_round_two( /* * On its 2nd round, the server sends 3 extra bytes which identify the - * curve. Therefore we should skip them only on the client side + * curve: + * - the 1st one is MBEDTLS_ECP_TLS_NAMED_CURVE + * - the 2nd and 3rd represent curve's TLS ID + * Validate this data before moving forward */ - if( ( step == PSA_PAKE_STEP_KEY_SHARE ) && + if( ( step == PSA_PAKE_STEP_KEY_SHARE ) && ( role == MBEDTLS_SSL_IS_CLIENT ) ) { - /* Length is stored after the 3 bytes for the curve */ - length = buf[input_offset + 3]; - input_offset += 3 + 1; - } - else - { - /* Length is stored at the first byte */ - length = buf[input_offset]; - input_offset += 1; + uint16_t tls_id = MBEDTLS_GET_UINT16_BE( buf, 1 ); + + if( ( *buf != MBEDTLS_ECP_TLS_NAMED_CURVE ) || + ( mbedtls_ecp_curve_info_from_tls_id( tls_id ) == NULL ) ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + input_offset += 3; } + /* Length is stored at the first byte */ + length = buf[input_offset]; + input_offset += 1; + if( input_offset + length > len ) { return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; From 6f1b5741ae239433414b772adb06e8515c1bd353 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 16 Nov 2022 10:00:32 +0100 Subject: [PATCH 07/69] tls12: psa_pake: simplify EC info parsing in server's 2nd round Signed-off-by: Valerio Setti --- library/ssl_tls12_server.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index 806efd21b..38899f952 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -2877,26 +2877,24 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, ssl->out_msglen; size_t output_offset = 0; size_t output_len = 0; - size_t ec_len; - -#if !defined(MBEDTLS_ECJPAKE_ALT) - psa_pake_operation_t* pake_op = &(ssl->handshake->psa_pake_ctx); - - mbedtls_ecp_tls_write_group( &(pake_op->ctx.ecjpake.grp), - &ec_len, out_p + output_offset, - end_p - out_p); -#else const mbedtls_ecp_curve_info *curve_info; - if( ( curve_info = mbedtls_ecp_curve_info_from_grp_id( MBEDTLS_ECP_DP_SECP256R1 ) ) == NULL ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - + /* + * The first 3 bytes are: + * [0] MBEDTLS_ECP_TLS_NAMED_CURVE + * [1, 2] elliptic curve's TLS ID + * + * However since we only support secp256r1 for now, we hardcode its + * TLS ID here + */ + if( ( curve_info = mbedtls_ecp_curve_info_from_grp_id( + MBEDTLS_ECP_DP_SECP256R1 ) ) == NULL ) + { + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); + } *out_p = MBEDTLS_ECP_TLS_NAMED_CURVE; - - MBEDTLS_PUT_UINT16_BE( curve_info->tls_id, out_p + 1, 0 ); - ec_len = 3; -#endif //MBEDTLS_PSA_BUILTIN_ALG_JPAKE - output_offset += ec_len; + MBEDTLS_PUT_UINT16_BE( curve_info->tls_id, out_p, 1 ); + output_offset += sizeof( uint8_t ) + sizeof( uint16_t ); ret = psa_tls12_write_ecjpake_round_two( &ssl->handshake->psa_pake_ctx, out_p + output_offset, From a08b1a40a0ff0a69fa7114280f3b1e31772466ee Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 17 Nov 2022 15:10:02 +0100 Subject: [PATCH 08/69] tls: psa_pake: move move key exchange read/write functions to ssl_tls.c Inlined functions might cause the compiled code to have different sizes depending on the usage and this not acceptable in some cases. Therefore read/write functions used in the initial key exchange are moved to a standard C file. Signed-off-by: Valerio Setti --- library/ssl_misc.h | 159 ++--------------------------------- library/ssl_tls.c | 167 +++++++++++++++++++++++++++++++++++++ library/ssl_tls12_client.c | 8 +- library/ssl_tls12_server.c | 6 +- 4 files changed, 182 insertions(+), 158 deletions(-) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 807e7811d..d022721a7 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2388,43 +2388,10 @@ static inline int psa_ssl_status_to_mbedtls( psa_status_t status ) * * \return 0 on success or a negative error code in case of failure */ -static inline int psa_tls12_parse_ecjpake_round_one( +int mbedtls_psa_ecjpake_read_round_one( psa_pake_operation_t *pake_ctx, const unsigned char *buf, - size_t len ) -{ - psa_status_t status; - size_t input_offset = 0; - - /* Repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice */ - for( unsigned int x = 1; x <= 2; ++x ) - { - for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE; - step <= PSA_PAKE_STEP_ZK_PROOF; - ++step ) - { - /* Length is stored at the first byte */ - size_t length = buf[input_offset]; - input_offset += 1; - - if( input_offset + length > len ) - { - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; - } - - status = psa_pake_input( pake_ctx, step, - buf + input_offset, length ); - if( status != PSA_SUCCESS) - { - return psa_ssl_status_to_mbedtls( status ); - } - - input_offset += length; - } - } - - return( 0 ); -} + size_t len ); /** * \brief Parse the provided input buffer for getting the second round @@ -2436,60 +2403,10 @@ static inline int psa_tls12_parse_ecjpake_round_one( * * \return 0 on success or a negative error code in case of failure */ -static inline int psa_tls12_parse_ecjpake_round_two( +int mbedtls_psa_ecjpake_read_round_two( psa_pake_operation_t *pake_ctx, const unsigned char *buf, - size_t len, int role ) -{ - psa_status_t status; - size_t input_offset = 0; - - for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; - step <= PSA_PAKE_STEP_ZK_PROOF ; - ++step ) - { - size_t length; - - /* - * On its 2nd round, the server sends 3 extra bytes which identify the - * curve: - * - the 1st one is MBEDTLS_ECP_TLS_NAMED_CURVE - * - the 2nd and 3rd represent curve's TLS ID - * Validate this data before moving forward - */ - if( ( step == PSA_PAKE_STEP_KEY_SHARE ) && - ( role == MBEDTLS_SSL_IS_CLIENT ) ) - { - uint16_t tls_id = MBEDTLS_GET_UINT16_BE( buf, 1 ); - - if( ( *buf != MBEDTLS_ECP_TLS_NAMED_CURVE ) || - ( mbedtls_ecp_curve_info_from_tls_id( tls_id ) == NULL ) ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - input_offset += 3; - } - - /* Length is stored at the first byte */ - length = buf[input_offset]; - input_offset += 1; - - if( input_offset + length > len ) - { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - status = psa_pake_input( pake_ctx, step, - buf + input_offset, length ); - if( status != PSA_SUCCESS) - { - return psa_ssl_status_to_mbedtls( status ); - } - - input_offset += length; - } - - return( 0 ); -} + size_t len, int role ); /** * \brief Write the first round of key exchange into the provided output @@ -2502,43 +2419,10 @@ static inline int psa_tls12_parse_ecjpake_round_two( * * \return 0 on success or a negative error code in case of failure */ -static inline int psa_tls12_write_ecjpake_round_one( +int mbedtls_psa_ecjpake_write_round_one( psa_pake_operation_t *pake_ctx, unsigned char *buf, - size_t len, size_t *olen ) -{ - psa_status_t status; - size_t output_offset = 0; - size_t output_len; - - /* Repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice */ - for( unsigned int x = 1 ; x <= 2 ; ++x ) - { - for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; - step <= PSA_PAKE_STEP_ZK_PROOF ; - ++step ) - { - /* For each step, prepend 1 byte with the length of the data */ - *(buf + output_offset) = MBEDTLS_SSL_ECJPAKE_OUTPUT_SIZE( step ); - output_offset += 1; - - status = psa_pake_output( pake_ctx, step, - buf + output_offset, - len - output_offset, - &output_len ); - if( status != PSA_SUCCESS ) - { - return( psa_ssl_status_to_mbedtls( status ) ); - } - - output_offset += output_len; - } - } - - *olen = output_offset; - - return( 0 ); -} + size_t len, size_t *olen ); /** * \brief Write the second round of key exchange into the provided output @@ -2551,38 +2435,11 @@ static inline int psa_tls12_write_ecjpake_round_one( * * \return 0 on success or a negative error code in case of failure */ -static inline int psa_tls12_write_ecjpake_round_two( +int mbedtls_psa_ecjpake_write_round_two( psa_pake_operation_t *pake_ctx, unsigned char *buf, - size_t len, size_t *olen ) -{ - psa_status_t status; - size_t output_offset = 0; - size_t output_len; + size_t len, size_t *olen ); - for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; - step <= PSA_PAKE_STEP_ZK_PROOF ; - ++step ) - { - /* For each step, prepend 1 byte with the length of the data */ - *(buf + output_offset) = MBEDTLS_SSL_ECJPAKE_OUTPUT_SIZE( step ); - output_offset += 1; - status = psa_pake_output( pake_ctx, - step, buf + output_offset, - len - output_offset, - &output_len ); - if( status != PSA_SUCCESS ) - { - return( psa_ssl_status_to_mbedtls( status ) ); - } - - output_offset += output_len; - } - - *olen = output_offset; - - return( 0 ); -} #endif //MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO /** diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 8771c595b..35262cb88 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -8194,6 +8194,173 @@ end: return( ret ); } +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ + defined(MBEDTLS_USE_PSA_CRYPTO) +int mbedtls_psa_ecjpake_read_round_one( + psa_pake_operation_t *pake_ctx, + const unsigned char *buf, + size_t len ) +{ + psa_status_t status; + size_t input_offset = 0; + + /* Repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice */ + for( unsigned int x = 1; x <= 2; ++x ) + { + for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE; + step <= PSA_PAKE_STEP_ZK_PROOF; + ++step ) + { + /* Length is stored at the first byte */ + size_t length = buf[input_offset]; + input_offset += 1; + + if( input_offset + length > len ) + { + return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; + } + + status = psa_pake_input( pake_ctx, step, + buf + input_offset, length ); + if( status != PSA_SUCCESS) + { + return psa_ssl_status_to_mbedtls( status ); + } + + input_offset += length; + } + } + + return( 0 ); +} + +int mbedtls_psa_ecjpake_read_round_two( + psa_pake_operation_t *pake_ctx, + const unsigned char *buf, + size_t len, int role ) +{ + psa_status_t status; + size_t input_offset = 0; + + for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; + step <= PSA_PAKE_STEP_ZK_PROOF ; + ++step ) + { + size_t length; + + /* + * On its 2nd round, the server sends 3 extra bytes which identify the + * curve: + * - the 1st one is MBEDTLS_ECP_TLS_NAMED_CURVE + * - the 2nd and 3rd represent curve's TLS ID + * Validate this data before moving forward + */ + if( ( step == PSA_PAKE_STEP_KEY_SHARE ) && + ( role == MBEDTLS_SSL_IS_CLIENT ) ) + { + uint16_t tls_id = MBEDTLS_GET_UINT16_BE( buf, 1 ); + + if( ( *buf != MBEDTLS_ECP_TLS_NAMED_CURVE ) || + ( mbedtls_ecp_curve_info_from_tls_id( tls_id ) == NULL ) ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + input_offset += 3; + } + + /* Length is stored at the first byte */ + length = buf[input_offset]; + input_offset += 1; + + if( input_offset + length > len ) + { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + status = psa_pake_input( pake_ctx, step, + buf + input_offset, length ); + if( status != PSA_SUCCESS) + { + return psa_ssl_status_to_mbedtls( status ); + } + + input_offset += length; + } + + return( 0 ); +} + +int mbedtls_psa_ecjpake_write_round_one( + psa_pake_operation_t *pake_ctx, + unsigned char *buf, + size_t len, size_t *olen ) +{ + psa_status_t status; + size_t output_offset = 0; + size_t output_len; + + /* Repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice */ + for( unsigned int x = 1 ; x <= 2 ; ++x ) + { + for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; + step <= PSA_PAKE_STEP_ZK_PROOF ; + ++step ) + { + /* For each step, prepend 1 byte with the length of the data */ + *(buf + output_offset) = MBEDTLS_SSL_ECJPAKE_OUTPUT_SIZE( step ); + output_offset += 1; + + status = psa_pake_output( pake_ctx, step, + buf + output_offset, + len - output_offset, + &output_len ); + if( status != PSA_SUCCESS ) + { + return( psa_ssl_status_to_mbedtls( status ) ); + } + + output_offset += output_len; + } + } + + *olen = output_offset; + + return( 0 ); +} + +int mbedtls_psa_ecjpake_write_round_two( + psa_pake_operation_t *pake_ctx, + unsigned char *buf, + size_t len, size_t *olen ) +{ + psa_status_t status; + size_t output_offset = 0; + size_t output_len; + + for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; + step <= PSA_PAKE_STEP_ZK_PROOF ; + ++step ) + { + /* For each step, prepend 1 byte with the length of the data */ + *(buf + output_offset) = MBEDTLS_SSL_ECJPAKE_OUTPUT_SIZE( step ); + output_offset += 1; + status = psa_pake_output( pake_ctx, + step, buf + output_offset, + len - output_offset, + &output_len ); + if( status != PSA_SUCCESS ) + { + return( psa_ssl_status_to_mbedtls( status ) ); + } + + output_offset += output_len; + } + + *olen = output_offset; + + return( 0 ); +} +#endif //MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO + #if defined(MBEDTLS_USE_PSA_CRYPTO) int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl, unsigned char *hash, size_t *hashlen, diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index c90ed2e46..4e986d1df 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -164,7 +164,7 @@ static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "generating new ecjpake parameters" ) ); #if defined(MBEDTLS_USE_PSA_CRYPTO) - ret = psa_tls12_write_ecjpake_round_one(&ssl->handshake->psa_pake_ctx, + ret = mbedtls_psa_ecjpake_write_round_one(&ssl->handshake->psa_pake_ctx, p + 2, end - p - 2, &kkpp_len ); if ( ret != 0 ) { @@ -908,7 +908,7 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, ssl->handshake->ecjpake_cache_len = 0; #if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ( ret = psa_tls12_parse_ecjpake_round_one( + if( ( ret = mbedtls_psa_ecjpake_read_round_one( &ssl->handshake->psa_pake_ctx, buf, len ) ) != 0 ) { psa_destroy_key( ssl->handshake->psa_pake_password ); @@ -2333,7 +2333,7 @@ start_processing: if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { #if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ( ret = psa_tls12_parse_ecjpake_round_two( + if( ( ret = mbedtls_psa_ecjpake_read_round_two( &ssl->handshake->psa_pake_ctx, p, end - p, ssl->conf->endpoint ) ) != 0 ) { @@ -3292,7 +3292,7 @@ ecdh_calc_secret: unsigned char *out_p = ssl->out_msg + header_len; unsigned char *end_p = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN - header_len; - ret = psa_tls12_write_ecjpake_round_two( &ssl->handshake->psa_pake_ctx, + ret = mbedtls_psa_ecjpake_write_round_two( &ssl->handshake->psa_pake_ctx, out_p, end_p - out_p, &content_len ); if ( ret != 0 ) { diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index 38899f952..f5c50ea67 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -305,7 +305,7 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, } #if defined(MBEDTLS_USE_PSA_CRYPTO) - if ( ( ret = psa_tls12_parse_ecjpake_round_one( + if ( ( ret = mbedtls_psa_ecjpake_read_round_one( &ssl->handshake->psa_pake_ctx, buf, len ) ) != 0 ) { psa_destroy_key( ssl->handshake->psa_pake_password ); @@ -2896,7 +2896,7 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, MBEDTLS_PUT_UINT16_BE( curve_info->tls_id, out_p, 1 ); output_offset += sizeof( uint8_t ) + sizeof( uint16_t ); - ret = psa_tls12_write_ecjpake_round_two( &ssl->handshake->psa_pake_ctx, + ret = mbedtls_psa_ecjpake_write_round_two( &ssl->handshake->psa_pake_ctx, out_p + output_offset, end_p - out_p - output_offset, &output_len ); if( ret != 0 ) @@ -4143,7 +4143,7 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { #if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ( ret = psa_tls12_parse_ecjpake_round_two( + if( ( ret = mbedtls_psa_ecjpake_read_round_two( &ssl->handshake->psa_pake_ctx, p, end - p, ssl->conf->endpoint ) ) != 0 ) { From a98836476782db7fc3883b02c25707fe3da2cd3a Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 17 Nov 2022 15:34:59 +0100 Subject: [PATCH 09/69] tls: psa_pake: fix missing new round one parsing function on tls12 server Signed-off-by: Valerio Setti --- library/ssl_tls12_server.c | 43 +++++++------------------------------- 1 file changed, 7 insertions(+), 36 deletions(-) diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index f5c50ea67..2e480636a 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -1995,11 +1995,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_status_t status; -#else int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ unsigned char *p = buf; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; size_t kkpp_len; @@ -2023,40 +2019,15 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, p += 2; #if defined(MBEDTLS_USE_PSA_CRYPTO) - size_t output_offset = 0; - size_t output_len; - - /* Repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice */ - for( unsigned int x = 1 ; x <= 2 ; ++x ) + ret = mbedtls_psa_ecjpake_write_round_one( &ssl->handshake->psa_pake_ctx, + p + 2, end - p - 2, &kkpp_len ); + if ( ret != 0 ) { - for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; - step <= PSA_PAKE_STEP_ZK_PROOF ; - ++step ) - { - /* For each step, prepend 1 byte with the length of the data */ - if (step != PSA_PAKE_STEP_ZK_PROOF) { - *(p + 2 + output_offset) = 65; - } else { - *(p + 2 + output_offset) = 32; - } - output_offset += 1; - status = psa_pake_output( &ssl->handshake->psa_pake_ctx, - step, p + 2 + output_offset, - end - p - output_offset - 2, - &output_len ); - if( status != PSA_SUCCESS ) - { - psa_destroy_key( ssl->handshake->psa_pake_password ); - psa_pake_abort( &ssl->handshake->psa_pake_ctx ); - MBEDTLS_SSL_DEBUG_RET( 1 , "psa_pake_output", status ); - return; - } - - output_offset += output_len; - } + psa_destroy_key( ssl->handshake->psa_pake_password ); + psa_pake_abort( &ssl->handshake->psa_pake_ctx ); + MBEDTLS_SSL_DEBUG_RET( 1 , "psa_pake_output", ret ); + return; } - - kkpp_len = output_offset; #else ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx, p + 2, end - p - 2, &kkpp_len, From 30ebe11f869ef6c04396e77bc091ca2d31a45c17 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 17 Nov 2022 16:23:34 +0100 Subject: [PATCH 10/69] tls: psa_pake: add a check on read size on both rounds Signed-off-by: Valerio Setti --- library/ssl_tls.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 35262cb88..06a5ec53d 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -8231,6 +8231,9 @@ int mbedtls_psa_ecjpake_read_round_one( } } + if ( input_offset != len ) + return PSA_ERROR_INVALID_ARGUMENT; + return( 0 ); } @@ -8286,6 +8289,9 @@ int mbedtls_psa_ecjpake_read_round_two( input_offset += length; } + if ( input_offset != len ) + return PSA_ERROR_INVALID_ARGUMENT; + return( 0 ); } From 9bed8ec5d85536275ca32b0cd6bb738612ea98e6 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 17 Nov 2022 16:36:19 +0100 Subject: [PATCH 11/69] tls: psa_pake: make round two reading function symmatric to the writing one Signed-off-by: Valerio Setti --- library/ssl_misc.h | 3 +-- library/ssl_tls.c | 21 +-------------------- library/ssl_tls12_client.c | 26 ++++++++++++++++++++++++-- library/ssl_tls12_server.c | 3 +-- 4 files changed, 27 insertions(+), 26 deletions(-) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index d022721a7..82a951a58 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2405,8 +2405,7 @@ int mbedtls_psa_ecjpake_read_round_one( */ int mbedtls_psa_ecjpake_read_round_two( psa_pake_operation_t *pake_ctx, - const unsigned char *buf, - size_t len, int role ); + const unsigned char *buf, size_t len ); /** * \brief Write the first round of key exchange into the provided output diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 06a5ec53d..ae12c7ebd 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -8240,7 +8240,7 @@ int mbedtls_psa_ecjpake_read_round_one( int mbedtls_psa_ecjpake_read_round_two( psa_pake_operation_t *pake_ctx, const unsigned char *buf, - size_t len, int role ) + size_t len ) { psa_status_t status; size_t input_offset = 0; @@ -8251,25 +8251,6 @@ int mbedtls_psa_ecjpake_read_round_two( { size_t length; - /* - * On its 2nd round, the server sends 3 extra bytes which identify the - * curve: - * - the 1st one is MBEDTLS_ECP_TLS_NAMED_CURVE - * - the 2nd and 3rd represent curve's TLS ID - * Validate this data before moving forward - */ - if( ( step == PSA_PAKE_STEP_KEY_SHARE ) && - ( role == MBEDTLS_SSL_IS_CLIENT ) ) - { - uint16_t tls_id = MBEDTLS_GET_UINT16_BE( buf, 1 ); - - if( ( *buf != MBEDTLS_ECP_TLS_NAMED_CURVE ) || - ( mbedtls_ecp_curve_info_from_tls_id( tls_id ) == NULL ) ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); - - input_offset += 3; - } - /* Length is stored at the first byte */ length = buf[input_offset]; input_offset += 1; diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index 4e986d1df..6dd8ef50f 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -2333,9 +2333,31 @@ start_processing: if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { #if defined(MBEDTLS_USE_PSA_CRYPTO) + /* + * The first 3 bytes are: + * [0] MBEDTLS_ECP_TLS_NAMED_CURVE + * [1, 2] elliptic curve's TLS ID + * + * However since we only support secp256r1 for now, we check only + * that TLS ID here + */ + uint16_t read_tls_id = MBEDTLS_GET_UINT16_BE( p, 1 ); + const mbedtls_ecp_curve_info *curve_info; + + if( ( curve_info = mbedtls_ecp_curve_info_from_grp_id( + MBEDTLS_ECP_DP_SECP256R1 ) ) == NULL ) + { + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); + } + + if( ( *p != MBEDTLS_ECP_TLS_NAMED_CURVE ) || + ( read_tls_id != curve_info->tls_id ) ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + p += 3; + if( ( ret = mbedtls_psa_ecjpake_read_round_two( - &ssl->handshake->psa_pake_ctx, p, end - p, - ssl->conf->endpoint ) ) != 0 ) + &ssl->handshake->psa_pake_ctx, p, end - p ) ) != 0 ) { psa_destroy_key( ssl->handshake->psa_pake_password ); psa_pake_abort( &ssl->handshake->psa_pake_ctx ); diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index 2e480636a..3bc7217b7 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -4115,8 +4115,7 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) { #if defined(MBEDTLS_USE_PSA_CRYPTO) if( ( ret = mbedtls_psa_ecjpake_read_round_two( - &ssl->handshake->psa_pake_ctx, p, end - p, - ssl->conf->endpoint ) ) != 0 ) + &ssl->handshake->psa_pake_ctx, p, end - p ) ) != 0 ) { psa_destroy_key( ssl->handshake->psa_pake_password ); psa_pake_abort( &ssl->handshake->psa_pake_ctx ); From 6b3dab03b5f0c3fe42ebfb83cf171192c08dd88f Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 17 Nov 2022 17:14:54 +0100 Subject: [PATCH 12/69] tls: psa_pake: use a single function for round one and two in key exchange read/write Signed-off-by: Valerio Setti --- library/ssl_misc.h | 48 +++++------------- library/ssl_tls.c | 101 +++++++------------------------------ library/ssl_tls12_client.c | 20 +++++--- library/ssl_tls12_server.c | 20 +++++--- 4 files changed, 57 insertions(+), 132 deletions(-) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 82a951a58..0f43a18f4 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2378,6 +2378,11 @@ static inline int psa_ssl_status_to_mbedtls( psa_status_t status ) MBEDTLS_SSL_ECJPAKE_PSA_PRIMITIVE, \ step ) +typedef enum { + MBEDTLS_ECJPAKE_ROUND_ONE, + MBEDTLS_ECJPAKE_ROUND_TWO +} mbedtls_ecjpake_rounds_t; + /** * \brief Parse the provided input buffer for getting the first round * of key exchange. This code is common between server and client @@ -2385,27 +2390,15 @@ static inline int psa_ssl_status_to_mbedtls( psa_status_t status ) * \param pake_ctx [in] the PAKE's operation/context structure * \param buf [in] input buffer to parse * \param len [in] length of the input buffer + * \param round [in] either MBEDTLS_ECJPAKE_ROUND_ONE or + * MBEDTLS_ECJPAKE_ROUND_TWO * * \return 0 on success or a negative error code in case of failure */ -int mbedtls_psa_ecjpake_read_round_one( +int mbedtls_psa_ecjpake_read_round( psa_pake_operation_t *pake_ctx, const unsigned char *buf, - size_t len ); - -/** - * \brief Parse the provided input buffer for getting the second round - * of key exchange. This code is common between server and client - * - * \param pake_ctx [in] the PAKE's operation/context structure - * \param buf [in] input buffer to parse - * \param len [in] length of the input buffer - * - * \return 0 on success or a negative error code in case of failure - */ -int mbedtls_psa_ecjpake_read_round_two( - psa_pake_operation_t *pake_ctx, - const unsigned char *buf, size_t len ); + size_t len, mbedtls_ecjpake_rounds_t round ); /** * \brief Write the first round of key exchange into the provided output @@ -2415,29 +2408,16 @@ int mbedtls_psa_ecjpake_read_round_two( * \param buf [out] the output buffer in which data will be written to * \param len [in] length of the output buffer * \param olen [out] the length of the data really written on the buffer + * \param round [in] either MBEDTLS_ECJPAKE_ROUND_ONE or + * MBEDTLS_ECJPAKE_ROUND_TWO * * \return 0 on success or a negative error code in case of failure */ -int mbedtls_psa_ecjpake_write_round_one( +int mbedtls_psa_ecjpake_write_round( psa_pake_operation_t *pake_ctx, unsigned char *buf, - size_t len, size_t *olen ); - -/** - * \brief Write the second round of key exchange into the provided output - * buffer. This code is common between server and client - * - * \param pake_ctx [in] the PAKE's operation/context structure - * \param buf [out] the output buffer in which data will be written to - * \param len [in] length of the output buffer - * \param olen [out] the length of the data really written on the buffer - * - * \return 0 on success or a negative error code in case of failure - */ -int mbedtls_psa_ecjpake_write_round_two( - psa_pake_operation_t *pake_ctx, - unsigned char *buf, - size_t len, size_t *olen ); + size_t len, size_t *olen, + mbedtls_ecjpake_rounds_t round ); #endif //MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO diff --git a/library/ssl_tls.c b/library/ssl_tls.c index ae12c7ebd..a1fa8697b 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -8196,16 +8196,20 @@ end: #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ defined(MBEDTLS_USE_PSA_CRYPTO) -int mbedtls_psa_ecjpake_read_round_one( +int mbedtls_psa_ecjpake_read_round( psa_pake_operation_t *pake_ctx, const unsigned char *buf, - size_t len ) + size_t len, mbedtls_ecjpake_rounds_t round ) { psa_status_t status; size_t input_offset = 0; + /* + * At round one repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice + * At round two perform a single cycle + */ + unsigned int remaining_steps = ( round == MBEDTLS_ECJPAKE_ROUND_ONE) ? 2 : 1; - /* Repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice */ - for( unsigned int x = 1; x <= 2; ++x ) + for( ; remaining_steps > 0; remaining_steps-- ) { for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE; step <= PSA_PAKE_STEP_ZK_PROOF; @@ -8237,59 +8241,25 @@ int mbedtls_psa_ecjpake_read_round_one( return( 0 ); } -int mbedtls_psa_ecjpake_read_round_two( - psa_pake_operation_t *pake_ctx, - const unsigned char *buf, - size_t len ) -{ - psa_status_t status; - size_t input_offset = 0; - - for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; - step <= PSA_PAKE_STEP_ZK_PROOF ; - ++step ) - { - size_t length; - - /* Length is stored at the first byte */ - length = buf[input_offset]; - input_offset += 1; - - if( input_offset + length > len ) - { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - status = psa_pake_input( pake_ctx, step, - buf + input_offset, length ); - if( status != PSA_SUCCESS) - { - return psa_ssl_status_to_mbedtls( status ); - } - - input_offset += length; - } - - if ( input_offset != len ) - return PSA_ERROR_INVALID_ARGUMENT; - - return( 0 ); -} - -int mbedtls_psa_ecjpake_write_round_one( +int mbedtls_psa_ecjpake_write_round( psa_pake_operation_t *pake_ctx, unsigned char *buf, - size_t len, size_t *olen ) + size_t len, size_t *olen, + mbedtls_ecjpake_rounds_t round ) { psa_status_t status; size_t output_offset = 0; size_t output_len; + /* + * At round one repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice + * At round two perform a single cycle + */ + unsigned int remaining_steps = ( round == MBEDTLS_ECJPAKE_ROUND_ONE) ? 2 : 1; - /* Repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice */ - for( unsigned int x = 1 ; x <= 2 ; ++x ) + for( ; remaining_steps > 0; remaining_steps-- ) { - for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; - step <= PSA_PAKE_STEP_ZK_PROOF ; + for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE; + step <= PSA_PAKE_STEP_ZK_PROOF; ++step ) { /* For each step, prepend 1 byte with the length of the data */ @@ -8313,39 +8283,6 @@ int mbedtls_psa_ecjpake_write_round_one( return( 0 ); } - -int mbedtls_psa_ecjpake_write_round_two( - psa_pake_operation_t *pake_ctx, - unsigned char *buf, - size_t len, size_t *olen ) -{ - psa_status_t status; - size_t output_offset = 0; - size_t output_len; - - for( psa_pake_step_t step = PSA_PAKE_STEP_KEY_SHARE ; - step <= PSA_PAKE_STEP_ZK_PROOF ; - ++step ) - { - /* For each step, prepend 1 byte with the length of the data */ - *(buf + output_offset) = MBEDTLS_SSL_ECJPAKE_OUTPUT_SIZE( step ); - output_offset += 1; - status = psa_pake_output( pake_ctx, - step, buf + output_offset, - len - output_offset, - &output_len ); - if( status != PSA_SUCCESS ) - { - return( psa_ssl_status_to_mbedtls( status ) ); - } - - output_offset += output_len; - } - - *olen = output_offset; - - return( 0 ); -} #endif //MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO #if defined(MBEDTLS_USE_PSA_CRYPTO) diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index 6dd8ef50f..8fcf5a4f5 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -164,8 +164,9 @@ static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "generating new ecjpake parameters" ) ); #if defined(MBEDTLS_USE_PSA_CRYPTO) - ret = mbedtls_psa_ecjpake_write_round_one(&ssl->handshake->psa_pake_ctx, - p + 2, end - p - 2, &kkpp_len ); + ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx, + p + 2, end - p - 2, &kkpp_len, + MBEDTLS_ECJPAKE_ROUND_ONE ); if ( ret != 0 ) { psa_destroy_key( ssl->handshake->psa_pake_password ); @@ -908,8 +909,9 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, ssl->handshake->ecjpake_cache_len = 0; #if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ( ret = mbedtls_psa_ecjpake_read_round_one( - &ssl->handshake->psa_pake_ctx, buf, len ) ) != 0 ) + if( ( ret = mbedtls_psa_ecjpake_read_round( + &ssl->handshake->psa_pake_ctx, buf, len, + MBEDTLS_ECJPAKE_ROUND_ONE ) ) != 0 ) { psa_destroy_key( ssl->handshake->psa_pake_password ); psa_pake_abort( &ssl->handshake->psa_pake_ctx ); @@ -2356,8 +2358,9 @@ start_processing: p += 3; - if( ( ret = mbedtls_psa_ecjpake_read_round_two( - &ssl->handshake->psa_pake_ctx, p, end - p ) ) != 0 ) + if( ( ret = mbedtls_psa_ecjpake_read_round( + &ssl->handshake->psa_pake_ctx, p, end - p, + MBEDTLS_ECJPAKE_ROUND_TWO ) ) != 0 ) { psa_destroy_key( ssl->handshake->psa_pake_password ); psa_pake_abort( &ssl->handshake->psa_pake_ctx ); @@ -3314,8 +3317,9 @@ ecdh_calc_secret: unsigned char *out_p = ssl->out_msg + header_len; unsigned char *end_p = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN - header_len; - ret = mbedtls_psa_ecjpake_write_round_two( &ssl->handshake->psa_pake_ctx, - out_p, end_p - out_p, &content_len ); + ret = mbedtls_psa_ecjpake_write_round( &ssl->handshake->psa_pake_ctx, + out_p, end_p - out_p, &content_len, + MBEDTLS_ECJPAKE_ROUND_TWO ); if ( ret != 0 ) { psa_destroy_key( ssl->handshake->psa_pake_password ); diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index 3bc7217b7..e6dee49c1 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -305,8 +305,9 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, } #if defined(MBEDTLS_USE_PSA_CRYPTO) - if ( ( ret = mbedtls_psa_ecjpake_read_round_one( - &ssl->handshake->psa_pake_ctx, buf, len ) ) != 0 ) + if ( ( ret = mbedtls_psa_ecjpake_read_round( + &ssl->handshake->psa_pake_ctx, buf, len, + MBEDTLS_ECJPAKE_ROUND_ONE ) ) != 0 ) { psa_destroy_key( ssl->handshake->psa_pake_password ); psa_pake_abort( &ssl->handshake->psa_pake_ctx ); @@ -2019,8 +2020,9 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, p += 2; #if defined(MBEDTLS_USE_PSA_CRYPTO) - ret = mbedtls_psa_ecjpake_write_round_one( &ssl->handshake->psa_pake_ctx, - p + 2, end - p - 2, &kkpp_len ); + ret = mbedtls_psa_ecjpake_write_round( &ssl->handshake->psa_pake_ctx, + p + 2, end - p - 2, &kkpp_len, + MBEDTLS_ECJPAKE_ROUND_ONE ); if ( ret != 0 ) { psa_destroy_key( ssl->handshake->psa_pake_password ); @@ -2867,9 +2869,10 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, MBEDTLS_PUT_UINT16_BE( curve_info->tls_id, out_p, 1 ); output_offset += sizeof( uint8_t ) + sizeof( uint16_t ); - ret = mbedtls_psa_ecjpake_write_round_two( &ssl->handshake->psa_pake_ctx, + ret = mbedtls_psa_ecjpake_write_round( &ssl->handshake->psa_pake_ctx, out_p + output_offset, - end_p - out_p - output_offset, &output_len ); + end_p - out_p - output_offset, &output_len, + MBEDTLS_ECJPAKE_ROUND_TWO ); if( ret != 0 ) { psa_destroy_key( ssl->handshake->psa_pake_password ); @@ -4114,8 +4117,9 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { #if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ( ret = mbedtls_psa_ecjpake_read_round_two( - &ssl->handshake->psa_pake_ctx, p, end - p ) ) != 0 ) + if( ( ret = mbedtls_psa_ecjpake_read_round( + &ssl->handshake->psa_pake_ctx, p, end - p, + MBEDTLS_ECJPAKE_ROUND_TWO ) ) != 0 ) { psa_destroy_key( ssl->handshake->psa_pake_password ); psa_pake_abort( &ssl->handshake->psa_pake_ctx ); From 819de86895383292f26ae83619f20eb853a00a75 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 17 Nov 2022 18:05:19 +0100 Subject: [PATCH 13/69] tls: removed extra white spaces and other minor fix Signed-off-by: Valerio Setti --- library/ssl_tls.c | 6 +++--- library/ssl_tls12_server.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index a1fa8697b..fa415a894 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -8203,7 +8203,7 @@ int mbedtls_psa_ecjpake_read_round( { psa_status_t status; size_t input_offset = 0; - /* + /* * At round one repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice * At round two perform a single cycle */ @@ -8235,7 +8235,7 @@ int mbedtls_psa_ecjpake_read_round( } } - if ( input_offset != len ) + if( input_offset != len ) return PSA_ERROR_INVALID_ARGUMENT; return( 0 ); @@ -8250,7 +8250,7 @@ int mbedtls_psa_ecjpake_write_round( psa_status_t status; size_t output_offset = 0; size_t output_len; - /* + /* * At round one repeat the KEY_SHARE, ZK_PUBLIC & ZF_PROOF twice * At round two perform a single cycle */ diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index e6dee49c1..1e9e51b30 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -305,8 +305,8 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, } #if defined(MBEDTLS_USE_PSA_CRYPTO) - if ( ( ret = mbedtls_psa_ecjpake_read_round( - &ssl->handshake->psa_pake_ctx, buf, len, + if( ( ret = mbedtls_psa_ecjpake_read_round( + &ssl->handshake->psa_pake_ctx, buf, len, MBEDTLS_ECJPAKE_ROUND_ONE ) ) != 0 ) { psa_destroy_key( ssl->handshake->psa_pake_password ); @@ -2867,7 +2867,7 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, } *out_p = MBEDTLS_ECP_TLS_NAMED_CURVE; MBEDTLS_PUT_UINT16_BE( curve_info->tls_id, out_p, 1 ); - output_offset += sizeof( uint8_t ) + sizeof( uint16_t ); + output_offset += 3; ret = mbedtls_psa_ecjpake_write_round( &ssl->handshake->psa_pake_ctx, out_p + output_offset, From aca21b717c26407f146f2bcf7ee7241854209639 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 17 Nov 2022 18:17:01 +0100 Subject: [PATCH 14/69] tls: psa_pake: enforce not empty passwords Signed-off-by: Valerio Setti --- include/mbedtls/ecjpake.h | 2 +- include/mbedtls/ssl.h | 3 ++- library/ssl_tls.c | 35 ++++++++++++++++------------------- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/include/mbedtls/ecjpake.h b/include/mbedtls/ecjpake.h index e7ca1b235..3dd3361a1 100644 --- a/include/mbedtls/ecjpake.h +++ b/include/mbedtls/ecjpake.h @@ -113,7 +113,7 @@ void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx ); * \param curve The identifier of the elliptic curve to use, * for example #MBEDTLS_ECP_DP_SECP256R1. * \param secret The pre-shared secret (passphrase). This must be - * a readable buffer of length \p len Bytes. It need + * a readable not empty buffer of length \p len Bytes. It need * only be valid for the duration of this call. * \param len The length of the pre-shared secret \p secret. * diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 01ede4088..085235721 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -3824,9 +3824,10 @@ void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf, * \note The SSL context needs to be already set up. The right place * to call this function is between \c mbedtls_ssl_setup() or * \c mbedtls_ssl_reset() and \c mbedtls_ssl_handshake(). + * Password cannot be empty (see RFC 8236). * * \param ssl SSL context - * \param pw EC J-PAKE password (pre-shared secret) + * \param pw EC J-PAKE password (pre-shared secret). It cannot be empty * \param pw_len length of pw in bytes * * \return 0 on success, or a negative error code. diff --git a/library/ssl_tls.c b/library/ssl_tls.c index fa415a894..062ff25dd 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1634,18 +1634,18 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, else psa_role = PSA_PAKE_ROLE_CLIENT; + /* Empty password is not valid */ + if( ( pw == NULL) || ( pw_len == 0 ) ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - if( pw_len > 0 ) - { - psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE ); - psa_set_key_algorithm( &attributes, PSA_ALG_JPAKE ); - psa_set_key_type( &attributes, PSA_KEY_TYPE_PASSWORD ); + psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE ); + psa_set_key_algorithm( &attributes, PSA_ALG_JPAKE ); + psa_set_key_type( &attributes, PSA_KEY_TYPE_PASSWORD ); - status = psa_import_key( &attributes, pw, pw_len, - &ssl->handshake->psa_pake_password ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } + status = psa_import_key( &attributes, pw, pw_len, + &ssl->handshake->psa_pake_password ); + if( status != PSA_SUCCESS ) + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); psa_pake_cs_set_algorithm( &cipher_suite, PSA_ALG_JPAKE ); psa_pake_cs_set_primitive( &cipher_suite, @@ -1669,16 +1669,13 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); } - if( pw_len > 0 ) + psa_pake_set_password_key( &ssl->handshake->psa_pake_ctx, + ssl->handshake->psa_pake_password ); + if( status != PSA_SUCCESS ) { - psa_pake_set_password_key( &ssl->handshake->psa_pake_ctx, - ssl->handshake->psa_pake_password ); - if( status != PSA_SUCCESS ) - { - psa_destroy_key( ssl->handshake->psa_pake_password ); - psa_pake_abort( &ssl->handshake->psa_pake_ctx ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } + psa_destroy_key( ssl->handshake->psa_pake_password ); + psa_pake_abort( &ssl->handshake->psa_pake_ctx ); + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); } ssl->handshake->psa_pake_ctx_is_ok = 1; From 61ea17d30a2da481987e634e100082fccc46062f Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 18 Nov 2022 12:11:00 +0100 Subject: [PATCH 15/69] tls: psa_pake: fix return values in parse functions Ensure they all belong to the MBEDTLS_ERR_SSL_* group Signed-off-by: Valerio Setti --- library/ssl_tls.c | 2 +- library/ssl_tls12_client.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 062ff25dd..c1436c532 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -8233,7 +8233,7 @@ int mbedtls_psa_ecjpake_read_round( } if( input_offset != len ) - return PSA_ERROR_INVALID_ARGUMENT; + return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; return( 0 ); } diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index 8fcf5a4f5..7c293ec9e 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -2354,7 +2354,7 @@ start_processing: if( ( *p != MBEDTLS_ECP_TLS_NAMED_CURVE ) || ( read_tls_id != curve_info->tls_id ) ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER ); p += 3; From 6969eee5d2a19b0aab2ffeece3d8a128e7f4e550 Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Mon, 10 Oct 2022 10:25:26 +0800 Subject: [PATCH 16/69] Remove `Terminated` message on 22.04 Signed-off-by: Jerry Yu --- tests/ssl-opt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index fdbb31050..53b3885c7 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -1362,7 +1362,7 @@ do_run_test_once() { if [ -n "$PXY_CMD" ]; then kill $PXY_PID >/dev/null 2>&1 - wait $PXY_PID + wait $PXY_PID >> $PXY_OUT 2>&1 fi } From 0b61217c36b19dadc278d6793a59e1b42475ec82 Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Wed, 12 Oct 2022 15:29:58 +0800 Subject: [PATCH 17/69] set new_session_ticket_* to handshake_over Signed-off-by: Jerry Yu --- include/mbedtls/ssl.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index d0558511a..366554587 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -4651,7 +4651,9 @@ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ); */ static inline int mbedtls_ssl_is_handshake_over( mbedtls_ssl_context *ssl ) { - return( ssl->MBEDTLS_PRIVATE( state ) == MBEDTLS_SSL_HANDSHAKE_OVER ); + return( ssl->MBEDTLS_PRIVATE( state ) == MBEDTLS_SSL_HANDSHAKE_OVER || + ssl->MBEDTLS_PRIVATE( state ) == MBEDTLS_SSL_NEW_SESSION_TICKET || + ssl->MBEDTLS_PRIVATE( state ) == MBEDTLS_SSL_NEW_SESSION_TICKET_FLUSH); } /** From e219c11b4e61b9f3f5077175fc083b26dc76e523 Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Mon, 24 Oct 2022 01:27:01 +0000 Subject: [PATCH 18/69] Replace internal usage of mbedtls_ssl_is_handshake_over Signed-off-by: Jerry Yu --- library/ssl_msg.c | 28 ++++++++++++++-------------- library/ssl_tls.c | 12 ++++++------ 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/library/ssl_msg.c b/library/ssl_msg.c index dbc639188..c4af7bf6d 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -1883,7 +1883,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) { len = in_buf_len - ( ssl->in_hdr - ssl->in_buf ); - if( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) timeout = ssl->handshake->retransmit_timeout; else timeout = ssl->conf->read_timeout; @@ -1907,7 +1907,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) ); mbedtls_ssl_set_timer( ssl, 0 ); - if( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) { if( ssl_double_retransmit_timeout( ssl ) != 0 ) { @@ -2343,7 +2343,7 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ) return( ret ); /* Update state and set timer */ - if( mbedtls_ssl_is_handshake_over( ssl ) == 1 ) + if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; else { @@ -2936,9 +2936,9 @@ int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ) } if( ssl->handshake != NULL && - ( ( mbedtls_ssl_is_handshake_over( ssl ) == 0 && + ( ( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && recv_msg_seq != ssl->handshake->in_msg_seq ) || - ( mbedtls_ssl_is_handshake_over( ssl ) == 1 && + ( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) ) ) { if( recv_msg_seq > ssl->handshake->in_msg_seq ) @@ -3004,7 +3004,7 @@ void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ) { mbedtls_ssl_handshake_params * const hs = ssl->handshake; - if( mbedtls_ssl_is_handshake_over( ssl ) == 0 && hs != NULL ) + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL ) { ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen ); } @@ -3651,7 +3651,7 @@ static int ssl_check_client_reconnect( mbedtls_ssl_context *ssl ) */ if( rec_epoch == 0 && ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - mbedtls_ssl_is_handshake_over( ssl ) == 1 && + ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && ssl->in_left > 13 && ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO ) @@ -4821,7 +4821,7 @@ int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ) /* Drop unexpected ApplicationData records, * except at the beginning of renegotiations */ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA && - mbedtls_ssl_is_handshake_over( ssl ) == 0 + ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER #if defined(MBEDTLS_SSL_RENEGOTIATION) && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && ssl->state == MBEDTLS_SSL_SERVER_HELLO ) @@ -4833,7 +4833,7 @@ int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ) } if( ssl->handshake != NULL && - mbedtls_ssl_is_handshake_over( ssl ) == 1 ) + ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) { mbedtls_ssl_handshake_wrapup_free_hs_transform( ssl ); } @@ -5258,7 +5258,7 @@ static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl ) int in_ctr_cmp; int out_ctr_cmp; - if( mbedtls_ssl_is_handshake_over( ssl ) == 0 || + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER || ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING || ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ) { @@ -5502,7 +5502,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) } #endif - if( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) { ret = mbedtls_ssl_handshake( ssl ); if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && @@ -5613,7 +5613,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) /* We're going to return something now, cancel timer, * except if handshake (renegotiation) is in progress */ - if( mbedtls_ssl_is_handshake_over( ssl ) == 1 ) + if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) mbedtls_ssl_set_timer( ssl, 0 ); #if defined(MBEDTLS_SSL_PROTO_DTLS) @@ -5758,7 +5758,7 @@ int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_ } #endif - if( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) { if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 ) { @@ -5786,7 +5786,7 @@ int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) ); - if( mbedtls_ssl_is_handshake_over( ssl ) == 1 ) + if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) { if( ( ret = mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_WARNING, diff --git a/library/ssl_tls.c b/library/ssl_tls.c index da90b2350..5eca7eec0 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -168,7 +168,7 @@ int mbedtls_ssl_get_peer_cid( mbedtls_ssl_context *ssl, *enabled = MBEDTLS_SSL_CID_DISABLED; if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM || - mbedtls_ssl_is_handshake_over( ssl ) == 0 ) + ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) { return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } @@ -3602,7 +3602,7 @@ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ) if( ssl == NULL || ssl->conf == NULL || ssl->handshake == NULL || - mbedtls_ssl_is_handshake_over( ssl ) == 1 ) + ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) { return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } @@ -3706,7 +3706,7 @@ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> handshake" ) ); /* Main handshake loop */ - while( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) + while( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) { ret = mbedtls_ssl_handshake_step( ssl ); @@ -3807,7 +3807,7 @@ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ) /* On server, just send the request */ if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) { - if( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING; @@ -3827,7 +3827,7 @@ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ) */ if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) { - if( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); if( ( ret = mbedtls_ssl_start_renegotiation( ssl ) ) != 0 ) @@ -4130,7 +4130,7 @@ int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl, * (only DTLS) but are currently used to simplify the implementation. */ /* The initial handshake must be over */ - if( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "Initial handshake isn't over" ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); From 6848a619229a9d12542ab721009002bef92cf245 Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Thu, 27 Oct 2022 13:03:26 +0800 Subject: [PATCH 19/69] Revert "Replace internal usage of mbedtls_ssl_is_handshake_over" This reverts commit 1d3ed2975e7ef0d84050a3aece02eec1f890dec3. Signed-off-by: Jerry Yu --- library/ssl_msg.c | 28 ++++++++++++++-------------- library/ssl_tls.c | 12 ++++++------ 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/library/ssl_msg.c b/library/ssl_msg.c index c4af7bf6d..dbc639188 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -1883,7 +1883,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) { len = in_buf_len - ( ssl->in_hdr - ssl->in_buf ); - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) + if( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) timeout = ssl->handshake->retransmit_timeout; else timeout = ssl->conf->read_timeout; @@ -1907,7 +1907,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) ); mbedtls_ssl_set_timer( ssl, 0 ); - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) + if( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) { if( ssl_double_retransmit_timeout( ssl ) != 0 ) { @@ -2343,7 +2343,7 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ) return( ret ); /* Update state and set timer */ - if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) + if( mbedtls_ssl_is_handshake_over( ssl ) == 1 ) ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; else { @@ -2936,9 +2936,9 @@ int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ) } if( ssl->handshake != NULL && - ( ( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && + ( ( mbedtls_ssl_is_handshake_over( ssl ) == 0 && recv_msg_seq != ssl->handshake->in_msg_seq ) || - ( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && + ( mbedtls_ssl_is_handshake_over( ssl ) == 1 && ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) ) ) { if( recv_msg_seq > ssl->handshake->in_msg_seq ) @@ -3004,7 +3004,7 @@ void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ) { mbedtls_ssl_handshake_params * const hs = ssl->handshake; - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL ) + if( mbedtls_ssl_is_handshake_over( ssl ) == 0 && hs != NULL ) { ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen ); } @@ -3651,7 +3651,7 @@ static int ssl_check_client_reconnect( mbedtls_ssl_context *ssl ) */ if( rec_epoch == 0 && ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && + mbedtls_ssl_is_handshake_over( ssl ) == 1 && ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && ssl->in_left > 13 && ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO ) @@ -4821,7 +4821,7 @@ int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ) /* Drop unexpected ApplicationData records, * except at the beginning of renegotiations */ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA && - ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER + mbedtls_ssl_is_handshake_over( ssl ) == 0 #if defined(MBEDTLS_SSL_RENEGOTIATION) && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && ssl->state == MBEDTLS_SSL_SERVER_HELLO ) @@ -4833,7 +4833,7 @@ int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ) } if( ssl->handshake != NULL && - ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) + mbedtls_ssl_is_handshake_over( ssl ) == 1 ) { mbedtls_ssl_handshake_wrapup_free_hs_transform( ssl ); } @@ -5258,7 +5258,7 @@ static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl ) int in_ctr_cmp; int out_ctr_cmp; - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER || + if( mbedtls_ssl_is_handshake_over( ssl ) == 0 || ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING || ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ) { @@ -5502,7 +5502,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) } #endif - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) + if( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) { ret = mbedtls_ssl_handshake( ssl ); if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && @@ -5613,7 +5613,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) /* We're going to return something now, cancel timer, * except if handshake (renegotiation) is in progress */ - if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) + if( mbedtls_ssl_is_handshake_over( ssl ) == 1 ) mbedtls_ssl_set_timer( ssl, 0 ); #if defined(MBEDTLS_SSL_PROTO_DTLS) @@ -5758,7 +5758,7 @@ int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_ } #endif - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) + if( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) { if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 ) { @@ -5786,7 +5786,7 @@ int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) ); - if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) + if( mbedtls_ssl_is_handshake_over( ssl ) == 1 ) { if( ( ret = mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_WARNING, diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 5eca7eec0..da90b2350 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -168,7 +168,7 @@ int mbedtls_ssl_get_peer_cid( mbedtls_ssl_context *ssl, *enabled = MBEDTLS_SSL_CID_DISABLED; if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM || - ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) + mbedtls_ssl_is_handshake_over( ssl ) == 0 ) { return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } @@ -3602,7 +3602,7 @@ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ) if( ssl == NULL || ssl->conf == NULL || ssl->handshake == NULL || - ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) + mbedtls_ssl_is_handshake_over( ssl ) == 1 ) { return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } @@ -3706,7 +3706,7 @@ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> handshake" ) ); /* Main handshake loop */ - while( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) + while( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) { ret = mbedtls_ssl_handshake_step( ssl ); @@ -3807,7 +3807,7 @@ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ) /* On server, just send the request */ if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) { - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) + if( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING; @@ -3827,7 +3827,7 @@ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ) */ if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) { - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) + if( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); if( ( ret = mbedtls_ssl_start_renegotiation( ssl ) ) != 0 ) @@ -4130,7 +4130,7 @@ int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl, * (only DTLS) but are currently used to simplify the implementation. */ /* The initial handshake must be over */ - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) + if( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "Initial handshake isn't over" ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); From 5ed73ff6de713a91c5486f09136c08947d84819a Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Thu, 27 Oct 2022 13:08:42 +0800 Subject: [PATCH 20/69] Add NEW_SESSION_TICKET* into handshake over states All state list after HANDSHAKE_OVER as is_handshakeover Signed-off-by: Jerry Yu --- include/mbedtls/ssl.h | 8 +++----- library/ssl_tls.c | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 366554587..8c4d76c86 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -661,8 +661,6 @@ typedef enum MBEDTLS_SSL_SERVER_FINISHED, MBEDTLS_SSL_FLUSH_BUFFERS, MBEDTLS_SSL_HANDSHAKE_WRAPUP, - MBEDTLS_SSL_HANDSHAKE_OVER, - MBEDTLS_SSL_NEW_SESSION_TICKET, MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT, MBEDTLS_SSL_HELLO_RETRY_REQUEST, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS, @@ -671,6 +669,8 @@ typedef enum MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO, MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO, MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST, + MBEDTLS_SSL_HANDSHAKE_OVER, + MBEDTLS_SSL_NEW_SESSION_TICKET, MBEDTLS_SSL_NEW_SESSION_TICKET_FLUSH, } mbedtls_ssl_states; @@ -4651,9 +4651,7 @@ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ); */ static inline int mbedtls_ssl_is_handshake_over( mbedtls_ssl_context *ssl ) { - return( ssl->MBEDTLS_PRIVATE( state ) == MBEDTLS_SSL_HANDSHAKE_OVER || - ssl->MBEDTLS_PRIVATE( state ) == MBEDTLS_SSL_NEW_SESSION_TICKET || - ssl->MBEDTLS_PRIVATE( state ) == MBEDTLS_SSL_NEW_SESSION_TICKET_FLUSH); + return( ssl->MBEDTLS_PRIVATE( state ) >= MBEDTLS_SSL_HANDSHAKE_OVER ); } /** diff --git a/library/ssl_tls.c b/library/ssl_tls.c index da90b2350..df57c9f96 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -7544,7 +7544,7 @@ void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ) #endif mbedtls_ssl_handshake_wrapup_free_hs_transform( ssl ); - ssl->state++; + ssl->state = MBEDTLS_SSL_HANDSHAKE_OVER; MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup" ) ); } From 1fb3299ad76abb608fe667a83169d65383d31e50 Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Thu, 27 Oct 2022 13:18:19 +0800 Subject: [PATCH 21/69] Replace internal usage of is_handshake_over. NEW_SESSION_TICKETS* are processed in handshake_step. Change the stop condition from `mbedtls_ssl_is_handshake_over` to directly check. Signed-off-by: Jerry Yu --- library/ssl_msg.c | 16 ++++++++-------- library/ssl_tls.c | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/library/ssl_msg.c b/library/ssl_msg.c index dbc639188..5d56dd6f4 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -1883,7 +1883,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) { len = in_buf_len - ( ssl->in_hdr - ssl->in_buf ); - if( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) timeout = ssl->handshake->retransmit_timeout; else timeout = ssl->conf->read_timeout; @@ -1907,7 +1907,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) ); mbedtls_ssl_set_timer( ssl, 0 ); - if( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) { if( ssl_double_retransmit_timeout( ssl ) != 0 ) { @@ -2936,9 +2936,9 @@ int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ) } if( ssl->handshake != NULL && - ( ( mbedtls_ssl_is_handshake_over( ssl ) == 0 && + ( ( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && recv_msg_seq != ssl->handshake->in_msg_seq ) || - ( mbedtls_ssl_is_handshake_over( ssl ) == 1 && + ( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) ) ) { if( recv_msg_seq > ssl->handshake->in_msg_seq ) @@ -3004,7 +3004,7 @@ void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ) { mbedtls_ssl_handshake_params * const hs = ssl->handshake; - if( mbedtls_ssl_is_handshake_over( ssl ) == 0 && hs != NULL ) + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL ) { ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen ); } @@ -4833,7 +4833,7 @@ int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ) } if( ssl->handshake != NULL && - mbedtls_ssl_is_handshake_over( ssl ) == 1 ) + ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) { mbedtls_ssl_handshake_wrapup_free_hs_transform( ssl ); } @@ -5502,7 +5502,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) } #endif - if( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) { ret = mbedtls_ssl_handshake( ssl ); if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && @@ -5758,7 +5758,7 @@ int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_ } #endif - if( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) { if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 ) { diff --git a/library/ssl_tls.c b/library/ssl_tls.c index df57c9f96..506333d77 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3602,7 +3602,7 @@ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ) if( ssl == NULL || ssl->conf == NULL || ssl->handshake == NULL || - mbedtls_ssl_is_handshake_over( ssl ) == 1 ) + ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) { return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } @@ -3706,7 +3706,7 @@ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> handshake" ) ); /* Main handshake loop */ - while( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) + while( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) { ret = mbedtls_ssl_handshake_step( ssl ); From c5826eaba2e2770e25492e71a27bc5262947faa4 Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Thu, 27 Oct 2022 17:20:26 +0800 Subject: [PATCH 22/69] Add debug message Signed-off-by: Jerry Yu --- tests/ssl-opt.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 53b3885c7..3ec345caa 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -11139,8 +11139,8 @@ not_with_valgrind # risk of non-mbedtls peer timing out requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 run_test "DTLS proxy: 3d, gnutls server, fragmentation, nbio" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \ - "$G_NEXT_SRV -u --mtu 512" \ - "$P_CLI dgram_packing=0 dtls=1 hs_timeout=500-60000 nbio=2" \ + "$G_NEXT_SRV -u --mtu 512 -d 10" \ + "$P_CLI dgram_packing=0 dtls=1 hs_timeout=500-60000 nbio=2 debug_level=5" \ 0 \ -s "Extra-header:" \ -c "Extra-header:" From cfda4bbeac554a4f77249d456e3c1946e17145b3 Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Thu, 27 Oct 2022 22:20:49 +0800 Subject: [PATCH 23/69] Replace handshake over in flight transmit Fix deadloop in DTLS resumption test. Signed-off-by: Jerry Yu --- library/ssl_msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 5d56dd6f4..eae1ddead 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -2343,7 +2343,7 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ) return( ret ); /* Update state and set timer */ - if( mbedtls_ssl_is_handshake_over( ssl ) == 1 ) + if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; else { From a8d3c5048f2553e11d6837724bbf4e1ceb89fcc9 Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Sun, 30 Oct 2022 14:51:23 +0800 Subject: [PATCH 24/69] Rename new session ticket name for TLS 1.3 NewSessionTicket is different with TLS 1.2. It should not share same state. Signed-off-by: Jerry Yu --- include/mbedtls/ssl.h | 6 ++++-- library/ssl_msg.c | 2 +- library/ssl_tls13_client.c | 4 ++-- library/ssl_tls13_server.c | 18 +++++++++--------- tests/ssl-opt.sh | 20 ++++++++++---------- 5 files changed, 26 insertions(+), 24 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 8c4d76c86..afb634e2f 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -661,6 +661,8 @@ typedef enum MBEDTLS_SSL_SERVER_FINISHED, MBEDTLS_SSL_FLUSH_BUFFERS, MBEDTLS_SSL_HANDSHAKE_WRAPUP, + + MBEDTLS_SSL_NEW_SESSION_TICKET, MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT, MBEDTLS_SSL_HELLO_RETRY_REQUEST, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS, @@ -670,8 +672,8 @@ typedef enum MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO, MBEDTLS_SSL_SERVER_CCS_AFTER_HELLO_RETRY_REQUEST, MBEDTLS_SSL_HANDSHAKE_OVER, - MBEDTLS_SSL_NEW_SESSION_TICKET, - MBEDTLS_SSL_NEW_SESSION_TICKET_FLUSH, + MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET, + MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH, } mbedtls_ssl_states; diff --git a/library/ssl_msg.c b/library/ssl_msg.c index eae1ddead..0a414abf9 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -5299,7 +5299,7 @@ static int ssl_tls13_check_new_session_ticket( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 3, ( "NewSessionTicket received" ) ); mbedtls_ssl_handshake_set_state( ssl, - MBEDTLS_SSL_NEW_SESSION_TICKET ); + MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET ); return( MBEDTLS_ERR_SSL_WANT_READ ); } diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 0372f2d98..db8476c75 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -2743,7 +2743,7 @@ static int ssl_tls13_postprocess_new_session_ticket( mbedtls_ssl_context *ssl, } /* - * Handler for MBEDTLS_SSL_NEW_SESSION_TICKET + * Handler for MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET */ MBEDTLS_CHECK_RETURN_CRITICAL static int ssl_tls13_process_new_session_ticket( mbedtls_ssl_context *ssl ) @@ -2857,7 +2857,7 @@ int mbedtls_ssl_tls13_handshake_client_step( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */ #if defined(MBEDTLS_SSL_SESSION_TICKETS) - case MBEDTLS_SSL_NEW_SESSION_TICKET: + case MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET: ret = ssl_tls13_process_new_session_ticket( ssl ); if( ret != 0 ) break; diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 3cd03108f..ce8767c5f 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -2628,7 +2628,7 @@ static int ssl_tls13_handshake_wrapup( mbedtls_ssl_context *ssl ) mbedtls_ssl_tls13_handshake_wrapup( ssl ); #if defined(MBEDTLS_SSL_SESSION_TICKETS) - mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_NEW_SESSION_TICKET ); + mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET ); #else mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_HANDSHAKE_OVER ); #endif @@ -2636,7 +2636,7 @@ static int ssl_tls13_handshake_wrapup( mbedtls_ssl_context *ssl ) } /* - * Handler for MBEDTLS_SSL_NEW_SESSION_TICKET + * Handler for MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET */ #define SSL_NEW_SESSION_TICKET_SKIP 0 #define SSL_NEW_SESSION_TICKET_WRITE 1 @@ -2872,7 +2872,7 @@ static int ssl_tls13_write_new_session_ticket_body( mbedtls_ssl_context *ssl, } /* - * Handler for MBEDTLS_SSL_NEW_SESSION_TICKET + * Handler for MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET */ static int ssl_tls13_write_new_session_ticket( mbedtls_ssl_context *ssl ) { @@ -2908,8 +2908,8 @@ static int ssl_tls13_write_new_session_ticket( mbedtls_ssl_context *ssl ) else ssl->handshake->new_session_tickets_count--; - mbedtls_ssl_handshake_set_state( ssl, - MBEDTLS_SSL_NEW_SESSION_TICKET_FLUSH ); + mbedtls_ssl_handshake_set_state( + ssl, MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH ); } else { @@ -3045,7 +3045,7 @@ int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ #if defined(MBEDTLS_SSL_SESSION_TICKETS) - case MBEDTLS_SSL_NEW_SESSION_TICKET: + case MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET: ret = ssl_tls13_write_new_session_ticket( ssl ); if( ret != 0 ) { @@ -3054,9 +3054,9 @@ int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl ) ret ); } break; - case MBEDTLS_SSL_NEW_SESSION_TICKET_FLUSH: + case MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH: /* This state is necessary to do the flush of the New Session - * Ticket message written in MBEDTLS_SSL_NEW_SESSION_TICKET + * Ticket message written in MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET * as part of ssl_prepare_handshake_step. */ ret = 0; @@ -3064,7 +3064,7 @@ int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl ) if( ssl->handshake->new_session_tickets_count == 0 ) mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_HANDSHAKE_OVER ); else - mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_NEW_SESSION_TICKET ); + mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET ); break; #endif /* MBEDTLS_SSL_SESSION_TICKETS */ diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 3ec345caa..062e68858 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -12920,8 +12920,8 @@ run_test "TLS 1.3: NewSessionTicket: Basic check, O->m" \ "$O_NEXT_CLI -msg -debug -tls1_3 -reconnect" \ 0 \ -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_NEW_SESSION_TICKET_FLUSH" + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" requires_gnutls_tls1_3 requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS @@ -12937,8 +12937,8 @@ run_test "TLS 1.3: NewSessionTicket: Basic check, G->m" \ -c "Connecting again- trying to resume previous session" \ -c "NEW SESSION TICKET (4) was received" \ -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_NEW_SESSION_TICKET_FLUSH" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \ -s "key exchange mode: ephemeral" \ -s "key exchange mode: psk_ephemeral" \ -s "found pre_shared_key extension" @@ -12960,8 +12960,8 @@ run_test "TLS 1.3: NewSessionTicket: Basic check, m->m" \ -c "Reconnecting with saved session" \ -c "HTTP/1.0 200 OK" \ -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_NEW_SESSION_TICKET_FLUSH" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \ -s "key exchange mode: ephemeral" \ -s "key exchange mode: psk_ephemeral" \ -s "found pre_shared_key extension" @@ -13015,8 +13015,8 @@ run_test "TLS 1.3: NewSessionTicket: servername check, m->m" \ -c "Reconnecting with saved session" \ -c "HTTP/1.0 200 OK" \ -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_NEW_SESSION_TICKET_FLUSH" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \ -s "key exchange mode: ephemeral" \ -s "key exchange mode: psk_ephemeral" \ -s "found pre_shared_key extension" @@ -13039,8 +13039,8 @@ run_test "TLS 1.3: NewSessionTicket: servername negative check, m->m" \ -c "Reconnecting with saved session" \ -c "Hostname mismatch the session ticket, disable session resumption." \ -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_NEW_SESSION_TICKET_FLUSH" + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" # Test heap memory usage after handshake requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 From 668070d5f41b425ce98a14f4f5e048e4366899a1 Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Wed, 9 Nov 2022 22:49:19 +0800 Subject: [PATCH 25/69] Remove unnecessary replace Signed-off-by: Jerry Yu --- library/ssl_msg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 0a414abf9..9eb1b7967 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -1883,7 +1883,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) { len = in_buf_len - ( ssl->in_hdr - ssl->in_buf ); - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) + if( mbedtls_ssl_is_handshake_over( ssl ) == 0 ) timeout = ssl->handshake->retransmit_timeout; else timeout = ssl->conf->read_timeout; @@ -3004,7 +3004,7 @@ void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ) { mbedtls_ssl_handshake_params * const hs = ssl->handshake; - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL ) + if( mbedtls_ssl_is_handshake_over( ssl ) == 0 && hs != NULL ) { ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen ); } From 9b421456b05c0b0c8354bb965e9e431159cd0c00 Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Fri, 18 Nov 2022 21:09:41 +0800 Subject: [PATCH 26/69] Revert change in dtls1.2 Signed-off-by: Jerry Yu --- library/ssl_msg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 9eb1b7967..cacedcaf9 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -2936,9 +2936,9 @@ int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ) } if( ssl->handshake != NULL && - ( ( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && + ( ( mbedtls_ssl_is_handshake_over( ssl ) == 0 && recv_msg_seq != ssl->handshake->in_msg_seq ) || - ( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && + ( mbedtls_ssl_is_handshake_over( ssl ) == 1 && ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) ) ) { if( recv_msg_seq > ssl->handshake->in_msg_seq ) @@ -4833,7 +4833,7 @@ int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ) } if( ssl->handshake != NULL && - ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) + mbedtls_ssl_is_handshake_over( ssl ) == 1 ) { mbedtls_ssl_handshake_wrapup_free_hs_transform( ssl ); } From dddd35ccf37b8372ff99c71faba367cec3e5714b Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Sun, 20 Nov 2022 12:30:58 +0800 Subject: [PATCH 27/69] remvoe unrelative change Signed-off-by: Jerry Yu --- tests/ssl-opt.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 062e68858..a4789db81 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -11139,8 +11139,8 @@ not_with_valgrind # risk of non-mbedtls peer timing out requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 run_test "DTLS proxy: 3d, gnutls server, fragmentation, nbio" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \ - "$G_NEXT_SRV -u --mtu 512 -d 10" \ - "$P_CLI dgram_packing=0 dtls=1 hs_timeout=500-60000 nbio=2 debug_level=5" \ + "$G_NEXT_SRV -u --mtu 512" \ + "$P_CLI dgram_packing=0 dtls=1 hs_timeout=500-60000 nbio=2" \ 0 \ -s "Extra-header:" \ -c "Extra-header:" From 0cd8967ba10a8f1d6a2b9be1e4f1a8289e8484ee Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 9 Nov 2022 12:14:14 +0000 Subject: [PATCH 28/69] Split test generator base class The class BaseTarget served two purposes: - track test cases and target files for generation - provide an abstract base class for individual test groups Splitting these allows decoupling these two and to have further common superclasses across targets. No intended change in generated test cases. Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 5 ++-- scripts/mbedtls_dev/bignum_core.py | 14 +++++------ scripts/mbedtls_dev/bignum_mod.py | 6 ++--- scripts/mbedtls_dev/bignum_mod_raw.py | 4 +-- scripts/mbedtls_dev/test_data_generation.py | 28 +++++++++++++-------- tests/scripts/generate_bignum_tests.py | 6 ++--- 6 files changed, 35 insertions(+), 28 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index 8b11bc283..ba30be40e 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -17,6 +17,8 @@ from abc import abstractmethod from typing import Iterator, List, Tuple, TypeVar +from . import test_data_generation + T = TypeVar('T') #pylint: disable=invalid-name def invmod(a: int, n: int) -> int: @@ -63,8 +65,7 @@ def combination_pairs(values: List[T]) -> List[Tuple[T, T]]: """Return all pair combinations from input values.""" return [(x, y) for x in values for y in values] - -class OperationCommon: +class OperationCommon(test_data_generation.BaseTest): """Common features for bignum binary operations. This adds functionality common in binary operation tests. diff --git a/scripts/mbedtls_dev/bignum_core.py b/scripts/mbedtls_dev/bignum_core.py index 0cc86b809..db9d1b7ca 100644 --- a/scripts/mbedtls_dev/bignum_core.py +++ b/scripts/mbedtls_dev/bignum_core.py @@ -16,20 +16,19 @@ import random -from abc import ABCMeta from typing import Dict, Iterator, List, Tuple from . import test_case from . import test_data_generation from . import bignum_common -class BignumCoreTarget(test_data_generation.BaseTarget, metaclass=ABCMeta): - #pylint: disable=abstract-method +class BignumCoreTarget(test_data_generation.BaseTarget): + #pylint: disable=abstract-method, too-few-public-methods """Target for bignum core test case generation.""" target_basename = 'test_suite_bignum_core.generated' -class BignumCoreShiftR(BignumCoreTarget, metaclass=ABCMeta): +class BignumCoreShiftR(BignumCoreTarget, test_data_generation.BaseTest): """Test cases for mbedtls_bignum_core_shift_r().""" count = 0 test_function = "mpi_core_shift_r" @@ -69,7 +68,7 @@ class BignumCoreShiftR(BignumCoreTarget, metaclass=ABCMeta): for count in counts: yield cls(input_hex, descr, count).create_test_case() -class BignumCoreCTLookup(BignumCoreTarget, metaclass=ABCMeta): +class BignumCoreCTLookup(BignumCoreTarget, test_data_generation.BaseTest): """Test cases for mbedtls_mpi_core_ct_uint_table_lookup().""" test_function = "mpi_core_ct_uint_table_lookup" test_name = "Constant time MPI table lookup" @@ -107,7 +106,8 @@ class BignumCoreCTLookup(BignumCoreTarget, metaclass=ABCMeta): yield (cls(bitsize, bitsize_description, window_size) .create_test_case()) -class BignumCoreOperation(bignum_common.OperationCommon, BignumCoreTarget, metaclass=ABCMeta): +class BignumCoreOperation(BignumCoreTarget, bignum_common.OperationCommon, + metaclass=ABCMeta): #pylint: disable=abstract-method """Common features for bignum core operations.""" input_values = [ @@ -297,7 +297,7 @@ class BignumCoreMLA(BignumCoreOperation): yield cur_op.create_test_case() -class BignumCoreMontmul(BignumCoreTarget): +class BignumCoreMontmul(BignumCoreTarget, test_data_generation.BaseTest): """Test cases for Montgomery multiplication.""" count = 0 test_function = "mpi_core_montmul" diff --git a/scripts/mbedtls_dev/bignum_mod.py b/scripts/mbedtls_dev/bignum_mod.py index 2bd7fbbda..a604cc0c5 100644 --- a/scripts/mbedtls_dev/bignum_mod.py +++ b/scripts/mbedtls_dev/bignum_mod.py @@ -14,12 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -from abc import ABCMeta - from . import test_data_generation -class BignumModTarget(test_data_generation.BaseTarget, metaclass=ABCMeta): - #pylint: disable=abstract-method +class BignumModTarget(test_data_generation.BaseTarget): + #pylint: disable=abstract-method, too-few-public-methods """Target for bignum mod test case generation.""" target_basename = 'test_suite_bignum_mod.generated' diff --git a/scripts/mbedtls_dev/bignum_mod_raw.py b/scripts/mbedtls_dev/bignum_mod_raw.py index bd694a608..4f12d9a86 100644 --- a/scripts/mbedtls_dev/bignum_mod_raw.py +++ b/scripts/mbedtls_dev/bignum_mod_raw.py @@ -21,8 +21,8 @@ from . import test_case from . import test_data_generation from . import bignum_common -class BignumModRawTarget(test_data_generation.BaseTarget, metaclass=ABCMeta): - #pylint: disable=abstract-method +class BignumModRawTarget(test_data_generation.BaseTarget): + #pylint: disable=abstract-method, too-few-public-methods """Target for bignum mod_raw test case generation.""" target_basename = 'test_suite_bignum_mod_raw.generated' diff --git a/scripts/mbedtls_dev/test_data_generation.py b/scripts/mbedtls_dev/test_data_generation.py index eec0f9d97..3d703eec7 100644 --- a/scripts/mbedtls_dev/test_data_generation.py +++ b/scripts/mbedtls_dev/test_data_generation.py @@ -25,6 +25,7 @@ import argparse import os import posixpath import re +import inspect from abc import ABCMeta, abstractmethod from typing import Callable, Dict, Iterable, Iterator, List, Type, TypeVar @@ -35,12 +36,8 @@ from . import test_case T = TypeVar('T') #pylint: disable=invalid-name -class BaseTarget(metaclass=ABCMeta): - """Base target for test case generation. - - Child classes of this class represent an output file, and can be referred - to as file targets. These indicate where test cases will be written to for - all subclasses of the file target, which is set by `target_basename`. +class BaseTest(metaclass=ABCMeta): + """Base class for test case generation. Attributes: count: Counter for test cases from this class. @@ -48,8 +45,6 @@ class BaseTarget(metaclass=ABCMeta): automatically generated using the class, or manually set. dependencies: A list of dependencies required for the test case. show_test_count: Toggle for inclusion of `count` in the test description. - target_basename: Basename of file to write generated tests to. This - should be specified in a child class of BaseTarget. test_function: Test function which the class generates cases for. test_name: A common name or description of the test function. This can be `test_function`, a clearer equivalent, or a short summary of the @@ -59,7 +54,6 @@ class BaseTarget(metaclass=ABCMeta): case_description = "" dependencies = [] # type: List[str] show_test_count = True - target_basename = "" test_function = "" test_name = "" @@ -121,6 +115,20 @@ class BaseTarget(metaclass=ABCMeta): """ raise NotImplementedError + +class BaseTarget: + """Base target for test case generation. + + Child classes of this class represent an output file, and can be referred + to as file targets. These indicate where test cases will be written to for + all subclasses of the file target, which is set by `target_basename`. + + Attributes: + target_basename: Basename of file to write generated tests to. This + should be specified in a child class of BaseTarget. + """ + target_basename = "" + @classmethod def generate_tests(cls) -> Iterator[test_case.TestCase]: """Generate test cases for the class and its subclasses. @@ -132,7 +140,7 @@ class BaseTarget(metaclass=ABCMeta): yield from `generate_tests()` in each. Calling this method on a class X will yield test cases from all classes derived from X. """ - if cls.test_function: + if issubclass(cls, BaseTest) and not inspect.isabstract(cls): yield from cls.generate_function_tests() for subclass in sorted(cls.__subclasses__(), key=lambda c: c.__name__): yield from subclass.generate_tests() diff --git a/tests/scripts/generate_bignum_tests.py b/tests/scripts/generate_bignum_tests.py index eee2f657a..9e5db3a11 100755 --- a/tests/scripts/generate_bignum_tests.py +++ b/tests/scripts/generate_bignum_tests.py @@ -68,13 +68,13 @@ from mbedtls_dev import bignum_common # the framework from mbedtls_dev import bignum_core, bignum_mod_raw # pylint: disable=unused-import -class BignumTarget(test_data_generation.BaseTarget, metaclass=ABCMeta): - #pylint: disable=abstract-method +class BignumTarget(test_data_generation.BaseTarget): """Target for bignum (legacy) test case generation.""" target_basename = 'test_suite_bignum.generated' -class BignumOperation(bignum_common.OperationCommon, BignumTarget, metaclass=ABCMeta): +class BignumOperation(bignum_common.OperationCommon, BignumTarget, + metaclass=ABCMeta): #pylint: disable=abstract-method """Common features for bignum operations in legacy tests.""" input_values = [ From 87df373e0e52949dbe394893ad768e563c2683a4 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 9 Nov 2022 12:31:23 +0000 Subject: [PATCH 29/69] Bignum test: Move identical function to superclass No intended change in generated test cases. Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 6 ++++++ scripts/mbedtls_dev/bignum_core.py | 5 ----- tests/scripts/generate_bignum_tests.py | 5 ----- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index ba30be40e..02241141f 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -17,6 +17,7 @@ from abc import abstractmethod from typing import Iterator, List, Tuple, TypeVar +from . import test_case from . import test_data_generation T = TypeVar('T') #pylint: disable=invalid-name @@ -122,6 +123,11 @@ class OperationCommon(test_data_generation.BaseTest): ) yield from cls.input_cases + @classmethod + def generate_function_tests(cls) -> Iterator[test_case.TestCase]: + for a_value, b_value in cls.get_value_pairs(): + yield cls(a_value, b_value).create_test_case() + # BEGIN MERGE SLOT 1 # END MERGE SLOT 1 diff --git a/scripts/mbedtls_dev/bignum_core.py b/scripts/mbedtls_dev/bignum_core.py index db9d1b7ca..a1c2e1bc6 100644 --- a/scripts/mbedtls_dev/bignum_core.py +++ b/scripts/mbedtls_dev/bignum_core.py @@ -144,11 +144,6 @@ class BignumCoreOperation(BignumCoreTarget, bignum_common.OperationCommon, ) return super().description() - @classmethod - def generate_function_tests(cls) -> Iterator[test_case.TestCase]: - for a_value, b_value in cls.get_value_pairs(): - yield cls(a_value, b_value).create_test_case() - class BignumCoreOperationArchSplit(BignumCoreOperation): #pylint: disable=abstract-method diff --git a/tests/scripts/generate_bignum_tests.py b/tests/scripts/generate_bignum_tests.py index 9e5db3a11..d923828ce 100755 --- a/tests/scripts/generate_bignum_tests.py +++ b/tests/scripts/generate_bignum_tests.py @@ -132,11 +132,6 @@ class BignumOperation(bignum_common.OperationCommon, BignumTarget, tmp = "large " + tmp return tmp - @classmethod - def generate_function_tests(cls) -> Iterator[test_case.TestCase]: - for a_value, b_value in cls.get_value_pairs(): - yield cls(a_value, b_value).create_test_case() - class BignumCmp(BignumOperation): """Test cases for bignum value comparison.""" From 3aeb60add6038855fc63704947824a016a6e79fc Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 9 Nov 2022 13:24:46 +0000 Subject: [PATCH 30/69] Bignum test: move archsplit to superclass We need arch split tests in different modules, moving it to the common module makes it reusable. No intended changes in the generated tests. (The position of the core_add_if tests changed, but they are still all there.) Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 46 +++++++++++++++ scripts/mbedtls_dev/bignum_core.py | 88 +++++++++------------------- 2 files changed, 73 insertions(+), 61 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index 02241141f..7ab788be0 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -97,6 +97,19 @@ class OperationCommon(test_data_generation.BaseTest): quote_str(self.arg_a), quote_str(self.arg_b) ] + self.result() + def description(self) -> str: + """Generate a description for the test case. + + If not set, case_description uses the form A `symbol` B, where symbol + is used to represent the operation. Descriptions of each value are + generated to provide some context to the test case. + """ + if not self.case_description: + self.case_description = "{:x} {} {:x}".format( + self.int_a, self.symbol, self.int_b + ) + return super().description() + @abstractmethod def result(self) -> List[str]: """Get the result of the operation. @@ -128,6 +141,39 @@ class OperationCommon(test_data_generation.BaseTest): for a_value, b_value in cls.get_value_pairs(): yield cls(a_value, b_value).create_test_case() + +class OperationCommonArchSplit(OperationCommon): + #pylint: disable=abstract-method + """Common features for operations where the result depends on + the limb size.""" + + def __init__(self, val_a: str, val_b: str, bits_in_limb: int) -> None: + super().__init__(val_a, val_b) + bound_val = max(self.int_a, self.int_b) + self.bits_in_limb = bits_in_limb + self.bound = bound_mpi(bound_val, self.bits_in_limb) + limbs = limbs_mpi(bound_val, self.bits_in_limb) + byte_len = limbs * self.bits_in_limb // 8 + self.hex_digits = 2 * byte_len + if self.bits_in_limb == 32: + self.dependencies = ["MBEDTLS_HAVE_INT32"] + elif self.bits_in_limb == 64: + self.dependencies = ["MBEDTLS_HAVE_INT64"] + else: + raise ValueError("Invalid number of bits in limb!") + self.arg_a = self.arg_a.zfill(self.hex_digits) + self.arg_b = self.arg_b.zfill(self.hex_digits) + + def pad_to_limbs(self, val) -> str: + return "{:x}".format(val).zfill(self.hex_digits) + + @classmethod + def generate_function_tests(cls) -> Iterator[test_case.TestCase]: + for a_value, b_value in cls.get_value_pairs(): + yield cls(a_value, b_value, 32).create_test_case() + yield cls(a_value, b_value, 64).create_test_case() + + # BEGIN MERGE SLOT 1 # END MERGE SLOT 1 diff --git a/scripts/mbedtls_dev/bignum_core.py b/scripts/mbedtls_dev/bignum_core.py index a1c2e1bc6..591e53c20 100644 --- a/scripts/mbedtls_dev/bignum_core.py +++ b/scripts/mbedtls_dev/bignum_core.py @@ -106,75 +106,41 @@ class BignumCoreCTLookup(BignumCoreTarget, test_data_generation.BaseTest): yield (cls(bitsize, bitsize_description, window_size) .create_test_case()) -class BignumCoreOperation(BignumCoreTarget, bignum_common.OperationCommon, - metaclass=ABCMeta): +INPUT_VALUES = [ + "0", "1", "3", "f", "fe", "ff", "100", "ff00", "fffe", "ffff", "10000", + "fffffffe", "ffffffff", "100000000", "1f7f7f7f7f7f7f", + "8000000000000000", "fefefefefefefefe", "fffffffffffffffe", + "ffffffffffffffff", "10000000000000000", "1234567890abcdef0", + "fffffffffffffffffefefefefefefefe", "fffffffffffffffffffffffffffffffe", + "ffffffffffffffffffffffffffffffff", "100000000000000000000000000000000", + "1234567890abcdef01234567890abcdef0", + "fffffffffffffffffffffffffffffffffffffffffffffffffefefefefefefefe", + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "10000000000000000000000000000000000000000000000000000000000000000", + "1234567890abcdef01234567890abcdef01234567890abcdef01234567890abcdef0", + ( + "4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f34029" + "643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf179298bd9947" + "c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38edf0c5889eca4a0" + "cfa99b45fbdeee4c696b328ddceae4723945901ec025076b12b" + ) +] + + +class BignumCoreOperation(BignumCoreTarget, bignum_common.OperationCommon): #pylint: disable=abstract-method """Common features for bignum core operations.""" - input_values = [ - "0", "1", "3", "f", "fe", "ff", "100", "ff00", "fffe", "ffff", "10000", - "fffffffe", "ffffffff", "100000000", "1f7f7f7f7f7f7f", - "8000000000000000", "fefefefefefefefe", "fffffffffffffffe", - "ffffffffffffffff", "10000000000000000", "1234567890abcdef0", - "fffffffffffffffffefefefefefefefe", "fffffffffffffffffffffffffffffffe", - "ffffffffffffffffffffffffffffffff", "100000000000000000000000000000000", - "1234567890abcdef01234567890abcdef0", - "fffffffffffffffffffffffffffffffffffffffffffffffffefefefefefefefe", - "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "10000000000000000000000000000000000000000000000000000000000000000", - "1234567890abcdef01234567890abcdef01234567890abcdef01234567890abcdef0", - ( - "4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f34029" - "643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf179298bd9947" - "c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38edf0c5889eca4a0" - "cfa99b45fbdeee4c696b328ddceae4723945901ec025076b12b" - ) - ] - - def description(self) -> str: - """Generate a description for the test case. - - If not set, case_description uses the form A `symbol` B, where symbol - is used to represent the operation. Descriptions of each value are - generated to provide some context to the test case. - """ - if not self.case_description: - self.case_description = "{:x} {} {:x}".format( - self.int_a, self.symbol, self.int_b - ) - return super().description() + input_values = INPUT_VALUES -class BignumCoreOperationArchSplit(BignumCoreOperation): +class BignumCoreOperationArchSplit(BignumCoreTarget, + bignum_common.OperationCommonArchSplit): #pylint: disable=abstract-method """Common features for bignum core operations where the result depends on the limb size.""" + input_values = INPUT_VALUES - def __init__(self, val_a: str, val_b: str, bits_in_limb: int) -> None: - super().__init__(val_a, val_b) - bound_val = max(self.int_a, self.int_b) - self.bits_in_limb = bits_in_limb - self.bound = bignum_common.bound_mpi(bound_val, self.bits_in_limb) - limbs = bignum_common.limbs_mpi(bound_val, self.bits_in_limb) - byte_len = limbs * self.bits_in_limb // 8 - self.hex_digits = 2 * byte_len - if self.bits_in_limb == 32: - self.dependencies = ["MBEDTLS_HAVE_INT32"] - elif self.bits_in_limb == 64: - self.dependencies = ["MBEDTLS_HAVE_INT64"] - else: - raise ValueError("Invalid number of bits in limb!") - self.arg_a = self.arg_a.zfill(self.hex_digits) - self.arg_b = self.arg_b.zfill(self.hex_digits) - - def pad_to_limbs(self, val) -> str: - return "{:x}".format(val).zfill(self.hex_digits) - - @classmethod - def generate_function_tests(cls) -> Iterator[test_case.TestCase]: - for a_value, b_value in cls.get_value_pairs(): - yield cls(a_value, b_value, 32).create_test_case() - yield cls(a_value, b_value, 64).create_test_case() class BignumCoreAddAndAddIf(BignumCoreOperationArchSplit): """Test cases for bignum core add and add-if.""" From 351e6885f55fd6354b57b51a5dbaadf3231aa7c8 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 9 Nov 2022 16:04:41 +0000 Subject: [PATCH 31/69] Make pylint happy Signed-off-by: Janos Follath --- scripts/mbedtls_dev/test_data_generation.py | 2 ++ tests/scripts/generate_bignum_tests.py | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/mbedtls_dev/test_data_generation.py b/scripts/mbedtls_dev/test_data_generation.py index 3d703eec7..02aa51051 100644 --- a/scripts/mbedtls_dev/test_data_generation.py +++ b/scripts/mbedtls_dev/test_data_generation.py @@ -117,6 +117,7 @@ class BaseTest(metaclass=ABCMeta): class BaseTarget: + #pylint: disable=too-few-public-methods """Base target for test case generation. Child classes of this class represent an output file, and can be referred @@ -141,6 +142,7 @@ class BaseTarget: will yield test cases from all classes derived from X. """ if issubclass(cls, BaseTest) and not inspect.isabstract(cls): + #pylint: disable=no-member yield from cls.generate_function_tests() for subclass in sorted(cls.__subclasses__(), key=lambda c: c.__name__): yield from subclass.generate_tests() diff --git a/tests/scripts/generate_bignum_tests.py b/tests/scripts/generate_bignum_tests.py index d923828ce..89d0ac29e 100755 --- a/tests/scripts/generate_bignum_tests.py +++ b/tests/scripts/generate_bignum_tests.py @@ -57,7 +57,7 @@ of BaseTarget in test_data_generation.py. import sys from abc import ABCMeta -from typing import Iterator, List +from typing import List import scripts_path # pylint: disable=unused-import from mbedtls_dev import test_case @@ -69,6 +69,7 @@ from mbedtls_dev import bignum_common from mbedtls_dev import bignum_core, bignum_mod_raw # pylint: disable=unused-import class BignumTarget(test_data_generation.BaseTarget): + #pylint: disable=too-few-public-methods """Target for bignum (legacy) test case generation.""" target_basename = 'test_suite_bignum.generated' From 5b1dbb4cbcdad4f3c37e40219c3f1a2398d7d87d Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Thu, 17 Nov 2022 13:32:43 +0000 Subject: [PATCH 32/69] Bignum Tests: Move ModOperation to common The class BignumModRawOperation implements functionality that are needed in other modules, therefore we move it to common. No intended changes to test cases. The order of add_and_add_if and sub tests have been switched. Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 52 +++++++++++++++++++++++++ scripts/mbedtls_dev/bignum_mod_raw.py | 55 +-------------------------- 2 files changed, 54 insertions(+), 53 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index 7ab788be0..28e27b039 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -142,6 +142,58 @@ class OperationCommon(test_data_generation.BaseTest): yield cls(a_value, b_value).create_test_case() +class ModOperationCommon(OperationCommon): + #pylint: disable=abstract-method + """Target for bignum mod_raw test case generation.""" + + def __init__(self, val_n: str, val_a: str, val_b: str = "0", bits_in_limb: int = 64) -> None: + super().__init__(val_a=val_a, val_b=val_b) + self.val_n = val_n + self.bits_in_limb = bits_in_limb + + @property + def int_n(self) -> int: + return hex_to_int(self.val_n) + + @property + def boundary(self) -> int: + data_in = [self.int_a, self.int_b, self.int_n] + return max([n for n in data_in if n is not None]) + + @property + def limbs(self) -> int: + return limbs_mpi(self.boundary, self.bits_in_limb) + + @property + def hex_digits(self) -> int: + return 2 * (self.limbs * self.bits_in_limb // 8) + + @property + def hex_n(self) -> str: + return "{:x}".format(self.int_n).zfill(self.hex_digits) + + @property + def hex_a(self) -> str: + return "{:x}".format(self.int_a).zfill(self.hex_digits) + + @property + def hex_b(self) -> str: + return "{:x}".format(self.int_b).zfill(self.hex_digits) + + @property + def r(self) -> int: # pylint: disable=invalid-name + l = limbs_mpi(self.int_n, self.bits_in_limb) + return bound_mpi_limbs(l, self.bits_in_limb) + + @property + def r_inv(self) -> int: + return invmod(self.r, self.int_n) + + @property + def r2(self) -> int: # pylint: disable=invalid-name + return pow(self.r, 2) + + class OperationCommonArchSplit(OperationCommon): #pylint: disable=abstract-method """Common features for operations where the result depends on diff --git a/scripts/mbedtls_dev/bignum_mod_raw.py b/scripts/mbedtls_dev/bignum_mod_raw.py index 4f12d9a86..884e2ef4a 100644 --- a/scripts/mbedtls_dev/bignum_mod_raw.py +++ b/scripts/mbedtls_dev/bignum_mod_raw.py @@ -14,7 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from abc import ABCMeta from typing import Dict, Iterator, List from . import test_case @@ -26,58 +25,8 @@ class BignumModRawTarget(test_data_generation.BaseTarget): """Target for bignum mod_raw test case generation.""" target_basename = 'test_suite_bignum_mod_raw.generated' -class BignumModRawOperation(bignum_common.OperationCommon, BignumModRawTarget, metaclass=ABCMeta): - #pylint: disable=abstract-method - """Target for bignum mod_raw test case generation.""" - - def __init__(self, val_n: str, val_a: str, val_b: str = "0", bits_in_limb: int = 64) -> None: - super().__init__(val_a=val_a, val_b=val_b) - self.val_n = val_n - self.bits_in_limb = bits_in_limb - - @property - def int_n(self) -> int: - return bignum_common.hex_to_int(self.val_n) - - @property - def boundary(self) -> int: - data_in = [self.int_a, self.int_b, self.int_n] - return max([n for n in data_in if n is not None]) - - @property - def limbs(self) -> int: - return bignum_common.limbs_mpi(self.boundary, self.bits_in_limb) - - @property - def hex_digits(self) -> int: - return 2 * (self.limbs * self.bits_in_limb // 8) - - @property - def hex_n(self) -> str: - return "{:x}".format(self.int_n).zfill(self.hex_digits) - - @property - def hex_a(self) -> str: - return "{:x}".format(self.int_a).zfill(self.hex_digits) - - @property - def hex_b(self) -> str: - return "{:x}".format(self.int_b).zfill(self.hex_digits) - - @property - def r(self) -> int: # pylint: disable=invalid-name - l = bignum_common.limbs_mpi(self.int_n, self.bits_in_limb) - return bignum_common.bound_mpi_limbs(l, self.bits_in_limb) - - @property - def r_inv(self) -> int: - return bignum_common.invmod(self.r, self.int_n) - - @property - def r2(self) -> int: # pylint: disable=invalid-name - return pow(self.r, 2) - -class BignumModRawOperationArchSplit(BignumModRawOperation): +class BignumModRawOperationArchSplit(bignum_common.ModOperationCommon, + BignumModRawTarget): #pylint: disable=abstract-method """Common features for bignum mod raw operations where the result depends on the limb size.""" From 948afcecb91caed178b85c6c285768ea604a82aa Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Thu, 17 Nov 2022 13:38:56 +0000 Subject: [PATCH 33/69] Bignum Tests: move ModOperationArchSplit to common The class BignumModRawOperationArchSplit has functionality that are needed in other modules, therefore moving it to bignum_common. Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 22 ++++++++++++++++++++++ scripts/mbedtls_dev/bignum_mod_raw.py | 24 ++---------------------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index 28e27b039..b853d1136 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -226,6 +226,28 @@ class OperationCommonArchSplit(OperationCommon): yield cls(a_value, b_value, 64).create_test_case() +class ModOperationCommonArchSplit(ModOperationCommon): + #pylint: disable=abstract-method + """Common features for bignum mod raw operations where the result depends on + the limb size.""" + + limb_sizes = [32, 64] # type: List[int] + + def __init__(self, val_n: str, val_a: str, val_b: str = "0", bits_in_limb: int = 64) -> None: + super().__init__(val_n=val_n, val_a=val_a, val_b=val_b, bits_in_limb=bits_in_limb) + + if bits_in_limb not in self.limb_sizes: + raise ValueError("Invalid number of bits in limb!") + + self.dependencies = ["MBEDTLS_HAVE_INT{:d}".format(bits_in_limb)] + + @classmethod + def generate_function_tests(cls) -> Iterator[test_case.TestCase]: + for a_value, b_value in cls.get_value_pairs(): + for bil in cls.limb_sizes: + yield cls(a_value, b_value, bits_in_limb=bil).create_test_case() + + # BEGIN MERGE SLOT 1 # END MERGE SLOT 1 diff --git a/scripts/mbedtls_dev/bignum_mod_raw.py b/scripts/mbedtls_dev/bignum_mod_raw.py index 884e2ef4a..58a93fc5d 100644 --- a/scripts/mbedtls_dev/bignum_mod_raw.py +++ b/scripts/mbedtls_dev/bignum_mod_raw.py @@ -25,27 +25,6 @@ class BignumModRawTarget(test_data_generation.BaseTarget): """Target for bignum mod_raw test case generation.""" target_basename = 'test_suite_bignum_mod_raw.generated' -class BignumModRawOperationArchSplit(bignum_common.ModOperationCommon, - BignumModRawTarget): - #pylint: disable=abstract-method - """Common features for bignum mod raw operations where the result depends on - the limb size.""" - - limb_sizes = [32, 64] # type: List[int] - - def __init__(self, val_n: str, val_a: str, val_b: str = "0", bits_in_limb: int = 64) -> None: - super().__init__(val_n=val_n, val_a=val_a, val_b=val_b, bits_in_limb=bits_in_limb) - - if bits_in_limb not in self.limb_sizes: - raise ValueError("Invalid number of bits in limb!") - - self.dependencies = ["MBEDTLS_HAVE_INT{:d}".format(bits_in_limb)] - - @classmethod - def generate_function_tests(cls) -> Iterator[test_case.TestCase]: - for a_value, b_value in cls.get_value_pairs(): - for bil in cls.limb_sizes: - yield cls(a_value, b_value, bits_in_limb=bil).create_test_case() # BEGIN MERGE SLOT 1 # END MERGE SLOT 1 @@ -71,7 +50,8 @@ class BignumModRawOperationArchSplit(bignum_common.ModOperationCommon, # END MERGE SLOT 6 # BEGIN MERGE SLOT 7 -class BignumModRawConvertToMont(BignumModRawOperationArchSplit): +class BignumModRawConvertToMont(bignum_common.ModOperationCommonArchSplit, + BignumModRawTarget): """ Test cases for mpi_mod_raw_to_mont_rep(). """ test_function = "mpi_mod_raw_to_mont_rep" From 155ad8c2971973b950c5c730a21fd9815f57fef7 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Thu, 17 Nov 2022 14:42:40 +0000 Subject: [PATCH 34/69] Bignum Tests: remove ModOperationCommonArchSplit The functionality of ModOperationCommonArchSplit is needed in several subclasses, therefore moving it to a superclass. There is another, redundant ArchSplit class, which will be removed in a later commit. Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 49 ++++++++++++--------------- scripts/mbedtls_dev/bignum_mod_raw.py | 3 +- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index b853d1136..cbbbf9f67 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -80,17 +80,29 @@ class OperationCommon(test_data_generation.BaseTest): unique_combinations_only: Boolean to select if test case combinations must be unique. If True, only A,B or B,A would be included as a test case. If False, both A,B and B,A would be included. + arch_split: Boolean to select if different test cases are needed + depending on the architecture/limb size. This will cause test + objects being generated with different architectures. Individual + test objects can tell their architecture by accessing the + bits_in_limb instance variable. """ symbol = "" input_values = [] # type: List[str] input_cases = [] # type: List[Tuple[str, str]] unique_combinations_only = True + arch_split = False + limb_sizes = [32, 64] # type: List[int] - def __init__(self, val_a: str, val_b: str) -> None: + def __init__(self, val_a: str, val_b: str, bits_in_limb: int = 64) -> None: self.arg_a = val_a self.arg_b = val_b self.int_a = hex_to_int(val_a) self.int_b = hex_to_int(val_b) + if bits_in_limb not in self.limb_sizes: + raise ValueError("Invalid number of bits in limb!") + if self.arch_split: + self.dependencies = ["MBEDTLS_HAVE_INT{:d}".format(bits_in_limb)] + self.bits_in_limb = bits_in_limb def arguments(self) -> List[str]: return [ @@ -139,17 +151,22 @@ class OperationCommon(test_data_generation.BaseTest): @classmethod def generate_function_tests(cls) -> Iterator[test_case.TestCase]: for a_value, b_value in cls.get_value_pairs(): - yield cls(a_value, b_value).create_test_case() + if cls.arch_split: + for bil in cls.limb_sizes: + yield cls(a_value, b_value, + bits_in_limb=bil).create_test_case() + else: + yield cls(a_value, b_value).create_test_case() class ModOperationCommon(OperationCommon): #pylint: disable=abstract-method """Target for bignum mod_raw test case generation.""" - def __init__(self, val_n: str, val_a: str, val_b: str = "0", bits_in_limb: int = 64) -> None: - super().__init__(val_a=val_a, val_b=val_b) + def __init__(self, val_n: str, val_a: str, val_b: str = "0", + bits_in_limb: int = 64) -> None: + super().__init__(val_a=val_a, val_b=val_b, bits_in_limb=bits_in_limb) self.val_n = val_n - self.bits_in_limb = bits_in_limb @property def int_n(self) -> int: @@ -226,28 +243,6 @@ class OperationCommonArchSplit(OperationCommon): yield cls(a_value, b_value, 64).create_test_case() -class ModOperationCommonArchSplit(ModOperationCommon): - #pylint: disable=abstract-method - """Common features for bignum mod raw operations where the result depends on - the limb size.""" - - limb_sizes = [32, 64] # type: List[int] - - def __init__(self, val_n: str, val_a: str, val_b: str = "0", bits_in_limb: int = 64) -> None: - super().__init__(val_n=val_n, val_a=val_a, val_b=val_b, bits_in_limb=bits_in_limb) - - if bits_in_limb not in self.limb_sizes: - raise ValueError("Invalid number of bits in limb!") - - self.dependencies = ["MBEDTLS_HAVE_INT{:d}".format(bits_in_limb)] - - @classmethod - def generate_function_tests(cls) -> Iterator[test_case.TestCase]: - for a_value, b_value in cls.get_value_pairs(): - for bil in cls.limb_sizes: - yield cls(a_value, b_value, bits_in_limb=bil).create_test_case() - - # BEGIN MERGE SLOT 1 # END MERGE SLOT 1 diff --git a/scripts/mbedtls_dev/bignum_mod_raw.py b/scripts/mbedtls_dev/bignum_mod_raw.py index 58a93fc5d..f44acef73 100644 --- a/scripts/mbedtls_dev/bignum_mod_raw.py +++ b/scripts/mbedtls_dev/bignum_mod_raw.py @@ -50,12 +50,13 @@ class BignumModRawTarget(test_data_generation.BaseTarget): # END MERGE SLOT 6 # BEGIN MERGE SLOT 7 -class BignumModRawConvertToMont(bignum_common.ModOperationCommonArchSplit, +class BignumModRawConvertToMont(bignum_common.ModOperationCommon, BignumModRawTarget): """ Test cases for mpi_mod_raw_to_mont_rep(). """ test_function = "mpi_mod_raw_to_mont_rep" test_name = "Convert into Mont: " + arch_split = True test_data_moduli = ["b", "fd", From b41ab926b2dc1808235099bbeed31159dbebc4c1 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Thu, 17 Nov 2022 15:13:02 +0000 Subject: [PATCH 35/69] Bignum Tests: move properties to superclass Move properties that are needed in several children to the superclass. Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 40 +++++++++++++++------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index cbbbf9f67..7d52749f8 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -104,6 +104,27 @@ class OperationCommon(test_data_generation.BaseTest): self.dependencies = ["MBEDTLS_HAVE_INT{:d}".format(bits_in_limb)] self.bits_in_limb = bits_in_limb + @property + def boundary(self) -> int: + data_in = [self.int_a, self.int_b] + return max([n for n in data_in if n is not None]) + + @property + def limbs(self) -> int: + return limbs_mpi(self.boundary, self.bits_in_limb) + + @property + def hex_digits(self) -> int: + return 2 * (self.limbs * self.bits_in_limb // 8) + + @property + def hex_a(self) -> str: + return "{:x}".format(self.int_a).zfill(self.hex_digits) + + @property + def hex_b(self) -> str: + return "{:x}".format(self.int_b).zfill(self.hex_digits) + def arguments(self) -> List[str]: return [ quote_str(self.arg_a), quote_str(self.arg_b) @@ -177,26 +198,10 @@ class ModOperationCommon(OperationCommon): data_in = [self.int_a, self.int_b, self.int_n] return max([n for n in data_in if n is not None]) - @property - def limbs(self) -> int: - return limbs_mpi(self.boundary, self.bits_in_limb) - - @property - def hex_digits(self) -> int: - return 2 * (self.limbs * self.bits_in_limb // 8) - @property def hex_n(self) -> str: return "{:x}".format(self.int_n).zfill(self.hex_digits) - @property - def hex_a(self) -> str: - return "{:x}".format(self.int_a).zfill(self.hex_digits) - - @property - def hex_b(self) -> str: - return "{:x}".format(self.int_b).zfill(self.hex_digits) - @property def r(self) -> int: # pylint: disable=invalid-name l = limbs_mpi(self.int_n, self.bits_in_limb) @@ -221,9 +226,6 @@ class OperationCommonArchSplit(OperationCommon): bound_val = max(self.int_a, self.int_b) self.bits_in_limb = bits_in_limb self.bound = bound_mpi(bound_val, self.bits_in_limb) - limbs = limbs_mpi(bound_val, self.bits_in_limb) - byte_len = limbs * self.bits_in_limb // 8 - self.hex_digits = 2 * byte_len if self.bits_in_limb == 32: self.dependencies = ["MBEDTLS_HAVE_INT32"] elif self.bits_in_limb == 64: From 6fa3f0653ae081ea43d5414624993d17f9b056dd Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Thu, 17 Nov 2022 20:33:51 +0000 Subject: [PATCH 36/69] Bignum Tests: remove OperationCommonArchSplit The ArchSplit functionality was duplicated and moved to OperationCommon from the other copy. The remnants of the functionality is moved to the only subclass using this. There is no semantic change to the generated tests. The order has changed however: core_add tests have been moved before core_mla tests and the order of the 64 and 32 bit versions have been swapped. Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 52 ++++++++------------------- scripts/mbedtls_dev/bignum_core.py | 24 +++++++------ scripts/mbedtls_dev/bignum_mod_raw.py | 2 +- 3 files changed, 29 insertions(+), 49 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index 7d52749f8..0784f845f 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -80,17 +80,18 @@ class OperationCommon(test_data_generation.BaseTest): unique_combinations_only: Boolean to select if test case combinations must be unique. If True, only A,B or B,A would be included as a test case. If False, both A,B and B,A would be included. - arch_split: Boolean to select if different test cases are needed - depending on the architecture/limb size. This will cause test - objects being generated with different architectures. Individual - test objects can tell their architecture by accessing the - bits_in_limb instance variable. + input_style: Controls the way how test data is passed to the functions + in the generated test cases. "variable" passes them as they are + defined in the python source. "arch_split" pads the values with + zeroes depending on the architecture/limb size. If this is set, + test cases are generated for all architectures. """ symbol = "" input_values = [] # type: List[str] input_cases = [] # type: List[Tuple[str, str]] unique_combinations_only = True - arch_split = False + input_styles = ["variable", "arch_split"] # type: List[str] + input_style = "variable" # type: str limb_sizes = [32, 64] # type: List[int] def __init__(self, val_a: str, val_b: str, bits_in_limb: int = 64) -> None: @@ -100,7 +101,7 @@ class OperationCommon(test_data_generation.BaseTest): self.int_b = hex_to_int(val_b) if bits_in_limb not in self.limb_sizes: raise ValueError("Invalid number of bits in limb!") - if self.arch_split: + if self.input_style == "arch_split": self.dependencies = ["MBEDTLS_HAVE_INT{:d}".format(bits_in_limb)] self.bits_in_limb = bits_in_limb @@ -109,6 +110,10 @@ class OperationCommon(test_data_generation.BaseTest): data_in = [self.int_a, self.int_b] return max([n for n in data_in if n is not None]) + @property + def limb_boundary(self) -> int: + return bound_mpi(self.boundary, self.bits_in_limb) + @property def limbs(self) -> int: return limbs_mpi(self.boundary, self.bits_in_limb) @@ -171,8 +176,10 @@ class OperationCommon(test_data_generation.BaseTest): @classmethod def generate_function_tests(cls) -> Iterator[test_case.TestCase]: + if cls.input_style not in cls.input_styles: + raise ValueError("Unknown input style!") for a_value, b_value in cls.get_value_pairs(): - if cls.arch_split: + if cls.input_style == "arch_split": for bil in cls.limb_sizes: yield cls(a_value, b_value, bits_in_limb=bil).create_test_case() @@ -216,35 +223,6 @@ class ModOperationCommon(OperationCommon): return pow(self.r, 2) -class OperationCommonArchSplit(OperationCommon): - #pylint: disable=abstract-method - """Common features for operations where the result depends on - the limb size.""" - - def __init__(self, val_a: str, val_b: str, bits_in_limb: int) -> None: - super().__init__(val_a, val_b) - bound_val = max(self.int_a, self.int_b) - self.bits_in_limb = bits_in_limb - self.bound = bound_mpi(bound_val, self.bits_in_limb) - if self.bits_in_limb == 32: - self.dependencies = ["MBEDTLS_HAVE_INT32"] - elif self.bits_in_limb == 64: - self.dependencies = ["MBEDTLS_HAVE_INT64"] - else: - raise ValueError("Invalid number of bits in limb!") - self.arg_a = self.arg_a.zfill(self.hex_digits) - self.arg_b = self.arg_b.zfill(self.hex_digits) - - def pad_to_limbs(self, val) -> str: - return "{:x}".format(val).zfill(self.hex_digits) - - @classmethod - def generate_function_tests(cls) -> Iterator[test_case.TestCase]: - for a_value, b_value in cls.get_value_pairs(): - yield cls(a_value, b_value, 32).create_test_case() - yield cls(a_value, b_value, 64).create_test_case() - - # BEGIN MERGE SLOT 1 # END MERGE SLOT 1 diff --git a/scripts/mbedtls_dev/bignum_core.py b/scripts/mbedtls_dev/bignum_core.py index 591e53c20..749403705 100644 --- a/scripts/mbedtls_dev/bignum_core.py +++ b/scripts/mbedtls_dev/bignum_core.py @@ -106,6 +106,7 @@ class BignumCoreCTLookup(BignumCoreTarget, test_data_generation.BaseTest): yield (cls(bitsize, bitsize_description, window_size) .create_test_case()) + INPUT_VALUES = [ "0", "1", "3", "f", "fe", "ff", "100", "ff00", "fffe", "ffff", "10000", "fffffffe", "ffffffff", "100000000", "1f7f7f7f7f7f7f", @@ -127,38 +128,39 @@ INPUT_VALUES = [ ) ] - class BignumCoreOperation(BignumCoreTarget, bignum_common.OperationCommon): #pylint: disable=abstract-method """Common features for bignum core operations.""" input_values = INPUT_VALUES -class BignumCoreOperationArchSplit(BignumCoreTarget, - bignum_common.OperationCommonArchSplit): - #pylint: disable=abstract-method - """Common features for bignum core operations where the result depends on - the limb size.""" - input_values = INPUT_VALUES - - -class BignumCoreAddAndAddIf(BignumCoreOperationArchSplit): +class BignumCoreAddAndAddIf(BignumCoreOperation): """Test cases for bignum core add and add-if.""" count = 0 symbol = "+" test_function = "mpi_core_add_and_add_if" test_name = "mpi_core_add_and_add_if" + input_style = "arch_split" + + def __init__(self, val_a: str, val_b: str, bits_in_limb: int) -> None: + super().__init__(val_a, val_b) + self.arg_a = self.arg_a.zfill(self.hex_digits) + self.arg_b = self.arg_b.zfill(self.hex_digits) + + def pad_to_limbs(self, val) -> str: + return "{:x}".format(val).zfill(self.hex_digits) def result(self) -> List[str]: result = self.int_a + self.int_b - carry, result = divmod(result, self.bound) + carry, result = divmod(result, self.limb_boundary) return [ bignum_common.quote_str(self.pad_to_limbs(result)), str(carry) ] + class BignumCoreSub(BignumCoreOperation): """Test cases for bignum core sub.""" count = 0 diff --git a/scripts/mbedtls_dev/bignum_mod_raw.py b/scripts/mbedtls_dev/bignum_mod_raw.py index f44acef73..b330c493d 100644 --- a/scripts/mbedtls_dev/bignum_mod_raw.py +++ b/scripts/mbedtls_dev/bignum_mod_raw.py @@ -56,7 +56,7 @@ class BignumModRawConvertToMont(bignum_common.ModOperationCommon, test_function = "mpi_mod_raw_to_mont_rep" test_name = "Convert into Mont: " - arch_split = True + input_style = "arch_split" test_data_moduli = ["b", "fd", From 4c59d35e00d08ae2a6ab51a13077776c05d22a3d Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Fri, 18 Nov 2022 16:05:46 +0000 Subject: [PATCH 37/69] Bignum tests: make args use input_style Before arg_ attributes were the arguments as they were defined in the python script. Turning these into properties and having them take the form respect the style set in input_style makes the class easier to use and more consistent. This change makes the hex_ properties redundant and therefore they are removed. There are no semantic changes to the generated test cases. (The order of appearance of 64 and 32 bit mpi_core_add_and_add_if test cases has changed.) Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 30 +++++++++++++++++++-------- scripts/mbedtls_dev/bignum_core.py | 10 +-------- scripts/mbedtls_dev/bignum_mod_raw.py | 4 ++-- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index 0784f845f..907c0b6d5 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -95,8 +95,8 @@ class OperationCommon(test_data_generation.BaseTest): limb_sizes = [32, 64] # type: List[int] def __init__(self, val_a: str, val_b: str, bits_in_limb: int = 64) -> None: - self.arg_a = val_a - self.arg_b = val_b + self.val_a = val_a + self.val_b = val_b self.int_a = hex_to_int(val_a) self.int_b = hex_to_int(val_b) if bits_in_limb not in self.limb_sizes: @@ -122,13 +122,25 @@ class OperationCommon(test_data_generation.BaseTest): def hex_digits(self) -> int: return 2 * (self.limbs * self.bits_in_limb // 8) - @property - def hex_a(self) -> str: - return "{:x}".format(self.int_a).zfill(self.hex_digits) + def format_arg(self, val) -> str: + if self.input_style not in self.input_styles: + raise ValueError("Unknown input style!") + if self.input_style == "variable": + return val + else: + return val.zfill(self.hex_digits) + + def format_result(self, res) -> str: + res_str = '{:x}'.format(res) + return quote_str(self.format_arg(res_str)) @property - def hex_b(self) -> str: - return "{:x}".format(self.int_b).zfill(self.hex_digits) + def arg_a(self) -> str: + return self.format_arg(self.val_a) + + @property + def arg_b(self) -> str: + return self.format_arg(self.val_b) def arguments(self) -> List[str]: return [ @@ -206,8 +218,8 @@ class ModOperationCommon(OperationCommon): return max([n for n in data_in if n is not None]) @property - def hex_n(self) -> str: - return "{:x}".format(self.int_n).zfill(self.hex_digits) + def arg_n(self) -> str: + return self.format_arg(self.val_n) @property def r(self) -> int: # pylint: disable=invalid-name diff --git a/scripts/mbedtls_dev/bignum_core.py b/scripts/mbedtls_dev/bignum_core.py index 749403705..48390b98c 100644 --- a/scripts/mbedtls_dev/bignum_core.py +++ b/scripts/mbedtls_dev/bignum_core.py @@ -142,21 +142,13 @@ class BignumCoreAddAndAddIf(BignumCoreOperation): test_name = "mpi_core_add_and_add_if" input_style = "arch_split" - def __init__(self, val_a: str, val_b: str, bits_in_limb: int) -> None: - super().__init__(val_a, val_b) - self.arg_a = self.arg_a.zfill(self.hex_digits) - self.arg_b = self.arg_b.zfill(self.hex_digits) - - def pad_to_limbs(self, val) -> str: - return "{:x}".format(val).zfill(self.hex_digits) - def result(self) -> List[str]: result = self.int_a + self.int_b carry, result = divmod(result, self.limb_boundary) return [ - bignum_common.quote_str(self.pad_to_limbs(result)), + self.format_result(result), str(carry) ] diff --git a/scripts/mbedtls_dev/bignum_mod_raw.py b/scripts/mbedtls_dev/bignum_mod_raw.py index b330c493d..e2d8cd698 100644 --- a/scripts/mbedtls_dev/bignum_mod_raw.py +++ b/scripts/mbedtls_dev/bignum_mod_raw.py @@ -114,8 +114,8 @@ class BignumModRawConvertToMont(bignum_common.ModOperationCommon, return [self.hex_x] def arguments(self) -> List[str]: - return [bignum_common.quote_str(n) for n in [self.hex_n, - self.hex_a, + return [bignum_common.quote_str(n) for n in [self.arg_n, + self.arg_a, self.hex_x]] def description(self) -> str: From abfca8f938e9923a849a0aaa350767e93f10ca5a Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Fri, 18 Nov 2022 16:48:45 +0000 Subject: [PATCH 38/69] Bignum tests: make n an attribute Having int_ variants as an attribute has the advantage of the input being validated when the object is instantiated. In theory otherwise if a particular int_ attribute is not accessed, then the invalid argument is passed to the tests as it is. (This would in all likelihood detected by the actual test cases, still, it is more robust like this.) There are no semantic changes to the generated test cases. (The order of appearance of 64 and 32 bit mpi_core_add_and_add_if test cases has changed.) Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index 907c0b6d5..58eb11ebd 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -97,6 +97,8 @@ class OperationCommon(test_data_generation.BaseTest): def __init__(self, val_a: str, val_b: str, bits_in_limb: int = 64) -> None: self.val_a = val_a self.val_b = val_b + # Setting the int versions here as opposed to making them @properties + # provides earlier/more robust input validation. self.int_a = hex_to_int(val_a) self.int_b = hex_to_int(val_b) if bits_in_limb not in self.limb_sizes: @@ -207,10 +209,9 @@ class ModOperationCommon(OperationCommon): bits_in_limb: int = 64) -> None: super().__init__(val_a=val_a, val_b=val_b, bits_in_limb=bits_in_limb) self.val_n = val_n - - @property - def int_n(self) -> int: - return hex_to_int(self.val_n) + # Setting the int versions here as opposed to making them @properties + # provides earlier/more robust input validation. + self.int_n = hex_to_int(val_n) @property def boundary(self) -> int: From a36a3d36b5c749011f8b94f88d37a3f3523ff8a8 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Fri, 18 Nov 2022 17:49:13 +0000 Subject: [PATCH 39/69] Bignum tests: add arity Add the ability to control the number of operands, by setting the arity class attribute. Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 30 ++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index 58eb11ebd..ecff206a3 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -85,6 +85,8 @@ class OperationCommon(test_data_generation.BaseTest): defined in the python source. "arch_split" pads the values with zeroes depending on the architecture/limb size. If this is set, test cases are generated for all architectures. + arity: the number of operands for the operation. Currently supported + values are 1 and 2. """ symbol = "" input_values = [] # type: List[str] @@ -93,8 +95,10 @@ class OperationCommon(test_data_generation.BaseTest): input_styles = ["variable", "arch_split"] # type: List[str] input_style = "variable" # type: str limb_sizes = [32, 64] # type: List[int] + arities = [1, 2] + arity = 2 - def __init__(self, val_a: str, val_b: str, bits_in_limb: int = 64) -> None: + def __init__(self, val_a: str, val_b: str = "0", bits_in_limb: int = 64) -> None: self.val_a = val_a self.val_b = val_b # Setting the int versions here as opposed to making them @properties @@ -109,8 +113,11 @@ class OperationCommon(test_data_generation.BaseTest): @property def boundary(self) -> int: - data_in = [self.int_a, self.int_b] - return max([n for n in data_in if n is not None]) + if self.arity == 1: + return self.int_a + elif self.arity == 2: + return max(self.int_a, self.int_b) + raise ValueError("Unsupported number of operands!") @property def limb_boundary(self) -> int: @@ -142,12 +149,15 @@ class OperationCommon(test_data_generation.BaseTest): @property def arg_b(self) -> str: + if self.arity == 1: + raise AttributeError("Operation is unary and doesn't have arg_b!") return self.format_arg(self.val_b) def arguments(self) -> List[str]: - return [ - quote_str(self.arg_a), quote_str(self.arg_b) - ] + self.result() + args = [quote_str(self.arg_a)] + if self.arity == 2: + args.append(quote_str(self.arg_b)) + return args + self.result() def description(self) -> str: """Generate a description for the test case. @@ -192,6 +202,8 @@ class OperationCommon(test_data_generation.BaseTest): def generate_function_tests(cls) -> Iterator[test_case.TestCase]: if cls.input_style not in cls.input_styles: raise ValueError("Unknown input style!") + if cls.arity not in cls.arities: + raise ValueError("Unsupported number of operands!") for a_value, b_value in cls.get_value_pairs(): if cls.input_style == "arch_split": for bil in cls.limb_sizes: @@ -215,13 +227,15 @@ class ModOperationCommon(OperationCommon): @property def boundary(self) -> int: - data_in = [self.int_a, self.int_b, self.int_n] - return max([n for n in data_in if n is not None]) + return self.int_n @property def arg_n(self) -> str: return self.format_arg(self.val_n) + def arguments(self) -> List[str]: + return [quote_str(self.arg_n)] + super().arguments() + @property def r(self) -> int: # pylint: disable=invalid-name l = limbs_mpi(self.int_n, self.bits_in_limb) From 1921fd585cb0314bb7e6e165727664c52052dd97 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Fri, 18 Nov 2022 17:51:02 +0000 Subject: [PATCH 40/69] Bignum tests: use arity in bignum_mod_raw This makes a couple of properties redundant which are cleaned up. Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_mod_raw.py | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_mod_raw.py b/scripts/mbedtls_dev/bignum_mod_raw.py index e2d8cd698..6c217c235 100644 --- a/scripts/mbedtls_dev/bignum_mod_raw.py +++ b/scripts/mbedtls_dev/bignum_mod_raw.py @@ -57,6 +57,7 @@ class BignumModRawConvertToMont(bignum_common.ModOperationCommon, test_function = "mpi_mod_raw_to_mont_rep" test_name = "Convert into Mont: " input_style = "arch_split" + arity = 1 test_data_moduli = ["b", "fd", @@ -111,12 +112,8 @@ class BignumModRawConvertToMont(bignum_common.ModOperationCommon, descr_tpl = '{} #{} N: \"{}\" A: \"{}\".' def result(self) -> List[str]: - return [self.hex_x] - - def arguments(self) -> List[str]: - return [bignum_common.quote_str(n) for n in [self.arg_n, - self.arg_a, - self.hex_x]] + result = (self.int_a * self.r) % self.int_n + return [self.format_result(result)] def description(self) -> str: return self.descr_tpl.format(self.test_name, @@ -134,13 +131,6 @@ class BignumModRawConvertToMont(bignum_common.ModOperationCommon, continue yield cls(n, i, bits_in_limb=bil).create_test_case() - @property - def x(self) -> int: # pylint: disable=invalid-name - return (self.int_a * self.r) % self.int_n - - @property - def hex_x(self) -> str: - return "{:x}".format(self.x).zfill(self.hex_digits) class BignumModRawConvertFromMont(BignumModRawConvertToMont): """ Test cases for mpi_mod_raw_from_mont_rep(). """ @@ -169,9 +159,11 @@ class BignumModRawConvertFromMont(BignumModRawConvertToMont): "138a7e6bfbc319ebd1725dacb9a359cbf693f2ecb785efb9d627" ] - @property - def x(self): # pylint: disable=invalid-name - return (self.int_a * self.r_inv) % self.int_n + def result(self) -> List[str]: + result = (self.int_a * self.r_inv) % self.int_n + return [self.format_result(result)] + + # END MERGE SLOT 7 # BEGIN MERGE SLOT 8 From 939621f8ed6803f2967568a3d70582ba27e85e07 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Fri, 18 Nov 2022 18:15:24 +0000 Subject: [PATCH 41/69] Bignum tests: add support for filtering Sometimes we don't want all possible combinations of the input data and sometimes not all combinations make sense. We are adding a convenient way to decide on a case by case basis. Now child classes only need to implement the is_valid method and the invalid cases will be filtered out automatically. Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index ecff206a3..b22846b71 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -172,6 +172,10 @@ class OperationCommon(test_data_generation.BaseTest): ) return super().description() + @property + def is_valid(self) -> bool: + return True + @abstractmethod def result(self) -> List[str]: """Get the result of the operation. @@ -204,13 +208,18 @@ class OperationCommon(test_data_generation.BaseTest): raise ValueError("Unknown input style!") if cls.arity not in cls.arities: raise ValueError("Unsupported number of operands!") - for a_value, b_value in cls.get_value_pairs(): - if cls.input_style == "arch_split": - for bil in cls.limb_sizes: - yield cls(a_value, b_value, - bits_in_limb=bil).create_test_case() - else: - yield cls(a_value, b_value).create_test_case() + if cls.input_style == "arch_split": + test_objects = (cls(a_value, b_value, bits_in_limb=bil) + for a_value, b_value in cls.get_value_pairs() + for bil in cls.limb_sizes) + else: + test_objects = (cls(a_value, b_value) for + a_value, b_value in cls.get_value_pairs()) + yield from (valid_test_object.create_test_case() + for valid_test_object in filter( + lambda test_object: test_object.is_valid, + test_objects + )) class ModOperationCommon(OperationCommon): From c4fca5de3ebe5a586a4be591f32b4b641d6e558c Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Sat, 19 Nov 2022 10:42:20 +0000 Subject: [PATCH 42/69] Bignum tests: automate modulo test object generation Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 37 +++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index b22846b71..7d7170d17 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -209,12 +209,12 @@ class OperationCommon(test_data_generation.BaseTest): if cls.arity not in cls.arities: raise ValueError("Unsupported number of operands!") if cls.input_style == "arch_split": - test_objects = (cls(a_value, b_value, bits_in_limb=bil) - for a_value, b_value in cls.get_value_pairs() + test_objects = (cls(a, b, bits_in_limb=bil) + for a, b in cls.get_value_pairs() for bil in cls.limb_sizes) else: - test_objects = (cls(a_value, b_value) for - a_value, b_value in cls.get_value_pairs()) + test_objects = (cls(a, b) + for a, b in cls.get_value_pairs()) yield from (valid_test_object.create_test_case() for valid_test_object in filter( lambda test_object: test_object.is_valid, @@ -225,6 +225,7 @@ class OperationCommon(test_data_generation.BaseTest): class ModOperationCommon(OperationCommon): #pylint: disable=abstract-method """Target for bignum mod_raw test case generation.""" + moduli = [] # type: List[str] def __init__(self, val_n: str, val_a: str, val_b: str = "0", bits_in_limb: int = 64) -> None: @@ -258,6 +259,34 @@ class ModOperationCommon(OperationCommon): def r2(self) -> int: # pylint: disable=invalid-name return pow(self.r, 2) + @property + def is_valid(self) -> bool: + if self.int_a >= self.int_n: + return False + if self.arity == 2 and self.int_b >= self.int_n: + return False + return True + + @classmethod + def generate_function_tests(cls) -> Iterator[test_case.TestCase]: + if cls.input_style not in cls.input_styles: + raise ValueError("Unknown input style!") + if cls.arity not in cls.arities: + raise ValueError("Unsupported number of operands!") + if cls.input_style == "arch_split": + test_objects = (cls(n, a, b, bits_in_limb=bil) + for n in cls.moduli + for a, b in cls.get_value_pairs() + for bil in cls.limb_sizes) + else: + test_objects = (cls(n, a, b) + for n in cls.moduli + for a, b in cls.get_value_pairs()) + yield from (valid_test_object.create_test_case() + for valid_test_object in filter( + lambda test_object: test_object.is_valid, + test_objects + )) # BEGIN MERGE SLOT 1 From 98edf21bb4bb33b1dc2b6a62f0eca204b4160c48 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Sat, 19 Nov 2022 12:48:17 +0000 Subject: [PATCH 43/69] Bignum test: remove type restrictrion The special case list type depends on the arity and the subclass. Remove type restriction to make defining special case lists more flexible and natural. Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 16 +++++++++++----- scripts/mbedtls_dev/bignum_core.py | 10 ++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index 7d7170d17..ed321d7c3 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -15,7 +15,8 @@ # limitations under the License. from abc import abstractmethod -from typing import Iterator, List, Tuple, TypeVar +from typing import Iterator, List, Tuple, TypeVar, Any +from itertools import chain from . import test_case from . import test_data_generation @@ -90,7 +91,7 @@ class OperationCommon(test_data_generation.BaseTest): """ symbol = "" input_values = [] # type: List[str] - input_cases = [] # type: List[Tuple[str, str]] + input_cases = [] # type: List[Any] unique_combinations_only = True input_styles = ["variable", "arch_split"] # type: List[str] input_style = "variable" # type: str @@ -200,7 +201,6 @@ class OperationCommon(test_data_generation.BaseTest): for a in cls.input_values for b in cls.input_values ) - yield from cls.input_cases @classmethod def generate_function_tests(cls) -> Iterator[test_case.TestCase]: @@ -212,14 +212,20 @@ class OperationCommon(test_data_generation.BaseTest): test_objects = (cls(a, b, bits_in_limb=bil) for a, b in cls.get_value_pairs() for bil in cls.limb_sizes) + special_cases = (cls(*args, bits_in_limb=bil) # type: ignore + for args in cls.input_cases + for bil in cls.limb_sizes) else: test_objects = (cls(a, b) for a, b in cls.get_value_pairs()) + special_cases = (cls(*args) for args in cls.input_cases) yield from (valid_test_object.create_test_case() for valid_test_object in filter( lambda test_object: test_object.is_valid, - test_objects - )) + chain(test_objects, special_cases) + ) + ) + class ModOperationCommon(OperationCommon): diff --git a/scripts/mbedtls_dev/bignum_core.py b/scripts/mbedtls_dev/bignum_core.py index 48390b98c..1bfc652ef 100644 --- a/scripts/mbedtls_dev/bignum_core.py +++ b/scripts/mbedtls_dev/bignum_core.py @@ -243,6 +243,16 @@ class BignumCoreMLA(BignumCoreOperation): "\"{:x}\"".format(carry_8) ] + @classmethod + def get_value_pairs(cls) -> Iterator[Tuple[str, str]]: + """Generator to yield pairs of inputs. + + Combinations are first generated from all input values, and then + specific cases provided. + """ + yield from super().get_value_pairs() + yield from cls.input_cases + @classmethod def generate_function_tests(cls) -> Iterator[test_case.TestCase]: """Override for additional scalar input.""" From 435b305a491853c7b477f5b012c226832574104e Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Sat, 19 Nov 2022 14:18:02 +0000 Subject: [PATCH 44/69] Bignum tests: add special cases to mod Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index ed321d7c3..6fd42d1e7 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -273,6 +273,15 @@ class ModOperationCommon(OperationCommon): return False return True + @classmethod + def input_cases_args(cls) -> Iterator[Tuple[Any, Any, Any]]: + if cls.arity == 1: + yield from ((n, a, "0") for a, n in cls.input_cases) + elif cls.arity == 2: + yield from ((n, a, b) for a, b, n in cls.input_cases) + else: + raise ValueError("Unsupported number of operands!") + @classmethod def generate_function_tests(cls) -> Iterator[test_case.TestCase]: if cls.input_style not in cls.input_styles: @@ -284,14 +293,18 @@ class ModOperationCommon(OperationCommon): for n in cls.moduli for a, b in cls.get_value_pairs() for bil in cls.limb_sizes) + special_cases = (cls(*args, bits_in_limb=bil) + for args in cls.input_cases_args() + for bil in cls.limb_sizes) else: test_objects = (cls(n, a, b) for n in cls.moduli for a, b in cls.get_value_pairs()) + special_cases = (cls(*args) for args in cls.input_cases_args()) yield from (valid_test_object.create_test_case() for valid_test_object in filter( lambda test_object: test_object.is_valid, - test_objects + chain(test_objects, special_cases) )) # BEGIN MERGE SLOT 1 From 284672ccfb23b7a62aa730cc86012722cd794f85 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Sat, 19 Nov 2022 14:55:43 +0000 Subject: [PATCH 45/69] Bignum tests: complete support for unary operators There are no intended changes to generated tests. (The ordering of tests in the mod_raw module has changed.) Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 19 ++-- scripts/mbedtls_dev/bignum_mod_raw.py | 149 ++++++++++++-------------- 2 files changed, 81 insertions(+), 87 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index 6fd42d1e7..318e25ca1 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -193,14 +193,19 @@ class OperationCommon(test_data_generation.BaseTest): Combinations are first generated from all input values, and then specific cases provided. """ - if cls.unique_combinations_only: - yield from combination_pairs(cls.input_values) + if cls.arity == 1: + yield from ((a, "0") for a in cls.input_values) + elif cls.arity == 2: + if cls.unique_combinations_only: + yield from combination_pairs(cls.input_values) + else: + yield from ( + (a, b) + for a in cls.input_values + for b in cls.input_values + ) else: - yield from ( - (a, b) - for a in cls.input_values - for b in cls.input_values - ) + raise ValueError("Unsupported number of operands!") @classmethod def generate_function_tests(cls) -> Iterator[test_case.TestCase]: diff --git a/scripts/mbedtls_dev/bignum_mod_raw.py b/scripts/mbedtls_dev/bignum_mod_raw.py index 6c217c235..087c8dc87 100644 --- a/scripts/mbedtls_dev/bignum_mod_raw.py +++ b/scripts/mbedtls_dev/bignum_mod_raw.py @@ -14,9 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Dict, Iterator, List +from typing import Dict, List -from . import test_case from . import test_data_generation from . import bignum_common @@ -59,55 +58,55 @@ class BignumModRawConvertToMont(bignum_common.ModOperationCommon, input_style = "arch_split" arity = 1 - test_data_moduli = ["b", - "fd", - "eeff99aa37", - "eeff99aa11", - "800000000005", - "7fffffffffffffff", - "80fe000a10000001", - "25a55a46e5da99c71c7", - "1058ad82120c3a10196bb36229c1", - "7e35b84cb19ea5bc57ec37f5e431462fa962d98c1e63738d4657f" - "18ad6532e6adc3eafe67f1e5fa262af94cee8d3e7268593942a2a" - "98df75154f8c914a282f8b", - "8335616aed761f1f7f44e6bd49e807b82e3bf2bf11bfa63", - "ffcece570f2f991013f26dd5b03c4c5b65f97be5905f36cb4664f" - "2c78ff80aa8135a4aaf57ccb8a0aca2f394909a74cef1ef6758a6" - "4d11e2c149c393659d124bfc94196f0ce88f7d7d567efa5a649e2" - "deefaa6e10fdc3deac60d606bf63fc540ac95294347031aefd73d" - "6a9ee10188aaeb7a90d920894553cb196881691cadc51808715a0" - "7e8b24fcb1a63df047c7cdf084dd177ba368c806f3d51ddb5d389" - "8c863e687ecaf7d649a57a46264a582f94d3c8f2edaf59f77a7f6" - "bdaf83c991e8f06abe220ec8507386fce8c3da84c6c3903ab8f3a" - "d4630a204196a7dbcbd9bcca4e40ec5cc5c09938d49f5e1e6181d" - "b8896f33bb12e6ef73f12ec5c5ea7a8a337" - ] + moduli = ["b", + "fd", + "eeff99aa37", + "eeff99aa11", + "800000000005", + "7fffffffffffffff", + "80fe000a10000001", + "25a55a46e5da99c71c7", + "1058ad82120c3a10196bb36229c1", + "7e35b84cb19ea5bc57ec37f5e431462fa962d98c1e63738d4657f" + "18ad6532e6adc3eafe67f1e5fa262af94cee8d3e7268593942a2a" + "98df75154f8c914a282f8b", + "8335616aed761f1f7f44e6bd49e807b82e3bf2bf11bfa63", + "ffcece570f2f991013f26dd5b03c4c5b65f97be5905f36cb4664f" + "2c78ff80aa8135a4aaf57ccb8a0aca2f394909a74cef1ef6758a6" + "4d11e2c149c393659d124bfc94196f0ce88f7d7d567efa5a649e2" + "deefaa6e10fdc3deac60d606bf63fc540ac95294347031aefd73d" + "6a9ee10188aaeb7a90d920894553cb196881691cadc51808715a0" + "7e8b24fcb1a63df047c7cdf084dd177ba368c806f3d51ddb5d389" + "8c863e687ecaf7d649a57a46264a582f94d3c8f2edaf59f77a7f6" + "bdaf83c991e8f06abe220ec8507386fce8c3da84c6c3903ab8f3a" + "d4630a204196a7dbcbd9bcca4e40ec5cc5c09938d49f5e1e6181d" + "b8896f33bb12e6ef73f12ec5c5ea7a8a337" + ] - test_input_numbers = ["0", - "1", - "97", - "f5", - "6f5c3", - "745bfe50f7", - "ffa1f9924123", - "334a8b983c79bd", - "5b84f632b58f3461", - "19acd15bc38008e1", - "ffffffffffffffff", - "54ce6a6bb8247fa0427cfc75a6b0599", - "fecafe8eca052f154ce6a6bb8247fa019558bfeecce9bb9", - "a87d7a56fa4bfdc7da42ef798b9cf6843d4c54794698cb14d72" - "851dec9586a319f4bb6d5695acbd7c92e7a42a5ede6972adcbc" - "f68425265887f2d721f462b7f1b91531bac29fa648facb8e3c6" - "1bd5ae42d5a59ba1c89a95897bfe541a8ce1d633b98f379c481" - "6f25e21f6ac49286b261adb4b78274fe5f61c187581f213e84b" - "2a821e341ef956ecd5de89e6c1a35418cd74a549379d2d4594a" - "577543147f8e35b3514e62cf3e89d1156cdc91ab5f4c928fbd6" - "9148c35df5962fed381f4d8a62852a36823d5425f7487c13a12" - "523473fb823aa9d6ea5f42e794e15f2c1a8785cf6b7d51a4617" - "947fb3baf674f74a673cf1d38126983a19ed52c7439fab42c2185" - ] + input_values = ["0", + "1", + "97", + "f5", + "6f5c3", + "745bfe50f7", + "ffa1f9924123", + "334a8b983c79bd", + "5b84f632b58f3461", + "19acd15bc38008e1", + "ffffffffffffffff", + "54ce6a6bb8247fa0427cfc75a6b0599", + "fecafe8eca052f154ce6a6bb8247fa019558bfeecce9bb9", + "a87d7a56fa4bfdc7da42ef798b9cf6843d4c54794698cb14d72" + "851dec9586a319f4bb6d5695acbd7c92e7a42a5ede6972adcbc" + "f68425265887f2d721f462b7f1b91531bac29fa648facb8e3c6" + "1bd5ae42d5a59ba1c89a95897bfe541a8ce1d633b98f379c481" + "6f25e21f6ac49286b261adb4b78274fe5f61c187581f213e84b" + "2a821e341ef956ecd5de89e6c1a35418cd74a549379d2d4594a" + "577543147f8e35b3514e62cf3e89d1156cdc91ab5f4c928fbd6" + "9148c35df5962fed381f4d8a62852a36823d5425f7487c13a12" + "523473fb823aa9d6ea5f42e794e15f2c1a8785cf6b7d51a4617" + "947fb3baf674f74a673cf1d38126983a19ed52c7439fab42c2185" + ] descr_tpl = '{} #{} N: \"{}\" A: \"{}\".' @@ -121,16 +120,6 @@ class BignumModRawConvertToMont(bignum_common.ModOperationCommon, self.int_n, self.int_a) - @classmethod - def generate_function_tests(cls) -> Iterator[test_case.TestCase]: - for bil in [32, 64]: - for n in cls.test_data_moduli: - for i in cls.test_input_numbers: - # Skip invalid combinations where A.limbs > N.limbs - if bignum_common.hex_to_int(i) > bignum_common.hex_to_int(n): - continue - yield cls(n, i, bits_in_limb=bil).create_test_case() - class BignumModRawConvertFromMont(BignumModRawConvertToMont): """ Test cases for mpi_mod_raw_from_mont_rep(). """ @@ -138,26 +127,26 @@ class BignumModRawConvertFromMont(BignumModRawConvertToMont): test_function = "mpi_mod_raw_from_mont_rep" test_name = "Convert from Mont: " - test_input_numbers = ["0", - "1", - "3ca", - "539ed428", - "7dfe5c6beb35a2d6", - "dca8de1c2adfc6d7aafb9b48e", - "a7d17b6c4be72f3d5c16bf9c1af6fc933", - "2fec97beec546f9553142ed52f147845463f579", - "378dc83b8bc5a7b62cba495af4919578dce6d4f175cadc4f", - "b6415f2a1a8e48a518345db11f56db3829c8f2c6415ab4a395a" - "b3ac2ea4cbef4af86eb18a84eb6ded4c6ecbfc4b59c2879a675" - "487f687adea9d197a84a5242a5cf6125ce19a6ad2e7341f1c57" - "d43ea4f4c852a51cb63dabcd1c9de2b827a3146a3d175b35bea" - "41ae75d2a286a3e9d43623152ac513dcdea1d72a7da846a8ab3" - "58d9be4926c79cfb287cf1cf25b689de3b912176be5dcaf4d4c" - "6e7cb839a4a3243a6c47c1e2c99d65c59d6fa3672575c2f1ca8" - "de6a32e854ec9d8ec635c96af7679fce26d7d159e4a9da3bd74" - "e1272c376cd926d74fe3fb164a5935cff3d5cdb92b35fe2cea32" - "138a7e6bfbc319ebd1725dacb9a359cbf693f2ecb785efb9d627" - ] + input_values = ["0", + "1", + "3ca", + "539ed428", + "7dfe5c6beb35a2d6", + "dca8de1c2adfc6d7aafb9b48e", + "a7d17b6c4be72f3d5c16bf9c1af6fc933", + "2fec97beec546f9553142ed52f147845463f579", + "378dc83b8bc5a7b62cba495af4919578dce6d4f175cadc4f", + "b6415f2a1a8e48a518345db11f56db3829c8f2c6415ab4a395a" + "b3ac2ea4cbef4af86eb18a84eb6ded4c6ecbfc4b59c2879a675" + "487f687adea9d197a84a5242a5cf6125ce19a6ad2e7341f1c57" + "d43ea4f4c852a51cb63dabcd1c9de2b827a3146a3d175b35bea" + "41ae75d2a286a3e9d43623152ac513dcdea1d72a7da846a8ab3" + "58d9be4926c79cfb287cf1cf25b689de3b912176be5dcaf4d4c" + "6e7cb839a4a3243a6c47c1e2c99d65c59d6fa3672575c2f1ca8" + "de6a32e854ec9d8ec635c96af7679fce26d7d159e4a9da3bd74" + "e1272c376cd926d74fe3fb164a5935cff3d5cdb92b35fe2cea32" + "138a7e6bfbc319ebd1725dacb9a359cbf693f2ecb785efb9d627" + ] def result(self) -> List[str]: result = (self.int_a * self.r_inv) % self.int_n From 8ae7a657acb7e35b51de4c39c4e47aba4858a11e Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Sat, 19 Nov 2022 15:05:19 +0000 Subject: [PATCH 46/69] Bignum tests: improve mod descriptions There are no semantic changes to the generated tests. Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 23 +++++++++++++++++++---- scripts/mbedtls_dev/bignum_mod_raw.py | 12 +++--------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index 318e25ca1..9e92b8e61 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -168,9 +168,14 @@ class OperationCommon(test_data_generation.BaseTest): generated to provide some context to the test case. """ if not self.case_description: - self.case_description = "{:x} {} {:x}".format( - self.int_a, self.symbol, self.int_b - ) + if self.arity == 1: + self.case_description = "{} {:x}".format( + self.symbol, self.int_a + ) + elif self.arity == 2: + self.case_description = "{:x} {} {:x}".format( + self.int_a, self.symbol, self.int_b + ) return super().description() @property @@ -232,7 +237,6 @@ class OperationCommon(test_data_generation.BaseTest): ) - class ModOperationCommon(OperationCommon): #pylint: disable=abstract-method """Target for bignum mod_raw test case generation.""" @@ -278,6 +282,17 @@ class ModOperationCommon(OperationCommon): return False return True + def description(self) -> str: + """Generate a description for the test case. + + It uses the form A `symbol` B mod N, where symbol is used to represent + the operation. + """ + + if not self.case_description: + return super().description() + " mod {:x}".format(self.int_n) + return super().description() + @classmethod def input_cases_args(cls) -> Iterator[Tuple[Any, Any, Any]]: if cls.arity == 1: diff --git a/scripts/mbedtls_dev/bignum_mod_raw.py b/scripts/mbedtls_dev/bignum_mod_raw.py index 087c8dc87..b23fbb2dc 100644 --- a/scripts/mbedtls_dev/bignum_mod_raw.py +++ b/scripts/mbedtls_dev/bignum_mod_raw.py @@ -55,6 +55,7 @@ class BignumModRawConvertToMont(bignum_common.ModOperationCommon, test_function = "mpi_mod_raw_to_mont_rep" test_name = "Convert into Mont: " + symbol = "R *" input_style = "arch_split" arity = 1 @@ -108,24 +109,17 @@ class BignumModRawConvertToMont(bignum_common.ModOperationCommon, "947fb3baf674f74a673cf1d38126983a19ed52c7439fab42c2185" ] - descr_tpl = '{} #{} N: \"{}\" A: \"{}\".' - def result(self) -> List[str]: result = (self.int_a * self.r) % self.int_n return [self.format_result(result)] - def description(self) -> str: - return self.descr_tpl.format(self.test_name, - self.count, - self.int_n, - self.int_a) - class BignumModRawConvertFromMont(BignumModRawConvertToMont): """ Test cases for mpi_mod_raw_from_mont_rep(). """ - + count = 0 test_function = "mpi_mod_raw_from_mont_rep" test_name = "Convert from Mont: " + symbol = "1/R *" input_values = ["0", "1", From a36e430251d855143267c2ea1185d13c7d8e3042 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Sat, 19 Nov 2022 15:55:53 +0000 Subject: [PATCH 47/69] Bignum tests: add support for fixed width input Only fixed width input_style uses the default value of the bits_in_limb parameter, so set it to 32 in order to have less leading zeroes. Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index 9e92b8e61..b68653a03 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -93,13 +93,13 @@ class OperationCommon(test_data_generation.BaseTest): input_values = [] # type: List[str] input_cases = [] # type: List[Any] unique_combinations_only = True - input_styles = ["variable", "arch_split"] # type: List[str] + input_styles = ["variable", "fixed", "arch_split"] # type: List[str] input_style = "variable" # type: str limb_sizes = [32, 64] # type: List[int] arities = [1, 2] arity = 2 - def __init__(self, val_a: str, val_b: str = "0", bits_in_limb: int = 64) -> None: + def __init__(self, val_a: str, val_b: str = "0", bits_in_limb: int = 32) -> None: self.val_a = val_a self.val_b = val_b # Setting the int versions here as opposed to making them @properties From b2a850c746ea475aaa22c7c26756d1eefdfd6883 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Sun, 20 Nov 2022 10:56:05 +0000 Subject: [PATCH 48/69] Bignum Tests: add test data The goal of this commit is to add some constants that can be used to define datasets and add test data in a more readable and reusable manner. All platforms using ECC need to support calculations with at least 192 bits, therefore constants for this length are added. We are not using a curve prime as those will be tested elsewhere and it is better not to play favourites. All platforms using RSA or FFDH need to support calculations with at least 1024 bits, therefore numbers of this size are added too. A safe prime is added for both sizes as it makes all elements generators (except 0 and 1 of course), which in turn makes some tests more effective. Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_data.py | 109 +++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 scripts/mbedtls_dev/bignum_data.py diff --git a/scripts/mbedtls_dev/bignum_data.py b/scripts/mbedtls_dev/bignum_data.py new file mode 100644 index 000000000..78fbb8c04 --- /dev/null +++ b/scripts/mbedtls_dev/bignum_data.py @@ -0,0 +1,109 @@ +"""Base values and datasets for bignum generated tests and helper functions that +produced them.""" +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import random + +# Functions calling these were used to produce test data and are here only for +# reproducability, they are not used by the test generation framework/classes +try: + from Cryptodome.Util.number import isPrime, getPrime #type: ignore #pylint: disable=import-error +except ImportError: + pass + +# Generated by bignum_common.gen_safe_prime(192,1) +SAFE_PRIME_192_BIT_SEED_1 = "d1c127a667786703830500038ebaef20e5a3e2dc378fb75b" + +# First number generated by random.getrandbits(192) - seed(2,2), not a prime +RANDOM_192_BIT_SEED_2_NO1 = "177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973" + +# Second number generated by random.getrandbits(192) - seed(2,2), not a prime +RANDOM_192_BIT_SEED_2_NO2 = "cf1822ffbc6887782b491044d5e341245c6e433715ba2bdd" + +# Third number generated by random.getrandbits(192) - seed(2,2), not a prime +RANDOM_192_BIT_SEED_2_NO3 = "3653f8dd9b1f282e4067c3584ee207f8da94e3e8ab73738f" + +# Fourth number generated by random.getrandbits(192) - seed(2,2), not a prime +RANDOM_192_BIT_SEED_2_NO4 = "ffed9235288bc781ae66267594c9c9500925e4749b575bd1" + +# Ninth number generated by random.getrandbits(192) - seed(2,2), not a prime +RANDOM_192_BIT_SEED_2_NO9 = "2a1be9cd8697bbd0e2520e33e44c50556c71c4a66148a86f" + +# Generated by bignum_common.gen_safe_prime(1024,3) +SAFE_PRIME_1024_BIT_SEED_3 = ("c93ba7ec74d96f411ba008bdb78e63ff11bb5df46a51e16b" + "2c9d156f8e4e18abf5e052cb01f47d0d1925a77f60991577" + "e128fb6f52f34a27950a594baadd3d8057abeb222cf3cca9" + "62db16abf79f2ada5bd29ab2f51244bf295eff9f6aaba130" + "2efc449b128be75eeaca04bc3c1a155d11d14e8be32a2c82" + "87b3996cf6ad5223") + +# First number generated by random.getrandbits(1024) - seed(4,2), not a prime +RANDOM_1024_BIT_SEED_4_NO1 = ("6905269ed6f0b09f165c8ce36e2f24b43000de01b2ed40ed" + "3addccb2c33be0ac79d679346d4ac7a5c3902b38963dc6e8" + "534f45738d048ec0f1099c6c3e1b258fd724452ccea71ff4" + "a14876aeaff1a098ca5996666ceab360512bd13110722311" + "710cf5327ac435a7a97c643656412a9b8a1abcd1a6916c74" + "da4f9fc3c6da5d7") + +# Second number generated by random.getrandbits(1024) - seed(4,2), not a prime +RANDOM_1024_BIT_SEED_4_NO2 = ("f1cfd99216df648647adec26793d0e453f5082492d83a823" + "3fb62d2c81862fc9634f806fabf4a07c566002249b191bf4" + "d8441b5616332aca5f552773e14b0190d93936e1daca3c06" + "f5ff0c03bb5d7385de08caa1a08179104a25e4664f5253a0" + "2a3187853184ff27459142deccea264542a00403ce80c4b0" + "a4042bb3d4341aad") + +# Third number generated by random.getrandbits(1024) - seed(4,2), not a prime +RANDOM_1024_BIT_SEED_4_NO3 = ("14c15c910b11ad28cc21ce88d0060cc54278c2614e1bcb38" + "3bb4a570294c4ea3738d243a6e58d5ca49c7b59b995253fd" + "6c79a3de69f85e3131f3b9238224b122c3e4a892d9196ada" + "4fcfa583e1df8af9b474c7e89286a1754abcb06ae8abb93f" + "01d89a024cdce7a6d7288ff68c320f89f1347e0cdd905ecf" + "d160c5d0ef412ed6") + +# Fourth number generated by random.getrandbits(1024) - seed(4,2), not a prime +RANDOM_1024_BIT_SEED_4_NO4 = ("32decd6b8efbc170a26a25c852175b7a96b98b5fbf37a2be" + "6f98bca35b17b9662f0733c846bbe9e870ef55b1a1f65507" + "a2909cb633e238b4e9dd38b869ace91311021c9e32111ac1" + "ac7cc4a4ff4dab102522d53857c49391b36cc9aa78a330a1" + "a5e333cb88dcf94384d4cd1f47ca7883ff5a52f1a05885ac" + "7671863c0bdbc23a") + +# Fifth number generated by random.getrandbits(1024) - seed(4,2), not a prime +RANDOM_1024_BIT_SEED_4_NO5 = ("53be4721f5b9e1f5acdac615bc20f6264922b9ccf469aef8" + "f6e7d078e55b85dd1525f363b281b8885b69dc230af5ac87" + "0692b534758240df4a7a03052d733dcdef40af2e54c0ce68" + "1f44ebd13cc75f3edcb285f89d8cf4d4950b16ffc3e1ac3b" + "4708d9893a973000b54a23020fc5b043d6e4a51519d9c9cc" + "52d32377e78131c1") + +def __gen_safe_prime(bits, seed): + ''' + Generate a safe prime. + + This function is intended for generating constants offline and shouldn't be + used in test generation classes. + + Requires pycryptodomex for getPrime and isPrime and python 3.9 or later for + randbytes. + ''' + rng = random.Random() + # We want reproducability across python versions + rng.seed(seed, version=2) + while True: + prime = 2*getPrime(bits-1, rng.randbytes)+1 #pylint: disable=no-member + if isPrime(prime, 1e-30): + return prime From dac44e6021f0653352ef81611738f8cbf432543d Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Sun, 20 Nov 2022 11:58:12 +0000 Subject: [PATCH 49/69] Bignum tests: add default datasets Add data for small values, 192 bit and 1024 bit values, primes, non-primes odd, even, and some typical corner cases. All subclasses override this for the time being so there are no changes to the test cases. Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 5 +++-- scripts/mbedtls_dev/bignum_data.py | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index b68653a03..e03c1c3f8 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -20,6 +20,7 @@ from itertools import chain from . import test_case from . import test_data_generation +from .bignum_data import INPUTS_DEFAULT, MODULI_DEFAULT T = TypeVar('T') #pylint: disable=invalid-name @@ -90,7 +91,7 @@ class OperationCommon(test_data_generation.BaseTest): values are 1 and 2. """ symbol = "" - input_values = [] # type: List[str] + input_values = INPUTS_DEFAULT # type: List[str] input_cases = [] # type: List[Any] unique_combinations_only = True input_styles = ["variable", "fixed", "arch_split"] # type: List[str] @@ -240,7 +241,7 @@ class OperationCommon(test_data_generation.BaseTest): class ModOperationCommon(OperationCommon): #pylint: disable=abstract-method """Target for bignum mod_raw test case generation.""" - moduli = [] # type: List[str] + moduli = MODULI_DEFAULT # type: List[str] def __init__(self, val_n: str, val_a: str, val_b: str = "0", bits_in_limb: int = 64) -> None: diff --git a/scripts/mbedtls_dev/bignum_data.py b/scripts/mbedtls_dev/bignum_data.py index 78fbb8c04..74d21d0ca 100644 --- a/scripts/mbedtls_dev/bignum_data.py +++ b/scripts/mbedtls_dev/bignum_data.py @@ -90,6 +90,33 @@ RANDOM_1024_BIT_SEED_4_NO5 = ("53be4721f5b9e1f5acdac615bc20f6264922b9ccf469aef8" "4708d9893a973000b54a23020fc5b043d6e4a51519d9c9cc" "52d32377e78131c1") +# Adding 192 bit and 1024 bit numbers because these are the shortest required +# for ECC and RSA respectively. +INPUTS_DEFAULT = [ + "0", "1", # corner cases + "2", "3", # small primes + "4", # non-prime even + "38", # small random + SAFE_PRIME_192_BIT_SEED_1, # prime + RANDOM_192_BIT_SEED_2_NO1, # not a prime + RANDOM_192_BIT_SEED_2_NO2, # not a prime + SAFE_PRIME_1024_BIT_SEED_3, # prime + RANDOM_1024_BIT_SEED_4_NO1, # not a prime + RANDOM_1024_BIT_SEED_4_NO3, # not a prime + RANDOM_1024_BIT_SEED_4_NO2, # largest (not a prime) + ] + +# Only odd moduli are present as in the new bignum code only odd moduli are +# supported for now. +MODULI_DEFAULT = [ + "53", # safe prime + "45", # non-prime + SAFE_PRIME_192_BIT_SEED_1, # safe prime + RANDOM_192_BIT_SEED_2_NO4, # not a prime + SAFE_PRIME_1024_BIT_SEED_3, # safe prime + RANDOM_1024_BIT_SEED_4_NO5, # not a prime + ] + def __gen_safe_prime(bits, seed): ''' Generate a safe prime. From be5e7aea7ceefc27dd69f405da1ed76170ba231c Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Sun, 20 Nov 2022 12:45:58 +0000 Subject: [PATCH 50/69] Bignum tests: remove deprecated dataset Remove old dataset that was overriding the defaults in bignum_core. This will change the datasets for core_sub and core_add to the default inherited from bignum_common. Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_core.py | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_core.py b/scripts/mbedtls_dev/bignum_core.py index 1bfc652ef..deff6a8a6 100644 --- a/scripts/mbedtls_dev/bignum_core.py +++ b/scripts/mbedtls_dev/bignum_core.py @@ -107,31 +107,9 @@ class BignumCoreCTLookup(BignumCoreTarget, test_data_generation.BaseTest): .create_test_case()) -INPUT_VALUES = [ - "0", "1", "3", "f", "fe", "ff", "100", "ff00", "fffe", "ffff", "10000", - "fffffffe", "ffffffff", "100000000", "1f7f7f7f7f7f7f", - "8000000000000000", "fefefefefefefefe", "fffffffffffffffe", - "ffffffffffffffff", "10000000000000000", "1234567890abcdef0", - "fffffffffffffffffefefefefefefefe", "fffffffffffffffffffffffffffffffe", - "ffffffffffffffffffffffffffffffff", "100000000000000000000000000000000", - "1234567890abcdef01234567890abcdef0", - "fffffffffffffffffffffffffffffffffffffffffffffffffefefefefefefefe", - "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "10000000000000000000000000000000000000000000000000000000000000000", - "1234567890abcdef01234567890abcdef01234567890abcdef01234567890abcdef0", - ( - "4df72d07b4b71c8dacb6cffa954f8d88254b6277099308baf003fab73227f34029" - "643b5a263f66e0d3c3fa297ef71755efd53b8fb6cb812c6bbf7bcf179298bd9947" - "c4c8b14324140a2c0f5fad7958a69050a987a6096e9f055fb38edf0c5889eca4a0" - "cfa99b45fbdeee4c696b328ddceae4723945901ec025076b12b" - ) -] - class BignumCoreOperation(BignumCoreTarget, bignum_common.OperationCommon): #pylint: disable=abstract-method """Common features for bignum core operations.""" - input_values = INPUT_VALUES class BignumCoreAddAndAddIf(BignumCoreOperation): From 76c21bd2421cd8ecb0bcd31c095399f31cb9da2e Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Sun, 20 Nov 2022 12:52:53 +0000 Subject: [PATCH 51/69] Bignum tests: flatten class hierarchy in _core There is no semantic changes to the generated tests, the order of the test blocks has changed. Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_core.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_core.py b/scripts/mbedtls_dev/bignum_core.py index deff6a8a6..806e13193 100644 --- a/scripts/mbedtls_dev/bignum_core.py +++ b/scripts/mbedtls_dev/bignum_core.py @@ -107,12 +107,7 @@ class BignumCoreCTLookup(BignumCoreTarget, test_data_generation.BaseTest): .create_test_case()) -class BignumCoreOperation(BignumCoreTarget, bignum_common.OperationCommon): - #pylint: disable=abstract-method - """Common features for bignum core operations.""" - - -class BignumCoreAddAndAddIf(BignumCoreOperation): +class BignumCoreAddAndAddIf(BignumCoreTarget, bignum_common.OperationCommon): """Test cases for bignum core add and add-if.""" count = 0 symbol = "+" @@ -131,7 +126,7 @@ class BignumCoreAddAndAddIf(BignumCoreOperation): ] -class BignumCoreSub(BignumCoreOperation): +class BignumCoreSub(BignumCoreTarget, bignum_common.OperationCommon): """Test cases for bignum core sub.""" count = 0 symbol = "-" @@ -157,7 +152,7 @@ class BignumCoreSub(BignumCoreOperation): ] -class BignumCoreMLA(BignumCoreOperation): +class BignumCoreMLA(BignumCoreTarget, bignum_common.OperationCommon): """Test cases for fixed-size multiply accumulate.""" count = 0 test_function = "mpi_core_mla" From f45797652fef6a53a11bd760c76e3f987f03a901 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Sun, 20 Nov 2022 13:32:54 +0000 Subject: [PATCH 52/69] Bignum tests: set unique combinations off by default Normally we need all the combinations, unique combinations make sense only if the operation is commutative. No changes to generated tests. Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_common.py | 2 +- scripts/mbedtls_dev/bignum_core.py | 3 +-- tests/scripts/generate_bignum_tests.py | 1 + 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index e03c1c3f8..67ea78db4 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -93,7 +93,7 @@ class OperationCommon(test_data_generation.BaseTest): symbol = "" input_values = INPUTS_DEFAULT # type: List[str] input_cases = [] # type: List[Any] - unique_combinations_only = True + unique_combinations_only = False input_styles = ["variable", "fixed", "arch_split"] # type: List[str] input_style = "variable" # type: str limb_sizes = [32, 64] # type: List[int] diff --git a/scripts/mbedtls_dev/bignum_core.py b/scripts/mbedtls_dev/bignum_core.py index 806e13193..4910daea8 100644 --- a/scripts/mbedtls_dev/bignum_core.py +++ b/scripts/mbedtls_dev/bignum_core.py @@ -114,6 +114,7 @@ class BignumCoreAddAndAddIf(BignumCoreTarget, bignum_common.OperationCommon): test_function = "mpi_core_add_and_add_if" test_name = "mpi_core_add_and_add_if" input_style = "arch_split" + unique_combinations_only = True def result(self) -> List[str]: result = self.int_a + self.int_b @@ -132,7 +133,6 @@ class BignumCoreSub(BignumCoreTarget, bignum_common.OperationCommon): symbol = "-" test_function = "mpi_core_sub" test_name = "mbedtls_mpi_core_sub" - unique_combinations_only = False def result(self) -> List[str]: if self.int_a >= self.int_b: @@ -157,7 +157,6 @@ class BignumCoreMLA(BignumCoreTarget, bignum_common.OperationCommon): count = 0 test_function = "mpi_core_mla" test_name = "mbedtls_mpi_core_mla" - unique_combinations_only = False input_values = [ "0", "1", "fffe", "ffffffff", "100000000", "20000000000000", diff --git a/tests/scripts/generate_bignum_tests.py b/tests/scripts/generate_bignum_tests.py index 89d0ac29e..c3058e98a 100755 --- a/tests/scripts/generate_bignum_tests.py +++ b/tests/scripts/generate_bignum_tests.py @@ -78,6 +78,7 @@ class BignumOperation(bignum_common.OperationCommon, BignumTarget, metaclass=ABCMeta): #pylint: disable=abstract-method """Common features for bignum operations in legacy tests.""" + unique_combinations_only = True input_values = [ "", "0", "-", "-0", "7b", "-7b", From f352c67bc30e48c4162126f340e247d5835b8627 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Sun, 20 Nov 2022 13:40:25 +0000 Subject: [PATCH 53/69] Bignum tests: use default dataset in mod_raw While at it, flatten class hierarchy as well. Signed-off-by: Janos Follath --- scripts/mbedtls_dev/bignum_mod_raw.py | 79 ++------------------------- 1 file changed, 5 insertions(+), 74 deletions(-) diff --git a/scripts/mbedtls_dev/bignum_mod_raw.py b/scripts/mbedtls_dev/bignum_mod_raw.py index b23fbb2dc..60f2feded 100644 --- a/scripts/mbedtls_dev/bignum_mod_raw.py +++ b/scripts/mbedtls_dev/bignum_mod_raw.py @@ -49,98 +49,29 @@ class BignumModRawTarget(test_data_generation.BaseTarget): # END MERGE SLOT 6 # BEGIN MERGE SLOT 7 + class BignumModRawConvertToMont(bignum_common.ModOperationCommon, BignumModRawTarget): """ Test cases for mpi_mod_raw_to_mont_rep(). """ - test_function = "mpi_mod_raw_to_mont_rep" test_name = "Convert into Mont: " symbol = "R *" input_style = "arch_split" arity = 1 - moduli = ["b", - "fd", - "eeff99aa37", - "eeff99aa11", - "800000000005", - "7fffffffffffffff", - "80fe000a10000001", - "25a55a46e5da99c71c7", - "1058ad82120c3a10196bb36229c1", - "7e35b84cb19ea5bc57ec37f5e431462fa962d98c1e63738d4657f" - "18ad6532e6adc3eafe67f1e5fa262af94cee8d3e7268593942a2a" - "98df75154f8c914a282f8b", - "8335616aed761f1f7f44e6bd49e807b82e3bf2bf11bfa63", - "ffcece570f2f991013f26dd5b03c4c5b65f97be5905f36cb4664f" - "2c78ff80aa8135a4aaf57ccb8a0aca2f394909a74cef1ef6758a6" - "4d11e2c149c393659d124bfc94196f0ce88f7d7d567efa5a649e2" - "deefaa6e10fdc3deac60d606bf63fc540ac95294347031aefd73d" - "6a9ee10188aaeb7a90d920894553cb196881691cadc51808715a0" - "7e8b24fcb1a63df047c7cdf084dd177ba368c806f3d51ddb5d389" - "8c863e687ecaf7d649a57a46264a582f94d3c8f2edaf59f77a7f6" - "bdaf83c991e8f06abe220ec8507386fce8c3da84c6c3903ab8f3a" - "d4630a204196a7dbcbd9bcca4e40ec5cc5c09938d49f5e1e6181d" - "b8896f33bb12e6ef73f12ec5c5ea7a8a337" - ] - - input_values = ["0", - "1", - "97", - "f5", - "6f5c3", - "745bfe50f7", - "ffa1f9924123", - "334a8b983c79bd", - "5b84f632b58f3461", - "19acd15bc38008e1", - "ffffffffffffffff", - "54ce6a6bb8247fa0427cfc75a6b0599", - "fecafe8eca052f154ce6a6bb8247fa019558bfeecce9bb9", - "a87d7a56fa4bfdc7da42ef798b9cf6843d4c54794698cb14d72" - "851dec9586a319f4bb6d5695acbd7c92e7a42a5ede6972adcbc" - "f68425265887f2d721f462b7f1b91531bac29fa648facb8e3c6" - "1bd5ae42d5a59ba1c89a95897bfe541a8ce1d633b98f379c481" - "6f25e21f6ac49286b261adb4b78274fe5f61c187581f213e84b" - "2a821e341ef956ecd5de89e6c1a35418cd74a549379d2d4594a" - "577543147f8e35b3514e62cf3e89d1156cdc91ab5f4c928fbd6" - "9148c35df5962fed381f4d8a62852a36823d5425f7487c13a12" - "523473fb823aa9d6ea5f42e794e15f2c1a8785cf6b7d51a4617" - "947fb3baf674f74a673cf1d38126983a19ed52c7439fab42c2185" - ] - def result(self) -> List[str]: result = (self.int_a * self.r) % self.int_n return [self.format_result(result)] -class BignumModRawConvertFromMont(BignumModRawConvertToMont): +class BignumModRawConvertFromMont(bignum_common.ModOperationCommon, + BignumModRawTarget): """ Test cases for mpi_mod_raw_from_mont_rep(). """ - count = 0 test_function = "mpi_mod_raw_from_mont_rep" test_name = "Convert from Mont: " symbol = "1/R *" - - input_values = ["0", - "1", - "3ca", - "539ed428", - "7dfe5c6beb35a2d6", - "dca8de1c2adfc6d7aafb9b48e", - "a7d17b6c4be72f3d5c16bf9c1af6fc933", - "2fec97beec546f9553142ed52f147845463f579", - "378dc83b8bc5a7b62cba495af4919578dce6d4f175cadc4f", - "b6415f2a1a8e48a518345db11f56db3829c8f2c6415ab4a395a" - "b3ac2ea4cbef4af86eb18a84eb6ded4c6ecbfc4b59c2879a675" - "487f687adea9d197a84a5242a5cf6125ce19a6ad2e7341f1c57" - "d43ea4f4c852a51cb63dabcd1c9de2b827a3146a3d175b35bea" - "41ae75d2a286a3e9d43623152ac513dcdea1d72a7da846a8ab3" - "58d9be4926c79cfb287cf1cf25b689de3b912176be5dcaf4d4c" - "6e7cb839a4a3243a6c47c1e2c99d65c59d6fa3672575c2f1ca8" - "de6a32e854ec9d8ec635c96af7679fce26d7d159e4a9da3bd74" - "e1272c376cd926d74fe3fb164a5935cff3d5cdb92b35fe2cea32" - "138a7e6bfbc319ebd1725dacb9a359cbf693f2ecb785efb9d627" - ] + input_style = "arch_split" + arity = 1 def result(self) -> List[str]: result = (self.int_a * self.r_inv) % self.int_n From 79f6b6bb1bcbef2fb783cb43724903dea30377f7 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 21 Nov 2022 14:17:03 +0100 Subject: [PATCH 54/69] tls: psa_pake: fixing mbedtls_psa_ecjpake_write_round() It might happen that the psa_pake_output() function returns elements which are not exactly 32 or 65 bytes as expected, but 1 bytes less. As a consequence, insted of hardcoding the expected value for the length in the output buffer, we write the correct one as obtained from psa_pake_output() Signed-off-by: Valerio Setti --- library/ssl_tls.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index c1436c532..7b51040c4 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -8259,20 +8259,27 @@ int mbedtls_psa_ecjpake_write_round( step <= PSA_PAKE_STEP_ZK_PROOF; ++step ) { - /* For each step, prepend 1 byte with the length of the data */ - *(buf + output_offset) = MBEDTLS_SSL_ECJPAKE_OUTPUT_SIZE( step ); - output_offset += 1; - + /* + * For each step, prepend 1 byte with the length of the data. + * + * NOTE = psa_pake_output() sometimes output elements which are + * NOT 32 or 65 bytes as expected, but 1 byte less. So, instead + * of hardcoding the expected length, we + * - get the output first + * - then write the length of this output + */ status = psa_pake_output( pake_ctx, step, - buf + output_offset, - len - output_offset, + buf + output_offset + 1, + len - output_offset - 1, &output_len ); if( status != PSA_SUCCESS ) { return( psa_ssl_status_to_mbedtls( status ) ); } - output_offset += output_len; + *(buf + output_offset) = output_len; + + output_offset += output_len + 1; } } From 5151bdf46eb83823c4946c500c48bbad3b8f76e7 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 21 Nov 2022 14:30:02 +0100 Subject: [PATCH 55/69] tls: psa_pake: add missing braces Signed-off-by: Valerio Setti --- library/ssl_tls12_client.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index 7c293ec9e..5ff8ab4b8 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -2354,7 +2354,9 @@ start_processing: if( ( *p != MBEDTLS_ECP_TLS_NAMED_CURVE ) || ( read_tls_id != curve_info->tls_id ) ) + { return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER ); + } p += 3; From fdd24b8c496449abc1e024857d582ea8b6b4b4b4 Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Tue, 22 Nov 2022 13:12:56 +0800 Subject: [PATCH 56/69] Revert change in flight transmit Signed-off-by: Jerry Yu --- library/ssl_msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ssl_msg.c b/library/ssl_msg.c index cacedcaf9..80471d4c5 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -2343,7 +2343,7 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ) return( ret ); /* Update state and set timer */ - if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) + if( mbedtls_ssl_is_handshake_over( ssl ) == 1 ) ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; else { From c2e110f44577908617815915f52793c6c39483f0 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 22 Nov 2022 09:01:46 +0100 Subject: [PATCH 57/69] tls13: Disable MBEDTLS_SSL_EARLY_DATA by default Eventually we want it to be enabled by default when TLS 1.3 is enabled but currently the feature is on development thus it should not be enabled by default. Signed-off-by: Ronald Cron --- include/mbedtls/mbedtls_config.h | 2 +- tests/scripts/all.sh | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h index 3f869b9ff..12d503e38 100644 --- a/include/mbedtls/mbedtls_config.h +++ b/include/mbedtls/mbedtls_config.h @@ -1648,7 +1648,7 @@ * production. * */ -#define MBEDTLS_SSL_EARLY_DATA +//#define MBEDTLS_SSL_EARLY_DATA /** * \def MBEDTLS_SSL_PROTO_DTLS diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 8272dcc31..3a69fd7d7 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -3250,6 +3250,7 @@ component_build_armcc () { component_test_tls13_only () { msg "build: default config with MBEDTLS_SSL_PROTO_TLS1_3, without MBEDTLS_SSL_PROTO_TLS1_2" + scripts/config.py set MBEDTLS_SSL_EARLY_DATA make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'" msg "test: TLS 1.3 only, all key exchange modes enabled" @@ -3269,6 +3270,7 @@ component_test_tls13_only_psk () { scripts/config.py unset MBEDTLS_SSL_SERVER_NAME_INDICATION scripts/config.py unset MBEDTLS_ECDSA_C scripts/config.py unset MBEDTLS_PKCS1_V21 + scripts/config.py set MBEDTLS_SSL_EARLY_DATA make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'" msg "test_suite_ssl: TLS 1.3 only, only PSK key exchange mode enabled" @@ -3301,6 +3303,7 @@ component_test_tls13_only_psk_ephemeral () { scripts/config.py unset MBEDTLS_SSL_SERVER_NAME_INDICATION scripts/config.py unset MBEDTLS_ECDSA_C scripts/config.py unset MBEDTLS_PKCS1_V21 + scripts/config.py set MBEDTLS_SSL_EARLY_DATA make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'" msg "test_suite_ssl: TLS 1.3 only, only PSK ephemeral key exchange mode" @@ -3318,6 +3321,7 @@ component_test_tls13_only_psk_all () { scripts/config.py unset MBEDTLS_SSL_SERVER_NAME_INDICATION scripts/config.py unset MBEDTLS_ECDSA_C scripts/config.py unset MBEDTLS_PKCS1_V21 + scripts/config.py set MBEDTLS_SSL_EARLY_DATA make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'" msg "test_suite_ssl: TLS 1.3 only, PSK and PSK ephemeral key exchange modes" @@ -3330,6 +3334,7 @@ component_test_tls13_only_psk_all () { component_test_tls13_only_ephemeral_all () { msg "build: TLS 1.3 only from default, without PSK key exchange mode" scripts/config.py unset MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED + scripts/config.py set MBEDTLS_SSL_EARLY_DATA make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'" msg "test_suite_ssl: TLS 1.3 only, ephemeral and PSK ephemeral key exchange modes" @@ -3344,6 +3349,7 @@ component_test_tls13 () { scripts/config.py set MBEDTLS_SSL_PROTO_TLS1_3 scripts/config.py set MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE scripts/config.py set MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY 1 + scripts/config.py set MBEDTLS_SSL_EARLY_DATA CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . make msg "test: default config with MBEDTLS_SSL_PROTO_TLS1_3 enabled, without padding" @@ -3357,6 +3363,7 @@ component_test_tls13_no_compatibility_mode () { scripts/config.py set MBEDTLS_SSL_PROTO_TLS1_3 scripts/config.py unset MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE scripts/config.py set MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY 1 + scripts/config.py set MBEDTLS_SSL_EARLY_DATA CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . make msg "test: default config with MBEDTLS_SSL_PROTO_TLS1_3 enabled, without padding" From 8bee89994dbcc119812ac81102eb22e959cf9093 Mon Sep 17 00:00:00 2001 From: Xiaokang Qian Date: Thu, 27 Oct 2022 10:21:05 +0000 Subject: [PATCH 58/69] Add parse function for early data in encrypted extentions Signed-off-by: Xiaokang Qian --- library/ssl_tls13_client.c | 63 +++++++++++++++++++++++++++++++ tests/opt-testcases/tls13-misc.sh | 4 +- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 0372f2d98..839fe3679 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -1335,6 +1335,53 @@ static int ssl_tls13_is_downgrade_negotiation( mbedtls_ssl_context *ssl, return( 0 ); } +#if defined(MBEDTLS_SSL_EARLY_DATA) +/* + * ssl_tls13_parse_ee_early_data_ext() + * Parse early data indication extension in EncryptedExtensions. + * + * struct {} Empty; + * + * struct { + * select (Handshake.msg_type) { + * ... + * case client_hello: Empty; + * case encrypted_extensions: Empty; + * }; + * } EarlyDataIndication; + * + */ + +MBEDTLS_CHECK_RETURN_CRITICAL +static int ssl_tls13_parse_ee_early_data_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + if( ssl->early_data_status < MBEDTLS_SSL_EARLY_DATA_STATUS_INDICATION_SENT ) + { + /* The server must not send the EarlyDataIndication if the + * client hasn't indicated the use of early data. */ + MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, + MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER ); + return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER ); + } + + if( len != 0 ) + { + /* The message must be empty. */ + MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, + MBEDTLS_ERR_SSL_DECODE_ERROR ); + return( MBEDTLS_ERR_SSL_DECODE_ERROR ); + } + + /* Nothing to parse */ + ((void) buf); + + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED; + return( 0 ); +} +#endif /* MBEDTLS_SSL_EARLY_DATA */ + /* Returns a negative value on failure, and otherwise * - SSL_SERVER_HELLO or * - SSL_SERVER_HELLO_HRR @@ -2060,6 +2107,22 @@ static int ssl_tls13_parse_encrypted_extensions( mbedtls_ssl_context *ssl, break; #endif /* MBEDTLS_SSL_ALPN */ + +#if defined(MBEDTLS_SSL_EARLY_DATA) + case MBEDTLS_TLS_EXT_EARLY_DATA: + ret = ssl_tls13_parse_ee_early_data_ext( + ssl, p, (size_t)extension_data_len ); + if( ret != 0 ) + { + ssl->early_data_status = + MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED; + MBEDTLS_SSL_DEBUG_RET( + 1, "ssl_tls13_parse_ee_early_data_ext", ret ); + return( ret ); + } + break; +#endif /* MBEDTLS_SSL_EARLY_DATA */ + default: MBEDTLS_SSL_PRINT_EXT( 3, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh index edece456b..ed428480c 100755 --- a/tests/opt-testcases/tls13-misc.sh +++ b/tests/opt-testcases/tls13-misc.sh @@ -301,7 +301,7 @@ run_test "TLS 1.3 m->G: EarlyData: basic check, good" \ -c "NewSessionTicket: early_data(42) extension received." \ -c "ClientHello: early_data(42) extension exists." \ -c "EncryptedExtensions: early_data(42) extension received." \ - -c "EncryptedExtensions: early_data(42) extension ( ignored )." \ + -c "EncryptedExtensions: early_data(42) extension exists." \ -s "Parsing extension 'Early Data/42' (0 bytes)" \ -s "Sending extension Early Data/42 (0 bytes)" \ -s "early data accepted" @@ -322,7 +322,7 @@ run_test "TLS 1.3 m->G: EarlyData: no early_data in NewSessionTicket, good" \ -C "NewSessionTicket: early_data(42) extension received." \ -c "ClientHello: early_data(42) extension does not exist." \ -C "EncryptedExtensions: early_data(42) extension received." \ - -C "EncryptedExtensions: early_data(42) extension ( ignored )." + -C "EncryptedExtensions: early_data(42) extension exists." #TODO: OpenSSL tests don't work now. It might be openssl options issue, cause GnuTLS has worked. skip_next_test From d4a9b1ab8d124eaf7bff20d4bfe078f4ddc09483 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 22 Nov 2022 11:11:10 +0100 Subject: [PATCH 59/69] tls: psa_pake: remove useless defines and fix a comment Signed-off-by: Valerio Setti --- library/ssl_misc.h | 11 ----------- library/ssl_tls.c | 9 ++------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 0f43a18f4..2ff7e0c22 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2367,17 +2367,6 @@ static inline int psa_ssl_status_to_mbedtls( psa_status_t status ) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ defined(MBEDTLS_USE_PSA_CRYPTO) -/* Currently JPAKE only supports elliptic curve secp256r1 */ -#define MBEDTLS_SSL_ECJPAKE_PSA_PRIMITIVE \ - PSA_PAKE_PRIMITIVE( PSA_PAKE_PRIMITIVE_TYPE_ECC, \ - PSA_ECC_FAMILY_SECP_R1, 256 ) - -/* Expected output data size for each "step" of EC-JPAKE key echange */ -#define MBEDTLS_SSL_ECJPAKE_OUTPUT_SIZE( step ) \ - PSA_PAKE_OUTPUT_SIZE( PSA_ALG_JPAKE, \ - MBEDTLS_SSL_ECJPAKE_PSA_PRIMITIVE, \ - step ) - typedef enum { MBEDTLS_ECJPAKE_ROUND_ONE, MBEDTLS_ECJPAKE_ROUND_TWO diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 7b51040c4..5bfdde7bc 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -8260,13 +8260,8 @@ int mbedtls_psa_ecjpake_write_round( ++step ) { /* - * For each step, prepend 1 byte with the length of the data. - * - * NOTE = psa_pake_output() sometimes output elements which are - * NOT 32 or 65 bytes as expected, but 1 byte less. So, instead - * of hardcoding the expected length, we - * - get the output first - * - then write the length of this output + * For each step, prepend 1 byte with the length of the data as + * given by psa_pake_output(). */ status = psa_pake_output( pake_ctx, step, buf + output_offset + 1, From da13072c5bfc56a04ec5bb0bf0ab464889d3699b Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 22 Nov 2022 09:08:57 +0100 Subject: [PATCH 60/69] tls13: Make ..._RECEIVED_NEW_SESSION_TICKET experimental We are considering using a callback instead. Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index d0558511a..94bbee59b 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -96,7 +96,10 @@ /* Error space gap */ /** Processing of the Certificate handshake message failed. */ #define MBEDTLS_ERR_SSL_BAD_CERTIFICATE -0x7A00 -/** Received NewSessionTicket Post Handshake Message */ +/** + * Received NewSessionTicket Post Handshake Message. + * This error code is experimental and may be changed or removed without notice. + */ #define MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET -0x7B00 /* Error space gap */ /* Error space gap */ From d9b2348d8f66553a03b9f95c10d7e0768d2988b4 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Thu, 25 Aug 2022 08:25:19 +0100 Subject: [PATCH 61/69] Extract MPI_CORE(sub_int) from the prototype Signed-off-by: Tom Cosgrove --- library/bignum_core.c | 15 +++++++++++++++ library/bignum_core.h | 18 ++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/library/bignum_core.c b/library/bignum_core.c index 34aecda50..0315c84f9 100644 --- a/library/bignum_core.c +++ b/library/bignum_core.c @@ -590,6 +590,21 @@ cleanup: /* BEGIN MERGE SLOT 3 */ +mbedtls_mpi_uint MPI_CORE(sub_int)( mbedtls_mpi_uint *d, + const mbedtls_mpi_uint *l, + mbedtls_mpi_uint c, size_t n ) +{ + for( size_t i = 0; i < n; i++ ) + { + mbedtls_mpi_uint s, t; + s = l[i]; + t = s - c; c = ( t > s ); + d[i] = t; + } + + return( c ); +} + /* END MERGE SLOT 3 */ /* BEGIN MERGE SLOT 4 */ diff --git a/library/bignum_core.h b/library/bignum_core.h index ad04e0828..68b4bd144 100644 --- a/library/bignum_core.h +++ b/library/bignum_core.h @@ -504,6 +504,24 @@ int mbedtls_mpi_core_fill_random( mbedtls_mpi_uint *X, size_t X_limbs, /* BEGIN MERGE SLOT 3 */ +#define MPI_CORE(func) mbedtls_mpi_core_ ## func ## _minimal + +/** + * \brief Subtract unsigned integer from known-size large unsigned integers. + * Return the borrow. + * + * \param[out] d The result of the subtraction. + * \param[in] l The left operand. + * \param[in] r The unsigned scalar to subtract. + * \param n Number of limbs of \p d and \p l. + * + * \return 1 if `l < r`. + * 0 if `l >= r`. + */ +mbedtls_mpi_uint MPI_CORE(sub_int)( mbedtls_mpi_uint *d, + const mbedtls_mpi_uint *l, + mbedtls_mpi_uint r, size_t n ); + /* END MERGE SLOT 3 */ /* BEGIN MERGE SLOT 4 */ From f7ff4c9a112bf0a56ee1c8ee7f1c02cb87a81857 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Thu, 25 Aug 2022 08:39:07 +0100 Subject: [PATCH 62/69] Tidy up, remove MPI_CORE(), and apply the naming convention Signed-off-by: Tom Cosgrove --- library/bignum_core.c | 17 +++++++++-------- library/bignum_core.h | 21 ++++++++++----------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/library/bignum_core.c b/library/bignum_core.c index 0315c84f9..41d323968 100644 --- a/library/bignum_core.c +++ b/library/bignum_core.c @@ -590,16 +590,17 @@ cleanup: /* BEGIN MERGE SLOT 3 */ -mbedtls_mpi_uint MPI_CORE(sub_int)( mbedtls_mpi_uint *d, - const mbedtls_mpi_uint *l, - mbedtls_mpi_uint c, size_t n ) +mbedtls_mpi_uint mbedtls_mpi_core_sub_int( mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + mbedtls_mpi_uint c, /* doubles as carry */ + size_t limbs ) { - for( size_t i = 0; i < n; i++ ) + for( size_t i = 0; i < limbs; i++ ) { - mbedtls_mpi_uint s, t; - s = l[i]; - t = s - c; c = ( t > s ); - d[i] = t; + mbedtls_mpi_uint s = A[i]; + mbedtls_mpi_uint t = s - c; + c = ( t > s ); + X[i] = t; } return( c ); diff --git a/library/bignum_core.h b/library/bignum_core.h index 68b4bd144..d48e7053b 100644 --- a/library/bignum_core.h +++ b/library/bignum_core.h @@ -504,23 +504,22 @@ int mbedtls_mpi_core_fill_random( mbedtls_mpi_uint *X, size_t X_limbs, /* BEGIN MERGE SLOT 3 */ -#define MPI_CORE(func) mbedtls_mpi_core_ ## func ## _minimal - /** * \brief Subtract unsigned integer from known-size large unsigned integers. * Return the borrow. * - * \param[out] d The result of the subtraction. - * \param[in] l The left operand. - * \param[in] r The unsigned scalar to subtract. - * \param n Number of limbs of \p d and \p l. + * \param[out] X The result of the subtraction. + * \param[in] A The left operand. + * \param b The unsigned scalar to subtract. + * \param limbs Number of limbs of \p X and \p A. * - * \return 1 if `l < r`. - * 0 if `l >= r`. + * \return 1 if `A < b`. + * 0 if `A >= b`. */ -mbedtls_mpi_uint MPI_CORE(sub_int)( mbedtls_mpi_uint *d, - const mbedtls_mpi_uint *l, - mbedtls_mpi_uint r, size_t n ); +mbedtls_mpi_uint mbedtls_mpi_core_sub_int( mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + mbedtls_mpi_uint b, + size_t limbs ); /* END MERGE SLOT 3 */ From 452c99c17331b1d5a718d2b70080c1608f0c50f3 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Thu, 25 Aug 2022 10:07:07 +0100 Subject: [PATCH 63/69] Use mbedtls_mpi_core_sub_int() in mbedtls_mpi_sub_abs() Signed-off-by: Tom Cosgrove --- library/bignum.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/library/bignum.c b/library/bignum.c index ba0398825..a68957a53 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -968,17 +968,15 @@ int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi carry = mbedtls_mpi_core_sub( X->p, A->p, B->p, n ); if( carry != 0 ) { - /* Propagate the carry to the first nonzero limb of X. */ - for( ; n < X->n && X->p[n] == 0; n++ ) - --X->p[n]; - /* If we ran out of space for the carry, it means that the result - * is negative. */ - if( n == X->n ) + /* Propagate the carry through the rest of X. */ + carry = mbedtls_mpi_core_sub_int( X->p + n, X->p + n, carry, X->n - n ); + + /* If we have further carry/borrow, the result is negative. */ + if( carry != 0 ) { ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE; goto cleanup; } - --X->p[n]; } /* X should always be positive as a result of unsigned subtractions. */ From 99d88c1ab488c806b4919d50301c38488f1fb478 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 22 Nov 2022 16:03:43 +0100 Subject: [PATCH 64/69] tls: psa_pake: fix missing casting in mbedtls_psa_ecjpake_write_round Signed-off-by: Valerio Setti --- library/ssl_tls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 5bfdde7bc..4efcee067 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -8272,7 +8272,7 @@ int mbedtls_psa_ecjpake_write_round( return( psa_ssl_status_to_mbedtls( status ) ); } - *(buf + output_offset) = output_len; + *(buf + output_offset) = (uint8_t) output_len; output_offset += output_len + 1; } From d66d5b2fef284e46953bac5a0f7ebb8f35d0e15b Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Tue, 22 Nov 2022 15:07:31 +0000 Subject: [PATCH 65/69] Add unit tests for mbedtls_mpi_core_sub_int(), MPI A - scalar b Signed-off-by: Tom Cosgrove --- scripts/mbedtls_dev/bignum_core.py | 31 +++++++++++++ tests/suites/test_suite_bignum_core.function | 46 ++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/scripts/mbedtls_dev/bignum_core.py b/scripts/mbedtls_dev/bignum_core.py index 4910daea8..b8e2a3123 100644 --- a/scripts/mbedtls_dev/bignum_core.py +++ b/scripts/mbedtls_dev/bignum_core.py @@ -763,6 +763,37 @@ def mpi_modmul_case_generate() -> None: # BEGIN MERGE SLOT 3 +class BignumCoreSubInt(BignumCoreTarget, bignum_common.OperationCommon): + """Test cases for bignum core sub int.""" + count = 0 + symbol = "-" + test_function = "mpi_core_sub_int" + test_name = "mpi_core_sub_int" + input_style = "arch_split" + + @property + def is_valid(self) -> bool: + # This is "sub int", so b is only one limb + if bignum_common.limbs_mpi(self.int_b, self.bits_in_limb) > 1: + return False + return True + + # Overriding because we don't want leading zeros on b + @property + def arg_b(self) -> str: + return self.val_b + + def result(self) -> List[str]: + result = self.int_a - self.int_b + + borrow, result = divmod(result, self.limb_boundary) + + # Borrow will be -1 if non-zero, but we want it to be 1 in the test data + return [ + self.format_result(result), + str(-borrow) + ] + # END MERGE SLOT 3 # BEGIN MERGE SLOT 4 diff --git a/tests/suites/test_suite_bignum_core.function b/tests/suites/test_suite_bignum_core.function index 612a7c6bd..d5bb42002 100644 --- a/tests/suites/test_suite_bignum_core.function +++ b/tests/suites/test_suite_bignum_core.function @@ -1049,6 +1049,52 @@ exit: /* BEGIN MERGE SLOT 3 */ +/* BEGIN_CASE */ +void mpi_core_sub_int( char * input_A, char * input_B, + char * input_X, int borrow ) +{ + /* We are testing A - b, where A is an MPI and b is a scalar, expecting + * result X with borrow borrow. However, for ease of handling we encode b + * as a 1-limb MPI (B) in the .data file. */ + + mbedtls_mpi_uint *A = NULL; + mbedtls_mpi_uint *B = NULL; + mbedtls_mpi_uint *X = NULL; + mbedtls_mpi_uint *R = NULL; + size_t A_limbs, B_limbs, X_limbs; + + TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &A, &A_limbs, input_A ) ); + TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &B, &B_limbs, input_B ) ); + TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &X, &X_limbs, input_X ) ); + + /* The MPI encoding of scalar b must be only 1 limb */ + TEST_EQUAL( B_limbs, 1 ); + + /* The subtraction is fixed-width, so A and X must have the same number of limbs */ + TEST_EQUAL( A_limbs, X_limbs ); + size_t limbs = A_limbs; + + ASSERT_ALLOC( R, limbs ); + +#define TEST_COMPARE_CORE_MPIS( A, B, limbs ) \ + ASSERT_COMPARE( A, (limbs) * sizeof(mbedtls_mpi_uint), B, (limbs) * sizeof(mbedtls_mpi_uint) ) + + /* 1. R = A - b. Result and borrow should be correct */ + TEST_EQUAL( mbedtls_mpi_core_sub_int( R, A, B[0], limbs ), borrow ); + TEST_COMPARE_CORE_MPIS( R, X, limbs ); + + /* 2. A = A - b. Result and borrow should be correct */ + TEST_EQUAL( mbedtls_mpi_core_sub_int( A, A, B[0], limbs ), borrow ); + TEST_COMPARE_CORE_MPIS( A, X, limbs ); + +exit: + mbedtls_free( A ); + mbedtls_free( B ); + mbedtls_free( X ); + mbedtls_free( R ); +} +/* END_CASE */ + /* END MERGE SLOT 3 */ /* BEGIN MERGE SLOT 4 */ From ca09afc60ace53dca16e6d1bea697fc308165423 Mon Sep 17 00:00:00 2001 From: Xiaokang Qian Date: Tue, 22 Nov 2022 10:05:19 +0000 Subject: [PATCH 66/69] Remove useless function and parse early data in ee Signed-off-by: Xiaokang Qian --- library/ssl_tls13_client.c | 72 +++++++++----------------------------- 1 file changed, 17 insertions(+), 55 deletions(-) diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 839fe3679..9db2b7928 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -1335,53 +1335,6 @@ static int ssl_tls13_is_downgrade_negotiation( mbedtls_ssl_context *ssl, return( 0 ); } -#if defined(MBEDTLS_SSL_EARLY_DATA) -/* - * ssl_tls13_parse_ee_early_data_ext() - * Parse early data indication extension in EncryptedExtensions. - * - * struct {} Empty; - * - * struct { - * select (Handshake.msg_type) { - * ... - * case client_hello: Empty; - * case encrypted_extensions: Empty; - * }; - * } EarlyDataIndication; - * - */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_parse_ee_early_data_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - if( ssl->early_data_status < MBEDTLS_SSL_EARLY_DATA_STATUS_INDICATION_SENT ) - { - /* The server must not send the EarlyDataIndication if the - * client hasn't indicated the use of early data. */ - MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER ); - } - - if( len != 0 ) - { - /* The message must be empty. */ - MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, - MBEDTLS_ERR_SSL_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_DECODE_ERROR ); - } - - /* Nothing to parse */ - ((void) buf); - - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED; - return( 0 ); -} -#endif /* MBEDTLS_SSL_EARLY_DATA */ - /* Returns a negative value on failure, and otherwise * - SSL_SERVER_HELLO or * - SSL_SERVER_HELLO_HRR @@ -2110,16 +2063,25 @@ static int ssl_tls13_parse_encrypted_extensions( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_SSL_EARLY_DATA) case MBEDTLS_TLS_EXT_EARLY_DATA: - ret = ssl_tls13_parse_ee_early_data_ext( - ssl, p, (size_t)extension_data_len ); - if( ret != 0 ) + if( ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_INDICATION_SENT ) { - ssl->early_data_status = - MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED; - MBEDTLS_SSL_DEBUG_RET( - 1, "ssl_tls13_parse_ee_early_data_ext", ret ); - return( ret ); + /* The server must not send the EarlyDataIndication if the + * client hasn't indicated the use of early data. */ + MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, + MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER ); + return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER ); } + + if( extension_data_len != 0 ) + { + /* The message must be empty. */ + MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, + MBEDTLS_ERR_SSL_DECODE_ERROR ); + return( MBEDTLS_ERR_SSL_DECODE_ERROR ); + } + + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED; + break; #endif /* MBEDTLS_SSL_EARLY_DATA */ From e861ba01d474034cbde57de9448d697daf8d8349 Mon Sep 17 00:00:00 2001 From: Xiaokang Qian Date: Wed, 23 Nov 2022 03:21:02 +0000 Subject: [PATCH 67/69] Remove the duplicate early_data_status check Signed-off-by: Xiaokang Qian --- library/ssl_tls13_client.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 9db2b7928..57d3adb71 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -2063,14 +2063,6 @@ static int ssl_tls13_parse_encrypted_extensions( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_SSL_EARLY_DATA) case MBEDTLS_TLS_EXT_EARLY_DATA: - if( ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_INDICATION_SENT ) - { - /* The server must not send the EarlyDataIndication if the - * client hasn't indicated the use of early data. */ - MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER ); - } if( extension_data_len != 0 ) { @@ -2080,7 +2072,7 @@ static int ssl_tls13_parse_encrypted_extensions( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_DECODE_ERROR ); } - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED; + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED; break; #endif /* MBEDTLS_SSL_EARLY_DATA */ From b157e915ad29e7e47443a2f624d9cb42c497d487 Mon Sep 17 00:00:00 2001 From: Xiaokang Qian Date: Wed, 23 Nov 2022 08:12:26 +0000 Subject: [PATCH 68/69] Move the early data status set afeter all of the extensions parse Signed-off-by: Xiaokang Qian --- library/ssl_tls13_client.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 57d3adb71..227c99d47 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -2072,8 +2072,6 @@ static int ssl_tls13_parse_encrypted_extensions( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_DECODE_ERROR ); } - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED; - break; #endif /* MBEDTLS_SSL_EARLY_DATA */ @@ -2119,6 +2117,14 @@ static int ssl_tls13_process_encrypted_extensions( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_PROC_CHK( ssl_tls13_parse_encrypted_extensions( ssl, buf, buf + buf_len ) ); +#if defined(MBEDTLS_SSL_EARLY_DATA) + if( ssl->handshake->received_extensions & + MBEDTLS_SSL_EXT_MASK( EARLY_DATA ) ) + { + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED; + } +#endif + mbedtls_ssl_add_hs_msg_to_checksum( ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, buf, buf_len ); From 4a8c9e2cff36efea58220d124f4850de67352f77 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 26 Oct 2022 18:49:09 +0200 Subject: [PATCH 69/69] tls13: Add definition of mbedtls_ssl_{write,read}_early_data Signed-off-by: Ronald Cron --- docs/architecture/tls13-support.md | 172 +++++++++++++++++++++++++++++ include/mbedtls/ssl.h | 162 +++++++++++++++++++++++++-- library/ssl_tls13_client.c | 8 +- 3 files changed, 326 insertions(+), 16 deletions(-) diff --git a/docs/architecture/tls13-support.md b/docs/architecture/tls13-support.md index f30590bd4..85482ba9e 100644 --- a/docs/architecture/tls13-support.md +++ b/docs/architecture/tls13-support.md @@ -478,3 +478,175 @@ outbound message on server side as well. * state change: the state change is done in the main state handler to ease the navigation of the state machine transitions. + + +Writing and reading early or 0-RTT data +--------------------------------------- + +An application function to write and send a buffer of data to a server through +TLS may plausibly look like: + +``` +int write_data( mbedtls_ssl_context *ssl, + const unsigned char *data_to_write, + size_t data_to_write_len, + size_t *data_written ) +{ + *data_written = 0; + + while( *data_written < data_to_write_len ) + { + ret = mbedtls_ssl_write( ssl, data_to_write + *data_written, + data_to_write_len - *data_written ); + + if( ret < 0 && + ret != MBEDTLS_ERR_SSL_WANT_READ && + ret != MBEDTLS_ERR_SSL_WANT_WRITE ) + { + return( ret ); + } + + *data_written += ret; + } + + return( 0 ); +} +``` +where ssl is the SSL context to use, data_to_write the address of the data +buffer and data_to_write_len the number of data bytes. The handshake may +not be completed, not even started for the SSL context ssl when the function is +called and in that case the mbedtls_ssl_write() API takes care transparently of +completing the handshake before to write and send data to the server. The +mbedtls_ssl_write() may not been able to write and send all data in one go thus +the need for a loop calling it as long as there are still data to write and +send. + +An application function to write and send early data and only early data, +data sent during the first flight of client messages while the handshake is in +its initial phase, would look completely similar but the call to +mbedtls_ssl_write_early_data() instead of mbedtls_ssl_write(). +``` +int write_early_data( mbedtls_ssl_context *ssl, + const unsigned char *data_to_write, + size_t data_to_write_len, + size_t *data_written ) +{ + *data_written = 0; + + while( *data_written < data_to_write_len ) + { + ret = mbedtls_ssl_write_early_data( ssl, data_to_write + *data_written, + data_to_write_len - *data_written ); + + if( ret < 0 && + ret != MBEDTLS_ERR_SSL_WANT_READ && + ret != MBEDTLS_ERR_SSL_WANT_WRITE ) + { + return( ret ); + } + + *data_written += ret; + } + + return( 0 ); +} +``` +Note that compared to write_data(), write_early_data() can also return +MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA and that should be handled +specifically by the user of write_early_data(). A fresh SSL context (typically +just after a call to mbedtls_ssl_setup() or mbedtls_ssl_session_reset()) would +be expected when calling `write_early_data`. + +All together, code to write and send a buffer of data as long as possible as +early data and then as standard post-handshake application data could +plausibly look like: + +``` +ret = write_early_data( ssl, data_to_write, data_to_write_len, + &early_data_written ); +if( ret < 0 && + ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA ) +{ + goto error; +} + +ret = write_data( ssl, data_to_write + early_data_written, + data_to_write_len - early_data_written, &data_written ); +if( ret < 0 ) + goto error; + +data_written += early_data_written; +``` + +Finally, taking into account that the server may reject early data, application +code to write and send a buffer of data could plausibly look like: +``` +ret = write_early_data( ssl, data_to_write, data_to_write_len, + &early_data_written ); +if( ret < 0 && + ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA ) +{ + goto error; +} + +/* + * Make sure the handshake is completed as it is a requisite to + * mbedtls_ssl_get_early_data_status(). + */ +while( !mbedtls_ssl_is_handshake_over( ssl ) ) +{ + ret = mbedtls_ssl_handshake( ssl ); + if( ret < 0 && + ret != MBEDTLS_ERR_SSL_WANT_READ && + ret != MBEDTLS_ERR_SSL_WANT_WRITE ) + { + goto error; + } +} + +ret = mbedtls_ssl_get_early_data_status( ssl ); +if( ret < 0 ) + goto error; + +if( ret == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED ) + early_data_written = 0; + +ret = write_data( ssl, data_to_write + early_data_written, + data_to_write_len - early_data_written, &data_written ); +if( ret < 0 ) + goto error; + +data_written += early_data_written; +``` + +Basically, the same holds for reading early data on the server side without the +complication of possible rejection. An application function to read early data +into a given buffer could plausibly look like: +``` +int read_early_data( mbedtls_ssl_context *ssl, + unsigned char *buffer, + size_t buffer_size, + size_t *data_len ) +{ + *data_len = 0; + + while( *data_len < buffer_size ) + { + ret = mbedtls_ssl_read_early_data( ssl, buffer + *data_len, + buffer_size - *data_len ); + + if( ret < 0 && + ret != MBEDTLS_ERR_SSL_WANT_READ && + ret != MBEDTLS_ERR_SSL_WANT_WRITE ) + { + return( ret ); + } + + *data_len += ret; + } + + return( 0 ); +} +``` +with again calls to read_early_data() expected to be done with a fresh SSL +context. diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index dddaaea39..ea5866108 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -96,15 +96,16 @@ /* Error space gap */ /** Processing of the Certificate handshake message failed. */ #define MBEDTLS_ERR_SSL_BAD_CERTIFICATE -0x7A00 +/* Error space gap */ /** * Received NewSessionTicket Post Handshake Message. * This error code is experimental and may be changed or removed without notice. */ #define MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET -0x7B00 -/* Error space gap */ -/* Error space gap */ -/* Error space gap */ -/* Error space gap */ +/** Not possible to read early data */ +#define MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA -0x7B80 +/** Not possible to write early data */ +#define MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA -0x7C00 /* Error space gap */ /* Error space gap */ /* Error space gap */ @@ -806,14 +807,6 @@ typedef struct mbedtls_ssl_key_cert mbedtls_ssl_key_cert; typedef struct mbedtls_ssl_flight_item mbedtls_ssl_flight_item; #endif -#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) -#define MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN 0 -#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT 1 -#define MBEDTLS_SSL_EARLY_DATA_STATUS_INDICATION_SENT 2 -#define MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED 3 -#define MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED 4 -#endif - #if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS) typedef uint8_t mbedtls_ssl_tls13_ticket_flags; @@ -4897,6 +4890,151 @@ int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, */ int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl ); +#if defined(MBEDTLS_SSL_EARLY_DATA) + +#if defined(MBEDTLS_SSL_SRV_C) +/** + * \brief Read at most 'len' application data bytes while performing + * the handshake (early data). + * + * \note This function behaves mainly as mbedtls_ssl_read(). The + * specification of mbedtls_ssl_read() relevant to TLS 1.3 + * (thus not the parts specific to (D)TLS 1.2) applies to this + * function and the present documentation is restricted to the + * differences with mbedtls_ssl_read(). + * + * \param ssl SSL context + * \param buf buffer that will hold the data + * \param len maximum number of bytes to read + * + * \return One additional specific return value: + * #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA. + * + * #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA is returned when it + * is not possible to read early data for the SSL context + * \p ssl. + * + * It may have been possible and it is not possible + * anymore because the server received the End of Early Data + * message or the maximum number of allowed early data for the + * PSK in use has been reached. + * + * It may never have been possible and will never be possible + * for the SSL context \p ssl because the use of early data + * is disabled for that context or more generally the context + * is not suitably configured to enable early data or the + * client does not use early data or the first call to the + * function was done while the handshake was already too + * advanced to gather and accept early data. + * + * It is not possible to read early data for the SSL context + * \p ssl but this does not preclude for using it with + * mbedtls_ssl_write(), mbedtls_ssl_read() or + * mbedtls_ssl_handshake(). + * + * \note When a server wants to retrieve early data, it is expected + * that this function starts the handshake for the SSL context + * \p ssl. But this is not mandatory. + * + */ +int mbedtls_ssl_read_early_data( mbedtls_ssl_context *ssl, + unsigned char *buf, size_t len ); +#endif /* MBEDTLS_SSL_SRV_C */ + +#if defined(MBEDTLS_SSL_CLI_C) +/** + * \brief Try to write exactly 'len' application data bytes while + * performing the handshake (early data). + * + * \note This function behaves mainly as mbedtls_ssl_write(). The + * specification of mbedtls_ssl_write() relevant to TLS 1.3 + * (thus not the parts specific to (D)TLS1.2) applies to this + * function and the present documentation is restricted to the + * differences with mbedtls_ssl_write(). + * + * \param ssl SSL context + * \param buf buffer holding the data + * \param len how many bytes must be written + * + * \return One additional specific return value: + * #MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA. + * + * #MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA is returned when it + * is not possible to write early data for the SSL context + * \p ssl. + * + * It may have been possible and it is not possible + * anymore because the client received the server Finished + * message, the server rejected early data or the maximum + * number of allowed early data for the PSK in use has been + * reached. + * + * It may never have been possible and will never be possible + * for the SSL context \p ssl because the use of early data + * is disabled for that context or more generally the context + * is not suitably configured to enable early data or the first + * call to the function was done while the handshake was + * already completed. + * + * It is not possible to write early data for the SSL context + * \p ssl but this does not preclude for using it with + * mbedtls_ssl_write(), mbedtls_ssl_read() or + * mbedtls_ssl_handshake(). + * + * \note This function may write early data only if the SSL context + * has been configured for the handshake with a PSK for which + * early data is allowed. + * + * \note To maximize the number of early data that can be written in + * the course of the handshake, it is expected that this + * function starts the handshake for the SSL context \p ssl. + * But this is not mandatory. + * + * \note This function does not provide any information on whether + * the server has accepted or will accept early data or not. + * When it returns a positive value, it just means that it + * has written early data to the server. To know whether the + * server has accepted early data or not, you should call + * mbedtls_ssl_get_early_data_status() with the handshake + * completed. + */ +int mbedtls_ssl_write_early_data( mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len ); + +#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT 0 +#define MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED 1 +#define MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED 2 +/** + * \brief Get the status of the negotiation of the use of early data. + * + * \param ssl The SSL context to query + * + * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if this function is called + * from the server-side. + * + * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if this function is called + * prior to completion of the handshake. + * + * \return #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT if the client has + * not indicated the use of early data to the server. + * + * \return #MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED if the client has + * indicated the use of early data and the server has accepted + * it. + * + * \return #MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED if the client has + * indicated the use of early data but the server has rejected + * it. In this situation, the client may want to re-send the + * early data it may have tried to send by calling + * mbedtls_ssl_write_early_data() as ordinary post-handshake + * application data by calling mbedtls_ssl_write(). + * + */ +int mbedtls_ssl_get_early_data_status( mbedtls_ssl_context *ssl ); +#endif /* MBEDTLS_SSL_CLI_C */ + +#endif /* MBEDTLS_SSL_EARLY_DATA */ + /** * \brief Free referenced items in an SSL context and clear memory * diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 9d2e69e3e..0109f776c 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -1183,11 +1183,11 @@ int mbedtls_ssl_tls13_write_client_hello_exts( mbedtls_ssl_context *ssl, return( ret ); p += ext_len; - /* Initializes the status to `indication sent`. It will be updated to - * `accepted` or `rejected` depending on whether the EncryptedExtension - * message will contain an early data indication extension or not. + /* Initializes the status to `rejected`. It will be updated to + * `accepted` if the EncryptedExtension message contain an early data + * indication extension. */ - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_INDICATION_SENT; + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED; } else {