Merge pull request #6788 from yuhaoth/pr/fix-gnutls_anti_replay_fail

TLS 1.3: Fix anti replay fail from GnuTLS
diff --git a/ChangeLog.d/gnutls_anti_replay_fail.txt b/ChangeLog.d/gnutls_anti_replay_fail.txt
new file mode 100644
index 0000000..cb35284
--- /dev/null
+++ b/ChangeLog.d/gnutls_anti_replay_fail.txt
@@ -0,0 +1,5 @@
+Bugfix
+    * Switch to milliseconds as the unit for ticket creation and reception time
+      instead of seconds. That avoids rounding errors when computing the age of
+      tickets compared to peer using a millisecond clock (observed with GnuTLS).
+      Fixes #6623.
diff --git a/include/mbedtls/debug.h b/include/mbedtls/debug.h
index 0aef2ed..9a17488 100644
--- a/include/mbedtls/debug.h
+++ b/include/mbedtls/debug.h
@@ -120,7 +120,12 @@
     /* (defined(__MINGW32__)  && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800) */
 
 #if !defined(MBEDTLS_PRINTF_MS_TIME)
+#include <inttypes.h>
+#if !defined(PRId64)
+#define MBEDTLS_PRINTF_MS_TIME MBEDTLS_PRINTF_LONGLONG
+#else
 #define MBEDTLS_PRINTF_MS_TIME PRId64
+#endif
 #endif /* MBEDTLS_PRINTF_MS_TIME */
 
 #ifdef __cplusplus
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index d137f00..a4e90c5 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -4099,20 +4099,23 @@
 /**
  * \def MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE
  *
- * Maximum time difference in milliseconds tolerated between the age of a
- * ticket from the server and client point of view.
- * From the client point of view, the age of a ticket is the time difference
- * between the time when the client proposes to the server to use the ticket
- * (time of writing of the Pre-Shared Key Extension including the ticket) and
- * the time the client received the ticket from the server.
- * From the server point of view, the age of a ticket is the time difference
- * between the time when the server receives a proposition from the client
- * to use the ticket and the time when the ticket was created by the server.
- * The server age is expected to be always greater than the client one and
- * MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE defines the
- * maximum difference tolerated for the server to accept the ticket.
- * This is not used in TLS 1.2.
+ * Maximum allowed ticket age difference in milliseconds tolerated between
+ * server and client. Default value is 6000. This is not used in TLS 1.2.
  *
+ * - The client ticket age is the time difference between the time when the
+ *   client proposes to the server to use the ticket and the time the client
+ *   received the ticket from the server.
+ * - The server ticket age is the time difference between the time when the
+ *   server receives a proposition from the client to use the ticket and the
+ *   time when the ticket was created by the server.
+ *
+ * The ages might be different due to the client and server clocks not running
+ * at the same pace. The typical accuracy of an RTC crystal is ±100 to ±20 parts
+ * per million (360 to 72 milliseconds per hour). Default tolerance window is
+ * 6s, thus in the worst case clients and servers must sync up their system time
+ * every 6000/360/2~=8 hours.
+ *
+ * See section 8.3 of the TLS 1.3 specification(RFC 8446) for more information.
  */
 //#define MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE 6000
 
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 7294bb1..07a9e88 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1217,7 +1217,7 @@
     mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(tls_version);
 
 #if defined(MBEDTLS_HAVE_TIME)
-    mbedtls_time_t MBEDTLS_PRIVATE(start);       /*!< starting time      */
+    mbedtls_time_t MBEDTLS_PRIVATE(start);       /*!< start time of current session */
 #endif
     int MBEDTLS_PRIVATE(ciphersuite);            /*!< chosen ciphersuite */
     size_t MBEDTLS_PRIVATE(id_len);              /*!< session id length  */
@@ -1254,9 +1254,14 @@
     char *MBEDTLS_PRIVATE(hostname);             /*!< host name binded with tickets */
 #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION && MBEDTLS_SSL_CLI_C */
 
