From 51d3ab544f46dc5eda6fbd5560f4fddba76215d6 Mon Sep 17 00:00:00 2001 From: Ron Eldor Date: Sun, 12 May 2019 14:54:30 +0300 Subject: [PATCH] Add public API for tls_prf Add a public API for key derivation, introducing an enum for `tls_prf` type. --- include/mbedtls/ssl.h | 60 +++++++++++++++++++++------------- include/mbedtls/ssl_internal.h | 8 +++-- library/ssl_tls.c | 58 ++++++++++++++++++++++++++++++-- programs/ssl/ssl_client2.c | 49 ++++++++++++++++++--------- programs/ssl/ssl_server2.c | 49 ++++++++++++++++++--------- 5 files changed, 164 insertions(+), 60 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 766217c44..a460e2073 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -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 diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index ac4d96dbf..9c4be53f7 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -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; diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 620adf968..df106a530 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -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 diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 353a5800f..a9bcd01f3 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -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, - 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 ) ); + + 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++ ) { @@ -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++ ) { diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 54e2e5197..363b2dc2d 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -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, - 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 ) ); + + 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++ ) { @@ -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++ ) {