From 78ba2af7c2e24626bb01fece73513a06c4a4fa74 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 24 May 2021 10:27:05 +0100 Subject: [PATCH 01/16] Remove old key export API Seems to be an oversight that this wasn't marked deprecated. Signed-off-by: Hanno Becker --- include/mbedtls/ssl.h | 30 ------------------------------ library/ssl_tls.c | 16 ---------------- 2 files changed, 46 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 603615b3c8..6c24aab77b 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1033,9 +1033,6 @@ struct mbedtls_ssl_config #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ #if defined(MBEDTLS_SSL_EXPORT_KEYS) - /** Callback to export key block and master secret */ - int (*MBEDTLS_PRIVATE(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 (*MBEDTLS_PRIVATE(f_export_keys_ext))( void *, const unsigned char *, @@ -1919,33 +1916,6 @@ typedef int mbedtls_ssl_ticket_write_t( void *p_ticket, uint32_t *lifetime ); #if defined(MBEDTLS_SSL_EXPORT_KEYS) -/** - * \brief Callback type: Export key block and master secret - * - * \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 - * - * \return 0 if successful, or - * a specific MBEDTLS_ERR_XXX code. - */ -typedef int mbedtls_ssl_export_keys_t( void *p_expkey, - const unsigned char *ms, - const unsigned char *kb, - size_t maclen, - size_t keylen, - size_t ivlen ); - /** * \brief Callback type: Export key block, master secret, * handshake randbytes and the tls_prf function diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 2961637a85..e6bc790fe5 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -986,14 +986,6 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform, ((void) mac_enc); #if defined(MBEDTLS_SSL_EXPORT_KEYS) - if( ssl->conf->f_export_keys != NULL ) - { - ssl->conf->f_export_keys( ssl->conf->p_export_keys, - master, keyblk, - 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, @@ -4193,14 +4185,6 @@ void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf, #endif /* MBEDTLS_SSL_SESSION_TICKETS */ #if defined(MBEDTLS_SSL_EXPORT_KEYS) -void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, - mbedtls_ssl_export_keys_t *f_export_keys, - void *p_export_keys ) -{ - 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 ) From 2d6e6f8fec7fe3a116f7aefe39644bad0df6506b Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 24 May 2021 10:58:31 +0100 Subject: [PATCH 02/16] Remove '_ext' suffix from SSL key exporter API Signed-off-by: Hanno Becker --- include/mbedtls/config.h | 2 +- include/mbedtls/ssl.h | 12 ++++++------ library/ssl_tls.c | 10 +++++----- programs/ssl/ssl_client2.c | 6 +++--- programs/ssl/ssl_server2.c | 6 +++--- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 598e59fcbd..e9da07a6e2 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1556,7 +1556,7 @@ * (see Section 5 of RFC 5764), are not handled by this feature. * Instead, after successful completion of a handshake negotiating * the use of DTLS-SRTP, the extended key exporter API - * mbedtls_ssl_conf_export_keys_ext_cb() should be used to implement + * mbedtls_ssl_conf_export_keys_cb() should be used to implement * the key exporter described in Section 4.2 of RFC 5764 and RFC 5705 * (this is implemented in the SSL example programs). * The resulting key should then be passed to an SRTP stack. diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 6c24aab77b..410ac0e0a2 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1035,7 +1035,7 @@ struct mbedtls_ssl_config #if defined(MBEDTLS_SSL_EXPORT_KEYS) /** Callback to export key block, master secret, * tls_prf and random bytes. Should replace f_export_keys */ - int (*MBEDTLS_PRIVATE(f_export_keys_ext))( void *, const unsigned char *, + int (*MBEDTLS_PRIVATE(f_export_keys))( void *, const unsigned char *, const unsigned char *, size_t, size_t, size_t, const unsigned char[32], const unsigned char[32], mbedtls_tls_prf_types ); @@ -1941,7 +1941,7 @@ typedef int mbedtls_ssl_ticket_write_t( void *p_ticket, * \return 0 if successful, or * a specific MBEDTLS_ERR_XXX code. */ -typedef int mbedtls_ssl_export_keys_ext_t( void *p_expkey, +typedef int mbedtls_ssl_export_keys_t( void *p_expkey, const unsigned char *ms, const unsigned char *kb, size_t maclen, @@ -2020,16 +2020,16 @@ void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, * \brief Configure extended key export callback. * (Default: none.) * - * \note See \c mbedtls_ssl_export_keys_ext_t. + * \note See \c mbedtls_ssl_export_keys_t. * \warning Exported key material must not be used for any purpose * before the (D)TLS handshake is completed * * \param conf SSL configuration context - * \param f_export_keys_ext Callback for exporting keys + * \param f_export_keys 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 mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, + mbedtls_ssl_export_keys_t *f_export_keys, void *p_export_keys ); #endif /* MBEDTLS_SSL_EXPORT_KEYS */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index e6bc790fe5..94f906afcb 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -986,9 +986,9 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform, ((void) mac_enc); #if defined(MBEDTLS_SSL_EXPORT_KEYS) - if( ssl->conf->f_export_keys_ext != NULL ) + if( ssl->conf->f_export_keys != NULL ) { - ssl->conf->f_export_keys_ext( ssl->conf->p_export_keys, + ssl->conf->f_export_keys( ssl->conf->p_export_keys, master, keyblk, mac_key_len, keylen, iv_copy_len, @@ -4185,11 +4185,11 @@ void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf, #endif /* MBEDTLS_SSL_SESSION_TICKETS */ #if defined(MBEDTLS_SSL_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 mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, + mbedtls_ssl_export_keys_t *f_export_keys, void *p_export_keys ) { - conf->f_export_keys_ext = f_export_keys_ext; + conf->f_export_keys = f_export_keys; conf->p_export_keys = p_export_keys; } #endif diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 322cef8b45..bc5ed2e9ee 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -1739,19 +1739,19 @@ int main( int argc, char *argv[] ) #if defined(MBEDTLS_SSL_EXPORT_KEYS) if( opt.eap_tls != 0 ) { - mbedtls_ssl_conf_export_keys_ext_cb( &conf, eap_tls_key_derivation, + mbedtls_ssl_conf_export_keys_cb( &conf, eap_tls_key_derivation, &eap_tls_keying ); } else if( opt.nss_keylog != 0 ) { - mbedtls_ssl_conf_export_keys_ext_cb( &conf, + mbedtls_ssl_conf_export_keys_cb( &conf, nss_keylog_export, NULL ); } #if defined( MBEDTLS_SSL_DTLS_SRTP ) else if( opt.use_srtp != 0 ) { - mbedtls_ssl_conf_export_keys_ext_cb( &conf, dtls_srtp_key_derivation, + mbedtls_ssl_conf_export_keys_cb( &conf, dtls_srtp_key_derivation, &dtls_srtp_keying ); } #endif /* MBEDTLS_SSL_DTLS_SRTP */ diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 51125bdb69..334eb7d445 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -2528,19 +2528,19 @@ int main( int argc, char *argv[] ) #if defined(MBEDTLS_SSL_EXPORT_KEYS) if( opt.eap_tls != 0 ) { - mbedtls_ssl_conf_export_keys_ext_cb( &conf, eap_tls_key_derivation, + mbedtls_ssl_conf_export_keys_cb( &conf, eap_tls_key_derivation, &eap_tls_keying ); } else if( opt.nss_keylog != 0 ) { - mbedtls_ssl_conf_export_keys_ext_cb( &conf, + mbedtls_ssl_conf_export_keys_cb( &conf, nss_keylog_export, NULL ); } #if defined( MBEDTLS_SSL_DTLS_SRTP ) else if( opt.use_srtp != 0 ) { - mbedtls_ssl_conf_export_keys_ext_cb( &conf, dtls_srtp_key_derivation, + mbedtls_ssl_conf_export_keys_cb( &conf, dtls_srtp_key_derivation, &dtls_srtp_keying ); } #endif /* MBEDTLS_SSL_DTLS_SRTP */ From 457d61602f4fcf6d0f50edc2c070a674646b96b5 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 24 May 2021 10:27:39 +0100 Subject: [PATCH 03/16] Define and implement new key export API for Mbed TLS 3.0 Signed-off-by: Hanno Becker --- include/mbedtls/ssl.h | 151 ++++++++++++++++++++---------------------- library/ssl_tls.c | 15 ++--- 2 files changed, 79 insertions(+), 87 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 410ac0e0a2..38a4a64d36 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -458,18 +458,6 @@ typedef enum } mbedtls_ssl_states; -/* - * The tls_prf function types. - */ -typedef enum -{ - MBEDTLS_SSL_TLS_PRF_NONE, - 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. * @@ -967,6 +955,58 @@ struct mbedtls_ssl_session #endif }; +/* + * Identifiers for PRFs used in various versions of TLS. + */ +typedef enum +{ + MBEDTLS_SSL_TLS_PRF_NONE, + MBEDTLS_SSL_TLS_PRF_TLS1, + MBEDTLS_SSL_TLS_PRF_SHA384, + MBEDTLS_SSL_TLS_PRF_SHA256, + MBEDTLS_SSL_HKDF_EXPAND_SHA384, + MBEDTLS_SSL_HKDF_EXPAND_SHA256 +} +mbedtls_tls_prf_types; + +#if defined(MBEDTLS_SSL_EXPORT_KEYS) +typedef enum +{ + MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET = 0, +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + MBEDTLS_SSL_KEY_EXPORT_TLS13_CLIENT_EARLY_SECRET, + MBEDTLS_SSL_KEY_EXPORT_TLS13_EARLY_EXPORTER_SECRET, + MBEDTLS_SSL_KEY_EXPORT_TLS13_CLIENT_HANDSHAKE_TRAFFIC_SECRET, + MBEDTLS_SSL_KEY_EXPORT_TLS13_SERVER_HANDSHAKE_TRAFFIC_SECRET, + MBEDTLS_SSL_KEY_EXPORT_TLS13_CLIENT_APPLICATION_TRAFFIC_SECRET, + MBEDTLS_SSL_KEY_EXPORT_TLS13_SERVER_APPLICATION_TRAFFIC_SECRET, +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ +} mbedtls_ssl_key_export_type; + +/** + * \brief Callback type: Export key alongside random values for + * session identification, and PRF for + * implementation of TLS key exporters. + * + * \param p_expkey Context for the callback. + * \param type The type of the key that is being exported. + * \param client_random The client random bytes. + * \param server_random The server random bytes. + * \param tls_prf_type The identifier for the PRF used in the handshake + * to which the key belongs. + * + * \return \c 0 if successful. + * \return A negative error code on failure. + */ +typedef int mbedtls_ssl_export_keys_t( void *p_expkey, + mbedtls_ssl_key_export_type type, + const unsigned char *secret, + size_t secret_len, + const unsigned char client_random[32], + const unsigned char server_random[32], + mbedtls_tls_prf_types tls_prf_type ); +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ + /** * SSL/TLS configuration to be shared between mbedtls_ssl_context structures. */ @@ -1033,12 +1073,8 @@ struct mbedtls_ssl_config #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ #if defined(MBEDTLS_SSL_EXPORT_KEYS) - /** Callback to export key block, master secret, - * tls_prf and random bytes. Should replace f_export_keys */ - int (*MBEDTLS_PRIVATE(f_export_keys))( void *, const unsigned char *, - const unsigned char *, size_t, size_t, size_t, - const unsigned char[32], const unsigned char[32], - mbedtls_tls_prf_types ); + /** Callback to export key block and master secret */ + mbedtls_ssl_export_keys_t *MBEDTLS_PRIVATE(f_export_keys); void *MBEDTLS_PRIVATE(p_export_keys); /*!< context for key export callback */ #endif @@ -1915,43 +1951,6 @@ typedef int mbedtls_ssl_ticket_write_t( void *p_ticket, size_t *tlen, uint32_t *lifetime ); -#if defined(MBEDTLS_SSL_EXPORT_KEYS) -/** - * \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_t( void *p_expkey, - const unsigned char *ms, - const unsigned char *kb, - size_t maclen, - size_t keylen, - size_t ivlen, - const unsigned char client_random[32], - const unsigned char server_random[32], - mbedtls_tls_prf_types tls_prf_type ); -#endif /* MBEDTLS_SSL_EXPORT_KEYS */ - /** * \brief Callback type: parse and load session ticket * @@ -2003,34 +2002,28 @@ void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf, #if defined(MBEDTLS_SSL_EXPORT_KEYS) /** - * \brief Configure key export callback. - * (Default: none.) + * \brief Configure a key export callback. + * (Default: none.) * - * \note See \c mbedtls_ssl_export_keys_t. + * This API can be used for two purposes: + * - Debugging: Use this API to e.g. generate an NSSKeylog + * file and use it to inspect encrypted traffic in tools + * such as Wireshark. + * - Application-specific export: Use this API to implement + * key exporters, e.g. for EAP-TLS or DTLS-SRTP. * - * \param conf SSL configuration context - * \param f_export_keys Callback for exporting keys - * \param p_export_keys Context for the callback + * + * \param conf The SSL configuration to which the export + * callback should be attached. All connections + * subsequently bound to this configuration will + * have their keys exported. + * \param f_export_keys The callback for the key export. + * \param p_export_keys The opaque context pointer to be passed to the + * callback \p f_export_keys. */ 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_t. - * \warning Exported key material must not be used for any purpose - * before the (D)TLS handshake is completed - * - * \param conf SSL configuration context - * \param f_export_keys Callback for exporting keys - * \param p_export_keys Context for the callback - */ -void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, - mbedtls_ssl_export_keys_t *f_export_keys, - void *p_export_keys ); + mbedtls_ssl_export_keys_t *f_export_keys, + void *p_export_keys ); #endif /* MBEDTLS_SSL_EXPORT_KEYS */ #if defined(MBEDTLS_SSL_ASYNC_PRIVATE) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 94f906afcb..4c69a0872b 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -989,12 +989,11 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform, if( ssl->conf->f_export_keys != NULL ) { ssl->conf->f_export_keys( ssl->conf->p_export_keys, - master, keyblk, - mac_key_len, keylen, - iv_copy_len, - randbytes + 32, - randbytes, - tls_prf_get_type( tls_prf ) ); + MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET, + master, 48, + randbytes + 32, + randbytes, + tls_prf_get_type( tls_prf ) ); } #endif @@ -4186,8 +4185,8 @@ void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf, #if defined(MBEDTLS_SSL_EXPORT_KEYS) void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, - mbedtls_ssl_export_keys_t *f_export_keys, - void *p_export_keys ) + mbedtls_ssl_export_keys_t *f_export_keys, + void *p_export_keys ) { conf->f_export_keys = f_export_keys; conf->p_export_keys = p_export_keys; From c4c38caca584098ffc98db4031d84ecd7a189fb2 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 24 May 2021 10:57:07 +0100 Subject: [PATCH 04/16] Adjust example programs to new key export API Signed-off-by: Hanno Becker --- programs/ssl/ssl_client2.c | 8 ++-- programs/ssl/ssl_server2.c | 8 ++-- programs/ssl/ssl_test_common_source.c | 67 ++++++++++++--------------- 3 files changed, 37 insertions(+), 46 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index bc5ed2e9ee..c25b9ee10a 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -1740,19 +1740,19 @@ int main( int argc, char *argv[] ) if( opt.eap_tls != 0 ) { mbedtls_ssl_conf_export_keys_cb( &conf, eap_tls_key_derivation, - &eap_tls_keying ); + &eap_tls_keying ); } else if( opt.nss_keylog != 0 ) { mbedtls_ssl_conf_export_keys_cb( &conf, - nss_keylog_export, - NULL ); + nss_keylog_export, + NULL ); } #if defined( MBEDTLS_SSL_DTLS_SRTP ) else if( opt.use_srtp != 0 ) { mbedtls_ssl_conf_export_keys_cb( &conf, dtls_srtp_key_derivation, - &dtls_srtp_keying ); + &dtls_srtp_keying ); } #endif /* MBEDTLS_SSL_DTLS_SRTP */ #endif /* MBEDTLS_SSL_EXPORT_KEYS */ diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 334eb7d445..9cecf7f3d8 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -2529,19 +2529,19 @@ int main( int argc, char *argv[] ) if( opt.eap_tls != 0 ) { mbedtls_ssl_conf_export_keys_cb( &conf, eap_tls_key_derivation, - &eap_tls_keying ); + &eap_tls_keying ); } else if( opt.nss_keylog != 0 ) { mbedtls_ssl_conf_export_keys_cb( &conf, - nss_keylog_export, - NULL ); + nss_keylog_export, + NULL ); } #if defined( MBEDTLS_SSL_DTLS_SRTP ) else if( opt.use_srtp != 0 ) { mbedtls_ssl_conf_export_keys_cb( &conf, dtls_srtp_key_derivation, - &dtls_srtp_keying ); + &dtls_srtp_keying ); } #endif /* MBEDTLS_SSL_DTLS_SRTP */ #endif /* MBEDTLS_SSL_EXPORT_KEYS */ diff --git a/programs/ssl/ssl_test_common_source.c b/programs/ssl/ssl_test_common_source.c index fa2c606975..6da0ba4a50 100644 --- a/programs/ssl/ssl_test_common_source.c +++ b/programs/ssl/ssl_test_common_source.c @@ -26,54 +26,48 @@ #if defined(MBEDTLS_SSL_EXPORT_KEYS) 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, + mbedtls_ssl_key_export_type secret_type, + const unsigned char *secret, + size_t secret_len, const unsigned char client_random[32], const 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 ) ); + /* We're only interested in the TLS 1.2 master secret */ + if( secret_type != MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET ) + return( 0 ); + if( secret_len != sizeof( keys->master_secret ) ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + memcpy( keys->master_secret, secret, 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 ); } int nss_keylog_export( void *p_expkey, - const unsigned char *ms, - const unsigned char *kb, - size_t maclen, - size_t keylen, - size_t ivlen, + mbedtls_ssl_key_export_type secret_type, + const unsigned char *secret, + size_t secret_len, const unsigned char client_random[32], const unsigned char server_random[32], mbedtls_tls_prf_types tls_prf_type ) { char nss_keylog_line[ 200 ]; size_t const client_random_len = 32; - size_t const master_secret_len = 48; size_t len = 0; size_t j; int ret = 0; + /* We're only interested in the TLS 1.2 master secret */ + if( secret_type != MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET ) + return( 0 ); + ((void) p_expkey); - ((void) kb); - ((void) maclen); - ((void) keylen); - ((void) ivlen); ((void) server_random); ((void) tls_prf_type); @@ -88,10 +82,10 @@ int nss_keylog_export( void *p_expkey, len += sprintf( nss_keylog_line + len, " " ); - for( j = 0; j < master_secret_len; j++ ) + for( j = 0; j < secret_len; j++ ) { len += sprintf( nss_keylog_line + len, - "%02x", ms[j] ); + "%02x", secret[j] ); } len += sprintf( nss_keylog_line + len, "\n" ); @@ -130,29 +124,26 @@ exit: #if defined( MBEDTLS_SSL_DTLS_SRTP ) int dtls_srtp_key_derivation( void *p_expkey, - const unsigned char *ms, - const unsigned char *kb, - size_t maclen, - size_t keylen, - size_t ivlen, + mbedtls_ssl_key_export_type secret_type, + const unsigned char *secret, + size_t secret_len, const unsigned char client_random[32], const unsigned char server_random[32], mbedtls_tls_prf_types tls_prf_type ) { dtls_srtp_keys *keys = (dtls_srtp_keys *)p_expkey; - ( ( void ) kb ); - memcpy( keys->master_secret, ms, sizeof( keys->master_secret ) ); + /* We're only interested in the TLS 1.2 master secret */ + if( secret_type != MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET ) + return( 0 ); + if( secret_len != sizeof( keys->master_secret ) ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + memcpy( keys->master_secret, secret, 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 /* MBEDTLS_SSL_DTLS_SRTP */ From d5c9cc7c90c91acb67693664aa0fc6a8728d55ce Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 24 May 2021 11:12:43 +0100 Subject: [PATCH 05/16] Add migration guide for modified key export API Signed-off-by: Hanno Becker --- docs/3.0-migration-guide.d/key-export.md | 28 ++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 docs/3.0-migration-guide.d/key-export.md diff --git a/docs/3.0-migration-guide.d/key-export.md b/docs/3.0-migration-guide.d/key-export.md new file mode 100644 index 0000000000..43781a2fb1 --- /dev/null +++ b/docs/3.0-migration-guide.d/key-export.md @@ -0,0 +1,28 @@ +SSL key export interface change +------------------------------- + +This affects users of the SSL key export APIs: +``` + mbedtls_ssl_conf_export_keys_cb() + mbedtls_ssl_conf_export_keys_ext_cb() +``` + +The API `mbedtls_ssl_conf_export_keys_ext_cb()` has been removed, +and the function type of key export callback passed to +`mbedtls_ssl_conf_export_keys_cb()` has changed, as follows: +- It no longer exports raw keys and IV. +- A secret type parameter has been added to identify which key + is being exported. For TLS 1.2, only the master secret is + exported, but upcoming TLS 1.3 support will add other kinds of keys. + +For users which do not rely on raw keys and IV, adjusting to the new +callback type should be straightforward - see the example programs +programs/ssl/ssl_client2 and programs/ssl/ssl_server2 for callbacks +for NSSKeylog, EAP-TLS and DTLS-SRTP. + +Users which require access to the raw keys used to secure application +traffic may derive those by hand based on the master secret and the +handshake transcript hashes which can be obtained from the raw data +on the wire. Such users are also encouraged to reach out to the +Mbed TLS team on the mailing list, to let the team know about their +use case. From 5a234e8718741a660aec8d9ec718b0f6e0434b2e Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 24 May 2021 11:15:29 +0100 Subject: [PATCH 06/16] Add ChangeLog entry Signed-off-by: Hanno Becker --- ChangeLog.d/key-export.txt | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 ChangeLog.d/key-export.txt diff --git a/ChangeLog.d/key-export.txt b/ChangeLog.d/key-export.txt new file mode 100644 index 0000000000..5882d231e4 --- /dev/null +++ b/ChangeLog.d/key-export.txt @@ -0,0 +1,8 @@ +API changes + * mbedtls_ssl_conf_export_keys_ext_cb() has been removed. + * The signature of key export callbacks configured via + mbedtls_ssl_conf_export_keys_cb() has changed, and raw + keys and IVs are no longer exported. Further, callbacks + now receive an additional parameter indicating the type + of secret that's being exported, paving the way for the + larger number of secrets in TLS 1.3. From 11a4c1abcd7a5da2341f2f4bb79d550874148d6f Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 26 May 2021 04:46:20 +0100 Subject: [PATCH 07/16] Adapt key export test in ssl-opt.sh to reduced output Signed-off-by: Hanno Becker --- tests/ssl-opt.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index d1221112ae..4210847dfa 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -8555,12 +8555,6 @@ 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 " \ -c "EAP-TLS key material is:"\ -s "EAP-TLS key material is:"\ -c "EAP-TLS IV is:" \ From ddc739cac41f4c03ac1e137d839dd186b7b59588 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 28 May 2021 05:10:38 +0100 Subject: [PATCH 08/16] Add missing documentation for key export callback parameters Signed-off-by: Hanno Becker --- include/mbedtls/ssl.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 38a4a64d36..bf8a9e2b43 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -988,8 +988,11 @@ typedef enum * session identification, and PRF for * implementation of TLS key exporters. * - * \param p_expkey Context for the callback. - * \param type The type of the key that is being exported. + * \param p_expkey Context for the callback. + * \param type The type of the key that is being exported. + * \param secret The address of the buffer holding the secret + * that's being exporterd. + * \param secret_len The length of \p secret in bytes. * \param client_random The client random bytes. * \param server_random The server random bytes. * \param tls_prf_type The identifier for the PRF used in the handshake From 22b34f75cdc371ee05ea4130c54c8906810d3790 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 28 May 2021 05:11:25 +0100 Subject: [PATCH 09/16] Remote key export identifier used for TLS < 1.2. Signed-off-by: Hanno Becker --- include/mbedtls/ssl.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index bf8a9e2b43..540f5527cd 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -961,7 +961,6 @@ struct mbedtls_ssl_session typedef enum { MBEDTLS_SSL_TLS_PRF_NONE, - MBEDTLS_SSL_TLS_PRF_TLS1, MBEDTLS_SSL_TLS_PRF_SHA384, MBEDTLS_SSL_TLS_PRF_SHA256, MBEDTLS_SSL_HKDF_EXPAND_SHA384, From a7991f2e11290a66e1d5a759dbb7b35b792580d6 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 28 May 2021 05:14:18 +0100 Subject: [PATCH 10/16] Remove all occurrences of TLS < 1.2 PRF identifier Signed-off-by: Hanno Becker --- tests/suites/test_suite_ssl.data | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index a497076c14..10f8f28bff 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -9278,14 +9278,6 @@ ssl_tls1_3_create_psk_binder:MBEDTLS_MD_SHA256:"4ecd0eb6ec3b4d87f5d6028f922ca4c5 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_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_SHA384_C:MBEDTLS_SSL_PROTO_TLS1_2 ssl_tls_prf:MBEDTLS_SSL_TLS_PRF_SHA384:"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"test tls_prf label":"a4206a36eef93f496611c2b7806625c3":0 @@ -9294,10 +9286,6 @@ 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_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-384 not enabled depends_on:!MBEDTLS_SHA384_C ssl_tls_prf:MBEDTLS_SSL_TLS_PRF_SHA384:"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef":"test tls_prf label":"a4206a36eef93f496611c2b7806625c3":MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE From 7e6c178b6dd200c0f36a603f9ab3fa4d4e83e709 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 8 Jun 2021 09:24:55 +0100 Subject: [PATCH 11/16] Make key export callback and context connection-specific Fixes #2188 Signed-off-by: Hanno Becker --- ChangeLog.d/key-export.txt | 13 +++++--- docs/3.0-migration-guide.d/key-export.md | 10 ++++-- include/mbedtls/ssl.h | 24 +++++++------- library/ssl_tls.c | 24 +++++++------- programs/ssl/ssl_client2.c | 42 ++++++++++++------------ programs/ssl/ssl_server2.c | 42 ++++++++++++------------ 6 files changed, 81 insertions(+), 74 deletions(-) diff --git a/ChangeLog.d/key-export.txt b/ChangeLog.d/key-export.txt index 5882d231e4..10d8c89913 100644 --- a/ChangeLog.d/key-export.txt +++ b/ChangeLog.d/key-export.txt @@ -1,8 +1,13 @@ API changes - * mbedtls_ssl_conf_export_keys_ext_cb() has been removed. + * mbedtls_ssl_conf_export_keys_ext_cb() and + mbedtls_ssl_conf_export_keys_cb() have been removed + and replaced by a new API + mbedtls_ssl_set_export_keys_cb(). * The signature of key export callbacks configured via - mbedtls_ssl_conf_export_keys_cb() has changed, and raw - keys and IVs are no longer exported. Further, callbacks + mbedtls_ssl_set_export_keys_cb() is different from that + of the previous mbedtls_ssl_conf_export_keys_cb(): First, + raw keys and IVs are no longer exported. Further, callbacks now receive an additional parameter indicating the type of secret that's being exported, paving the way for the - larger number of secrets in TLS 1.3. + larger number of secrets in TLS 1.3. Finally, the key export + callback and context are now connection-specific. diff --git a/docs/3.0-migration-guide.d/key-export.md b/docs/3.0-migration-guide.d/key-export.md index 43781a2fb1..967ecf87bf 100644 --- a/docs/3.0-migration-guide.d/key-export.md +++ b/docs/3.0-migration-guide.d/key-export.md @@ -7,9 +7,13 @@ This affects users of the SSL key export APIs: mbedtls_ssl_conf_export_keys_ext_cb() ``` -The API `mbedtls_ssl_conf_export_keys_ext_cb()` has been removed, -and the function type of key export callback passed to -`mbedtls_ssl_conf_export_keys_cb()` has changed, as follows: +Those APIs have been removed and replaced by the new API +`mbedtls_ssl_set_export_keys_cb()`. This API differs from +the previous key export API in the following ways: + +- It is no longer bound to an SSL configuration, but to an + SSL context. This allows users to more easily identify the + connection an exported key belongs to. - It no longer exports raw keys and IV. - A secret type parameter has been added to identify which key is being exported. For TLS 1.2, only the master secret is diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 540f5527cd..25800209e0 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1074,12 +1074,6 @@ struct mbedtls_ssl_config void *MBEDTLS_PRIVATE(p_ticket); /*!< context for the ticket callbacks */ #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ -#if defined(MBEDTLS_SSL_EXPORT_KEYS) - /** Callback to export key block and master secret */ - mbedtls_ssl_export_keys_t *MBEDTLS_PRIVATE(f_export_keys); - void *MBEDTLS_PRIVATE(p_export_keys); /*!< context for key export callback */ -#endif - #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) size_t MBEDTLS_PRIVATE(cid_len); /*!< The length of CIDs for incoming DTLS records. */ #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ @@ -1260,6 +1254,12 @@ struct mbedtls_ssl_context int MBEDTLS_PRIVATE(minor_ver); /*!< one of MBEDTLS_SSL_MINOR_VERSION_x macros */ unsigned MBEDTLS_PRIVATE(badmac_seen); /*!< records with a bad MAC received */ +#if defined(MBEDTLS_SSL_EXPORT_KEYS) + /** Callback to export key block and master secret */ + mbedtls_ssl_export_keys_t *MBEDTLS_PRIVATE(f_export_keys); + void *MBEDTLS_PRIVATE(p_export_keys); /*!< context for key export callback */ +#endif + #if defined(MBEDTLS_X509_CRT_PARSE_C) /** Callback to customize X.509 certificate chain verification */ int (*MBEDTLS_PRIVATE(f_vrfy))(void *, mbedtls_x509_crt *, int, uint32_t *); @@ -2015,17 +2015,15 @@ void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf, * key exporters, e.g. for EAP-TLS or DTLS-SRTP. * * - * \param conf The SSL configuration to which the export - * callback should be attached. All connections - * subsequently bound to this configuration will - * have their keys exported. + * \param ssl The SSL context to which the export + * callback should be attached. * \param f_export_keys The callback for the key export. * \param p_export_keys The opaque context pointer to be passed to the * callback \p f_export_keys. */ -void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, - mbedtls_ssl_export_keys_t *f_export_keys, - void *p_export_keys ); +void mbedtls_ssl_set_export_keys_cb( mbedtls_ssl_context *ssl, + mbedtls_ssl_export_keys_t *f_export_keys, + void *p_export_keys ); #endif /* MBEDTLS_SSL_EXPORT_KEYS */ #if defined(MBEDTLS_SSL_ASYNC_PRIVATE) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 4c69a0872b..9268ede285 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -986,14 +986,14 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform, ((void) mac_enc); #if defined(MBEDTLS_SSL_EXPORT_KEYS) - if( ssl->conf->f_export_keys != NULL ) + if( ssl->f_export_keys != NULL ) { - ssl->conf->f_export_keys( ssl->conf->p_export_keys, - MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET, - master, 48, - randbytes + 32, - randbytes, - tls_prf_get_type( tls_prf ) ); + ssl->f_export_keys( ssl->p_export_keys, + MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET, + master, 48, + randbytes + 32, + randbytes, + tls_prf_get_type( tls_prf ) ); } #endif @@ -4184,12 +4184,12 @@ void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf, #endif /* MBEDTLS_SSL_SESSION_TICKETS */ #if defined(MBEDTLS_SSL_EXPORT_KEYS) -void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, - mbedtls_ssl_export_keys_t *f_export_keys, - void *p_export_keys ) +void mbedtls_ssl_set_export_keys_cb( mbedtls_ssl_context *ssl, + mbedtls_ssl_export_keys_t *f_export_keys, + void *p_export_keys ) { - conf->f_export_keys = f_export_keys; - conf->p_export_keys = p_export_keys; + ssl->f_export_keys = f_export_keys; + ssl->p_export_keys = p_export_keys; } #endif diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index c25b9ee10a..a7b7ece4f4 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -1736,27 +1736,6 @@ 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_cb( &conf, eap_tls_key_derivation, - &eap_tls_keying ); - } - else if( opt.nss_keylog != 0 ) - { - mbedtls_ssl_conf_export_keys_cb( &conf, - nss_keylog_export, - NULL ); - } -#if defined( MBEDTLS_SSL_DTLS_SRTP ) - else if( opt.use_srtp != 0 ) - { - mbedtls_ssl_conf_export_keys_cb( &conf, dtls_srtp_key_derivation, - &dtls_srtp_keying ); - } -#endif /* MBEDTLS_SSL_DTLS_SRTP */ -#endif /* MBEDTLS_SSL_EXPORT_KEYS */ - #if defined(MBEDTLS_DHM_C) if( opt.dhmlen != DFL_DHMLEN ) mbedtls_ssl_conf_dhm_min_bitlen( &conf, opt.dhmlen ); @@ -1886,6 +1865,27 @@ int main( int argc, char *argv[] ) goto exit; } +#if defined(MBEDTLS_SSL_EXPORT_KEYS) + if( opt.eap_tls != 0 ) + { + mbedtls_ssl_set_export_keys_cb( &ssl, eap_tls_key_derivation, + &eap_tls_keying ); + } + else if( opt.nss_keylog != 0 ) + { + mbedtls_ssl_set_export_keys_cb( &ssl, + nss_keylog_export, + NULL ); + } +#if defined( MBEDTLS_SSL_DTLS_SRTP ) + else if( opt.use_srtp != 0 ) + { + mbedtls_ssl_set_export_keys_cb( &ssl, dtls_srtp_key_derivation, + &dtls_srtp_keying ); + } +#endif /* MBEDTLS_SSL_DTLS_SRTP */ +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ + #if defined(MBEDTLS_X509_CRT_PARSE_C) if( ( ret = mbedtls_ssl_set_hostname( &ssl, opt.server_name ) ) != 0 ) { diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 9cecf7f3d8..cb15866b04 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -2525,27 +2525,6 @@ 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_cb( &conf, eap_tls_key_derivation, - &eap_tls_keying ); - } - else if( opt.nss_keylog != 0 ) - { - mbedtls_ssl_conf_export_keys_cb( &conf, - nss_keylog_export, - NULL ); - } -#if defined( MBEDTLS_SSL_DTLS_SRTP ) - else if( opt.use_srtp != 0 ) - { - mbedtls_ssl_conf_export_keys_cb( &conf, dtls_srtp_key_derivation, - &dtls_srtp_keying ); - } -#endif /* MBEDTLS_SSL_DTLS_SRTP */ -#endif /* MBEDTLS_SSL_EXPORT_KEYS */ - #if defined(MBEDTLS_SSL_ALPN) if( opt.alpn_string != NULL ) if( ( ret = mbedtls_ssl_conf_alpn_protocols( &conf, alpn_list ) ) != 0 ) @@ -2872,6 +2851,27 @@ int main( int argc, char *argv[] ) goto exit; } +#if defined(MBEDTLS_SSL_EXPORT_KEYS) + if( opt.eap_tls != 0 ) + { + mbedtls_ssl_set_export_keys_cb( &ssl, eap_tls_key_derivation, + &eap_tls_keying ); + } + else if( opt.nss_keylog != 0 ) + { + mbedtls_ssl_set_export_keys_cb( &ssl, + nss_keylog_export, + NULL ); + } +#if defined( MBEDTLS_SSL_DTLS_SRTP ) + else if( opt.use_srtp != 0 ) + { + mbedtls_ssl_set_export_keys_cb( &ssl, dtls_srtp_key_derivation, + &dtls_srtp_keying ); + } +#endif /* MBEDTLS_SSL_DTLS_SRTP */ +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ + io_ctx.ssl = &ssl; io_ctx.net = &client_fd; mbedtls_ssl_set_bio( &ssl, &io_ctx, send_cb, recv_cb, From e0dad720ee3962264abba2867a0620a8de4babb9 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 11 Jun 2021 15:38:37 +0100 Subject: [PATCH 12/16] Remove return value from key export callback Signed-off-by: Hanno Becker --- include/mbedtls/ssl.h | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 25800209e0..a434912868 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -996,17 +996,14 @@ typedef enum * \param server_random The server random bytes. * \param tls_prf_type The identifier for the PRF used in the handshake * to which the key belongs. - * - * \return \c 0 if successful. - * \return A negative error code on failure. */ -typedef int mbedtls_ssl_export_keys_t( void *p_expkey, - mbedtls_ssl_key_export_type type, - const unsigned char *secret, - size_t secret_len, - const unsigned char client_random[32], - const unsigned char server_random[32], - mbedtls_tls_prf_types tls_prf_type ); +typedef void mbedtls_ssl_export_keys_t( void *p_expkey, + mbedtls_ssl_key_export_type type, + const unsigned char *secret, + size_t secret_len, + const unsigned char client_random[32], + const unsigned char server_random[32], + mbedtls_tls_prf_types tls_prf_type ); #endif /* MBEDTLS_SSL_EXPORT_KEYS */ /** From 1e1c23d768a83827d6a0e86d363fd87c1bebcb7f Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 11 Jun 2021 15:40:16 +0100 Subject: [PATCH 13/16] Improve ChangeLog wording for key export Signed-off-by: Hanno Becker --- ChangeLog.d/key-export.txt | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/ChangeLog.d/key-export.txt b/ChangeLog.d/key-export.txt index 10d8c89913..2fc01a4c52 100644 --- a/ChangeLog.d/key-export.txt +++ b/ChangeLog.d/key-export.txt @@ -1,13 +1,10 @@ API changes * mbedtls_ssl_conf_export_keys_ext_cb() and - mbedtls_ssl_conf_export_keys_cb() have been removed - and replaced by a new API - mbedtls_ssl_set_export_keys_cb(). - * The signature of key export callbacks configured via - mbedtls_ssl_set_export_keys_cb() is different from that - of the previous mbedtls_ssl_conf_export_keys_cb(): First, - raw keys and IVs are no longer exported. Further, callbacks - now receive an additional parameter indicating the type - of secret that's being exported, paving the way for the - larger number of secrets in TLS 1.3. Finally, the key export - callback and context are now connection-specific. + mbedtls_ssl_conf_export_keys_cb() have been removed and + replaced by a new API mbedtls_ssl_set_export_keys_cb(). + Raw keys and IVs are no longer passed to the callback. + Further, callbacks now receive an additional parameter + indicating the type of secret that's being exported, + paving the way for the larger number of secrets + in TLS 1.3. Finally, the key export callback and + context are now connection-specific. From d8f32e72b4ef90ab09e2b647932b182ac1a6ea53 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Thu, 17 Jun 2021 05:14:58 +0100 Subject: [PATCH 14/16] Move export callback and context to the end of SSL context This saves some code when compiling for Thumb, where access to fields with offset index > 127 requires intermediate address computations. Frequently used fields should therefore be located at the top of the structure, while less frequently used ones -- such as the export callback -- can be moved to the back. Signed-off-by: Hanno Becker --- include/mbedtls/ssl.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index a434912868..512f0ccfd6 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1251,12 +1251,6 @@ struct mbedtls_ssl_context int MBEDTLS_PRIVATE(minor_ver); /*!< one of MBEDTLS_SSL_MINOR_VERSION_x macros */ unsigned MBEDTLS_PRIVATE(badmac_seen); /*!< records with a bad MAC received */ -#if defined(MBEDTLS_SSL_EXPORT_KEYS) - /** Callback to export key block and master secret */ - mbedtls_ssl_export_keys_t *MBEDTLS_PRIVATE(f_export_keys); - void *MBEDTLS_PRIVATE(p_export_keys); /*!< context for key export callback */ -#endif - #if defined(MBEDTLS_X509_CRT_PARSE_C) /** Callback to customize X.509 certificate chain verification */ int (*MBEDTLS_PRIVATE(f_vrfy))(void *, mbedtls_x509_crt *, int, uint32_t *); @@ -1427,6 +1421,12 @@ struct mbedtls_ssl_context * Possible values are #MBEDTLS_SSL_CID_ENABLED * and #MBEDTLS_SSL_CID_DISABLED. */ #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + +#if defined(MBEDTLS_SSL_EXPORT_KEYS) + /** Callback to export key block and master secret */ + mbedtls_ssl_export_keys_t *MBEDTLS_PRIVATE(f_export_keys); + void *MBEDTLS_PRIVATE(p_export_keys); /*!< context for key export callback */ +#endif }; /** From 296fefeb981f8c95d580abfb46d52e1838a082eb Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 21 Jun 2021 09:32:27 +0100 Subject: [PATCH 15/16] Fix return type of example key export callbacks Signed-off-by: Hanno Becker --- programs/ssl/ssl_test_common_source.c | 60 ++++++++++++--------------- 1 file changed, 26 insertions(+), 34 deletions(-) diff --git a/programs/ssl/ssl_test_common_source.c b/programs/ssl/ssl_test_common_source.c index 6da0ba4a50..d30c36ea56 100644 --- a/programs/ssl/ssl_test_common_source.c +++ b/programs/ssl/ssl_test_common_source.c @@ -25,47 +25,44 @@ */ #if defined(MBEDTLS_SSL_EXPORT_KEYS) -int eap_tls_key_derivation( void *p_expkey, - mbedtls_ssl_key_export_type secret_type, - const unsigned char *secret, - size_t secret_len, - const unsigned char client_random[32], - const unsigned char server_random[32], - mbedtls_tls_prf_types tls_prf_type ) +void eap_tls_key_derivation( void *p_expkey, + mbedtls_ssl_key_export_type secret_type, + const unsigned char *secret, + size_t secret_len, + const unsigned char client_random[32], + const unsigned char server_random[32], + mbedtls_tls_prf_types tls_prf_type ) { eap_tls_keys *keys = (eap_tls_keys *)p_expkey; /* We're only interested in the TLS 1.2 master secret */ if( secret_type != MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET ) - return( 0 ); + return; if( secret_len != sizeof( keys->master_secret ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + return; memcpy( keys->master_secret, secret, sizeof( keys->master_secret ) ); memcpy( keys->randbytes, client_random, 32 ); memcpy( keys->randbytes + 32, server_random, 32 ); keys->tls_prf_type = tls_prf_type; - - return( 0 ); } -int nss_keylog_export( void *p_expkey, - mbedtls_ssl_key_export_type secret_type, - const unsigned char *secret, - size_t secret_len, - const unsigned char client_random[32], - const unsigned char server_random[32], - mbedtls_tls_prf_types tls_prf_type ) +void nss_keylog_export( void *p_expkey, + mbedtls_ssl_key_export_type secret_type, + const unsigned char *secret, + size_t secret_len, + const unsigned char client_random[32], + const unsigned char server_random[32], + mbedtls_tls_prf_types tls_prf_type ) { char nss_keylog_line[ 200 ]; size_t const client_random_len = 32; size_t len = 0; size_t j; - int ret = 0; /* We're only interested in the TLS 1.2 master secret */ if( secret_type != MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET ) - return( 0 ); + return; ((void) p_expkey); ((void) server_random); @@ -102,13 +99,11 @@ int nss_keylog_export( void *p_expkey, if( ( f = fopen( opt.nss_keylog_file, "a" ) ) == NULL ) { - ret = -1; goto exit; } if( fwrite( nss_keylog_line, 1, len, f ) != len ) { - ret = -1; fclose( f ); goto exit; } @@ -119,32 +114,29 @@ int nss_keylog_export( void *p_expkey, exit: mbedtls_platform_zeroize( nss_keylog_line, sizeof( nss_keylog_line ) ); - return( ret ); } #if defined( MBEDTLS_SSL_DTLS_SRTP ) -int dtls_srtp_key_derivation( void *p_expkey, - mbedtls_ssl_key_export_type secret_type, - const unsigned char *secret, - size_t secret_len, - const unsigned char client_random[32], - const unsigned char server_random[32], - mbedtls_tls_prf_types tls_prf_type ) +void dtls_srtp_key_derivation( void *p_expkey, + mbedtls_ssl_key_export_type secret_type, + const unsigned char *secret, + size_t secret_len, + const unsigned char client_random[32], + const unsigned char server_random[32], + mbedtls_tls_prf_types tls_prf_type ) { dtls_srtp_keys *keys = (dtls_srtp_keys *)p_expkey; /* We're only interested in the TLS 1.2 master secret */ if( secret_type != MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET ) - return( 0 ); + return; if( secret_len != sizeof( keys->master_secret ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + return; memcpy( keys->master_secret, secret, sizeof( keys->master_secret ) ); memcpy( keys->randbytes, client_random, 32 ); memcpy( keys->randbytes + 32, server_random, 32 ); keys->tls_prf_type = tls_prf_type; - - return( 0 ); } #endif /* MBEDTLS_SSL_DTLS_SRTP */ From 5ec50039927601005534460385bbe9206dcf7ad0 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 22 Jun 2021 13:41:56 +0100 Subject: [PATCH 16/16] Document the return type change in the migration guide Signed-off-by: Dave Rodgman --- docs/3.0-migration-guide.d/key-export.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/3.0-migration-guide.d/key-export.md b/docs/3.0-migration-guide.d/key-export.md index 967ecf87bf..f8b3505b51 100644 --- a/docs/3.0-migration-guide.d/key-export.md +++ b/docs/3.0-migration-guide.d/key-export.md @@ -18,6 +18,10 @@ the previous key export API in the following ways: - A secret type parameter has been added to identify which key is being exported. For TLS 1.2, only the master secret is exported, but upcoming TLS 1.3 support will add other kinds of keys. +- The callback now specifies a void return type, rather than + returning an error code. It is the responsibility of the application + to handle failures in the key export callback, for example by + shutting down the TLS connection. For users which do not rely on raw keys and IV, adjusting to the new callback type should be straightforward - see the example programs