Add helper function for calculation of TLS 1.3 PSK binder
Signed-off-by: Hanno Becker <hanno.becker@arm.com>
This commit is contained in:
parent
a4f40a0f48
commit
b7d9bad6be
2 changed files with 165 additions and 0 deletions
|
@ -565,4 +565,136 @@ int mbedtls_ssl_tls1_3_derive_resumption_master_secret(
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
static int ssl_tls1_3_calc_finished_core( mbedtls_md_type_t md_type,
|
||||
unsigned char const *base_key,
|
||||
unsigned char const *transcript,
|
||||
unsigned char *dst )
|
||||
{
|
||||
const mbedtls_md_info_t* const md_info = mbedtls_md_info_from_type( md_type );
|
||||
size_t const md_size = mbedtls_md_get_size( md_info );
|
||||
unsigned char finished_key[MBEDTLS_MD_MAX_SIZE];
|
||||
int ret;
|
||||
|
||||
/* We should never call this function with an unknown hash,
|
||||
* but add an assertion anyway. */
|
||||
if( md_info == 0 )
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
|
||||
/* TLS 1.3 Finished message
|
||||
*
|
||||
* struct {
|
||||
* opaque verify_data[Hash.length];
|
||||
* } Finished;
|
||||
*
|
||||
* verify_data =
|
||||
* HMAC( finished_key,
|
||||
* Hash( Handshake Context +
|
||||
* Certificate* +
|
||||
* CertificateVerify* )
|
||||
* )
|
||||
*
|
||||
* finished_key =
|
||||
* HKDF-Expand-Label( BaseKey, "finished", "", Hash.length )
|
||||
*/
|
||||
|
||||
ret = mbedtls_ssl_tls1_3_hkdf_expand_label(
|
||||
md_type, base_key, md_size,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( finished ),
|
||||
NULL, 0,
|
||||
finished_key, md_size );
|
||||
if( ret != 0 )
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_md_hmac( md_info, finished_key, md_size, transcript, md_size, dst );
|
||||
if( ret != 0 )
|
||||
goto exit;
|
||||
|
||||
exit:
|
||||
|
||||
mbedtls_platform_zeroize( finished_key, sizeof( finished_key ) );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int mbedtls_ssl_tls1_3_create_psk_binder( mbedtls_ssl_context *ssl,
|
||||
const mbedtls_md_type_t md_type,
|
||||
unsigned char const *psk, size_t psk_len,
|
||||
int psk_type,
|
||||
unsigned char const *transcript,
|
||||
unsigned char *result )
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char binder_key[MBEDTLS_MD_MAX_SIZE];
|
||||
unsigned char early_secret[MBEDTLS_MD_MAX_SIZE];
|
||||
mbedtls_md_info_t const *md_info = mbedtls_md_info_from_type( md_type );
|
||||
size_t const md_size = mbedtls_md_get_size( md_info );
|
||||
|
||||
/* We should never call this function with an unknown hash,
|
||||
* but add an assertion anyway. */
|
||||
if( md_info == 0 )
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
|
||||
/*
|
||||
* 0
|
||||
* |
|
||||
* v
|
||||
* PSK -> HKDF-Extract = Early Secret
|
||||
* |
|
||||
* +-----> Derive-Secret(., "ext binder" | "res binder", "")
|
||||
* | = binder_key
|
||||
* v
|
||||
*/
|
||||
|
||||
ret = mbedtls_ssl_tls1_3_evolve_secret( md_type,
|
||||
NULL, /* Old secret */
|
||||
psk, psk_len, /* Input */
|
||||
early_secret );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls1_3_evolve_secret", ret );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if( psk_type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION )
|
||||
{
|
||||
ret = mbedtls_ssl_tls1_3_derive_secret( md_type,
|
||||
early_secret, md_size,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( res_binder ),
|
||||
NULL, 0, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
|
||||
binder_key, md_size );
|
||||
MBEDTLS_SSL_DEBUG_MSG( 4, ( "Derive Early Secret with 'res binder'" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = mbedtls_ssl_tls1_3_derive_secret( md_type,
|
||||
early_secret, md_size,
|
||||
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( ext_binder ),
|
||||
NULL, 0, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
|
||||
binder_key, md_size );
|
||||
MBEDTLS_SSL_DEBUG_MSG( 4, ( "Derive Early Secret with 'ext binder'" ) );
|
||||
}
|
||||
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls1_3_derive_secret", ret );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* The binding_value is computed in the same way as the Finished message
|
||||
* but with the BaseKey being the binder_key.
|
||||
*/
|
||||
|
||||
ret = ssl_tls1_3_calc_finished_core( md_type, binder_key, transcript, result );
|
||||
if( ret != 0 )
|
||||
goto exit;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF( 3, "psk binder", result, md_size );
|
||||
|
||||
exit:
|
||||
|
||||
mbedtls_platform_zeroize( early_secret, sizeof( early_secret ) );
|
||||
mbedtls_platform_zeroize( binder_key, sizeof( binder_key ) );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
|
||||
|
|
|
@ -465,4 +465,37 @@ int mbedtls_ssl_tls1_3_evolve_secret(
|
|||
const unsigned char *input, size_t input_len,
|
||||
unsigned char *secret_new );
|
||||
|
||||
#define MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL 0
|
||||
#define MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION 1
|
||||
|
||||
/**
|
||||
* \brief Calculate a TLS 1.3 PSK binder.
|
||||
*
|
||||
* \param ssl The SSL context. This is used for debugging only and may
|
||||
* be \c NULL if MBEDTLS_DEBUG_C is disabled.
|
||||
* \param md_type The hash algorithm associated to the PSK \p psk.
|
||||
* \param psk The buffer holding the PSK for which to create a binder.
|
||||
* \param psk_len The size of \p psk in bytes.
|
||||
* \param is_external This indicates whether the PSK \p psk is externally
|
||||
* provisioned (#MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL) or a
|
||||
* resumption PSK (#MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION).
|
||||
* \param transcript The handshake transcript up to the point where the
|
||||
* PSK binder calculation happens. This must be readable,
|
||||
* and its size must be equal to the digest size of
|
||||
* the hash algorithm represented by \p md_type.
|
||||
* \param result The address at which to store the PSK binder on success.
|
||||
* This must be writable, and its size must be equal to the
|
||||
* digest size of the hash algorithm represented by
|
||||
* \p md_type.
|
||||
*
|
||||
* \returns \c 0 on success.
|
||||
* \returns A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_ssl_tls1_3_create_psk_binder( mbedtls_ssl_context *ssl,
|
||||
const mbedtls_md_type_t md_type,
|
||||
unsigned char const *psk, size_t psk_len,
|
||||
int psk_type,
|
||||
unsigned char const *transcript,
|
||||
unsigned char *result );
|
||||
|
||||
#endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */
|
||||
|
|
Loading…
Reference in a new issue