Add public API for tls_prf

Add a public API for key derivation, introducing an enum for `tls_prf`
type.
This commit is contained in:
Ron Eldor 2019-05-12 14:54:30 +03:00
parent b7fd64ce2b
commit 51d3ab544f
5 changed files with 164 additions and 60 deletions

View file

@ -450,6 +450,18 @@ typedef enum
}
mbedtls_ssl_states;
/*
* The tls_prf function types.
*/
typedef enum
{
MBEDTLS_SSL_TLS_PRF_NONE,
MBEDTLS_SSL_TLS_PRF_SSL3,
MBEDTLS_SSL_TLS_PRF_TLS1,
MBEDTLS_SSL_TLS_PRF_SHA384,
MBEDTLS_SSL_TLS_PRF_SHA256
}
mbedtls_tls_prf_types;
/**
* \brief Callback type: send data on the network.
*
@ -559,25 +571,6 @@ typedef void mbedtls_ssl_set_timer_t( void * ctx,
*/
typedef int mbedtls_ssl_get_timer_t( void * ctx );
/**
* \brief Function type: TLS-PRF function.
*
* \param secret Secret for the key derivation function.
* \param slen Length of the secret.
* \param label String label for the key derivation function,
* terminated with null character.
* \param random Random bytes.
* \param rlen Length of the random bytes buffer.
* \param dstbuf The buffer holding the derived key.
* \param dlen Length of the output buffer.
*
* \return 0 on sucess. An SSL specific error on failure.
*/
typedef int mbedtls_ssl_tls_prf( const unsigned char *secret, size_t slen,
const char *label,
const unsigned char *random, size_t rlen,
unsigned char *dstbuf, size_t dlen );
/* Defined below */
typedef struct mbedtls_ssl_session mbedtls_ssl_session;
typedef struct mbedtls_ssl_context mbedtls_ssl_context;
@ -943,7 +936,7 @@ struct mbedtls_ssl_config
* tls_prf and random bytes. Should replace f_export_keys */
int (*f_export_keys_ext)( void *, const unsigned char *,
const unsigned char *, size_t, size_t, size_t,
mbedtls_ssl_tls_prf *, unsigned char[32], unsigned char[32]);
unsigned char[32], unsigned char[32], mbedtls_tls_prf_types );
void *p_export_keys; /*!< context for key export callback */
#endif
@ -1667,9 +1660,9 @@ typedef int mbedtls_ssl_export_keys_t( void *p_expkey,
* \param maclen MAC length.
* \param keylen Key length.
* \param ivlen IV length.
* \param tls_prf The TLS PRF function used in the handshake.
* \param client_random The client random bytes.
* \param server_random The server random bytes.
* \param tls_prf_type The tls_prf enum type.
*
* \return 0 if successful, or
* a specific MBEDTLS_ERR_XXX code.
@ -1680,9 +1673,9 @@ typedef int mbedtls_ssl_export_keys_ext_t( void *p_expkey,
size_t maclen,
size_t keylen,
size_t ivlen,
mbedtls_ssl_tls_prf *tls_prf,
unsigned char client_random[32],
unsigned char server_random[32] );
unsigned char server_random[32],
mbedtls_tls_prf_types tls_prf_type );
#endif /* MBEDTLS_SSL_EXPORT_KEYS */
/**
@ -3560,6 +3553,27 @@ void mbedtls_ssl_session_init( mbedtls_ssl_session *session );
*/
void mbedtls_ssl_session_free( mbedtls_ssl_session *session );
/**
* \brief TLS-PRF function for key derivation.
*
* \param prf The tls_prf type funtion type to be used.
* \param secret Secret for the key derivation function.
* \param slen Length of the secret.
* \param label String label for the key derivation function,
* terminated with null character.
* \param random Random bytes.
* \param rlen Length of the random bytes buffer.
* \param dstbuf The buffer holding the derived key.
* \param dlen Length of the output buffer.
*
* \return 0 on sucess. An SSL specific error on failure.
*/
int mbedtls_ssl_tls_prf( const mbedtls_tls_prf_types prf,
const unsigned char *secret, size_t slen,
const char *label,
const unsigned char *random, size_t rlen,
unsigned char *dstbuf, size_t dlen );
#ifdef __cplusplus
}
#endif

View file

@ -276,6 +276,10 @@ struct mbedtls_ssl_sig_hash_set_t
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
typedef int mbedtls_ssl_tls_prf_cb( const unsigned char *secret, size_t slen,
const char *label,
const unsigned char *random, size_t rlen,
unsigned char *dstbuf, size_t dlen );
/*
* This structure contains the parameters only needed during handshake.
*/
@ -425,9 +429,7 @@ struct mbedtls_ssl_handshake_params
void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t);
void (*calc_verify)(mbedtls_ssl_context *, unsigned char *);
void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int);
int (*tls_prf)(const unsigned char *, size_t, const char *,
const unsigned char *, size_t,
unsigned char *, size_t);
mbedtls_ssl_tls_prf_cb *tls_prf;
mbedtls_ssl_ciphersuite_t const *ciphersuite_info;