-#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_CLI_C)
-    mbedtls_time_t MBEDTLS_PRIVATE(ticket_received);        /*!< time ticket was received */
-#endif /* MBEDTLS_HAVE_TIME && MBEDTLS_SSL_CLI_C */
+#if defined(MBEDTLS_HAVE_TIME)
+#if defined(MBEDTLS_SSL_CLI_C)
+    mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_reception_time);   /*!< time when ticket was received. */
+#endif
+#if defined(MBEDTLS_SSL_SRV_C)
+    mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_creation_time);    /*!< time when ticket was created. */
+#endif
+#endif /* MBEDTLS_HAVE_TIME */
 
 #endif /*  MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */
 
diff --git a/library/ssl_client.c b/library/ssl_client.c
index 7a78406..0e87d86 100644
--- a/library/ssl_client.c
+++ b/library/ssl_client.c
@@ -756,10 +756,9 @@
     if (ssl->handshake->resume != 0 &&
         session_negotiate->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
         session_negotiate->ticket != NULL) {
-        mbedtls_time_t now = mbedtls_time(NULL);
-        uint64_t age = (uint64_t) (now - session_negotiate->ticket_received);
-        if (session_negotiate->ticket_received > now ||
-            age > session_negotiate->ticket_lifetime) {
+        mbedtls_ms_time_t now = mbedtls_ms_time();
+        mbedtls_ms_time_t age = now - session_negotiate->ticket_reception_time;
+        if (age < 0 || age > session_negotiate->ticket_lifetime * 1000) {
             /* Without valid ticket, disable session resumption.*/
             MBEDTLS_SSL_DEBUG_MSG(
                 3, ("Ticket expired, disable session resumption"));
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 8482ee1..c636ad4 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -2765,6 +2765,9 @@
 #endif
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
+
+#define MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME (604800)
+
 static inline unsigned int mbedtls_ssl_session_get_ticket_flags(
     mbedtls_ssl_session *session, unsigned int flags)
 {
diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c
index 875abcb..61c87be 100644
--- a/library/ssl_ticket.c
+++ b/library/ssl_ticket.c
@@ -495,7 +495,31 @@
     }
 
 #if defined(MBEDTLS_HAVE_TIME)
-    {
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+    if (session->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
+        /* Check for expiration */
+        mbedtls_ms_time_t ticket_age = -1;
+#if defined(MBEDTLS_SSL_SRV_C)
+        if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
+            ticket_age = mbedtls_ms_time() - session->ticket_creation_time;
+        }
+#endif
+#if defined(MBEDTLS_SSL_CLI_C)
+        if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
+            ticket_age = mbedtls_ms_time() - session->ticket_reception_time;
+        }
+#endif
+
+        mbedtls_ms_time_t ticket_lifetime = ctx->ticket_lifetime * 1000;
+
+        if (ticket_age < 0 || ticket_age > ticket_lifetime) {
+            ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
+            goto cleanup;
+        }
+    }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    if (session->tls_version == MBEDTLS_SSL_VERSION_TLS1_2) {
         /* Check for expiration */
         mbedtls_time_t current_time = mbedtls_time(NULL);
 
@@ -505,7 +529,8 @@
             goto cleanup;
         }
     }
-#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+#endif /* MBEDTLS_HAVE_TIME */
 
 cleanup:
 #if defined(MBEDTLS_THREADING_C)
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index f855576..944caa0 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -2443,7 +2443,7 @@
  *
  *     struct {
  *       opaque hostname<0..2^16-1>;
- *       uint64 ticket_received;
+ *       uint64 ticket_reception_time;
  *       uint32 ticket_lifetime;
  *       opaque ticket<1..2^16-1>;
  *     } ClientOnlyData;
@@ -2457,7 +2457,7 @@
  *       uint32 max_early_data_size;
  *       select ( endpoint ) {
  *            case client: ClientOnlyData;
- *            case server: uint64 start_time;
+ *            case server: uint64 ticket_creation_time;
  *        };
  *     } serialized_session_tls13;
  *
