Merge remote-tracking branch 'origin/pr/2538' into development

* origin/pr/2538:
  Remove unneeded whitespaces
  Fix mingw CI failures
  Initialize psa_crypto in ssl test
  Fix missing tls version test failures
  Fix typo
  Fix ChangeLog entry location
  Add changeLog entry
  Add test for export keys functionality
  Add function to retrieve the tls_prf type
  Add tests for the public tls_prf API
  Add public API for tls_prf
  Add eap-tls key derivation in the examples.
  Add ChangeLog entry
  Add an extra key export function
  Have the temporary buffer allocated dynamically
  Zeroize secret data in the exit point
  Add a single exit point in key derivation function
This commit is contained in:
Jaeden Amero 2019-05-20 10:58:36 +01:00
commit 9ebcf9b00a
9 changed files with 578 additions and 41 deletions

View file

@ -11,6 +11,9 @@ Features
* Add the oid certificate policy x509 extension.
* It is now possible to perform RSA PKCS v1.5 signatures with RIPEMD-160 digest.
Contributed by Jack Lloyd and Fortanix Inc.
* Extend the MBEDTLS_SSL_EXPORT_KEYS to export the handshake randbytes,
and the used tls-prf.
* Add public API for tls-prf function, according to requested enum.
Bugfix
* Fix private key DER output in the key_app_writer example. File contents
@ -36,6 +39,11 @@ Bugfix
* Add a check for MBEDTLS_X509_CRL_PARSE_C in ssl_server2, guarding the crl
sni entry parameter. Reported by inestlerode in #560.
API Changes
* Extend the MBEDTLS_SSL_EXPORT_KEYS to export the handshake randbytes,
and the used tls-prf.
* Add public API for tls-prf function, according to requested enum.
Changes
* Server's RSA certificate in certs.c was SHA-1 signed. In the default
mbedTLS configuration only SHA-2 signed certificates are accepted.

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.
*
@ -920,6 +932,11 @@ struct mbedtls_ssl_config
/** Callback to export key block and master secret */
int (*f_export_keys)( void *, const unsigned char *,
const unsigned char *, size_t, size_t, size_t );
/** Callback to export key block, master secret,
* 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,
unsigned char[32], unsigned char[32], mbedtls_tls_prf_types );
void *p_export_keys; /*!< context for key export callback */
#endif
@ -1624,6 +1641,41 @@ typedef int mbedtls_ssl_export_keys_t( void *p_expkey,
size_t maclen,
size_t keylen,
size_t ivlen );
/**
* \brief Callback type: Export key block, master secret,
* handshake randbytes and the tls_prf function
* used to derive keys.
*
* \note This is required for certain uses of TLS, e.g. EAP-TLS
* (RFC 5216) and Thread. The key pointers are ephemeral and
* therefore must not be stored. The master secret and keys
* should not be used directly except as an input to a key
* derivation function.
*
* \param p_expkey Context for the callback.
* \param ms Pointer to master secret (fixed length: 48 bytes).
* \param kb Pointer to key block, see RFC 5246 section 6.3.
* (variable length: 2 * maclen + 2 * keylen + 2 * ivlen).
* \param maclen MAC length.
* \param keylen Key length.
* \param ivlen IV length.
* \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.
*/
typedef int mbedtls_ssl_export_keys_ext_t( void *p_expkey,
const unsigned char *ms,
const unsigned char *kb,
size_t maclen,
size_t keylen,
size_t ivlen,
unsigned char client_random[32],
unsigned char server_random[32],
mbedtls_tls_prf_types tls_prf_type );
#endif /* MBEDTLS_SSL_EXPORT_KEYS */
/**
@ -1689,6 +1741,20 @@ void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf,
void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
mbedtls_ssl_export_keys_t *f_export_keys,
void *p_export_keys );
/**
* \brief Configure extended key export callback.
* (Default: none.)
*
* \note See \c mbedtls_ssl_export_keys_ext_t.
*
* \param conf SSL configuration context
* \param f_export_keys_ext Callback for exporting keys
* \param p_export_keys Context for the callback
*/
void mbedtls_ssl_conf_export_keys_ext_cb( mbedtls_ssl_config *conf,
mbedtls_ssl_export_keys_ext_t *f_export_keys_ext,
void *p_export_keys );
#endif /* MBEDTLS_SSL_EXPORT_KEYS */
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
@ -3487,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

