1
0
mirror of https://github.com/Mbed-TLS/mbedtls.git synced 2025-07-30 22:43:08 +03:00

Create MBEDTLS_SSL_KEYING_MATERIAL_EXPORT option

Add the option MBEDTLS_SSL_KEYING_MATERIAL_EXPORT to mbedtls_config.h
to control if the function mbedtls_ssl_export_keying_material() should
be available. By default, the option is disabled.

This is because the exporter for TLS 1.2 requires client_random and
server_random need to be stored after the handshake is complete.

Signed-off-by: Max Fillinger <max@max-fillinger.net>
This commit is contained in:
Max Fillinger
2024-10-25 00:52:24 +02:00
committed by Max Fillinger
parent 7b52328f6c
commit 951b886801
6 changed files with 56 additions and 19 deletions

View File

@ -1763,6 +1763,21 @@
*/ */
#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE #define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
/**
/*
* \def MBEDTLS_SSL_KEYING_MATERIAL_EXPORT
*
* When this option is enabled, the client and server can extract additional
* shared symmetric keys after an SSL handshake using the function
* mbedtls_ssl_export_keying_material().
*
* The process for deriving the keys is specified in RFC 5705 for TLS 1.2 and
* in RFC 8446, Section 7.5, for TLS 1.3.
*
* Uncomment this macro to enable mbedtls_ssl_export_keying_material().
*/
//#define MBEDTLS_SSL_KEYING_MATERIAL_EXPORT
/** /**
* \def MBEDTLS_SSL_RENEGOTIATION * \def MBEDTLS_SSL_RENEGOTIATION
* *

View File

@ -729,6 +729,14 @@ union mbedtls_ssl_premaster_secret {
/* Length in number of bytes of the TLS sequence number */ /* Length in number of bytes of the TLS sequence number */
#define MBEDTLS_SSL_SEQUENCE_NUMBER_LEN 8 #define MBEDTLS_SSL_SEQUENCE_NUMBER_LEN 8
/* Helper to state that client_random and server_random need to be stored
* after the handshake is complete. This is required for context serialization
* and for the keying material exporter in TLS 1.2. */
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) || \
(defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) && defined(MBEDTLS_SSL_PROTO_TLS1_2))
#define MBEDTLS_SSL_KEEP_RANDBYTES
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -5786,7 +5794,7 @@ int mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf,
* *
* \return 0 on success. An SSL specific error on failure. * \return 0 on success. An SSL specific error on failure.
*/ */
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) || !defined(MBEDTLS_SSL_PROTO_TLS1_2) #if defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT)
int mbedtls_ssl_export_keying_material(mbedtls_ssl_context *ssl, int mbedtls_ssl_export_keying_material(mbedtls_ssl_context *ssl,
uint8_t *out, const size_t key_len, uint8_t *out, const size_t key_len,
const char *label, const size_t label_len, const char *label, const size_t label_len,

View File

@ -1166,10 +1166,11 @@ struct mbedtls_ssl_transform {
unsigned char out_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX]; unsigned char out_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX];
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) #if defined(MBEDTLS_SSL_KEEP_RANDBYTES)
/* We need the Hello random bytes in order to re-derive keys from the /* We need the Hello random bytes in order to re-derive keys from the
* Master Secret and other session info, * Master Secret and other session info and for the keying material
* see ssl_tls12_populate_transform() */ * exporter in TLS 1.2.
* See ssl_tls12_populate_transform() */
unsigned char randbytes[MBEDTLS_SERVER_HELLO_RANDOM_LEN + unsigned char randbytes[MBEDTLS_SERVER_HELLO_RANDOM_LEN +
MBEDTLS_CLIENT_HELLO_RANDOM_LEN]; MBEDTLS_CLIENT_HELLO_RANDOM_LEN];
/*!< ServerHello.random+ClientHello.random */ /*!< ServerHello.random+ClientHello.random */

View File

@ -8669,7 +8669,7 @@ static int ssl_tls12_populate_transform(mbedtls_ssl_transform *transform,
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */ #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */
transform->tls_version = tls_version; transform->tls_version = tls_version;
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) #if defined(MBEDTLS_SSL_KEEP_RANDBYTES)
memcpy(transform->randbytes, randbytes, sizeof(transform->randbytes)); memcpy(transform->randbytes, randbytes, sizeof(transform->randbytes));
#endif #endif
@ -10054,8 +10054,7 @@ int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl,
} }
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT)
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) || !defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
static int mbedtls_ssl_tls12_export_keying_material(const mbedtls_ssl_context *ssl, static int mbedtls_ssl_tls12_export_keying_material(const mbedtls_ssl_context *ssl,
@ -10176,6 +10175,6 @@ int mbedtls_ssl_export_keying_material(mbedtls_ssl_context *ssl,
} }
} }
#endif /* defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) || !defined(MBEDTLS_SSL_PROTO_TLS1_2) */ #endif /* defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) */
#endif /* MBEDTLS_SSL_TLS_C */ #endif /* MBEDTLS_SSL_TLS_C */

View File

