ssl_tls13_generic: check value of RecordSizeLimit in helper function
Signed-off-by: Yanray Wang <yanray.wang@arm.com>
diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c
index ecfaf8a..0befe3b 100644
--- a/library/ssl_tls13_generic.c
+++ b/library/ssl_tls13_generic.c
@@ -1700,6 +1700,27 @@
#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
* RecordSizeLimit:
* uint16 RecordSizeLimit;
@@ -1709,6 +1730,7 @@
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 @@
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 @@
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 */