Merge pull request #6135 from yuhaoth/pr/tls13-finalize-external-psk-negotiation
TLS 1.3: SRV: Finalize external PSK negotiation
This commit is contained in:
commit
e00d6d6b55
7 changed files with 1759 additions and 160 deletions
|
@ -1694,9 +1694,9 @@ int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
|
|||
{
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_key_attributes_t key_attributes = psa_key_attributes_init();
|
||||
psa_status_t status;
|
||||
psa_algorithm_t alg;
|
||||
mbedtls_svc_key_id_t key;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_algorithm_t alg = PSA_ALG_NONE;
|
||||
mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
if( psk == NULL || ssl->handshake == NULL )
|
||||
|
@ -1708,17 +1708,26 @@ int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
|
|||
ssl_remove_psk( ssl );
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if( ssl->handshake->ciphersuite_info->mac == MBEDTLS_MD_SHA384)
|
||||
alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384);
|
||||
else
|
||||
alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256);
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
if( ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2 )
|
||||
{
|
||||
if( ssl->handshake->ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
|
||||
alg = PSA_ALG_TLS12_PSK_TO_MS( PSA_ALG_SHA_384 );
|
||||
else
|
||||
alg = PSA_ALG_TLS12_PSK_TO_MS( PSA_ALG_SHA_256 );
|
||||
psa_set_key_usage_flags( &key_attributes, PSA_KEY_USAGE_DERIVE );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
psa_set_key_usage_flags( &key_attributes,
|
||||
PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT );
|
||||
#else
|
||||
psa_set_key_usage_flags( &key_attributes, PSA_KEY_USAGE_DERIVE );
|
||||
#endif
|
||||
if( ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 )
|
||||
{
|
||||
alg = PSA_ALG_HKDF_EXTRACT( PSA_ALG_ANY_HASH );
|
||||
psa_set_key_usage_flags( &key_attributes,
|
||||
PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
psa_set_key_algorithm( &key_attributes, alg );
|
||||
psa_set_key_type( &key_attributes, PSA_KEY_TYPE_DERIVE );
|
||||
|
||||
|
|
|
@ -359,7 +359,7 @@ int mbedtls_ssl_tls13_evolve_secret(
|
|||
|
||||
ret = 0;
|
||||
|
||||
if( input != NULL )
|
||||
if( input != NULL && input_len != 0 )
|
||||
{
|
||||
memcpy( tmp_input, input, input_len );
|
||||
ilen = input_len;
|
||||
|
@ -825,6 +825,9 @@ int mbedtls_ssl_tls13_create_psk_binder( mbedtls_ssl_context *ssl,
|
|||
goto exit;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF( 4, "mbedtls_ssl_tls13_create_psk_binder",
|
||||
early_secret, hash_len ) ;
|
||||
|
||||
if( psk_type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION )
|
||||
{
|
||||
ret = mbedtls_ssl_tls13_derive_secret( hash_alg,
|
||||
|
@ -1052,6 +1055,8 @@ int mbedtls_ssl_tls13_key_schedule_stage_early( mbedtls_ssl_context *ssl )
|
|||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
psa_algorithm_t hash_alg;
|
||||
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
|
||||
unsigned char *psk = NULL;
|
||||
size_t psk_len = 0;
|
||||
|
||||
if( handshake->ciphersuite_info == NULL )
|
||||
{
|
||||
|
@ -1060,15 +1065,34 @@ int mbedtls_ssl_tls13_key_schedule_stage_early( mbedtls_ssl_context *ssl )
|
|||
}
|
||||
|
||||
hash_alg = mbedtls_hash_info_psa_from_md( handshake->ciphersuite_info->mac );
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
if( mbedtls_ssl_tls13_key_exchange_mode_with_psk( ssl ) )
|
||||
{
|
||||
ret = mbedtls_ssl_tls13_export_handshake_psk( ssl, &psk, &psk_len );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_export_handshake_psk",
|
||||
ret );
|
||||
return( ret );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = mbedtls_ssl_tls13_evolve_secret( hash_alg, NULL, NULL, 0,
|
||||
ret = mbedtls_ssl_tls13_evolve_secret( hash_alg, NULL, psk, psk_len,
|
||||
handshake->tls13_master_secrets.early );
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
mbedtls_free( (void*)psk );
|
||||
#endif
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_evolve_secret", ret );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF( 4, "mbedtls_ssl_tls13_key_schedule_stage_early",
|
||||
handshake->tls13_master_secrets.early,
|
||||
PSA_HASH_LENGTH( hash_alg ) );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
@ -1543,4 +1567,48 @@ cleanup:
|
|||
return( ret );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
int mbedtls_ssl_tls13_export_handshake_psk( mbedtls_ssl_context *ssl,
|
||||
unsigned char **psk,
|
||||
size_t *psk_len )
|
||||
{
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
*psk_len = 0;
|
||||
*psk = NULL;
|
||||
|
||||
if( mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) )
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
|
||||
status = psa_get_key_attributes( ssl->handshake->psk_opaque, &key_attributes );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( psa_ssl_status_to_mbedtls( status ) );
|
||||
|
||||
*psk_len = PSA_BITS_TO_BYTES( psa_get_key_bits( &key_attributes ) );
|
||||
*psk = mbedtls_calloc( 1, *psk_len );
|
||||
if( *psk == NULL )
|
||||
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
|
||||
|
||||
status = psa_export_key( ssl->handshake->psk_opaque,
|
||||
(uint8_t *)*psk, *psk_len, psk_len );
|
||||
if( status != PSA_SUCCESS )
|
||||
{
|
||||
mbedtls_free( (void *)*psk );
|
||||
*psk = NULL;
|
||||
return( psa_ssl_status_to_mbedtls( status ) );
|
||||
}
|
||||
return( 0 );
|
||||
#else
|
||||
*psk = ssl->handshake->psk;
|
||||
*psk_len = ssl->handshake->psk_len;
|
||||
if( *psk == NULL )
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
return( 0 );
|
||||
#endif /* !MBEDTLS_USE_PSA_CRYPTO */
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
|
|
|
@ -692,6 +692,24 @@ int mbedtls_ssl_tls13_compute_handshake_transform( mbedtls_ssl_context *ssl );
|
|||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_compute_application_transform( mbedtls_ssl_context *ssl );
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
/**
|
||||
* \brief Export TLS 1.3 PSK from handshake context
|
||||
*
|
||||
* \param[in] ssl The SSL context to operate on.
|
||||
* \param[out] psk PSK output pointer.
|
||||
* \param[out] psk_len Length of PSK.
|
||||
*
|
||||
* \returns \c 0 if there is a configured PSK and it was exported
|
||||
* successfully.
|
||||
* \returns A negative error code on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_ssl_tls13_export_handshake_psk( mbedtls_ssl_context *ssl,
|
||||
unsigned char **psk,
|
||||
size_t *psk_len );
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */
|
||||
|
|
|
@ -46,6 +46,25 @@
|
|||
#include "ssl_tls13_keys.h"
|
||||
#include "ssl_debug_helpers.h"
|
||||
|
||||
|
||||
static const mbedtls_ssl_ciphersuite_t *ssl_tls13_validate_peer_ciphersuite(
|
||||
mbedtls_ssl_context *ssl,
|
||||
unsigned int cipher_suite )
|
||||
{
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
|
||||
if( ! mbedtls_ssl_tls13_cipher_suite_is_offered( ssl, cipher_suite ) )
|
||||
return( NULL );
|
||||
|
||||
ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( cipher_suite );
|
||||
if( ( mbedtls_ssl_validate_ciphersuite( ssl, ciphersuite_info,
|
||||
ssl->tls_version,
|
||||
ssl->tls_version ) != 0 ) )
|
||||
{
|
||||
return( NULL );
|
||||
}
|
||||
return( ciphersuite_info );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
/* From RFC 8446:
|
||||
*
|
||||
|
@ -100,14 +119,16 @@ static int ssl_tls13_parse_key_exchange_modes_ext( mbedtls_ssl_context *ssl,
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
#define SSL_TLS1_3_OFFERED_PSK_NOT_MATCH 0
|
||||
#define SSL_TLS1_3_OFFERED_PSK_MATCH 1
|
||||
#define SSL_TLS1_3_OFFERED_PSK_NOT_MATCH 1
|
||||
#define SSL_TLS1_3_OFFERED_PSK_MATCH 0
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_offered_psks_check_identity_match(
|
||||
mbedtls_ssl_context *ssl,
|
||||
const unsigned char *identity,
|
||||
size_t identity_len )
|
||||
size_t identity_len,
|
||||
int *psk_type )
|
||||
{
|
||||
*psk_type = MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL;
|
||||
/* Check identity with external configured function */
|
||||
if( ssl->conf->f_psk != NULL )
|
||||
{
|
||||
|
@ -133,86 +154,33 @@ static int ssl_tls13_offered_psks_check_identity_match(
|
|||
return( SSL_TLS1_3_OFFERED_PSK_NOT_MATCH );
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_get_psk( mbedtls_ssl_context *ssl,
|
||||
unsigned char **psk,
|
||||
size_t *psk_len )
|
||||
{
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_status_t status;
|
||||
|
||||
*psk_len = 0;
|
||||
*psk = NULL;
|
||||
|
||||
status = psa_get_key_attributes( ssl->handshake->psk_opaque, &key_attributes );
|
||||
if( status != PSA_SUCCESS)
|
||||
{
|
||||
return( psa_ssl_status_to_mbedtls( status ) );
|
||||
}
|
||||
|
||||
*psk_len = PSA_BITS_TO_BYTES( psa_get_key_bits( &key_attributes ) );
|
||||
*psk = mbedtls_calloc( 1, *psk_len );
|
||||
if( *psk == NULL )
|
||||
{
|
||||
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
|
||||
}
|
||||
|
||||
status = psa_export_key( ssl->handshake->psk_opaque,
|
||||
(uint8_t *)*psk, *psk_len, psk_len );
|
||||
if( status != PSA_SUCCESS)
|
||||
{
|
||||
mbedtls_free( (void *)*psk );
|
||||
return( psa_ssl_status_to_mbedtls( status ) );
|
||||
}
|
||||
#else
|
||||
*psk = ssl->handshake->psk;
|
||||
*psk_len = ssl->handshake->psk_len;
|
||||
#endif /* !MBEDTLS_USE_PSA_CRYPTO */
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_offered_psks_check_binder_match( mbedtls_ssl_context *ssl,
|
||||
const unsigned char *binder,
|
||||
size_t binder_len )
|
||||
size_t binder_len,
|
||||
int psk_type,
|
||||
psa_algorithm_t psk_hash_alg )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int psk_type;
|
||||
|
||||
mbedtls_md_type_t md_alg;
|
||||
psa_algorithm_t psa_md_alg;
|
||||
unsigned char transcript[PSA_HASH_MAX_SIZE];
|
||||
size_t transcript_len;
|
||||
unsigned char *psk;
|
||||
size_t psk_len;
|
||||
unsigned char server_computed_binder[PSA_HASH_MAX_SIZE];
|
||||
|
||||
psk_type = MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL;
|
||||
switch( binder_len )
|
||||
{
|
||||
case 32:
|
||||
md_alg = MBEDTLS_MD_SHA256;
|
||||
break;
|
||||
case 48:
|
||||
md_alg = MBEDTLS_MD_SHA384;
|
||||
break;
|
||||
default:
|
||||
return( MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR );
|
||||
}
|
||||
psa_md_alg = mbedtls_psa_translate_md( md_alg );
|
||||
/* Get current state of handshake transcript. */
|
||||
ret = mbedtls_ssl_get_handshake_transcript( ssl, md_alg,
|
||||
transcript, sizeof( transcript ),
|
||||
&transcript_len );
|
||||
ret = mbedtls_ssl_get_handshake_transcript(
|
||||
ssl, mbedtls_hash_info_md_from_psa( psk_hash_alg ),
|
||||
transcript, sizeof( transcript ), &transcript_len );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
ret = ssl_tls13_get_psk( ssl, &psk, &psk_len );
|
||||
ret = mbedtls_ssl_tls13_export_handshake_psk( ssl, &psk, &psk_len );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
ret = mbedtls_ssl_tls13_create_psk_binder( ssl, psa_md_alg,
|
||||
ret = mbedtls_ssl_tls13_create_psk_binder( ssl, psk_hash_alg,
|
||||
psk, psk_len, psk_type,
|
||||
transcript,
|
||||
server_computed_binder );
|
||||
|
@ -239,6 +207,73 @@ static int ssl_tls13_offered_psks_check_binder_match( mbedtls_ssl_context *ssl,
|
|||
return( SSL_TLS1_3_OFFERED_PSK_NOT_MATCH );
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_select_ciphersuite_for_psk(
|
||||
mbedtls_ssl_context *ssl,
|
||||
const unsigned char *cipher_suites,
|
||||
const unsigned char *cipher_suites_end,
|
||||
uint16_t *selected_ciphersuite,
|
||||
const mbedtls_ssl_ciphersuite_t **selected_ciphersuite_info )
|
||||
{
|
||||
psa_algorithm_t psk_hash_alg = PSA_ALG_SHA_256;
|
||||
|
||||
*selected_ciphersuite = 0;
|
||||
*selected_ciphersuite_info = NULL;
|
||||
|
||||
/* RFC 8446, page 55.
|
||||
*
|
||||
* For externally established PSKs, the Hash algorithm MUST be set when the
|
||||
* PSK is established or default to SHA-256 if no such algorithm is defined.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Search for a matching ciphersuite
|
||||
*/
|
||||
for ( const unsigned char *p = cipher_suites;
|
||||
p < cipher_suites_end; p += 2 )
|
||||
{
|
||||
uint16_t cipher_suite;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
|
||||
|
||||
cipher_suite = MBEDTLS_GET_UINT16_BE( p, 0 );
|
||||
ciphersuite_info = ssl_tls13_validate_peer_ciphersuite( ssl,
|
||||
cipher_suite );
|
||||
if( ciphersuite_info == NULL )
|
||||
continue;
|
||||
|
||||
/* MAC of selected ciphersuite MUST be same with PSK binder if exist.
|
||||
* Otherwise, client should reject.
|
||||
*/
|
||||
if( psk_hash_alg == mbedtls_psa_translate_md( ciphersuite_info->mac ) )
|
||||
{
|
||||
*selected_ciphersuite = cipher_suite;
|
||||
*selected_ciphersuite_info = ciphersuite_info;
|
||||
return( 0 );
|
||||
}
|
||||
}
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "No matched ciphersuite" ) );
|
||||
return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
|
||||
}
|
||||
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_select_ciphersuite_for_resumption(
|
||||
mbedtls_ssl_context *ssl,
|
||||
const unsigned char *cipher_suites,
|
||||
const unsigned char *cipher_suites_end,
|
||||
mbedtls_ssl_session *session,
|
||||
uint16_t *selected_ciphersuite,
|
||||
const mbedtls_ssl_ciphersuite_t **selected_ciphersuite_info )
|
||||
{
|
||||
((void) ssl);
|
||||
((void) session);
|
||||
((void) cipher_suites);
|
||||
((void) cipher_suites_end);
|
||||
*selected_ciphersuite = 0;
|
||||
*selected_ciphersuite_info = NULL;
|
||||
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||
}
|
||||
|
||||
/* Parser for pre_shared_key extension in client hello
|
||||
* struct {
|
||||
* opaque identity<1..2^16-1>;
|
||||
|
@ -261,10 +296,12 @@ static int ssl_tls13_offered_psks_check_binder_match( mbedtls_ssl_context *ssl,
|
|||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
static int ssl_tls13_parse_pre_shared_key_ext( mbedtls_ssl_context *ssl,
|
||||
const unsigned char *buf,
|
||||
const unsigned char *end )
|
||||
const unsigned char *pre_shared_key_ext,
|
||||
const unsigned char *pre_shared_key_ext_end,
|
||||
const unsigned char *ciphersuites,
|
||||
const unsigned char *ciphersuites_end )
|
||||
{
|
||||
const unsigned char *identities = buf;
|
||||
const unsigned char *identities = pre_shared_key_ext;
|
||||
const unsigned char *p_identity_len;
|
||||
size_t identities_len;
|
||||
const unsigned char *identities_end;
|
||||
|
@ -275,28 +312,32 @@ static int ssl_tls13_parse_pre_shared_key_ext( mbedtls_ssl_context *ssl,
|
|||
int matched_identity = -1;
|
||||
int identity_id = -1;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF( 3, "pre_shared_key extension", buf, end - buf );
|
||||
MBEDTLS_SSL_DEBUG_BUF( 3, "pre_shared_key extension",
|
||||
pre_shared_key_ext,
|
||||
pre_shared_key_ext_end - pre_shared_key_ext );
|
||||
|
||||
/* identities_len 2 bytes
|
||||
* identities_data >= 7 bytes
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR( identities, end, 7 + 2 );
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR( identities, pre_shared_key_ext_end, 7 + 2 );
|
||||
identities_len = MBEDTLS_GET_UINT16_BE( identities, 0 );
|
||||
p_identity_len = identities + 2;
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR( p_identity_len, end, identities_len );
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR( p_identity_len, pre_shared_key_ext_end,
|
||||
identities_len );
|
||||
identities_end = p_identity_len + identities_len;
|
||||
|
||||
/* binders_len 2 bytes
|
||||
* binders >= 33 bytes
|
||||
*/
|
||||
binders = identities_end;
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR( binders, end, 33 + 2 );
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR( binders, pre_shared_key_ext_end, 33 + 2 );
|
||||
binders_len = MBEDTLS_GET_UINT16_BE( binders, 0 );
|
||||
p_binder_len = binders + 2;
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR( p_binder_len, end, binders_len );
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR( p_binder_len, pre_shared_key_ext_end, binders_len );
|
||||
binders_end = p_binder_len + binders_len;
|
||||
|
||||
ssl->handshake->update_checksum( ssl, buf, identities_end - buf );
|
||||
ssl->handshake->update_checksum( ssl, pre_shared_key_ext,
|
||||
identities_end - pre_shared_key_ext );
|
||||
|
||||
while( p_identity_len < identities_end && p_binder_len < binders_end )
|
||||
{
|
||||
|
@ -305,6 +346,9 @@ static int ssl_tls13_parse_pre_shared_key_ext( mbedtls_ssl_context *ssl,
|
|||
const unsigned char *binder;
|
||||
size_t binder_len;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int psk_type;
|
||||
uint16_t cipher_suite;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR( p_identity_len, identities_end, 2 + 1 + 4 );
|
||||
identity_len = MBEDTLS_GET_UINT16_BE( p_identity_len, 0 );
|
||||
|
@ -318,20 +362,51 @@ static int ssl_tls13_parse_pre_shared_key_ext( mbedtls_ssl_context *ssl,
|
|||
MBEDTLS_SSL_CHK_BUF_READ_PTR( binder, binders_end, binder_len );
|
||||
p_binder_len += binder_len + 1;
|
||||
|
||||
|
||||
identity_id++;
|
||||
if( matched_identity != -1 )
|
||||
continue;
|
||||
|
||||
ret = ssl_tls13_offered_psks_check_identity_match(
|
||||
ssl, identity, identity_len );
|
||||
if( SSL_TLS1_3_OFFERED_PSK_NOT_MATCH == ret )
|
||||
ssl, identity, identity_len, &psk_type );
|
||||
if( ret != SSL_TLS1_3_OFFERED_PSK_MATCH )
|
||||
continue;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 4, ( "found matched identity" ) );
|
||||
switch( psk_type )
|
||||
{
|
||||
case MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL:
|
||||
ret = ssl_tls13_select_ciphersuite_for_psk(
|
||||
ssl, ciphersuites, ciphersuites_end,
|
||||
&cipher_suite, &ciphersuite_info );
|
||||
break;
|
||||
case MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION:
|
||||
ret = ssl_tls13_select_ciphersuite_for_resumption(
|
||||
ssl, ciphersuites, ciphersuites_end, NULL,
|
||||
&cipher_suite, &ciphersuite_info );
|
||||
break;
|
||||
default:
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
}
|
||||
if( ret != 0 )
|
||||
{
|
||||
/* See below, no cipher_suite available, abort handshake */
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR,
|
||||
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
|
||||
MBEDTLS_SSL_DEBUG_RET(
|
||||
2, "ssl_tls13_select_ciphersuite", ret );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
ret = ssl_tls13_offered_psks_check_binder_match(
|
||||
ssl, binder, binder_len );
|
||||
ssl, binder, binder_len, psk_type,
|
||||
mbedtls_psa_translate_md( ciphersuite_info->mac ) );
|
||||
if( ret != SSL_TLS1_3_OFFERED_PSK_MATCH )
|
||||
{
|
||||
/* For security reasons, the handshake should be aborted when we
|
||||
* fail to validate a binder value. See RFC 8446 section 4.2.11.2
|
||||
* and appendix E.6. */
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Invalid binder." ) );
|
||||
MBEDTLS_SSL_DEBUG_RET( 1,
|
||||
"ssl_tls13_offered_psks_check_binder_match" , ret );
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
|
@ -339,10 +414,15 @@ static int ssl_tls13_parse_pre_shared_key_ext( mbedtls_ssl_context *ssl,
|
|||
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
|
||||
return( ret );
|
||||
}
|
||||
if( SSL_TLS1_3_OFFERED_PSK_NOT_MATCH == ret )
|
||||
continue;
|
||||
|
||||
matched_identity = identity_id;
|
||||
|
||||
/* Update handshake parameters */
|
||||
ssl->session_negotiate->ciphersuite = cipher_suite;
|
||||
ssl->handshake->ciphersuite_info = ciphersuite_info;
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "overwrite ciphersuite: %04x - %s",
|
||||
cipher_suite, ciphersuite_info->name ) );
|
||||
|
||||
}
|
||||
|
||||
if( p_identity_len != identities_end || p_binder_len != binders_end )
|
||||
|
@ -359,7 +439,7 @@ static int ssl_tls13_parse_pre_shared_key_ext( mbedtls_ssl_context *ssl,
|
|||
(size_t)( binders_end - identities_end ) );
|
||||
if( matched_identity == -1 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "No matched pre shared key found" ) );
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "No matched PSK or ticket." ) );
|
||||
return( MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY );
|
||||
}
|
||||
|
||||
|
@ -946,16 +1026,15 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
|
|||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
const unsigned char *p = buf;
|
||||
size_t legacy_session_id_len;
|
||||
const unsigned char *cipher_suites;
|
||||
size_t cipher_suites_len;
|
||||
const unsigned char *cipher_suites_end;
|
||||
size_t extensions_len;
|
||||
const unsigned char *extensions_end;
|
||||
int hrr_required = 0;
|
||||
|
||||
const mbedtls_ssl_ciphersuite_t* ciphersuite_info;
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
const unsigned char *pre_shared_key_ext_start = NULL;
|
||||
const unsigned char *cipher_suites;
|
||||
const unsigned char *pre_shared_key_ext = NULL;
|
||||
const unsigned char *pre_shared_key_ext_end = NULL;
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
|
||||
|
@ -1039,7 +1118,7 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
|
|||
p, legacy_session_id_len );
|
||||
/*
|
||||
* Check we have enough data for the legacy session identifier
|
||||
* and the ciphersuite list length.
|
||||
* and the ciphersuite list length.
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, legacy_session_id_len + 2 );
|
||||
|
||||
|
@ -1051,6 +1130,10 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
|
|||
|
||||
/* Check we have enough data for the ciphersuite list, the legacy
|
||||
* compression methods and the length of the extensions.
|
||||
*
|
||||
* cipher_suites cipher_suites_len bytes
|
||||
* legacy_compression_methods 2 bytes
|
||||
* extensions_len 2 bytes
|
||||
*/
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, cipher_suites_len + 2 + 2 );
|
||||
|
||||
|
@ -1060,51 +1143,43 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
|
|||
* with CipherSuite defined as:
|
||||
* uint8 CipherSuite[2];
|
||||
*/
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
|
||||
cipher_suites = p;
|
||||
#endif
|
||||
cipher_suites_end = p + cipher_suites_len;
|
||||
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist",
|
||||
p, cipher_suites_len );
|
||||
|
||||
/*
|
||||
* Search for a matching ciphersuite
|
||||
*/
|
||||
int ciphersuite_match = 0;
|
||||
for ( ; p < cipher_suites_end; p += 2 )
|
||||
{
|
||||
uint16_t cipher_suite;
|
||||
const mbedtls_ssl_ciphersuite_t* ciphersuite_info;
|
||||
|
||||
MBEDTLS_SSL_CHK_BUF_READ_PTR( p, cipher_suites_end, 2 );
|
||||
|
||||
cipher_suite = MBEDTLS_GET_UINT16_BE( p, 0 );
|
||||
ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( cipher_suite );
|
||||
/*
|
||||
* Check whether this ciphersuite is valid and offered.
|
||||
*/
|
||||
if( ( mbedtls_ssl_validate_ciphersuite(
|
||||
ssl, ciphersuite_info, ssl->tls_version,
|
||||
ssl->tls_version ) != 0 ) ||
|
||||
! mbedtls_ssl_tls13_cipher_suite_is_offered( ssl, cipher_suite ) )
|
||||
{
|
||||
ciphersuite_info = ssl_tls13_validate_peer_ciphersuite(
|
||||
ssl,cipher_suite );
|
||||
if( ciphersuite_info == NULL )
|
||||
continue;
|
||||
}
|
||||
|
||||
ssl->session_negotiate->ciphersuite = cipher_suite;
|
||||
ssl->handshake->ciphersuite_info = ciphersuite_info;
|
||||
ciphersuite_match = 1;
|
||||
|
||||
break;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %04x - %s",
|
||||
cipher_suite,
|
||||
ciphersuite_info->name ) );
|
||||
}
|
||||
|
||||
if( ! ciphersuite_match )
|
||||
if( ssl->handshake->ciphersuite_info == NULL )
|
||||
{
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
|
||||
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
|
||||
return ( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s",
|
||||
ciphersuite_info->name ) );
|
||||
|
||||
p = cipher_suites + cipher_suites_len;
|
||||
|
||||
/* ...
|
||||
* opaque legacy_compression_methods<1..2^8-1>;
|
||||
* ...
|
||||
|
@ -1281,7 +1356,7 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
|
|||
* found out which algorithms to use. We keep a pointer
|
||||
* to the buffer and the size for later processing.
|
||||
*/
|
||||
pre_shared_key_ext_start = p;
|
||||
pre_shared_key_ext = p;
|
||||
pre_shared_key_ext_end = extension_data_end;
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
|
||||
ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PRE_SHARED_KEY;
|
||||
|
@ -1344,14 +1419,17 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
|
|||
*/
|
||||
/* If we've settled on a PSK-based exchange, parse PSK identity ext */
|
||||
if( mbedtls_ssl_tls13_some_psk_enabled( ssl ) &&
|
||||
mbedtls_ssl_conf_tls13_some_psk_enabled( ssl ) &&
|
||||
( ssl->handshake->extensions_present & MBEDTLS_SSL_EXT_PRE_SHARED_KEY ) )
|
||||
{
|
||||
ssl->handshake->update_checksum( ssl, buf,
|
||||
pre_shared_key_ext_start - buf );
|
||||
pre_shared_key_ext - buf );
|
||||
ret = ssl_tls13_parse_pre_shared_key_ext( ssl,
|
||||
pre_shared_key_ext_start,
|
||||
pre_shared_key_ext_end );
|
||||
if( ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY)
|
||||
pre_shared_key_ext,
|
||||
pre_shared_key_ext_end,
|
||||
cipher_suites,
|
||||
cipher_suites_end );
|
||||
if( ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY )
|
||||
{
|
||||
ssl->handshake->extensions_present &= ~MBEDTLS_SSL_EXT_PRE_SHARED_KEY;
|
||||
}
|
||||
|
@ -1372,6 +1450,8 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl,
|
|||
if( ret < 0 )
|
||||
return( ret );
|
||||
|
||||
mbedtls_ssl_optimize_checksum( ssl, ssl->handshake->ciphersuite_info );
|
||||
|
||||
return( hrr_required ? SSL_CLIENT_HELLO_HRR_REQUIRED : SSL_CLIENT_HELLO_OK );
|
||||
}
|
||||
|
||||
|
@ -1802,7 +1882,7 @@ static int ssl_tls13_write_server_hello_body( mbedtls_ssl_context *ssl,
|
|||
}
|
||||
p += output_len;
|
||||
|
||||
if( mbedtls_ssl_conf_tls13_some_ephemeral_enabled( ssl ) )
|
||||
if( mbedtls_ssl_tls13_key_exchange_mode_with_ephemeral( ssl ) )
|
||||
{
|
||||
if( is_hrr )
|
||||
ret = ssl_tls13_write_hrr_key_share_ext( ssl, p, end, &output_len );
|
||||
|
|
|
@ -471,7 +471,8 @@ int main( void )
|
|||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
#define USAGE_TLS1_3_KEY_EXCHANGE_MODES \
|
||||
" tls13_kex_modes=%%s default: all\n" \
|
||||
" options: psk, psk_ephemeral, ephemeral, ephemeral_all, psk_all, all\n"
|
||||
" options: psk, psk_ephemeral, psk_all, ephemeral,\n" \
|
||||
" ephemeral_all, all, psk_or_ephemeral\n"
|
||||
#else
|
||||
#define USAGE_TLS1_3_KEY_EXCHANGE_MODES ""
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
@ -1859,6 +1860,16 @@ int main( int argc, char *argv[] )
|
|||
opt.tls13_kex_modes = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL;
|
||||
else if( strcmp( q, "all" ) == 0 )
|
||||
opt.tls13_kex_modes = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_ALL;
|
||||
/* The purpose of `psk_or_ephemeral` is to improve test coverage. That
|
||||
* is not recommended in practice.
|
||||
* `psk_or_ephemeral` exists in theory, we need this mode to test if
|
||||
* this setting work correctly. With this key exchange setting, server
|
||||
* should always perform `ephemeral` handshake. `psk` or `psk_ephermal`
|
||||
* is not expected.
|
||||
*/
|
||||
else if( strcmp( q, "psk_or_ephemeral" ) == 0 )
|
||||
opt.tls13_kex_modes = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK |
|
||||
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL ;
|
||||
else goto usage;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
|
1447
tests/opt-testcases/tls13-kex-modes.sh
Executable file
1447
tests/opt-testcases/tls13-kex-modes.sh
Executable file
File diff suppressed because it is too large
Load diff
|
@ -2313,40 +2313,6 @@ run_test "TLS 1.3: key exchange mode parameter passing: All" \
|
|||
"$P_CLI tls13_kex_modes=all" \
|
||||
0
|
||||
|
||||
requires_openssl_tls1_3
|
||||
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
|
||||
requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
|
||||
requires_config_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
requires_config_enabled MBEDTLS_SSL_SRV_C
|
||||
requires_config_enabled MBEDTLS_DEBUG_C
|
||||
run_test "TLS 1.3: PSK: basic check, O->m" \
|
||||
"$P_SRV force_version=tls13 tls13_kex_modes=psk debug_level=5 psk=6162636465666768696a6b6c6d6e6f70" \
|
||||
"$O_NEXT_CLI -tls1_3 -psk 1234 -psk 6162636465666768696a6b6c6d6e6f70 -allow_no_dhe_kex" \
|
||||
1 \
|
||||
-s "found psk key exchange modes extension" \
|
||||
-s "found pre_shared_key extension" \
|
||||
-s "Found PSK_EPHEMERAL KEX MODE" \
|
||||
-s "Found PSK KEX MODE" \
|
||||
-s "Pre shared key found"
|
||||
|
||||
requires_gnutls_tls1_3
|
||||
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
|
||||
requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE
|
||||
requires_config_enabled MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
requires_config_enabled MBEDTLS_SSL_SRV_C
|
||||
requires_config_enabled MBEDTLS_DEBUG_C
|
||||
run_test "TLS 1.3: PSK: basic check, G->m" \
|
||||
"$P_SRV force_version=tls13 tls13_kex_modes=psk debug_level=5 psk=6162636465666768696a6b6c6d6e6f70" \
|
||||
"$G_NEXT_CLI --priority NORMAL:-VERS-ALL:+KX-ALL:+PSK:+DHE-PSK:+VERS-TLS1.3 \
|
||||
--pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70 \
|
||||
localhost" \
|
||||
1 \
|
||||
-s "found psk key exchange modes extension" \
|
||||
-s "found pre_shared_key extension" \
|
||||
-s "Found PSK_EPHEMERAL KEX MODE" \
|
||||
-s "Found PSK KEX MODE" \
|
||||
-s "Pre shared key found"
|
||||
|
||||
# Tests for datagram packing
|
||||
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
|
||||
run_test "DTLS: multiple records in same datagram, client and server" \
|
||||
|
|
Loading…
Reference in a new issue