View file

@ -751,6 +751,43 @@ static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl )
#endif /* MBEDTLS_USE_PSA_CRYPTO &&
MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
int mbedtls_ssl_tls_prf( const mbedtls_tls_prf_types prf,
const unsigned char *secret, size_t slen,
const char *label,
const unsigned char *random, size_t rlen,
unsigned char *dstbuf, size_t dlen )
{
mbedtls_ssl_tls_prf_cb *tls_prf = NULL;
switch( prf )
{
#if defined(MBEDTLS_SSL_PROTO_SSL3)
case MBEDTLS_SSL_TLS_PRF_SSL3:
tls_prf = ssl3_prf;
break;
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
case MBEDTLS_SSL_TLS_PRF_TLS1:
tls_prf = tls1_prf;
break;
#endif
#if defined(MBEDTLS_SHA512_C)
case MBEDTLS_SSL_TLS_PRF_SHA384:
tls_prf = tls_prf_sha384;
break;
#endif
#if defined(MBEDTLS_SHA256_C)
case MBEDTLS_SSL_TLS_PRF_SHA256:
tls_prf = tls_prf_sha256;
break;
#endif
default:
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
}
return( tls_prf( secret, slen, label, random, rlen, dstbuf, dlen ) );
}
int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
{
int ret = 0;
@ -774,6 +811,10 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
* "The master secret is always exactly 48 bytes in length." */
size_t const master_secret_len = 48;
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
mbedtls_tls_prf_types tls_prf_type = MBEDTLS_SSL_TLS_PRF_NONE;
#endif
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
unsigned char session_hash[48];
#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
@ -815,6 +856,9 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
handshake->tls_prf = ssl3_prf;
handshake->calc_verify = ssl_calc_verify_ssl;
handshake->calc_finished = ssl_calc_finished_ssl;
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
tls_prf_type = MBEDTLS_SSL_TLS_PRF_SSL3;
#endif
}
else
#endif
@ -824,6 +868,9 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
handshake->tls_prf = tls1_prf;
handshake->calc_verify = ssl_calc_verify_tls;
handshake->calc_finished = ssl_calc_finished_tls;
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
tls_prf_type = MBEDTLS_SSL_TLS_PRF_TLS1;
#endif
}
else
#endif
@ -835,6 +882,9 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
handshake->tls_prf = tls_prf_sha384;
handshake->calc_verify = ssl_calc_verify_tls_sha384;
handshake->calc_finished = ssl_calc_finished_tls_sha384;
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
tls_prf_type = MBEDTLS_SSL_TLS_PRF_SHA384;
#endif
}
else
#endif
@ -844,6 +894,9 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
handshake->tls_prf = tls_prf_sha256;
handshake->calc_verify = ssl_calc_verify_tls_sha256;
handshake->calc_finished = ssl_calc_finished_tls_sha256;
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
tls_prf_type = MBEDTLS_SSL_TLS_PRF_SHA256;
#endif
}
else
#endif
@ -1271,9 +1324,10 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
ssl->conf->f_export_keys_ext( ssl->conf->p_export_keys,
session->master, keyblk,
mac_key_len, keylen,
iv_copy_len, handshake->tls_prf,
iv_copy_len,
handshake->randbytes + 32,
handshake->randbytes );
handshake->randbytes,
tls_prf_type);
}
#endif

View file