@@ -2492,7 +2492,7 @@
 #endif
 
 #if defined(MBEDTLS_HAVE_TIME)
-    needed += 8; /* start_time or ticket_received */
+    needed += 8; /* ticket_creation_time or ticket_reception_time */
 #endif
 
 #if defined(MBEDTLS_SSL_CLI_C)
@@ -2537,7 +2537,7 @@
 
 #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);
+        MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_creation_time, p, 0);
         p += 8;
     }
 #endif /* MBEDTLS_HAVE_TIME */
@@ -2555,7 +2555,7 @@
 #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
 
 #if defined(MBEDTLS_HAVE_TIME)
-        MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_received, p, 0);
+        MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_reception_time, p, 0);
         p += 8;
 #endif
         MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0);
@@ -2616,7 +2616,7 @@
         if (end - p < 8) {
             return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
         }
-        session->start = MBEDTLS_GET_UINT64_BE(p, 0);
+        session->ticket_creation_time = MBEDTLS_GET_UINT64_BE(p, 0);
         p += 8;
     }
 #endif /* MBEDTLS_HAVE_TIME */
@@ -2651,7 +2651,7 @@
         if (end - p < 8) {
             return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
         }
-        session->ticket_received = MBEDTLS_GET_UINT64_BE(p, 0);
+        session->ticket_reception_time = MBEDTLS_GET_UINT64_BE(p, 0);
         p += 8;
 #endif
         if (end - p < 4) {
diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c
index eac6326..44814b9 100644
--- a/library/ssl_tls13_client.c
+++ b/library/ssl_tls13_client.c
@@ -931,28 +931,14 @@
     if (ssl_tls13_ticket_get_identity(
             ssl, &hash_alg, &identity, &identity_len) == 0) {
 #if defined(MBEDTLS_HAVE_TIME)
-        mbedtls_time_t now = mbedtls_time(NULL);
+        mbedtls_ms_time_t now = mbedtls_ms_time();
         mbedtls_ssl_session *session = ssl->session_negotiate;
+        /* The ticket age has been checked to be smaller than the
+         * `ticket_lifetime` in ssl_prepare_client_hello() which is smaller than
+         * 7 days (enforced in ssl_tls13_parse_new_session_ticket()) . Thus the
+         * cast to `uint32_t` of the ticket age is safe. */
         uint32_t obfuscated_ticket_age =
-            (uint32_t) (now - session->ticket_received);
-
-        /*
-         * The ticket timestamp is in seconds but the ticket age is in
-         * milliseconds. If the ticket was received at the end of a second and
-         * re-used here just at the beginning of the next second, the computed
-         * age `now - session->ticket_received` is equal to 1s thus 1000 ms
-         * while the actual age could be just a few milliseconds or tens of
-         * milliseconds. If the server has more accurate ticket timestamps
-         * (typically timestamps in milliseconds), as part of the processing of
-         * the ClientHello, it may compute a ticket lifetime smaller than the
-         * one computed here and potentially reject the ticket. To avoid that,
-         * remove one second to the ticket age if possible.
-         */
-        if (obfuscated_ticket_age > 0) {
-            obfuscated_ticket_age -= 1;
-        }
-
-        obfuscated_ticket_age *= 1000;
+            (uint32_t) (now - session->ticket_reception_time);
         obfuscated_ticket_age += session->ticket_age_add;
 
         ret = ssl_tls13_write_identity(ssl, p, end,
@@ -2762,6 +2748,11 @@
     MBEDTLS_SSL_DEBUG_MSG(3,
                           ("ticket_lifetime: %u",
                            (unsigned int) session->ticket_lifetime));
+    if (session->ticket_lifetime >
+        MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME) {
+        MBEDTLS_SSL_DEBUG_MSG(3, ("ticket_lifetime exceeds 7 days."));
+        return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
+    }
 
     session->ticket_age_add = MBEDTLS_GET_UINT32_BE(p, 4);
     MBEDTLS_SSL_DEBUG_MSG(3,
@@ -2837,7 +2828,7 @@
 
 #if defined(MBEDTLS_HAVE_TIME)
     /* Store ticket creation time */
-    session->ticket_received = mbedtls_time(NULL);
+    session->ticket_reception_time = mbedtls_ms_time();
 #endif
 
     ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(session->ciphersuite);
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index b418ee6..d983a00 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -111,9 +111,10 @@
     unsigned char *ticket_buffer;
     unsigned int key_exchanges;
 #if defined(MBEDTLS_HAVE_TIME)
-    mbedtls_time_t now;
-    uint64_t age_in_s;
-    int64_t age_diff_in_ms;
+    mbedtls_ms_time_t now;
+    mbedtls_ms_time_t server_age;
+    uint32_t client_age;
+    mbedtls_ms_time_t age_diff;
 #endif
 
     ((void) obfuscated_ticket_age);
@@ -190,17 +191,17 @@
 
     ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
 #if defined(MBEDTLS_HAVE_TIME)
-    now = mbedtls_time(NULL);
+    now = mbedtls_ms_time();
 
-    if (now < session->start) {
+    if (now < session->ticket_creation_time) {
         MBEDTLS_SSL_DEBUG_MSG(
-            3, ("Invalid ticket start time ( now=%" MBEDTLS_PRINTF_LONGLONG
-                ", start=%" MBEDTLS_PRINTF_LONGLONG " )",
-                (long long) now, (long long) session->start));
+            3, ("Invalid ticket creation time ( now = %" MBEDTLS_PRINTF_MS_TIME
+                ", creation_time = %" MBEDTLS_PRINTF_MS_TIME " )",
+                now, session->ticket_creation_time));
         goto exit;
     }
 
-    age_in_s = (uint64_t) (now - session->start);
+    server_age = now - session->ticket_creation_time;
 
     /* RFC 8446 section 4.6.1
      *
@@ -211,12 +212,11 @@
      * Clients MUST NOT attempt to use tickets which have ages greater than
      * the "ticket_lifetime" value which was provided with the ticket.
      *
-     * For time being, the age MUST be less than 604800 seconds (7 days).
      */
-    if (age_in_s > 604800) {
+    if (server_age > MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME * 1000) {
         MBEDTLS_SSL_DEBUG_MSG(
-            3, ("Ticket age exceeds limitation ticket_age=%lu",
-                (long unsigned int) age_in_s));
+            3, ("Ticket age exceeds limitation ticket_age = %" MBEDTLS_PRINTF_MS_TIME,
+                server_age));
         goto exit;
     }
 
@@ -227,18 +227,19 @@
      * ticket_age_add from PskIdentity.obfuscated_ticket_age modulo 2^32) is
      * within a small tolerance of the time since the ticket was issued.
      *
-     * NOTE: When `now == session->start`, `age_diff_in_ms` may be negative
-     *       as the age units are different on the server (s) and in the
-     *       client (ms) side. Add a -1000 ms tolerance window to take this
-     *       into account.
+     * NOTE: The typical accuracy of an RTC crystal is ±100 to ±20 parts per
+     *       million (360 to 72 milliseconds per hour). Default tolerance
+     *       window is 6s, thus in the worst case clients and servers must
+     *       sync up their system time every 6000/360/2~=8 hours.
      */
-    age_diff_in_ms = age_in_s * 1000;
-    age_diff_in_ms -= (obfuscated_ticket_age - session->ticket_age_add);
-    if (age_diff_in_ms <= -1000 ||
-        age_diff_in_ms > MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE) {
+    client_age = obfuscated_ticket_age - session->ticket_age_add;
+    age_diff = server_age - (mbedtls_ms_time_t) client_age;
+    if (age_diff < -MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE ||
+        age_diff > MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE) {
         MBEDTLS_SSL_DEBUG_MSG(
-            3, ("Ticket age outside tolerance window ( diff=%d )",
-                (int) age_diff_in_ms));
+            3, ("Ticket age outside tolerance window ( diff = %"
+                MBEDTLS_PRINTF_MS_TIME ")",
+                age_diff));
         goto exit;
     }
 
@@ -2877,7 +2878,7 @@
     MBEDTLS_SSL_DEBUG_MSG(2, ("=> prepare NewSessionTicket msg"));
 
 #if defined(MBEDTLS_HAVE_TIME)
-    session->start = mbedtls_time(NULL);
+    session->ticket_creation_time = mbedtls_ms_time();
 #endif
 
     /* Set ticket_flags depends on the advertised psk key exchange mode */
@@ -3024,8 +3025,8 @@
      *      MAY treat a ticket as valid for a shorter period of time than what
      *      is stated in the ticket_lifetime.
      */
-    if (ticket_lifetime > 604800) {
-        ticket_lifetime = 604800;
+    if (ticket_lifetime > MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME) {
+        ticket_lifetime = MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME;
     }
     MBEDTLS_PUT_UINT32_BE(ticket_lifetime, p, 0);
     MBEDTLS_SSL_DEBUG_MSG(3, ("ticket_lifetime: %u",
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 3e2360e..c96128b 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -1419,22 +1419,29 @@
             return MBEDTLS_ERR_SSL_INVALID_MAC;
         case 2:
             return MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
         case 3:
-            session->start = mbedtls_time(NULL) + 10;
+            /* Creation time in the future. */
+            session->ticket_creation_time = mbedtls_ms_time() + 1000;
             break;
         case 4:
-            session->start = mbedtls_time(NULL) - 10 - 7 * 24 * 3600;
+            /* Ticket has reached the end of lifetime. */
+            session->ticket_creation_time = mbedtls_ms_time() -
+                                            (7 * 24 * 3600 * 1000 + 1000);
             break;
         case 5:
-            session->start = mbedtls_time(NULL) - 10;
+            /* Ticket is valid, but client age is below the lower bound of the tolerance window. */
+            session->ticket_age_add += MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE + 4 * 1000;
+            /* Make sure the execution time does not affect the result */
+            session->ticket_creation_time = mbedtls_ms_time();
             break;
+
         case 6:
-            session->start = mbedtls_time(NULL);
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
-            session->ticket_age_add -= 1000;
-#endif
+            /* Ticket is valid, but client age is beyond the upper bound of the tolerance window. */
+            session->ticket_age_add -= MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE + 4 * 1000;
+            /* Make sure the execution time does not affect the result */
+            session->ticket_creation_time = mbedtls_ms_time();
             break;
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
         case 7:
             session->ticket_flags = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE;
             break;
diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh
index 3816a2b..9208384 100755
--- a/tests/opt-testcases/tls13-misc.sh
+++ b/tests/opt-testcases/tls13-misc.sh
@@ -86,7 +86,7 @@
          -S "key exchange mode: psk$" \
          -s "ticket is not authentic" \
          -S "ticket is expired" \
-         -S "Invalid ticket start time" \
+         -S "Invalid ticket creation time" \
          -S "Ticket age exceeds limitation" \
          -S "Ticket age outside tolerance window"
 
@@ -105,7 +105,7 @@
          -S "key exchange mode: psk$" \
          -S "ticket is not authentic" \
          -s "ticket is expired" \
-         -S "Invalid ticket start time" \
+         -S "Invalid ticket creation time" \
          -S "Ticket age exceeds limitation" \
          -S "Ticket age outside tolerance window"
 
@@ -124,7 +124,7 @@
          -S "key exchange mode: psk$" \
          -S "ticket is not authentic" \
          -S "ticket is expired" \
-         -s "Invalid ticket start time" \
+         -s "Invalid ticket creation time" \
          -S "Ticket age exceeds limitation" \
          -S "Ticket age outside tolerance window"
 
@@ -143,7 +143,7 @@
          -S "key exchange mode: psk$" \
          -S "ticket is not authentic" \
          -S "ticket is expired" \
-         -S "Invalid ticket start time" \
+         -S "Invalid ticket creation time" \
          -s "Ticket age exceeds limitation" \
          -S "Ticket age outside tolerance window"
 
@@ -162,7 +162,7 @@
          -S "key exchange mode: psk$" \
          -S "ticket is not authentic" \
          -S "ticket is expired" \
-         -S "Invalid ticket start time" \
+         -S "Invalid ticket creation time" \
          -S "Ticket age exceeds limitation" \
          -s "Ticket age outside tolerance window"
 
@@ -181,7 +181,7 @@
          -S "key exchange mode: psk$" \
          -S "ticket is not authentic" \
          -S "ticket is expired" \
-         -S "Invalid ticket start time" \
+         -S "Invalid ticket creation time" \
          -S "Ticket age exceeds limitation" \
          -s "Ticket age outside tolerance window"
 
diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c
index 54b57be..d02d305 100644
--- a/tests/src/test_helpers/ssl_helpers.c
+++ b/tests/src/test_helpers/ssl_helpers.c
@@ -1633,6 +1633,7 @@
 }
 #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 int mbedtls_test_ssl_tls12_populate_session(mbedtls_ssl_session *session,
                                             int ticket_len,
                                             const char *crt_file)
@@ -1729,6 +1730,7 @@
 
     return 0;
 }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
 int mbedtls_test_ssl_tls13_populate_session(mbedtls_ssl_session *session,
@@ -1750,16 +1752,16 @@
     session->max_early_data_size = 0x87654321;
 #endif
 
-#if defined(MBEDTLS_HAVE_TIME)
+#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
     if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
-        session->start = mbedtls_time(NULL) - 42;
+        session->ticket_creation_time = mbedtls_ms_time() - 42;
     }
 #endif
 
 #if defined(MBEDTLS_SSL_CLI_C)
     if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
 #if defined(MBEDTLS_HAVE_TIME)
-        session->ticket_received = mbedtls_time(NULL) - 40;
+        session->ticket_reception_time = mbedtls_ms_time() - 40;
 #endif
         session->ticket_lifetime = 0xfedcba98;
 
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index 7cdf17e..85776cc 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -1943,16 +1943,21 @@
     /* Prepare a dummy session to work on */
     ((void) endpoint_type);
     ((void) tls_version);
+    ((void) ticket_len);
+    ((void) crt_file);
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
     if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
         TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
                         &original, 0, endpoint_type) == 0);
-    } else
+    }
 #endif