@ -425,7 +425,8 @@ static int tls1_prf( const unsigned char *secret, size_t slen,
size_t nb, hs;
size_t i, j, k;
const unsigned char *S1, *S2;
unsigned char tmp[128];
unsigned char *tmp;
size_t tmp_len = 0;
unsigned char h_i[20];
const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx;
@ -433,8 +434,13 @@ static int tls1_prf( const unsigned char *secret, size_t slen,
mbedtls_md_init( &md_ctx );
if( sizeof( tmp ) < 20 + strlen( label ) + rlen )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
tmp_len = 20 + strlen( label ) + rlen;
tmp = mbedtls_calloc( 1, tmp_len );
if( tmp == NULL )
{
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
goto exit;
}
hs = ( slen + 1 ) / 2;
S1 = secret;
@ -449,10 +455,15 @@ static int tls1_prf( const unsigned char *secret, size_t slen,
* First compute P_md5(secret,label+random)[0..dlen]
*/
if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ) ) == NULL )
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
{
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
goto exit;
}
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
return( ret );
{
goto exit;
}
mbedtls_md_hmac_starts( &md_ctx, S1, hs );
mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb );
@ -480,10 +491,15 @@ static int tls1_prf( const unsigned char *secret, size_t slen,
* XOR out with P_sha1(secret,label+random)[0..dlen]
*/
if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ) ) == NULL )
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
{
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
goto exit;
}
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
return( ret );
{
goto exit;
}
mbedtls_md_hmac_starts( &md_ctx, S2, hs );
mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb );
@ -505,12 +521,14 @@ static int tls1_prf( const unsigned char *secret, size_t slen,
dstbuf[i + j] = (unsigned char)( dstbuf[i + j] ^ h_i[j] );
}
exit:
mbedtls_md_free( &md_ctx );
mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
mbedtls_platform_zeroize( tmp, tmp_len );
mbedtls_platform_zeroize( h_i, sizeof( h_i ) );
return( 0 );
mbedtls_free( tmp );
return( ret );
}
#endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */
@ -593,7 +611,8 @@ static int tls_prf_generic( mbedtls_md_type_t md_type,
{
size_t nb;
size_t i, j, k, md_len;
unsigned char tmp[128];
unsigned char *tmp;
size_t tmp_len = 0;
unsigned char h_i[MBEDTLS_MD_MAX_SIZE];
const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx;
@ -606,8 +625,13 @@ static int tls_prf_generic( mbedtls_md_type_t md_type,
md_len = mbedtls_md_get_size( md_info );
if( sizeof( tmp ) < md_len + strlen( label ) + rlen )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
tmp_len = md_len + strlen( label ) + rlen;
tmp = mbedtls_calloc( 1, tmp_len );
if( tmp == NULL )
{
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
goto exit;
}
nb = strlen( label );
memcpy( tmp + md_len, label, nb );
@ -618,7 +642,7 @@ static int tls_prf_generic( mbedtls_md_type_t md_type,
* Compute P_<hash>(secret, label + random)[0..dlen]
*/
if ( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
return( ret );
goto exit;
mbedtls_md_hmac_starts( &md_ctx, secret, slen );
mbedtls_md_hmac_update( &md_ctx, tmp + md_len, nb );
@ -640,12 +664,15 @@ static int tls_prf_generic( mbedtls_md_type_t md_type,
dstbuf[i + j] = h_i[j];
}
exit:
mbedtls_md_free( &md_ctx );
mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
mbedtls_platform_zeroize( tmp, tmp_len );
mbedtls_platform_zeroize( h_i, sizeof( h_i ) );
return( 0 );
mbedtls_free( tmp );
return( ret );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_SHA256_C)
@ -724,6 +751,83 @@ static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl )
#endif /* MBEDTLS_USE_PSA_CRYPTO &&
MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
static mbedtls_tls_prf_types tls_prf_get_type( mbedtls_ssl_tls_prf_cb *tls_prf )
{
#if defined(MBEDTLS_SSL_PROTO_SSL3)
if( tls_prf == ssl3_prf )
{
return( MBEDTLS_SSL_TLS_PRF_SSL3 );
}
else
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
if( tls_prf == tls1_prf )
{
return( MBEDTLS_SSL_TLS_PRF_TLS1 );
}
else
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA512_C)
if( tls_prf == tls_prf_sha384 )
{
return( MBEDTLS_SSL_TLS_PRF_SHA384 );
}
else
#endif
#if defined(MBEDTLS_SHA256_C)
if( tls_prf == tls_prf_sha256 )
{
return( MBEDTLS_SSL_TLS_PRF_SHA256 );
}
else
#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
return( MBEDTLS_SSL_TLS_PRF_NONE );
}
#endif /* MBEDTLS_SSL_EXPORT_KEYS */
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 /* MBEDTLS_SSL_PROTO_SSL3 */
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
case MBEDTLS_SSL_TLS_PRF_TLS1:
tls_prf = tls1_prf;
break;
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA512_C)
case MBEDTLS_SSL_TLS_PRF_SHA384:
tls_prf = tls_prf_sha384;
break;
#endif /* MBEDTLS_SHA512_C */
#if defined(MBEDTLS_SHA256_C)
case MBEDTLS_SSL_TLS_PRF_SHA256:
tls_prf = tls_prf_sha256;
break;
#endif /* MBEDTLS_SHA256_C */
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
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;
@ -988,9 +1092,6 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_BUF( 4, "random bytes", handshake->randbytes, 64 );
MBEDTLS_SSL_DEBUG_BUF( 4, "key block", keyblk, 256 );
mbedtls_platform_zeroize( handshake->randbytes,
sizeof( handshake->randbytes ) );
/*
* Determine the appropriate key, IV and MAC length.
*/
@ -1036,7 +1137,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
( ret = mbedtls_md_setup( &transform->md_ctx_dec, md_info, 1 ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
return( ret );
goto end;
}
/* Get MAC length */
@ -1106,7 +1207,8 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
#endif
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
goto end;
}
}
}
@ -1168,7 +1270,8 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_SSL_SRV_C */
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
goto end;
}
#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
@ -1178,7 +1281,8 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
if( mac_key_len > sizeof( transform->mac_enc ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
goto end;
}
memcpy( transform->mac_enc, mac_enc, mac_key_len );
@ -1202,7 +1306,8 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
#endif
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
goto end;
}
#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
@ -1220,7 +1325,8 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
mac_key_len ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_init", ret );
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
goto end;
}
}
#else
@ -1236,6 +1342,17 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
mac_key_len, keylen,
iv_copy_len );
}
if( ssl->conf->f_export_keys_ext != NULL )
{
ssl->conf->f_export_keys_ext( ssl->conf->p_export_keys,
session->master, keyblk,
mac_key_len, keylen,
iv_copy_len,
handshake->randbytes + 32,
handshake->randbytes,
tls_prf_get_type( handshake->tls_prf ) );
}
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
@ -1253,7 +1370,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup_psa", ret );
return( ret );
goto end;
}
if( ret == 0 )
@ -1279,7 +1396,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
cipher_info ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
return( ret );
goto end;
}
#if defined(MBEDTLS_USE_PSA_CRYPTO)
@ -1296,7 +1413,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup_psa", ret );
return( ret );
goto end;
}
if( ret == 0 )
@ -1322,7 +1439,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
cipher_info ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
return( ret );
goto end;
}
if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_enc, key1,
@ -1330,7 +1447,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
MBEDTLS_ENCRYPT ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
return( ret );
goto end;
}
if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_dec, key2,
@ -1338,7 +1455,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
MBEDTLS_DECRYPT ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
return( ret );
goto end;
}
#if defined(MBEDTLS_CIPHER_MODE_CBC)
@ -1348,19 +1465,18 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
MBEDTLS_PADDING_NONE ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
return( ret );
goto end;
}
if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_dec,
MBEDTLS_PADDING_NONE ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
return( ret );
goto end;
}
}
#endif /* MBEDTLS_CIPHER_MODE_CBC */
mbedtls_platform_zeroize( keyblk, sizeof( keyblk ) );
#if defined(MBEDTLS_ZLIB_SUPPORT)
// Initialize compression
@ -1375,7 +1491,8 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
MBEDTLS_SSL_COMPRESS_BUFFER_LEN ) );
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
goto end;
}
}
@ -1389,14 +1506,18 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
inflateInit( &transform->ctx_inflate ) != Z_OK )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to initialize compression" ) );
return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
ret = MBEDTLS_ERR_SSL_COMPRESSION_FAILED;
goto end;
}
}
#endif /* MBEDTLS_ZLIB_SUPPORT */
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= derive keys" ) );
return( 0 );
end:
mbedtls_platform_zeroize( keyblk, sizeof( keyblk ) );
mbedtls_platform_zeroize( handshake->randbytes,
sizeof( handshake->randbytes ) );
return( ret );
}
#if defined(MBEDTLS_SSL_PROTO_SSL3)
@ -8620,6 +8741,14 @@ void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
conf->f_export_keys = f_export_keys;
conf->p_export_keys = p_export_keys;
}
void mbedtls_ssl_conf_export_keys_ext_cb( mbedtls_ssl_config *conf,
mbedtls_ssl_export_keys_ext_t *f_export_keys_ext,
void *p_export_keys )
{
conf->f_export_keys_ext = f_export_keys_ext;
conf->p_export_keys = p_export_keys;
}
#endif
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)

