Add public API for tls_prf
Add a public API for key derivation, introducing an enum for `tls_prf`
type.
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 766217c..a460e20 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -450,6 +450,18 @@
}
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 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 @@
* 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 @@
* \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 @@
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_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 ac4d96d..9c4be53 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -276,6 +276,10 @@
#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 @@
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 620adf9..df106a5 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -751,6 +751,43 @@
#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 @@
* "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 @@
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 @@
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 @@
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 @@
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 @@
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 353a580..a9bcd01 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -466,7 +466,7 @@
{
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 @@
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 @@
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 @@
#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 @@
}
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 54e2e51..363b2dc 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -582,7 +582,7 @@
{
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 @@
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 @@
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 @@
#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 @@
}
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++ )
{