-    {
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    if (tls_version == MBEDTLS_SSL_VERSION_TLS1_2) {
         TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
                         &original, ticket_len, crt_file) == 0);
     }
+#endif
 
     /* Serialize it */
     TEST_ASSERT(mbedtls_ssl_session_save(&original, NULL, 0, &len)
@@ -1968,8 +1973,27 @@
      * Make sure both session structures are identical
      */
 #if defined(MBEDTLS_HAVE_TIME)
-    TEST_ASSERT(original.start == restored.start);
+    switch (tls_version) {
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SRV_C)
+        case MBEDTLS_SSL_VERSION_TLS1_3:
+            TEST_ASSERT(original.ticket_creation_time == restored.ticket_creation_time);
+            break;
 #endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        case MBEDTLS_SSL_VERSION_TLS1_2:
+            TEST_ASSERT(original.start == restored.start);
+            break;
+#endif
+
+        default:
+            /* should never happen */
+            TEST_ASSERT(0);
+            break;
+    }
+
+
+#endif
+
     TEST_ASSERT(original.tls_version == restored.tls_version);
     TEST_ASSERT(original.ciphersuite == restored.ciphersuite);
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
@@ -2049,13 +2073,13 @@
 
 #if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
         if (endpoint_type == MBEDTLS_SSL_IS_SERVER) {
-            TEST_ASSERT(original.start == restored.start);
+            TEST_ASSERT(original.ticket_creation_time == restored.ticket_creation_time);
         }
 #endif
 #if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
         if (endpoint_type == MBEDTLS_SSL_IS_CLIENT) {
 #if defined(MBEDTLS_HAVE_TIME)
-            TEST_ASSERT(original.ticket_received == restored.ticket_received);
+            TEST_ASSERT(original.ticket_reception_time == restored.ticket_reception_time);
 #endif
             TEST_ASSERT(original.ticket_lifetime == restored.ticket_lifetime);
             TEST_ASSERT(original.ticket_len == restored.ticket_len);
@@ -2096,16 +2120,27 @@
 
     /* Prepare a dummy session to work on */
     ((void) endpoint_type);
-    ((void) tls_version);
+    ((void) ticket_len);
+    ((void) crt_file);
+
+    switch (tls_version) {
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
-    if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
-        TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
-                        &session, 0, endpoint_type) == 0);
-    } else
+        case MBEDTLS_SSL_VERSION_TLS1_3:
+            TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
+                            &session, 0, endpoint_type) == 0);
+            break;
 #endif