@ -466,7 +466,7 @@ typedef struct eap_tls_keys
{
unsigned char master_secret[48];
unsigned char randbytes[64];
mbedtls_ssl_tls_prf *tls_prf;
mbedtls_tls_prf_types tls_prf_type;
} eap_tls_keys;
static int eap_tls_key_derivation ( void *p_expkey,
@ -475,9 +475,9 @@ static int eap_tls_key_derivation ( void *p_expkey,
size_t maclen,
size_t keylen,
size_t ivlen,
mbedtls_ssl_tls_prf *tls_prf,
unsigned char client_random[32],
unsigned char server_random[32] )
unsigned char server_random[32],
mbedtls_tls_prf_types tls_prf_type )
{
eap_tls_keys *keys = (eap_tls_keys *)p_expkey;
@ -488,7 +488,7 @@ static int eap_tls_key_derivation ( void *p_expkey,
memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) );
memcpy( keys->randbytes, client_random, 32 );
memcpy( keys->randbytes + 32, server_random, 32 );
keys->tls_prf = tls_prf;
keys->tls_prf_type = tls_prf_type;
return( 0 );
}
@ -1979,17 +1979,25 @@ int main( int argc, char *argv[] )
#endif
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
if( opt.eap_tls != 0 &&
eap_tls_keying.tls_prf != NULL )
if( opt.eap_tls != 0 )
{
size_t j = 0;
eap_tls_keying.tls_prf( eap_tls_keying.master_secret,
if( ( ret = mbedtls_ssl_tls_prf( eap_tls_keying.tls_prf_type,
eap_tls_keying.master_secret,
sizeof( eap_tls_keying.master_secret ),
eap_tls_label,
eap_tls_keying.randbytes,
sizeof( eap_tls_keying.randbytes ),
eap_tls_keymaterial,
sizeof( eap_tls_keymaterial ) );
sizeof( eap_tls_keymaterial ) ) )
!= 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_tls_prf returned -0x%x\n\n",
-ret );
goto exit;
}
mbedtls_printf( " EAP-TLS key material is:" );
for( j = 0; j < sizeof( eap_tls_keymaterial ); j++ )
{
@ -1999,9 +2007,18 @@ int main( int argc, char *argv[] )
}
mbedtls_printf("\n");
eap_tls_keying.tls_prf( NULL, 0, eap_tls_label, eap_tls_keying.randbytes,
sizeof( eap_tls_keying.randbytes ), eap_tls_iv,
sizeof( eap_tls_iv ) );
if( ( ret = mbedtls_ssl_tls_prf( eap_tls_keying.tls_prf_type, NULL, 0,
eap_tls_label,
eap_tls_keying.randbytes,
sizeof( eap_tls_keying.randbytes ),
eap_tls_iv,
sizeof( eap_tls_iv ) ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_tls_prf returned -0x%x\n\n",
-ret );
goto exit;
}
mbedtls_printf( " EAP-TLS IV is:" );
for( j = 0; j < sizeof( eap_tls_iv ); j++ )
{

View file

@ -582,7 +582,7 @@ typedef struct eap_tls_keys
{
unsigned char master_secret[48];
unsigned char randbytes[64];
mbedtls_ssl_tls_prf *tls_prf;
mbedtls_tls_prf_types tls_prf_type;
} eap_tls_keys;
static int eap_tls_key_derivation ( void *p_expkey,
@ -591,9 +591,9 @@ static int eap_tls_key_derivation ( void *p_expkey,
size_t maclen,
size_t keylen,
size_t ivlen,
mbedtls_ssl_tls_prf *tls_prf,
unsigned char client_random[32],
unsigned char server_random[32] )
unsigned char server_random[32],
mbedtls_tls_prf_types tls_prf_type )
{
eap_tls_keys *keys = (eap_tls_keys *)p_expkey;
@ -604,7 +604,7 @@ static int eap_tls_key_derivation ( void *p_expkey,
memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) );
memcpy( keys->randbytes, client_random, 32 );
memcpy( keys->randbytes + 32, server_random, 32 );
keys->tls_prf = tls_prf;
keys->tls_prf_type = tls_prf_type;
return( 0 );
}
@ -3180,17 +3180,25 @@ handshake:
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
if( opt.eap_tls != 0 &&
eap_tls_keying.tls_prf != NULL )
if( opt.eap_tls != 0 )
{
size_t j = 0;
eap_tls_keying.tls_prf( eap_tls_keying.master_secret,
if( ( ret = mbedtls_ssl_tls_prf( eap_tls_keying.tls_prf_type,
eap_tls_keying.master_secret,
sizeof( eap_tls_keying.master_secret ),
eap_tls_label,
eap_tls_keying.randbytes,
sizeof( eap_tls_keying.randbytes ),
eap_tls_keymaterial,
sizeof( eap_tls_keymaterial ) );
sizeof( eap_tls_keymaterial ) ) )
!= 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_tls_prf returned -0x%x\n\n",
-ret );
goto exit;
}
mbedtls_printf( " EAP-TLS key material is:" );
for( j = 0; j < sizeof( eap_tls_keymaterial ); j++ )
{
@ -3200,9 +3208,18 @@ handshake:
}
mbedtls_printf("\n");
eap_tls_keying.tls_prf( NULL, 0, eap_tls_label, eap_tls_keying.randbytes,
sizeof( eap_tls_keying.randbytes ), eap_tls_iv,
sizeof( eap_tls_iv ) );
if( ( ret = mbedtls_ssl_tls_prf( eap_tls_keying.tls_prf_type, NULL, 0,
eap_tls_label,
eap_tls_keying.randbytes,
sizeof( eap_tls_keying.randbytes ),
eap_tls_iv,
sizeof( eap_tls_iv ) ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_tls_prf returned -0x%x\n\n",
-ret );
goto exit;
}
mbedtls_printf( " EAP-TLS IV is:" );
for( j = 0; j < sizeof( eap_tls_iv ); j++ )
{