Merge pull request #9976 from mpg/defragment-ext-test-3.6

Defragment ext test 3.6
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index 693edc7..5757d20 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -92,7 +92,7 @@
         return;
     }
 
-    MBEDTLS_SSL_DEBUG_MSG(2, ("No matched ciphersuite, psk_ciphersuite_id=%x, psk_hash_alg=%lx",
+    MBEDTLS_SSL_DEBUG_MSG(1, ("No matched ciphersuite, psk_ciphersuite_id=%x, psk_hash_alg=%lx",
                               (unsigned) psk_ciphersuite_id,
                               (unsigned long) psk_hash_alg));
 }
@@ -1380,6 +1380,7 @@
     }
 
     if (ret == 0) {
+        MBEDTLS_SSL_DEBUG_MSG(2, ("no supported_versions extension"));
         return SSL_CLIENT_HELLO_TLS1_2;
     }
 
@@ -1401,6 +1402,7 @@
          * the TLS version to negotiate.
          */
         if (MBEDTLS_SSL_VERSION_TLS1_2 == ret) {
+            MBEDTLS_SSL_DEBUG_MSG(2, ("supported_versions without 1.3"));
             return SSL_CLIENT_HELLO_TLS1_2;
         }
     }
@@ -1985,6 +1987,7 @@
         }
         ssl->keep_current_message = 1;
         ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_2;
+        MBEDTLS_SSL_DEBUG_MSG(1, ("non-1.3 ClientHello left for later processing"));
         return 0;
     }
 
diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c
index 3cb6175..578b2ea 100644
--- a/tests/src/test_helpers/ssl_helpers.c
+++ b/tests/src/test_helpers/ssl_helpers.c
@@ -28,9 +28,22 @@
 {
     mbedtls_test_ssl_log_pattern *p = (mbedtls_test_ssl_log_pattern *) ctx;
 
+/* Change 0 to 1 for debugging of test cases that use this function. */
+#if 0
+    const char *q, *basename;
+    /* Extract basename from file */
+    for (q = basename = file; *q != '\0'; q++) {
+        if (*q == '/' || *q == '\\') {
+            basename = q + 1;
+        }
+    }
+    printf("%s:%04d: |%d| %s",
+           basename, line, level, str);
+#else
     (void) level;
     (void) line;
     (void) file;
+#endif
 
     if (NULL != p &&
         NULL != p->pattern &&
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index 10e10ba..2dabaea 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -5037,3 +5037,193 @@
     PSA_DONE();
 }
 /* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_DEBUG_C:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
+void inject_client_content_on_the_wire(int pk_alg,
+                                       int state, data_t *data,
+                                       char *log_pattern, int expected_ret)
+{
+    /* This function allows us to inject content at a specific state
+     * in the handshake, or when it's completed. The content is injected
+     * on the mock TCP socket, as if we were an active network attacker.
+     *
+     * This function is suitable to inject:
+     * - crafted records, at any point;
+     * - valid records that contain crafted handshake messages, but only
+     *   when the traffic is still unprotected (for TLS 1.2 that's most of the
+     *   handshake, for TLS 1.3 that's only the Hello messages);
+     * - handshake messages that are fragmented in a specific way,
+     *   under the same conditions as above.
+     */
+    enum { BUFFSIZE = 16384 };
+    mbedtls_test_ssl_endpoint server, client;
+    mbedtls_platform_zeroize(&server, sizeof(server));
+    mbedtls_platform_zeroize(&client, sizeof(client));
+    mbedtls_test_handshake_test_options options;
+    mbedtls_test_init_handshake_options(&options);
+    mbedtls_test_ssl_log_pattern srv_pattern;
+    memset(&srv_pattern, 0, sizeof(srv_pattern));
+    int ret = -1;
+
+    PSA_INIT();
+
+    srv_pattern.pattern = log_pattern;
+    options.srv_log_obj = &srv_pattern;
+    options.srv_log_fun = mbedtls_test_ssl_log_analyzer;
+    mbedtls_debug_set_threshold(3);
+
+    options.pk_alg = pk_alg;
+
+    ret = mbedtls_test_ssl_endpoint_init(&server, MBEDTLS_SSL_IS_SERVER,
+                                         &options, NULL, NULL, NULL);
+    TEST_EQUAL(ret,  0);
+
+    ret = mbedtls_test_ssl_endpoint_init(&client, MBEDTLS_SSL_IS_CLIENT,
+                                         &options, NULL, NULL, NULL);
+    TEST_EQUAL(ret,  0);
+
+    ret = mbedtls_test_mock_socket_connect(&server.socket, &client.socket,
+                                           BUFFSIZE);
+    TEST_EQUAL(ret,  0);
+
+    /* Make the server move to the required state */
+    ret = mbedtls_test_move_handshake_to_state(&client.ssl, &server.ssl, state);
+    TEST_EQUAL(ret, 0);
+
+    /* Send the crafted message */
+    ret = mbedtls_test_mock_tcp_send_b(&client.socket, data->x, data->len);
+    TEST_EQUAL(ret, (int) data->len);
+
+    /* Have the server process it.
+     * Need the loop because a server that support 1.3 and 1.2
+     * will process a 1.2 ClientHello in two steps.
+     */
+    do {
+        ret = mbedtls_ssl_handshake_step(&server.ssl);
+    } while (ret == 0 && server.ssl.state == state);
+    TEST_EQUAL(ret,  expected_ret);
+    TEST_ASSERT(srv_pattern.counter >= 1);
+
+exit:
+    mbedtls_test_free_handshake_options(&options);
+    mbedtls_test_ssl_endpoint_free(&server, NULL);
+    mbedtls_test_ssl_endpoint_free(&client, NULL);
+    mbedtls_debug_set_threshold(0);
+    PSA_DONE();
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_DEBUG_C:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY */
+void send_large_fragmented_hello(int hs_len_int, int first_frag_content_len_int,
+                                 char *log_pattern, int expected_ret)
+{
+    /* This function sends a long message (claiming to be a ClientHello)
+     * fragmented in 1-byte fragments (except the initial fragment).
+     * The purpose is to test how the stack reacts when receiving:
+     * - a message larger than our buffer;
+     * - a message smaller than our buffer, but where the intermediate size of
+     *   holding all the fragments (including overhead) is larger than our
+     *   buffer.
+     */
+    enum { BUFFSIZE = 16384 };
+    mbedtls_test_ssl_endpoint server, client;
+    mbedtls_platform_zeroize(&server, sizeof(server));
+    mbedtls_platform_zeroize(&client, sizeof(client));
+
+    mbedtls_test_handshake_test_options options;
+    mbedtls_test_init_handshake_options(&options);
+
+    mbedtls_test_ssl_log_pattern srv_pattern;
+    memset(&srv_pattern, 0, sizeof(srv_pattern));
+
+    unsigned char *first_frag = NULL;
+    int ret = -1;
+
+    size_t hs_len = (size_t) hs_len_int;
+    size_t first_frag_content_len = (size_t) first_frag_content_len_int;
+
+    PSA_INIT();
+
+    srv_pattern.pattern = log_pattern;
+    options.srv_log_obj = &srv_pattern;
+    options.srv_log_fun = mbedtls_test_ssl_log_analyzer;
+    mbedtls_debug_set_threshold(1);
+
+    // Does't really matter but we want to know to declare dependencies.
+    options.pk_alg = MBEDTLS_PK_ECDSA;
+
+    ret = mbedtls_test_ssl_endpoint_init(&server, MBEDTLS_SSL_IS_SERVER,
+                                         &options, NULL, NULL, NULL);
+    TEST_EQUAL(ret,  0);
+
+    ret = mbedtls_test_ssl_endpoint_init(&client, MBEDTLS_SSL_IS_CLIENT,
+                                         &options, NULL, NULL, NULL);
+    TEST_EQUAL(ret,  0);
+
+    ret = mbedtls_test_mock_socket_connect(&server.socket, &client.socket,
+                                           BUFFSIZE);
+    TEST_EQUAL(ret,  0);
+
+    /* Make the server move past the initial dummy state */
+    ret = mbedtls_test_move_handshake_to_state(&client.ssl, &server.ssl,
+                                               MBEDTLS_SSL_CLIENT_HELLO);
+    TEST_EQUAL(ret, 0);
+
+    /* Prepare initial fragment */
+    const size_t first_len = 5 // record header, see below
+                             + 4 // handshake header, see balow
+                             + first_frag_content_len;
+    TEST_CALLOC(first_frag, first_len);
+    unsigned char *p = first_frag;
+    // record header
+    // record type: handshake
+    *p++ = 0x16,
+    // record version (actually common to TLS 1.2 and TLS 1.3)
+    *p++ = 0x03,
+    *p++ = 0x03,
+    // record length: two bytes
+    *p++ = (unsigned char) (((4 + first_frag_content_len) >> 8) & 0xff);
+    *p++ = (unsigned char) (((4 + first_frag_content_len) >> 0) & 0xff);
+    // handshake header
+    // handshake type: ClientHello
+    *p++ = 0x01,
+    // handshake length: three bytes
+    *p++ = (unsigned char) ((hs_len >> 16) & 0xff);
+    *p++ = (unsigned char) ((hs_len >>  8) & 0xff);
+    *p++ = (unsigned char) ((hs_len >>  0) & 0xff);
+    // handshake content: dummy value
+    memset(p, 0x2a, first_frag_content_len);
+
+    /* Send initial fragment and have the server process it. */
+    ret = mbedtls_test_mock_tcp_send_b(&client.socket, first_frag, first_len);
+    TEST_ASSERT(ret >= 0 && (size_t) ret == first_len);
+
+    ret = mbedtls_ssl_handshake_step(&server.ssl);
+    TEST_EQUAL(ret, MBEDTLS_ERR_SSL_WANT_READ);
+
+    /* Dummy 1-byte fragment to repeatedly send next */
+    const unsigned char next[] = {
+        0x16, 0x03, 0x03, 0x00, 0x01, // record header (see above)
+        0x2a, // Dummy handshake message content
+    };
+    for (size_t left = hs_len - first_frag_content_len; left != 0; left--) {
+        ret = mbedtls_test_mock_tcp_send_b(&client.socket, next, sizeof(next));
+        TEST_ASSERT(ret >= 0 && (size_t) ret == sizeof(next));
+
+        ret = mbedtls_ssl_handshake_step(&server.ssl);
+        if (ret != MBEDTLS_ERR_SSL_WANT_READ) {
+            break;
+        }
+    }
+    TEST_EQUAL(ret, expected_ret);
+    TEST_EQUAL(srv_pattern.counter, 1);
+
+exit:
+    mbedtls_test_free_handshake_options(&options);
+    mbedtls_test_ssl_endpoint_free(&server, NULL);
+    mbedtls_test_ssl_endpoint_free(&client, NULL);
+    mbedtls_debug_set_threshold(0);
+    mbedtls_free(first_frag);
+    PSA_DONE();
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_ssl.tls-defrag.data b/tests/suites/test_suite_ssl.tls-defrag.data
new file mode 100644
index 0000000..8fca923
--- /dev/null
+++ b/tests/suites/test_suite_ssl.tls-defrag.data
@@ -0,0 +1,215 @@
+# (Minimal) ClientHello breakdown:
+# 160303rlrl - record header, 2-byte record contents len
+# 01hlhlhl - handshake header, 3-byte handshake message len
+# 0303 - protocol version: 1.2
+# 0123456789abcdef (repeated, 4 times total) - 32-byte "random"
+# 00 - session ID (empty)
+# 0002cvcv - ciphersuite list: 2-byte len + list of 2-byte values (see below)
+# 0100 - compression methods: 1-byte len then "null" (only legal value now)
+# [then end, or extensions, see notes below]
+# elel - 2-byte extensions length
+# ...
+# 000a - elliptic_curves aka supported_groups
+# 0004 - extension length
+# 0002 - length of named_curve_list / named_group_list
+# 0017 - secp256r1 aka NIST P-256
+# ...
+# 002b - supported version (for TLS 1.3)
+# 0003 - extension length
+# 02   - length of versions
+# 0304 - TLS 1.3 ("SSL 3.4")
+# ...
+# 000d - signature algorithms
+# 0004 - extension length
+# 0002 - SignatureSchemeList length
+# 0403 - ecdsa_secp256r1_sha256
+# ...
+# 0033 - key share
+# 0002 - extension length
+# 0000 - length of client_shares (empty is valid)
+#
+# Note: currently our TLS "1.3 or 1.2" code requires extension length to be
+# present even it it's 0. This is not strictly compliant but doesn't matter
+# much in practice as these days everyone wants to use signature_algorithms
+# (for hashes better than SHA-1), secure_renego (even if you have renego
+# disabled), and most people want either ECC or PSK related extensions.
+# See https://github.com/Mbed-TLS/mbedtls/issues/9963
+#
+# Also, currently we won't negotiate ECC ciphersuites unless at least the
+# supported_groups extension is present, see
+# https://github.com/Mbed-TLS/mbedtls/issues/7458
+#
+# For TLS 1.3 with ephemeral key exchange, mandatory extensions are:
+# - supported versions (as for all of TLS 1.3)
+# - supported groups
+# - key share
+# - signature algorithms
+# (see ssl_tls13_client_hello_has_exts_for_ephemeral_key_exchange()).
+#
+# Note: cccc is currently not assigned, so can be used get a consistent
+# "no matching ciphersuite" behaviour regardless of the configuration.
+# c02b is MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (1.2)
+# 1301 is MBEDTLS_TLS1_3_AES_128_GCM_SHA256 (1.3)
+
+# See "ClientHello breakdown" above
+# MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 with secp256r1
+Inject ClientHello - TLS 1.2 good (for reference)
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_MD_CAN_SHA1
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"16030300370100003303030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef000002c02b01000008000a000400020017":"<= parse client hello":0
+
+# See "ClientHello breakdown" above
+# Same as the above test with s/c02b/cccc/ as the ciphersuite
+Inject ClientHello - TLS 1.2 unknown ciphersuite (for reference)
+depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_MD_CAN_SHA1
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"160303002f0100002b03030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef000002cccc01000000":"got no ciphersuites in common":MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE
+
+# See "ClientHello breakdown" above
+# ephemeral with secp256r1 + MBEDTLS_TLS1_3_AES_128_GCM_SHA256
+Inject ClientHello - TLS 1.3 good (for reference)
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"160303004c0100004803030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000213010100001d000a000400020017002b0003020304000d000400020403003300020000":"key exchange mode\: ephemeral":0
+
+# See "ClientHello breakdown" above
+# Same as the above test with s/1301/cccc/ as the ciphersuite
+Inject ClientHello - TLS 1.3 unknown ciphersuite (for reference)
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"160303004c0100004803030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef000002cccc0100001d000a000400020017002b0003020304000d000400020403003300020000":"No matched ciphersuite":MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE
+
+# See "ClientHello breakdown" above
+# ephemeral with secp256r1 + MBEDTLS_TLS1_3_AES_128_GCM_SHA256
+# The purpose of this test case is to ensure nothing bad happens when the
+# connection is closed while we're waiting for more fragments.
+Inject ClientHello - TLS 1.3 4 + 71 then EOF (missing 1 byte)
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"160303000401000048160303004703030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000213010100001d000a000400020017002b0003020304000d0004000204030033000200":"waiting for more handshake fragments":MBEDTLS_ERR_SSL_WANT_READ
+
+# See "ClientHello breakdown" above
+# ephemeral with secp256r1 + MBEDTLS_TLS1_3_AES_128_GCM_SHA256
+# The purpose of this test case is to ensure nothing bad happens when the
+# connection is closed while we're waiting for more fragments.
+Inject ClientHello - TLS 1.3 4 then EOF (missing 72 bytes)
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"160303000401000048":"waiting for more handshake fragments":MBEDTLS_ERR_SSL_WANT_READ
+
+# See "ClientHello breakdown" above
+# ephemeral with secp256r1 + MBEDTLS_TLS1_3_AES_128_GCM_SHA256
+Inject ClientHello - TLS 1.3 fragmented 4 + 72 OK
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"160303000401000048160303004803030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000213010100001d000a000400020017002b0003020304000d000400020403003300020000":"key exchange mode\: ephemeral":0
+
+# See "ClientHello breakdown" above
+# ephemeral with secp256r1 + MBEDTLS_TLS1_3_AES_128_GCM_SHA256
+Inject ClientHello - TLS 1.3 fragmented 3 + 73 rejected
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"160303000301000016030300494803030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000213010100001d000a000400020017002b0003020304000d000400020403003300020000":"handshake message too short":MBEDTLS_ERR_SSL_INVALID_RECORD
+
+# See "ClientHello breakdown" above
+# ephemeral with secp256r1 + MBEDTLS_TLS1_3_AES_128_GCM_SHA256
+Inject ClientHello - TLS 1.3 fragmented 2 + 74 rejected
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"16030300020100160303004a004803030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000213010100001d000a000400020017002b0003020304000d000400020403003300020000":"handshake message too short":MBEDTLS_ERR_SSL_INVALID_RECORD
+
+# See "ClientHello breakdown" above
+# ephemeral with secp256r1 + MBEDTLS_TLS1_3_AES_128_GCM_SHA256
+Inject ClientHello - TLS 1.3 fragmented 1 + 75 rejected
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"160303000101160303004b00004803030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000213010100001d000a000400020017002b0003020304000d000400020403003300020000":"handshake message too short":MBEDTLS_ERR_SSL_INVALID_RECORD
+
+# See "ClientHello breakdown" above
+# ephemeral with secp256r1 + MBEDTLS_TLS1_3_AES_128_GCM_SHA256
+Inject ClientHello - TLS 1.3 fragmented 0 + 76 rejected
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"1603030000160303004c0100004803030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000213010100001d000a000400020017002b0003020304000d000400020403003300020000":"ssl_get_next_record() returned":MBEDTLS_ERR_SSL_INVALID_RECORD
+
+# See "ClientHello breakdown" above
+# ephemeral with secp256r1 + MBEDTLS_TLS1_3_AES_128_GCM_SHA256
+Inject ClientHello - TLS 1.3 fragmented 72 + 4 OK
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"16030300480100004803030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000213010100001d000a000400020017002b0003020304000d0004000204030033160303000400020000":"key exchange mode\: ephemeral":0
+
+# See "ClientHello breakdown" above
+# ephemeral with secp256r1 + MBEDTLS_TLS1_3_AES_128_GCM_SHA256
+Inject ClientHello - TLS 1.3 fragmented 73 + 3 OK
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"16030300490100004803030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000213010100001d000a000400020017002b0003020304000d0004000204030033001603030003020000":"key exchange mode\: ephemeral":0
+
+# See "ClientHello breakdown" above
+# ephemeral with secp256r1 + MBEDTLS_TLS1_3_AES_128_GCM_SHA256
+Inject ClientHello - TLS 1.3 fragmented 74 + 2 OK
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"160303004a0100004803030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000213010100001d000a000400020017002b0003020304000d0004000204030033000216030300020000":"key exchange mode\: ephemeral":0
+
+# See "ClientHello breakdown" above
+# ephemeral with secp256r1 + MBEDTLS_TLS1_3_AES_128_GCM_SHA256
+Inject ClientHello - TLS 1.3 fragmented 73 + 1 OK
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"160303004b0100004803030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000213010100001d000a000400020017002b0003020304000d0004000204030033000200160303000100":"key exchange mode\: ephemeral":0
+
+# See "ClientHello breakdown" above
+# ephemeral with secp256r1 + MBEDTLS_TLS1_3_AES_128_GCM_SHA256
+Inject ClientHello - TLS 1.3 fragmented 4 + appdata + 72 rejected
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"16030300040100004817030300020102160303004803030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000213010100001d000a000400020017002b0003020304000d000400020403003300020000":"non-handshake message in the middle of a fragmented handshake message":MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE
+
+# See "ClientHello breakdown" above
+# ephemeral with secp256r1 + MBEDTLS_TLS1_3_AES_128_GCM_SHA256
+Inject ClientHello - TLS 1.3 fragmented 4 + alert(warn) + 72 rejected
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"1603030004010000481503030002015a160303004803030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000213010100001d000a000400020017002b0003020304000d000400020403003300020000":"non-handshake message in the middle of a fragmented handshake message":MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE
+
+# See "ClientHello breakdown" above
+# ephemeral with secp256r1 + MBEDTLS_TLS1_3_AES_128_GCM_SHA256
+Inject ClientHello - TLS 1.3 fragmented 4 + alert(fatal) + 72 rejected
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"1603030004010000481503030002025a160303004803030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000213010100001d000a000400020017002b0003020304000d000400020403003300020000":"non-handshake message in the middle of a fragmented handshake message":MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE
+
+# See "ClientHello breakdown" above
+# ephemeral with secp256r1 + MBEDTLS_TLS1_3_AES_128_GCM_SHA256
+Inject ClientHello - TLS 1.3 fragmented 4 + CCS + 72 rejected
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"160303000401000048140303000101160303004803030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000213010100001d000a000400020017002b0003020304000d000400020403003300020000":"non-handshake message in the middle of a fragmented handshake message":MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE
+
+# See "ClientHello breakdown" above
+# ephemeral with secp256r1 + MBEDTLS_TLS1_3_AES_128_GCM_SHA256
+Inject ClientHello - TLS 1.3 fragmented 4 + invalid type + 72 rejected
+depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY
+inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"1603030004010000481003030002015a160303004803030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef00000213010100001d000a000400020017002b0003020304000d000400020403003300020000":"unknown record type":MBEDTLS_ERR_SSL_INVALID_RECORD
+
+# The buffer is actually larger than IN_CONTENT_LEN as we leave room for
+# record protection overhead (IV, MAC/tag, padding (up to 256 bytes)), CID...
+# The maximum size for an unencrypted (and without CID which is DTLS only)
+# handshake message we can hold in the buffer is
+#   MBEDTLS_SSL_IN_BUFFER_LEN - MBEDTLS_SSL_HEADER_LEN - 4
+# (the 4 is for the handshake header).
+# However, due to overhead, fragmented messages need to be 5 bytes shorter in
+# order to actually fit (leave room for an extra record header).
+Send large fragmented ClientHello: reassembled 1 byte larger than the buffer
+send_large_fragmented_hello:MBEDTLS_SSL_IN_BUFFER_LEN - MBEDTLS_SSL_HEADER_LEN - 3:0:"requesting more data than fits":MBEDTLS_ERR_SSL_BAD_INPUT_DATA
+
+Send large fragmented ClientHello: would just fit except for overhead
+send_large_fragmented_hello:MBEDTLS_SSL_IN_BUFFER_LEN - MBEDTLS_SSL_HEADER_LEN - 4:0:"requesting more data than fits":MBEDTLS_ERR_SSL_BAD_INPUT_DATA
+
+Send large fragmented ClientHello: would fit except for overhead (1)
+send_large_fragmented_hello:MBEDTLS_SSL_IN_BUFFER_LEN - MBEDTLS_SSL_HEADER_LEN - 5:0:"requesting more data than fits":MBEDTLS_ERR_SSL_BAD_INPUT_DATA
+
+Send large fragmented ClientHello: would fit except for overhead (2)
+send_large_fragmented_hello:MBEDTLS_SSL_IN_BUFFER_LEN - MBEDTLS_SSL_HEADER_LEN - 6:0:"requesting more data than fits":MBEDTLS_ERR_SSL_BAD_INPUT_DATA
+
+Send large fragmented ClientHello: would fit except for overhead (3)
+send_large_fragmented_hello:MBEDTLS_SSL_IN_BUFFER_LEN - MBEDTLS_SSL_HEADER_LEN - 7:0:"requesting more data than fits":MBEDTLS_ERR_SSL_BAD_INPUT_DATA
+
+Send large fragmented ClientHello: would fit except for overhead (4)
+send_large_fragmented_hello:MBEDTLS_SSL_IN_BUFFER_LEN - MBEDTLS_SSL_HEADER_LEN - 8:0:"requesting more data than fits":MBEDTLS_ERR_SSL_BAD_INPUT_DATA
+
+# Since we're sending dummy contents (all 0x2a) for the ClientHello,
+# the first thing that's going to fail is the version check. The fact that we
+# got around to checking it confirms reassembly completed sucessfully.
+Send large fragmented ClientHello: just fits
+send_large_fragmented_hello:MBEDTLS_SSL_IN_BUFFER_LEN - MBEDTLS_SSL_HEADER_LEN - 9:0:"Unsupported version of TLS":MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION
+
+# We're generating a virtual record header for the reassembled HS message,
+# which requires that the length fits in two bytes. Of course we won't get
+# there because if the length doesn't fit in two bytes then the message won't
+# fit in the buffer, but still add a test just in case.
+Send large fragmented ClientHello: length doesn't fit in two bytes
+send_large_fragmented_hello:0x10000:0:"requesting more data than fits":MBEDTLS_ERR_SSL_BAD_INPUT_DATA