Merge pull request #6616 from lpy4105/6551-tls13-SessionTicket-kex-change-check

This PR needs some change logs but there is a follow-up PR (issue #6935) that would change the change logs we would had here thus we will do them all while working on #6935.
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 661b23c..dbc37e8 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -809,8 +809,6 @@
 #endif
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
-typedef uint8_t mbedtls_ssl_tls13_ticket_flags;
-
 #define MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_RESUMPTION                          \
     MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK                        /* 1U << 0 */
 #define MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_PSK_EPHEMERAL_RESUMPTION                \
diff --git a/library/ssl_debug_helpers.h b/library/ssl_debug_helpers.h
index 4d2a170..5c22ed2 100644
--- a/library/ssl_debug_helpers.h
+++ b/library/ssl_debug_helpers.h
@@ -55,6 +55,12 @@
                                  int hs_msg_type, unsigned int extension_type,
                                  const char *extra_msg0, const char *extra_msg1);
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
+void mbedtls_ssl_print_ticket_flags(const mbedtls_ssl_context *ssl,
+                                    int level, const char *file, int line,
+                                    unsigned int flags);
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */
+
 #define MBEDTLS_SSL_PRINT_EXTS(level, hs_msg_type, extensions_mask)            \
     mbedtls_ssl_print_extensions(ssl, level, __FILE__, __LINE__,       \
                                  hs_msg_type, extensions_mask, NULL)
@@ -63,12 +69,22 @@
     mbedtls_ssl_print_extension(ssl, level, __FILE__, __LINE__,        \
                                 hs_msg_type, extension_type,           \
                                 extra, NULL)
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
+#define MBEDTLS_SSL_PRINT_TICKET_FLAGS(level, flags)             \
+    mbedtls_ssl_print_ticket_flags(ssl, level, __FILE__, __LINE__, flags)
+#endif
+
 #else
 
 #define MBEDTLS_SSL_PRINT_EXTS(level, hs_msg_type, extension_mask)
 
 #define MBEDTLS_SSL_PRINT_EXT(level, hs_msg_type, extension_type, extra)
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
+#define MBEDTLS_SSL_PRINT_TICKET_FLAGS(level, flags)
+#endif
+
 #endif /* MBEDTLS_DEBUG_C */
 
 #endif /* MBEDTLS_SSL_DEBUG_HELPERS_H */
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 16eccfc..146dae0 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -2719,4 +2719,25 @@
                                      const char *hostname);
 #endif
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
+static inline unsigned int mbedtls_ssl_session_get_ticket_flags(
+    mbedtls_ssl_session *session, unsigned int flags)
+{
+    return session->ticket_flags &
+           (flags & MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
+}
+
+static inline void mbedtls_ssl_session_set_ticket_flags(
+    mbedtls_ssl_session *session, unsigned int flags)
+{
+    session->ticket_flags |= (flags & MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
+}
+
+static inline void mbedtls_ssl_session_clear_ticket_flags(
+    mbedtls_ssl_session *session, unsigned int flags)
+{
+    session->ticket_flags &= ~(flags & MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */
+
 #endif /* ssl_misc.h */
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index bd8fd8c..86f5c0b 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -735,6 +735,36 @@
     }
 }
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS)
+#define ARRAY_LENGTH(a) (sizeof(a) / sizeof(*(a)))
+
+static const char *ticket_flag_name_table[] =
+{
+    [0] = "ALLOW_PSK_RESUMPTION",
+    [2] = "ALLOW_PSK_EPHEMERAL_RESUMPTION",
+    [3] = "ALLOW_EARLY_DATA",
+};
+
+void mbedtls_ssl_print_ticket_flags(const mbedtls_ssl_context *ssl,
+                                    int level, const char *file, int line,
+                                    unsigned int flags)
+{
+    size_t i;
+
+    mbedtls_debug_print_msg(ssl, level, file, line,
+                            "print ticket_flags (0x%02x)", flags);
+
+    flags = flags & MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK;
+
+    for (i = 0; i < ARRAY_LENGTH(ticket_flag_name_table); i++) {
+        if ((flags & (1 << i))) {
+            mbedtls_debug_print_msg(ssl, level, file, line, "- %s is set.",
+                                    ticket_flag_name_table[i]);
+        }
+    }
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */
+
 #endif /* MBEDTLS_DEBUG_C */
 
 void mbedtls_ssl_optimize_checksum(mbedtls_ssl_context *ssl,
diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c
index 291a4cf..4aea61c 100644
--- a/library/ssl_tls13_client.c
+++ b/library/ssl_tls13_client.c
@@ -676,7 +676,10 @@
 {
     mbedtls_ssl_session *session = ssl->session_negotiate;
     return ssl->handshake->resume &&
-           session != NULL && session->ticket != NULL;
+           session != NULL && session->ticket != NULL &&
+           mbedtls_ssl_conf_tls13_check_kex_modes(
+        ssl, mbedtls_ssl_session_get_ticket_flags(
+            session, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL));
 }
 
 #if defined(MBEDTLS_SSL_EARLY_DATA)
@@ -2618,6 +2621,10 @@
     session->ticket = ticket;
     session->ticket_len = ticket_len;
 
+    /* Clear all flags in ticket_flags */
+    mbedtls_ssl_session_clear_ticket_flags(
+        session, MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
+
     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
     extensions_len = MBEDTLS_GET_UINT16_BE(p, 0);
     p += 2;
@@ -2701,6 +2708,11 @@
                           session->resumption_key,
                           session->resumption_key_len);
 
+    /* Set ticket_flags depends on the selected key exchange modes */
+    mbedtls_ssl_session_set_ticket_flags(
+        session, ssl->conf->tls13_kex_modes);
+    MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags);
+
     return 0;
 }
 
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index 980c225..ef90f69 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -161,6 +161,26 @@
         goto exit;
     }
 
