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:
Ronald Cron 2022-08-31 17:21:57 +02:00 committed by GitHub
commit e00d6d6b55
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 1759 additions and 160 deletions

View file

@ -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 );

View file

@ -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 */

View file

@ -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 */

View file

@ -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 );

View file

@ -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 */

File diff suppressed because it is too large Load diff

View file

@ -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" \