Skip to content

Commit

Permalink
Add non-PSA support for TLS 1.3 client
Browse files Browse the repository at this point in the history
Summary:
Add non-PSA crypto support for the client when it uses TLS 1.3.
* Update include/mbedtls/check_config.h to allow
MBEDTLS_SSL_PROTO_TLS1_3 without MBEDTLS_PSA_CRYPTO_C
* Add non-PSA crypto support in TLS 1.3 implementation.
* Require MBEDTLS_USE_PSA_CRYPTO for the TLS 1.3: Client authentication, rsa_pss_rsae tests. It is because the padding is set to [PSA_ALG_RSA_PSS](https://github.com/hannestschofenig/mbedtls/blob/tls13-prototype/library/pk.c#L557) in `mbedtls_pk_sign_ext` which is only for MBEDTLS_USE_PSA_CRYPTO.

Test Plan:
```
tests/ssl-opt.sh -p -s -f "TLS 1.3: "
```

Reviewers:

Subscribers:

Tasks:

Tags:
  • Loading branch information
lhuang04 committed Oct 6, 2022
1 parent 48962af commit d27a567
Show file tree
Hide file tree
Showing 8 changed files with 588 additions and 24 deletions.
3 changes: 1 addition & 2 deletions include/mbedtls/check_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -746,8 +746,7 @@
*/
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
( ( !defined(MBEDTLS_HKDF_C) ) || \
( !defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA384_C) ) || \
( !defined(MBEDTLS_PSA_CRYPTO_C) ) )
( !defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA384_C) ) )
#error "MBEDTLS_SSL_PROTO_TLS1_3 defined, but not all prerequisites"
#endif

Expand Down
36 changes: 32 additions & 4 deletions library/ssl_misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -679,14 +679,14 @@ struct mbedtls_ssl_handshake_params
mbedtls_ecdh_context ecdh_ctx; /*!< ECDH key exchange */
#endif /* !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_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3))
psa_key_type_t ecdh_psa_type;
size_t ecdh_bits;
mbedtls_svc_key_id_t ecdh_psa_privkey;
uint8_t ecdh_psa_privkey_is_external;
unsigned char ecdh_psa_peerkey[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
size_t ecdh_psa_peerkey_len;
#endif /* MBEDTLS_USE_PSA_CRYPTO || MBEDTLS_SSL_PROTO_TLS1_3 */
#endif /* MBEDTLS_USE_PSA_CRYPTO || (defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3)) */
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */

#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
Expand Down Expand Up @@ -2014,6 +2014,34 @@ static inline int mbedtls_ssl_conf_is_hybrid_tls12_tls13( const mbedtls_ssl_conf
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_SSL_PROTO_TLS1_3 */

#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
#if defined(MBEDTLS_ECDH_C)
/**
* \brief This function generates an EC key pair and exports its
* in the format used in a TLS 1.3 KeyShare extension.
*
* \see ecp.h
*
* \param ctx The ECDH context to use. This must be initialized
* and bound to a group, for example via mbedtls_ecdh_setup().
* \param olen The address at which to store the number of Bytes written.
* \param buf The destination buffer. This must be a writable buffer of
* length \p blen Bytes.
* \param blen The length of the destination buffer \p buf in Bytes.
* \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL in case \p f_rng doesn't need a context argument.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
*/
int mbedtls_ecdh_make_tls13_params( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );

#endif /* MBEDTLS_ECDH_C */
extern const uint8_t mbedtls_ssl_tls13_hello_retry_request_magic[
MBEDTLS_SERVER_HELLO_RANDOM_LEN ];
MBEDTLS_CHECK_RETURN_CRITICAL
Expand Down Expand Up @@ -2637,7 +2665,7 @@ int mbedtls_ssl_tls13_check_sig_alg_cert_key_match( uint16_t sig_alg,

#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */

#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
#if defined(MBEDTLS_USE_PSA_CRYPTO) || (defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3))
/* Corresponding PSA algorithm for MBEDTLS_CIPHER_NULL.
* Same value is used for PSA_ALG_CATEGORY_CIPHER, hence it is
* guaranteed to not be a valid PSA algorithm identifier.
Expand Down Expand Up @@ -2697,7 +2725,7 @@ static inline int psa_ssl_status_to_mbedtls( psa_status_t status )
return( MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED );
}
}
#endif /* MBEDTLS_USE_PSA_CRYPTO || MBEDTLS_SSL_PROTO_TLS1_3 */
#endif /* MBEDTLS_USE_PSA_CRYPTO || (defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3))*/

/**
* \brief TLS record protection modes
Expand Down
7 changes: 4 additions & 3 deletions library/ssl_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -3975,11 +3975,12 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
mbedtls_ssl_buffering_free( ssl );
#endif /* MBEDTLS_SSL_PROTO_DTLS */

#if defined(MBEDTLS_ECDH_C) && \
( defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3) )
#if defined(MBEDTLS_ECDH_C) && ( defined(MBEDTLS_USE_PSA_CRYPTO) \
|| ( defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3) ) )
if( handshake->ecdh_psa_privkey_is_external == 0 )
psa_destroy_key( handshake->ecdh_psa_privkey );
#endif /* MBEDTLS_ECDH_C && MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_ECDH_C && ( defined(MBEDTLS_USE_PSA_CRYPTO) \
|| ( defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3) ) ) */