+    /* RFC 8446 section 4.2.9
+     *
+     * Servers SHOULD NOT send NewSessionTicket with tickets that are not
+     * compatible with the advertised modes; however, if a server does so,
+     * the impact will just be that the client's attempts at resumption fail.
+     *
+     * We regard the ticket with incompatible key exchange modes as not match.
+     */
+    ret = MBEDTLS_ERR_ERROR_GENERIC_ERROR;
+    MBEDTLS_SSL_PRINT_TICKET_FLAGS(4,
+                                   session->ticket_flags);
+    if (mbedtls_ssl_tls13_check_kex_modes(
+            ssl,
+            mbedtls_ssl_session_get_ticket_flags(
+                session,
+                MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL))) {
+        MBEDTLS_SSL_DEBUG_MSG(3, ("No suitable key exchange mode"));
+        goto exit;
+    }
+
     ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
 #if defined(MBEDTLS_HAVE_TIME)
     now = mbedtls_time(NULL);
@@ -2549,11 +2569,20 @@
 
     mbedtls_ssl_tls13_handshake_wrapup(ssl);
 
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
-    mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET);
-#else
-    mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER);
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \
+    defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
+/* TODO: Remove the check of SOME_PSK_ENABLED since SESSION_TICKETS requires
+ *       SOME_PSK_ENABLED to be enabled. Here is just to make CI happy. It is
+ *       expected to be resolved with issue#6395.
+ */
+    /* Sent NewSessionTicket message only when client supports PSK */
+    if (mbedtls_ssl_tls13_some_psk_enabled(ssl)) {
+        mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET);
+    } else
 #endif
+    {
+        mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER);
+    }
     return 0;
 }
 
@@ -2604,6 +2633,15 @@
     session->start = mbedtls_time(NULL);
 #endif
 
