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