From faf70bdf9d314e52fd8b3e7d92a922316cac05c5 Mon Sep 17 00:00:00 2001 From: Yanray Wang Date: Thu, 7 Dec 2023 10:03:32 +0800 Subject: [PATCH] ssl_tls13_generic: check value of RecordSizeLimit in helper function Signed-off-by: Yanray Wang --- library/ssl_tls13_generic.c | 67 +++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index ecfaf8a1a..0befe3bba 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -1698,6 +1698,27 @@ int mbedtls_ssl_tls13_check_received_extension( } #if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) +/* RFC 8449, section 4: + * + * Endpoints MUST NOT send a "record_size_limit" extension with a value + * smaller than 64. An endpoint MUST treat receipt of a smaller value + * as a fatal error and generate an "illegal_parameter" alert. + */ +static int mbedtls_ssl_is_record_size_limit_valid(mbedtls_ssl_context *ssl, + uint16_t record_size_limit) +{ + if (record_size_limit < MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN) { + MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid record size limit : %u Bytes", + record_size_limit)); + MBEDTLS_SSL_PEND_FATAL_ALERT( + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, + MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); + return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; + } + + return 0; +} + /* RFC 8449, section 4: * * The ExtensionData of the "record_size_limit" extension is @@ -1709,6 +1730,7 @@ int mbedtls_ssl_tls13_parse_record_size_limit_ext(mbedtls_ssl_context *ssl, const unsigned char *buf, const unsigned char *end) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; const unsigned char *p = buf; uint16_t record_size_limit; const size_t extension_data_len = end - buf; @@ -1731,17 +1753,9 @@ int mbedtls_ssl_tls13_parse_record_size_limit_ext(mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG(2, ("RecordSizeLimit: %u Bytes", record_size_limit)); - /* RFC 8449, section 4: - * - * Endpoints MUST NOT send a "record_size_limit" extension with a value - * smaller than 64. An endpoint MUST treat receipt of a smaller value - * as a fatal error and generate an "illegal_parameter" alert. - */ - if (record_size_limit < MBEDTLS_SSL_RECORD_SIZE_LIMIT_MIN) { - MBEDTLS_SSL_PEND_FATAL_ALERT( - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; + ret = mbedtls_ssl_is_record_size_limit_valid(ssl, record_size_limit); + if (ret != 0) { + return ret; } ssl->session_negotiate->record_size_limit = record_size_limit; @@ -1749,6 +1763,37 @@ int mbedtls_ssl_tls13_parse_record_size_limit_ext(mbedtls_ssl_context *ssl, return 0; } +MBEDTLS_CHECK_RETURN_CRITICAL +int mbedtls_ssl_tls13_write_record_size_limit_ext(mbedtls_ssl_context *ssl, + uint16_t record_size_limit, + unsigned char *buf, + const unsigned char *end, + size_t *out_len) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char *p = buf; + *out_len = 0; + + ret = mbedtls_ssl_is_record_size_limit_valid(ssl, record_size_limit); + if (ret != 0) { + return ret; + } + + MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6); + + MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT, p, 0); + MBEDTLS_PUT_UINT16_BE(MBEDTLS_SSL_RECORD_SIZE_LIMIT_EXTENSION_DATA_LENGTH, p, 2); + MBEDTLS_PUT_UINT16_BE(record_size_limit, p, 4); + + *out_len = 6; + + MBEDTLS_SSL_DEBUG_MSG(2, ("Sent RecordSizeLimit: %u Bytes", record_size_limit)); + + mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT); + + return 0; +} + #endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ #endif /* MBEDTLS_SSL_TLS_C && MBEDTLS_SSL_PROTO_TLS1_3 */