Merge branch 'mbedtls-3.6-restricted' into mbedtls-3.6.3rc0-pr
Signed-off-by: Minos Galanakis <minos.galanakis@arm.com>
diff --git a/docs/3.0-migration-guide.md b/docs/3.0-migration-guide.md
index 42af9db..e927667 100644
--- a/docs/3.0-migration-guide.md
+++ b/docs/3.0-migration-guide.md
@@ -71,7 +71,7 @@
If no accessor function exists, please open an [enhancement request against Mbed TLS](https://github.com/Mbed-TLS/mbedtls/issues/new?template=feature_request.md) and describe your use case. The Mbed TLS development team is aware that some useful accessor functions are missing in the 3.0 release, and we expect to add them to the first minor release(s) (3.1, etc.).
-As a last resort, you can access the field `foo` of a structure `bar` by writing `bar.MBEDTLS_PRIVATE(foo)`. Note that you do so at your own risk, since such code is likely to break in a future minor version of Mbed TLS.
+As a last resort, you can access the field `foo` of a structure `bar` by writing `bar.MBEDTLS_PRIVATE(foo)`. Note that you do so at your own risk, since such code is likely to break in a future minor version of Mbed TLS. In the Mbed TLS 3.6 LTS this will tend to be safer than in a normal minor release because LTS versions try to maintain ABI stability.
### Move part of timing module out of the library
@@ -349,7 +349,7 @@
| `mbedtls_sha512_finish_ret` | `mbedtls_sha512_finish` |
| `mbedtls_sha512_ret` | `mbedtls_sha512` |
-To migrate to the this change the user can keep the `*_ret` names in their code
+To migrate to this change the user can keep the `*_ret` names in their code
and include the `compat_2.x.h` header file which holds macros with proper
renaming or to rename those functions in their code according to the list from
mentioned header file.
@@ -409,7 +409,7 @@
Previously, the documentation didn't state explicitly if it was OK to call
`mbedtls_cipher_check_tag()` or `mbedtls_cipher_write_tag()` directly after
the last call to `mbedtls_cipher_update()` — that is, without calling
-`mbedtls_cipher_finish()` in-between. If you code was missing that call,
+`mbedtls_cipher_finish()` in-between. If your code was missing that call,
please add it and be prepared to get as much as 15 bytes of output.
Currently the output is always 0 bytes, but it may be more when alternative
@@ -422,7 +422,7 @@
They are already niche or obsolete and most of them are weak or broken. For
those reasons possible users should consider switching to modern and safe
-alternatives to be found in literature.
+alternatives to be found in the literature.
### Deprecated functions were removed from cipher
@@ -806,11 +806,11 @@
In Mbed TLS 2.x, users would observe later calls overwriting
the effect of earlier calls, with the prevailing PSK being
the one that has been configured last. In Mbed TLS 3.0,
-calling `mbedtls_ssl_conf_[opaque_]psk()` multiple times
+calling `mbedtls_ssl_conf_psk[_opaque]()` multiple times
will return an error, leaving the first PSK intact.
To achieve equivalent functionality when migrating to Mbed TLS 3.0,
-users calling `mbedtls_ssl_conf_[opaque_]psk()` multiple times should
+users calling `mbedtls_ssl_conf_psk[_opaque]()` multiple times should
remove all but the last call, so that only one call to _either_
`mbedtls_ssl_conf_psk()` _or_ `mbedtls_ssl_conf_psk_opaque()`
remains.
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/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 425239e..fc45e9f 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -77,6 +77,7 @@
#define DFL_RECO_SERVER_NAME NULL
#define DFL_RECO_DELAY 0
#define DFL_RECO_MODE 1
+#define DFL_RENEGO_DELAY -2
#define DFL_CID_ENABLED 0
#define DFL_CID_VALUE ""
#define DFL_CID_ENABLED_RENEGO -1
@@ -309,7 +310,8 @@
#if defined(MBEDTLS_SSL_RENEGOTIATION)
#define USAGE_RENEGO \
" renegotiation=%%d default: 0 (disabled)\n" \
- " renegotiate=%%d default: 0 (disabled)\n"
+ " renegotiate=%%d default: 0 (disabled)\n" \
+ " renego_delay=%%d default: -2 (library default)\n"
#else
#define USAGE_RENEGO ""
#endif
@@ -963,6 +965,7 @@
opt.renegotiation = DFL_RENEGOTIATION;
opt.allow_legacy = DFL_ALLOW_LEGACY;
opt.renegotiate = DFL_RENEGOTIATE;
+ opt.renego_delay = DFL_RENEGO_DELAY;
opt.exchanges = DFL_EXCHANGES;
opt.min_version = DFL_MIN_VERSION;
opt.max_version = DFL_MAX_VERSION;
@@ -1200,6 +1203,8 @@
break;
default: goto usage;
}
+ } else if (strcmp(p, "renego_delay") == 0) {
+ opt.renego_delay = (atoi(q));
} else if (strcmp(p, "renegotiate") == 0) {
opt.renegotiate = atoi(q);
if (opt.renegotiate < 0 || opt.renegotiate > 1) {
@@ -1983,6 +1988,9 @@
}
#if defined(MBEDTLS_SSL_RENEGOTIATION)
mbedtls_ssl_conf_renegotiation(&conf, opt.renegotiation);
+ if (opt.renego_delay != DFL_RENEGO_DELAY) {
+ mbedtls_ssl_conf_renegotiation_enforced(&conf, opt.renego_delay);
+ }
#endif
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
@@ -2541,6 +2549,8 @@
}
mbedtls_printf(" ok\n");
}
+
+
#endif /* MBEDTLS_SSL_RENEGOTIATION */
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c
index 9a3859d..58b8362 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/ssl-opt.sh b/tests/ssl-opt.sh
index 361e7c2..61cb366 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -103,12 +103,14 @@
O_NEXT_SRV_NO_CERT="$OPENSSL_NEXT s_server -www "
O_NEXT_CLI="echo 'GET / HTTP/1.0' | $OPENSSL_NEXT s_client -CAfile $DATA_FILES_PATH/test-ca_cat12.crt"
O_NEXT_CLI_NO_CERT="echo 'GET / HTTP/1.0' | $OPENSSL_NEXT s_client"
+ O_NEXT_CLI_RENEGOTIATE="echo 'R' | $OPENSSL_NEXT s_client -cert $DATA_FILES_PATH/server5.crt -key $DATA_FILES_PATH/server5.key"
else
O_NEXT_SRV=false
O_NEXT_SRV_NO_CERT=false
O_NEXT_SRV_EARLY_DATA=false
O_NEXT_CLI_NO_CERT=false
O_NEXT_CLI=false
+ O_NEXT_CLI_RENEGOTIATE=false
fi
if [ -n "${GNUTLS_NEXT_SERV:-}" ]; then
@@ -14715,7 +14717,7 @@
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
requires_certificate_authentication
-run_test "Handshake defragmentation on server: len=32, TLS 1.2 ClientHello" \
+run_test "Handshake defragmentation on server: len=32, TLS 1.2 ClientHello (unsupported)" \
"$P_SRV debug_level=4 force_version=tls12 auth_mode=required" \
"$O_NEXT_CLI -tls1_2 -split_send_frag 32 -cert $DATA_FILES_PATH/server5.crt -key $DATA_FILES_PATH/server5.key" \
1 \
@@ -14723,6 +14725,165 @@
-s "bad client hello message" \
-s "SSL - A message could not be parsed due to a syntactic error"
+# Test server-side buffer resizing with fragmented handshake on TLS1.2
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+requires_config_enabled MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
+requires_max_content_len 1025
+run_test "Handshake defragmentation on server: len=256, buffer resizing with MFL=1024" \
+ "$P_SRV debug_level=4 auth_mode=required" \
+ "$O_NEXT_CLI -tls1_2 -split_send_frag 256 -maxfraglen 1024 -cert $DATA_FILES_PATH/server5.crt -key $DATA_FILES_PATH/server5.key" \
+ 0 \
+ -s "Reallocating in_buf" \
+ -s "Reallocating out_buf" \
+ -s "reassembled record" \
+ -s "initial handshake fragment: 256, 0\\.\\.256 of [0-9]\\+" \
+ -s "Prepare: waiting for more handshake fragments 256/" \
+ -s "Consume: waiting for more handshake fragments 256/"
+
+# Test client-initiated renegotiation with fragmented handshake on TLS1.2
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+run_test "Handshake defragmentation on server: len=512, client-initiated renegotiation" \
+ "$P_SRV debug_level=4 exchanges=2 renegotiation=1 auth_mode=required" \
+ "$O_NEXT_CLI_RENEGOTIATE -tls1_2 -split_send_frag 512 -connect 127.0.0.1:+$SRV_PORT" \
+ 0 \
+ -s "received TLS_EMPTY_RENEGOTIATION_INFO" \
+ -s "found renegotiation extension" \
+ -s "server hello, secure renegotiation extension" \
+ -s "=> renegotiate" \
+ -S "write hello request" \
+ -s "reassembled record" \
+ -s "initial handshake fragment: 512, 0\\.\\.512 of [0-9]\\+" \
+ -s "Prepare: waiting for more handshake fragments 512/" \
+ -s "Consume: waiting for more handshake fragments 512/" \
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+run_test "Handshake defragmentation on server: len=256, client-initiated renegotiation" \
+ "$P_SRV debug_level=4 exchanges=2 renegotiation=1 auth_mode=required" \
+ "$O_NEXT_CLI_RENEGOTIATE -tls1_2 -split_send_frag 256 -connect 127.0.0.1:+$SRV_PORT" \
+ 0 \
+ -s "received TLS_EMPTY_RENEGOTIATION_INFO" \
+ -s "found renegotiation extension" \
+ -s "server hello, secure renegotiation extension" \
+ -s "=> renegotiate" \
+ -S "write hello request" \
+ -s "reassembled record" \
+ -s "initial handshake fragment: 256, 0\\.\\.256 of [0-9]\\+" \
+ -s "Prepare: waiting for more handshake fragments 256/" \
+ -s "Consume: waiting for more handshake fragments 256/" \
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+run_test "Handshake defragmentation on server: len=128, client-initiated renegotiation" \
+ "$P_SRV debug_level=4 exchanges=2 renegotiation=1 auth_mode=required" \
+ "$O_NEXT_CLI_RENEGOTIATE -tls1_2 -split_send_frag 128 -connect 127.0.0.1:+$SRV_PORT" \
+ 0 \
+ -s "received TLS_EMPTY_RENEGOTIATION_INFO" \
+ -s "found renegotiation extension" \
+ -s "server hello, secure renegotiation extension" \
+ -s "=> renegotiate" \
+ -S "write hello request" \
+ -s "reassembled record" \
+ -s "initial handshake fragment: 128, 0\\.\\.128 of [0-9]\\+" \
+ -s "Prepare: waiting for more handshake fragments 128/" \
+ -s "Consume: waiting for more handshake fragments 128/" \
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+run_test "Handshake defragmentation on server: len=4, client-initiated renegotiation" \
+ "$P_SRV debug_level=4 exchanges=2 renegotiation=1 auth_mode=required" \
+ "$O_NEXT_CLI_RENEGOTIATE -tls1_2 -split_send_frag 4 -connect 127.0.0.1:+$SRV_PORT" \
+ 0 \
+ -s "received TLS_EMPTY_RENEGOTIATION_INFO" \
+ -s "found renegotiation extension" \
+ -s "server hello, secure renegotiation extension" \
+ -s "=> renegotiate" \
+ -S "write hello request" \
+ -s "reassembled record" \
+ -s "initial handshake fragment: 4, 0\\.\\.4 of [0-9]\\+" \
+ -s "Prepare: waiting for more handshake fragments 4/" \
+ -s "Consume: waiting for more handshake fragments 4/" \
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+run_test "Handshake defragmentation on server: len=4, client-initiated server-rejected renegotiation" \
+ "$P_SRV debug_level=4 exchanges=2 renegotiation=0 auth_mode=required" \
+ "$O_NEXT_CLI_RENEGOTIATE -tls1_2 -split_send_frag 4 -connect 127.0.0.1:+$SRV_PORT" \
+ 1 \
+ -s "received TLS_EMPTY_RENEGOTIATION_INFO" \
+ -s "refusing renegotiation, sending alert" \
+ -s "server hello, secure renegotiation extension" \
+ -s "initial handshake fragment: 4, 0\\.\\.4 of [0-9]\\+" \
+ -s "Prepare: waiting for more handshake fragments 4/" \
+ -s "Consume: waiting for more handshake fragments 4/" \
+
+# Test server-initiated renegotiation with fragmented handshake on TLS1.2
+
+# Note: The /reneg endpoint serves as a directive for OpenSSL's s_server
+# to initiate a handshake renegotiation.
+# Note: Adjusting the renegotiation delay beyond the library's default
+# value of 16 is necessary. This parameter defines the maximum
+# number of records received before renegotiation is completed.
+# By fragmenting records and thereby increasing their quantity,
+# the default threshold can be reached more quickly.
+# Setting it to -1 disables that policy's enforment.
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+run_test "Handshake defragmentation on client: len=512, server-initiated renegotiation" \
+ "$O_NEXT_SRV -tls1_2 -split_send_frag 512 -cert $DATA_FILES_PATH/server5.crt -key $DATA_FILES_PATH/server5.key" \
+ "$P_CLI debug_level=3 renegotiation=1 request_page=/reneg" \
+ 0 \
+ -c "initial handshake fragment: 512, 0\\.\\.512 of [0-9]\\+" \
+ -c "Prepare: waiting for more handshake fragments 512/" \
+ -c "Consume: waiting for more handshake fragments 512/" \
+ -c "client hello, adding renegotiation extension" \
+ -c "found renegotiation extension" \
+ -c "=> renegotiate"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+run_test "Handshake defragmentation on client: len=256, server-initiated renegotiation" \
+ "$O_NEXT_SRV -tls1_2 -split_send_frag 256 -cert $DATA_FILES_PATH/server5.crt -key $DATA_FILES_PATH/server5.key" \
+ "$P_CLI debug_level=3 renegotiation=1 renego_delay=-1 request_page=/reneg" \
+ 0 \
+ -c "initial handshake fragment: 256, 0\\.\\.256 of [0-9]\\+" \
+ -c "Prepare: waiting for more handshake fragments 256/" \
+ -c "Consume: waiting for more handshake fragments 256/" \
+ -c "client hello, adding renegotiation extension" \
+ -c "found renegotiation extension" \
+ -c "=> renegotiate"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+run_test "Handshake defragmentation on client: len=128, server-initiated renegotiation" \
+ "$O_NEXT_SRV -tls1_2 -split_send_frag 128 -cert $DATA_FILES_PATH/server5.crt -key $DATA_FILES_PATH/server5.key" \
+ "$P_CLI debug_level=3 renegotiation=1 renego_delay=-1 request_page=/reneg" \
+ 0 \
+ -c "initial handshake fragment: 128, 0\\.\\.128 of [0-9]\\+" \
+ -c "Prepare: waiting for more handshake fragments 128/" \
+ -c "Consume: waiting for more handshake fragments 128/" \
+ -c "client hello, adding renegotiation extension" \
+ -c "found renegotiation extension" \
+ -c "=> renegotiate"
+
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+run_test "Handshake defragmentation on client: len=4, server-initiated renegotiation" \
+ "$O_NEXT_SRV -tls1_2 -split_send_frag 4 -cert $DATA_FILES_PATH/server5.crt -key $DATA_FILES_PATH/server5.key" \
+ "$P_CLI debug_level=3 renegotiation=1 renego_delay=-1 request_page=/reneg" \
+ 0 \
+ -c "initial handshake fragment: 4, 0\\.\\.4 of [0-9]\\+" \
+ -c "Prepare: waiting for more handshake fragments 4/" \
+ -c "Consume: waiting for more handshake fragments 4/" \
+ -c "client hello, adding renegotiation extension" \
+ -c "found renegotiation extension" \
+ -c "=> renegotiate"
+
# Test heap memory usage after handshake
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
requires_config_enabled MBEDTLS_MEMORY_DEBUG
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