@ -347,11 +347,7 @@ int main(void)
" in the form of base64 code (serialize option\n" \ " in the form of base64 code (serialize option\n" \
" must be set)\n" \ " must be set)\n" \
" default: \"\" (do nothing)\n" \ " default: \"\" (do nothing)\n" \
" option: a file path\n" \ " option: a file path\n"
" exp_label=%%s Label to input into TLS-Exporter\n" \
" default: None (don't try to export a key)\n" \
" exp_len=%%d Length of key to extract from TLS-Exporter \n" \
" default: 20\n"
#else #else
#define USAGE_SERIALIZATION "" #define USAGE_SERIALIZATION ""
#endif #endif
@ -381,6 +377,16 @@ int main(void)
#define USAGE_TLS1_3_KEY_EXCHANGE_MODES "" #define USAGE_TLS1_3_KEY_EXCHANGE_MODES ""
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
#if defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT)
#define USAGE_EXPORT \
" exp_label=%%s Label to input into TLS-Exporter\n" \
" default: None (don't try to export a key)\n" \
" exp_len=%%d Length of key to extract from TLS-Exporter \n" \
" default: 20\n"
#else
#define USAGE_EXPORT ""
#endif /* defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) */
/* USAGE is arbitrarily split to stay under the portable string literal /* USAGE is arbitrarily split to stay under the portable string literal
* length limit: 4095 bytes in C99. */ * length limit: 4095 bytes in C99. */
#define USAGE1 \ #define USAGE1 \
@ -471,6 +477,7 @@ int main(void)
" otherwise. The expansion of the macro\n" \ " otherwise. The expansion of the macro\n" \
" is printed if it is defined\n" \ " is printed if it is defined\n" \
USAGE_SERIALIZATION \ USAGE_SERIALIZATION \
USAGE_EXPORT \
"\n" "\n"
/* /*
@ -2574,7 +2581,7 @@ usage:
} }
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) #if defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT)
if (opt.exp_label != NULL && opt.exp_len > 0) { if (opt.exp_label != NULL && opt.exp_len > 0) {
unsigned char *exported_key = calloc((size_t) opt.exp_len, sizeof(unsigned int)); unsigned char *exported_key = calloc((size_t) opt.exp_len, sizeof(unsigned int));
if (exported_key == NULL) { if (exported_key == NULL) {
@ -2597,7 +2604,7 @@ usage:
mbedtls_printf("\n\n"); mbedtls_printf("\n\n");
fflush(stdout); fflush(stdout);
} }
#endif /* defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) */ #endif /* defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) */
/* /*
* 6. Write the GET request * 6. Write the GET request

View File

@ -473,13 +473,19 @@ int main(void)
" in the form of base64 code (serialize option\n" \ " in the form of base64 code (serialize option\n" \
" must be set)\n" \ " must be set)\n" \
" default: \"\" (do nothing)\n" \ " default: \"\" (do nothing)\n" \
" option: a file path\n" \ " option: a file path\n"
#else
#define USAGE_SERIALIZATION ""
#endif
#if defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT)
#define USAGE_EXPORT \
" exp_label=%%s Label to input into TLS-Exporter\n" \ " exp_label=%%s Label to input into TLS-Exporter\n" \
" default: None (don't try to export a key)\n" \ " default: None (don't try to export a key)\n" \
" exp_len=%%d Length of key to extract from TLS-Exporter \n" \ " exp_len=%%d Length of key to extract from TLS-Exporter \n" \
" default: 20\n" " default: 20\n"
#else #else
#define USAGE_SERIALIZATION "" #define USAGE_EXPORT ""
#endif #endif
#define USAGE_KEY_OPAQUE_ALGS \ #define USAGE_KEY_OPAQUE_ALGS \
@ -589,6 +595,7 @@ int main(void)
" otherwise. The expansion of the macro\n" \ " otherwise. The expansion of the macro\n" \
" is printed if it is defined\n" \ " is printed if it is defined\n" \
USAGE_SERIALIZATION \ USAGE_SERIALIZATION \
USAGE_EXPORT \
"\n" "\n"
#define PUT_UINT64_BE(out_be, in_le, i) \ #define PUT_UINT64_BE(out_be, in_le, i) \
@ -3656,7 +3663,7 @@ handshake:
mbedtls_printf("\n"); mbedtls_printf("\n");
} }
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) #if defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT)
if (opt.exp_label != NULL && opt.exp_len > 0) { if (opt.exp_label != NULL && opt.exp_len > 0) {
unsigned char *exported_key = calloc((size_t) opt.exp_len, sizeof(unsigned int)); unsigned char *exported_key = calloc((size_t) opt.exp_len, sizeof(unsigned int));
if (exported_key == NULL) { if (exported_key == NULL) {
@ -3679,7 +3686,7 @@ handshake:
mbedtls_printf("\n\n"); mbedtls_printf("\n\n");
fflush(stdout); fflush(stdout);
} }
#endif /* defined(MBEDTLS_SSL_CONTEXT_SERIALZIATION) */ #endif /* defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) */
#if defined(MBEDTLS_SSL_DTLS_SRTP) #if defined(MBEDTLS_SSL_DTLS_SRTP)
else if (opt.use_srtp != 0) { else if (opt.use_srtp != 0) {