From a9a97dca63be6946c63ef27a9381514ce64d0c47 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 28 Nov 2022 18:26:16 +0100 Subject: [PATCH 01/28] psa_pake: add support for opaque password Signed-off-by: Valerio Setti --- include/mbedtls/ssl.h | 20 ++++++++++++++++ library/ssl_tls.c | 55 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index ea5866108..575520825 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -3860,6 +3860,26 @@ void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf, int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, const unsigned char *pw, size_t pw_len ); + +/** + * \brief Set the EC J-PAKE opaque password for current handshake. + * + * \note An internal copy is made, and destroyed as soon as the + * handshake is completed, or when the SSL context is reset or + * freed. + * + * \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 pwd EC J-PAKE opaque password + * + * \return 0 on success, or a negative error code. + */ +int mbedtls_ssl_set_hs_ecjpake_password_opaque( mbedtls_ssl_context *ssl, + mbedtls_svc_key_id_t pwd ); #endif /*MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_SSL_ALPN) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 3d3491bc6..f1d286c7d 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1921,6 +1921,61 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, return( 0 ); } + +int mbedtls_ssl_set_hs_ecjpake_password_opaque( mbedtls_ssl_context *ssl, + mbedtls_svc_key_id_t pwd ) +{ + psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); + psa_pake_role_t psa_role; + psa_status_t status; + + if( ssl->handshake == NULL || ssl->conf == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) + psa_role = PSA_PAKE_ROLE_SERVER; + else + psa_role = PSA_PAKE_ROLE_CLIENT; + + if( mbedtls_svc_key_id_is_null( pwd ) ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + ssl->handshake->psa_pake_password = pwd; + + 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 ); + } + + 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 /* MBEDTLS_USE_PSA_CRYPTO */ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, const unsigned char *pw, From d572a82df98fab426957f7e17a13cc5837f54180 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 28 Nov 2022 18:27:51 +0100 Subject: [PATCH 02/28] tls: psa_pake: add test for opaque password Signed-off-by: Valerio Setti --- programs/ssl/ssl_client2.c | 63 ++++++++++++++++++++++++++++++++----- programs/ssl/ssl_server2.c | 64 +++++++++++++++++++++++++++++++++----- tests/ssl-opt.sh | 18 +++++++++++ 3 files changed, 129 insertions(+), 16 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 6aa295d66..5c3af2c2f 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -68,6 +68,7 @@ int main( void ) #define DFL_PSK_OPAQUE 0 #define DFL_PSK_IDENTITY "Client_identity" #define DFL_ECJPAKE_PW NULL +#define DFL_ECJPAKE_PW_OPAQUE 0 #define DFL_EC_MAX_OPS -1 #define DFL_FORCE_CIPHER 0 #define DFL_TLS1_3_KEX_MODES MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_ALL @@ -319,7 +320,8 @@ int main( void ) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) #define USAGE_ECJPAKE \ - " ecjpake_pw=%%s default: none (disabled)\n" + " ecjpake_pw=%%s default: none (disabled)\n" \ + " ecjpake_pw_opaque=%%d default: 0 (disabled)\n" #else #define USAGE_ECJPAKE "" #endif @@ -492,6 +494,7 @@ struct options const char *psk; /* the pre-shared key */ const char *psk_identity; /* the pre-shared key identity */ const char *ecjpake_pw; /* the EC J-PAKE password */ + int ecjpake_pw_opaque; /* set to 1 to use the opaque method for setting the password */ int ec_max_ops; /* EC consecutive operations limit */ int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */ #if defined(MBEDTLS_SSL_PROTO_TLS1_3) @@ -824,6 +827,10 @@ int main( int argc, char *argv[] ) MBEDTLS_TLS_SRTP_UNSET }; #endif /* MBEDTLS_SSL_DTLS_SRTP */ +#if defined( MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED ) && \ + defined( MBEDTLS_USE_PSA_CRYPTO ) + mbedtls_svc_key_id_t ecjpake_pw_slot = MBEDTLS_SVC_KEY_ID_INIT; /* ecjpake password key slot */ +#endif // MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) ); @@ -919,6 +926,7 @@ int main( int argc, char *argv[] ) #endif opt.psk_identity = DFL_PSK_IDENTITY; opt.ecjpake_pw = DFL_ECJPAKE_PW; + opt.ecjpake_pw_opaque = DFL_ECJPAKE_PW_OPAQUE; opt.ec_max_ops = DFL_EC_MAX_OPS; opt.force_ciphersuite[0]= DFL_FORCE_CIPHER; #if defined(MBEDTLS_SSL_PROTO_TLS1_3) @@ -1094,6 +1102,8 @@ int main( int argc, char *argv[] ) opt.psk_identity = q; else if( strcmp( p, "ecjpake_pw" ) == 0 ) opt.ecjpake_pw = q; + else if( strcmp( p, "ecjpake_pw_opaque" ) == 0 ) + opt.ecjpake_pw_opaque = atoi( q ); else if( strcmp( p, "ec_max_ops" ) == 0 ) opt.ec_max_ops = atoi( q ); else if( strcmp( p, "force_ciphersuite" ) == 0 ) @@ -2166,16 +2176,45 @@ int main( int argc, char *argv[] ) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) if( opt.ecjpake_pw != DFL_ECJPAKE_PW ) { - if( ( ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl, - (const unsigned char *) opt.ecjpake_pw, - strlen( opt.ecjpake_pw ) ) ) != 0 ) +#if defined( MBEDTLS_USE_PSA_CRIPTO ) + if ( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) { - mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password returned %d\n\n", - ret ); - goto exit; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + 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, + (const unsigned char *) opt.ecjpake_pw, + strlen( opt.ecjpake_pw ), + &ecjpake_pw_slot ); + if( status != PSA_SUCCESS ) + { + mbedtls_printf( " failed\n ! psa_import_key returned %d\n\n", + status ); + goto exit; + } + if( ( ret = mbedtls_ssl_set_hs_ecjpake_password_opaque( &ssl, + ecjpake_pw_slot ) ) != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password_opaque returned %d\n\n", ret ); + goto exit; + } + } + else +#endif // MBEDTLS_USE_PSA_CRIPTO + { + if( ( ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl, + (const unsigned char *) opt.ecjpake_pw, + strlen( opt.ecjpake_pw ) ) ) != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password returned %d\n\n", ret ); + goto exit; + } } } -#endif +#endif // MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) if( opt.context_crt_cb == 1 ) @@ -3276,6 +3315,14 @@ exit: #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED && MBEDTLS_USE_PSA_CRYPTO */ +#if defined( MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED ) && \ + defined( MBEDTLS_USE_PSA_CRYPTO ) + if( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) + { + psa_destroy_key( ecjpake_pw_slot ); + } +#endif // MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO + #if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3) const char* message = mbedtls_test_helper_is_psa_leaking(); if( message ) diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 1b4a94ab0..8e1aaf351 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -98,6 +98,7 @@ int main( void ) #define DFL_PSK_LIST_OPAQUE 0 #define DFL_PSK_IDENTITY "Client_identity" #define DFL_ECJPAKE_PW NULL +#define DFL_ECJPAKE_PW_OPAQUE 0 #define DFL_PSK_LIST NULL #define DFL_FORCE_CIPHER 0 #define DFL_TLS1_3_KEX_MODES MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_ALL @@ -419,7 +420,8 @@ int main( void ) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) #define USAGE_ECJPAKE \ - " ecjpake_pw=%%s default: none (disabled)\n" + " ecjpake_pw=%%s default: none (disabled)\n" \ + " ecjpake_pw_opaque=%%d default: 0 (disabled)\n" #else #define USAGE_ECJPAKE "" #endif @@ -621,6 +623,7 @@ struct options const char *psk_identity; /* the pre-shared key identity */ char *psk_list; /* list of PSK id/key pairs for callback */ const char *ecjpake_pw; /* the EC J-PAKE password */ + int ecjpake_pw_opaque; /* set to 1 to use the opaque method for setting the password */ int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */ #if defined(MBEDTLS_SSL_PROTO_TLS1_3) int tls13_kex_modes; /* supported TLS 1.3 key exchange modes */ @@ -1506,6 +1509,10 @@ int main( int argc, char *argv[] ) unsigned char *context_buf = NULL; size_t context_buf_len = 0; #endif +#if defined( MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED ) && \ + defined( MBEDTLS_USE_PSA_CRYPTO ) + mbedtls_svc_key_id_t ecjpake_pw_slot = MBEDTLS_SVC_KEY_ID_INIT; /* ecjpake password key slot */ +#endif // MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) uint16_t sig_alg_list[SIG_ALG_LIST_SIZE]; @@ -1661,6 +1668,7 @@ int main( int argc, char *argv[] ) opt.psk_identity = DFL_PSK_IDENTITY; opt.psk_list = DFL_PSK_LIST; opt.ecjpake_pw = DFL_ECJPAKE_PW; + opt.ecjpake_pw_opaque = DFL_ECJPAKE_PW_OPAQUE; opt.force_ciphersuite[0]= DFL_FORCE_CIPHER; #if defined(MBEDTLS_SSL_PROTO_TLS1_3) opt.tls13_kex_modes = DFL_TLS1_3_KEX_MODES; @@ -1864,6 +1872,8 @@ int main( int argc, char *argv[] ) opt.psk_list = q; else if( strcmp( p, "ecjpake_pw" ) == 0 ) opt.ecjpake_pw = q; + else if( strcmp( p, "ecjpake_pw_opaque" ) == 0 ) + opt.ecjpake_pw_opaque = atoi( q ); else if( strcmp( p, "force_ciphersuite" ) == 0 ) { opt.force_ciphersuite[0] = mbedtls_ssl_get_ciphersuite_id( q ); @@ -3488,18 +3498,48 @@ reset: } #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#if defined( MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED ) if( opt.ecjpake_pw != DFL_ECJPAKE_PW ) { - if( ( ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl, - (const unsigned char *) opt.ecjpake_pw, - strlen( opt.ecjpake_pw ) ) ) != 0 ) +#if defined( MBEDTLS_USE_PSA_CRIPTO ) + if ( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) { - mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password returned %d\n\n", ret ); - goto exit; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + 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, + (const unsigned char *) opt.ecjpake_pw, + strlen( opt.ecjpake_pw ), + &ecjpake_pw_slot ); + if( status != PSA_SUCCESS ) + { + mbedtls_printf( " failed\n ! psa_import_key returned %d\n\n", + status ); + goto exit; + } + if( ( ret = mbedtls_ssl_set_hs_ecjpake_password_opaque( &ssl, + ecjpake_pw_slot ) ) != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password_opaque returned %d\n\n", ret ); + goto exit; + } + } + else +#endif // MBEDTLS_USE_PSA_CRIPTO + { + if( ( ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl, + (const unsigned char *) opt.ecjpake_pw, + strlen( opt.ecjpake_pw ) ) ) != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password returned %d\n\n", ret ); + goto exit; + } } } -#endif +#endif // MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) #if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) @@ -4385,6 +4425,14 @@ exit: #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED && MBEDTLS_USE_PSA_CRYPTO */ +#if defined( MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED ) && \ + defined( MBEDTLS_USE_PSA_CRYPTO ) + if( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) + { + psa_destroy_key( ecjpake_pw_slot ); + } +#endif // MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO + #if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3) const char* message = mbedtls_test_helper_is_psa_leaking(); if( message ) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index c6f6e2963..224c8c054 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -8007,6 +8007,24 @@ run_test "ECJPAKE: working, TLS" \ -S "SSL - The handshake negotiation failed" \ -S "SSL - Verification of the message MAC failed" +requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 +run_test "ECJPAKE: working, TLS, opaque password" \ + "$P_SRV debug_level=3 ecjpake_pw=bla ecjpake_pw_opaque=1" \ + "$P_CLI debug_level=3 ecjpake_pw=bla ecjpake_pw_opaque=1\ + force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \ + 0 \ + -c "add ciphersuite: c0ff" \ + -c "adding ecjpake_kkpp extension" \ + -C "re-using cached ecjpake parameters" \ + -s "found ecjpake kkpp extension" \ + -S "skip ecjpake kkpp extension" \ + -S "ciphersuite mismatch: ecjpake not configured" \ + -s "server hello, ecjpake kkpp extension" \ + -c "found ecjpake_kkpp extension" \ + -S "SSL - The handshake negotiation failed" \ + -S "SSL - Verification of the message MAC failed" + server_needs_more_time 1 requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 From 77e8315f5b82fbce385c8b1695b83513ff32c216 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 29 Nov 2022 17:17:11 +0100 Subject: [PATCH 03/28] fix formatting and typos Signed-off-by: Valerio Setti --- programs/ssl/ssl_client2.c | 18 +++++++++--------- programs/ssl/ssl_server2.c | 20 ++++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 5c3af2c2f..3a79b76ca 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -827,10 +827,10 @@ int main( int argc, char *argv[] ) MBEDTLS_TLS_SRTP_UNSET }; #endif /* MBEDTLS_SSL_DTLS_SRTP */ -#if defined( MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED ) && \ - defined( MBEDTLS_USE_PSA_CRYPTO ) +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ + defined(MBEDTLS_USE_PSA_CRYPTO) mbedtls_svc_key_id_t ecjpake_pw_slot = MBEDTLS_SVC_KEY_ID_INIT; /* ecjpake password key slot */ -#endif // MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED +#endif /* MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) ); @@ -2176,7 +2176,7 @@ int main( int argc, char *argv[] ) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) if( opt.ecjpake_pw != DFL_ECJPAKE_PW ) { -#if defined( MBEDTLS_USE_PSA_CRIPTO ) +#if defined(MBEDTLS_USE_PSA_CRYPTO) if ( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; @@ -2203,7 +2203,7 @@ int main( int argc, char *argv[] ) } } else -#endif // MBEDTLS_USE_PSA_CRIPTO +#endif /* MBEDTLS_USE_PSA_CRYPTO */ { if( ( ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl, (const unsigned char *) opt.ecjpake_pw, @@ -2214,7 +2214,7 @@ int main( int argc, char *argv[] ) } } } -#endif // MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) if( opt.context_crt_cb == 1 ) @@ -3315,13 +3315,13 @@ exit: #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED && MBEDTLS_USE_PSA_CRYPTO */ -#if defined( MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED ) && \ - defined( MBEDTLS_USE_PSA_CRYPTO ) +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ + defined(MBEDTLS_USE_PSA_CRYPTO) if( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) { psa_destroy_key( ecjpake_pw_slot ); } -#endif // MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO */ #if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3) const char* message = mbedtls_test_helper_is_psa_leaking(); diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 8e1aaf351..c09a47a16 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -1509,10 +1509,10 @@ int main( int argc, char *argv[] ) unsigned char *context_buf = NULL; size_t context_buf_len = 0; #endif -#if defined( MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED ) && \ - defined( MBEDTLS_USE_PSA_CRYPTO ) +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ + defined(MBEDTLS_USE_PSA_CRYPTO) mbedtls_svc_key_id_t ecjpake_pw_slot = MBEDTLS_SVC_KEY_ID_INIT; /* ecjpake password key slot */ -#endif // MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED +#endif /* MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) uint16_t sig_alg_list[SIG_ALG_LIST_SIZE]; @@ -3498,10 +3498,10 @@ reset: } #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ -#if defined( MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED ) +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) if( opt.ecjpake_pw != DFL_ECJPAKE_PW ) { -#if defined( MBEDTLS_USE_PSA_CRIPTO ) +#if defined(MBEDTLS_USE_PSA_CRYPTO) if ( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; @@ -3528,7 +3528,7 @@ reset: } } else -#endif // MBEDTLS_USE_PSA_CRIPTO +#endif /* MBEDTLS_USE_PSA_CRYPTO */ { if( ( ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl, (const unsigned char *) opt.ecjpake_pw, @@ -3539,7 +3539,7 @@ reset: } } } -#endif // MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) #if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) @@ -4425,13 +4425,13 @@ exit: #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED && MBEDTLS_USE_PSA_CRYPTO */ -#if defined( MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED ) && \ - defined( MBEDTLS_USE_PSA_CRYPTO ) +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ + defined(MBEDTLS_USE_PSA_CRYPTO) if( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) { psa_destroy_key( ecjpake_pw_slot ); } -#endif // MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO */ #if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3) const char* message = mbedtls_test_helper_is_psa_leaking(); From 661b9bca75560fc234febe03ea27d02504227e87 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 29 Nov 2022 17:19:25 +0100 Subject: [PATCH 04/28] test: psa_pake: add specific log message for the opaque password Signed-off-by: Valerio Setti --- programs/ssl/ssl_client2.c | 1 + programs/ssl/ssl_server2.c | 1 + tests/ssl-opt.sh | 2 ++ 3 files changed, 4 insertions(+) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 3a79b76ca..736bc5123 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -2201,6 +2201,7 @@ int main( int argc, char *argv[] ) mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password_opaque returned %d\n\n", ret ); goto exit; } + mbedtls_printf( "using opaque password\n"); } else #endif /* MBEDTLS_USE_PSA_CRYPTO */ diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index c09a47a16..6db20c66e 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -3526,6 +3526,7 @@ reset: mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password_opaque returned %d\n\n", ret ); goto exit; } + mbedtls_printf( "using opaque password\n"); } else #endif /* MBEDTLS_USE_PSA_CRYPTO */ diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 224c8c054..53fe49e06 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -8016,6 +8016,8 @@ run_test "ECJPAKE: working, TLS, opaque password" \ 0 \ -c "add ciphersuite: c0ff" \ -c "adding ecjpake_kkpp extension" \ + -c "using opaque password" \ + -s "using opaque password" \ -C "re-using cached ecjpake parameters" \ -s "found ecjpake kkpp extension" \ -S "skip ecjpake kkpp extension" \ From a6b69dabc5edc13b3c7bb42233237652964c8ecd Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 30 Nov 2022 16:44:49 +0100 Subject: [PATCH 05/28] test: psa_pake: add a separate test for opaque password Signed-off-by: Valerio Setti --- tests/scripts/all.sh | 19 +++++++++++++++++-- tests/ssl-opt.sh | 3 ++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index b43f999d8..f465616d0 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -1456,13 +1456,28 @@ component_test_tls1_2_ecjpake_compatibility() { 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 + P_SRV=../s2_no_use_psa tests/ssl-opt.sh -f ECJPAKE -e ECJPAKE_OPAQUE_PW msg "test: client w/o USE_PSA - server w/ USE_PSA" - P_CLI=../c2_no_use_psa tests/ssl-opt.sh -f ECJPAKE + P_CLI=../c2_no_use_psa tests/ssl-opt.sh -f ECJPAKE -e ECJPAKE_OPAQUE_PW rm s2_no_use_psa c2_no_use_psa } +# Opaque password testing requires a separate test with repect to +# "test_tls1_2_ecjpake_compatibility". In that case there's a mix of PSA and +# MbedTLS based implementations of EC-JPAKE which makes it difficult to parse +# proper strings during the test. As a consequence here we just build the +# PSA variant for both client and server. +component_test_tls1_2_ecjpake_opaque_password() { + msg "build: TLS1.2 server+client w/ opaque password support" + scripts/config.py set MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED + scripts/config.py set MBEDTLS_USE_PSA_CRYPTO + make -C programs ssl/ssl_server2 ssl/ssl_client2 + make -C programs test/udp_proxy test/query_compile_time_config + + tests/ssl-opt.sh -f ECJPAKE_OPAQUE_PW +} + 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 diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 53fe49e06..f9393d779 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -8008,8 +8008,9 @@ run_test "ECJPAKE: working, TLS" \ -S "SSL - Verification of the message MAC failed" requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED +requires_config_enabled MBEDTLS_USE_PSA_CRYPTO requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 -run_test "ECJPAKE: working, TLS, opaque password" \ +run_test "ECJPAKE_OPAQUE_PW: working, TLS, opaque password" \ "$P_SRV debug_level=3 ecjpake_pw=bla ecjpake_pw_opaque=1" \ "$P_CLI debug_level=3 ecjpake_pw=bla ecjpake_pw_opaque=1\ force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \ From 094432903603a19e23419652127c34475212a7d0 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 1 Dec 2022 15:06:09 +0100 Subject: [PATCH 06/28] tls: pake: add check for empty passwords in mbedtls_ssl_set_hs_ecjpake_password() Signed-off-by: Valerio Setti --- library/ssl_tls.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index f1d286c7d..47c02a603 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1991,6 +1991,10 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, else role = MBEDTLS_ECJPAKE_CLIENT; + /* Empty password is not valid */ + if( ( pw == NULL) || ( pw_len == 0 ) ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + return( mbedtls_ecjpake_setup( &ssl->handshake->ecjpake_ctx, role, MBEDTLS_MD_SHA256, From 4452e98ec19faa66628f8d2fbf97d627b87ea2c7 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 1 Dec 2022 15:08:35 +0100 Subject: [PATCH 07/28] test: pake: add tests for set password functions Signed-off-by: Valerio Setti --- tests/suites/test_suite_ssl.data | 28 ++++++++++ tests/suites/test_suite_ssl.function | 83 ++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index a35762d7f..0cec78493 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3567,3 +3567,31 @@ cookie_parsing:"16fefd0000000000000000002F010000de000000000000011efefd7b72727272 TLS 1.3 srv Certificate msg - wrong vector lengths tls13_server_certificate_msg_invalid_vector_len + +EC-JPAKE set password +depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED +ssl_ecjpake_set_password:0:ECJPAKE_ERR_NONE:0 + +EC-JPAKE set password - uninitiazed SSL context +depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED +ssl_ecjpake_set_password:0:ECJPAKE_ERR_UNITIALIZED_SSL_CONTEXT:MBEDTLS_ERR_SSL_BAD_INPUT_DATA + +EC-JPAKE set password - empty password +depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED +ssl_ecjpake_set_password:0:ECJPAKE_ERR_EMPTY_PASSWORD:MBEDTLS_ERR_SSL_BAD_INPUT_DATA + +EC-JPAKE set opaque password +depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED:MBEDTLS_USE_PSA_CRYPTO +ssl_ecjpake_set_password:1:ECJPAKE_ERR_NONE:0 + +EC-JPAKE set opaque password - uninitiazed SSL context +depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED:MBEDTLS_USE_PSA_CRYPTO +ssl_ecjpake_set_password:1:ECJPAKE_ERR_UNITIALIZED_SSL_CONTEXT:MBEDTLS_ERR_SSL_BAD_INPUT_DATA + +EC-JPAKE set opaque password - empty password +depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED:MBEDTLS_USE_PSA_CRYPTO +ssl_ecjpake_set_password:1:ECJPAKE_ERR_EMPTY_PASSWORD:MBEDTLS_ERR_SSL_BAD_INPUT_DATA + +EC-JPAKE set opaque password - uninitalized password key +depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED:MBEDTLS_USE_PSA_CRYPTO +ssl_ecjpake_set_password:1:ECJPAKE_ERR_UNINITIALIZED_PWD_KEY:MBEDTLS_ERR_SSL_BAD_INPUT_DATA diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 7447a1d0e..bfc6a379f 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -2582,6 +2582,15 @@ int tweak_tls13_certificate_msg_vector_len( return( 0 ); } #endif /* MBEDTLS_TEST_HOOKS */ + +typedef enum { + ECJPAKE_ERR_NONE, + ECJPAKE_ERR_UNITIALIZED_SSL_CONTEXT, + ECJPAKE_ERR_EMPTY_PASSWORD, + ECJPAKE_ERR_UNINITIALIZED_PWD_KEY, +} ecjpake_err_inj_step_t; + +#define ECJPAKE_TEST_PWD "bla" /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -6180,3 +6189,77 @@ exit: USE_PSA_DONE( ); } /* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ +void ssl_ecjpake_set_password( int use_opaque_arg, + int err_injection_step_arg, + int expected_error_arg ) +{ + mbedtls_ssl_context ssl; + mbedtls_ssl_config conf; +#if defined( MBEDTLS_USE_PSA_CRYPTO ) + mbedtls_svc_key_id_t pwd_slot = MBEDTLS_SVC_KEY_ID_INIT; +#else /* MBEDTLS_USE_PSA_CRYPTO */ + (void) use_opaque_arg; +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + const unsigned char pwd_string[ sizeof(ECJPAKE_TEST_PWD) ] = ""; + size_t pwd_len = 0; + ecjpake_err_inj_step_t err_injection_step = err_injection_step_arg; + int ret; + + USE_PSA_INIT( ); + + mbedtls_ssl_init( &ssl ); + + if( err_injection_step == ECJPAKE_ERR_UNITIALIZED_SSL_CONTEXT ) + goto run_test; + + mbedtls_ssl_config_init( &conf ); + + TEST_ASSERT( mbedtls_ssl_config_defaults( &conf, + MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT ) + == 0 ); + + TEST_ASSERT( mbedtls_ssl_setup( &ssl, &conf ) == 0 ); + + if( err_injection_step == ECJPAKE_ERR_EMPTY_PASSWORD ) + goto run_test; + + pwd_len = strlen( ECJPAKE_TEST_PWD ); + memcpy( (void*) pwd_string, ECJPAKE_TEST_PWD, pwd_len ); + +#if defined( MBEDTLS_USE_PSA_CRYPTO ) + if( use_opaque_arg ) + { + if( err_injection_step == ECJPAKE_ERR_UNINITIALIZED_PWD_KEY ) + goto run_test; + + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + 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 ); + + TEST_ASSERT( psa_import_key( &attributes, pwd_string, + pwd_len, &pwd_slot ) == PSA_SUCCESS ); + } +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +run_test: +#if defined( MBEDTLS_USE_PSA_CRYPTO ) + ret = ( use_opaque_arg ) ? + mbedtls_ssl_set_hs_ecjpake_password_opaque( &ssl, pwd_slot ) : + mbedtls_ssl_set_hs_ecjpake_password( &ssl, pwd_string, pwd_len ); +#else /* MBEDTLS_USE_PSA_CRYPTO */ + ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl, pwd_string, pwd_len ); +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + TEST_EQUAL( ret, expected_error_arg ); + + mbedtls_ssl_free( &ssl ); + mbedtls_ssl_config_free( &conf ); + + USE_PSA_DONE( ); +} +/* END_CASE */ From dc40bbc2d7c42f98d4ecc503dccebbe41c5dad03 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 1 Dec 2022 15:25:49 +0100 Subject: [PATCH 08/28] test: pake: remove redundant test for opaque passwords This is already covered by other already existing cases such as "component_test_full_cmake_gcc_asan" which build with "config.py full" and run all "ssl-opt.sh" test cases. Signed-off-by: Valerio Setti --- tests/scripts/all.sh | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index f465616d0..435ea232d 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -1463,21 +1463,6 @@ component_test_tls1_2_ecjpake_compatibility() { rm s2_no_use_psa c2_no_use_psa } -# Opaque password testing requires a separate test with repect to -# "test_tls1_2_ecjpake_compatibility". In that case there's a mix of PSA and -# MbedTLS based implementations of EC-JPAKE which makes it difficult to parse -# proper strings during the test. As a consequence here we just build the -# PSA variant for both client and server. -component_test_tls1_2_ecjpake_opaque_password() { - msg "build: TLS1.2 server+client w/ opaque password support" - scripts/config.py set MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED - scripts/config.py set MBEDTLS_USE_PSA_CRYPTO - make -C programs ssl/ssl_server2 ssl/ssl_client2 - make -C programs test/udp_proxy test/query_compile_time_config - - tests/ssl-opt.sh -f ECJPAKE_OPAQUE_PW -} - 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 b287ddff7e9d50f10dd31ce6e02cb1f8d310ad69 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 1 Dec 2022 16:18:12 +0100 Subject: [PATCH 09/28] test: psa_pake: add more tests for opaque password setting Added mixed cases: - server using opaque password, while client not - client using opaque password, while server not Added a test with mismatched passwords in case both server and client are using opaque passwords (the same test was already present for the non-opaque case) Signed-off-by: Valerio Setti --- tests/ssl-opt.sh | 58 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index f9393d779..547a0f55c 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -8010,7 +8010,7 @@ run_test "ECJPAKE: working, TLS" \ requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED requires_config_enabled MBEDTLS_USE_PSA_CRYPTO requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 -run_test "ECJPAKE_OPAQUE_PW: working, TLS, opaque password" \ +run_test "ECJPAKE_OPAQUE_PW: working, TLS, opaque password client+server" \ "$P_SRV debug_level=3 ecjpake_pw=bla ecjpake_pw_opaque=1" \ "$P_CLI debug_level=3 ecjpake_pw=bla ecjpake_pw_opaque=1\ force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \ @@ -8028,6 +8028,48 @@ run_test "ECJPAKE_OPAQUE_PW: working, TLS, opaque password" \ -S "SSL - The handshake negotiation failed" \ -S "SSL - Verification of the message MAC failed" +requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED +requires_config_enabled MBEDTLS_USE_PSA_CRYPTO +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 +run_test "ECJPAKE_OPAQUE_PW: working, TLS, opaque password client only" \ + "$P_SRV debug_level=3 ecjpake_pw=bla" \ + "$P_CLI debug_level=3 ecjpake_pw=bla ecjpake_pw_opaque=1\ + force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \ + 0 \ + -c "add ciphersuite: c0ff" \ + -c "adding ecjpake_kkpp extension" \ + -c "using opaque password" \ + -S "using opaque password" \ + -C "re-using cached ecjpake parameters" \ + -s "found ecjpake kkpp extension" \ + -S "skip ecjpake kkpp extension" \ + -S "ciphersuite mismatch: ecjpake not configured" \ + -s "server hello, ecjpake kkpp extension" \ + -c "found ecjpake_kkpp extension" \ + -S "SSL - The handshake negotiation failed" \ + -S "SSL - Verification of the message MAC failed" + +requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED +requires_config_enabled MBEDTLS_USE_PSA_CRYPTO +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 +run_test "ECJPAKE_OPAQUE_PW: working, TLS, opaque password server only" \ + "$P_SRV debug_level=3 ecjpake_pw=bla ecjpake_pw_opaque=1" \ + "$P_CLI debug_level=3 ecjpake_pw=bla\ + force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \ + 0 \ + -c "add ciphersuite: c0ff" \ + -c "adding ecjpake_kkpp extension" \ + -C "using opaque password" \ + -s "using opaque password" \ + -C "re-using cached ecjpake parameters" \ + -s "found ecjpake kkpp extension" \ + -S "skip ecjpake kkpp extension" \ + -S "ciphersuite mismatch: ecjpake not configured" \ + -s "server hello, ecjpake kkpp extension" \ + -c "found ecjpake_kkpp extension" \ + -S "SSL - The handshake negotiation failed" \ + -S "SSL - Verification of the message MAC failed" + server_needs_more_time 1 requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 @@ -8039,6 +8081,20 @@ run_test "ECJPAKE: password mismatch, TLS" \ -C "re-using cached ecjpake parameters" \ -s "SSL - Verification of the message MAC failed" +server_needs_more_time 1 +requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED +requires_config_enabled MBEDTLS_USE_PSA_CRYPTO +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 +run_test "ECJPAKE_OPAQUE_PW: opaque password mismatch, TLS" \ + "$P_SRV debug_level=3 ecjpake_pw=bla ecjpake_pw_opaque=1" \ + "$P_CLI debug_level=3 ecjpake_pw=bad ecjpake_pw_opaque=1 \ + force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \ + 1 \ + -c "using opaque password" \ + -s "using opaque password" \ + -C "re-using cached ecjpake parameters" \ + -s "SSL - Verification of the message MAC failed" + requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 run_test "ECJPAKE: working, DTLS" \ From e98db0b866996da2fbf71bec92d8cf7e365e4fa8 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 1 Dec 2022 16:52:57 +0100 Subject: [PATCH 10/28] tls: pake: fix description for mbedtls_ssl_set_hs_ecjpake_password_opaque Signed-off-by: Valerio Setti --- include/mbedtls/ssl.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 575520825..97caad881 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -3864,14 +3864,12 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, /** * \brief Set the EC J-PAKE opaque password for current handshake. * - * \note An internal copy is made, and destroyed as soon as the - * handshake is completed, or when the SSL context is reset or - * freed. + * \note The input key in not copied, so the caller must not destroy + * it before the handshake is over. * * \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 pwd EC J-PAKE opaque password From 757f3594741ebf7687fffb79079551836603c7e6 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 2 Dec 2022 11:07:11 +0100 Subject: [PATCH 11/28] tls: pake: do not destroy key on errors while setting opaque password Signed-off-by: Valerio Setti --- library/ssl_tls.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 47c02a603..1438124dd 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1950,31 +1950,24 @@ int mbedtls_ssl_set_hs_ecjpake_password_opaque( mbedtls_ssl_context *ssl, 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 ); - } + goto error; 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 ); - } + goto error; 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 ); - } + goto error; ssl->handshake->psa_pake_ctx_is_ok = 1; return( 0 ); + +error: + psa_pake_abort( &ssl->handshake->psa_pake_ctx ); + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); } #else /* MBEDTLS_USE_PSA_CRYPTO */ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, From e7518ba28eb7c88b6de12e8882843a66783fb6fc Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 2 Dec 2022 12:09:43 +0100 Subject: [PATCH 12/28] test: pake: reshaping the ssl_ecjpake_set_password() Removed the "error injection" strategy. Now the functions checks for all the errors in a row. Signed-off-by: Valerio Setti --- tests/suites/test_suite_ssl.data | 24 ++----------- tests/suites/test_suite_ssl.function | 51 ++++++++++++++-------------- 2 files changed, 27 insertions(+), 48 deletions(-) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 0cec78493..66d32a14b 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3570,28 +3570,8 @@ tls13_server_certificate_msg_invalid_vector_len EC-JPAKE set password depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED -ssl_ecjpake_set_password:0:ECJPAKE_ERR_NONE:0 - -EC-JPAKE set password - uninitiazed SSL context -depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED -ssl_ecjpake_set_password:0:ECJPAKE_ERR_UNITIALIZED_SSL_CONTEXT:MBEDTLS_ERR_SSL_BAD_INPUT_DATA - -EC-JPAKE set password - empty password -depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED -ssl_ecjpake_set_password:0:ECJPAKE_ERR_EMPTY_PASSWORD:MBEDTLS_ERR_SSL_BAD_INPUT_DATA +ssl_ecjpake_set_password:0 EC-JPAKE set opaque password depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED:MBEDTLS_USE_PSA_CRYPTO -ssl_ecjpake_set_password:1:ECJPAKE_ERR_NONE:0 - -EC-JPAKE set opaque password - uninitiazed SSL context -depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED:MBEDTLS_USE_PSA_CRYPTO -ssl_ecjpake_set_password:1:ECJPAKE_ERR_UNITIALIZED_SSL_CONTEXT:MBEDTLS_ERR_SSL_BAD_INPUT_DATA - -EC-JPAKE set opaque password - empty password -depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED:MBEDTLS_USE_PSA_CRYPTO -ssl_ecjpake_set_password:1:ECJPAKE_ERR_EMPTY_PASSWORD:MBEDTLS_ERR_SSL_BAD_INPUT_DATA - -EC-JPAKE set opaque password - uninitalized password key -depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED:MBEDTLS_USE_PSA_CRYPTO -ssl_ecjpake_set_password:1:ECJPAKE_ERR_UNINITIALIZED_PWD_KEY:MBEDTLS_ERR_SSL_BAD_INPUT_DATA +ssl_ecjpake_set_password:1 diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index bfc6a379f..0530ca00f 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -2583,14 +2583,20 @@ int tweak_tls13_certificate_msg_vector_len( } #endif /* MBEDTLS_TEST_HOOKS */ -typedef enum { - ECJPAKE_ERR_NONE, - ECJPAKE_ERR_UNITIALIZED_SSL_CONTEXT, - ECJPAKE_ERR_EMPTY_PASSWORD, - ECJPAKE_ERR_UNINITIALIZED_PWD_KEY, -} ecjpake_err_inj_step_t; - #define ECJPAKE_TEST_PWD "bla" + +#if defined( MBEDTLS_USE_PSA_CRYPTO ) +#define ECJPAKE_TEST_SET_PASSWORD( exp_ret_val ) \ + ret = ( use_opaque_arg ) ? \ + mbedtls_ssl_set_hs_ecjpake_password_opaque( &ssl, pwd_slot ) : \ + mbedtls_ssl_set_hs_ecjpake_password( &ssl, pwd_string, pwd_len ); \ + TEST_ASSERT( ret == exp_ret_val ) +#else +#define ECJPAKE_TEST_SET_PASSWORD( exp_ret_val ) \ + ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl, \ + pwd_string, pwd_len ); \ + TEST_ASSERT( ret == exp_ret_val ) +#endif /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -6191,9 +6197,7 @@ exit: /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ -void ssl_ecjpake_set_password( int use_opaque_arg, - int err_injection_step_arg, - int expected_error_arg ) +void ssl_ecjpake_set_password( int use_opaque_arg ) { mbedtls_ssl_context ssl; mbedtls_ssl_config conf; @@ -6204,15 +6208,14 @@ void ssl_ecjpake_set_password( int use_opaque_arg, #endif /* MBEDTLS_USE_PSA_CRYPTO */ const unsigned char pwd_string[ sizeof(ECJPAKE_TEST_PWD) ] = ""; size_t pwd_len = 0; - ecjpake_err_inj_step_t err_injection_step = err_injection_step_arg; int ret; USE_PSA_INIT( ); mbedtls_ssl_init( &ssl ); - if( err_injection_step == ECJPAKE_ERR_UNITIALIZED_SSL_CONTEXT ) - goto run_test; + /* test with uninitalized SSL context */ + ECJPAKE_TEST_SET_PASSWORD( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); mbedtls_ssl_config_init( &conf ); @@ -6224,8 +6227,8 @@ void ssl_ecjpake_set_password( int use_opaque_arg, TEST_ASSERT( mbedtls_ssl_setup( &ssl, &conf ) == 0 ); - if( err_injection_step == ECJPAKE_ERR_EMPTY_PASSWORD ) - goto run_test; + /* test with empty password */ + ECJPAKE_TEST_SET_PASSWORD( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); pwd_len = strlen( ECJPAKE_TEST_PWD ); memcpy( (void*) pwd_string, ECJPAKE_TEST_PWD, pwd_len ); @@ -6233,8 +6236,8 @@ void ssl_ecjpake_set_password( int use_opaque_arg, #if defined( MBEDTLS_USE_PSA_CRYPTO ) if( use_opaque_arg ) { - if( err_injection_step == ECJPAKE_ERR_UNINITIALIZED_PWD_KEY ) - goto run_test; + /* test with uninitialized password key */ + ECJPAKE_TEST_SET_PASSWORD( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; @@ -6247,16 +6250,12 @@ void ssl_ecjpake_set_password( int use_opaque_arg, } #endif /* MBEDTLS_USE_PSA_CRYPTO */ -run_test: -#if defined( MBEDTLS_USE_PSA_CRYPTO ) - ret = ( use_opaque_arg ) ? - mbedtls_ssl_set_hs_ecjpake_password_opaque( &ssl, pwd_slot ) : - mbedtls_ssl_set_hs_ecjpake_password( &ssl, pwd_string, pwd_len ); -#else /* MBEDTLS_USE_PSA_CRYPTO */ - ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl, pwd_string, pwd_len ); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - TEST_EQUAL( ret, expected_error_arg ); + /* final check which should work without errors */ + ECJPAKE_TEST_SET_PASSWORD( 0 ); +#if defined( MBEDTLS_USE_PSA_CRYPTO ) + psa_destroy_key( pwd_slot ); +#endif /* MBEDTLS_USE_PSA_CRYPTO */ mbedtls_ssl_free( &ssl ); mbedtls_ssl_config_free( &conf ); From d6feb208694f33b6e612351ff02c7b061335cdef Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 2 Dec 2022 14:28:49 +0100 Subject: [PATCH 13/28] test: pake: allow opaque password only when USE_PSA is enabled Signed-off-by: Valerio Setti --- programs/ssl/ssl_client2.c | 15 +++++++++++++-- programs/ssl/ssl_server2.c | 15 +++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 736bc5123..f7b66aeac 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -319,12 +319,17 @@ int main( void ) #endif #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#if defined(MBEDTLS_USE_PSA_CRYPTO) #define USAGE_ECJPAKE \ " ecjpake_pw=%%s default: none (disabled)\n" \ " ecjpake_pw_opaque=%%d default: 0 (disabled)\n" -#else +#else /* MBEDTLS_USE_PSA_CRYPTO */ +#define USAGE_ECJPAKE \ + " ecjpake_pw=%%s default: none (disabled)\n" +#endif /* MBEDTLS_USE_PSA_CRYPTO */ +#else /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #define USAGE_ECJPAKE "" -#endif +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_ECP_RESTARTABLE) #define USAGE_ECRESTART \ @@ -494,7 +499,9 @@ struct options const char *psk; /* the pre-shared key */ const char *psk_identity; /* the pre-shared key identity */ const char *ecjpake_pw; /* the EC J-PAKE password */ +#if defined(MBEDTLS_USE_PSA_CRYPTO) int ecjpake_pw_opaque; /* set to 1 to use the opaque method for setting the password */ +#endif int ec_max_ops; /* EC consecutive operations limit */ int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */ #if defined(MBEDTLS_SSL_PROTO_TLS1_3) @@ -926,7 +933,9 @@ int main( int argc, char *argv[] ) #endif opt.psk_identity = DFL_PSK_IDENTITY; opt.ecjpake_pw = DFL_ECJPAKE_PW; +#if defined(MBEDTLS_USE_PSA_CRYPTO) opt.ecjpake_pw_opaque = DFL_ECJPAKE_PW_OPAQUE; +#endif opt.ec_max_ops = DFL_EC_MAX_OPS; opt.force_ciphersuite[0]= DFL_FORCE_CIPHER; #if defined(MBEDTLS_SSL_PROTO_TLS1_3) @@ -1102,8 +1111,10 @@ int main( int argc, char *argv[] ) opt.psk_identity = q; else if( strcmp( p, "ecjpake_pw" ) == 0 ) opt.ecjpake_pw = q; +#if defined(MBEDTLS_USE_PSA_CRYPTO) else if( strcmp( p, "ecjpake_pw_opaque" ) == 0 ) opt.ecjpake_pw_opaque = atoi( q ); +#endif else if( strcmp( p, "ec_max_ops" ) == 0 ) opt.ec_max_ops = atoi( q ); else if( strcmp( p, "force_ciphersuite" ) == 0 ) diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 6db20c66e..3b5ca73ca 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -419,12 +419,17 @@ int main( void ) #endif #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#if defined(MBEDTLS_USE_PSA_CRYPTO) #define USAGE_ECJPAKE \ " ecjpake_pw=%%s default: none (disabled)\n" \ " ecjpake_pw_opaque=%%d default: 0 (disabled)\n" -#else +#else /* MBEDTLS_USE_PSA_CRYPTO */ +#define USAGE_ECJPAKE \ + " ecjpake_pw=%%s default: none (disabled)\n" +#endif /* MBEDTLS_USE_PSA_CRYPTO */ +#else /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #define USAGE_ECJPAKE "" -#endif +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_ECP_C) #define USAGE_CURVES \ @@ -623,7 +628,9 @@ struct options const char *psk_identity; /* the pre-shared key identity */ char *psk_list; /* list of PSK id/key pairs for callback */ const char *ecjpake_pw; /* the EC J-PAKE password */ +#if defined(MBEDTLS_USE_PSA_CRYPTO) int ecjpake_pw_opaque; /* set to 1 to use the opaque method for setting the password */ +#endif int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */ #if defined(MBEDTLS_SSL_PROTO_TLS1_3) int tls13_kex_modes; /* supported TLS 1.3 key exchange modes */ @@ -1668,7 +1675,9 @@ int main( int argc, char *argv[] ) opt.psk_identity = DFL_PSK_IDENTITY; opt.psk_list = DFL_PSK_LIST; opt.ecjpake_pw = DFL_ECJPAKE_PW; +#if defined(MBEDTLS_USE_PSA_CRYPTO) opt.ecjpake_pw_opaque = DFL_ECJPAKE_PW_OPAQUE; +#endif opt.force_ciphersuite[0]= DFL_FORCE_CIPHER; #if defined(MBEDTLS_SSL_PROTO_TLS1_3) opt.tls13_kex_modes = DFL_TLS1_3_KEX_MODES; @@ -1872,8 +1881,10 @@ int main( int argc, char *argv[] ) opt.psk_list = q; else if( strcmp( p, "ecjpake_pw" ) == 0 ) opt.ecjpake_pw = q; +#if defined(MBEDTLS_USE_PSA_CRYPTO) else if( strcmp( p, "ecjpake_pw_opaque" ) == 0 ) opt.ecjpake_pw_opaque = atoi( q ); +#endif else if( strcmp( p, "force_ciphersuite" ) == 0 ) { opt.force_ciphersuite[0] = mbedtls_ssl_get_ciphersuite_id( q ); From 70e029006d6907cbc528664660e30a591464ed7e Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 2 Dec 2022 16:21:56 +0100 Subject: [PATCH 14/28] test: pake: fix mixed testing in test_tls1_2_ecjpake_compatibility Signed-off-by: Valerio Setti --- tests/scripts/all.sh | 12 ++++++++---- tests/ssl-opt.sh | 6 +++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 435ea232d..780f996a3 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -1455,10 +1455,14 @@ component_test_tls1_2_ecjpake_compatibility() { 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 -e ECJPAKE_OPAQUE_PW - msg "test: client w/o USE_PSA - server w/ USE_PSA" - P_CLI=../c2_no_use_psa tests/ssl-opt.sh -f ECJPAKE -e ECJPAKE_OPAQUE_PW + msg "test: server w/o USE_PSA - client w/ USE_PSA, text password" + P_SRV=../s2_no_use_psa tests/ssl-opt.sh -f "ECJPAKE: working, TLS" + msg "test: server w/o USE_PSA - client w/ USE_PSA, opaque password" + P_SRV=../s2_no_use_psa tests/ssl-opt.sh -f "ECJPAKE: opaque password client only, working, TLS" + msg "test: client w/o USE_PSA - server w/ USE_PSA, text password" + P_CLI=../c2_no_use_psa tests/ssl-opt.sh -f "ECJPAKE: working, TLS" + msg "test: client w/o USE_PSA - server w/ USE_PSA, opaque password" + P_CLI=../c2_no_use_psa tests/ssl-opt.sh -f "ECJPAKE: opaque password server only, working, TLS" rm s2_no_use_psa c2_no_use_psa } diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 547a0f55c..3906d3ed1 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -8010,7 +8010,7 @@ run_test "ECJPAKE: working, TLS" \ requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED requires_config_enabled MBEDTLS_USE_PSA_CRYPTO requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 -run_test "ECJPAKE_OPAQUE_PW: working, TLS, opaque password client+server" \ +run_test "ECJPAKE: opaque password client+server, working, TLS" \ "$P_SRV debug_level=3 ecjpake_pw=bla ecjpake_pw_opaque=1" \ "$P_CLI debug_level=3 ecjpake_pw=bla ecjpake_pw_opaque=1\ force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \ @@ -8031,7 +8031,7 @@ run_test "ECJPAKE_OPAQUE_PW: working, TLS, opaque password client+server" \ requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED requires_config_enabled MBEDTLS_USE_PSA_CRYPTO requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 -run_test "ECJPAKE_OPAQUE_PW: working, TLS, opaque password client only" \ +run_test "ECJPAKE: opaque password client only, working, TLS" \ "$P_SRV debug_level=3 ecjpake_pw=bla" \ "$P_CLI debug_level=3 ecjpake_pw=bla ecjpake_pw_opaque=1\ force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \ @@ -8052,7 +8052,7 @@ run_test "ECJPAKE_OPAQUE_PW: working, TLS, opaque password client only" \ requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED requires_config_enabled MBEDTLS_USE_PSA_CRYPTO requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 -run_test "ECJPAKE_OPAQUE_PW: working, TLS, opaque password server only" \ +run_test "ECJPAKE: opaque password server only, working, TLS" \ "$P_SRV debug_level=3 ecjpake_pw=bla ecjpake_pw_opaque=1" \ "$P_CLI debug_level=3 ecjpake_pw=bla\ force_ciphersuite=TLS-ECJPAKE-WITH-AES-128-CCM-8" \ From 2e1e43fb82e1f914934e2c17f8be92b1f8bd247f Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 6 Dec 2022 11:41:57 +0100 Subject: [PATCH 15/28] test: pake: fix error in ssl_ecjpake_set_password() Signed-off-by: Valerio Setti --- tests/suites/test_suite_ssl.function | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 0530ca00f..4f8ef524d 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -6206,7 +6206,7 @@ void ssl_ecjpake_set_password( int use_opaque_arg ) #else /* MBEDTLS_USE_PSA_CRYPTO */ (void) use_opaque_arg; #endif /* MBEDTLS_USE_PSA_CRYPTO */ - const unsigned char pwd_string[ sizeof(ECJPAKE_TEST_PWD) ] = ""; + unsigned char pwd_string[ sizeof(ECJPAKE_TEST_PWD) ] = ""; size_t pwd_len = 0; int ret; @@ -6231,7 +6231,7 @@ void ssl_ecjpake_set_password( int use_opaque_arg ) ECJPAKE_TEST_SET_PASSWORD( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); pwd_len = strlen( ECJPAKE_TEST_PWD ); - memcpy( (void*) pwd_string, ECJPAKE_TEST_PWD, pwd_len ); + memcpy( pwd_string, ECJPAKE_TEST_PWD, pwd_len ); #if defined( MBEDTLS_USE_PSA_CRYPTO ) if( use_opaque_arg ) From ba22c9c1ff453f5d1585313207d158b34c4a1fb5 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 6 Dec 2022 11:42:33 +0100 Subject: [PATCH 16/28] test: pake: remove useless check in ssl_ecjpake_set_password() Signed-off-by: Valerio Setti --- tests/suites/test_suite_ssl.function | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 4f8ef524d..c3b6015a3 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -6227,7 +6227,7 @@ void ssl_ecjpake_set_password( int use_opaque_arg ) TEST_ASSERT( mbedtls_ssl_setup( &ssl, &conf ) == 0 ); - /* test with empty password */ + /* test with empty password or unitialized password key (depending on use_opaque_arg) */ ECJPAKE_TEST_SET_PASSWORD( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); pwd_len = strlen( ECJPAKE_TEST_PWD ); @@ -6236,9 +6236,6 @@ void ssl_ecjpake_set_password( int use_opaque_arg ) #if defined( MBEDTLS_USE_PSA_CRYPTO ) if( use_opaque_arg ) { - /* test with uninitialized password key */ - ECJPAKE_TEST_SET_PASSWORD( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE ); From c689ed86330d8b16010e4c4a9faf9b848a237676 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 7 Dec 2022 14:40:38 +0100 Subject: [PATCH 17/28] tls: pake: minor adjustments Signed-off-by: Valerio Setti --- include/mbedtls/ssl.h | 3 +-- library/ssl_tls.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 97caad881..6d453ad1c 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -3864,8 +3864,7 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, /** * \brief Set the EC J-PAKE opaque password for current handshake. * - * \note The input key in not copied, so the caller must not destroy - * it before the handshake is over. + * \note The key must remain valid until the handshake is over. * * \note The SSL context needs to be already set up. The right place * to call this function is between \c mbedtls_ssl_setup() or diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 1438124dd..810db243d 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1932,11 +1932,6 @@ int mbedtls_ssl_set_hs_ecjpake_password_opaque( mbedtls_ssl_context *ssl, if( ssl->handshake == NULL || ssl->conf == NULL ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) - psa_role = PSA_PAKE_ROLE_SERVER; - else - psa_role = PSA_PAKE_ROLE_CLIENT; - if( mbedtls_svc_key_id_is_null( pwd ) ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); ssl->handshake->psa_pake_password = pwd; @@ -1952,6 +1947,11 @@ int mbedtls_ssl_set_hs_ecjpake_password_opaque( mbedtls_ssl_context *ssl, if( status != PSA_SUCCESS ) goto error; + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) + psa_role = PSA_PAKE_ROLE_SERVER; + else + psa_role = PSA_PAKE_ROLE_CLIENT; + status = psa_pake_set_role( &ssl->handshake->psa_pake_ctx, psa_role ); if( status != PSA_SUCCESS ) goto error; @@ -1979,15 +1979,15 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, if( ssl->handshake == NULL || ssl->conf == NULL ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + /* Empty password is not valid */ + if( ( pw == NULL) || ( pw_len == 0 ) ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) role = MBEDTLS_ECJPAKE_SERVER; else role = MBEDTLS_ECJPAKE_CLIENT; - /* Empty password is not valid */ - if( ( pw == NULL) || ( pw_len == 0 ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - return( mbedtls_ecjpake_setup( &ssl->handshake->ecjpake_ctx, role, MBEDTLS_MD_SHA256, From d5fa0bfb859fe2410bbafa9714bc01ac8f4ddd21 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 7 Dec 2022 15:27:08 +0100 Subject: [PATCH 18/28] test: pake: check psa key validity before destroying it Signed-off-by: Valerio Setti --- programs/ssl/ssl_client2.c | 11 ++++++++++- programs/ssl/ssl_server2.c | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index f7b66aeac..54e9861cc 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -3331,7 +3331,16 @@ exit: defined(MBEDTLS_USE_PSA_CRYPTO) if( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) { - psa_destroy_key( ecjpake_pw_slot ); + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; + + /* Ensure the key is still valid before destroying it */ + status = psa_get_key_attributes( ecjpake_pw_slot, &key_attr ); + if( status == PSA_SUCCESS && + PSA_ALG_IS_PAKE( psa_get_key_algorithm( &key_attr ) ) ) + { + psa_destroy_key( ecjpake_pw_slot ); + } + psa_reset_key_attributes( &key_attr ); } #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO */ diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 3b5ca73ca..004616fd1 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -4441,7 +4441,16 @@ exit: defined(MBEDTLS_USE_PSA_CRYPTO) if( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) { - psa_destroy_key( ecjpake_pw_slot ); + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; + + /* Ensure the key is still valid before destroying it */ + status = psa_get_key_attributes( ecjpake_pw_slot, &key_attr ); + if( status == PSA_SUCCESS && + PSA_ALG_IS_PAKE( psa_get_key_algorithm( &key_attr ) ) ) + { + psa_destroy_key( ecjpake_pw_slot ); + } + psa_reset_key_attributes( &key_attr ); } #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO */ From f11e05a41307275e91a91b23ebe0550557e57da1 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 7 Dec 2022 15:41:05 +0100 Subject: [PATCH 19/28] test: psa: minor improvements to test Signed-off-by: Valerio Setti --- tests/ssl-opt.sh | 6 ++++++ tests/suites/test_suite_ssl.function | 15 +++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 3906d3ed1..03f5955e9 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -7989,6 +7989,8 @@ run_test "ECJPAKE: server not configured" \ -C "found ecjpake_kkpp extension" \ -s "SSL - The handshake negotiation failed" +# Note: if the name of this test is changed, then please adjust the corresponding +# filtering label in "test_tls1_2_ecjpake_compatibility" (in "all.sh") requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 run_test "ECJPAKE: working, TLS" \ @@ -8028,6 +8030,8 @@ run_test "ECJPAKE: opaque password client+server, working, TLS" \ -S "SSL - The handshake negotiation failed" \ -S "SSL - Verification of the message MAC failed" +# Note: if the name of this test is changed, then please adjust the corresponding +# filtering label in "test_tls1_2_ecjpake_compatibility" (in "all.sh") requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED requires_config_enabled MBEDTLS_USE_PSA_CRYPTO requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 @@ -8049,6 +8053,8 @@ run_test "ECJPAKE: opaque password client only, working, TLS" \ -S "SSL - The handshake negotiation failed" \ -S "SSL - Verification of the message MAC failed" +# Note: if the name of this test is changed, then please adjust the corresponding +# filtering label in "test_tls1_2_ecjpake_compatibility" (in "all.sh") requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED requires_config_enabled MBEDTLS_USE_PSA_CRYPTO requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index c3b6015a3..3d9a6fd73 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -2590,12 +2590,12 @@ int tweak_tls13_certificate_msg_vector_len( ret = ( use_opaque_arg ) ? \ mbedtls_ssl_set_hs_ecjpake_password_opaque( &ssl, pwd_slot ) : \ mbedtls_ssl_set_hs_ecjpake_password( &ssl, pwd_string, pwd_len ); \ - TEST_ASSERT( ret == exp_ret_val ) + TEST_EQUAL( ret, exp_ret_val ) #else #define ECJPAKE_TEST_SET_PASSWORD( exp_ret_val ) \ ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl, \ pwd_string, pwd_len ); \ - TEST_ASSERT( ret == exp_ret_val ) + TEST_EQUAL( ret, exp_ret_val ) #endif /* END_HEADER */ @@ -6219,13 +6219,12 @@ void ssl_ecjpake_set_password( int use_opaque_arg ) mbedtls_ssl_config_init( &conf ); - TEST_ASSERT( mbedtls_ssl_config_defaults( &conf, + TEST_EQUAL( mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, - MBEDTLS_SSL_PRESET_DEFAULT ) - == 0 ); + MBEDTLS_SSL_PRESET_DEFAULT ), 0 ); - TEST_ASSERT( mbedtls_ssl_setup( &ssl, &conf ) == 0 ); + TEST_EQUAL( mbedtls_ssl_setup( &ssl, &conf ), 0 ); /* test with empty password or unitialized password key (depending on use_opaque_arg) */ ECJPAKE_TEST_SET_PASSWORD( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); @@ -6242,8 +6241,8 @@ void ssl_ecjpake_set_password( int use_opaque_arg ) psa_set_key_algorithm( &attributes, PSA_ALG_JPAKE ); psa_set_key_type( &attributes, PSA_KEY_TYPE_PASSWORD ); - TEST_ASSERT( psa_import_key( &attributes, pwd_string, - pwd_len, &pwd_slot ) == PSA_SUCCESS ); + PSA_ASSERT( psa_import_key( &attributes, pwd_string, + pwd_len, &pwd_slot ) ); } #endif /* MBEDTLS_USE_PSA_CRYPTO */ From 70d1fa538a864ee5201e04a3c0f64b4d86e0021b Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 7 Dec 2022 16:20:27 +0100 Subject: [PATCH 20/28] tls: pake: fix missing return values check Signed-off-by: Valerio Setti --- library/ssl_tls.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 810db243d..c5a8d2478 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1908,7 +1908,7 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); } - psa_pake_set_password_key( &ssl->handshake->psa_pake_ctx, + status = psa_pake_set_password_key( &ssl->handshake->psa_pake_ctx, ssl->handshake->psa_pake_password ); if( status != PSA_SUCCESS ) { @@ -1956,7 +1956,7 @@ int mbedtls_ssl_set_hs_ecjpake_password_opaque( mbedtls_ssl_context *ssl, if( status != PSA_SUCCESS ) goto error; - psa_pake_set_password_key( &ssl->handshake->psa_pake_ctx, + status = psa_pake_set_password_key( &ssl->handshake->psa_pake_ctx, ssl->handshake->psa_pake_password ); if( status != PSA_SUCCESS ) goto error; From ae7fe7ee536580f941b02af2acd81936ee337523 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 7 Dec 2022 17:36:59 +0100 Subject: [PATCH 21/28] tls: pake: avoid useless psa_pake_abort in setting opaque password 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 c5a8d2478..57cfe424e 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1945,7 +1945,7 @@ int mbedtls_ssl_set_hs_ecjpake_password_opaque( mbedtls_ssl_context *ssl, status = psa_pake_setup( &ssl->handshake->psa_pake_ctx, &cipher_suite ); if( status != PSA_SUCCESS ) - goto error; + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) psa_role = PSA_PAKE_ROLE_SERVER; From 2a3ffb4203b952a7de3512db311e45e6d4e332f3 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 8 Dec 2022 16:27:46 +0100 Subject: [PATCH 22/28] test: pake: add test for opaque password key Signed-off-by: Valerio Setti --- tests/suites/test_suite_ssl.function | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 3d9a6fd73..01d4fe357 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -6237,10 +6237,21 @@ void ssl_ecjpake_set_password( int use_opaque_arg ) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE ); + /* First try with an invalid usage */ + psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH ); psa_set_key_algorithm( &attributes, PSA_ALG_JPAKE ); psa_set_key_type( &attributes, PSA_KEY_TYPE_PASSWORD ); + PSA_ASSERT( psa_import_key( &attributes, pwd_string, + pwd_len, &pwd_slot ) ); + + ECJPAKE_TEST_SET_PASSWORD( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + + psa_destroy_key( pwd_slot ); + + /* Then set the correct usage */ + psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DERIVE ); + PSA_ASSERT( psa_import_key( &attributes, pwd_string, pwd_len, &pwd_slot ) ); } From eb3f788b032a514875320db819b67625cd9fedb8 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 8 Dec 2022 18:42:58 +0100 Subject: [PATCH 23/28] tls: pake: do not destroy password key in TLS Signed-off-by: Valerio Setti --- library/ssl_tls.c | 14 ++++++++++---- programs/ssl/ssl_client2.c | 18 +++++++----------- programs/ssl/ssl_server2.c | 18 +++++++----------- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 57cfe424e..259d08884 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1934,7 +1934,6 @@ int mbedtls_ssl_set_hs_ecjpake_password_opaque( mbedtls_ssl_context *ssl, if( mbedtls_svc_key_id_is_null( pwd ) ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - ssl->handshake->psa_pake_password = pwd; psa_pake_cs_set_algorithm( &cipher_suite, PSA_ALG_JPAKE ); psa_pake_cs_set_primitive( &cipher_suite, @@ -1956,8 +1955,7 @@ int mbedtls_ssl_set_hs_ecjpake_password_opaque( mbedtls_ssl_context *ssl, if( status != PSA_SUCCESS ) goto error; - status = psa_pake_set_password_key( &ssl->handshake->psa_pake_ctx, - ssl->handshake->psa_pake_password ); + status = psa_pake_set_password_key( &ssl->handshake->psa_pake_ctx, pwd ); if( status != PSA_SUCCESS ) goto error; @@ -4037,7 +4035,15 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ) #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 ); + /* + * Opaque keys are not stored in the handshake's data and it's the user + * responsibility to destroy them. Clear ones, instead, are created by + * the TLS library and should be destroyed at the same level + */ + if( ! mbedtls_svc_key_id_is_null( handshake->psa_pake_password ) ) + { + psa_destroy_key( handshake->psa_pake_password ); + } handshake->psa_pake_password = MBEDTLS_SVC_KEY_ID_INIT; #else mbedtls_ecjpake_free( &handshake->ecjpake_ctx ); diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 54e9861cc..13ffa3d53 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -3329,18 +3329,14 @@ exit: #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ defined(MBEDTLS_USE_PSA_CRYPTO) - if( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) + /* + * In case opaque keys it's the user responsibility to keep the key valid + * for the duration of the handshake and destroy it at the end + */ + if( ( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) && + ( ! mbedtls_svc_key_id_is_null( ecjpake_pw_slot ) ) ) { - psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; - - /* Ensure the key is still valid before destroying it */ - status = psa_get_key_attributes( ecjpake_pw_slot, &key_attr ); - if( status == PSA_SUCCESS && - PSA_ALG_IS_PAKE( psa_get_key_algorithm( &key_attr ) ) ) - { - psa_destroy_key( ecjpake_pw_slot ); - } - psa_reset_key_attributes( &key_attr ); + psa_destroy_key( ecjpake_pw_slot ); } #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO */ diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 004616fd1..4b195c4f1 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -4439,18 +4439,14 @@ exit: #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ defined(MBEDTLS_USE_PSA_CRYPTO) - if( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) + /* + * In case opaque keys it's the user responsibility to keep the key valid + * for the duration of the handshake and destroy it at the end + */ + if( ( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) && + ( ! mbedtls_svc_key_id_is_null( ecjpake_pw_slot ) ) ) { - psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; - - /* Ensure the key is still valid before destroying it */ - status = psa_get_key_attributes( ecjpake_pw_slot, &key_attr ); - if( status == PSA_SUCCESS && - PSA_ALG_IS_PAKE( psa_get_key_algorithm( &key_attr ) ) ) - { - psa_destroy_key( ecjpake_pw_slot ); - } - psa_reset_key_attributes( &key_attr ); + psa_destroy_key( ecjpake_pw_slot ); } #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO */ From 9d313dfeebab6e1958d458cf9df5bc2b3ea686a4 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 9 Dec 2022 11:38:59 +0100 Subject: [PATCH 24/28] test: pake: minor enhancement for opaque keys Signed-off-by: Valerio Setti --- tests/suites/test_suite_ssl.function | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 01d4fe357..22620411f 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -6247,6 +6247,9 @@ void ssl_ecjpake_set_password( int use_opaque_arg ) ECJPAKE_TEST_SET_PASSWORD( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + /* check that the opaque key is still valid after failure */ + TEST_ASSERT( ! mbedtls_svc_key_id_is_null( pwd_slot ) ); + psa_destroy_key( pwd_slot ); /* Then set the correct usage */ From 016f682796da67f86c6ba4e9b0d44ff214a42012 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 9 Dec 2022 14:17:50 +0100 Subject: [PATCH 25/28] tls: pake: small code refactoring for password setting functions Signed-off-by: Valerio Setti --- library/ssl_tls.c | 117 +++++++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 69 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 259d08884..dda140ef7 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1852,27 +1852,55 @@ void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl, #endif #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -/* - * 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 ) -{ - 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; - if( ssl->handshake == NULL || ssl->conf == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); +#if defined(MBEDTLS_USE_PSA_CRYPTO) +static psa_status_t mbedtls_ssl_set_hs_ecjpake_password_common( + mbedtls_ssl_context *ssl, + mbedtls_svc_key_id_t pwd ) +{ + psa_status_t status; + psa_pake_role_t psa_role; + psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); + + 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 ) + return status; if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) psa_role = PSA_PAKE_ROLE_SERVER; else psa_role = PSA_PAKE_ROLE_CLIENT; + status = psa_pake_set_role( &ssl->handshake->psa_pake_ctx, psa_role ); + if( status != PSA_SUCCESS ) + return status; + + status = psa_pake_set_password_key( &ssl->handshake->psa_pake_ctx, pwd ); + if( status != PSA_SUCCESS ) + return status; + + ssl->handshake->psa_pake_ctx_is_ok = 1; + + return ( PSA_SUCCESS ); +} + +int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, + const unsigned char *pw, + size_t pw_len ) +{ + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status; + + if( ssl->handshake == NULL || ssl->conf == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + /* Empty password is not valid */ if( ( pw == NULL) || ( pw_len == 0 ) ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); @@ -1886,21 +1914,8 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, 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 ); + status = mbedtls_ssl_set_hs_ecjpake_password_common( ssl, + ssl->handshake->psa_pake_password ); if( status != PSA_SUCCESS ) { psa_destroy_key( ssl->handshake->psa_pake_password ); @@ -1908,25 +1923,12 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); } - status = 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 ); } int mbedtls_ssl_set_hs_ecjpake_password_opaque( mbedtls_ssl_context *ssl, mbedtls_svc_key_id_t pwd ) { - psa_pake_cipher_suite_t cipher_suite = psa_pake_cipher_suite_init(); - psa_pake_role_t psa_role; psa_status_t status; if( ssl->handshake == NULL || ssl->conf == NULL ) @@ -1935,37 +1937,14 @@ int mbedtls_ssl_set_hs_ecjpake_password_opaque( mbedtls_ssl_context *ssl, if( mbedtls_svc_key_id_is_null( pwd ) ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - 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 ); + status = mbedtls_ssl_set_hs_ecjpake_password_common( ssl, pwd ); if( status != PSA_SUCCESS ) + { + psa_pake_abort( &ssl->handshake->psa_pake_ctx ); return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) - psa_role = PSA_PAKE_ROLE_SERVER; - else - psa_role = PSA_PAKE_ROLE_CLIENT; - - status = psa_pake_set_role( &ssl->handshake->psa_pake_ctx, psa_role ); - if( status != PSA_SUCCESS ) - goto error; - - status = psa_pake_set_password_key( &ssl->handshake->psa_pake_ctx, pwd ); - if( status != PSA_SUCCESS ) - goto error; - - ssl->handshake->psa_pake_ctx_is_ok = 1; + } return( 0 ); - -error: - psa_pake_abort( &ssl->handshake->psa_pake_ctx ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); } #else /* MBEDTLS_USE_PSA_CRYPTO */ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, From 31e99bb0c751da69a2190b0babb02ce707be67d3 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 9 Dec 2022 14:35:10 +0100 Subject: [PATCH 26/28] test: pake: fix: destroy key only in opaque case Signed-off-by: Valerio Setti --- tests/suites/test_suite_ssl.function | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 22620411f..7163d226c 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -6264,7 +6264,10 @@ void ssl_ecjpake_set_password( int use_opaque_arg ) ECJPAKE_TEST_SET_PASSWORD( 0 ); #if defined( MBEDTLS_USE_PSA_CRYPTO ) - psa_destroy_key( pwd_slot ); + if( use_opaque_arg ) + { + psa_destroy_key( pwd_slot ); + } #endif /* MBEDTLS_USE_PSA_CRYPTO */ mbedtls_ssl_free( &ssl ); mbedtls_ssl_config_free( &conf ); From 785116a5bedac26290e6ac5370f8633762c9cd0b Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 12 Dec 2022 11:59:25 +0100 Subject: [PATCH 27/28] test: pake: modify opaque key verification before destruction Signed-off-by: Valerio Setti --- programs/ssl/ssl_client2.c | 12 +++++++++--- programs/ssl/ssl_server2.c | 12 +++++++++--- tests/suites/test_suite_ssl.function | 4 +++- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 13ffa3d53..02fbbd341 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -3333,10 +3333,16 @@ exit: * In case opaque keys it's the user responsibility to keep the key valid * for the duration of the handshake and destroy it at the end */ - if( ( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) && - ( ! mbedtls_svc_key_id_is_null( ecjpake_pw_slot ) ) ) + if( ( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) ) { - psa_destroy_key( ecjpake_pw_slot ); + psa_key_attributes_t check_attributes = PSA_KEY_ATTRIBUTES_INIT; + + /* Verify that the key is still valid before destroying it */ + if( psa_get_key_attributes( ecjpake_pw_slot, &check_attributes ) == + PSA_SUCCESS ) + { + psa_destroy_key( ecjpake_pw_slot ); + } } #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO */ diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 4b195c4f1..d8c20c29f 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -4443,10 +4443,16 @@ exit: * In case opaque keys it's the user responsibility to keep the key valid * for the duration of the handshake and destroy it at the end */ - if( ( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) && - ( ! mbedtls_svc_key_id_is_null( ecjpake_pw_slot ) ) ) + if( ( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE ) ) { - psa_destroy_key( ecjpake_pw_slot ); + psa_key_attributes_t check_attributes = PSA_KEY_ATTRIBUTES_INIT; + + /* Verify that the key is still valid before destroying it */ + if( psa_get_key_attributes( ecjpake_pw_slot, &check_attributes ) == + PSA_SUCCESS ) + { + psa_destroy_key( ecjpake_pw_slot ); + } } #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO */ diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 7163d226c..33231b91e 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -6236,6 +6236,7 @@ void ssl_ecjpake_set_password( int use_opaque_arg ) if( use_opaque_arg ) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_attributes_t check_attributes = PSA_KEY_ATTRIBUTES_INIT; /* First try with an invalid usage */ psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH ); @@ -6248,7 +6249,8 @@ void ssl_ecjpake_set_password( int use_opaque_arg ) ECJPAKE_TEST_SET_PASSWORD( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); /* check that the opaque key is still valid after failure */ - TEST_ASSERT( ! mbedtls_svc_key_id_is_null( pwd_slot ) ); + TEST_EQUAL( psa_get_key_attributes( pwd_slot, &check_attributes ), + PSA_SUCCESS ); psa_destroy_key( pwd_slot ); From d75c5c440560918cb311e9796b621e174737ccac Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 13 Dec 2022 11:51:32 +0100 Subject: [PATCH 28/28] test: pake: fail in case the opaque key is destroyed unexpectedly Signed-off-by: Valerio Setti --- programs/ssl/ssl_client2.c | 8 +++++++- programs/ssl/ssl_server2.c | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 02fbbd341..02ee7cf69 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -3338,8 +3338,14 @@ exit: psa_key_attributes_t check_attributes = PSA_KEY_ATTRIBUTES_INIT; /* Verify that the key is still valid before destroying it */ - if( psa_get_key_attributes( ecjpake_pw_slot, &check_attributes ) == + if( psa_get_key_attributes( ecjpake_pw_slot, &check_attributes ) != PSA_SUCCESS ) + { + if( ret == 0 ) + ret = 1; + mbedtls_printf( "The EC J-PAKE password key has unexpectedly been already destroyed\n" ); + } + else { psa_destroy_key( ecjpake_pw_slot ); } diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index d8c20c29f..06c80908c 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -4448,8 +4448,14 @@ exit: psa_key_attributes_t check_attributes = PSA_KEY_ATTRIBUTES_INIT; /* Verify that the key is still valid before destroying it */ - if( psa_get_key_attributes( ecjpake_pw_slot, &check_attributes ) == + if( psa_get_key_attributes( ecjpake_pw_slot, &check_attributes ) != PSA_SUCCESS ) + { + if( ret == 0 ) + ret = 1; + mbedtls_printf( "The EC J-PAKE password key has unexpectedly been already destroyed\n" ); + } + else { psa_destroy_key( ecjpake_pw_slot ); }