-    {
-        TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
-                        &session, ticket_len, crt_file) == 0);
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        case MBEDTLS_SSL_VERSION_TLS1_2:
+            TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
+                            &session, ticket_len, crt_file) == 0);
+            break;
+#endif
+        default:
+            /* should never happen */
+            TEST_ASSERT(0);
+            break;
     }
 
     /* Get desired buffer size for serializing */
@@ -2159,17 +2194,28 @@
 
     /* Prepare dummy session and get serialized size */
     ((void) endpoint_type);
-    ((void) tls_version);
+    ((void) ticket_len);
+    ((void) crt_file);
+
+    switch (tls_version) {
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
-    if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
-        TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
-                        &session, 0, endpoint_type) == 0);
-    } else
+        case MBEDTLS_SSL_VERSION_TLS1_3:
+            TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
+                            &session, 0, endpoint_type) == 0);
+            break;
 #endif
-    {
-        TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
-                        &session, ticket_len, crt_file) == 0);
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        case MBEDTLS_SSL_VERSION_TLS1_2:
+            TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
+                            &session, ticket_len, crt_file) == 0);
+            break;
+#endif
+        default:
+            /* should never happen */
+            TEST_ASSERT(0);
+            break;
     }
+
     TEST_ASSERT(mbedtls_ssl_session_save(&session, NULL, 0, &good_len)
                 == MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL);
 
