Merge pull request #6680 from valeriosetti/issue6599

Allow isolation of EC J-PAKE password when used in TLS
This commit is contained in:
Manuel Pégourié-Gonnard 2022-12-14 11:04:33 +01:00 committed by GitHub
commit c98624af3c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 457 additions and 58 deletions

View file

@ -3899,6 +3899,23 @@ void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf,
int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
const unsigned char *pw, const unsigned char *pw,
size_t pw_len ); size_t pw_len );
/**
* \brief Set the EC J-PAKE opaque password for current handshake.
*
* \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
* \c mbedtls_ssl_reset() and \c mbedtls_ssl_handshake().
*
* \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 */ #endif /*MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_ALPN) #if defined(MBEDTLS_SSL_ALPN)

View file

@ -1863,27 +1863,55 @@ void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl,
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) #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 ) #if defined(MBEDTLS_USE_PSA_CRYPTO)
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 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 ) if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
psa_role = PSA_PAKE_ROLE_SERVER; psa_role = PSA_PAKE_ROLE_SERVER;
else else
psa_role = PSA_PAKE_ROLE_CLIENT; 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 */ /* Empty password is not valid */
if( ( pw == NULL) || ( pw_len == 0 ) ) if( ( pw == NULL) || ( pw_len == 0 ) )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
@ -1897,29 +1925,7 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
if( status != PSA_SUCCESS ) if( status != PSA_SUCCESS )
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
psa_pake_cs_set_algorithm( &cipher_suite, PSA_ALG_JPAKE ); status = mbedtls_ssl_set_hs_ecjpake_password_common( ssl,
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 ); ssl->handshake->psa_pake_password );
if( status != PSA_SUCCESS ) if( status != PSA_SUCCESS )
{ {
@ -1928,7 +1934,26 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); 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_status_t status;
if( ssl->handshake == NULL || ssl->conf == NULL )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
if( mbedtls_svc_key_id_is_null( pwd ) )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
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 );
}
return( 0 ); return( 0 );
} }
@ -1942,6 +1967,10 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
if( ssl->handshake == NULL || ssl->conf == NULL ) if( ssl->handshake == NULL || ssl->conf == NULL )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 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 ) if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
role = MBEDTLS_ECJPAKE_SERVER; role = MBEDTLS_ECJPAKE_SERVER;
else else
@ -3996,7 +4025,15 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#if defined(MBEDTLS_USE_PSA_CRYPTO) #if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_pake_abort( &handshake->psa_pake_ctx ); psa_pake_abort( &handshake->psa_pake_ctx );
/*
* 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 ); psa_destroy_key( handshake->psa_pake_password );
}
handshake->psa_pake_password = MBEDTLS_SVC_KEY_ID_INIT; handshake->psa_pake_password = MBEDTLS_SVC_KEY_ID_INIT;
#else #else
mbedtls_ecjpake_free( &handshake->ecjpake_ctx ); mbedtls_ecjpake_free( &handshake->ecjpake_ctx );

View file

@ -68,6 +68,7 @@ int main( void )
#define DFL_PSK_OPAQUE 0 #define DFL_PSK_OPAQUE 0
#define DFL_PSK_IDENTITY "Client_identity" #define DFL_PSK_IDENTITY "Client_identity"
#define DFL_ECJPAKE_PW NULL #define DFL_ECJPAKE_PW NULL
#define DFL_ECJPAKE_PW_OPAQUE 0
#define DFL_EC_MAX_OPS -1 #define DFL_EC_MAX_OPS -1
#define DFL_FORCE_CIPHER 0 #define DFL_FORCE_CIPHER 0
#define DFL_TLS1_3_KEX_MODES MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_ALL #define DFL_TLS1_3_KEX_MODES MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_ALL
@ -318,11 +319,17 @@ int main( void )
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) #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 /* MBEDTLS_USE_PSA_CRYPTO */
#define USAGE_ECJPAKE \ #define USAGE_ECJPAKE \
" ecjpake_pw=%%s default: none (disabled)\n" " ecjpake_pw=%%s default: none (disabled)\n"
#else #endif /* MBEDTLS_USE_PSA_CRYPTO */
#else /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#define USAGE_ECJPAKE "" #define USAGE_ECJPAKE ""
#endif #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_ECP_RESTARTABLE) #if defined(MBEDTLS_ECP_RESTARTABLE)
#define USAGE_ECRESTART \ #define USAGE_ECRESTART \
@ -492,6 +499,9 @@ struct options
const char *psk; /* the pre-shared key */ const char *psk; /* the pre-shared key */
const char *psk_identity; /* the pre-shared key identity */ const char *psk_identity; /* the pre-shared key identity */
const char *ecjpake_pw; /* the EC J-PAKE password */ 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 ec_max_ops; /* EC consecutive operations limit */
int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */ int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
@ -824,6 +834,10 @@ int main( int argc, char *argv[] )
MBEDTLS_TLS_SRTP_UNSET MBEDTLS_TLS_SRTP_UNSET
}; };
#endif /* MBEDTLS_SSL_DTLS_SRTP */ #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) #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) ); mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
@ -919,6 +933,9 @@ int main( int argc, char *argv[] )
#endif #endif
opt.psk_identity = DFL_PSK_IDENTITY; opt.psk_identity = DFL_PSK_IDENTITY;
opt.ecjpake_pw = DFL_ECJPAKE_PW; 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.ec_max_ops = DFL_EC_MAX_OPS;
opt.force_ciphersuite[0]= DFL_FORCE_CIPHER; opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
@ -1094,6 +1111,10 @@ int main( int argc, char *argv[] )
opt.psk_identity = q; opt.psk_identity = q;
else if( strcmp( p, "ecjpake_pw" ) == 0 ) else if( strcmp( p, "ecjpake_pw" ) == 0 )
opt.ecjpake_pw = q; 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 ) else if( strcmp( p, "ec_max_ops" ) == 0 )
opt.ec_max_ops = atoi( q ); opt.ec_max_ops = atoi( q );
else if( strcmp( p, "force_ciphersuite" ) == 0 ) else if( strcmp( p, "force_ciphersuite" ) == 0 )
@ -2165,17 +2186,47 @@ int main( int argc, char *argv[] )
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( opt.ecjpake_pw != DFL_ECJPAKE_PW ) if( opt.ecjpake_pw != DFL_ECJPAKE_PW )
{
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if ( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE )
{
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;
}
mbedtls_printf( "using opaque password\n");
}
else
#endif /* MBEDTLS_USE_PSA_CRYPTO */
{ {
if( ( ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl, if( ( ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl,
(const unsigned char *) opt.ecjpake_pw, (const unsigned char *) opt.ecjpake_pw,
strlen( opt.ecjpake_pw ) ) ) != 0 ) strlen( opt.ecjpake_pw ) ) ) != 0 )
{ {
mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password returned %d\n\n", mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password returned %d\n\n", ret );
ret );
goto exit; goto exit;
} }
} }
#endif }
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
if( opt.context_crt_cb == 1 ) if( opt.context_crt_cb == 1 )
@ -3276,6 +3327,31 @@ exit:
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED && #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED &&
MBEDTLS_USE_PSA_CRYPTO */ MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
defined(MBEDTLS_USE_PSA_CRYPTO)
/*
* 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 ) )
{
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 )
{
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 );
}
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3) #if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
const char* message = mbedtls_test_helper_is_psa_leaking(); const char* message = mbedtls_test_helper_is_psa_leaking();
if( message ) if( message )

View file

@ -98,6 +98,7 @@ int main( void )
#define DFL_PSK_LIST_OPAQUE 0 #define DFL_PSK_LIST_OPAQUE 0
#define DFL_PSK_IDENTITY "Client_identity" #define DFL_PSK_IDENTITY "Client_identity"
#define DFL_ECJPAKE_PW NULL #define DFL_ECJPAKE_PW NULL
#define DFL_ECJPAKE_PW_OPAQUE 0
#define DFL_PSK_LIST NULL #define DFL_PSK_LIST NULL
#define DFL_FORCE_CIPHER 0 #define DFL_FORCE_CIPHER 0
#define DFL_TLS1_3_KEX_MODES MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_ALL #define DFL_TLS1_3_KEX_MODES MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_ALL
@ -419,11 +420,17 @@ int main( void )
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) #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 /* MBEDTLS_USE_PSA_CRYPTO */
#define USAGE_ECJPAKE \ #define USAGE_ECJPAKE \
" ecjpake_pw=%%s default: none (disabled)\n" " ecjpake_pw=%%s default: none (disabled)\n"
#else #endif /* MBEDTLS_USE_PSA_CRYPTO */
#else /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#define USAGE_ECJPAKE "" #define USAGE_ECJPAKE ""
#endif #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_EARLY_DATA) #if defined(MBEDTLS_SSL_EARLY_DATA)
#define USAGE_EARLY_DATA \ #define USAGE_EARLY_DATA \
@ -631,6 +638,9 @@ struct options
const char *psk_identity; /* the pre-shared key identity */ const char *psk_identity; /* the pre-shared key identity */
char *psk_list; /* list of PSK id/key pairs for callback */ char *psk_list; /* list of PSK id/key pairs for callback */
const char *ecjpake_pw; /* the EC J-PAKE password */ 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 */ int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
int tls13_kex_modes; /* supported TLS 1.3 key exchange modes */ int tls13_kex_modes; /* supported TLS 1.3 key exchange modes */
@ -1517,6 +1527,10 @@ int main( int argc, char *argv[] )
unsigned char *context_buf = NULL; unsigned char *context_buf = NULL;
size_t context_buf_len = 0; size_t context_buf_len = 0;
#endif #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) #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
uint16_t sig_alg_list[SIG_ALG_LIST_SIZE]; uint16_t sig_alg_list[SIG_ALG_LIST_SIZE];
@ -1675,6 +1689,9 @@ int main( int argc, char *argv[] )
opt.psk_identity = DFL_PSK_IDENTITY; opt.psk_identity = DFL_PSK_IDENTITY;
opt.psk_list = DFL_PSK_LIST; opt.psk_list = DFL_PSK_LIST;
opt.ecjpake_pw = DFL_ECJPAKE_PW; 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; opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
opt.tls13_kex_modes = DFL_TLS1_3_KEX_MODES; opt.tls13_kex_modes = DFL_TLS1_3_KEX_MODES;
@ -1879,6 +1896,10 @@ int main( int argc, char *argv[] )
opt.psk_list = q; opt.psk_list = q;
else if( strcmp( p, "ecjpake_pw" ) == 0 ) else if( strcmp( p, "ecjpake_pw" ) == 0 )
opt.ecjpake_pw = q; 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 ) else if( strcmp( p, "force_ciphersuite" ) == 0 )
{ {
opt.force_ciphersuite[0] = mbedtls_ssl_get_ciphersuite_id( q ); opt.force_ciphersuite[0] = mbedtls_ssl_get_ciphersuite_id( q );
@ -3527,6 +3548,36 @@ reset:
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( opt.ecjpake_pw != DFL_ECJPAKE_PW ) if( opt.ecjpake_pw != DFL_ECJPAKE_PW )
{
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if ( opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE )
{
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;
}
mbedtls_printf( "using opaque password\n");
}
else
#endif /* MBEDTLS_USE_PSA_CRYPTO */
{ {
if( ( ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl, if( ( ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl,
(const unsigned char *) opt.ecjpake_pw, (const unsigned char *) opt.ecjpake_pw,
@ -3536,7 +3587,8 @@ reset:
goto exit; goto exit;
} }
} }
#endif }
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
@ -4422,6 +4474,31 @@ exit:
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED && #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED &&
MBEDTLS_USE_PSA_CRYPTO */ MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
defined(MBEDTLS_USE_PSA_CRYPTO)
/*
* 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 ) )
{
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 )
{
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 );
}
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3) #if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
const char* message = mbedtls_test_helper_is_psa_leaking(); const char* message = mbedtls_test_helper_is_psa_leaking();
if( message ) if( message )

View file

@ -1457,10 +1457,14 @@ component_test_tls1_2_ecjpake_compatibility() {
make -C programs ssl/ssl_server2 ssl/ssl_client2 make -C programs ssl/ssl_server2 ssl/ssl_client2
make -C programs test/udp_proxy test/query_compile_time_config make -C programs test/udp_proxy test/query_compile_time_config
msg "test: server w/o USE_PSA - client w/ USE_PSA" 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 P_SRV=../s2_no_use_psa tests/ssl-opt.sh -f "ECJPAKE: working, TLS"
msg "test: client w/o USE_PSA - server w/ USE_PSA" msg "test: server w/o USE_PSA - client w/ USE_PSA, opaque password"
P_CLI=../c2_no_use_psa tests/ssl-opt.sh -f ECJPAKE 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 rm s2_no_use_psa c2_no_use_psa
} }

View file

@ -7986,6 +7986,8 @@ run_test "ECJPAKE: server not configured" \
-C "found ecjpake_kkpp extension" \ -C "found ecjpake_kkpp extension" \
-s "SSL - The handshake negotiation failed" -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_KEY_EXCHANGE_ECJPAKE_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "ECJPAKE: working, TLS" \ run_test "ECJPAKE: working, TLS" \
@ -8004,6 +8006,73 @@ run_test "ECJPAKE: working, TLS" \
-S "SSL - The handshake negotiation failed" \ -S "SSL - The handshake negotiation failed" \
-S "SSL - Verification of the message MAC 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 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" \
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"
# 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
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" \
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"
# 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
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" \
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 server_needs_more_time 1
requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
@ -8015,6 +8084,20 @@ run_test "ECJPAKE: password mismatch, TLS" \
-C "re-using cached ecjpake parameters" \ -C "re-using cached ecjpake parameters" \
-s "SSL - Verification of the message MAC 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_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_KEY_EXCHANGE_ECJPAKE_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "ECJPAKE: working, DTLS" \ run_test "ECJPAKE: working, DTLS" \

View file

@ -3539,3 +3539,11 @@ cookie_parsing:"16fefd0000000000000000002F010000de000000000000011efefd7b72727272
TLS 1.3 srv Certificate msg - wrong vector lengths TLS 1.3 srv Certificate msg - wrong vector lengths
tls13_server_certificate_msg_invalid_vector_len tls13_server_certificate_msg_invalid_vector_len
EC-JPAKE set password
depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
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

View file

@ -2582,6 +2582,21 @@ int tweak_tls13_certificate_msg_vector_len(
return( 0 ); return( 0 );
} }
#endif /* MBEDTLS_TEST_HOOKS */ #endif /* MBEDTLS_TEST_HOOKS */
#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_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_EQUAL( ret, exp_ret_val )
#endif
/* END_HEADER */ /* END_HEADER */
/* BEGIN_DEPENDENCIES /* BEGIN_DEPENDENCIES
@ -5997,3 +6012,85 @@ exit:
USE_PSA_DONE( ); USE_PSA_DONE( );
} }
/* END_CASE */ /* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
void ssl_ecjpake_set_password( int use_opaque_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 */
unsigned char pwd_string[ sizeof(ECJPAKE_TEST_PWD) ] = "";
size_t pwd_len = 0;
int ret;
USE_PSA_INIT( );
mbedtls_ssl_init( &ssl );
/* test with uninitalized SSL context */
ECJPAKE_TEST_SET_PASSWORD( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
mbedtls_ssl_config_init( &conf );
TEST_EQUAL( mbedtls_ssl_config_defaults( &conf,
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT ), 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 );
pwd_len = strlen( ECJPAKE_TEST_PWD );
memcpy( pwd_string, ECJPAKE_TEST_PWD, pwd_len );
#if defined( MBEDTLS_USE_PSA_CRYPTO )
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 );
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 );
/* check that the opaque key is still valid after failure */
TEST_EQUAL( psa_get_key_attributes( pwd_slot, &check_attributes ),
PSA_SUCCESS );
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 ) );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* final check which should work without errors */
ECJPAKE_TEST_SET_PASSWORD( 0 );
#if defined( MBEDTLS_USE_PSA_CRYPTO )
if( use_opaque_arg )
{
psa_destroy_key( pwd_slot );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
mbedtls_ssl_free( &ssl );
mbedtls_ssl_config_free( &conf );
USE_PSA_DONE( );
}
/* END_CASE */