From c6fd1a24d27055c250dff9258ac9f595dfc5969b Mon Sep 17 00:00:00 2001 From: Max Fillinger Date: Fri, 1 Nov 2024 16:05:34 +0100 Subject: [PATCH] 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 e3772891b0..7304a3bfc0 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -5396,15 +5396,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. @@ -5416,7 +5423,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 79bd623ebd..46197c95ca 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -9000,16 +9000,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; } @@ -9029,6 +9026,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 017ab8529a..6d6812c4e6 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3345,7 +3345,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 @@ -3373,7 +3373,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 @@ -3389,7 +3389,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