Merge pull request #7071 from yuhaoth/pr/tls13-ticket-add-max_early_data_size-field

TLS 1.3 EarlyData: add `max_early_data_size` field for ticket
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 30b8685..7294bb1 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1260,6 +1260,10 @@
 
 #endif /*  MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */
 
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+    uint32_t MBEDTLS_PRIVATE(max_early_data_size);          /*!< maximum amount of early data in tickets */
+#endif
+
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
     int MBEDTLS_PRIVATE(encrypt_then_mac);       /*!< flag for EtM activation                */
 #endif
@@ -2046,6 +2050,10 @@
  *
  * \warning This interface is experimental and may change without notice.
  *
+ * \warning This interface DOES NOT influence/limit the amount of early data
+ *          that can be received through previously created and issued tickets,
+ *          which clients may have stored.
+ *
  */
 void mbedtls_ssl_conf_max_early_data_size(
     mbedtls_ssl_config *conf, uint32_t max_early_data_size);
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 4751d34..f855576 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -2454,6 +2454,7 @@
  *       uint32 ticket_age_add;
  *       uint8 ticket_flags;
  *       opaque resumption_key<0..255>;
+ *       uint32 max_early_data_size;
  *       select ( endpoint ) {
  *            case client: ClientOnlyData;
  *            case server: uint64 start_time;
@@ -2486,6 +2487,10 @@
     }
     needed += session->resumption_key_len;  /* resumption_key */
 
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+    needed += 4;                            /* max_early_data_size */
+#endif
+
 #if defined(MBEDTLS_HAVE_TIME)
     needed += 8; /* start_time or ticket_received */
 #endif
@@ -2525,6 +2530,11 @@
     memcpy(p, session->resumption_key, session->resumption_key_len);
     p += session->resumption_key_len;
 
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+    MBEDTLS_PUT_UINT32_BE(session->max_early_data_size, p, 0);
+    p += 4;
+#endif
+
 #if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
     if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
         MBEDTLS_PUT_UINT64_BE((uint64_t) session->start, p, 0);
@@ -2593,6 +2603,14 @@
     memcpy(session->resumption_key, p, session->resumption_key_len);
     p += session->resumption_key_len;
 
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+    if (end - p < 4) {
+        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+    }
+    session->max_early_data_size = MBEDTLS_GET_UINT32_BE(p, 0);
+    p += 4;
+#endif
+
 #if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
     if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
         if (end - p < 8) {
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index 061dcf7..b418ee6 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -472,6 +472,10 @@
     }
     memcpy(dst->resumption_key, src->resumption_key, src->resumption_key_len);
 
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+    dst->max_early_data_size = src->max_early_data_size;
+#endif
+
     return 0;
 }
 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c
index be2aede..54b57be 100644
--- a/tests/src/test_helpers/ssl_helpers.c
+++ b/tests/src/test_helpers/ssl_helpers.c
@@ -1746,6 +1746,10 @@
     session->resumption_key_len = 32;
     memset(session->resumption_key, 0x99, sizeof(session->resumption_key));
 
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+    session->max_early_data_size = 0x87654321;
+#endif
+
 #if defined(MBEDTLS_HAVE_TIME)
     if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
         session->start = mbedtls_time(NULL) - 42;
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index a19e08a..7cdf17e 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -2041,6 +2041,12 @@
                                restored.resumption_key,
                                original.resumption_key_len) == 0);
         }
+
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+        TEST_ASSERT(
+            original.max_early_data_size == restored.max_early_data_size);
+#endif
+
 #if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
         if (endpoint_type == MBEDTLS_SSL_IS_SERVER) {
             TEST_ASSERT(original.start == restored.start);