diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h index 2dc475b9f7..ca1486dbdf 100644 --- a/include/mbedtls/mbedtls_config.h +++ b/include/mbedtls/mbedtls_config.h @@ -737,6 +737,20 @@ */ //#define MBEDTLS_SSL_RECORD_SIZE_LIMIT +/* + * \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 * diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 9ded4e6d22..8383ead054 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -676,6 +676,14 @@ union mbedtls_ssl_premaster_secret { /* 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 @@ -5407,7 +5415,7 @@ int mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf, * * \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 e51a3df5ed..596e7bc833 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -1118,10 +1118,11 @@ struct mbedtls_ssl_transform { 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 e4450b681d..c20a68d2e0 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -7746,7 +7746,7 @@ static int ssl_tls12_populate_transform(mbedtls_ssl_transform *transform, #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 @@ -8930,8 +8930,7 @@ int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl, } #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, @@ -9052,6 +9051,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 */ diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 9e38f690af..061096bdf0 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -336,11 +336,7 @@ int main(void) " 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 @@ -370,6 +366,16 @@ int main(void) #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 \ @@ -456,6 +462,7 @@ int main(void) " otherwise. The expansion of the macro\n" \ " is printed if it is defined\n" \ USAGE_SERIALIZATION \ + USAGE_EXPORT \ "\n" /* @@ -2499,7 +2506,7 @@ usage: } #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) { @@ -2522,7 +2529,7 @@ usage: 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 9eab6cddb1..5186006886 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -471,13 +471,19 @@ int main(void) " 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 \ @@ -587,6 +593,7 @@ int main(void) " 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) \ @@ -3619,7 +3626,7 @@ handshake: 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) { @@ -3642,7 +3649,7 @@ handshake: 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) {