@@ -2208,17 +2254,30 @@
 
     /* Prepare serialized session data */
     ((void) endpoint_type);
-    ((void) tls_version);
+    ((void) ticket_len);
+    ((void) crt_file);
+
+    switch (tls_version) {
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
-    if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
-        TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
-                        &session, 0, endpoint_type) == 0);
-    } else
+        case MBEDTLS_SSL_VERSION_TLS1_3:
+            TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
+                            &session, 0, endpoint_type) == 0);
+            break;
 #endif
-    {
-        TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
-                        &session, ticket_len, crt_file) == 0);
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        case MBEDTLS_SSL_VERSION_TLS1_2:
+            TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
+                            &session, ticket_len, crt_file) == 0);
+            break;
+#endif
+
+        default:
+            /* should never happen */
+            TEST_ASSERT(0);
+            break;
     }
+
     TEST_ASSERT(mbedtls_ssl_session_save(&session, NULL, 0, &good_len)
                 == MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL);
     TEST_CALLOC(good_buf, good_len);
@@ -2267,16 +2326,26 @@
     mbedtls_ssl_session_init(&session);
     USE_PSA_INIT();
     ((void) endpoint_type);
-    ((void) tls_version);
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
-    if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
-        TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
-                        &session, 0, endpoint_type) == 0);
-    } else
-#endif
-    TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
-                    &session, 0, NULL) == 0);
 
+    switch (tls_version) {
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+        case MBEDTLS_SSL_VERSION_TLS1_3:
+            TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session(
+                            &session, 0, endpoint_type) == 0);
+            break;
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        case MBEDTLS_SSL_VERSION_TLS1_2:
+            TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session(
+                            &session, 0, NULL) == 0);
+
+            break;
+#endif
+        default:
+            /* should never happen */
+            TEST_ASSERT(0);
+            break;
+    }
 
     /* Infer length of serialized session. */
     TEST_ASSERT(mbedtls_ssl_session_save(&session,