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