#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
mbedtls_ssl_transform_free( handshake->transform_handshake );
Expand Down
76 changes: 74 additions & 2 deletions library/ssl_tls13_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
#define mbedtls_free free
#endif

#include "ecp_internal.h"

/* Write extensions */

/*
Expand Down Expand Up @@ -203,6 +205,7 @@ static int ssl_tls13_reset_key_share( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_ECDH_C)
if( mbedtls_ssl_tls13_named_group_is_ecdhe( group_id ) )
{
#if defined(MBEDTLS_USE_PSA_CRYPTO)
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;

Expand All @@ -216,6 +219,7 @@ static int ssl_tls13_reset_key_share( mbedtls_ssl_context *ssl )
}

ssl->handshake->ecdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
return( 0 );
}
else
Expand Down Expand Up @@ -337,8 +341,34 @@ static int ssl_tls13_write_key_share_ext( mbedtls_ssl_context *ssl,
*/
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
p += 4;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
ret = mbedtls_ssl_tls13_generate_and_write_ecdh_key_exchange(
ssl, group_id, p, end, &key_exchange_len );
#else
mbedtls_ecp_group_id ecp_group_id = mbedtls_ecp_named_group_to_id( group_id );
if( ecp_group_id == MBEDTLS_ECP_DP_NONE )
{
MBEDTLS_SSL_DEBUG_MSG( 4, ( "Unrecognized NamedGroup %u",
(unsigned) group_id ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}

ret = mbedtls_ecdh_setup( &ssl->handshake->ecdh_ctx, ecp_group_id);
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_setup", ret );
return( ret );
}

ret = mbedtls_ecdh_make_tls13_params( &ssl->handshake->ecdh_ctx, &key_exchange_len,
p, end - p,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_tls_13_params", ret );
return( ret );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
p += key_exchange_len;
if( ret != 0 )
return( ret );
Expand Down Expand Up @@ -386,6 +416,33 @@ static int ssl_tls13_write_key_share_ext( mbedtls_ssl_context *ssl,
return( ret );
}

#if defined(MBEDTLS_ECDH_C)

#if defined(MBEDTLS_USE_PSA_CRYPTO)
static int ssl_tls13_read_public_ecdhe_share( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t buf_len )
{
uint8_t *p = (uint8_t*)buf;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;

/* Get size of the TLS opaque key_exchange field of the KeyShareEntry struct. */
uint16_t peerkey_len = MBEDTLS_GET_UINT16_BE( p, 0 );
p += 2;

/* Check if key size is consistent with given buffer length. */
if ( peerkey_len > ( buf_len - 2 ) )
return( MBEDTLS_ERR_SSL_DECODE_ERROR );

/* Store peer's ECDH public key. */
memcpy( handshake->ecdh_psa_peerkey, p, peerkey_len );
handshake->ecdh_psa_peerkey_len = peerkey_len;

return( 0 );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_ECDH_C */

/*
* ssl_tls13_parse_hrr_key_share_ext()
* Parse key_share extension in Hello Retry Request
Expand Down Expand Up @@ -511,9 +568,18 @@ static int ssl_tls13_parse_key_share_ext( mbedtls_ssl_context *ssl,

MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) );

#if defined(MBEDTLS_USE_PSA_CRYPTO)
ret = mbedtls_ssl_tls13_read_public_ecdhe_share( ssl, p, end - p );
if( ret != 0 )
return( ret );
#else
if( ( ret = mbedtls_ecdh_import_public_raw( &ssl->handshake->ecdh_ctx, p,
end ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_import_public_raw" ), ret );
return( ret );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
}
else
#endif /* MBEDTLS_ECDH_C */
Expand Down Expand Up @@ -926,7 +992,10 @@ int mbedtls_ssl_tls13_write_pre_shared_key_ext_binders(
return( ret );

ret = mbedtls_ssl_tls13_create_psk_binder( ssl,
mbedtls_psa_translate_md( suite_info->mac ),
#if defined(MBEDTLS_USE_PSA_CRYPTO)
mbedtls_psa_translate_md
#endif /* MBEDTLS_USE_PSA_CRYPTO */
( suite_info->mac ),
psk, psk_len, psk_type,
transcript, p );
if( ret != 0 )
Expand Down Expand Up @@ -3244,7 +3313,10 @@ static int ssl_tls13_new_session_ticket_parse( mbedtls_ssl_context *ssl,
* "resumption", ticket_nonce, Hash.length )
*/
ret = mbedtls_ssl_tls13_hkdf_expand_label(
mbedtls_psa_translate_md( suite_info->mac ),
#if defined(MBEDTLS_USE_PSA_CRYPTO)
mbedtls_psa_translate_md
#endif /* MBEDTLS_USE_PSA_CRYPTO */
( suite_info->mac ),
ssl->session->app_secrets.resumption_master_secret,
hash_length,
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( resumption ),
Expand Down
Loading

0 comments on commit d27a567

Please sign in to comment.