From 44042f0a57aafd3e9d2fd80354114eb66c5dae97 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Mon, 22 Jul 2024 14:43:56 +0200 Subject: [PATCH 01/57] Implement TLS-Exporter feature The TLS-Exporter is a function to derive shared symmetric keys for the server and client from the secrets generated during the handshake. It is defined in RFC 8446, Section 7.5 for TLS 1.3 and in RFC 5705 for TLS 1.2. Signed-off-by: Max Fillinger --- include/mbedtls/ssl.h | 24 ++++++++++ library/ssl_tls.c | 95 ++++++++++++++++++++++++++++++++++++++++ library/ssl_tls13_keys.c | 34 ++++++++++++++ library/ssl_tls13_keys.h | 16 +++++++ 4 files changed, 169 insertions(+) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index f9b103e382..f1c8bd293b 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -5767,6 +5767,30 @@ int mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf, const unsigned char *random, size_t rlen, unsigned char *dstbuf, size_t dlen); + /** + * \brief TLS-Exporter to derive shared symmetric keys between server and client. + * + * \param ctx SSL context from which to export keys. Must have finished the handshake. + * \param out Output buffer of length at least key_len bytes. + * \param key_len Length of the key to generate in bytes. Must be < 2^16 in TLS 1.3. + * \param label Label for which to generate the key of length label_len. + * \param label_len Length of label in bytes. Must be < 251 in TLS 1.3. + * \param context Context of the key. Can be NULL if context_len or use_context is 0. + * \param context_len Length of context. Must be < 2^16 in TLS1.2. + * \param use_context Indicates if a context should be used in deriving the key. + * + * \note TLS 1.2 makes a distinction between a 0-length context and no context. + * This is why the use_context argument exists. TLS 1.3 does not make + * this distinction. If use_context is 0 and TLS 1.3 is used, context and + * context_len are ignored and a 0-length context is used. + * + * \return 0 on success. An SSL specific error on failure. + */ + int mbedtls_ssl_export_keying_material(mbedtls_ssl_context *ssl, + uint8_t *out, size_t key_len, + const char *label, size_t label_len, + const unsigned char *context, size_t context_len, + int use_context); #ifdef __cplusplus } #endif diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 8d451778d9..3c1c5cf588 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -19,6 +19,7 @@ #include "ssl_client.h" #include "ssl_debug_helpers.h" #include "ssl_misc.h" +#include "ssl_tls13_keys.h" #include "debug_internal.h" #include "mbedtls/error.h" @@ -10053,4 +10054,98 @@ int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ +static int mbedtls_ssl_tls12_export_keying_material(const mbedtls_ssl_context *ssl, + const mbedtls_md_type_t hash_alg, + uint8_t *out, const size_t key_len, + const char *label, const size_t label_len, + const unsigned char *context, const size_t context_len, + const int use_context) +{ + int ret = 0; + size_t prf_input_len = use_context ? 64 + 2 + context_len : 64; + unsigned char *prf_input = NULL; + char *label_str = NULL; + + if (use_context && context_len >= (1 << 16)) { + ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + goto exit; + } + + prf_input = mbedtls_calloc(prf_input_len, sizeof(unsigned char)); + label_str = mbedtls_calloc(label_len + 1, sizeof(char)); + if (prf_input == NULL || label_str == NULL) { + ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; + goto exit; + } + + memcpy(label_str, label, label_len); + label_str[label_len] = '\0'; + + /* The input to the PRF is client_random, then server_random. + * If a context is provided, this is then followed by the context length + * as a 16-bit big-endian integer, and then the context itself. */ + memcpy(prf_input, ssl->transform->randbytes + 32, 32); + memcpy(prf_input + 32, ssl->transform->randbytes, 32); + if (use_context) { + prf_input[64] = (unsigned char)((context_len >> 8) & 0xff); + prf_input[65] = (unsigned char)(context_len & 0xff); + memcpy(prf_input + 66, context, context_len); + } + ret = tls_prf_generic(hash_alg, ssl->session->master, 48, label_str, + prf_input, prf_input_len, + out, key_len); + +exit: + mbedtls_free(prf_input); + mbedtls_free(label_str); + return ret; +} + +static int mbedtls_ssl_tls13_export_keying_material(mbedtls_ssl_context *ssl, + const mbedtls_md_type_t hash_alg, + uint8_t *out, const size_t key_len, + const char *label, const size_t label_len, + const unsigned char *context, const size_t context_len) +{ + const psa_algorithm_t psa_hash_alg = mbedtls_md_psa_alg_from_type(hash_alg); + const size_t hash_len = PSA_HASH_LENGTH(hash_alg); + const unsigned char *secret = ssl->session->app_secrets.exporter_master_secret; + + if (key_len > 0xff || label_len > 250) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + return mbedtls_ssl_tls13_exporter(psa_hash_alg, secret, hash_len, + (const unsigned char *)label, label_len, + context, context_len, out, key_len); +} + +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, + const unsigned char *context, const size_t context_len, + const int use_context) +{ + if (!mbedtls_ssl_is_handshake_over(ssl)) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + int ciphersuite_id = mbedtls_ssl_get_ciphersuite_id_from_ssl(ssl); + const mbedtls_ssl_ciphersuite_t *ciphersuite = mbedtls_ssl_ciphersuite_from_id(ciphersuite_id); + const mbedtls_md_type_t hash_alg = ciphersuite->mac; + + switch (mbedtls_ssl_get_version_number(ssl)) { + case MBEDTLS_SSL_VERSION_TLS1_2: + return mbedtls_ssl_tls12_export_keying_material(ssl, hash_alg, out, key_len, + label, label_len, + context, context_len, use_context); + case MBEDTLS_SSL_VERSION_TLS1_3: + return mbedtls_ssl_tls13_export_keying_material(ssl, hash_alg, out, key_len, label, label_len, + use_context ? context : NULL, + use_context ? context_len : 0); + default: + return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION; + } +} + #endif /* MBEDTLS_SSL_TLS_C */ diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c index 739414ea2f..bbaa7c47fe 100644 --- a/library/ssl_tls13_keys.c +++ b/library/ssl_tls13_keys.c @@ -1882,4 +1882,38 @@ int mbedtls_ssl_tls13_export_handshake_psk(mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */ +int mbedtls_ssl_tls13_exporter(const psa_algorithm_t hash_alg, + const unsigned char *secret, const size_t secret_len, + const unsigned char *label, const size_t label_len, + const unsigned char *context_value, const size_t context_len, + unsigned char *out, const size_t out_len) +{ + size_t hash_len = PSA_HASH_LENGTH(hash_alg); + unsigned char hkdf_secret[MBEDTLS_TLS1_3_MD_MAX_SIZE]; + unsigned char hashed_context[PSA_HASH_MAX_SIZE]; + size_t hashed_context_len = 0; + int ret = 0; + psa_status_t status = 0; + + ret = mbedtls_ssl_tls13_derive_secret(hash_alg, secret, secret_len, label, label_len, NULL, 0, + MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, hkdf_secret, hash_len); + if (ret != 0) { + goto exit; + } + + status = psa_hash_compute(hash_alg, context_value, context_len, hashed_context, hash_len, &hashed_context_len); + if (status != PSA_SUCCESS) { + ret = PSA_TO_MBEDTLS_ERR(status); + goto exit; + } + ret = mbedtls_ssl_tls13_hkdf_expand_label(hash_alg, hkdf_secret, hash_len, + MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(exporter), + hashed_context, hashed_context_len, + out, out_len); + +exit: + mbedtls_platform_zeroize(hkdf_secret, sizeof(hkdf_secret)); + return ret; +} + #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ diff --git a/library/ssl_tls13_keys.h b/library/ssl_tls13_keys.h index d3a4c6c992..41604c7e29 100644 --- a/library/ssl_tls13_keys.h +++ b/library/ssl_tls13_keys.h @@ -646,6 +646,22 @@ int mbedtls_ssl_tls13_export_handshake_psk(mbedtls_ssl_context *ssl, size_t *psk_len); #endif +/** + * \brief Calculate TLS-Exporter function as defined in RFC 8446, Section 7.5. + * + * \param[in] hash_alg The hash algorithm. + * \param[in] secret The secret to use. (Should be the exporter master secret.) + * \param[in] secret_len Length of secret. + * \param[in] label The label of the exported key. + * \param[in] label_len The length of label. + * \param[out] out The output buffer for the exported key. Must have room for at least out_len bytes. + * \param[in] out_len Length of the key to generate. +int mbedtls_ssl_tls13_exporter(psa_algorithm_t hash_alg, + const unsigned char *secret, size_t secret_len, + const unsigned char *label, size_t label_len, + const unsigned char *context_value, size_t context_len, + unsigned char *out, size_t out_len); + #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ #endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */ From 90ed7f7f5e56427218d03d98befbb7534a9d65f6 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Mon, 22 Jul 2024 14:44:09 +0200 Subject: [PATCH 02/57] Add TLS-Exporter options to ssl_server2 The program prints out the derived symmetric key for testing purposes. Signed-off-by: Max Fillinger --- programs/ssl/ssl_server2.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 5de734f7eb..01be48ab7f 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -71,6 +71,8 @@ int main(void) #define DFL_NBIO 0 #define DFL_EVENT 0 #define DFL_READ_TIMEOUT 0 +#define DFL_EXP_LABEL NULL +#define DFL_EXP_LEN 20 #define DFL_CA_FILE "" #define DFL_CA_PATH "" #define DFL_CRT_FILE "" @@ -519,6 +521,10 @@ int main(void) " event=%%d default: 0 (loop)\n" \ " options: 1 (level-triggered, implies nbio=1),\n" \ " read_timeout=%%d default: 0 ms (no timeout)\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" \ "\n" \ USAGE_DTLS \ USAGE_SRTP \ @@ -610,6 +616,8 @@ struct options { int nbio; /* should I/O be blocking? */ int event; /* loop or event-driven IO? level or edge triggered? */ uint32_t read_timeout; /* timeout on mbedtls_ssl_read() in milliseconds */ + const char *exp_label; /* label to input into mbedtls_ssl_export_keying_material() */ + int exp_len; /* Lenght of key to export using mbedtls_ssl_export_keying_material() */ int response_size; /* pad response with header to requested size */ uint16_t buffer_size; /* IO buffer size */ const char *ca_file; /* the file with the CA certificate(s) */ @@ -1699,6 +1707,8 @@ int main(int argc, char *argv[]) opt.cid_val = DFL_CID_VALUE; opt.cid_val_renego = DFL_CID_VALUE_RENEGO; opt.read_timeout = DFL_READ_TIMEOUT; + opt.exp_label = DFL_EXP_LABEL; + opt.exp_len = DFL_EXP_LEN; opt.ca_file = DFL_CA_FILE; opt.ca_path = DFL_CA_PATH; opt.crt_file = DFL_CRT_FILE; @@ -1877,6 +1887,10 @@ usage: } } else if (strcmp(p, "read_timeout") == 0) { opt.read_timeout = atoi(q); + } else if (strcmp(p, "exp_label") == 0) { + opt.exp_label = q; + } else if (strcmp(p, "exp_len") == 0) { + opt.exp_len = atoi(q); } else if (strcmp(p, "buffer_size") == 0) { opt.buffer_size = atoi(q); if (opt.buffer_size < 1) { @@ -3642,6 +3656,27 @@ handshake: mbedtls_printf("\n"); } + 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) { + mbedtls_printf("Could not allocate %d bytes\n", opt.exp_len); + ret = 3; + goto exit; + } + ret = mbedtls_ssl_export_keying_material(&ssl, exported_key, (size_t)opt.exp_len, + opt.exp_label, strlen(opt.exp_label), + NULL, 0, 0); + if (ret != 0) { + goto exit; + } + mbedtls_printf("Exporting key of length %d with label \"%s\": 0x", opt.exp_len, opt.exp_label); + for (i = 0; i < opt.exp_len; i++) { + mbedtls_printf("%02X", exported_key[i]); + } + mbedtls_printf("\n\n"); + fflush(stdout); + } + #if defined(MBEDTLS_SSL_DTLS_SRTP) else if (opt.use_srtp != 0) { size_t j = 0; From de3d5fdc837041d6874c378d7f3a2156aaa4f2b4 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Mon, 22 Jul 2024 15:09:24 +0200 Subject: [PATCH 03/57] Add TLS-Exporter options to ssl_client2 Prints out the exported key on the command line for testing purposes. Signed-off-by: Max Fillinger --- programs/ssl/ssl_client2.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index fc45e9fac0..b018b59de1 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -105,6 +105,8 @@ int main(void) #define DFL_NSS_KEYLOG 0 #define DFL_NSS_KEYLOG_FILE NULL #define DFL_SKIP_CLOSE_NOTIFY 0 +#define DFL_EXP_LABEL NULL +#define DFL_EXP_LEN 20 #define DFL_QUERY_CONFIG_MODE 0 #define DFL_USE_SRTP 0 #define DFL_SRTP_FORCE_PROFILE 0 @@ -400,6 +402,10 @@ int main(void) " read_timeout=%%d default: 0 ms (no timeout)\n" \ " max_resend=%%d default: 0 (no resend on timeout)\n" \ " skip_close_notify=%%d default: 0 (send close_notify)\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" \ "\n" \ USAGE_DTLS \ USAGE_CID \ @@ -553,6 +559,8 @@ struct options { * after renegotiation */ int reproducible; /* make communication reproducible */ int skip_close_notify; /* skip sending the close_notify alert */ + const char *exp_label; /* label to input into mbedtls_ssl_export_keying_material() */ + int exp_len; /* Lenght of key to export using mbedtls_ssl_export_keying_material() */ #if defined(MBEDTLS_SSL_EARLY_DATA) int early_data; /* early data enablement flag */ #endif @@ -1460,6 +1468,10 @@ usage: if (opt.skip_close_notify < 0 || opt.skip_close_notify > 1) { goto usage; } + } else if (strcmp(p, "exp_label") == 0) { + opt.exp_label = q; + } else if (strcmp(p, "exp_len") == 0) { + opt.exp_len = atoi(q); } else if (strcmp(p, "use_srtp") == 0) { opt.use_srtp = atoi(q); } else if (strcmp(p, "srtp_force_profile") == 0) { @@ -2560,6 +2572,27 @@ usage: } #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + 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) { + mbedtls_printf("Could not allocate %d bytes\n", opt.exp_len); + ret = 3; + goto exit; + } + ret = mbedtls_ssl_export_keying_material(&ssl, exported_key, (size_t)opt.exp_len, + opt.exp_label, strlen(opt.exp_label), + NULL, 0, 0); + if (ret != 0) { + goto exit; + } + mbedtls_printf("Exporting key of length %d with label \"%s\": 0x", opt.exp_len, opt.exp_label); + for (i = 0; i < opt.exp_len; i++) { + mbedtls_printf("%02X", exported_key[i]); + } + mbedtls_printf("\n\n"); + fflush(stdout); + } + /* * 6. Write the GET request */ From 91ad62efc74f61fdb0cf1c8472635ddabdcc7e76 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Thu, 25 Jul 2024 16:16:02 +0200 Subject: [PATCH 04/57] Add changelog entry for TLS-Exporter feature Signed-off-by: Max Fillinger --- ChangeLog.d/add-tls-exporter.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ChangeLog.d/add-tls-exporter.txt diff --git a/ChangeLog.d/add-tls-exporter.txt b/ChangeLog.d/add-tls-exporter.txt new file mode 100644 index 0000000000..c752a18e1d --- /dev/null +++ b/ChangeLog.d/add-tls-exporter.txt @@ -0,0 +1,4 @@ +Features: + * Add the function mbedtls_ssl_export_keying_material() which allows the + client and server to extract additional shared symmetric keys from an SSL + session, according to the TLS-Exporter specification in RFC 8446 and 5705. From 29f79ea7f4d17e6afa3b7fed4f30105c57617da5 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Fri, 9 Aug 2024 18:54:36 +0200 Subject: [PATCH 05/57] Fix commented out function declaration Signed-off-by: Max Fillinger --- library/ssl_tls13_keys.h | 1 + 1 file changed, 1 insertion(+) diff --git a/library/ssl_tls13_keys.h b/library/ssl_tls13_keys.h index 41604c7e29..07b970aaf6 100644 --- a/library/ssl_tls13_keys.h +++ b/library/ssl_tls13_keys.h @@ -656,6 +656,7 @@ int mbedtls_ssl_tls13_export_handshake_psk(mbedtls_ssl_context *ssl, * \param[in] label_len The length of label. * \param[out] out The output buffer for the exported key. Must have room for at least out_len bytes. * \param[in] out_len Length of the key to generate. + */ int mbedtls_ssl_tls13_exporter(psa_algorithm_t hash_alg, const unsigned char *secret, size_t secret_len, const unsigned char *label, size_t label_len, From d3d7ff4c6bec1adbe3db07d7d0b76ff50db481fb Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Fri, 9 Aug 2024 19:46:15 +0200 Subject: [PATCH 06/57] Add test for TLS-Exporter in TLS 1.3 Signed-off-by: Max Fillinger --- tests/suites/test_suite_ssl.data | 5 +++++ tests/suites/test_suite_ssl.function | 31 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index b6a843b77d..d54383b035 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -2904,6 +2904,11 @@ SSL TLS 1.3 Key schedule: Derive-Secret( ., "res master", hash) depends_on:PSA_WANT_ALG_SHA_256 ssl_tls13_derive_secret:PSA_ALG_SHA_256:"e2d32d4ed66dd37897a0e80c84107503ce58bf8aad4cb55a5002d77ecb890ece":tls13_label_res_master:"c3c122e0bd907a4a3ff6112d8fd53dbf89c773d9552e8b6b9d56d361b3a97bf6":32:MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED:"5e95bdf1f89005ea2e9aa0ba85e728e3c19c5fe0c699e3f5bee59faebd0b5406" +SSL TLS 1.3 Exporter +# Based on the "exp master" key from RFC 8448, expected result calculated with a HMAC-SHA256 calculator. +depends_on:PSA_WANT_ALG_SHA_256 +ssl_tls13_exporter:PSA_ALG_SHA_256:"3fd93d4ffddc98e64b14dd107aedf8ee4add23f4510f58a4592d0b201bee56b4":"test":"context value":32:"83d0fac39f87c1b4fbcd261369f31149c535391a9199bd4c5daf89fe259c2e94" + SSL TLS 1.3 Key schedule: Early secrets derivation helper # Vector from RFC 8448 depends_on:PSA_WANT_ALG_SHA_256 diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index f189affe86..85a6e5d7c3 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -1964,6 +1964,37 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3 */ +void ssl_tls13_exporter(int hash_alg, + data_t *secret, + char *label, + char *context_value, + int desired_length, + data_t *expected) +{ + unsigned char dst[100]; + + /* Check sanity of test parameters. */ + TEST_ASSERT((size_t) desired_length <= sizeof(dst)); + TEST_ASSERT((size_t) desired_length == expected->len); + + PSA_INIT(); + + TEST_ASSERT(mbedtls_ssl_tls13_exporter( + (psa_algorithm_t) hash_alg, + secret->x, secret->len, + (unsigned char *)label, strlen(label), + (unsigned char *)context_value, strlen(context_value), + dst, desired_length) == 0); + + TEST_MEMORY_COMPARE(dst, desired_length, + expected->x, desired_length); + +exit: + PSA_DONE(); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3 */ void ssl_tls13_derive_early_secrets(int hash_alg, data_t *secret, From 404f7a3bfb467bbbc3a58f30b75d1c5138be0600 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Mon, 12 Aug 2024 11:20:39 +0200 Subject: [PATCH 07/57] Simplify mbedtls_ssl_tls13_exporter RFC 8446 made it look like we can't use Derive-Secret for the second step, but actually, Transcript-Hash and Hash are the same thing, so we can. Signed-off-by: Max Fillinger --- library/ssl_tls13_keys.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c index bbaa7c47fe..9098418afb 100644 --- a/library/ssl_tls13_keys.c +++ b/library/ssl_tls13_keys.c @@ -1890,26 +1890,17 @@ int mbedtls_ssl_tls13_exporter(const psa_algorithm_t hash_alg, { size_t hash_len = PSA_HASH_LENGTH(hash_alg); unsigned char hkdf_secret[MBEDTLS_TLS1_3_MD_MAX_SIZE]; - unsigned char hashed_context[PSA_HASH_MAX_SIZE]; - size_t hashed_context_len = 0; int ret = 0; - psa_status_t status = 0; ret = mbedtls_ssl_tls13_derive_secret(hash_alg, secret, secret_len, label, label_len, NULL, 0, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, hkdf_secret, hash_len); if (ret != 0) { goto exit; } - - status = psa_hash_compute(hash_alg, context_value, context_len, hashed_context, hash_len, &hashed_context_len); - if (status != PSA_SUCCESS) { - ret = PSA_TO_MBEDTLS_ERR(status); - goto exit; - } - ret = mbedtls_ssl_tls13_hkdf_expand_label(hash_alg, hkdf_secret, hash_len, - MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(exporter), - hashed_context, hashed_context_len, - out, out_len); + ret = mbedtls_ssl_tls13_derive_secret(hash_alg, hkdf_secret, hash_len, + MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(exporter), + context_value, context_len, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, + out, out_len); exit: mbedtls_platform_zeroize(hkdf_secret, sizeof(hkdf_secret)); From 77a447ba975038aaf9e023ca9deed7158947de76 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Mon, 12 Aug 2024 12:51:02 +0200 Subject: [PATCH 08/57] Actually set exporter defaults in ssl_client2 Signed-off-by: Max Fillinger --- programs/ssl/ssl_client2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index b018b59de1..c7655ca9ef 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -1012,6 +1012,8 @@ int main(int argc, char *argv[]) opt.nss_keylog = DFL_NSS_KEYLOG; opt.nss_keylog_file = DFL_NSS_KEYLOG_FILE; opt.skip_close_notify = DFL_SKIP_CLOSE_NOTIFY; + opt.exp_label = DFL_EXP_LABEL; + opt.exp_len = DFL_EXP_LEN; opt.query_config_mode = DFL_QUERY_CONFIG_MODE; opt.use_srtp = DFL_USE_SRTP; opt.force_srtp_profile = DFL_SRTP_FORCE_PROFILE; From 1466bf88974bf7ad40e1a3a6179ba3b48f5002b0 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Mon, 12 Aug 2024 13:20:46 +0200 Subject: [PATCH 09/57] Fix key_len check in TLS-Exporter The length of the generated key must fit into a uint16_t, so it must not be larger than 0xffff. Signed-off-by: Max Fillinger --- library/ssl_tls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 3c1c5cf588..4fe13ffbfc 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -10111,7 +10111,7 @@ static int mbedtls_ssl_tls13_export_keying_material(mbedtls_ssl_context *ssl, const size_t hash_len = PSA_HASH_LENGTH(hash_alg); const unsigned char *secret = ssl->session->app_secrets.exporter_master_secret; - if (key_len > 0xff || label_len > 250) { + if (key_len > 0xffff || label_len > 250) { return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; } From 3be83a7696fa251cca20e825e8b01c1c80bb74e6 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Wed, 14 Aug 2024 16:44:50 +0200 Subject: [PATCH 10/57] Fix mismatches in function declarations Missed some const keywords in function declarations. Signed-off-by: Max Fillinger --- include/mbedtls/ssl.h | 8 ++++---- library/ssl_tls.c | 8 ++++---- library/ssl_tls13_keys.h | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index f1c8bd293b..fe107b76dc 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -5787,10 +5787,10 @@ int mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf, * \return 0 on success. An SSL specific error on failure. */ int mbedtls_ssl_export_keying_material(mbedtls_ssl_context *ssl, - uint8_t *out, size_t key_len, - const char *label, size_t label_len, - const unsigned char *context, size_t context_len, - int use_context); + uint8_t *out, const size_t key_len, + const char *label, const size_t label_len, + const unsigned char *context, const size_t context_len, + const int use_context); #ifdef __cplusplus } #endif diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 4fe13ffbfc..9e4cf3ec96 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -10121,10 +10121,10 @@ static int mbedtls_ssl_tls13_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, - const char *label, const size_t label_len, - const unsigned char *context, const size_t context_len, - const int use_context) + uint8_t *out, const size_t key_len, + const char *label, const size_t label_len, + const unsigned char *context, const size_t context_len, + const int use_context) { if (!mbedtls_ssl_is_handshake_over(ssl)) { return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; diff --git a/library/ssl_tls13_keys.h b/library/ssl_tls13_keys.h index 07b970aaf6..a4b012f36e 100644 --- a/library/ssl_tls13_keys.h +++ b/library/ssl_tls13_keys.h @@ -657,11 +657,11 @@ int mbedtls_ssl_tls13_export_handshake_psk(mbedtls_ssl_context *ssl, * \param[out] out The output buffer for the exported key. Must have room for at least out_len bytes. * \param[in] out_len Length of the key to generate. */ -int mbedtls_ssl_tls13_exporter(psa_algorithm_t hash_alg, - const unsigned char *secret, size_t secret_len, - const unsigned char *label, size_t label_len, - const unsigned char *context_value, size_t context_len, - unsigned char *out, size_t out_len); +int mbedtls_ssl_tls13_exporter(const psa_algorithm_t hash_alg, + const unsigned char *secret, const size_t secret_len, + const unsigned char *label, const size_t label_len, + const unsigned char *context_value, const size_t context_len, + uint8_t *out, const size_t out_len); #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ From 5805cc9807e75a33df89126e56eb2d5cfd87a62b Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Fri, 20 Sep 2024 15:22:06 +0200 Subject: [PATCH 11/57] Fix typos in comment Signed-off-by: Max Fillinger --- include/mbedtls/ssl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index fe107b76dc..e847022752 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -5776,7 +5776,7 @@ int mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf, * \param label Label for which to generate the key of length label_len. * \param label_len Length of label in bytes. Must be < 251 in TLS 1.3. * \param context Context of the key. Can be NULL if context_len or use_context is 0. - * \param context_len Length of context. Must be < 2^16 in TLS1.2. + * \param context_len Length of context. Must be < 2^16 in TLS 1.2. * \param use_context Indicates if a context should be used in deriving the key. * * \note TLS 1.2 makes a distinction between a 0-length context and no context. From f95bfda1f9b51ee8cd35286fef18d224f1f57023 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Fri, 20 Sep 2024 17:50:16 +0200 Subject: [PATCH 12/57] Fix doxygen comment parameter name Signed-off-by: Max Fillinger --- include/mbedtls/ssl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index e847022752..5dc3d526ec 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -5770,7 +5770,7 @@ int mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf, /** * \brief TLS-Exporter to derive shared symmetric keys between server and client. * - * \param ctx SSL context from which to export keys. Must have finished the handshake. + * \param ssl SSL context from which to export keys. Must have finished the handshake. * \param out Output buffer of length at least key_len bytes. * \param key_len Length of the key to generate in bytes. Must be < 2^16 in TLS 1.3. * \param label Label for which to generate the key of length label_len. From 15f9f5e5629a46ce14eec97c144453cc299c0fe0 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Fri, 20 Sep 2024 17:57:52 +0200 Subject: [PATCH 13/57] Fix TLS exporter changelog entry Signed-off-by: Max Fillinger --- ChangeLog.d/add-tls-exporter.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog.d/add-tls-exporter.txt b/ChangeLog.d/add-tls-exporter.txt index c752a18e1d..2b06c5f294 100644 --- a/ChangeLog.d/add-tls-exporter.txt +++ b/ChangeLog.d/add-tls-exporter.txt @@ -1,4 +1,4 @@ -Features: +Features * Add the function mbedtls_ssl_export_keying_material() which allows the client and server to extract additional shared symmetric keys from an SSL session, according to the TLS-Exporter specification in RFC 8446 and 5705. From 9359f4d70312adb1405d6611e25e1a4e1521c93c Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Sat, 21 Sep 2024 10:48:57 +0200 Subject: [PATCH 14/57] Fix coding style Signed-off-by: Max Fillinger --- include/mbedtls/ssl.h | 40 ++++++++++++++-------------- library/ssl_tls.c | 31 ++++++++++++++------- library/ssl_tls13_keys.c | 14 +++++++--- programs/ssl/ssl_client2.c | 8 +++--- programs/ssl/ssl_server2.c | 8 +++--- tests/suites/test_suite_ssl.function | 4 +-- 6 files changed, 63 insertions(+), 42 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 5dc3d526ec..ccc562ea64 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -5767,26 +5767,26 @@ int mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf, const unsigned char *random, size_t rlen, unsigned char *dstbuf, size_t dlen); - /** - * \brief TLS-Exporter to derive shared symmetric keys between server and client. - * - * \param ssl SSL context from which to export keys. Must have finished the handshake. - * \param out Output buffer of length at least key_len bytes. - * \param key_len Length of the key to generate in bytes. Must be < 2^16 in TLS 1.3. - * \param label Label for which to generate the key of length label_len. - * \param label_len Length of label in bytes. Must be < 251 in TLS 1.3. - * \param context Context of the key. Can be NULL if context_len or use_context is 0. - * \param context_len Length of context. Must be < 2^16 in TLS 1.2. - * \param use_context Indicates if a context should be used in deriving the key. - * - * \note TLS 1.2 makes a distinction between a 0-length context and no context. - * This is why the use_context argument exists. TLS 1.3 does not make - * this distinction. If use_context is 0 and TLS 1.3 is used, context and - * context_len are ignored and a 0-length context is used. - * - * \return 0 on success. An SSL specific error on failure. - */ - int mbedtls_ssl_export_keying_material(mbedtls_ssl_context *ssl, +/** + * \brief TLS-Exporter to derive shared symmetric keys between server and client. + * + * \param ssl SSL context from which to export keys. Must have finished the handshake. + * \param out Output buffer of length at least key_len bytes. + * \param key_len Length of the key to generate in bytes. Must be < 2^16 in TLS 1.3. + * \param label Label for which to generate the key of length label_len. + * \param label_len Length of label in bytes. Must be < 251 in TLS 1.3. + * \param context Context of the key. Can be NULL if context_len or use_context is 0. + * \param context_len Length of context. Must be < 2^16 in TLS 1.2. + * \param use_context Indicates if a context should be used in deriving the key. + * + * \note TLS 1.2 makes a distinction between a 0-length context and no context. + * This is why the use_context argument exists. TLS 1.3 does not make + * this distinction. If use_context is 0 and TLS 1.3 is used, context and + * context_len are ignored and a 0-length context is used. + * + * \return 0 on success. An SSL specific error on failure. + */ +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, const unsigned char *context, const size_t context_len, diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 9e4cf3ec96..a109cfc395 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -10056,9 +10056,12 @@ int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl, static int mbedtls_ssl_tls12_export_keying_material(const mbedtls_ssl_context *ssl, const mbedtls_md_type_t hash_alg, - uint8_t *out, const size_t key_len, - const char *label, const size_t label_len, - const unsigned char *context, const size_t context_len, + uint8_t *out, + const size_t key_len, + const char *label, + const size_t label_len, + const unsigned char *context, + const size_t context_len, const int use_context) { int ret = 0; @@ -10087,8 +10090,8 @@ static int mbedtls_ssl_tls12_export_keying_material(const mbedtls_ssl_context *s memcpy(prf_input, ssl->transform->randbytes + 32, 32); memcpy(prf_input + 32, ssl->transform->randbytes, 32); if (use_context) { - prf_input[64] = (unsigned char)((context_len >> 8) & 0xff); - prf_input[65] = (unsigned char)(context_len & 0xff); + prf_input[64] = (unsigned char) ((context_len >> 8) & 0xff); + prf_input[65] = (unsigned char) (context_len & 0xff); memcpy(prf_input + 66, context, context_len); } ret = tls_prf_generic(hash_alg, ssl->session->master, 48, label_str, @@ -10103,9 +10106,12 @@ exit: static int mbedtls_ssl_tls13_export_keying_material(mbedtls_ssl_context *ssl, const mbedtls_md_type_t hash_alg, - uint8_t *out, const size_t key_len, - const char *label, const size_t label_len, - const unsigned char *context, const size_t context_len) + uint8_t *out, + const size_t key_len, + const char *label, + const size_t label_len, + const unsigned char *context, + const size_t context_len) { const psa_algorithm_t psa_hash_alg = mbedtls_md_psa_alg_from_type(hash_alg); const size_t hash_len = PSA_HASH_LENGTH(hash_alg); @@ -10116,7 +10122,7 @@ static int mbedtls_ssl_tls13_export_keying_material(mbedtls_ssl_context *ssl, } return mbedtls_ssl_tls13_exporter(psa_hash_alg, secret, hash_len, - (const unsigned char *)label, label_len, + (const unsigned char *) label, label_len, context, context_len, out, key_len); } @@ -10140,7 +10146,12 @@ int mbedtls_ssl_export_keying_material(mbedtls_ssl_context *ssl, label, label_len, context, context_len, use_context); case MBEDTLS_SSL_VERSION_TLS1_3: - return mbedtls_ssl_tls13_export_keying_material(ssl, hash_alg, out, key_len, label, label_len, + return mbedtls_ssl_tls13_export_keying_material(ssl, + hash_alg, + out, + key_len, + label, + label_len, use_context ? context : NULL, use_context ? context_len : 0); default: diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c index 9098418afb..e0a866944c 100644 --- a/library/ssl_tls13_keys.c +++ b/library/ssl_tls13_keys.c @@ -1893,14 +1893,20 @@ int mbedtls_ssl_tls13_exporter(const psa_algorithm_t hash_alg, int ret = 0; ret = mbedtls_ssl_tls13_derive_secret(hash_alg, secret, secret_len, label, label_len, NULL, 0, - MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, hkdf_secret, hash_len); + MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, hkdf_secret, + hash_len); if (ret != 0) { goto exit; } - ret = mbedtls_ssl_tls13_derive_secret(hash_alg, hkdf_secret, hash_len, + ret = mbedtls_ssl_tls13_derive_secret(hash_alg, + hkdf_secret, + hash_len, MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(exporter), - context_value, context_len, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, - out, out_len); + context_value, + context_len, + MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, + out, + out_len); exit: mbedtls_platform_zeroize(hkdf_secret, sizeof(hkdf_secret)); diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index c7655ca9ef..d12d4477e7 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -2575,19 +2575,21 @@ usage: #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 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) { mbedtls_printf("Could not allocate %d bytes\n", opt.exp_len); ret = 3; goto exit; } - ret = mbedtls_ssl_export_keying_material(&ssl, exported_key, (size_t)opt.exp_len, + ret = mbedtls_ssl_export_keying_material(&ssl, exported_key, (size_t) opt.exp_len, opt.exp_label, strlen(opt.exp_label), NULL, 0, 0); if (ret != 0) { goto exit; } - mbedtls_printf("Exporting key of length %d with label \"%s\": 0x", opt.exp_len, opt.exp_label); + mbedtls_printf("Exporting key of length %d with label \"%s\": 0x", + opt.exp_len, + opt.exp_label); for (i = 0; i < opt.exp_len; i++) { mbedtls_printf("%02X", exported_key[i]); } diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 01be48ab7f..1d6cc121d7 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -3657,19 +3657,21 @@ handshake: } 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) { mbedtls_printf("Could not allocate %d bytes\n", opt.exp_len); ret = 3; goto exit; } - ret = mbedtls_ssl_export_keying_material(&ssl, exported_key, (size_t)opt.exp_len, + ret = mbedtls_ssl_export_keying_material(&ssl, exported_key, (size_t) opt.exp_len, opt.exp_label, strlen(opt.exp_label), NULL, 0, 0); if (ret != 0) { goto exit; } - mbedtls_printf("Exporting key of length %d with label \"%s\": 0x", opt.exp_len, opt.exp_label); + mbedtls_printf("Exporting key of length %d with label \"%s\": 0x", + opt.exp_len, + opt.exp_label); for (i = 0; i < opt.exp_len; i++) { mbedtls_printf("%02X", exported_key[i]); } diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 85a6e5d7c3..d2aec06859 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -1983,8 +1983,8 @@ void ssl_tls13_exporter(int hash_alg, TEST_ASSERT(mbedtls_ssl_tls13_exporter( (psa_algorithm_t) hash_alg, secret->x, secret->len, - (unsigned char *)label, strlen(label), - (unsigned char *)context_value, strlen(context_value), + (unsigned char *) label, strlen(label), + (unsigned char *) context_value, strlen(context_value), dst, desired_length) == 0); TEST_MEMORY_COMPARE(dst, desired_length, From 0118293e236cacad689b7157c60f826fe2d4b6bd Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Sat, 21 Sep 2024 11:06:28 +0200 Subject: [PATCH 15/57] Fix build when one of TLS 1.2 or 1.3 is disabled Signed-off-by: Max Fillinger --- library/ssl_tls.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index a109cfc395..6af502e77d 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -10054,6 +10054,7 @@ int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) static int mbedtls_ssl_tls12_export_keying_material(const mbedtls_ssl_context *ssl, const mbedtls_md_type_t hash_alg, uint8_t *out, @@ -10103,7 +10104,9 @@ exit: mbedtls_free(label_str); return ret; } +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_3) static int mbedtls_ssl_tls13_export_keying_material(mbedtls_ssl_context *ssl, const mbedtls_md_type_t hash_alg, uint8_t *out, @@ -10125,6 +10128,7 @@ static int mbedtls_ssl_tls13_export_keying_material(mbedtls_ssl_context *ssl, (const unsigned char *) label, label_len, context, context_len, out, key_len); } +#endif int mbedtls_ssl_export_keying_material(mbedtls_ssl_context *ssl, uint8_t *out, const size_t key_len, @@ -10141,10 +10145,13 @@ int mbedtls_ssl_export_keying_material(mbedtls_ssl_context *ssl, const mbedtls_md_type_t hash_alg = ciphersuite->mac; switch (mbedtls_ssl_get_version_number(ssl)) { +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) case MBEDTLS_SSL_VERSION_TLS1_2: return mbedtls_ssl_tls12_export_keying_material(ssl, hash_alg, out, key_len, label, label_len, context, context_len, use_context); +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_3) case MBEDTLS_SSL_VERSION_TLS1_3: return mbedtls_ssl_tls13_export_keying_material(ssl, hash_alg, @@ -10154,6 +10161,7 @@ int mbedtls_ssl_export_keying_material(mbedtls_ssl_context *ssl, label_len, use_context ? context : NULL, use_context ? context_len : 0); +#endif default: return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION; } From c48e9e00049df2eeb2bf80d847a22fc8a305a050 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Sun, 22 Sep 2024 01:28:12 +0200 Subject: [PATCH 16/57] Fix coding style Signed-off-by: Max Fillinger --- include/mbedtls/ssl.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index ccc562ea64..779dab6e21 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -5787,10 +5787,10 @@ int mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf, * \return 0 on success. An SSL specific error on failure. */ 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, - const unsigned char *context, const size_t context_len, - const int use_context); + uint8_t *out, const size_t key_len, + const char *label, const size_t label_len, + const unsigned char *context, const size_t context_len, + const int use_context); #ifdef __cplusplus } #endif From 85b33ee42e7cfcf9f63cbb347d9f5d5c65a8a87e Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Fri, 18 Oct 2024 16:19:39 +0200 Subject: [PATCH 17/57] Store randbytes for TLS 1.2 TLS-Exporter Previously, if MBEDTLS_SSL_CONTEXT_SERIALIZATION is not defined, randbytes are not stored after the handshake is done, but they are needed for TLS-Exporter in TLS 1.2. This commit also saves randbytes if MBEDTLS_SSL_PROTO_TLS1_2 is defined. Signed-off-by: Max Fillinger --- library/ssl_misc.h | 6 +++--- library/ssl_tls.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 29254958fc..7b56accac7 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -1166,10 +1166,10 @@ 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_CONTEXT_SERIALIZATION) || defined(MBEDTLS_SSL_PROTO_TLS1_2) /* 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, see ssl_tls12_populate_transform(). + * They are also needed for the TLS 1.2 TLS-Exporter. */ 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 6af502e77d..67c60661aa 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -8669,7 +8669,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_CONTEXT_SERIALIZATION) || defined(MBEDTLS_SSL_PROTO_TLS1_2) memcpy(transform->randbytes, randbytes, sizeof(transform->randbytes)); #endif From 76077e2e31b64b45ce1ff3c9b7034d32718ea7e0 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Wed, 23 Oct 2024 15:47:23 +0200 Subject: [PATCH 18/57] Add label length argument to tls_prf_generic() This way, it's not required that the label is null-terminated. This allows us to avoid an allocation in mbedtls_ssl_tls12_export_keying_material(). Signed-off-by: Max Fillinger --- library/ssl_tls.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 67c60661aa..bfb8606eed 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -6769,7 +6769,7 @@ static psa_status_t setup_psa_key_derivation(psa_key_derivation_operation_t *der MBEDTLS_CHECK_RETURN_CRITICAL static int tls_prf_generic(mbedtls_md_type_t md_type, const unsigned char *secret, size_t slen, - const char *label, + const char *label, size_t label_len, const unsigned char *random, size_t rlen, unsigned char *dstbuf, size_t dlen) { @@ -6809,7 +6809,7 @@ static int tls_prf_generic(mbedtls_md_type_t md_type, NULL, 0, random, rlen, (unsigned char const *) label, - (size_t) strlen(label), + label_len, NULL, 0, dlen); if (status != PSA_SUCCESS) { @@ -6960,7 +6960,7 @@ static int tls_prf_sha256(const unsigned char *secret, size_t slen, unsigned char *dstbuf, size_t dlen) { return tls_prf_generic(MBEDTLS_MD_SHA256, secret, slen, - label, random, rlen, dstbuf, dlen); + label, strlen(label), random, rlen, dstbuf, dlen); } #endif /* MBEDTLS_MD_CAN_SHA256*/ @@ -6972,7 +6972,7 @@ static int tls_prf_sha384(const unsigned char *secret, size_t slen, unsigned char *dstbuf, size_t dlen) { return tls_prf_generic(MBEDTLS_MD_SHA384, secret, slen, - label, random, rlen, dstbuf, dlen); + label, strlen(label), random, rlen, dstbuf, dlen); } #endif /* MBEDTLS_MD_CAN_SHA384*/ @@ -10068,7 +10068,6 @@ static int mbedtls_ssl_tls12_export_keying_material(const mbedtls_ssl_context *s int ret = 0; size_t prf_input_len = use_context ? 64 + 2 + context_len : 64; unsigned char *prf_input = NULL; - char *label_str = NULL; if (use_context && context_len >= (1 << 16)) { ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA; @@ -10076,15 +10075,11 @@ static int mbedtls_ssl_tls12_export_keying_material(const mbedtls_ssl_context *s } prf_input = mbedtls_calloc(prf_input_len, sizeof(unsigned char)); - label_str = mbedtls_calloc(label_len + 1, sizeof(char)); - if (prf_input == NULL || label_str == NULL) { + if (prf_input == NULL) { ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; goto exit; } - memcpy(label_str, label, label_len); - label_str[label_len] = '\0'; - /* The input to the PRF is client_random, then server_random. * If a context is provided, this is then followed by the context length * as a 16-bit big-endian integer, and then the context itself. */ @@ -10095,13 +10090,13 @@ static int mbedtls_ssl_tls12_export_keying_material(const mbedtls_ssl_context *s prf_input[65] = (unsigned char) (context_len & 0xff); memcpy(prf_input + 66, context, context_len); } - ret = tls_prf_generic(hash_alg, ssl->session->master, 48, label_str, + ret = tls_prf_generic(hash_alg, ssl->session->master, 48, + label, label_len, prf_input, prf_input_len, out, key_len); exit: mbedtls_free(prf_input); - mbedtls_free(label_str); return ret; } #endif From 6c02ea86aab81c7923cfb2c082667c39f5aac708 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Wed, 23 Oct 2024 16:32:54 +0200 Subject: [PATCH 19/57] Use fewer magic numbers in TLS-Exporter functions Signed-off-by: Max Fillinger --- library/ssl_tls.c | 53 ++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index bfb8606eed..bfffa97e13 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -10066,36 +10066,43 @@ static int mbedtls_ssl_tls12_export_keying_material(const mbedtls_ssl_context *s const int use_context) { int ret = 0; - size_t prf_input_len = use_context ? 64 + 2 + context_len : 64; unsigned char *prf_input = NULL; - if (use_context && context_len >= (1 << 16)) { - ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - goto exit; - } - - prf_input = mbedtls_calloc(prf_input_len, sizeof(unsigned char)); - if (prf_input == NULL) { - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto exit; - } - /* The input to the PRF is client_random, then server_random. * If a context is provided, this is then followed by the context length * as a 16-bit big-endian integer, and then the context itself. */ - memcpy(prf_input, ssl->transform->randbytes + 32, 32); - memcpy(prf_input + 32, ssl->transform->randbytes, 32); + const size_t randbytes_len = MBEDTLS_CLIENT_HELLO_RANDOM_LEN + MBEDTLS_SERVER_HELLO_RANDOM_LEN; + size_t prf_input_len = randbytes_len; if (use_context) { - prf_input[64] = (unsigned char) ((context_len >> 8) & 0xff); - prf_input[65] = (unsigned char) (context_len & 0xff); - memcpy(prf_input + 66, context, context_len); + if (context_len > UINT16_MAX) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + /* This does not overflow a 32-bit size_t because the current value of + * prf_input_len is 64 (length of client_random + server_random) and + * context_len fits into two bytes (checked above). */ + prf_input_len += sizeof(uint16_t) + context_len; } - ret = tls_prf_generic(hash_alg, ssl->session->master, 48, + + prf_input = mbedtls_calloc(prf_input_len, sizeof(unsigned char)); + if (prf_input == NULL) { + return MBEDTLS_ERR_SSL_ALLOC_FAILED; + } + + memcpy(prf_input, + ssl->transform->randbytes + MBEDTLS_SERVER_HELLO_RANDOM_LEN, + MBEDTLS_CLIENT_HELLO_RANDOM_LEN); + memcpy(prf_input + MBEDTLS_CLIENT_HELLO_RANDOM_LEN, + ssl->transform->randbytes, + MBEDTLS_SERVER_HELLO_RANDOM_LEN); + if (use_context) { + MBEDTLS_PUT_UINT16_BE(context_len, prf_input, randbytes_len); + memcpy(prf_input + randbytes_len + sizeof(uint16_t), context, context_len); + } + ret = tls_prf_generic(hash_alg, ssl->session->master, sizeof(ssl->session->master), label, label_len, prf_input, prf_input_len, out, key_len); - -exit: mbedtls_free(prf_input); return ret; } @@ -10115,7 +10122,11 @@ static int mbedtls_ssl_tls13_export_keying_material(mbedtls_ssl_context *ssl, const size_t hash_len = PSA_HASH_LENGTH(hash_alg); const unsigned char *secret = ssl->session->app_secrets.exporter_master_secret; - if (key_len > 0xffff || label_len > 250) { + /* Check that the label and key_len fit into the HkdfLabel struct as defined + * in RFC 8446, Section 7.1. key_len must fit into an uint16 and the label + * must be at most 250 bytes long. (The struct allows up to 256 bytes for + * the label, but it is prefixed with "tls13 ".) */ + if (key_len > UINT16_MAX || label_len > 250) { return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; } From 948e15d3b7231235520f56e84e28c2c305ca18cd Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Wed, 23 Oct 2024 17:21:40 +0200 Subject: [PATCH 20/57] Fix typos in comments Signed-off-by: Max Fillinger --- programs/ssl/ssl_client2.c | 2 +- programs/ssl/ssl_server2.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index d12d4477e7..27a674fc52 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -560,7 +560,7 @@ struct options { int reproducible; /* make communication reproducible */ int skip_close_notify; /* skip sending the close_notify alert */ const char *exp_label; /* label to input into mbedtls_ssl_export_keying_material() */ - int exp_len; /* Lenght of key to export using mbedtls_ssl_export_keying_material() */ + int exp_len; /* Length of key to export using mbedtls_ssl_export_keying_material() */ #if defined(MBEDTLS_SSL_EARLY_DATA) int early_data; /* early data enablement flag */ #endif diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 1d6cc121d7..3bcee9a153 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -617,7 +617,7 @@ struct options { int event; /* loop or event-driven IO? level or edge triggered? */ uint32_t read_timeout; /* timeout on mbedtls_ssl_read() in milliseconds */ const char *exp_label; /* label to input into mbedtls_ssl_export_keying_material() */ - int exp_len; /* Lenght of key to export using mbedtls_ssl_export_keying_material() */ + int exp_len; /* Length of key to export using mbedtls_ssl_export_keying_material() */ int response_size; /* pad response with header to requested size */ uint16_t buffer_size; /* IO buffer size */ const char *ca_file; /* the file with the CA certificate(s) */ From 92d29301bc139530444767687b468928b9d3f2da Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Wed, 23 Oct 2024 17:24:03 +0200 Subject: [PATCH 21/57] Revert "Store randbytes for TLS 1.2 TLS-Exporter" This reverts commit cb01dd1333f8083af469e9a0c59f316f1eb0cfe3. Signed-off-by: Max Fillinger --- library/ssl_misc.h | 6 +++--- library/ssl_tls.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 7b56accac7..29254958fc 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -1166,10 +1166,10 @@ 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) || defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) /* 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(). - * They are also needed for the TLS 1.2 TLS-Exporter. */ + * Master Secret and other session info, + * 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 bfffa97e13..3e85254844 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -8669,7 +8669,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) || defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) memcpy(transform->randbytes, randbytes, sizeof(transform->randbytes)); #endif From 7b52328f6c43d5030ced3500e0ee333115d8f5f3 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Wed, 23 Oct 2024 18:35:09 +0200 Subject: [PATCH 22/57] Remove TLS 1.2 Exporter if we don't have randbytes The TLS-Exporter in TLS 1.2 requires client_random and server_random. Unless MBEDTLS_SSL_CONTEXT_SERIALIZATION is defined, these aren't stored after the handshake is completed. Therefore, mbedtls_ssl_export_keying_material() exists only if either MBEDTLS_SSL_CONTEXT_SERIALIZATION is defined or MBEDTLS_SSL_PROTO_TLS1_2 is *not* defined. Signed-off-by: Max Fillinger --- include/mbedtls/ssl.h | 2 ++ library/ssl_tls.c | 9 +++++++-- programs/ssl/ssl_client2.c | 12 +++++++----- programs/ssl/ssl_server2.c | 12 +++++++----- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 779dab6e21..3da4ecaf61 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -5786,11 +5786,13 @@ 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) 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, const unsigned char *context, const size_t context_len, const int use_context); +#endif #ifdef __cplusplus } #endif diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 3e85254844..971821ae1b 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -10054,6 +10054,9 @@ 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_PROTO_TLS1_2) static int mbedtls_ssl_tls12_export_keying_material(const mbedtls_ssl_context *ssl, const mbedtls_md_type_t hash_alg, @@ -10106,7 +10109,7 @@ static int mbedtls_ssl_tls12_export_keying_material(const mbedtls_ssl_context *s mbedtls_free(prf_input); return ret; } -#endif +#endif /* defined(MBEDTLS_SSL_PROTO_TLS1_2) */ #if defined(MBEDTLS_SSL_PROTO_TLS1_3) static int mbedtls_ssl_tls13_export_keying_material(mbedtls_ssl_context *ssl, @@ -10134,7 +10137,7 @@ static int mbedtls_ssl_tls13_export_keying_material(mbedtls_ssl_context *ssl, (const unsigned char *) label, label_len, context, context_len, out, key_len); } -#endif +#endif /* defined(MBEDTLS_SSL_PROTO_TLS1_3) */ int mbedtls_ssl_export_keying_material(mbedtls_ssl_context *ssl, uint8_t *out, const size_t key_len, @@ -10173,4 +10176,6 @@ int mbedtls_ssl_export_keying_material(mbedtls_ssl_context *ssl, } } +#endif /* defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) || !defined(MBEDTLS_SSL_PROTO_TLS1_2) */ + #endif /* MBEDTLS_SSL_TLS_C */ diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 27a674fc52..8f7ae0419d 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -347,7 +347,11 @@ 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" \ + " 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 "" #endif @@ -402,10 +406,6 @@ int main(void) " read_timeout=%%d default: 0 ms (no timeout)\n" \ " max_resend=%%d default: 0 (no resend on timeout)\n" \ " skip_close_notify=%%d default: 0 (send close_notify)\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" \ "\n" \ USAGE_DTLS \ USAGE_CID \ @@ -2574,6 +2574,7 @@ usage: } #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ +#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) 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) { @@ -2596,6 +2597,7 @@ usage: mbedtls_printf("\n\n"); fflush(stdout); } +#endif /* defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) */ /* * 6. Write the GET request diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 3bcee9a153..538d0d08e8 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -473,7 +473,11 @@ 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" \ + " 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 "" #endif @@ -521,10 +525,6 @@ int main(void) " event=%%d default: 0 (loop)\n" \ " options: 1 (level-triggered, implies nbio=1),\n" \ " read_timeout=%%d default: 0 ms (no timeout)\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" \ "\n" \ USAGE_DTLS \ USAGE_SRTP \ @@ -3656,6 +3656,7 @@ handshake: mbedtls_printf("\n"); } +#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) 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) { @@ -3678,6 +3679,7 @@ handshake: mbedtls_printf("\n\n"); fflush(stdout); } +#endif /* defined(MBEDTLS_SSL_CONTEXT_SERIALZIATION) */ #if defined(MBEDTLS_SSL_DTLS_SRTP) else if (opt.use_srtp != 0) { From 951b8868011366c8717e7136ba38cabf9d06cc72 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Fri, 25 Oct 2024 00:52:24 +0200 Subject: [PATCH 23/57] 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 --- include/mbedtls/mbedtls_config.h | 15 +++++++++++++++ include/mbedtls/ssl.h | 10 +++++++++- library/ssl_misc.h | 7 ++++--- library/ssl_tls.c | 7 +++---- programs/ssl/ssl_client2.c | 21 ++++++++++++++------- programs/ssl/ssl_server2.c | 15 +++++++++++---- 6 files changed, 56 insertions(+), 19 deletions(-) diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h index 45feb5eccb..76be29743c 100644 --- a/include/mbedtls/mbedtls_config.h +++ b/include/mbedtls/mbedtls_config.h @@ -1763,6 +1763,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 * diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 3da4ecaf61..ae5eb8de9a 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -729,6 +729,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 @@ -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. */ - #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 29254958fc..0fe2800949 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -1166,10 +1166,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 971821ae1b..d631420ad1 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -8669,7 +8669,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 @@ -10054,8 +10054,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, @@ -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 */ diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 8f7ae0419d..228e7f8761 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -347,11 +347,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 @@ -381,6 +377,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 \ @@ -471,6 +477,7 @@ int main(void) " otherwise. The expansion of the macro\n" \ " is printed if it is defined\n" \ USAGE_SERIALIZATION \ + USAGE_EXPORT \ "\n" /* @@ -2574,7 +2581,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) { @@ -2597,7 +2604,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 538d0d08e8..2b81fc18ef 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -473,13 +473,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 \ @@ -589,6 +595,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) \ @@ -3656,7 +3663,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) { @@ -3679,7 +3686,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) { From d97e0e8edca386c2161da4888a9464effed8c190 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Mon, 28 Oct 2024 13:14:39 +0100 Subject: [PATCH 24/57] Enable MBEDTLS_SSL_KEYING_MATERIAL_EXPORT by default Signed-off-by: Max Fillinger --- include/mbedtls/mbedtls_config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h index 76be29743c..df6dacf587 100644 --- a/include/mbedtls/mbedtls_config.h +++ b/include/mbedtls/mbedtls_config.h @@ -1774,9 +1774,9 @@ * 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(). + * Comment this macro to disable mbedtls_ssl_export_keying_material(). */ -//#define MBEDTLS_SSL_KEYING_MATERIAL_EXPORT +#define MBEDTLS_SSL_KEYING_MATERIAL_EXPORT /** * \def MBEDTLS_SSL_RENEGOTIATION From 8fa72523be15cd40e87140d21cc0777f95e83c0f Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Mon, 28 Oct 2024 14:44:25 +0100 Subject: [PATCH 25/57] Fix #endif comment Signed-off-by: Max Fillinger --- library/ssl_misc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 0fe2800949..faa1b5ec05 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -1174,7 +1174,7 @@ struct mbedtls_ssl_transform { unsigned char randbytes[MBEDTLS_SERVER_HELLO_RANDOM_LEN + MBEDTLS_CLIENT_HELLO_RANDOM_LEN]; /*!< ServerHello.random+ClientHello.random */ -#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */ +#endif /* defined(MBEDTLS_SSL_KEEP_RANDBYTES) */ }; /* From 1bc2a9bdbf39948bf213cbe0c0f93903d47bdcee Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Mon, 28 Oct 2024 14:46:46 +0100 Subject: [PATCH 26/57] Mention MBEDTLS_SSL_KEYING_MATERIAL_EXPORT in change log Signed-off-by: Max Fillinger --- ChangeLog.d/add-tls-exporter.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog.d/add-tls-exporter.txt b/ChangeLog.d/add-tls-exporter.txt index 2b06c5f294..1aea653e09 100644 --- a/ChangeLog.d/add-tls-exporter.txt +++ b/ChangeLog.d/add-tls-exporter.txt @@ -2,3 +2,5 @@ Features * Add the function mbedtls_ssl_export_keying_material() which allows the client and server to extract additional shared symmetric keys from an SSL session, according to the TLS-Exporter specification in RFC 8446 and 5705. + This requires MBEDTLS_SSL_KEYING_MATERIAL_EXPORT to be defined in + mbedtls_config.h. From 9e23339ae98cda90605f48f7fa62619280330ba7 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Tue, 29 Oct 2024 16:57:09 +0100 Subject: [PATCH 27/57] Add more tests for keying material export Signed-off-by: Max Fillinger --- tests/include/test/ssl_helpers.h | 7 + tests/src/test_helpers/ssl_helpers.c | 49 ++++++ tests/suites/test_suite_ssl.data | 64 ++++++++ tests/suites/test_suite_ssl.function | 232 ++++++++++++++++++++++++++- 4 files changed, 351 insertions(+), 1 deletion(-) diff --git a/tests/include/test/ssl_helpers.h b/tests/include/test/ssl_helpers.h index 2da73ca3c0..31103ece19 100644 --- a/tests/include/test/ssl_helpers.h +++ b/tests/include/test/ssl_helpers.h @@ -596,6 +596,13 @@ int mbedtls_test_ssl_exchange_data( mbedtls_ssl_context *ssl_2, int msg_len_2, const int expected_fragments_2); +#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) +int mbedtls_test_ssl_do_handshake_with_endpoints( + mbedtls_test_ssl_endpoint *server_ep, + mbedtls_test_ssl_endpoint *client_ep, + mbedtls_ssl_protocol_version proto); +#endif /* defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) */ + #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) void mbedtls_test_ssl_perform_handshake( mbedtls_test_handshake_test_options *options); diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index 58b8362f01..770b0cbcd7 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -2037,6 +2037,55 @@ exit: } #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ +#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) +int mbedtls_test_ssl_do_handshake_with_endpoints( + mbedtls_test_ssl_endpoint *server_ep, + mbedtls_test_ssl_endpoint *client_ep, + mbedtls_ssl_protocol_version proto) +{ + enum { BUFFSIZE = 1024 }; + + int ret = -1; + mbedtls_test_handshake_test_options options; + + mbedtls_test_init_handshake_options(&options); + options.server_min_version = proto; + options.client_min_version = proto; + options.server_max_version = proto; + options.client_max_version = proto; + + ret = mbedtls_test_ssl_endpoint_init(client_ep, MBEDTLS_SSL_IS_CLIENT, &options, + NULL, NULL, NULL); + if (ret != 0) { + return ret; + } + ret = mbedtls_test_ssl_endpoint_init(server_ep, MBEDTLS_SSL_IS_SERVER, &options, + NULL, NULL, NULL); + if (ret != 0) { + return ret; + } + + ret = mbedtls_test_mock_socket_connect(&client_ep->socket, &server_ep->socket, BUFFSIZE); + if (ret != 0) { + return ret; + } + + ret = mbedtls_test_move_handshake_to_state(&server_ep->ssl, &client_ep->ssl, MBEDTLS_SSL_HANDSHAKE_OVER); + if (ret != 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + return ret; + } + ret = mbedtls_test_move_handshake_to_state(&client_ep->ssl, &server_ep->ssl, MBEDTLS_SSL_HANDSHAKE_OVER); + if (ret != 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + return ret; + } + if (!mbedtls_ssl_is_handshake_over(&client_ep->ssl) || !mbedtls_ssl_is_handshake_over(&server_ep->ssl)) { + return -1; + } + + return 0; +} +#endif /* defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) */ + #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) void mbedtls_test_ssl_perform_handshake( mbedtls_test_handshake_test_options *options) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index d54383b035..37d2d4d76b 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3450,3 +3450,67 @@ tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:3:3 TLS 1.3 srv, max early data size, HRR, 98, wsz=49 tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:97:0 + +TLS 1.2 Keying Material Exporter: Consistent results, no context +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_2:24:0 + +TLS 1.2 Keying Material Exporter: Consistent results, with context +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_2:24:1 + +TLS 1.2 Keying Material Exporter: Consistent results, large keys +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_2:UINT16_MAX:0 + +TLS 1.2 Keying Material Exporter: Uses label +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +ssl_tls_exporter_uses_label:MBEDTLS_SSL_VERSION_TLS1_2 + +TLS 1.2 Keying Material Exporter: Uses context +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +ssl_tls_exporter_uses_context:MBEDTLS_SSL_VERSION_TLS1_2 + +TLS 1.2 Keying Material Exporter: Context too long +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +ssl_tls_exporter_rejects_bad_parameters:MBEDTLS_SSL_VERSION_TLS1_2:24:251:UINT16_MAX + 1 + +TLS 1.2 Keying Material Exporter: Handshake not done +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +ssl_tls_exporter_too_early:MBEDTLS_SSL_VERSION_TLS1_2:1:MBEDTLS_SSL_SERVER_CERTIFICATE + +TLS 1.3 Keying Material Exporter: Consistent results, no context +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:24:0 + +TLS 1.3 Keying Material Exporter: Consistent results, with context +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:24:1 + +TLS 1.3 Keying Material Exporter: Consistent results, large keys +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:UINT16_MAX:0 + +TLS 1.3 Keying Material Exporter: Uses label +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +ssl_tls_exporter_uses_label:MBEDTLS_SSL_VERSION_TLS1_3 + +TLS 1.3 Keying Material Exporter: Uses context +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +ssl_tls_exporter_uses_context:MBEDTLS_SSL_VERSION_TLS1_3 + +TLS 1.3 Keying Material Exporter: Uses length +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +ssl_tls13_exporter_uses_length + +TLS 1.3 Keying Material Exporter: Exported key too long +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +ssl_tls_exporter_rejects_bad_parameters:MBEDTLS_SSL_VERSION_TLS1_3:UINT16_MAX + 1:20:20 + +TLS 1.3 Keying Material Exporter: Label too long +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +ssl_tls_exporter_rejects_bad_parameters:MBEDTLS_SSL_VERSION_TLS1_3:24:251:10 + +TLS 1.3 Keying Material Exporter: Handshake not done +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +ssl_tls_exporter_too_early:MBEDTLS_SSL_VERSION_TLS1_3:1:MBEDTLS_SSL_SERVER_CERTIFICATE diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index d2aec06859..332e16ac6c 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -1964,7 +1964,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3 */ +/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT */ void ssl_tls13_exporter(int hash_alg, data_t *secret, char *label, @@ -5726,3 +5726,233 @@ exit: PSA_DONE(); } /* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT */ +void ssl_tls_exporter_consistent_result(int proto, int exported_key_length, int use_context) +{ + /* Test that the client and server generate the same key. */ + + int ret = -1; + uint8_t *key_buffer_server = NULL; + uint8_t *key_buffer_client = NULL; + mbedtls_test_ssl_endpoint client_ep, server_ep; + + MD_OR_USE_PSA_INIT(); + + ret = mbedtls_test_ssl_do_handshake_with_endpoints(&server_ep, &client_ep, proto); + TEST_ASSERT(ret == 0); + + TEST_ASSERT(exported_key_length > 0); + TEST_CALLOC(key_buffer_server, exported_key_length); + TEST_CALLOC(key_buffer_client, exported_key_length); + + char label[] = "test-label"; + unsigned char context[128] = { 0 }; + ret = mbedtls_ssl_export_keying_material(&server_ep.ssl, + key_buffer_server, (size_t)exported_key_length, + label, sizeof(label), + context, sizeof(context), use_context); + TEST_ASSERT(ret == 0); + ret = mbedtls_ssl_export_keying_material(&client_ep.ssl, + key_buffer_client, (size_t)exported_key_length, + label, sizeof(label), + context, sizeof(context), use_context); + TEST_ASSERT(ret == 0); + TEST_ASSERT(memcmp(key_buffer_server, key_buffer_client, (size_t)exported_key_length) == 0); + +exit: + MD_OR_USE_PSA_DONE(); + mbedtls_free(key_buffer_server); + mbedtls_free(key_buffer_client); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT */ +void ssl_tls_exporter_uses_label(int proto) +{ + /* Test that the client and server export different keys when using different labels. */ + + int ret = -1; + mbedtls_test_ssl_endpoint client_ep, server_ep; + + MD_OR_USE_PSA_INIT(); + + ret = mbedtls_test_ssl_do_handshake_with_endpoints(&server_ep, &client_ep, proto); + TEST_ASSERT(ret == 0); + + char label_server[] = "test-label-server"; + char label_client[] = "test-label-client"; + uint8_t key_buffer_server[24] = { 0 }; + uint8_t key_buffer_client[24] = { 0 }; + unsigned char context[128] = { 0 }; + ret = mbedtls_ssl_export_keying_material(&server_ep.ssl, + key_buffer_server, sizeof(key_buffer_server), + label_server, sizeof(label_server), + context, sizeof(context), 1); + TEST_ASSERT(ret == 0); + ret = mbedtls_ssl_export_keying_material(&client_ep.ssl, + key_buffer_client, sizeof(key_buffer_client), + label_client, sizeof(label_client), + context, sizeof(context), 1); + TEST_ASSERT(ret == 0); + TEST_ASSERT(memcmp(key_buffer_server, key_buffer_client, sizeof(key_buffer_server)) != 0); + +exit: + MD_OR_USE_PSA_DONE(); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT */ +void ssl_tls_exporter_uses_context(int proto) +{ + /* Test that the client and server export different keys when using different contexts. */ + + int ret = -1; + mbedtls_test_ssl_endpoint client_ep, server_ep; + + MD_OR_USE_PSA_INIT(); + + ret = mbedtls_test_ssl_do_handshake_with_endpoints(&server_ep, &client_ep, proto); + TEST_ASSERT(ret == 0); + + char label[] = "test-label"; + uint8_t key_buffer_server[24] = { 0 }; + uint8_t key_buffer_client[24] = { 0 }; + unsigned char context_server[128] = { 0 }; + unsigned char context_client[128] = { 23 }; + ret = mbedtls_ssl_export_keying_material(&server_ep.ssl, + key_buffer_server, sizeof(key_buffer_server), + label, sizeof(label), + context_server, sizeof(context_server), 1); + TEST_ASSERT(ret == 0); + ret = mbedtls_ssl_export_keying_material(&client_ep.ssl, + key_buffer_client, sizeof(key_buffer_client), + label, sizeof(label), + context_client, sizeof(context_client), 1); + TEST_ASSERT(ret == 0); + TEST_ASSERT(memcmp(key_buffer_server, key_buffer_client, sizeof(key_buffer_server)) != 0); + +exit: + MD_OR_USE_PSA_DONE(); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT */ +void ssl_tls13_exporter_uses_length(void) +{ + /* In TLS 1.3, when two keys are exported with the same parameters except one is shorter, + * the shorter key should NOT be a prefix of the longer one. */ + + int ret = -1; + mbedtls_test_ssl_endpoint client_ep, server_ep; + + MD_OR_USE_PSA_INIT(); + + ret = mbedtls_test_ssl_do_handshake_with_endpoints(&server_ep, &client_ep, MBEDTLS_SSL_VERSION_TLS1_3); + TEST_ASSERT(ret == 0); + + char label[] = "test-label"; + uint8_t key_buffer_server[16] = { 0 }; + uint8_t key_buffer_client[24] = { 0 }; + unsigned char context[128] = { 0 }; + ret = mbedtls_ssl_export_keying_material(&server_ep.ssl, + key_buffer_server, sizeof(key_buffer_server), + label, sizeof(label), + context, sizeof(context), 1); + TEST_ASSERT(ret == 0); + ret = mbedtls_ssl_export_keying_material(&client_ep.ssl, + key_buffer_client, sizeof(key_buffer_client), + label, sizeof(label), + context, sizeof(context), 1); + TEST_ASSERT(ret == 0); + TEST_ASSERT(memcmp(key_buffer_server, key_buffer_client, sizeof(key_buffer_server)) != 0); + +exit: + MD_OR_USE_PSA_DONE(); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT */ +void ssl_tls_exporter_rejects_bad_parameters( + int proto, int exported_key_length, int label_length, int context_length) +{ + MD_OR_USE_PSA_INIT(); + + int ret = -1; + uint8_t *key_buffer = NULL; + char *label = NULL; + uint8_t *context = NULL; + mbedtls_test_ssl_endpoint client_ep, server_ep; + + TEST_ASSERT(exported_key_length > 0); + TEST_ASSERT(label_length > 0); + TEST_ASSERT(context_length > 0); + TEST_CALLOC(key_buffer, exported_key_length); + TEST_CALLOC(label, label_length); + TEST_CALLOC(context, context_length); + + ret = mbedtls_test_ssl_do_handshake_with_endpoints(&server_ep, &client_ep, proto); + TEST_ASSERT(ret == 0); + + ret = mbedtls_ssl_export_keying_material(&client_ep.ssl, + key_buffer, exported_key_length, + label, label_length, + context, context_length, 1); + TEST_ASSERT(ret == MBEDTLS_ERR_SSL_BAD_INPUT_DATA); + +exit: + MD_OR_USE_PSA_DONE(); + mbedtls_free(key_buffer); + mbedtls_free(label); + mbedtls_free(context); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT */ +void ssl_tls_exporter_too_early(int proto, int check_server, int state) +{ + enum { BUFFSIZE = 1024 }; + + int ret = -1; + mbedtls_test_ssl_endpoint server_ep, client_ep; + + mbedtls_test_handshake_test_options options; + mbedtls_test_init_handshake_options(&options); + options.server_min_version = proto; + options.client_min_version = proto; + options.server_max_version = proto; + options.client_max_version = proto; + + MD_OR_USE_PSA_INIT(); + + ret = mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER, &options, + NULL, NULL, NULL); + TEST_ASSERT(ret == 0); + ret = mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT, &options, + NULL, NULL, NULL); + TEST_ASSERT(ret == 0); + + ret = mbedtls_test_mock_socket_connect(&client_ep.socket, &server_ep.socket, BUFFSIZE); + TEST_ASSERT(ret == 0); + + if (check_server) { + ret = mbedtls_test_move_handshake_to_state(&server_ep.ssl, &client_ep.ssl, state); + } else { + ret = mbedtls_test_move_handshake_to_state(&client_ep.ssl, &server_ep.ssl, state); + } + TEST_ASSERT(ret == 0 || ret == MBEDTLS_ERR_SSL_WANT_READ || MBEDTLS_ERR_SSL_WANT_WRITE); + + char label[] = "test-label"; + uint8_t key_buffer[24] = { 0 }; + ret = mbedtls_ssl_export_keying_material(check_server ? &server_ep.ssl : &client_ep.ssl, + key_buffer, sizeof(key_buffer), + label, sizeof(label), + NULL, 0, 0); + + /* FIXME: A more appropriate error code should be created for this case. */ + TEST_ASSERT(ret == MBEDTLS_ERR_SSL_BAD_INPUT_DATA); + +exit: + MD_OR_USE_PSA_DONE(); +} +/* END_CASE */ From ffc47e6e2b02f576284cc2b9c214550196d1f6b0 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Tue, 29 Oct 2024 18:49:30 +0100 Subject: [PATCH 28/57] Increase allowed output size of HKDF-Expand-Label Signed-off-by: Max Fillinger --- library/ssl_tls13_keys.c | 12 +++++------- library/ssl_tls13_keys.h | 12 +++++------- tests/suites/test_suite_ssl.data | 2 +- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c index e0a866944c..4a7ca4f1ab 100644 --- a/library/ssl_tls13_keys.c +++ b/library/ssl_tls13_keys.c @@ -109,15 +109,13 @@ static void ssl_tls13_hkdf_encode_label( unsigned char *p = dst; - /* Add the size of the expanded key material. - * We're hardcoding the high byte to 0 here assuming that we never use - * TLS 1.3 HKDF key expansion to more than 255 Bytes. */ -#if MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN > 255 -#error "The implementation of ssl_tls13_hkdf_encode_label() is not fit for the \ - value of MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN" + /* Add the size of the expanded key material. */ +#if MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN > UINT16_MAX +#error "The desired key length must fit into an uint16 but \ + MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN is greater than UINT16_MAX" #endif - *p++ = 0; + *p++ = MBEDTLS_BYTE_1(desired_length); *p++ = MBEDTLS_BYTE_0(desired_length); /* Add label incl. prefix */ diff --git a/library/ssl_tls13_keys.h b/library/ssl_tls13_keys.h index a4b012f36e..31ffe4481e 100644 --- a/library/ssl_tls13_keys.h +++ b/library/ssl_tls13_keys.h @@ -70,13 +70,11 @@ extern const struct mbedtls_ssl_tls13_labels_struct mbedtls_ssl_tls13_labels; PSA_HASH_MAX_SIZE /* Maximum desired length for expanded key material generated - * by HKDF-Expand-Label. - * - * Warning: If this ever needs to be increased, the implementation - * ssl_tls13_hkdf_encode_label() in ssl_tls13_keys.c needs to be - * adjusted since it currently assumes that HKDF key expansion - * is never used with more than 255 Bytes of output. */ -#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN 255 + * by HKDF-Expand-Label. This algorithm can output up to 255 * hash_size + * bytes of key material where hash_size is the output size of the + * underlying hash function. */ +#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN \ + (255 * MBEDTLS_TLS1_3_MD_MAX_SIZE) /** * \brief The \c HKDF-Expand-Label function from diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 37d2d4d76b..b566d7cf16 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3489,7 +3489,7 @@ ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:24:1 TLS 1.3 Keying Material Exporter: Consistent results, large keys depends_on:MBEDTLS_SSL_PROTO_TLS1_3 -ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:UINT16_MAX:0 +ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:1024:0 TLS 1.3 Keying Material Exporter: Uses label depends_on:MBEDTLS_SSL_PROTO_TLS1_3 From e95edbf6c531bca861e64e16cfaa98749110a98f Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Tue, 29 Oct 2024 19:18:54 +0100 Subject: [PATCH 29/57] Fix output size check for key material exporter HKDF-Expand can produce at most 255 * hash_size bytes of key material, so this limit applies to the TLS 1.3 key material exporter. Signed-off-by: Max Fillinger --- include/mbedtls/ssl.h | 3 ++- library/ssl_tls.c | 15 ++++++++++----- tests/suites/test_suite_ssl.data | 4 ++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index ae5eb8de9a..c9f9325961 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -5780,7 +5780,8 @@ int mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf, * * \param ssl SSL context from which to export keys. Must have finished the handshake. * \param out Output buffer of length at least key_len bytes. - * \param key_len Length of the key to generate in bytes. Must be < 2^16 in TLS 1.3. + * \param key_len Length of the key to generate in bytes. In TLS 1.3, this can be at most + * 8160 if SHA256 is used as hash function or 12240 if SHA384 is used. * \param label Label for which to generate the key of length label_len. * \param label_len Length of label in bytes. Must be < 251 in TLS 1.3. * \param context Context of the key. Can be NULL if context_len or use_context is 0. diff --git a/library/ssl_tls.c b/library/ssl_tls.c index d631420ad1..82cb36c5c9 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -10124,11 +10124,16 @@ static int mbedtls_ssl_tls13_export_keying_material(mbedtls_ssl_context *ssl, const size_t hash_len = PSA_HASH_LENGTH(hash_alg); const unsigned char *secret = ssl->session->app_secrets.exporter_master_secret; - /* Check that the label and key_len fit into the HkdfLabel struct as defined - * in RFC 8446, Section 7.1. key_len must fit into an uint16 and the label - * must be at most 250 bytes long. (The struct allows up to 256 bytes for - * the label, but it is prefixed with "tls13 ".) */ - if (key_len > UINT16_MAX || label_len > 250) { + /* Validate the length of the label and the desired key length. The key + * length can be at most 255 * hash_len by definition of HKDF-Expand in + * RFC 5869. + * + * The length of the label must be at most 250 bytes long to fit into the + * HkdfLabel struct as defined in RFC 8446, Section 7.1. This struct also + * requires that key_len fits into a uint16, but until we have to deal with + * a hash function with more than 2048 bits of output, the 255 * hash_len + * limit will guarantee that. */ + if (key_len > 255 * hash_len || label_len > 250) { return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; } diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index b566d7cf16..79e56b4a81 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3489,7 +3489,7 @@ ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:24:1 TLS 1.3 Keying Material Exporter: Consistent results, large keys depends_on:MBEDTLS_SSL_PROTO_TLS1_3 -ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:1024:0 +ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:255 * 32:0 TLS 1.3 Keying Material Exporter: Uses label depends_on:MBEDTLS_SSL_PROTO_TLS1_3 @@ -3505,7 +3505,7 @@ ssl_tls13_exporter_uses_length TLS 1.3 Keying Material Exporter: Exported key too long depends_on:MBEDTLS_SSL_PROTO_TLS1_3 -ssl_tls_exporter_rejects_bad_parameters:MBEDTLS_SSL_VERSION_TLS1_3:UINT16_MAX + 1:20:20 +ssl_tls_exporter_rejects_bad_parameters:MBEDTLS_SSL_VERSION_TLS1_3:255 * 48 + 1:20:20 TLS 1.3 Keying Material Exporter: Label too long depends_on:MBEDTLS_SSL_PROTO_TLS1_3 From 436cc20378a49099721a4042e4b46c40f9e04359 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Wed, 30 Oct 2024 00:29:37 +0100 Subject: [PATCH 30/57] Exportert tests: Free endpoints and options Signed-off-by: Max Fillinger --- tests/include/test/ssl_helpers.h | 1 + tests/src/test_helpers/ssl_helpers.c | 16 +++++++------- tests/suites/test_suite_ssl.function | 33 +++++++++++++++++++++++----- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/tests/include/test/ssl_helpers.h b/tests/include/test/ssl_helpers.h index 31103ece19..33ed2a883d 100644 --- a/tests/include/test/ssl_helpers.h +++ b/tests/include/test/ssl_helpers.h @@ -600,6 +600,7 @@ int mbedtls_test_ssl_exchange_data( int mbedtls_test_ssl_do_handshake_with_endpoints( mbedtls_test_ssl_endpoint *server_ep, mbedtls_test_ssl_endpoint *client_ep, + mbedtls_test_handshake_test_options *options, mbedtls_ssl_protocol_version proto); #endif /* defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) */ diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index 770b0cbcd7..e7b80b1dba 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -2041,25 +2041,25 @@ exit: int mbedtls_test_ssl_do_handshake_with_endpoints( mbedtls_test_ssl_endpoint *server_ep, mbedtls_test_ssl_endpoint *client_ep, + mbedtls_test_handshake_test_options *options, mbedtls_ssl_protocol_version proto) { enum { BUFFSIZE = 1024 }; int ret = -1; - mbedtls_test_handshake_test_options options; - mbedtls_test_init_handshake_options(&options); - options.server_min_version = proto; - options.client_min_version = proto; - options.server_max_version = proto; - options.client_max_version = proto; + mbedtls_test_init_handshake_options(options); + options->server_min_version = proto; + options->client_min_version = proto; + options->server_max_version = proto; + options->client_max_version = proto; - ret = mbedtls_test_ssl_endpoint_init(client_ep, MBEDTLS_SSL_IS_CLIENT, &options, + ret = mbedtls_test_ssl_endpoint_init(client_ep, MBEDTLS_SSL_IS_CLIENT, options, NULL, NULL, NULL); if (ret != 0) { return ret; } - ret = mbedtls_test_ssl_endpoint_init(server_ep, MBEDTLS_SSL_IS_SERVER, &options, + ret = mbedtls_test_ssl_endpoint_init(server_ep, MBEDTLS_SSL_IS_SERVER, options, NULL, NULL, NULL); if (ret != 0) { return ret; diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 332e16ac6c..0925a06137 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -5736,10 +5736,11 @@ void ssl_tls_exporter_consistent_result(int proto, int exported_key_length, int uint8_t *key_buffer_server = NULL; uint8_t *key_buffer_client = NULL; mbedtls_test_ssl_endpoint client_ep, server_ep; + mbedtls_test_handshake_test_options options; MD_OR_USE_PSA_INIT(); - ret = mbedtls_test_ssl_do_handshake_with_endpoints(&server_ep, &client_ep, proto); + ret = mbedtls_test_ssl_do_handshake_with_endpoints(&server_ep, &client_ep, &options, proto); TEST_ASSERT(ret == 0); TEST_ASSERT(exported_key_length > 0); @@ -5762,6 +5763,9 @@ void ssl_tls_exporter_consistent_result(int proto, int exported_key_length, int exit: MD_OR_USE_PSA_DONE(); + mbedtls_test_ssl_endpoint_free(&server_ep, NULL); + mbedtls_test_ssl_endpoint_free(&client_ep, NULL); + mbedtls_test_free_handshake_options(&options); mbedtls_free(key_buffer_server); mbedtls_free(key_buffer_client); } @@ -5774,10 +5778,11 @@ void ssl_tls_exporter_uses_label(int proto) int ret = -1; mbedtls_test_ssl_endpoint client_ep, server_ep; + mbedtls_test_handshake_test_options options; MD_OR_USE_PSA_INIT(); - ret = mbedtls_test_ssl_do_handshake_with_endpoints(&server_ep, &client_ep, proto); + ret = mbedtls_test_ssl_do_handshake_with_endpoints(&server_ep, &client_ep, &options, proto); TEST_ASSERT(ret == 0); char label_server[] = "test-label-server"; @@ -5798,6 +5803,9 @@ void ssl_tls_exporter_uses_label(int proto) TEST_ASSERT(memcmp(key_buffer_server, key_buffer_client, sizeof(key_buffer_server)) != 0); exit: + mbedtls_test_ssl_endpoint_free(&server_ep, NULL); + mbedtls_test_ssl_endpoint_free(&client_ep, NULL); + mbedtls_test_free_handshake_options(&options); MD_OR_USE_PSA_DONE(); } /* END_CASE */ @@ -5809,10 +5817,11 @@ void ssl_tls_exporter_uses_context(int proto) int ret = -1; mbedtls_test_ssl_endpoint client_ep, server_ep; + mbedtls_test_handshake_test_options options; MD_OR_USE_PSA_INIT(); - ret = mbedtls_test_ssl_do_handshake_with_endpoints(&server_ep, &client_ep, proto); + ret = mbedtls_test_ssl_do_handshake_with_endpoints(&server_ep, &client_ep, &options, proto); TEST_ASSERT(ret == 0); char label[] = "test-label"; @@ -5833,6 +5842,9 @@ void ssl_tls_exporter_uses_context(int proto) TEST_ASSERT(memcmp(key_buffer_server, key_buffer_client, sizeof(key_buffer_server)) != 0); exit: + mbedtls_test_ssl_endpoint_free(&server_ep, NULL); + mbedtls_test_ssl_endpoint_free(&client_ep, NULL); + mbedtls_test_free_handshake_options(&options); MD_OR_USE_PSA_DONE(); } /* END_CASE */ @@ -5845,10 +5857,11 @@ void ssl_tls13_exporter_uses_length(void) int ret = -1; mbedtls_test_ssl_endpoint client_ep, server_ep; + mbedtls_test_handshake_test_options options; MD_OR_USE_PSA_INIT(); - ret = mbedtls_test_ssl_do_handshake_with_endpoints(&server_ep, &client_ep, MBEDTLS_SSL_VERSION_TLS1_3); + ret = mbedtls_test_ssl_do_handshake_with_endpoints(&server_ep, &client_ep, &options, MBEDTLS_SSL_VERSION_TLS1_3); TEST_ASSERT(ret == 0); char label[] = "test-label"; @@ -5868,6 +5881,9 @@ void ssl_tls13_exporter_uses_length(void) TEST_ASSERT(memcmp(key_buffer_server, key_buffer_client, sizeof(key_buffer_server)) != 0); exit: + mbedtls_test_ssl_endpoint_free(&server_ep, NULL); + mbedtls_test_ssl_endpoint_free(&client_ep, NULL); + mbedtls_test_free_handshake_options(&options); MD_OR_USE_PSA_DONE(); } /* END_CASE */ @@ -5883,6 +5899,7 @@ void ssl_tls_exporter_rejects_bad_parameters( char *label = NULL; uint8_t *context = NULL; mbedtls_test_ssl_endpoint client_ep, server_ep; + mbedtls_test_handshake_test_options options; TEST_ASSERT(exported_key_length > 0); TEST_ASSERT(label_length > 0); @@ -5891,7 +5908,7 @@ void ssl_tls_exporter_rejects_bad_parameters( TEST_CALLOC(label, label_length); TEST_CALLOC(context, context_length); - ret = mbedtls_test_ssl_do_handshake_with_endpoints(&server_ep, &client_ep, proto); + ret = mbedtls_test_ssl_do_handshake_with_endpoints(&server_ep, &client_ep, &options, proto); TEST_ASSERT(ret == 0); ret = mbedtls_ssl_export_keying_material(&client_ep.ssl, @@ -5902,6 +5919,9 @@ void ssl_tls_exporter_rejects_bad_parameters( exit: MD_OR_USE_PSA_DONE(); + mbedtls_test_ssl_endpoint_free(&server_ep, NULL); + mbedtls_test_ssl_endpoint_free(&client_ep, NULL); + mbedtls_test_free_handshake_options(&options); mbedtls_free(key_buffer); mbedtls_free(label); mbedtls_free(context); @@ -5954,5 +5974,8 @@ void ssl_tls_exporter_too_early(int proto, int check_server, int state) exit: MD_OR_USE_PSA_DONE(); + mbedtls_test_ssl_endpoint_free(&server_ep, NULL); + mbedtls_test_ssl_endpoint_free(&client_ep, NULL); + mbedtls_test_free_handshake_options(&options); } /* END_CASE */ From e8251103915e5b564b037febfd1ab58066891e4f Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Wed, 30 Oct 2024 00:39:54 +0100 Subject: [PATCH 31/57] Exporter tests: Initialize allocated memory Signed-off-by: Max Fillinger --- tests/suites/test_suite_ssl.function | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 0925a06137..43a65d338c 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -5747,6 +5747,9 @@ void ssl_tls_exporter_consistent_result(int proto, int exported_key_length, int TEST_CALLOC(key_buffer_server, exported_key_length); TEST_CALLOC(key_buffer_client, exported_key_length); + memset(key_buffer_server, 0, exported_key_length); + memset(key_buffer_client, 0, exported_key_length); + char label[] = "test-label"; unsigned char context[128] = { 0 }; ret = mbedtls_ssl_export_keying_material(&server_ep.ssl, @@ -5908,6 +5911,10 @@ void ssl_tls_exporter_rejects_bad_parameters( TEST_CALLOC(label, label_length); TEST_CALLOC(context, context_length); + memset(key_buffer, 0, exported_key_length); + memset(label, 0, label_length); + memset(context, 0, context_length); + ret = mbedtls_test_ssl_do_handshake_with_endpoints(&server_ep, &client_ep, &options, proto); TEST_ASSERT(ret == 0); From 538ed71ecb1ba00e7e8b58b03e0bfabd2df3dbb0 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Wed, 30 Oct 2024 00:49:10 +0100 Subject: [PATCH 32/57] Coding style cleanup Signed-off-by: Max Fillinger --- tests/src/test_helpers/ssl_helpers.c | 11 ++++++++--- tests/suites/test_suite_ssl.function | 11 +++++++---- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index e7b80b1dba..2ad1c370d1 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -2070,15 +2070,20 @@ int mbedtls_test_ssl_do_handshake_with_endpoints( return ret; } - ret = mbedtls_test_move_handshake_to_state(&server_ep->ssl, &client_ep->ssl, MBEDTLS_SSL_HANDSHAKE_OVER); + ret = mbedtls_test_move_handshake_to_state(&server_ep->ssl, + &client_ep->ssl, + MBEDTLS_SSL_HANDSHAKE_OVER); if (ret != 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { return ret; } - ret = mbedtls_test_move_handshake_to_state(&client_ep->ssl, &server_ep->ssl, MBEDTLS_SSL_HANDSHAKE_OVER); + ret = mbedtls_test_move_handshake_to_state(&client_ep->ssl, + &server_ep->ssl, + MBEDTLS_SSL_HANDSHAKE_OVER); if (ret != 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { return ret; } - if (!mbedtls_ssl_is_handshake_over(&client_ep->ssl) || !mbedtls_ssl_is_handshake_over(&server_ep->ssl)) { + if (!mbedtls_ssl_is_handshake_over(&client_ep->ssl) || + !mbedtls_ssl_is_handshake_over(&server_ep->ssl)) { return -1; } diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 43a65d338c..88fa71b7f1 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -5753,16 +5753,16 @@ void ssl_tls_exporter_consistent_result(int proto, int exported_key_length, int char label[] = "test-label"; unsigned char context[128] = { 0 }; ret = mbedtls_ssl_export_keying_material(&server_ep.ssl, - key_buffer_server, (size_t)exported_key_length, + key_buffer_server, (size_t) exported_key_length, label, sizeof(label), context, sizeof(context), use_context); TEST_ASSERT(ret == 0); ret = mbedtls_ssl_export_keying_material(&client_ep.ssl, - key_buffer_client, (size_t)exported_key_length, + key_buffer_client, (size_t) exported_key_length, label, sizeof(label), context, sizeof(context), use_context); TEST_ASSERT(ret == 0); - TEST_ASSERT(memcmp(key_buffer_server, key_buffer_client, (size_t)exported_key_length) == 0); + TEST_ASSERT(memcmp(key_buffer_server, key_buffer_client, (size_t) exported_key_length) == 0); exit: MD_OR_USE_PSA_DONE(); @@ -5864,7 +5864,10 @@ void ssl_tls13_exporter_uses_length(void) MD_OR_USE_PSA_INIT(); - ret = mbedtls_test_ssl_do_handshake_with_endpoints(&server_ep, &client_ep, &options, MBEDTLS_SSL_VERSION_TLS1_3); + ret = mbedtls_test_ssl_do_handshake_with_endpoints(&server_ep, + &client_ep, + &options, + MBEDTLS_SSL_VERSION_TLS1_3); TEST_ASSERT(ret == 0); char label[] = "test-label"; From 81b41d40dc2d76dac7f3b7387c85b032ef21f253 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Wed, 30 Oct 2024 18:58:50 +0100 Subject: [PATCH 33/57] Exporter tests: Fix possible uninitialized variable use Signed-off-by: Max Fillinger --- tests/suites/test_suite_ssl.function | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 88fa71b7f1..e0e1a433bf 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -5898,8 +5898,6 @@ exit: void ssl_tls_exporter_rejects_bad_parameters( int proto, int exported_key_length, int label_length, int context_length) { - MD_OR_USE_PSA_INIT(); - int ret = -1; uint8_t *key_buffer = NULL; char *label = NULL; @@ -5914,9 +5912,7 @@ void ssl_tls_exporter_rejects_bad_parameters( TEST_CALLOC(label, label_length); TEST_CALLOC(context, context_length); - memset(key_buffer, 0, exported_key_length); - memset(label, 0, label_length); - memset(context, 0, context_length); + MD_OR_USE_PSA_INIT(); ret = mbedtls_test_ssl_do_handshake_with_endpoints(&server_ep, &client_ep, &options, proto); TEST_ASSERT(ret == 0); From 20e4ac8b3ea23aec835a5f5f825ecfaf3d73095c Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Thu, 31 Oct 2024 12:43:19 +0100 Subject: [PATCH 34/57] Exporter tests: Free endpoints before PSA_DONE() Signed-off-by: Max Fillinger --- tests/suites/test_suite_ssl.function | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index e0e1a433bf..2625850608 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -5765,12 +5765,12 @@ void ssl_tls_exporter_consistent_result(int proto, int exported_key_length, int TEST_ASSERT(memcmp(key_buffer_server, key_buffer_client, (size_t) exported_key_length) == 0); exit: - MD_OR_USE_PSA_DONE(); mbedtls_test_ssl_endpoint_free(&server_ep, NULL); mbedtls_test_ssl_endpoint_free(&client_ep, NULL); mbedtls_test_free_handshake_options(&options); mbedtls_free(key_buffer_server); mbedtls_free(key_buffer_client); + MD_OR_USE_PSA_DONE(); } /* END_CASE */ @@ -5924,13 +5924,13 @@ void ssl_tls_exporter_rejects_bad_parameters( TEST_ASSERT(ret == MBEDTLS_ERR_SSL_BAD_INPUT_DATA); exit: - MD_OR_USE_PSA_DONE(); mbedtls_test_ssl_endpoint_free(&server_ep, NULL); mbedtls_test_ssl_endpoint_free(&client_ep, NULL); mbedtls_test_free_handshake_options(&options); mbedtls_free(key_buffer); mbedtls_free(label); mbedtls_free(context); + MD_OR_USE_PSA_DONE(); } /* END_CASE */ @@ -5979,9 +5979,9 @@ void ssl_tls_exporter_too_early(int proto, int check_server, int state) TEST_ASSERT(ret == MBEDTLS_ERR_SSL_BAD_INPUT_DATA); exit: - MD_OR_USE_PSA_DONE(); mbedtls_test_ssl_endpoint_free(&server_ep, NULL); mbedtls_test_ssl_endpoint_free(&client_ep, NULL); mbedtls_test_free_handshake_options(&options); + MD_OR_USE_PSA_DONE(); } /* END_CASE */ From fb7e57868984d8bab4e908ff244cd5ddd7bdf681 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Thu, 31 Oct 2024 15:31:55 +0100 Subject: [PATCH 35/57] Exporter tests: Reduce key size in long key tests Signed-off-by: Max Fillinger --- tests/suites/test_suite_ssl.data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 79e56b4a81..d6706c4856 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3461,7 +3461,7 @@ ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_2:24:1 TLS 1.2 Keying Material Exporter: Consistent results, large keys depends_on:MBEDTLS_SSL_PROTO_TLS1_2 -ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_2:UINT16_MAX:0 +ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_2:255 * 32:0 TLS 1.2 Keying Material Exporter: Uses label depends_on:MBEDTLS_SSL_PROTO_TLS1_2 From 8ee21410f143df2c2682676e3a406f87ea561d5e Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Fri, 1 Nov 2024 16:05:34 +0100 Subject: [PATCH 36/57] Use one maximum key_len for all exported keys Signed-off-by: Max Fillinger --- include/mbedtls/ssl.h | 14 ++++++++++---- library/ssl_tls.c | 19 ++++++++++--------- tests/suites/test_suite_ssl.data | 6 +++--- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index c9f9325961..649dc75a7d 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -5775,15 +5775,22 @@ int mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf, const unsigned char *random, size_t rlen, unsigned char *dstbuf, size_t dlen); +#if defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) +/* Maximum value for key_len in mbedtls_ssl_export_keying material. Depending on the TLS + * version and the negotiated ciphersuite, larger keys could in principle be exported, + * but for simplicity, we define one limit that works in all cases. TLS 1.3 with SHA256 + * has the strictest limit: 255 blocks of SHA256 output, or 8160 bytes. */ +#define MBEDTLS_SSL_EXPORT_MAX_KEY_LEN 8160 + /** * \brief TLS-Exporter to derive shared symmetric keys between server and client. * * \param ssl SSL context from which to export keys. Must have finished the handshake. * \param out Output buffer of length at least key_len bytes. - * \param key_len Length of the key to generate in bytes. In TLS 1.3, this can be at most - * 8160 if SHA256 is used as hash function or 12240 if SHA384 is used. + * \param key_len Length of the key to generate in bytes, must be at most + * MBEDTLS_SSL_EXPORT_MAX_KEY_LEN (8160). * \param label Label for which to generate the key of length label_len. - * \param label_len Length of label in bytes. Must be < 251 in TLS 1.3. + * \param label_len Length of label in bytes. Must be at most 250 in TLS 1.3. * \param context Context of the key. Can be NULL if context_len or use_context is 0. * \param context_len Length of context. Must be < 2^16 in TLS 1.2. * \param use_context Indicates if a context should be used in deriving the key. @@ -5795,7 +5802,6 @@ 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_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_tls.c b/library/ssl_tls.c index 82cb36c5c9..32fbe132cd 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -10124,16 +10124,13 @@ static int mbedtls_ssl_tls13_export_keying_material(mbedtls_ssl_context *ssl, const size_t hash_len = PSA_HASH_LENGTH(hash_alg); const unsigned char *secret = ssl->session->app_secrets.exporter_master_secret; - /* Validate the length of the label and the desired key length. The key - * length can be at most 255 * hash_len by definition of HKDF-Expand in - * RFC 5869. + /* The length of the label must be at most 250 bytes to fit into the HkdfLabel + * struct as defined in RFC 8446, Section 7.1. * - * The length of the label must be at most 250 bytes long to fit into the - * HkdfLabel struct as defined in RFC 8446, Section 7.1. This struct also - * requires that key_len fits into a uint16, but until we have to deal with - * a hash function with more than 2048 bits of output, the 255 * hash_len - * limit will guarantee that. */ - if (key_len > 255 * hash_len || label_len > 250) { + * The length of the context is unlimited even though the context field in the + * struct can only hold up to 256 bytes. This is because we place a *hash* of + * the context in the field. */ + if (label_len > 250) { return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; } @@ -10153,6 +10150,10 @@ int mbedtls_ssl_export_keying_material(mbedtls_ssl_context *ssl, return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; } + if (key_len > MBEDTLS_SSL_EXPORT_MAX_KEY_LEN) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + int ciphersuite_id = mbedtls_ssl_get_ciphersuite_id_from_ssl(ssl); const mbedtls_ssl_ciphersuite_t *ciphersuite = mbedtls_ssl_ciphersuite_from_id(ciphersuite_id); const mbedtls_md_type_t hash_alg = ciphersuite->mac; diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index d6706c4856..c50adf3e43 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3461,7 +3461,7 @@ ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_2:24:1 TLS 1.2 Keying Material Exporter: Consistent results, large keys depends_on:MBEDTLS_SSL_PROTO_TLS1_2 -ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_2:255 * 32:0 +ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_2:MBEDTLS_SSL_EXPORT_MAX_KEY_LEN:0 TLS 1.2 Keying Material Exporter: Uses label depends_on:MBEDTLS_SSL_PROTO_TLS1_2 @@ -3489,7 +3489,7 @@ ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:24:1 TLS 1.3 Keying Material Exporter: Consistent results, large keys depends_on:MBEDTLS_SSL_PROTO_TLS1_3 -ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:255 * 32:0 +ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:MBEDTLS_SSL_EXPORT_MAX_KEY_LEN:0 TLS 1.3 Keying Material Exporter: Uses label depends_on:MBEDTLS_SSL_PROTO_TLS1_3 @@ -3505,7 +3505,7 @@ ssl_tls13_exporter_uses_length TLS 1.3 Keying Material Exporter: Exported key too long depends_on:MBEDTLS_SSL_PROTO_TLS1_3 -ssl_tls_exporter_rejects_bad_parameters:MBEDTLS_SSL_VERSION_TLS1_3:255 * 48 + 1:20:20 +ssl_tls_exporter_rejects_bad_parameters:MBEDTLS_SSL_VERSION_TLS1_3:MBEDTLS_SSL_EXPORT_MAX_KEY_LEN + 1:20:20 TLS 1.3 Keying Material Exporter: Label too long depends_on:MBEDTLS_SSL_PROTO_TLS1_3 From 2c2a6ac64c3dcb4ee7ca49ee2d3c1eee31b895b8 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Fri, 1 Nov 2024 14:14:19 +0100 Subject: [PATCH 37/57] Exporter tests: Add missing depends-ons Signed-off-by: Max Fillinger --- tests/suites/test_suite_ssl.data | 32 ++++++++++++++-------------- tests/suites/test_suite_ssl.function | 12 +++++------ 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index c50adf3e43..3bd357313c 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3452,65 +3452,65 @@ TLS 1.3 srv, max early data size, HRR, 98, wsz=49 tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:97:0 TLS 1.2 Keying Material Exporter: Consistent results, no context -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_2:24:0 TLS 1.2 Keying Material Exporter: Consistent results, with context -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_2:24:1 TLS 1.2 Keying Material Exporter: Consistent results, large keys -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_2:MBEDTLS_SSL_EXPORT_MAX_KEY_LEN:0 TLS 1.2 Keying Material Exporter: Uses label -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY ssl_tls_exporter_uses_label:MBEDTLS_SSL_VERSION_TLS1_2 TLS 1.2 Keying Material Exporter: Uses context -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY ssl_tls_exporter_uses_context:MBEDTLS_SSL_VERSION_TLS1_2 TLS 1.2 Keying Material Exporter: Context too long -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY ssl_tls_exporter_rejects_bad_parameters:MBEDTLS_SSL_VERSION_TLS1_2:24:251:UINT16_MAX + 1 TLS 1.2 Keying Material Exporter: Handshake not done -depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY ssl_tls_exporter_too_early:MBEDTLS_SSL_VERSION_TLS1_2:1:MBEDTLS_SSL_SERVER_CERTIFICATE TLS 1.3 Keying Material Exporter: Consistent results, no context -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:24:0 TLS 1.3 Keying Material Exporter: Consistent results, with context -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:24:1 TLS 1.3 Keying Material Exporter: Consistent results, large keys -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:MBEDTLS_SSL_EXPORT_MAX_KEY_LEN:0 TLS 1.3 Keying Material Exporter: Uses label -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 ssl_tls_exporter_uses_label:MBEDTLS_SSL_VERSION_TLS1_3 TLS 1.3 Keying Material Exporter: Uses context -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 ssl_tls_exporter_uses_context:MBEDTLS_SSL_VERSION_TLS1_3 TLS 1.3 Keying Material Exporter: Uses length -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 ssl_tls13_exporter_uses_length TLS 1.3 Keying Material Exporter: Exported key too long -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 ssl_tls_exporter_rejects_bad_parameters:MBEDTLS_SSL_VERSION_TLS1_3:MBEDTLS_SSL_EXPORT_MAX_KEY_LEN + 1:20:20 TLS 1.3 Keying Material Exporter: Label too long -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 ssl_tls_exporter_rejects_bad_parameters:MBEDTLS_SSL_VERSION_TLS1_3:24:251:10 TLS 1.3 Keying Material Exporter: Handshake not done -depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 ssl_tls_exporter_too_early:MBEDTLS_SSL_VERSION_TLS1_3:1:MBEDTLS_SSL_SERVER_CERTIFICATE diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 2625850608..8fa5120d4a 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -5727,7 +5727,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT */ +/* BEGIN_CASE depends_on:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:PSA_WANT_ECC_SECP_R1_384:PSA_WANT_ALG_SHA_256 */ void ssl_tls_exporter_consistent_result(int proto, int exported_key_length, int use_context) { /* Test that the client and server generate the same key. */ @@ -5774,7 +5774,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT */ +/* BEGIN_CASE depends_on:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:PSA_WANT_ECC_SECP_R1_384:PSA_WANT_ALG_SHA_256 */ void ssl_tls_exporter_uses_label(int proto) { /* Test that the client and server export different keys when using different labels. */ @@ -5813,7 +5813,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT */ +/* BEGIN_CASE depends_on:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:PSA_WANT_ECC_SECP_R1_384:PSA_WANT_ALG_SHA_256 */ void ssl_tls_exporter_uses_context(int proto) { /* Test that the client and server export different keys when using different contexts. */ @@ -5852,7 +5852,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT */ +/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:PSA_WANT_ECC_SECP_R1_384:PSA_WANT_ALG_SHA_256 */ void ssl_tls13_exporter_uses_length(void) { /* In TLS 1.3, when two keys are exported with the same parameters except one is shorter, @@ -5894,7 +5894,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT */ +/* BEGIN_CASE depends_on:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:PSA_WANT_ECC_SECP_R1_384:PSA_WANT_ALG_SHA_256 */ void ssl_tls_exporter_rejects_bad_parameters( int proto, int exported_key_length, int label_length, int context_length) { @@ -5934,7 +5934,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT */ +/* BEGIN_CASE depends_on:MBEDTLS_SSL_KEYING_MATERIAL_EXPORT:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:PSA_WANT_ECC_SECP_R1_384:PSA_WANT_ALG_SHA_256 */ void ssl_tls_exporter_too_early(int proto, int check_server, int state) { enum { BUFFSIZE = 1024 }; From ede294ea42e2bcc669a3c8f35bbfc86af6f36e55 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Tue, 5 Nov 2024 19:45:41 +0100 Subject: [PATCH 38/57] Exporter tests: Don't use unavailbable constant Signed-off-by: Max Fillinger --- tests/suites/test_suite_ssl.data | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 3bd357313c..98af39873c 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3461,7 +3461,7 @@ ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_2:24:1 TLS 1.2 Keying Material Exporter: Consistent results, large keys depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY -ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_2:MBEDTLS_SSL_EXPORT_MAX_KEY_LEN:0 +ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_2:255 * 32:0 TLS 1.2 Keying Material Exporter: Uses label depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY @@ -3489,7 +3489,7 @@ ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:24:1 TLS 1.3 Keying Material Exporter: Consistent results, large keys depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 -ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:MBEDTLS_SSL_EXPORT_MAX_KEY_LEN:0 +ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:255 * 32:0 TLS 1.3 Keying Material Exporter: Uses label depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 @@ -3505,7 +3505,7 @@ ssl_tls13_exporter_uses_length TLS 1.3 Keying Material Exporter: Exported key too long depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 -ssl_tls_exporter_rejects_bad_parameters:MBEDTLS_SSL_VERSION_TLS1_3:MBEDTLS_SSL_EXPORT_MAX_KEY_LEN + 1:20:20 +ssl_tls_exporter_rejects_bad_parameters:MBEDTLS_SSL_VERSION_TLS1_3:255 * 32 + 1:20:20 TLS 1.3 Keying Material Exporter: Label too long depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 From c8f936e746d45413f477b1548b9bad3ab11c205a Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Fri, 8 Nov 2024 22:17:33 +0100 Subject: [PATCH 39/57] mbedtls_test_ssl_do_handshake_with_endpoints: Zeroize endpoints Signed-off-by: Max Fillinger --- tests/src/test_helpers/ssl_helpers.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index 2ad1c370d1..cf051d1126 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -2048,6 +2048,9 @@ int mbedtls_test_ssl_do_handshake_with_endpoints( int ret = -1; + mbedtls_platform_zeroize(server_ep, sizeof(mbedtls_test_ssl_endpoint)); + mbedtls_platform_zeroize(client_ep, sizeof(mbedtls_test_ssl_endpoint)); + mbedtls_test_init_handshake_options(options); options->server_min_version = proto; options->client_min_version = proto; From 9c3a7ba6da319fcfc8592453a01d3596be6826eb Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Mon, 11 Nov 2024 17:50:34 +0100 Subject: [PATCH 40/57] ssl-opt.sh: Add tests for keying material export Signed-off-by: Max Fillinger --- tests/ssl-opt.sh | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 61cb366c12..654a2cb100 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -1230,6 +1230,26 @@ check_server_hello_time() { fi } +# Extract the exported key from the output. +get_exported_key() { + OUTPUT="$1" + EXPORTED_KEY1=$(sed -n '/Exporting key of length 20 with label ".*": /s/.*: //p' $OUTPUT) +} + +# Check that the exported key from the output matches the one obtained in get_exported_key(). +check_exported_key() { + OUTPUT="$1" + EXPORTED_KEY2=$(sed -n '/Exporting key of length 20 with label ".*": /s/.*: //p' $OUTPUT) + test "$EXPORTED_KEY1" = "$EXPORTED_KEY2" +} + +# Check that the exported key from the output matches the one obtained in get_exported_key(). +check_exported_key_openssl() { + OUTPUT="$1" + EXPORTED_KEY2=0x$(sed -n '/Keying material: /s/.*: //p' $OUTPUT) + test "$EXPORTED_KEY1" = "$EXPORTED_KEY2" +} + # Get handshake memory usage from server or client output and put it into the variable specified by the first argument handshake_memory_get() { OUTPUT_VARIABLE="$1" @@ -1977,6 +1997,34 @@ run_tests_memory_after_handshake() run_test_memory_after_handshake_with_mfl 512 "$MEMORY_USAGE_MFL_16K" } +run_test_export_keying_material() { + unset EXPORTED_KEY1 + unset EXPORTED_KEY2 + TLS_VERSION="$1" + run_test "TLS $TLS_VERSION: Export keying material" \ + "$P_SRV debug_level=4 force_version=$TLS_VERSION exp_label=test-label" \ + "$P_CLI debug_level=4 force_version=$TLS_VERSION exp_label=test-label" \ + 0 \ + -s "Exporting key of length 20 with label \".*\": 0x" \ + -c "Exporting key of length 20 with label \".*\": 0x" \ + -f get_exported_key \ + -F check_exported_key +} + +run_test_export_keying_material_openssl_compat() { + unset EXPORTED_KEY1 + unset EXPORTED_KEY2 + TLS_VERSION="$1" + run_test "TLS $TLS_VERSION: Export keying material (OpenSSL compatibility)" \ + "$P_SRV debug_level=4 force_version=$TLS_VERSION exp_label=test-label" \ + "$O_CLI -keymatexport=test-label" \ + 0 \ + -s "Exporting key of length 20 with label \".*\": 0x" \ + -c "Keying material exporter:" \ + -F get_exported_key \ + -f check_exported_key_openssl +} + cleanup() { rm -f $CLI_OUT $SRV_OUT $PXY_OUT $SESSION rm -f context_srv.txt @@ -3138,6 +3186,23 @@ run_test "Saving the serialized context to a file" \ 0 \ -s "Save serialized context to a file... ok" \ -c "Save serialized context to a file... ok" + +requires_config_enabled MBEDTLS_SSL_KEYING_MATERIAL_EXPORT +requires_protocol_version tls12 +run_test_export_keying_material tls12 + +requires_config_enabled MBEDTLS_SSL_KEYING_MATERIAL_EXPORT +requires_protocol_version tls12 +run_test_export_keying_material_openssl_compat tls12 + +requires_config_enabled MBEDTLS_SSL_KEYING_MATERIAL_EXPORT +requires_protocol_version tls13 +run_test_export_keying_material tls13 + +requires_config_enabled MBEDTLS_SSL_KEYING_MATERIAL_EXPORT +requires_protocol_version tls13 +run_test_export_keying_material_openssl_compat tls13 + rm -f context_srv.txt rm -f context_cli.txt From a442aea2be3697ea31b55b17e3e1da2c183ec544 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Wed, 13 Nov 2024 15:19:03 +0100 Subject: [PATCH 41/57] Fix memory leak in example programs Signed-off-by: Max Fillinger --- programs/ssl/ssl_client2.c | 2 ++ programs/ssl/ssl_server2.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 228e7f8761..88c9f8c9fe 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -2593,6 +2593,7 @@ usage: opt.exp_label, strlen(opt.exp_label), NULL, 0, 0); if (ret != 0) { + mbedtls_free(exported_key); goto exit; } mbedtls_printf("Exporting key of length %d with label \"%s\": 0x", @@ -2603,6 +2604,7 @@ usage: } mbedtls_printf("\n\n"); fflush(stdout); + mbedtls_free(exported_key); } #endif /* defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) */ diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 2b81fc18ef..1a934e32d7 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -3675,6 +3675,7 @@ handshake: opt.exp_label, strlen(opt.exp_label), NULL, 0, 0); if (ret != 0) { + mbedtls_free(exported_key); goto exit; } mbedtls_printf("Exporting key of length %d with label \"%s\": 0x", @@ -3685,6 +3686,7 @@ handshake: } mbedtls_printf("\n\n"); fflush(stdout); + mbedtls_free(exported_key); } #endif /* defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) */ From d22493f86b7c3ea12f118438ee630683079e64b1 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Wed, 13 Nov 2024 15:27:23 +0100 Subject: [PATCH 42/57] Print names of new tests properly Signed-off-by: Max Fillinger --- tests/ssl-opt.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 654a2cb100..6cb26eece3 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -2001,7 +2001,13 @@ run_test_export_keying_material() { unset EXPORTED_KEY1 unset EXPORTED_KEY2 TLS_VERSION="$1" - run_test "TLS $TLS_VERSION: Export keying material" \ + + case $TLS_VERSION in + tls12) TLS_VERSION_PRINT="TLS 1.2";; + tls13) TLS_VERSION_PRINT="TLS 1.3";; + esac + + run_test "$TLS_VERSION_PRINT: Export keying material" \ "$P_SRV debug_level=4 force_version=$TLS_VERSION exp_label=test-label" \ "$P_CLI debug_level=4 force_version=$TLS_VERSION exp_label=test-label" \ 0 \ @@ -2015,7 +2021,13 @@ run_test_export_keying_material_openssl_compat() { unset EXPORTED_KEY1 unset EXPORTED_KEY2 TLS_VERSION="$1" - run_test "TLS $TLS_VERSION: Export keying material (OpenSSL compatibility)" \ + + case TLS_VERSION in + tls12) TLS_VERSION_PRINT="TLS 1.2";; + tls13) TLS_VERSION_PRINT="TLS 1.3";; + esac + + run_test "$TLS_VERSION_PRINT: Export keying material (OpenSSL compatibility)" \ "$P_SRV debug_level=4 force_version=$TLS_VERSION exp_label=test-label" \ "$O_CLI -keymatexport=test-label" \ 0 \ From 0faf5d19a76ab46019bee4f119eebf9461b61afb Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Thu, 14 Nov 2024 15:28:05 +0100 Subject: [PATCH 43/57] Fix openssl s_client invocation Signed-off-by: Max Fillinger --- tests/ssl-opt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 6cb26eece3..9dd91efd01 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -2029,7 +2029,7 @@ run_test_export_keying_material_openssl_compat() { run_test "$TLS_VERSION_PRINT: Export keying material (OpenSSL compatibility)" \ "$P_SRV debug_level=4 force_version=$TLS_VERSION exp_label=test-label" \ - "$O_CLI -keymatexport=test-label" \ + "$O_CLI -keymatexport test-label" \ 0 \ -s "Exporting key of length 20 with label \".*\": 0x" \ -c "Keying material exporter:" \ From e009158d718bf5bcfe85bf2b2cdf4be6e308e4cc Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Thu, 14 Nov 2024 15:32:01 +0100 Subject: [PATCH 44/57] Remove exporter compatibility test for TLS 1.3 The openssl version in the docker image doesn't support TLS 1.3, so we can't run the test. Signed-off-by: Max Fillinger --- tests/ssl-opt.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 9dd91efd01..5ebe6572a3 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -3211,10 +3211,6 @@ requires_config_enabled MBEDTLS_SSL_KEYING_MATERIAL_EXPORT requires_protocol_version tls13 run_test_export_keying_material tls13 -requires_config_enabled MBEDTLS_SSL_KEYING_MATERIAL_EXPORT -requires_protocol_version tls13 -run_test_export_keying_material_openssl_compat tls13 - rm -f context_srv.txt rm -f context_cli.txt From 2310c1970b218a5d53084e4df3957f49ab017166 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Thu, 14 Nov 2024 17:50:42 +0100 Subject: [PATCH 45/57] Add fixed compatibility test for TLS 1.3 Exporter When testing TLS 1.3, use O_NEXT_CLI. Signed-off-by: Max Fillinger --- tests/ssl-opt.sh | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 5ebe6572a3..a4e5809c02 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -2022,14 +2022,14 @@ run_test_export_keying_material_openssl_compat() { unset EXPORTED_KEY2 TLS_VERSION="$1" - case TLS_VERSION in - tls12) TLS_VERSION_PRINT="TLS 1.2";; - tls13) TLS_VERSION_PRINT="TLS 1.3";; + case $TLS_VERSION in + tls12) TLS_VERSION_PRINT="TLS 1.2"; OPENSSL_CLIENT="$O_CLI";; + tls13) TLS_VERSION_PRINT="TLS 1.3"; OPENSSL_CLIENT="$O_NEXT_CLI";; esac run_test "$TLS_VERSION_PRINT: Export keying material (OpenSSL compatibility)" \ "$P_SRV debug_level=4 force_version=$TLS_VERSION exp_label=test-label" \ - "$O_CLI -keymatexport test-label" \ + "$OPENSSL_CLIENT -keymatexport test-label" \ 0 \ -s "Exporting key of length 20 with label \".*\": 0x" \ -c "Keying material exporter:" \ @@ -3211,6 +3211,11 @@ requires_config_enabled MBEDTLS_SSL_KEYING_MATERIAL_EXPORT requires_protocol_version tls13 run_test_export_keying_material tls13 +requires_config_enabled MBEDTLS_SSL_KEYING_MATERIAL_EXPORT +requires_protocol_version tls13 +requires_openssl_next +run_test_export_keying_material_openssl_compat tls13 + rm -f context_srv.txt rm -f context_cli.txt From 6f7cf0e4026529fab6d86519cc20269c4645183d Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Thu, 14 Nov 2024 20:41:03 +0100 Subject: [PATCH 46/57] Use mbedtls_calloc, not regular calloc Also fix the allocation size. Signed-off-by: Max Fillinger --- programs/ssl/ssl_client2.c | 2 +- programs/ssl/ssl_server2.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 88c9f8c9fe..ed72095da5 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -2583,7 +2583,7 @@ usage: #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)); + unsigned char *exported_key = mbedtls_calloc((size_t) opt.exp_len, sizeof(unsigned char)); if (exported_key == NULL) { mbedtls_printf("Could not allocate %d bytes\n", opt.exp_len); ret = 3; diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 1a934e32d7..e9539499d1 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -3665,7 +3665,7 @@ handshake: #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)); + unsigned char *exported_key = mbedtls_calloc((size_t) opt.exp_len, sizeof(unsigned char)); if (exported_key == NULL) { mbedtls_printf("Could not allocate %d bytes\n", opt.exp_len); ret = 3; From c361064dee6d27ff91e14b5259493bd7d76181ae Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Thu, 14 Nov 2024 21:11:26 +0100 Subject: [PATCH 47/57] Fix requirements for TLS 1.3 Exporter compat test Signed-off-by: Max Fillinger --- tests/ssl-opt.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index a4e5809c02..16e2675193 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -3212,8 +3212,8 @@ requires_protocol_version tls13 run_test_export_keying_material tls13 requires_config_enabled MBEDTLS_SSL_KEYING_MATERIAL_EXPORT -requires_protocol_version tls13 -requires_openssl_next +requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_openssl_tls1_3_with_compatible_ephemeral run_test_export_keying_material_openssl_compat tls13 rm -f context_srv.txt From 97a287953ffc35a17cc67b5697e5856c623f8bb2 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Mon, 18 Nov 2024 18:22:51 +0100 Subject: [PATCH 48/57] Document BAD_INPUT_DATA error in key material exporter Signed-off-by: Max Fillinger --- include/mbedtls/ssl.h | 4 +++- library/ssl_tls.c | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 649dc75a7d..57669a4db5 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -5800,7 +5800,9 @@ int mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf, * this distinction. If use_context is 0 and TLS 1.3 is used, context and * context_len are ignored and a 0-length context is used. * - * \return 0 on success. An SSL specific error on failure. + * \return 0 on success. + * \return MBEDTLS_ERR_SSL_BAD_INPUT_DATA if the handshake is not yet completed. + * \return An SSL-specific error on failure. */ int mbedtls_ssl_export_keying_material(mbedtls_ssl_context *ssl, uint8_t *out, const size_t key_len, diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 32fbe132cd..0c3fc8415f 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -10147,6 +10147,7 @@ int mbedtls_ssl_export_keying_material(mbedtls_ssl_context *ssl, const int use_context) { if (!mbedtls_ssl_is_handshake_over(ssl)) { + /* TODO: Change this to a more appropriate error code when one is available. */ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; } From 76bb753054cf84827ed5196593a6244538b54a8d Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Thu, 21 Nov 2024 12:33:46 +0100 Subject: [PATCH 49/57] Fix max. label length in key material exporter Signed-off-by: Max Fillinger --- include/mbedtls/ssl.h | 2 +- library/ssl_tls.c | 6 +++--- tests/suites/test_suite_ssl.data | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 57669a4db5..cc9da3417d 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -5790,7 +5790,7 @@ int mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf, * \param key_len Length of the key to generate in bytes, must be at most * MBEDTLS_SSL_EXPORT_MAX_KEY_LEN (8160). * \param label Label for which to generate the key of length label_len. - * \param label_len Length of label in bytes. Must be at most 250 in TLS 1.3. + * \param label_len Length of label in bytes. Must be at most 249 in TLS 1.3. * \param context Context of the key. Can be NULL if context_len or use_context is 0. * \param context_len Length of context. Must be < 2^16 in TLS 1.2. * \param use_context Indicates if a context should be used in deriving the key. diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 0c3fc8415f..d964611e16 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -10124,13 +10124,13 @@ static int mbedtls_ssl_tls13_export_keying_material(mbedtls_ssl_context *ssl, const size_t hash_len = PSA_HASH_LENGTH(hash_alg); const unsigned char *secret = ssl->session->app_secrets.exporter_master_secret; - /* The length of the label must be at most 250 bytes to fit into the HkdfLabel + /* The length of the label must be at most 249 bytes to fit into the HkdfLabel * struct as defined in RFC 8446, Section 7.1. * * The length of the context is unlimited even though the context field in the - * struct can only hold up to 256 bytes. This is because we place a *hash* of + * struct can only hold up to 255 bytes. This is because we place a *hash* of * the context in the field. */ - if (label_len > 250) { + if (label_len > 249) { return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; } diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 98af39873c..4d091847dc 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3509,7 +3509,7 @@ ssl_tls_exporter_rejects_bad_parameters:MBEDTLS_SSL_VERSION_TLS1_3:255 * 32 + 1: TLS 1.3 Keying Material Exporter: Label too long depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 -ssl_tls_exporter_rejects_bad_parameters:MBEDTLS_SSL_VERSION_TLS1_3:24:251:10 +ssl_tls_exporter_rejects_bad_parameters:MBEDTLS_SSL_VERSION_TLS1_3:24:250:10 TLS 1.3 Keying Material Exporter: Handshake not done depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 From 6a64f0f171f26f0f711088d85f7a8c1194025656 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Mon, 25 Nov 2024 20:21:29 +0100 Subject: [PATCH 50/57] Exporter: Add min. and max. label tests Signed-off-by: Max Fillinger --- tests/suites/test_suite_ssl.data | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 4d091847dc..9ee7507467 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -2909,6 +2909,16 @@ SSL TLS 1.3 Exporter depends_on:PSA_WANT_ALG_SHA_256 ssl_tls13_exporter:PSA_ALG_SHA_256:"3fd93d4ffddc98e64b14dd107aedf8ee4add23f4510f58a4592d0b201bee56b4":"test":"context value":32:"83d0fac39f87c1b4fbcd261369f31149c535391a9199bd4c5daf89fe259c2e94" +SSL TLS 1.3 Exporter, 0-byte label and context +# Expected output taken from OpenSSL. +depends_on:PSA_WANT_ALG_SHA_384 +ssl_tls13_exporter:PSA_ALG_SHA_384:"9f355772f34017927ecc81d16e653c7408f945e7f62dc632d3f59e6310ef49401e62a2e3be886e3f930d4bf6300ce30a":"":"":20:"18268580D7C6769194794A84B7A3EE35317DB88A" + +SSL TLS 1.3 Exporter, 249-byte label and 0-byte context +# Expected output taken from OpenSSL. +depends_on:PSA_WANT_ALG_SHA_384 +ssl_tls13_exporter:PSA_ALG_SHA_384:"c453aeae318ebae00617c430a0066cf586593a4b0150219107420798933cf9e6e4434337cccc2cae5429dc4f77401e39":"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef012345678":"":20:"259531766AAA10FBAB6BF2D11D23264B321743D9" + SSL TLS 1.3 Key schedule: Early secrets derivation helper # Vector from RFC 8448 depends_on:PSA_WANT_ALG_SHA_256 From 529931a34a6d0648c23f8791f5ba14030ff7f93a Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Mon, 25 Nov 2024 20:38:04 +0100 Subject: [PATCH 51/57] Allow maximum label length in Hkdf-Expand-Label Previously, the length of the label was limited to the maximal length that would be used in the TLS 1.3 key schedule. With the keying material exporter, labels of up to 249 bytes may be used. Signed-off-by: Max Fillinger --- library/ssl_tls13_keys.c | 6 +++--- library/ssl_tls13_keys.h | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c index 4a7ca4f1ab..52d19f0baf 100644 --- a/library/ssl_tls13_keys.c +++ b/library/ssl_tls13_keys.c @@ -66,7 +66,7 @@ struct mbedtls_ssl_tls13_labels_struct const mbedtls_ssl_tls13_labels = * hardcoding the writing of the high bytes. * - (label, label_len): label + label length, without "tls13 " prefix * The label length MUST be less than or equal to - * MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN + * MBEDTLS_SSL_TLS1_3_HKDF_LABEL_MAX_LABEL_LEN. * It is the caller's responsibility to ensure this. * All (label, label length) pairs used in TLS 1.3 * can be obtained via MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(). @@ -93,7 +93,7 @@ static const char tls13_label_prefix[6] = "tls13 "; #define SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN \ SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( \ sizeof(tls13_label_prefix) + \ - MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN, \ + MBEDTLS_SSL_TLS1_3_HKDF_LABEL_MAX_LABEL_LEN, \ MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN) static void ssl_tls13_hkdf_encode_label( @@ -149,7 +149,7 @@ int mbedtls_ssl_tls13_hkdf_expand_label( psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT; - if (label_len > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN) { + if (label_len > MBEDTLS_SSL_TLS1_3_HKDF_LABEL_MAX_LABEL_LEN) { /* Should never happen since this is an internal * function, and we know statically which labels * are allowed. */ diff --git a/library/ssl_tls13_keys.h b/library/ssl_tls13_keys.h index 31ffe4481e..14f6e4876c 100644 --- a/library/ssl_tls13_keys.h +++ b/library/ssl_tls13_keys.h @@ -60,8 +60,9 @@ extern const struct mbedtls_ssl_tls13_labels_struct mbedtls_ssl_tls13_labels; mbedtls_ssl_tls13_labels.LABEL, \ MBEDTLS_SSL_TLS1_3_LBL_LEN(LABEL) -#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN \ - sizeof(union mbedtls_ssl_tls13_labels_union) +/* Maximum length of the label field in the HkdfLabel struct defined in + * RFC 8446, Section 7.1, excluding the "tls13 " prefix. */ +#define MBEDTLS_SSL_TLS1_3_HKDF_LABEL_MAX_LABEL_LEN 249 /* The maximum length of HKDF contexts used in the TLS 1.3 standard. * Since contexts are always hashes of message transcripts, this can From 7833b180088b796046ddce95691451936fb322cb Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Mon, 2 Dec 2024 19:26:13 +0100 Subject: [PATCH 52/57] Fix HkdfLabel comment Signed-off-by: Max Fillinger --- library/ssl_tls13_keys.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c index 52d19f0baf..3d31013c6c 100644 --- a/library/ssl_tls13_keys.c +++ b/library/ssl_tls13_keys.c @@ -58,12 +58,8 @@ struct mbedtls_ssl_tls13_labels_struct const mbedtls_ssl_tls13_labels = * }; * * Parameters: - * - desired_length: Length of expanded key material - * Even though the standard allows expansion to up to - * 2**16 Bytes, TLS 1.3 never uses expansion to more than - * 255 Bytes, so we require `desired_length` to be at most - * 255. This allows us to save a few Bytes of code by - * hardcoding the writing of the high bytes. + * - desired_length: Length of expanded key material. + * As the type implies, this must be less than 2**16 bytes. * - (label, label_len): label + label length, without "tls13 " prefix * The label length MUST be less than or equal to * MBEDTLS_SSL_TLS1_3_HKDF_LABEL_MAX_LABEL_LEN. From 5122dc621931c5ec03b8c2c905860044e88892b4 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Mon, 2 Dec 2024 19:34:40 +0100 Subject: [PATCH 53/57] Fix mistake in previous comment change Signed-off-by: Max Fillinger --- library/ssl_tls13_keys.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c index 3d31013c6c..0eae6fd5ba 100644 --- a/library/ssl_tls13_keys.c +++ b/library/ssl_tls13_keys.c @@ -59,7 +59,12 @@ struct mbedtls_ssl_tls13_labels_struct const mbedtls_ssl_tls13_labels = * * Parameters: * - desired_length: Length of expanded key material. - * As the type implies, this must be less than 2**16 bytes. + * The length field can hold numbers up to 2**16, but HKDF + * can only generate outputs of up to 255 * HASH_LEN bytes. + * It is the caller's responsibility to ensure that this + * limit is not exceeded. In TLS 1.3, SHA256 is the hash + * function with the smallest block size, so a length + * <= 255 * 32 = 8160 is always safe. * - (label, label_len): label + label length, without "tls13 " prefix * The label length MUST be less than or equal to * MBEDTLS_SSL_TLS1_3_HKDF_LABEL_MAX_LABEL_LEN. From 0b65a91eea0f48a3b72fd4240df1211a4446742c Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Fri, 17 Jan 2025 14:10:08 +0100 Subject: [PATCH 54/57] Fix doxygen for MBEDTLS_SSL_KEYING_MATERIAL_EXPORT Error was introduced while resolving a merge conflict. Signed-off-by: Max Fillinger --- include/mbedtls/mbedtls_config.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h index df6dacf587..d2831367cd 100644 --- a/include/mbedtls/mbedtls_config.h +++ b/include/mbedtls/mbedtls_config.h @@ -1764,7 +1764,6 @@ #define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE /** -/* * \def MBEDTLS_SSL_KEYING_MATERIAL_EXPORT * * When this option is enabled, the client and server can extract additional From 820e5cc29b04490ecae28e7ad4f8f288791ea742 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Tue, 21 Jan 2025 21:40:04 +0100 Subject: [PATCH 55/57] Fix dependencies for TLS-Exporter tests Signed-off-by: Max Fillinger --- tests/suites/test_suite_ssl.data | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 9ee7507467..92bda3efd1 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3490,37 +3490,37 @@ depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY ssl_tls_exporter_too_early:MBEDTLS_SSL_VERSION_TLS1_2:1:MBEDTLS_SSL_SERVER_CERTIFICATE TLS 1.3 Keying Material Exporter: Consistent results, no context -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:MBEDTLS_X509_RSASSA_PSS_SUPPORT ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:24:0 TLS 1.3 Keying Material Exporter: Consistent results, with context -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:MBEDTLS_X509_RSASSA_PSS_SUPPORT ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:24:1 TLS 1.3 Keying Material Exporter: Consistent results, large keys -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:MBEDTLS_X509_RSASSA_PSS_SUPPORT ssl_tls_exporter_consistent_result:MBEDTLS_SSL_VERSION_TLS1_3:255 * 32:0 TLS 1.3 Keying Material Exporter: Uses label -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:MBEDTLS_X509_RSASSA_PSS_SUPPORT ssl_tls_exporter_uses_label:MBEDTLS_SSL_VERSION_TLS1_3 TLS 1.3 Keying Material Exporter: Uses context -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:MBEDTLS_X509_RSASSA_PSS_SUPPORT ssl_tls_exporter_uses_context:MBEDTLS_SSL_VERSION_TLS1_3 TLS 1.3 Keying Material Exporter: Uses length -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:MBEDTLS_X509_RSASSA_PSS_SUPPORT ssl_tls13_exporter_uses_length TLS 1.3 Keying Material Exporter: Exported key too long -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:MBEDTLS_X509_RSASSA_PSS_SUPPORT ssl_tls_exporter_rejects_bad_parameters:MBEDTLS_SSL_VERSION_TLS1_3:255 * 32 + 1:20:20 TLS 1.3 Keying Material Exporter: Label too long -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:MBEDTLS_X509_RSASSA_PSS_SUPPORT ssl_tls_exporter_rejects_bad_parameters:MBEDTLS_SSL_VERSION_TLS1_3:24:250:10 TLS 1.3 Keying Material Exporter: Handshake not done -depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_PKCS1 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:MBEDTLS_X509_RSASSA_PSS_SUPPORT ssl_tls_exporter_too_early:MBEDTLS_SSL_VERSION_TLS1_3:1:MBEDTLS_SSL_SERVER_CERTIFICATE From 40c202461fe67bf0ed4f69455defdd17b2676000 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Tue, 15 Apr 2025 21:18:20 +0200 Subject: [PATCH 56/57] Add label_len argument to non-PSA tls_prf_generic Signed-off-by: Max Fillinger --- library/ssl_tls.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index d964611e16..ce14c7d7ba 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -6849,7 +6849,7 @@ static int tls_prf_generic(mbedtls_md_type_t md_type, MBEDTLS_CHECK_RETURN_CRITICAL static int tls_prf_generic(mbedtls_md_type_t md_type, const unsigned char *secret, size_t slen, - const char *label, + const char *label, size_t label_len, const unsigned char *random, size_t rlen, unsigned char *dstbuf, size_t dlen) { @@ -6870,14 +6870,14 @@ static int tls_prf_generic(mbedtls_md_type_t md_type, md_len = mbedtls_md_get_size(md_info); - tmp_len = md_len + strlen(label) + rlen; + tmp_len = md_len + label_len + rlen; tmp = mbedtls_calloc(1, tmp_len); if (tmp == NULL) { ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; goto exit; } - nb = strlen(label); + nb = label_len; memcpy(tmp + md_len, label, nb); memcpy(tmp + md_len + nb, random, rlen); nb += rlen; From 1b0e2e903ba6f04b84784c774cfd629c57266dc6 Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Wed, 16 Apr 2025 14:35:24 +0200 Subject: [PATCH 57/57] Add missing ifdef for mbedtls_ssl_tls13_exporter Signed-off-by: Max Fillinger --- library/ssl_tls13_keys.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c index 0eae6fd5ba..fd559a7d7f 100644 --- a/library/ssl_tls13_keys.c +++ b/library/ssl_tls13_keys.c @@ -1881,6 +1881,7 @@ int mbedtls_ssl_tls13_export_handshake_psk(mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */ +#if defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) int mbedtls_ssl_tls13_exporter(const psa_algorithm_t hash_alg, const unsigned char *secret, const size_t secret_len, const unsigned char *label, const size_t label_len, @@ -1911,5 +1912,6 @@ exit: mbedtls_platform_zeroize(hkdf_secret, sizeof(hkdf_secret)); return ret; } +#endif /* defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) */ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */