diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 11435df8d..58342798a 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1178,6 +1178,16 @@ */ #define MBEDTLS_SSL_SESSION_TICKETS +/** + * \def MBEDTLS_SSL_EXPORT_KEYS + * + * Enable support for exporting key block and master key. + * This is required for certain users of TLS, e.g. EAP-TLS. + * + * Comment this macro to disable support for key export + */ +#define MBEDTLS_SSL_EXPORT_KEYS + /** * \def MBEDTLS_SSL_SERVER_NAME_INDICATION * diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 3d73da975..1a9f1a9cd 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -544,6 +544,13 @@ struct mbedtls_ssl_config void *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 key */ + int (*f_export_keys)( void *, const unsigned char *, + const unsigned char *, size_t, size_t, size_t ); + void *p_export_keys; /*!< context for key export callback */ +#endif + #if defined(MBEDTLS_X509_CRT_PARSE_C) const mbedtls_x509_crt_profile *cert_profile; /*!< verification profile */ mbedtls_ssl_key_cert *key_cert; /*!< own certificate/key pair(s) */ @@ -1071,6 +1078,34 @@ 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 and master key + * + * \note This is required for certain uses of TLS, e.g. EAP-TLS + * (RFC 5216). The key pointers are ephemeral and therefore + * must not be stored. The keys should not be copied + * verbatim and should be used specifically for key + * derivation purposes + * + * \param p_expkey Context for the callback + * \param kb Pointer to key block + * \param mk Pointer to master key + * \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 *kb, + const unsigned char *mk, + size_t maclen, + size_t keylen, + size_t ivlen ); +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ + /** * \brief Callback type: parse and load session ticket * @@ -1120,6 +1155,26 @@ void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf, void *p_ticket ); #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ +#if defined(MBEDTLS_SSL_EXPORT_KEYS) +/** + * \brief Configure key export callback. + * (Default: none.) + * + * \note This is required for certain uses of TLS, e.g. EAP-TLS + * (RFC 5216). The key pointers are ephemeral and therefore + * must not be stored. The keys should not be copied + * verbatim and should be used specifically for key + * derivation purposes + * + * \param conf SSL configuration context + * \param f_export_keys Callback for exporting keys + * \param p_export_key Context shared by 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 ); +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ + /** * \brief Callback type: generate a cookie * diff --git a/library/ssl_tls.c b/library/ssl_tls.c index c1bccbecc..a42fcc528 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -862,6 +862,16 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ +#if defined(MBEDTLS_SSL_EXPORT_KEYS) + if( ssl->conf->f_export_keys != NULL) + { + ssl->conf->f_export_keys( ssl->conf->p_export_keys, + keyblk, session->master, + transform->maclen, transform->keylen, + iv_copy_len ); + } +#endif + if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc, cipher_info ) ) != 0 ) { @@ -5807,6 +5817,16 @@ void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf, #endif #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; +} +#endif + /* * SSL get accessors */