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>
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index 45feb5e..76be297 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -1764,6 +1764,21 @@
#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
*
* Enable support for TLS renegotiation.
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 3da4eca..ae5eb8d 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -729,6 +729,14 @@
/* Length in number of bytes of the TLS sequence number */
#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
extern "C" {
#endif
@@ -5786,7 +5794,7 @@
*
* \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,
uint8_t *out, const size_t key_len,
const char *label, const size_t label_len,
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 2925495..0fe2800 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -1166,10 +1166,11 @@
unsigned char out_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX];
#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
- * Master Secret and other session info,
- * see ssl_tls12_populate_transform() */
+ * Master Secret and other session info and for the keying material
+ * exporter in TLS 1.2.
+ * See ssl_tls12_populate_transform() */
unsigned char randbytes[MBEDTLS_SERVER_HELLO_RANDOM_LEN +
MBEDTLS_CLIENT_HELLO_RANDOM_LEN];
/*!< ServerHello.random+ClientHello.random */
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 971821a..d631420 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -8669,7 +8669,7 @@
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */
transform->tls_version = tls_version;
-#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+#if defined(MBEDTLS_SSL_KEEP_RANDBYTES)
memcpy(transform->randbytes, randbytes, sizeof(transform->randbytes));
#endif
@@ -10054,8 +10054,7 @@
}
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
-
-#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) || !defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT)
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
static int mbedtls_ssl_tls12_export_keying_material(const mbedtls_ssl_context *ssl,
@@ -10176,6 +10175,6 @@
}
}
-#endif /* defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) || !defined(MBEDTLS_SSL_PROTO_TLS1_2) */
+#endif /* defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) */
#endif /* MBEDTLS_SSL_TLS_C */
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 8f7ae04..228e7f8 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -347,11 +347,7 @@
" in the form of base64 code (serialize option\n" \
" must be set)\n" \
" default: \"\" (do nothing)\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"
+ " option: a file path\n"
#else
#define USAGE_SERIALIZATION ""
#endif
@@ -381,6 +377,16 @@
#define USAGE_TLS1_3_KEY_EXCHANGE_MODES ""
#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
* length limit: 4095 bytes in C99. */
#define USAGE1 \
@@ -471,6 +477,7 @@
" otherwise. The expansion of the macro\n" \
" is printed if it is defined\n" \
USAGE_SERIALIZATION \
+ USAGE_EXPORT \
"\n"
/*
@@ -2574,7 +2581,7 @@
}
#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) {
unsigned char *exported_key = calloc((size_t) opt.exp_len, sizeof(unsigned int));
if (exported_key == NULL) {
@@ -2597,7 +2604,7 @@
mbedtls_printf("\n\n");
fflush(stdout);
}
-#endif /* defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) */
+#endif /* defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) */
/*
* 6. Write the GET request
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 538d0d0..2b81fc1 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -473,13 +473,19 @@
" in the form of base64 code (serialize option\n" \
" must be set)\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" \
" 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_SERIALIZATION ""
+#define USAGE_EXPORT ""
#endif
#define USAGE_KEY_OPAQUE_ALGS \
@@ -589,6 +595,7 @@
" otherwise. The expansion of the macro\n" \
" is printed if it is defined\n" \
USAGE_SERIALIZATION \
+ USAGE_EXPORT \
"\n"
#define PUT_UINT64_BE(out_be, in_le, i) \
@@ -3656,7 +3663,7 @@
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) {
unsigned char *exported_key = calloc((size_t) opt.exp_len, sizeof(unsigned int));
if (exported_key == NULL) {
@@ -3679,7 +3686,7 @@
mbedtls_printf("\n\n");
fflush(stdout);
}
-#endif /* defined(MBEDTLS_SSL_CONTEXT_SERIALZIATION) */
+#endif /* defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) */
#if defined(MBEDTLS_SSL_DTLS_SRTP)
else if (opt.use_srtp != 0) {