View file

@ -126,7 +126,7 @@ int main( void )
#define DFL_EXTENDED_MS -1
#define DFL_ETM -1
#define DFL_CA_CALLBACK 0
#define DFL_EAP_TLS 0
#define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: "
#define GET_REQUEST_END "\r\n\r\n"
@ -204,6 +204,13 @@ int main( void )
#define USAGE_TICKETS ""
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
#define USAGE_EAP_TLS \
" eap_tls=%%d default: 0 (disabled)\n"
#else
#define USAGE_EAP_TLS ""
#endif /* MBEDTLS_SSL_EXPORT_KEYS */
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
#define USAGE_TRUNC_HMAC \
" trunc_hmac=%%d default: library default\n"
@ -348,6 +355,7 @@ int main( void )
" reco_delay=%%d default: 0 seconds\n" \
" reconnect_hard=%%d default: 0 (disabled)\n" \
USAGE_TICKETS \
USAGE_EAP_TLS \
USAGE_MAX_FRAG_LEN \
USAGE_TRUNC_HMAC \
USAGE_CONTEXT_CRT_CB \
@ -448,10 +456,47 @@ struct options
int extended_ms; /* negotiate extended master secret? */
int etm; /* negotiate encrypt then mac? */
int context_crt_cb; /* use context-specific CRT verify callback */
int eap_tls; /* derive EAP-TLS keying material? */
} opt;
int query_config( const char *config );
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
typedef struct eap_tls_keys
{
unsigned char master_secret[48];
unsigned char randbytes[64];
mbedtls_tls_prf_types tls_prf_type;
} eap_tls_keys;
static int eap_tls_key_derivation ( void *p_expkey,
const unsigned char *ms,
const unsigned char *kb,
size_t maclen,
size_t keylen,
size_t ivlen,
unsigned char client_random[32],
unsigned char server_random[32],
mbedtls_tls_prf_types tls_prf_type )
{
eap_tls_keys *keys = (eap_tls_keys *)p_expkey;
( ( void ) kb );
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_type = tls_prf_type;
if( opt.debug_level > 2 )
{
mbedtls_printf("exported maclen is %u\n", (unsigned)maclen);
mbedtls_printf("exported keylen is %u\n", (unsigned)keylen);
mbedtls_printf("exported ivlen is %u\n", (unsigned)ivlen);
}
return( 0 );
}
#endif
static void my_debug( void *ctx, int level,
const char *file, int line,
const char *str )
@ -713,6 +758,12 @@ int main( int argc, char *argv[] )
#endif
char *p, *q;
const int *list;
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
unsigned char eap_tls_keymaterial[16];
unsigned char eap_tls_iv[8];
const char* eap_tls_label = "client EAP encryption";
eap_tls_keys eap_tls_keying;
#endif
/*
* Make sure memory references are valid.
@ -818,6 +869,7 @@ int main( int argc, char *argv[] )
opt.extended_ms = DFL_EXTENDED_MS;
opt.etm = DFL_ETM;
opt.dgram_packing = DFL_DGRAM_PACKING;
opt.eap_tls = DFL_EAP_TLS;
for( i = 1; i < argc; i++ )
{
@ -1176,6 +1228,12 @@ int main( int argc, char *argv[] )
{
return query_config( q );
}
else if( strcmp( p, "eap_tls" ) == 0 )
{
opt.eap_tls = atoi( q );
if( opt.eap_tls < 0 || opt.eap_tls > 1 )
goto usage;
}
else
goto usage;
}
@ -1652,6 +1710,12 @@ int main( int argc, char *argv[] )
mbedtls_ssl_conf_encrypt_then_mac( &conf, opt.etm );
#endif
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
if( opt.eap_tls != 0 )
mbedtls_ssl_conf_export_keys_ext_cb( &conf, eap_tls_key_derivation,
&eap_tls_keying );
#endif
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
if( opt.recsplit != DFL_RECSPLIT )
mbedtls_ssl_conf_cbc_record_splitting( &conf, opt.recsplit
@ -1917,6 +1981,57 @@ int main( int argc, char *argv[] )
}
#endif
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
if( opt.eap_tls != 0 )
{
size_t j = 0;
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 ) ) )
!= 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++ )
{
if( j % 8 == 0 )
mbedtls_printf("\n ");
mbedtls_printf("%02x ", eap_tls_keymaterial[j] );
}
mbedtls_printf("\n");
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++ )
{
if( j % 8 == 0 )
mbedtls_printf("\n ");
mbedtls_printf("%02x ", eap_tls_iv[j] );
}
mbedtls_printf("\n");
}
#endif
if( opt.reconnect != 0 )
{
mbedtls_printf(" . Saving session for reuse..." );

View file

@ -168,6 +168,7 @@ int main( void )
#define DFL_EXTENDED_MS -1
#define DFL_ETM -1
#define DFL_CA_CALLBACK 0
#define DFL_EAP_TLS 0
#define LONG_RESPONSE "<p>01-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
"02-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
@ -281,6 +282,13 @@ int main( void )
#define USAGE_TICKETS ""
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
#define USAGE_EAP_TLS \
" eap_tls=%%d default: 0 (disabled)\n"
#else
#define USAGE_EAP_TLS ""
#endif /* MBEDTLS_SSL_EXPORT_KEYS */
#if defined(MBEDTLS_SSL_CACHE_C)
#define USAGE_CACHE \
" cache_max=%%d default: cache default (50)\n" \
@ -442,6 +450,7 @@ int main( void )
" exchanges=%%d default: 1\n" \
"\n" \
USAGE_TICKETS \
USAGE_EAP_TLS \
USAGE_CACHE \
USAGE_MAX_FRAG_LEN \
USAGE_TRUNC_HMAC \
@ -563,10 +572,47 @@ struct options
int dtls_mtu; /* UDP Maximum tranport unit for DTLS */
int dgram_packing; /* allow/forbid datagram packing */
int badmac_limit; /* Limit of records with bad MAC */
int eap_tls; /* derive EAP-TLS keying material? */
} opt;
int query_config( const char *config );
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
typedef struct eap_tls_keys
{
unsigned char master_secret[48];
unsigned char randbytes[64];
mbedtls_tls_prf_types tls_prf_type;
} eap_tls_keys;
static int eap_tls_key_derivation ( void *p_expkey,
const unsigned char *ms,
const unsigned char *kb,
size_t maclen,
size_t keylen,
size_t ivlen,
unsigned char client_random[32],
unsigned char server_random[32],
mbedtls_tls_prf_types tls_prf_type )
{
eap_tls_keys *keys = (eap_tls_keys *)p_expkey;
( ( void ) kb );
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_type = tls_prf_type;
if( opt.debug_level > 2 )
{
mbedtls_printf("exported maclen is %u\n", (unsigned)maclen);
mbedtls_printf("exported keylen is %u\n", (unsigned)keylen);
mbedtls_printf("exported ivlen is %u\n", (unsigned)ivlen);
}
return( 0 );
}
#endif
static void my_debug( void *ctx, int level,
const char *file, int line,
const char *str )
@ -1444,6 +1490,12 @@ int main( int argc, char *argv[] )
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_status_t status;
#endif
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
unsigned char eap_tls_keymaterial[16];
unsigned char eap_tls_iv[8];
const char* eap_tls_label = "client EAP encryption";
eap_tls_keys eap_tls_keying;
#endif
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
@ -1585,6 +1637,7 @@ int main( int argc, char *argv[] )
opt.badmac_limit = DFL_BADMAC_LIMIT;
opt.extended_ms = DFL_EXTENDED_MS;
opt.etm = DFL_ETM;
opt.eap_tls = DFL_EAP_TLS;
for( i = 1; i < argc; i++ )
{
@ -1975,6 +2028,12 @@ int main( int argc, char *argv[] )
{
return query_config( q );
}
else if( strcmp( p, "eap_tls" ) == 0 )
{
opt.eap_tls = atoi( q );
if( opt.eap_tls < 0 || opt.eap_tls > 1 )
goto usage;
}
else
goto usage;
}
@ -2537,6 +2596,12 @@ int main( int argc, char *argv[] )
mbedtls_ssl_conf_encrypt_then_mac( &conf, opt.etm );
#endif
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
if( opt.eap_tls != 0 )
mbedtls_ssl_conf_export_keys_ext_cb( &conf, eap_tls_key_derivation,
&eap_tls_keying );
#endif
#if defined(MBEDTLS_SSL_ALPN)
if( opt.alpn_string != NULL )
if( ( ret = mbedtls_ssl_conf_alpn_protocols( &conf, alpn_list ) ) != 0 )
@ -3117,6 +3182,57 @@ handshake:
}
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
if( opt.eap_tls != 0 )
{
size_t j = 0;
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 ) ) )
!= 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++ )
{
if( j % 8 == 0 )
mbedtls_printf("\n ");
mbedtls_printf("%02x ", eap_tls_keymaterial[j] );
}
mbedtls_printf("\n");
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++ )
{
if( j % 8 == 0 )
mbedtls_printf("\n ");
mbedtls_printf("%02x ", eap_tls_iv[j] );
}
mbedtls_printf("\n");
}
#endif
if( opt.exchanges == 0 )
goto close_notify;