+    /* Set ticket_flags depends on the advertised psk key exchange mode */
+    mbedtls_ssl_session_clear_ticket_flags(
+        session, MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
+#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
+    mbedtls_ssl_session_set_ticket_flags(
+        session, ssl->handshake->tls13_kex_modes);
+#endif
+    MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags);
+
     /* Generate ticket_age_add */
     if ((ret = ssl->conf->f_rng(ssl->conf->p_rng,
                                 (unsigned char *) &session->ticket_age_add,
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 4b3799f..b124065 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -371,7 +371,8 @@
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
 #define USAGE_TLS1_3_KEY_EXCHANGE_MODES \
     "    tls13_kex_modes=%%s   default: all\n"     \
-    "                          options: psk, psk_ephemeral, ephemeral, ephemeral_all, psk_all, all\n"
+    "                          options: psk, psk_ephemeral, psk_all, ephemeral,\n"     \
+    "                                   ephemeral_all, all, psk_or_ephemeral\n"
 #else
 #define USAGE_TLS1_3_KEY_EXCHANGE_MODES ""
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
@@ -1215,6 +1216,9 @@
                 opt.tls13_kex_modes = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL;
             } else if (strcmp(q, "all") == 0) {
                 opt.tls13_kex_modes = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_ALL;
+            } else if (strcmp(q, "psk_or_ephemeral") == 0) {
+                opt.tls13_kex_modes = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK |
+                                      MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL;
             } else {
                 goto usage;
             }
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 90a13eb..b3d9f5a 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -1412,7 +1412,7 @@
         return ret;
     }
 
-    switch (opt.dummy_ticket % 7) {
+    switch (opt.dummy_ticket % 11) {
         case 1:
             return MBEDTLS_ERR_SSL_INVALID_MAC;
         case 2:
@@ -1432,6 +1432,20 @@
             session->ticket_age_add -= 1000;
 #endif
             break;
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+        case 7:
+            session->ticket_flags = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE;
+            break;
+        case 8:
+            session->ticket_flags = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
+            break;
+        case 9:
+            session->ticket_flags = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
+            break;
+        case 10:
+            session->ticket_flags = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL;
+            break;
+#endif
         default:
             break;
     }
diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh
index 3aaf3f3..821a37b 100755
--- a/tests/opt-testcases/tls13-misc.sh
+++ b/tests/opt-testcases/tls13-misc.sh
@@ -323,3 +323,171 @@
             -c "EncryptedExtensions: early_data(42) extension received." \
             -c "EncryptedExtensions: early_data(42) extension ( ignored )."
 
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/none." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=7" \
+         "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "sent selected_identity:" \
+         -s "key exchange mode: ephemeral" \
+         -S "key exchange mode: psk_ephemeral" \
+         -S "key exchange mode: psk$" \
+         -s "No suitable key exchange mode" \
+         -s "No matched PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=8" \
+         "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "No suitable key exchange mode" \
+         -s "found matched identity"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk_ephemeral." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=9" \
+         "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "sent selected_identity:" \
+         -s "key exchange mode: ephemeral" \
+         -S "key exchange mode: psk_ephemeral" \
+         -S "key exchange mode: psk$" \
+         -s "No suitable key exchange mode" \
+         -s "No matched PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk_all." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=10" \
+         "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "No suitable key exchange mode" \
+         -s "found matched identity"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/none." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=7" \
+         "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "sent selected_identity:" \
+         -s "key exchange mode: ephemeral" \
+         -S "key exchange mode: psk_ephemeral" \
+         -S "key exchange mode: psk$" \
+         -s "No suitable key exchange mode" \
+         -s "No matched PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=8" \
+         "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "sent selected_identity:" \
+         -s "key exchange mode: ephemeral" \
+         -S "key exchange mode: psk_ephemeral" \
+         -S "key exchange mode: psk$" \
+         -s "No suitable key exchange mode" \
+         -s "No matched PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk_ephemeral." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=9" \
+         "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "No suitable key exchange mode" \
+         -s "found matched identity"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk_all." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=10" \
+         "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "No suitable key exchange mode" \
+         -s "found matched identity"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/none." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=7" \
+         "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "sent selected_identity:" \
+         -s "key exchange mode: ephemeral" \
+         -S "key exchange mode: psk_ephemeral" \
+         -S "key exchange mode: psk$" \
+         -s "No suitable key exchange mode" \
+         -s "No matched PSK or ticket"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=8" \
+         "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "No suitable key exchange mode" \
+         -s "found matched identity"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk_ephemeral." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=9" \
+         "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "No suitable key exchange mode" \
+         -s "found matched identity"
+
+requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
+                             MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+                             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk_all." \
+         "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 dummy_ticket=10" \
+         "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \
+         0 \
+         -c "Pre-configured PSK number = 1" \
+         -S "No suitable key exchange mode" \
+         -s "found matched identity"
+