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; 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. * \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 ); 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 */ /* Defined below */
typedef struct mbedtls_ssl_session mbedtls_ssl_session; typedef struct mbedtls_ssl_session mbedtls_ssl_session;
typedef struct mbedtls_ssl_context mbedtls_ssl_context; 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 */ * tls_prf and random bytes. Should replace f_export_keys */
int (*f_export_keys_ext)( void *, const unsigned char *, int (*f_export_keys_ext)( void *, const unsigned char *,
const unsigned char *, size_t, size_t, size_t, 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 */ void *p_export_keys; /*!< context for key export callback */
#endif #endif
@ -1667,9 +1660,9 @@ typedef int mbedtls_ssl_export_keys_t( void *p_expkey,
* \param maclen MAC length. * \param maclen MAC length.
* \param keylen Key length. * \param keylen Key length.
* \param ivlen IV length. * \param ivlen IV length.
* \param tls_prf The TLS PRF function used in the handshake.
* \param client_random The client random bytes. * \param client_random The client random bytes.
* \param server_random The server random bytes. * \param server_random The server random bytes.
* \param tls_prf_type The tls_prf enum type.
* *
* \return 0 if successful, or * \return 0 if successful, or
* a specific MBEDTLS_ERR_XXX code. * 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 maclen,
size_t keylen, size_t keylen,
size_t ivlen, size_t ivlen,
mbedtls_ssl_tls_prf *tls_prf,
unsigned char client_random[32], 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 */ #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 ); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -276,6 +276,10 @@ struct mbedtls_ssl_sig_hash_set_t
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && #endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ 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. * 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 (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t);
void (*calc_verify)(mbedtls_ssl_context *, unsigned char *); void (*calc_verify)(mbedtls_ssl_context *, unsigned char *);
void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int); void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int);
int (*tls_prf)(const unsigned char *, size_t, const char *, mbedtls_ssl_tls_prf_cb *tls_prf;
const unsigned char *, size_t,
unsigned char *, size_t);
mbedtls_ssl_ciphersuite_t const *ciphersuite_info; 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 && #endif /* MBEDTLS_USE_PSA_CRYPTO &&
MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ 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 mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
{ {
int ret = 0; 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." */ * "The master secret is always exactly 48 bytes in length." */
size_t const master_secret_len = 48; 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) #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
unsigned char session_hash[48]; unsigned char session_hash[48];
#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ #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->tls_prf = ssl3_prf;
handshake->calc_verify = ssl_calc_verify_ssl; handshake->calc_verify = ssl_calc_verify_ssl;
handshake->calc_finished = ssl_calc_finished_ssl; handshake->calc_finished = ssl_calc_finished_ssl;
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
tls_prf_type = MBEDTLS_SSL_TLS_PRF_SSL3;
#endif
} }
else else
#endif #endif
@ -824,6 +868,9 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
handshake->tls_prf = tls1_prf; handshake->tls_prf = tls1_prf;
handshake->calc_verify = ssl_calc_verify_tls; handshake->calc_verify = ssl_calc_verify_tls;
handshake->calc_finished = ssl_calc_finished_tls; handshake->calc_finished = ssl_calc_finished_tls;
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
tls_prf_type = MBEDTLS_SSL_TLS_PRF_TLS1;
#endif
} }
else else
#endif #endif
@ -835,6 +882,9 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
handshake->tls_prf = tls_prf_sha384; handshake->tls_prf = tls_prf_sha384;
handshake->calc_verify = ssl_calc_verify_tls_sha384; handshake->calc_verify = ssl_calc_verify_tls_sha384;
handshake->calc_finished = ssl_calc_finished_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 else
#endif #endif
@ -844,6 +894,9 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
handshake->tls_prf = tls_prf_sha256; handshake->tls_prf = tls_prf_sha256;
handshake->calc_verify = ssl_calc_verify_tls_sha256; handshake->calc_verify = ssl_calc_verify_tls_sha256;
handshake->calc_finished = ssl_calc_finished_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 else
#endif #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, ssl->conf->f_export_keys_ext( ssl->conf->p_export_keys,
session->master, keyblk, session->master, keyblk,
mac_key_len, keylen, mac_key_len, keylen,
iv_copy_len, handshake->tls_prf, iv_copy_len,
handshake->randbytes + 32, handshake->randbytes + 32,
handshake->randbytes ); handshake->randbytes,
tls_prf_type);
} }
#endif #endif

View File

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