View file

@ -7939,6 +7939,18 @@ run_test "DTLS proxy: 3d, gnutls server, fragmentation, nbio" \
-s "Extra-header:" \
-c "Extra-header:"
requires_config_enabled MBEDTLS_SSL_EXPORT_KEYS
run_test "export keys functionality" \
"$P_SRV eap_tls=1 debug_level=3" \
"$P_CLI eap_tls=1 debug_level=3" \
0 \
-s "exported maclen is " \
-s "exported keylen is " \
-s "exported ivlen is " \
-c "exported maclen is " \
-c "exported keylen is " \
-c "exported ivlen is "
# Final report
echo "------------------------------------------------------------------------"

View file

@ -5633,3 +5633,42 @@ ssl_crypt_record_small:MBEDTLS_CIPHER_NULL:MBEDTLS_MD_MD5:0:1:MBEDTLS_SSL_MINOR_
Record crypt, little space, NULL cipher, SSL3, MD5, short tag, EtM
depends_on:MBEDTLS_CIPHER_NULL_CIPHER:MBEDTLS_SSL_PROTO_SSL3:MBEDTLS_MD5_C:MBEDTLS_SSL_ENCRYPT_THEN_MAC
ssl_crypt_record_small:MBEDTLS_CIPHER_NULL:MBEDTLS_MD_MD5:1:1:MBEDTLS_SSL_MINOR_VERSION_0
SSL TLS_PRF MBEDTLS_SSL_TLS_PRF_NONE
ssl_tls_prf:MBEDTLS_SSL_TLS_PRF_NONE:"":"":"test tls_prf label":"":MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE
SSL TLS_PRF MBEDTLS_SSL_TLS_PRF_SSL3
depends_on:MBEDTLS_SSL_PROTO_SSL3
ssl_tls_prf:MBEDTLS_SSL_TLS_PRF_SSL3:"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"test tls_prf label":"3ff3d192aa599255339def5a9723444a":0
SSL TLS_PRF MBEDTLS_SSL_TLS_PRF_TLS1 TLS 1.0 enabled
depends_on:MBEDTLS_SSL_PROTO_TLS1
ssl_tls_prf:MBEDTLS_SSL_TLS_PRF_TLS1:"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"test tls_prf label":"8defca540d41d4c79d390027295bb4e6":0
SSL TLS_PRF MBEDTLS_SSL_TLS_PRF_TLS1 TLS 1.1 enabled
depends_on:MBEDTLS_SSL_PROTO_TLS1_1
ssl_tls_prf:MBEDTLS_SSL_TLS_PRF_TLS1:"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"test tls_prf label":"8defca540d41d4c79d390027295bb4e6":0
SSL TLS_PRF MBEDTLS_SSL_TLS_PRF_SHA384
depends_on:MBEDTLS_SHA512_C:MBEDTLS_SSL_PROTO_TLS1_2
ssl_tls_prf:MBEDTLS_SSL_TLS_PRF_SHA384:"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"test tls_prf label":"a4206a36eef93f496611c2b7806625c3":0
SSL TLS_PRF MBEDTLS_SSL_TLS_PRF_SHA256
depends_on:MBEDTLS_SHA256_C:MBEDTLS_SSL_PROTO_TLS1_2
ssl_tls_prf:MBEDTLS_SSL_TLS_PRF_SHA256:"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"test tls_prf label":"7f9998393198a02c8d731ccc2ef90b2c":0
SSL TLS_PRF MBEDTLS_SSL_TLS_PRF_SSL3 not enabled
depends_on:!MBEDTLS_SSL_PROTO_SSL3
ssl_tls_prf:MBEDTLS_SSL_TLS_PRF_SSL3:"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"test tls_prf label":"3ff3d192aa599255339def5a9723444a":MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE
SSL TLS_PRF MBEDTLS_SSL_TLS_PRF_TLS1 TLS 1.X not enabled
depends_on:!MBEDTLS_SSL_PROTO_TLS1:!MBEDTLS_SSL_PROTO_TLS1_1
ssl_tls_prf:MBEDTLS_SSL_TLS_PRF_TLS1:"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"test tls_prf label":"8defca540d41d4c79d390027295bb4e6":MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE
SSL TLS_PRF MBEDTLS_SSL_TLS_PRF_SHA384 SHA-512 not enabled
depends_on:!MBEDTLS_SHA512_C
ssl_tls_prf:MBEDTLS_SSL_TLS_PRF_SHA384:"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"test tls_prf label":"a4206a36eef93f496611c2b7806625c3":MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE
SSL TLS_PRF MBEDTLS_SSL_TLS_PRF_SHA256 SHA-256 not enabled
depends_on:!MBEDTLS_SHA256_C
ssl_tls_prf:MBEDTLS_SSL_TLS_PRF_SHA256:"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"test tls_prf label":"7f9998393198a02c8d731ccc2ef90b2c":MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE

View file

@ -541,3 +541,32 @@ exit:
mbedtls_free( buf );
}
/* END_CASE */
/* BEGIN_CASE */
void ssl_tls_prf( int type, data_t * secret, data_t * random,
char *label, data_t *result_hex_str, int exp_ret )
{
unsigned char *output;
output = mbedtls_calloc( 1, result_hex_str->len );
if( output == NULL )
goto exit;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
TEST_ASSERT( psa_crypto_init() == 0 );
#endif
TEST_ASSERT( mbedtls_ssl_tls_prf( type, secret->x, secret->len,
label, random->x, random->len,
output, result_hex_str->len ) == exp_ret );
if( exp_ret == 0 )
{
TEST_ASSERT( hexcmp( output, result_hex_str->x,
result_hex_str->len, result_hex_str->len ) == 0 );
}
exit:
mbedtls_free( output );
}
/* END_CASE */