Merge pull request #1507 from gilles-peskine-arm/merge-development-restricted-20260311

Merge public development with tf-psa-crypto directory reorg prep
This commit is contained in:
Gilles Peskine
2026-03-11 16:04:01 +01:00
committed by GitHub
24 changed files with 714 additions and 986 deletions

View File

@@ -373,6 +373,20 @@ foreach(target IN LISTS tf_psa_crypto_library_targets)
endif()
endforeach(target)
#
# TF-PSA-Crypto directories with internal headers that are currently still
# consumed by Mbed TLS. When we have finished cleaning up this list should be
# empty.
#
set(TF_PSA_CRYPTO_PRIVATE_INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/tf-psa-crypto/core
${CMAKE_CURRENT_SOURCE_DIR}/tf-psa-crypto/dispatch
${CMAKE_CURRENT_SOURCE_DIR}/tf-psa-crypto/drivers/builtin/src
${CMAKE_CURRENT_SOURCE_DIR}/tf-psa-crypto/extras
${CMAKE_CURRENT_SOURCE_DIR}/tf-psa-crypto/platform
${CMAKE_CURRENT_SOURCE_DIR}/tf-psa-crypto/utilities
)
add_subdirectory(library)
add_subdirectory(pkgconfig)
@@ -416,16 +430,16 @@ if(ENABLE_TESTING OR ENABLE_PROGRAMS)
endif()
target_include_directories(mbedtls_test
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/tests/include
PRIVATE ${MBEDTLS_FRAMEWORK_DIR}/tests/include
PRIVATE tests/include
PRIVATE include
PRIVATE tf-psa-crypto/include
PRIVATE tf-psa-crypto/drivers/builtin/include
PRIVATE tf-psa-crypto/drivers/everest/include
PRIVATE tf-psa-crypto/drivers/pqcp/include
PRIVATE library
PRIVATE tf-psa-crypto/core
PRIVATE tf-psa-crypto/drivers/builtin/src)
${MBEDTLS_FRAMEWORK_DIR}/tests/include
tests/include
include
tf-psa-crypto/include
tf-psa-crypto/drivers/builtin/include
tf-psa-crypto/drivers/everest/include
tf-psa-crypto/drivers/pqcp/include
library
${TF_PSA_CRYPTO_PRIVATE_INCLUDE_DIRS}
)
# Request C11, needed for memory poisoning tests
set_target_properties(mbedtls_test PROPERTIES C_STANDARD 11)
set_config_files_compile_definitions(mbedtls_test)
@@ -453,16 +467,15 @@ if(ENABLE_TESTING OR ENABLE_PROGRAMS)
endif()
target_include_directories(mbedtls_test_helpers
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/tests/include
PRIVATE ${MBEDTLS_FRAMEWORK_DIR}/tests/include
PRIVATE tests/include
PRIVATE include
PRIVATE tf-psa-crypto/include
PRIVATE tf-psa-crypto/drivers/builtin/include
PRIVATE library
PRIVATE tf-psa-crypto/core
PRIVATE tf-psa-crypto/drivers/builtin/src
PRIVATE tf-psa-crypto/drivers/everest/include
PRIVATE tf-psa-crypto/drivers/pqcp/include
${MBEDTLS_FRAMEWORK_DIR}/tests/include
tests/include
include
tf-psa-crypto/include
tf-psa-crypto/drivers/builtin/include
library
tf-psa-crypto/drivers/everest/include
tf-psa-crypto/drivers/pqcp/include
${TF_PSA_CRYPTO_PRIVATE_INCLUDE_DIRS}
)
set_config_files_compile_definitions(mbedtls_test_helpers)

View File

@@ -0,0 +1,5 @@
Bugfix
* Support re-assembly of fragmented DTLS 1.2 ClientHello in Mbed TLS server.
* Support re-assembly of fragmented TLS 1.2 ClientHello in Mbed TLS server
even if TLS 1.3 support is disabled. This removes the main limitation on
support for re-assembly of fragmented handshake messages in TLS 1.2.

View File

@@ -4788,13 +4788,6 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl,
* supported with some limitations (those limitations do
* not apply to DTLS, where defragmentation is fully
* supported):
* - On an Mbed TLS server that only accepts TLS 1.2,
* the initial ClientHello message must not be fragmented.
* A TLS 1.2 ClientHello may be fragmented if the server
* also accepts TLS 1.3 connections (meaning
* that #MBEDTLS_SSL_PROTO_TLS1_3 enabled, and the
* accepted versions have not been restricted with
* mbedtls_ssl_conf_max_tls_version() or the like).
* - The first fragment of a handshake message must be
* at least 4 bytes long.
* - Non-handshake records must not be interleaved between

View File

@@ -236,15 +236,14 @@ foreach(target IN LISTS target_libraries)
add_library(MbedTLS::${target} ALIAS ${target}) # add_subdirectory support
# Include public header files from /include, /tf-psa-crypto/include/ and
# tf-psa-crypto/drivers/builtin/include/. Include private header files
# from /library, tf-psa-crypto/core/ and tf-psa-crypto/drivers/builtin/src/.
# from /library and ${TF_PSA_CRYPTO_PRIVATE_INCLUDE_DIRS}.
target_include_directories(${target}
PUBLIC $<BUILD_INTERFACE:${MBEDTLS_DIR}/include/>
$<BUILD_INTERFACE:${MBEDTLS_DIR}/tf-psa-crypto/include/>
$<BUILD_INTERFACE:${MBEDTLS_DIR}/tf-psa-crypto/drivers/builtin/include/>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE ${MBEDTLS_DIR}/library/
${MBEDTLS_DIR}/tf-psa-crypto/core
${MBEDTLS_DIR}/tf-psa-crypto/drivers/builtin/src
${TF_PSA_CRYPTO_PRIVATE_INCLUDE_DIRS}
# needed for generated headers
${CMAKE_CURRENT_BINARY_DIR})
set_config_files_compile_definitions(${target})

View File

@@ -2967,6 +2967,49 @@ int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_SSL_INVALID_RECORD;
}
if (ssl->in_msg[0] == MBEDTLS_SSL_HS_CLIENT_HELLO &&
ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
if (ssl->state == MBEDTLS_SSL_CLIENT_HELLO
#if defined(MBEDTLS_SSL_RENEGOTIATION)
&& ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE
#endif
) {
/*
* When establishing the connection, the client may go through
* a series of ClientHello and HelloVerifyRequest requests and
* responses. The server intentionally does not keep trace of
* these initial round trips: minimum allocated ressources as
* long as the reachability of the client has not been
* confirmed. When receiving the "first ClientHello" from
* server perspective, we may thus need to adapt the next
* expected `message_seq` for the incoming and outgoing
* handshake messages.
*/
ssl->handshake->in_msg_seq = recv_msg_seq;
ssl->handshake->out_msg_seq = recv_msg_seq;
/* Epoch should be 0 for initial handshakes */
if (ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0) {
MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
}
memcpy(&ssl->cur_out_ctr[2], ssl->in_ctr + 2,
sizeof(ssl->cur_out_ctr) - 2);
} else if (mbedtls_ssl_is_handshake_over(ssl) == 1) {
/* In case of a post-handshake ClientHello that initiates a
* renegotiation check that the handshake message sequence
* number is zero.
*/
if (recv_msg_seq != 0) {
MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message_seq: "
"%u (expected 0)",
recv_msg_seq));
return MBEDTLS_ERR_SSL_DECODE_ERROR;
}
}
}
if (ssl->handshake != NULL &&
((mbedtls_ssl_is_handshake_over(ssl) == 0 &&
recv_msg_seq != ssl->handshake->in_msg_seq) ||
@@ -4843,14 +4886,9 @@ static int ssl_get_next_record(mbedtls_ssl_context *ssl)
/* The record content type may change during decryption,
* so re-read it. */
ssl->in_msgtype = rec.type;
/* Also update the input buffer, because unfortunately
* the server-side ssl_parse_client_hello() reparses the
* record header when receiving a ClientHello initiating
* a renegotiation. */
ssl->in_hdr[0] = rec.type;
ssl->in_msg = rec.buf + rec.data_offset;
ssl->in_msglen = rec.data_len;
MBEDTLS_PUT_UINT16_BE(rec.data_len, ssl->in_len, 0);
return 0;
}
@@ -5504,6 +5542,11 @@ static int ssl_tls12_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
}
#endif
/* Keep the ClientHello message for ssl_parse_client_hello() */
if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
ssl->keep_current_message = 1;
}
ret = mbedtls_ssl_start_renegotiation(ssl);
if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
ret != 0) {

View File

@@ -2892,13 +2892,6 @@ size_t mbedtls_ssl_get_output_max_frag_len(const mbedtls_ssl_context *ssl)
#if defined(MBEDTLS_SSL_PROTO_DTLS)
size_t mbedtls_ssl_get_current_mtu(const mbedtls_ssl_context *ssl)
{
/* Return unlimited mtu for client hello messages to avoid fragmentation. */
if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
(ssl->state == MBEDTLS_SSL_CLIENT_HELLO ||
ssl->state == MBEDTLS_SSL_SERVER_HELLO)) {
return 0;
}
if (ssl->handshake == NULL || ssl->handshake->mtu == 0) {
return ssl->mtu;
}

View File

@@ -869,131 +869,35 @@ static int ssl_parse_client_hello(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse client hello"));
int renegotiating;
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
read_record_header:
#endif
/*
* If renegotiating, then the input was read with mbedtls_ssl_read_record(),
* otherwise read it ourselves manually in order to support SSLv2
* ClientHello, which doesn't use the same record layer format.
* Otherwise in a scenario of TLS 1.3/TLS 1.2 version negotiation, the
* ClientHello has been already fully fetched by the TLS 1.3 code and the
* flag ssl->keep_current_message is raised.
* Fetch the expected ClientHello handshake message. Do not ask
* mbedtls_ssl_read_record() to update the handshake digest, because the
* ClientHello may already have been read in ssl_tls13_process_client_hello()
* or as a post-handshake message (renegotiation). In those cases we need
* to update the digest ourselves, and it is simpler to do so
* unconditionally than to track whether it is needed.
*/
renegotiating = 0;
#if defined(MBEDTLS_SSL_RENEGOTIATION)
renegotiating = (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE);
#endif
if (!renegotiating && !ssl->keep_current_message) {
if ((ret = mbedtls_ssl_fetch_input(ssl, 5)) != 0) {
/* No alert on a read error. */
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret);
return ret;
}
if ((ret = mbedtls_ssl_read_record(ssl, 0)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record ", ret);
return ret;
}
buf = ssl->in_hdr;
MBEDTLS_SSL_DEBUG_BUF(4, "record header", buf, mbedtls_ssl_in_hdr_len(ssl));
/*
* TLS Client Hello
* Update the handshake checksum.
*
* Record layer:
* 0 . 0 message type
* 1 . 2 protocol version
* 3 . 11 DTLS: epoch + record sequence number
* 3 . 4 message length
* Note that the checksum must be updated before parsing the extensions
* because ssl_parse_session_ticket_ext() may decrypt the ticket in place
* and therefore modify the ClientHello message. This occurs when using
* the Mbed TLS ssl_ticket.c implementation.
*/
MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, message type: %d",
buf[0]));
if (buf[0] != MBEDTLS_SSL_MSG_HANDSHAKE) {
MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
}
MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, message len.: %d",
MBEDTLS_GET_UINT16_BE(ssl->in_len, 0)));
MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, protocol version: [%d:%d]",
buf[1], buf[2]));
/* For DTLS if this is the initial handshake, remember the client sequence
* number to use it in our next message (RFC 6347 4.2.1) */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM
#if defined(MBEDTLS_SSL_RENEGOTIATION)
&& ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE
#endif
) {
/* Epoch should be 0 for initial handshakes */
if (ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0) {
MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
}
memcpy(&ssl->cur_out_ctr[2], ssl->in_ctr + 2,
sizeof(ssl->cur_out_ctr) - 2);
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
if (mbedtls_ssl_dtls_replay_check(ssl) != 0) {
MBEDTLS_SSL_DEBUG_MSG(1, ("replayed record, discarding"));
ssl->next_record_offset = 0;
ssl->in_left = 0;
goto read_record_header;
}
/* No MAC to check yet, so we can update right now */
mbedtls_ssl_dtls_replay_update(ssl);
#endif
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
msg_len = MBEDTLS_GET_UINT16_BE(ssl->in_len, 0);
#if defined(MBEDTLS_SSL_RENEGOTIATION)
if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
/* Set by mbedtls_ssl_read_record() */
msg_len = ssl->in_hslen;
} else
#endif
{
if (ssl->keep_current_message) {
ssl->keep_current_message = 0;
} else {
if (msg_len > MBEDTLS_SSL_IN_CONTENT_LEN) {
MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
}
if ((ret = mbedtls_ssl_fetch_input(ssl,
mbedtls_ssl_in_hdr_len(ssl) + msg_len)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret);
return ret;
}
/* Done reading this record, get ready for the next one */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
ssl->next_record_offset = msg_len + mbedtls_ssl_in_hdr_len(ssl);
} else
#endif
ssl->in_left = 0;
}
ret = mbedtls_ssl_update_handshake_status(ssl);
if (0 != ret) {
MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_update_handshake_status"), ret);
return ret;
}
buf = ssl->in_msg;
MBEDTLS_SSL_DEBUG_BUF(4, "record contents", buf, msg_len);
ret = ssl->handshake->update_checksum(ssl, buf, msg_len);
if (0 != ret) {
MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret);
return ret;
}
msg_len = ssl->in_hslen;
/*
* Handshake layer:
@@ -1003,64 +907,12 @@ read_record_header:
* 6 . 8 DTLS only: fragment offset
* 9 . 11 DTLS only: fragment length
*/
if (msg_len < mbedtls_ssl_hs_hdr_len(ssl)) {
MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
return MBEDTLS_ERR_SSL_DECODE_ERROR;
}
MBEDTLS_SSL_DEBUG_MSG(3, ("client hello v3, handshake type: %d", buf[0]));
if (buf[0] != MBEDTLS_SSL_HS_CLIENT_HELLO) {
if ((ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) ||
(buf[0] != MBEDTLS_SSL_HS_CLIENT_HELLO)) {
MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
/*
* Copy the client's handshake message_seq on initial handshakes,
* check sequence number on renego.
*/
#if defined(MBEDTLS_SSL_RENEGOTIATION)
if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
/* This couldn't be done in ssl_prepare_handshake_record() */
unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
if (cli_msg_seq != ssl->handshake->in_msg_seq) {
MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message_seq: "
"%u (expected %u)", cli_msg_seq,
ssl->handshake->in_msg_seq));
return MBEDTLS_ERR_SSL_DECODE_ERROR;
}
ssl->handshake->in_msg_seq++;
} else
#endif
{
unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
ssl->handshake->out_msg_seq = cli_msg_seq;
ssl->handshake->in_msg_seq = cli_msg_seq + 1;
}
{
/*
* For now we don't support fragmentation, so make sure
* fragment_offset == 0 and fragment_length == length
*/
size_t fragment_offset, fragment_length, length;
fragment_offset = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 6);
fragment_length = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 9);
length = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 1);
MBEDTLS_SSL_DEBUG_MSG(
4, ("fragment_offset=%u fragment_length=%u length=%u",
(unsigned) fragment_offset, (unsigned) fragment_length,
(unsigned) length));
if (fragment_offset != 0 || length != fragment_length) {
MBEDTLS_SSL_DEBUG_MSG(1, ("ClientHello fragmentation not supported"));
return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
}
}
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
buf += mbedtls_ssl_hs_hdr_len(ssl);
msg_len -= mbedtls_ssl_hs_hdr_len(ssl);
@@ -1390,7 +1242,11 @@ read_record_header:
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
case MBEDTLS_TLS_EXT_SESSION_TICKET:
MBEDTLS_SSL_DEBUG_MSG(3, ("found session ticket extension"));
/*
* If the Mbed TLS ssl_ticket.c implementation is used, the
* ticket is decrypted in place. This modifies the ClientHello
* message in the input buffer.
*/
ret = ssl_parse_session_ticket_ext(ssl, ext + 4, ext_size);
if (ret != 0) {
return ret;

View File

@@ -199,7 +199,7 @@ endif
test/metatest$(EXEXT): $(FRAMEWORK)/tests/programs/metatest.c $(DEP)
echo " CC $(FRAMEWORK)/tests/programs/metatest.c"
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) -I../library -I../tf-psa-crypto/core -I../tf-psa-crypto/drivers/builtin/include -I../tf-psa-crypto/drivers/builtin/src $(FRAMEWORK)/tests/programs/metatest.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) -I../library -I../tf-psa-crypto/core -I../tf-psa-crypto/drivers/builtin/src -I../tf-psa-crypto/platform $(FRAMEWORK)/tests/programs/metatest.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
test/query_config.o: test/query_config.c $(FRAMEWORK)/tests/programs/query_config.h $(DEP)
echo " CC test/query_config.c"

View File

@@ -4131,7 +4131,55 @@ close_notify:
} while (ret == MBEDTLS_ERR_SSL_WANT_WRITE);
ret = 0;
mbedtls_printf(" done\n");
/*
* In the DTLS case, attempt to read a possible response to the close
* notification. This avoids reconnecting to the same client when we
* reset and later receive its close-notification response during
* step 3 (waiting for a client to connect).
*
* Stop waiting for the response if the connection has already ended.
*
* The waiting loop below relies on mbedtls_ssl_read() returning regularly
* in order to keep the total waiting time approximately bounded to 1s. If
* no read timeout is configured (see the read_timeout option), or if the
* configured timeout is close to or larger than 1s, the total waiting time
* may exceed 1s by a significant margin.
*/
#if defined(MBEDTLS_SSL_PROTO_DTLS) && defined(MBEDTLS_HAVE_TIME)
if (opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
mbedtls_ms_time_t start = mbedtls_ms_time();
for (;;) {
ret = mbedtls_ssl_read(&ssl, buf, opt.buffer_size);
/*
* mbedtls_ssl_read() returned some data or timed out, loop if we
* have not spent already too much time, quite arbitrarily 1s.
*/
if ((ret > 0) || (ret == MBEDTLS_ERR_SSL_TIMEOUT)) {
if ((mbedtls_ms_time() - start) < 1000) {
continue;
}
}
if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
mbedtls_printf(" done, received client close notification.\n");
} else {
/* ret = 0, silent transport EOF or ret < 0 except
* MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY. Note that we do not
* handle specifically the non-fatal error codes like
* MBEDTLS_ERR_SSL_WANT_READ as we do not really expect them
* here.
*/
mbedtls_printf(" done\n");
}
break;
}
ret = 0;
} else
#endif /* MBEDTLS_SSL_PROTO_DTLS && MBEDTLS_HAVE_TIME */
{
mbedtls_printf(" done\n");
}
fflush(stdout);
#if defined(MBEDTLS_SSL_CACHE_C)
if (opt.cache_remove > 0) {

View File

@@ -103,9 +103,9 @@ foreach(exe IN LISTS executables)
endforeach()
target_include_directories(metatest
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tf-psa-crypto/drivers/builtin/include
${CMAKE_CURRENT_SOURCE_DIR}/../../tf-psa-crypto/drivers/builtin/src)
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tf-psa-crypto/drivers/builtin/src
${CMAKE_CURRENT_SOURCE_DIR}/../../tf-psa-crypto/platform
)
install(TARGETS ${executables}
DESTINATION "bin"
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)

View File

@@ -1,711 +1,16 @@
#!/usr/bin/env python3
"""This script compares the interfaces of two versions of Mbed TLS, looking
for backward incompatibilities between two different Git revisions within
an Mbed TLS repository. It must be run from the root of a Git working tree.
### How the script works ###
For the source (API) and runtime (ABI) interface compatibility, this script
is a small wrapper around the abi-compliance-checker and abi-dumper tools,
applying them to compare the header and library files.
For the storage format, this script compares the automatically generated
storage tests and the manual read tests, and complains if there is a
reduction in coverage. A change in test data will be signaled as a
coverage reduction since the old test data is no longer present. A change in
how test data is presented will be signaled as well; this would be a false
positive.
The results of the API/ABI comparison are either formatted as HTML and stored
at a configurable location, or are given as a brief list of problems.
Returns 0 on success, 1 on non-compliance, and 2 if there is an error
while running the script.
### How to interpret non-compliance ###
This script has relatively common false positives. In many scenarios, it only
reports a pass if there is a strict textual match between the old version and
the new version, and it reports problems where there is a sufficient semantic
match but not a textual match. This section lists some common false positives.
This is not an exhaustive list: in the end what matters is whether we are
breaking a backward compatibility goal.
**API**: the goal is that if an application works with the old version of the
library, it can be recompiled against the new version and will still work.
This is normally validated by comparing the declarations in `include/*/*.h`.
A failure is a declaration that has disappeared or that now has a different
type.
* It's ok to change or remove macros and functions that are documented as
for internal use only or as experimental.
* It's ok to rename function or macro parameters as long as the semantics
has not changed.
* It's ok to change or remove structure fields that are documented as
private.
* It's ok to add fields to a structure that already had private fields
or was documented as extensible.
**ABI**: the goal is that if an application was built against the old version
of the library, the same binary will work when linked against the new version.
This is normally validated by comparing the symbols exported by `libmbed*.so`.
A failure is a symbol that is no longer exported by the same library or that
now has a different type.
* All ABI changes are acceptable if the library version is bumped
(see `scripts/bump_version.sh`).
* ABI changes that concern functions which are declared only inside the
library directory, and not in `include/*/*.h`, are acceptable only if
the function was only ever used inside the same library (libmbedcrypto,
libmbedx509, libmbedtls). As a counter example, if the old version
of libmbedtls calls mbedtls_foo() from libmbedcrypto, and the new version
of libmbedcrypto no longer has a compatible mbedtls_foo(), this does
require a version bump for libmbedcrypto.
**Storage format**: the goal is to check that persistent keys stored by the
old version can be read by the new version. This is normally validated by
comparing the `*read*` test cases in `test_suite*storage_format*.data`.
A failure is a storage read test case that is no longer present with the same
function name and parameter list.
* It's ok if the same test data is present, but its presentation has changed,
for example if a test function is renamed or has different parameters.
* It's ok if redundant tests are removed.
**Generated test coverage**: the goal is to check that automatically
generated tests have as much coverage as before. This is normally validated
by comparing the test cases that are automatically generated by a script.
A failure is a generated test case that is no longer present with the same
function name and parameter list.
* It's ok if the same test data is present, but its presentation has changed,
for example if a test function is renamed or has different parameters.
* It's ok if redundant tests are removed.
"""Bridge script
See framework/scripts/mbedtls_framework/interface_checks.py for detailed documentation.
This is a convenient place to encode any branch-specific information we might want to add
in the future.
"""
# Copyright The Mbed TLS Contributors
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
import glob
import os
import re
import sys
import traceback
import shutil
import subprocess
import argparse
import logging
import tempfile
import fnmatch
from types import SimpleNamespace
import xml.etree.ElementTree as ET
import framework_scripts_path # pylint: disable=unused-import
from mbedtls_framework import build_tree
class AbiChecker:
"""API and ABI checker."""
def __init__(self, old_version, new_version, configuration):
"""Instantiate the API/ABI checker.
old_version: RepoVersion containing details to compare against
new_version: RepoVersion containing details to check
configuration.report_dir: directory for output files
configuration.keep_all_reports: if false, delete old reports
configuration.brief: if true, output shorter report to stdout
configuration.check_abi: if true, compare ABIs
configuration.check_api: if true, compare APIs
configuration.check_storage: if true, compare storage format tests
configuration.skip_file: path to file containing symbols and types to skip
"""
self.repo_path = "."
self.log = None
self.verbose = configuration.verbose
self._setup_logger()
self.report_dir = os.path.abspath(configuration.report_dir)
self.keep_all_reports = configuration.keep_all_reports
self.can_remove_report_dir = not (os.path.exists(self.report_dir) or
self.keep_all_reports)
self.old_version = old_version
self.new_version = new_version
self.skip_file = configuration.skip_file
self.check_abi = configuration.check_abi
self.check_api = configuration.check_api
if self.check_abi != self.check_api:
raise Exception('Checking API without ABI or vice versa is not supported')
self.check_storage_tests = configuration.check_storage
self.brief = configuration.brief
self.git_command = "git"
self.make_command = "make"
def _setup_logger(self):
self.log = logging.getLogger()
if self.verbose:
self.log.setLevel(logging.DEBUG)
else:
self.log.setLevel(logging.INFO)
self.log.addHandler(logging.StreamHandler())
@staticmethod
def check_abi_tools_are_installed():
for command in ["abi-dumper", "abi-compliance-checker"]:
if not shutil.which(command):
raise Exception("{} not installed, aborting".format(command))
def _get_clean_worktree_for_git_revision(self, version):
"""Make a separate worktree with version.revision checked out.
Do not modify the current worktree."""
git_worktree_path = tempfile.mkdtemp()
if version.repository:
self.log.debug(
"Checking out git worktree for revision {} from {}".format(
version.revision, version.repository
)
)
fetch_output = subprocess.check_output(
[self.git_command, "fetch",
version.repository, version.revision],
cwd=self.repo_path,
stderr=subprocess.STDOUT
)
self.log.debug(fetch_output.decode("utf-8"))
worktree_rev = "FETCH_HEAD"
else:
self.log.debug("Checking out git worktree for revision {}".format(
version.revision
))
worktree_rev = version.revision
worktree_output = subprocess.check_output(
[self.git_command, "worktree", "add", "--detach",
git_worktree_path, worktree_rev],
cwd=self.repo_path,
stderr=subprocess.STDOUT
)
self.log.debug(worktree_output.decode("utf-8"))
version.commit = subprocess.check_output(
[self.git_command, "rev-parse", "HEAD"],
cwd=git_worktree_path,
stderr=subprocess.STDOUT
).decode("ascii").rstrip()
self.log.debug("Commit is {}".format(version.commit))
return git_worktree_path
def _update_git_submodules(self, git_worktree_path, version):
"""If the crypto submodule is present, initialize it.
if version.crypto_revision exists, update it to that revision,
otherwise update it to the default revision"""
submodule_output = subprocess.check_output(
[self.git_command, "submodule", "foreach", "--recursive",
f'git worktree add --detach "{git_worktree_path}/$displaypath" HEAD'],
cwd=self.repo_path,
stderr=subprocess.STDOUT
)
self.log.debug(submodule_output.decode("utf-8"))
try:
# Try to update the submodules using local commits
# (Git will sometimes insist on fetching the remote without --no-fetch
# if the submodules are shallow clones)
update_output = subprocess.check_output(
[self.git_command, "submodule", "update", "--init", '--recursive', '--no-fetch'],
cwd=git_worktree_path,
stderr=subprocess.STDOUT
)
except subprocess.CalledProcessError as err:
self.log.debug(err.stdout.decode("utf-8"))
# Checkout with --no-fetch failed, falling back to fetching from origin
update_output = subprocess.check_output(
[self.git_command, "submodule", "update", "--init", '--recursive'],
cwd=git_worktree_path,
stderr=subprocess.STDOUT
)
self.log.debug(update_output.decode("utf-8"))
if not (os.path.exists(os.path.join(git_worktree_path, "crypto"))
and version.crypto_revision):
return
if version.crypto_repository:
fetch_output = subprocess.check_output(
[self.git_command, "fetch", version.crypto_repository,
version.crypto_revision],
cwd=os.path.join(git_worktree_path, "crypto"),
stderr=subprocess.STDOUT
)
self.log.debug(fetch_output.decode("utf-8"))
crypto_rev = "FETCH_HEAD"
else:
crypto_rev = version.crypto_revision
checkout_output = subprocess.check_output(
[self.git_command, "checkout", crypto_rev],
cwd=os.path.join(git_worktree_path, "crypto"),
stderr=subprocess.STDOUT
)
self.log.debug(checkout_output.decode("utf-8"))
def _build_shared_libraries(self, git_worktree_path, version):
"""Build the shared libraries in the specified worktree."""
my_environment = os.environ.copy()
my_environment["CFLAGS"] = "-g -Og"
my_environment["SHARED"] = "1"
if os.path.exists(os.path.join(git_worktree_path, "crypto")):
my_environment["USE_CRYPTO_SUBMODULE"] = "1"
if os.path.exists(os.path.join(git_worktree_path, "scripts", "legacy.make")):
command = [self.make_command, "-f", "scripts/legacy.make", "lib"]
else:
command = [self.make_command, "lib"]
make_output = subprocess.check_output(
command,
env=my_environment,
cwd=git_worktree_path,
stderr=subprocess.STDOUT
)
self.log.debug(make_output.decode("utf-8"))
for root, _dirs, files in os.walk(git_worktree_path):
for file in fnmatch.filter(files, "*.so"):
version.modules[os.path.splitext(file)[0]] = (
os.path.join(root, file)
)
@staticmethod
def _pretty_revision(version):
if version.revision == version.commit:
return version.revision
else:
return "{} ({})".format(version.revision, version.commit)
def _get_abi_dumps_from_shared_libraries(self, version):
"""Generate the ABI dumps for the specified git revision.
The shared libraries must have been built and the module paths
present in version.modules."""
for mbed_module, module_path in version.modules.items():
output_path = os.path.join(
self.report_dir, "{}-{}-{}.dump".format(
mbed_module, version.revision, version.version
)
)
abi_dump_command = [
"abi-dumper",
module_path,
"-o", output_path,
"-lver", self._pretty_revision(version),
]
abi_dump_output = subprocess.check_output(
abi_dump_command,
stderr=subprocess.STDOUT
)
self.log.debug(abi_dump_output.decode("utf-8"))
version.abi_dumps[mbed_module] = output_path
@staticmethod
def _normalize_storage_test_case_data(line):
"""Eliminate cosmetic or irrelevant details in storage format test cases."""
line = re.sub(r'\s+', r'', line)
return line
def _read_storage_tests(self,
directory,
filename,
is_generated,
storage_tests):
"""Record storage tests from the given file.
Populate the storage_tests dictionary with test cases read from
filename under directory.
"""
at_paragraph_start = True
description = None
full_path = os.path.join(directory, filename)
with open(full_path) as fd:
for line_number, line in enumerate(fd, 1):
line = line.strip()
if not line:
at_paragraph_start = True
continue
if line.startswith('#'):
continue
if at_paragraph_start:
description = line.strip()
at_paragraph_start = False
continue
if line.startswith('depends_on:'):
continue
# We've reached a test case data line
test_case_data = self._normalize_storage_test_case_data(line)
if not is_generated:
# In manual test data, only look at read tests.
function_name = test_case_data.split(':', 1)[0]
if 'read' not in function_name.split('_'):
continue
metadata = SimpleNamespace(
filename=filename,
line_number=line_number,
description=description
)
storage_tests[test_case_data] = metadata
@staticmethod
def _list_generated_test_data_files(git_worktree_path):
"""List the generated test data files."""
generate_psa_tests = 'framework/scripts/generate_psa_tests.py'
if not os.path.isfile(git_worktree_path + '/' + generate_psa_tests):
# The checked-out revision is from before generate_psa_tests.py
# was moved to the framework submodule. Use the old location.
generate_psa_tests = 'tests/scripts/generate_psa_tests.py'
output = subprocess.check_output(
[generate_psa_tests, '--list'],
cwd=git_worktree_path,
).decode('ascii')
return [line for line in output.split('\n') if line]
def _get_storage_format_tests(self, version, git_worktree_path):
"""Record the storage format tests for the specified git version.
The storage format tests are the test suite data files whose name
contains "storage_format".
The version must be checked out at git_worktree_path.
This function creates or updates the generated data files.
"""
# Existing test data files. This may be missing some automatically
# generated files if they haven't been generated yet.
if os.path.isdir(os.path.join(git_worktree_path, 'tf-psa-crypto',
'tests', 'suites')):
storage_data_files = set(glob.glob(
'tf-psa-crypto/tests/suites/test_suite_*storage_format*.data'
))
else:
storage_data_files = set(glob.glob(
'tests/suites/test_suite_*storage_format*.data'
))
# Discover and (re)generate automatically generated data files.
to_be_generated = set()
for filename in self._list_generated_test_data_files(git_worktree_path):
if 'storage_format' in filename:
storage_data_files.add(filename)
to_be_generated.add(filename)
generate_psa_tests = 'framework/scripts/generate_psa_tests.py'
if not os.path.isfile(git_worktree_path + '/' + generate_psa_tests):
# The checked-out revision is from before generate_psa_tests.py
# was moved to the framework submodule. Use the old location.
generate_psa_tests = 'tests/scripts/generate_psa_tests.py'
subprocess.check_call(
[generate_psa_tests] + sorted(to_be_generated),
cwd=git_worktree_path,
)
for test_file in sorted(storage_data_files):
self._read_storage_tests(git_worktree_path,
test_file,
test_file in to_be_generated,
version.storage_tests)
def _cleanup_worktree(self, git_worktree_path):
"""Remove the specified git worktree."""
shutil.rmtree(git_worktree_path)
submodule_output = subprocess.check_output(
[self.git_command, "submodule", "foreach", "--recursive",
f'git worktree remove "{git_worktree_path}/$displaypath"'],
cwd=self.repo_path,
stderr=subprocess.STDOUT
)
self.log.debug(submodule_output.decode("utf-8"))
worktree_output = subprocess.check_output(
[self.git_command, "worktree", "remove", git_worktree_path],
cwd=self.repo_path,
stderr=subprocess.STDOUT
)
self.log.debug(worktree_output.decode("utf-8"))
def _get_abi_dump_for_ref(self, version):
"""Generate the interface information for the specified git revision."""
git_worktree_path = self._get_clean_worktree_for_git_revision(version)
self._update_git_submodules(git_worktree_path, version)
if self.check_abi:
self._build_shared_libraries(git_worktree_path, version)
self._get_abi_dumps_from_shared_libraries(version)
if self.check_storage_tests:
self._get_storage_format_tests(version, git_worktree_path)
self._cleanup_worktree(git_worktree_path)
def _remove_children_with_tag(self, parent, tag):
children = parent.getchildren()
for child in children:
if child.tag == tag:
parent.remove(child)
else:
self._remove_children_with_tag(child, tag)
def _remove_extra_detail_from_report(self, report_root):
for tag in ['test_info', 'test_results', 'problem_summary',
'added_symbols', 'affected']:
self._remove_children_with_tag(report_root, tag)
for report in report_root:
for problems in report.getchildren()[:]:
if not problems.getchildren():
report.remove(problems)
def _abi_compliance_command(self, mbed_module, output_path):
"""Build the command to run to analyze the library mbed_module.
The report will be placed in output_path."""
abi_compliance_command = [
"abi-compliance-checker",
"-l", mbed_module,
"-old", self.old_version.abi_dumps[mbed_module],
"-new", self.new_version.abi_dumps[mbed_module],
"-strict",
"-report-path", output_path,
]
if self.skip_file:
abi_compliance_command += ["-skip-symbols", self.skip_file,
"-skip-types", self.skip_file]
if self.brief:
abi_compliance_command += ["-report-format", "xml",
"-stdout"]
return abi_compliance_command
def _is_library_compatible(self, mbed_module, compatibility_report):
"""Test if the library mbed_module has remained compatible.
Append a message regarding compatibility to compatibility_report."""
output_path = os.path.join(
self.report_dir, "{}-{}-{}.html".format(
mbed_module, self.old_version.revision,
self.new_version.revision
)
)
try:
subprocess.check_output(
self._abi_compliance_command(mbed_module, output_path),
stderr=subprocess.STDOUT
)
except subprocess.CalledProcessError as err:
if err.returncode != 1:
raise err
if self.brief:
self.log.info(
"Compatibility issues found for {}".format(mbed_module)
)
report_root = ET.fromstring(err.output.decode("utf-8"))
self._remove_extra_detail_from_report(report_root)
self.log.info(ET.tostring(report_root).decode("utf-8"))
else:
self.can_remove_report_dir = False
compatibility_report.append(
"Compatibility issues found for {}, "
"for details see {}".format(mbed_module, output_path)
)
return False
compatibility_report.append(
"No compatibility issues for {}".format(mbed_module)
)
if not (self.keep_all_reports or self.brief):
os.remove(output_path)
return True
@staticmethod
def _is_storage_format_compatible(old_tests, new_tests,
compatibility_report):
"""Check whether all tests present in old_tests are also in new_tests.
Append a message regarding compatibility to compatibility_report.
"""
missing = frozenset(old_tests.keys()).difference(new_tests.keys())
for test_data in sorted(missing):
metadata = old_tests[test_data]
compatibility_report.append(
'Test case from {} line {} "{}" has disappeared: {}'.format(
metadata.filename, metadata.line_number,
metadata.description, test_data
)
)
compatibility_report.append(
'FAIL: {}/{} storage format test cases have changed or disappeared.'.format(
len(missing), len(old_tests)
) if missing else
'PASS: All {} storage format test cases are preserved.'.format(
len(old_tests)
)
)
compatibility_report.append(
'Info: number of storage format tests cases: {} -> {}.'.format(
len(old_tests), len(new_tests)
)
)
return not missing
def get_abi_compatibility_report(self):
"""Generate a report of the differences between the reference ABI
and the new ABI. ABI dumps from self.old_version and self.new_version
must be available."""
compatibility_report = ["Checking evolution from {} to {}".format(
self._pretty_revision(self.old_version),
self._pretty_revision(self.new_version)
)]
compliance_return_code = 0
if self.check_abi:
shared_modules = list(set(self.old_version.modules.keys()) &
set(self.new_version.modules.keys()))
for mbed_module in shared_modules:
if not self._is_library_compatible(mbed_module,
compatibility_report):
compliance_return_code = 1
if self.check_storage_tests:
if not self._is_storage_format_compatible(
self.old_version.storage_tests,
self.new_version.storage_tests,
compatibility_report):
compliance_return_code = 1
for version in [self.old_version, self.new_version]:
for mbed_module, mbed_module_dump in version.abi_dumps.items():
os.remove(mbed_module_dump)
if self.can_remove_report_dir:
os.rmdir(self.report_dir)
self.log.info("\n".join(compatibility_report))
return compliance_return_code
def check_for_abi_changes(self):
"""Generate a report of ABI differences
between self.old_rev and self.new_rev."""
build_tree.check_repo_path()
if self.check_api or self.check_abi:
self.check_abi_tools_are_installed()
self._get_abi_dump_for_ref(self.old_version)
self._get_abi_dump_for_ref(self.new_version)
return self.get_abi_compatibility_report()
def run_main():
try:
parser = argparse.ArgumentParser(
description=__doc__
)
parser.add_argument(
"-v", "--verbose", action="store_true",
help="set verbosity level",
)
parser.add_argument(
"-r", "--report-dir", type=str, default="reports",
help="directory where reports are stored, default is reports",
)
parser.add_argument(
"-k", "--keep-all-reports", action="store_true",
help="keep all reports, even if there are no compatibility issues",
)
parser.add_argument(
"-o", "--old-rev", type=str, help="revision for old version.",
required=True,
)
parser.add_argument(
"-or", "--old-repo", type=str, help="repository for old version."
)
parser.add_argument(
"-oc", "--old-crypto-rev", type=str,
help="revision for old crypto submodule."
)
parser.add_argument(
"-ocr", "--old-crypto-repo", type=str,
help="repository for old crypto submodule."
)
parser.add_argument(
"-n", "--new-rev", type=str, help="revision for new version",
required=True,
)
parser.add_argument(
"-nr", "--new-repo", type=str, help="repository for new version."
)
parser.add_argument(
"-nc", "--new-crypto-rev", type=str,
help="revision for new crypto version"
)
parser.add_argument(
"-ncr", "--new-crypto-repo", type=str,
help="repository for new crypto submodule."
)
parser.add_argument(
"-s", "--skip-file", type=str,
help=("path to file containing symbols and types to skip "
"(typically \"-s identifiers\" after running "
"\"tests/scripts/list-identifiers.sh --internal\")")
)
parser.add_argument(
"--check-abi",
action='store_true', default=True,
help="Perform ABI comparison (default: yes)"
)
parser.add_argument("--no-check-abi", action='store_false', dest='check_abi')
parser.add_argument(
"--check-api",
action='store_true', default=True,
help="Perform API comparison (default: yes)"
)
parser.add_argument("--no-check-api", action='store_false', dest='check_api')
parser.add_argument(
"--check-storage",
action='store_true', default=True,
help="Perform storage tests comparison (default: yes)"
)
parser.add_argument("--no-check-storage", action='store_false', dest='check_storage')
parser.add_argument(
"-b", "--brief", action="store_true",
help="output only the list of issues to stdout, instead of a full report",
)
abi_args = parser.parse_args()
if os.path.isfile(abi_args.report_dir):
print("Error: {} is not a directory".format(abi_args.report_dir))
parser.exit()
old_version = SimpleNamespace(
version="old",
repository=abi_args.old_repo,
revision=abi_args.old_rev,
commit=None,
crypto_repository=abi_args.old_crypto_repo,
crypto_revision=abi_args.old_crypto_rev,
abi_dumps={},
storage_tests={},
modules={}
)
new_version = SimpleNamespace(
version="new",
repository=abi_args.new_repo,
revision=abi_args.new_rev,
commit=None,
crypto_repository=abi_args.new_crypto_repo,
crypto_revision=abi_args.new_crypto_rev,
abi_dumps={},
storage_tests={},
modules={}
)
configuration = SimpleNamespace(
verbose=abi_args.verbose,
report_dir=abi_args.report_dir,
keep_all_reports=abi_args.keep_all_reports,
brief=abi_args.brief,
check_abi=abi_args.check_abi,
check_api=abi_args.check_api,
check_storage=abi_args.check_storage,
skip_file=abi_args.skip_file
)
abi_check = AbiChecker(old_version, new_version, configuration)
return_code = abi_check.check_for_abi_changes()
sys.exit(return_code)
except Exception: # pylint: disable=broad-except
# Print the backtrace and exit explicitly so as to exit with
# status 2, not 1.
traceback.print_exc()
sys.exit(2)
from mbedtls_framework import interface_checks
if __name__ == "__main__":
run_main()
interface_checks.run_main()

View File

@@ -6,12 +6,9 @@ Generate miscellaneous TLS test cases relating to the handshake.
# Copyright The Mbed TLS Contributors
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
import sys
import framework_scripts_path # pylint: disable=unused-import
from mbedtls_framework import tls_handshake_tests
if __name__ == '__main__':
sys.argv[1:1] = ["--no-tls12-client-hello-defragmentation-support"]
tls_handshake_tests.main()

View File

@@ -180,6 +180,10 @@ C_SOURCE_FILES = $(wildcard \
tf-psa-crypto/drivers/*/*/*.c \
tf-psa-crypto/drivers/*/*/*/*.c \
tf-psa-crypto/drivers/*/*/*/*/*.c \
tf-psa-crypto/dispatch/*.[hc] \
tf-psa-crypto/extras/*.[hc] \
tf-psa-crypto/platform/*.[hc] \
tf-psa-crypto/utilities/*.[hc] \
programs/*/*.[hc] \
framework/tests/include/*/*.h framework/tests/include/*/*/*.h \
framework/tests/src/*.c framework/tests/src/*/*.c \
@@ -200,5 +204,9 @@ cscope.in.out cscope.po.out cscope.out: $(C_SOURCE_FILES)
cscope -bq -u -Iinclude -Ilibrary -Itf-psa-crypto/core \
-Itf-psa-crypto/include \
-Itf-psa-crypto/drivers/builtin/src \
-Itf-psa-crypto/dispatch \
-Itf-psa-crypto/extras \
-Itf-psa-crypto/platform \
-Itf-psa-crypto/utilities \
$(patsubst %,-I%,$(wildcard tf-psa-crypto/drivers/*/include)) -Iframework/tests/include $(C_SOURCE_FILES)
.PHONY: cscope global

View File

@@ -177,11 +177,11 @@ function(add_test_suite suite_name)
# them as PUBLIC.
target_include_directories(test_suite_${data_name}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/include
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../framework/tests/include
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../library
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../tf-psa-crypto/core
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../tf-psa-crypto/drivers/builtin/src)
${CMAKE_CURRENT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/framework/tests/include
${PROJECT_SOURCE_DIR}/library
${TF_PSA_CRYPTO_PRIVATE_INCLUDE_DIRS}
)
# Request C11, which is needed for memory poisoning tests
set_target_properties(test_suite_${data_name} PROPERTIES C_STANDARD 11)

View File

@@ -252,7 +252,19 @@ libtestdriver1.a:
cp -Rf ../scripts ./libtestdriver1
cp -Rf ../tf-psa-crypto/core ./libtestdriver1/tf-psa-crypto
cp -Rf ../tf-psa-crypto/include ./libtestdriver1/tf-psa-crypto
cp -Rf ../tf-psa-crypto/drivers/builtin ./libtestdriver1/tf-psa-crypto/drivers
cp -Rf ../tf-psa-crypto/drivers/builtin ./libtestdriver1/tf-psa-crypto/drivers/builtin
if [ -d ../tf-psa-crypto/dispatch ]; then \
cp -Rf ../tf-psa-crypto/dispatch ./libtestdriver1/tf-psa-crypto/dispatch; \
fi
if [ -d ../tf-psa-crypto/extras ]; then \
cp -Rf ../tf-psa-crypto/extras ./libtestdriver1/tf-psa-crypto/extras; \
fi
if [ -d ../tf-psa-crypto/platform ]; then \
cp -Rf ../tf-psa-crypto/platform ./libtestdriver1/tf-psa-crypto/platform; \
fi
if [ -d ../tf-psa-crypto/utilities ]; then \
cp -Rf ../tf-psa-crypto/utilities ./libtestdriver1/tf-psa-crypto/utilities; \
fi
cp -Rf ../tf-psa-crypto/scripts ./libtestdriver1/tf-psa-crypto
# Set the test driver base (minimal) configuration.
@@ -285,7 +297,18 @@ libtestdriver1.a:
perl -i ./scripts/libtestdriver1_rewrite.pl ./libtestdriver1/tf-psa-crypto/drivers/builtin/include/*/*.h
perl -i ./scripts/libtestdriver1_rewrite.pl ./libtestdriver1/tf-psa-crypto/drivers/builtin/include/*/*/*.h
perl -i ./scripts/libtestdriver1_rewrite.pl ./libtestdriver1/tf-psa-crypto/drivers/builtin/src/*.[ch]
if [ -d ../tf-psa-crypto/dispatch ]; then \
perl -i ./scripts/libtestdriver1_rewrite.pl ./libtestdriver1/tf-psa-crypto/dispatch/*.[ch]; \
fi
if [ -d ../tf-psa-crypto/extras ]; then \
perl -i ./scripts/libtestdriver1_rewrite.pl ./libtestdriver1/tf-psa-crypto/extras/*.[ch]; \
fi
if [ -d ../tf-psa-crypto/platform ]; then \
perl -i ./scripts/libtestdriver1_rewrite.pl ./libtestdriver1/tf-psa-crypto/platform/*.[ch]; \
fi
if [ -d ../tf-psa-crypto/utilities ]; then \
perl -i ./scripts/libtestdriver1_rewrite.pl ./libtestdriver1/tf-psa-crypto/utilities/*.[ch]; \
fi
$(MAKE) -C ./libtestdriver1/library CFLAGS="-I../../ $(CFLAGS)" LDFLAGS="$(LDFLAGS)" libmbedcrypto.a
cp ./libtestdriver1/library/libmbedcrypto.a ../library/libtestdriver1.a

View File

@@ -557,6 +557,7 @@ setup_arguments()
# with OpenSSL 1.0.1h, -www, -WWW and -HTTP break DTLS handshakes
if is_dtls "$MODE"; then
O_SERVER_ARGS="$O_SERVER_ARGS"
M_SERVER_ARGS="$M_SERVER_ARGS read_timeout=1000"
else
O_SERVER_ARGS="$O_SERVER_ARGS -www"
fi

View File

@@ -43,7 +43,7 @@ class CoverageTask(outcome_analysis.CoverageTask):
'DTLS cookie: enabled, IPv6',
# Disabled due to OpenSSL bug.
# https://github.com/openssl/openssl/issues/18887
'DTLS fragmenting: 3d, openssl client, DTLS 1.2',
'DTLS fragmenting: 3d, MTU=512, openssl client, DTLS 1.2',
# We don't run ssl-opt.sh with Valgrind on the CI because
# it's extremely slow. We don't intend to change this.
'DTLS fragmenting: proxy MTU: auto-reduction (with valgrind)',

View File

@@ -12,8 +12,6 @@
component_check_recursion () {
msg "Check: recursion.pl" # < 1s
./framework/scripts/recursion.pl library/*.c
./framework/scripts/recursion.pl ${PSA_CORE_PATH}/*.c
./framework/scripts/recursion.pl ${BUILTIN_SRC_PATH}/*.c
}
component_check_generated_files () {

View File

@@ -10,6 +10,7 @@
################################################################
CMAKE_BUILTIN_BUILD_DIR="tf-psa-crypto/drivers/builtin/CMakeFiles/builtin.dir/src"
CMAKE_EXTRAS_BUILD_DIR="tf-psa-crypto/extras/CMakeFiles/extras.dir"
component_test_psa_crypto_key_id_encodes_owner () {
msg "build: full config + PSA_CRYPTO_KEY_ID_ENCODES_OWNER, cmake, gcc, ASan"
@@ -280,8 +281,13 @@ component_full_no_pkparse_pkwrite () {
cmake --build .
# Ensure that PK_[PARSE|WRITE]_C were not re-enabled accidentally (additive config).
not grep mbedtls_pk_parse_key ${CMAKE_BUILTIN_BUILD_DIR}/pkparse.c.o
not grep mbedtls_pk_write_key_der ${CMAKE_BUILTIN_BUILD_DIR}/pkwrite.c.o
if [ -f ${TF_PSA_CRYPTO_ROOT_DIR}/extras/pkparse.c ]; then
not grep mbedtls_pk_parse_key ${CMAKE_EXTRAS_BUILD_DIR}/pkparse.c.o
not grep mbedtls_pk_write_key_der ${CMAKE_EXTRAS_BUILD_DIR}/pkwrite.c.o
else
not grep mbedtls_pk_parse_key ${CMAKE_BUILTIN_BUILD_DIR}/pkparse.c.o
not grep mbedtls_pk_write_key_der ${CMAKE_BUILTIN_BUILD_DIR}/pkwrite.c.o
fi
msg "test: full without pkparse and pkwrite"
ctest
@@ -302,7 +308,11 @@ component_full_no_pkwrite () {
make
# Ensure that PK_WRITE_C was not re-enabled accidentally (additive config).
not grep mbedtls_pk_write_key_der ${CMAKE_BUILTIN_BUILD_DIR}/pkwrite.c.o
if [ -f ${TF_PSA_CRYPTO_ROOT_DIR}/extras/pkwrite.c ]; then
not grep mbedtls_pk_write_key_der ${CMAKE_EXTRAS_BUILD_DIR}/pkwrite.c.o
else
not grep mbedtls_pk_write_key_der ${CMAKE_BUILTIN_BUILD_DIR}/pkwrite.c.o
fi
msg "test: full without pkwrite"
make test
@@ -329,8 +339,13 @@ component_test_crypto_full_md_light_only () {
cmake --build .
# Make sure we don't have the HMAC functions, but the hashing functions
not grep mbedtls_md_hmac ${CMAKE_BUILTIN_BUILD_DIR}/md.c.o
grep mbedtls_md ${CMAKE_BUILTIN_BUILD_DIR}/md.c.o
if [ -f ${TF_PSA_CRYPTO_ROOT_DIR}/extras/md.c ]; then
not grep mbedtls_md_hmac ${CMAKE_EXTRAS_BUILD_DIR}/md.c.o
grep mbedtls_md ${CMAKE_EXTRAS_BUILD_DIR}/md.c.o
else
not grep mbedtls_md_hmac ${CMAKE_BUILTIN_BUILD_DIR}/md.c.o
grep mbedtls_md ${CMAKE_BUILTIN_BUILD_DIR}/md.c.o
fi
msg "test: crypto_full with only the light subset of MD"
ctest
@@ -1668,7 +1683,11 @@ component_test_psa_crypto_config_accel_hmac () {
helper_libtestdriver1_make_main "$loc_accel_list"
# Ensure that built-in support for HMAC is disabled.
not grep mbedtls_md_hmac ${BUILTIN_SRC_PATH}/md.o
if [ -f ${TF_PSA_CRYPTO_ROOT_DIR}/extras/md.c ]; then
not grep mbedtls_md_hmac ${TF_PSA_CRYPTO_ROOT_DIR}/extras/md.o
else
not grep mbedtls_md_hmac ${BUILTIN_SRC_PATH}/md.o
fi
# Run the tests
# -------------

View File

@@ -165,6 +165,7 @@ component_test_tls1_2_ccm_psk_dtls () {
msg "build: configs/config-ccm-psk-dtls1_2.h"
MBEDTLS_CONFIG="configs/config-ccm-psk-dtls1_2.h"
CRYPTO_CONFIG="configs/crypto-config-ccm-psk-tls1_2.h"
tf-psa-crypto/scripts/config.py -f "$CRYPTO_CONFIG" set MBEDTLS_HAVE_TIME
CC=$ASAN_CC cmake -DMBEDTLS_CONFIG_FILE="$MBEDTLS_CONFIG" -DTF_PSA_CRYPTO_CONFIG_FILE="$CRYPTO_CONFIG" -D CMAKE_BUILD_TYPE:String=Asan .
make

View File

@@ -439,6 +439,18 @@ component_build_arm_none_eabi_gcc () {
${ARM_NONE_EABI_GCC_PREFIX}size -t library/*.o
${ARM_NONE_EABI_GCC_PREFIX}size -t ${PSA_CORE_PATH}/*.o
${ARM_NONE_EABI_GCC_PREFIX}size -t ${BUILTIN_SRC_PATH}/*.o
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/dispatch/*.o" > /dev/null; then
${ARM_NONE_EABI_GCC_PREFIX}size -t ${TF_PSA_CRYPTO_ROOT_DIR}/dispatch/*.o
fi
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/extras/*.o" > /dev/null; then
${ARM_NONE_EABI_GCC_PREFIX}size -t ${TF_PSA_CRYPTO_ROOT_DIR}/extras/*.o
fi
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/platform/*.o" > /dev/null; then
${ARM_NONE_EABI_GCC_PREFIX}size -t ${TF_PSA_CRYPTO_ROOT_DIR}/platform/*.o
fi
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/utilities/*.o" > /dev/null; then
${ARM_NONE_EABI_GCC_PREFIX}size -t ${TF_PSA_CRYPTO_ROOT_DIR}/utilities/*.o
fi
}
component_build_arm_linux_gnueabi_gcc_arm5vte () {
@@ -455,6 +467,18 @@ component_build_arm_linux_gnueabi_gcc_arm5vte () {
${ARM_LINUX_GNUEABI_GCC_PREFIX}size -t library/*.o
${ARM_LINUX_GNUEABI_GCC_PREFIX}size -t ${PSA_CORE_PATH}/*.o
${ARM_LINUX_GNUEABI_GCC_PREFIX}size -t ${BUILTIN_SRC_PATH}/*.o
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/dispatch/*.o" > /dev/null; then
${ARM_LINUX_GNUEABI_GCC_PREFIX}size -t ${TF_PSA_CRYPTO_ROOT_DIR}/dispatch/*.o
fi
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/extras/*.o" > /dev/null; then
${ARM_LINUX_GNUEABI_GCC_PREFIX}size -t ${TF_PSA_CRYPTO_ROOT_DIR}/extras/*.o
fi
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/platform/*.o" > /dev/null; then
${ARM_LINUX_GNUEABI_GCC_PREFIX}size -t ${TF_PSA_CRYPTO_ROOT_DIR}/platform/*.o
fi
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/utilities/*.o" > /dev/null; then
${ARM_LINUX_GNUEABI_GCC_PREFIX}size -t ${TF_PSA_CRYPTO_ROOT_DIR}/utilities/*.o
fi
}
support_build_arm_linux_gnueabi_gcc_arm5vte () {
@@ -473,6 +497,18 @@ component_build_arm_none_eabi_gcc_arm5vte () {
${ARM_NONE_EABI_GCC_PREFIX}size -t library/*.o
${ARM_NONE_EABI_GCC_PREFIX}size -t ${PSA_CORE_PATH}/*.o
${ARM_NONE_EABI_GCC_PREFIX}size -t ${BUILTIN_SRC_PATH}/*.o
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/dispatch/*.o" > /dev/null; then
${ARM_NONE_EABI_GCC_PREFIX}size -t ${TF_PSA_CRYPTO_ROOT_DIR}/dispatch/*.o
fi
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/extras/*.o" > /dev/null; then
${ARM_NONE_EABI_GCC_PREFIX}size -t ${TF_PSA_CRYPTO_ROOT_DIR}/extras/*.o
fi
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/platform/*.o" > /dev/null; then
${ARM_NONE_EABI_GCC_PREFIX}size -t ${TF_PSA_CRYPTO_ROOT_DIR}/platform/*.o
fi
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/utilities/*.o" > /dev/null; then
${ARM_NONE_EABI_GCC_PREFIX}size -t ${TF_PSA_CRYPTO_ROOT_DIR}/utilities/*.o
fi
}
component_build_arm_none_eabi_gcc_m0plus () {
@@ -484,6 +520,18 @@ component_build_arm_none_eabi_gcc_m0plus () {
${ARM_NONE_EABI_GCC_PREFIX}size -t library/*.o
${ARM_NONE_EABI_GCC_PREFIX}size -t ${PSA_CORE_PATH}/*.o
${ARM_NONE_EABI_GCC_PREFIX}size -t ${BUILTIN_SRC_PATH}/*.o
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/dispatch/*.o" > /dev/null; then
${ARM_NONE_EABI_GCC_PREFIX}size -t ${TF_PSA_CRYPTO_ROOT_DIR}/dispatch/*.o
fi
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/extras/*.o" > /dev/null; then
${ARM_NONE_EABI_GCC_PREFIX}size -t ${TF_PSA_CRYPTO_ROOT_DIR}/extras/*.o
fi
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/platform/*.o" > /dev/null; then
${ARM_NONE_EABI_GCC_PREFIX}size -t ${TF_PSA_CRYPTO_ROOT_DIR}/platform/*.o
fi
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/utilities/*.o" > /dev/null; then
${ARM_NONE_EABI_GCC_PREFIX}size -t ${TF_PSA_CRYPTO_ROOT_DIR}/utilities/*.o
fi
for lib in library/*.a; do
echo "$lib:"
${ARM_NONE_EABI_GCC_PREFIX}size -t $lib | grep TOTALS
@@ -499,6 +547,18 @@ component_build_arm_none_eabi_gcc_no_udbl_division () {
not grep __aeabi_uldiv library/*.o
not grep __aeabi_uldiv ${PSA_CORE_PATH}/*.o
not grep __aeabi_uldiv ${BUILTIN_SRC_PATH}/*.o
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/dispatch/*.o" > /dev/null; then
not grep __aeabi_uldiv ${TF_PSA_CRYPTO_ROOT_DIR}/dispatch/*.o
fi
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/extras/*.o" > /dev/null; then
not grep __aeabi_uldiv ${TF_PSA_CRYPTO_ROOT_DIR}/extras/*.o
fi
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/platform/*.o" > /dev/null; then
not grep __aeabi_uldiv ${TF_PSA_CRYPTO_ROOT_DIR}/platform/*.o
fi
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/utilities/*.o" > /dev/null; then
not grep __aeabi_uldiv ${TF_PSA_CRYPTO_ROOT_DIR}/utilities/*.o
fi
}
component_build_arm_none_eabi_gcc_no_64bit_multiplication () {
@@ -510,6 +570,18 @@ component_build_arm_none_eabi_gcc_no_64bit_multiplication () {
not grep __aeabi_lmul library/*.o
not grep __aeabi_lmul ${PSA_CORE_PATH}/*.o
not grep __aeabi_lmul ${BUILTIN_SRC_PATH}/*.o
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/dispatch/*.o" > /dev/null; then
not grep __aeabi_lmul ${TF_PSA_CRYPTO_ROOT_DIR}/dispatch/*.o
fi
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/extras/*.o" > /dev/null; then
not grep __aeabi_lmul ${TF_PSA_CRYPTO_ROOT_DIR}/extras/*.o
fi
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/platform/*.o" > /dev/null; then
not grep __aeabi_lmul ${TF_PSA_CRYPTO_ROOT_DIR}/platform/*.o
fi
if compgen -G "${TF_PSA_CRYPTO_ROOT_DIR}/utilities/*.o" > /dev/null; then
not grep __aeabi_lmul ${TF_PSA_CRYPTO_ROOT_DIR}/utilities/*.o
fi
}
component_build_arm_clang_thumb () {

View File

@@ -37,7 +37,9 @@ def main():
"include/mbedtls/*_internal.h",
"library/*.h",
"tf-psa-crypto/core/*.h",
"tf-psa-crypto/drivers/builtin/src/*.h"
"tf-psa-crypto/drivers/builtin/src/*.h",
"tf-psa-crypto/platform/*.h",
"tf-psa-crypto/utilities/*.h",
])[0]
result.sort(key=lambda x: x.name)

View File

@@ -9931,7 +9931,7 @@ run_test "DTLS reassembly: more fragmentation (gnutls server)" \
requires_gnutls
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS reassembly: more fragmentation, nbio (gnutls server)" \
"$G_SRV -u --mtu 128" \
"$G_SRV -u --mtu 109" \
"$P_CLI dtls=1 nbio=2 debug_level=2" \
0 \
-c "found fragmented DTLS handshake message" \
@@ -9943,7 +9943,7 @@ requires_gnutls
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS reassembly: fragmentation, renego (gnutls server)" \
"$G_SRV -u --mtu 256" \
"$G_SRV -u --mtu 241" \
"$P_CLI debug_level=3 dtls=1 renegotiation=1 renegotiate=1" \
0 \
-c "found fragmented DTLS handshake message" \
@@ -9971,6 +9971,52 @@ run_test "DTLS reassembly: fragmentation, nbio, renego (gnutls server)" \
-C "error" \
-s "Extra-header:"
requires_gnutls
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS reassembly: no fragmentation (gnutls client)" \
"$P_SRV debug_level=2 dtls=1" \
"$G_NEXT_CLI -u --mtu 2048 --insecure 127.0.0.1" \
0 \
-S "found fragmented DTLS handshake message" \
-S "error"
requires_gnutls
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS reassembly: some fragmentation (gnutls client)" \
"$P_SRV debug_level=2 dtls=1 auth_mode=required" \
"$G_NEXT_CLI -u --mtu 211 --insecure 127.0.0.1 --x509certfile $DATA_FILES_PATH/server5.crt --x509keyfile $DATA_FILES_PATH/server5.key" \
0 \
-s "found fragmented DTLS handshake message" \
-s "Certificate handshake message has been buffered and reassembled" \
-S "error"
# Set the MTU to 128 bytes. The minimum size of a DTLS 1.2 record
# containing a ClientHello handshake message is 69 bytes, without any cookie,
# ciphersuite, or extension. With an MTU of 128 bytes, the ClientHello handshake
# message is therefore very likely to be fragmented, regardless of the
# GnuTLS client version. For example, the ClientHello sent by the GnuTLS 3.7.2
# client is 206 bytes in this test.
requires_gnutls
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS reassembly: more fragmentation (gnutls client)" \
"$P_SRV debug_level=2 dtls=1" \
"$G_NEXT_CLI -u --mtu 103 --insecure 127.0.0.1" \
0 \
-s "ClientHello handshake message has been buffered and reassembled" \
-S "error"
requires_gnutls
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS reassembly: more fragmentation, nbio (gnutls client)" \
"$P_SRV debug_level=2 dtls=1 nbio=2" \
"$G_NEXT_CLI -u --mtu 103 --insecure 127.0.0.1" \
0 \
-s "ClientHello handshake message has been buffered and reassembled" \
-S "error"
# No fragmentation and renegotiation tests with GnuTLS client as the feature
# does not work properly.
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS reassembly: no fragmentation (openssl server)" \
"$O_SRV -dtls -mtu 2048" \
@@ -9994,13 +10040,45 @@ run_test "DTLS reassembly: fragmentation (openssl server)" \
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS reassembly: fragmentation, nbio (openssl server)" \
"$O_SRV -dtls -mtu 256" \
"$O_SRV -dtls -mtu 273" \
"$P_CLI dtls=1 nbio=2 debug_level=2" \
0 \
-c "found fragmented DTLS handshake message" \
-c "Certificate handshake message has been buffered and reassembled" \
-C "error"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS reassembly: no fragmentation (openssl client)" \
"$P_SRV debug_level=2 dtls=1 auth_mode=required" \
"$O_NEXT_CLI -dtls -mtu 2048 -cert $DATA_FILES_PATH/server5.crt -key $DATA_FILES_PATH/server5.key" \
0 \
-S "found fragmented DTLS handshake message" \
-S "error"
# Minimum possible MTU for OpenSSL server: 256 bytes.
# We expect the client Certificate handshake message to be fragmented and
# verify that this is the case. With OpenSSL 3.0.13, the ClientHello handshake
# message is 224 bytes and also fragmented. However, it may not hold across
# OpenSSL version updates. Therefore, we do not verify that the ClientHello is
# reassembled by the server.
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS reassembly: some fragmentation (openssl client)" \
"$P_SRV debug_level=2 dtls=1 auth_mode=required" \
"$O_NEXT_CLI -dtls -mtu 256 -cert $DATA_FILES_PATH/server5.crt -key $DATA_FILES_PATH/server5.key" \
0 \
-s "found fragmented DTLS handshake message" \
-s "Certificate handshake message has been buffered and reassembled" \
-S "error"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS reassembly: fragmentation, nbio (openssl client)" \
"$P_SRV debug_level=2 dtls=1 auth_mode=required nbio=2" \
"$O_NEXT_CLI -dtls -mtu 269 -cert $DATA_FILES_PATH/server5.crt -key $DATA_FILES_PATH/server5.key" \
0 \
-s "found fragmented DTLS handshake message" \
-s "Certificate handshake message has been buffered and reassembled" \
-S "error"
# Tests for sending fragmented handshake messages with DTLS
#
# Use client auth when we need the client to send large messages,
@@ -10242,20 +10320,20 @@ run_test "DTLS fragmenting: server (MTU)" \
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_max_content_len 2048
requires_max_content_len 1038
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS fragmenting: both (MTU=1024)" \
-p "$P_PXY mtu=1024" \
run_test "DTLS fragmenting: both (MTU=1038)" \
-p "$P_PXY mtu=1038" \
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
crt_file=$DATA_FILES_PATH/server7_int-ca.crt \
key_file=$DATA_FILES_PATH/server7.key \
hs_timeout=2500-60000 \
mtu=1024" \
mtu=1038" \
"$P_CLI dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server8_int-ca2.crt \
key_file=$DATA_FILES_PATH/server8.key \
hs_timeout=2500-60000 \
mtu=1024" \
mtu=1038" \
0 \
-s "found fragmented DTLS handshake message" \
-c "found fragmented DTLS handshake message" \
@@ -10265,25 +10343,108 @@ run_test "DTLS fragmenting: both (MTU=1024)" \
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_hash_alg SHA_256
requires_max_content_len 2048
run_test "DTLS fragmenting: both (MTU=512)" \
-p "$P_PXY mtu=512" \
requires_max_content_len 509
run_test "DTLS fragmenting: both (MTU=509)" \
-p "$P_PXY mtu=509" \
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
crt_file=$DATA_FILES_PATH/server7_int-ca.crt \
key_file=$DATA_FILES_PATH/server7.key \
hs_timeout=2500-60000 \
mtu=512" \
mtu=509" \
"$P_CLI dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server8_int-ca2.crt \
key_file=$DATA_FILES_PATH/server8.key \
force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
hs_timeout=2500-60000 \
mtu=512" \
mtu=509" \
0 \
-s "found fragmented DTLS handshake message" \
-c "found fragmented DTLS handshake message" \
-C "error"
# Depending on the ciphersuite selected to encrypt the application data, the
# maximum application data payload per record may be small with an MTU of 128.
# For example, with TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384, this maximum is
# 35 bytes. We therefore reduce the size of the client request and the server
# response in this test and the two following tests.
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_max_content_len 128
run_test "DTLS fragmenting: both (MTU=128)" \
-p "$P_PXY mtu=128" \
"$P_SRV dtls=1 debug_level=5 auth_mode=required \
crt_file=$DATA_FILES_PATH/server7_int-ca.crt \
key_file=$DATA_FILES_PATH/server7.key \
response_size=8 \
hs_timeout=2500-60000 \
mtu=128" \
"$P_CLI dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server8_int-ca2.crt \
key_file=$DATA_FILES_PATH/server8.key \
request_size=8 \
hs_timeout=2500-60000 \
mtu=128" \
0 \
-s "found fragmented DTLS handshake message" \
-s "fragmenting Certificate handshake message" \
-s "fragmenting ServerKeyExchange handshake message" \
-c "found fragmented DTLS handshake message" \
-c "fragmenting ClientHello handshake message" \
-c "fragmenting Certificate handshake message" \
-c "fragmenting CertificateVerify handshake message" \
-C "error"
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_max_content_len 2048
run_test "DTLS fragmenting: both (MTU=107)" \
-p "$P_PXY mtu=107" \
"$P_SRV dtls=1 debug_level=5 auth_mode=required \
crt_file=$DATA_FILES_PATH/server7_int-ca.crt \
key_file=$DATA_FILES_PATH/server7.key \
response_size=8 \
hs_timeout=2500-60000 \
mtu=107" \
"$P_CLI dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server8_int-ca2.crt \
key_file=$DATA_FILES_PATH/server8.key \
request_size=8 \
hs_timeout=2500-60000 \
mtu=107" \
0 \
-s "found fragmented DTLS handshake message" \
-s "fragmenting Certificate handshake message" \
-s "fragmenting ServerKeyExchange handshake message" \
-c "found fragmented DTLS handshake message" \
-c "fragmenting ClientHello handshake message" \
-c "fragmenting Certificate handshake message" \
-c "fragmenting CertificateVerify handshake message" \
-C "error"
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_max_content_len 2048
run_test "DTLS fragmenting: both (MTU=133)" \
-p "$P_PXY mtu=133" \
"$P_SRV dtls=1 debug_level=5 auth_mode=required \
crt_file=$DATA_FILES_PATH/server7_int-ca.crt \
key_file=$DATA_FILES_PATH/server7.key \
response_size=8 \
hs_timeout=2500-60000 \
mtu=133" \
"$P_CLI dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server8_int-ca2.crt \
key_file=$DATA_FILES_PATH/server8.key \
request_size=8 \
hs_timeout=2500-60000 \
mtu=133" \
0 \
-s "found fragmented DTLS handshake message" \
-s "fragmenting Certificate handshake message" \
-s "fragmenting ServerKeyExchange handshake message" \
-c "found fragmented DTLS handshake message" \
-c "fragmenting ClientHello handshake message" \
-c "fragmenting Certificate handshake message" \
-c "fragmenting CertificateVerify handshake message" \
-C "error"
# Test for automatic MTU reduction on repeated resend.
# Forcing ciphersuite for this test to fit the MTU of 508 with full config.
# The ratio of max/min timeout should ideally equal 4 to accept two
@@ -10337,7 +10498,7 @@ run_test "DTLS fragmenting: proxy MTU: auto-reduction (with valgrind)" \
not_with_valgrind # spurious autoreduction due to timeout
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_max_content_len 2048
requires_max_content_len 1024
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS fragmenting: proxy MTU, simple handshake (MTU=1024)" \
-p "$P_PXY mtu=1024" \
@@ -10364,7 +10525,7 @@ run_test "DTLS fragmenting: proxy MTU, simple handshake (MTU=1024)" \
not_with_valgrind # spurious autoreduction due to timeout
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_max_content_len 2048
requires_max_content_len 512
run_test "DTLS fragmenting: proxy MTU, simple handshake (MTU=512)" \
-p "$P_PXY mtu=512" \
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -10387,7 +10548,7 @@ run_test "DTLS fragmenting: proxy MTU, simple handshake (MTU=512)" \
not_with_valgrind # spurious autoreduction due to timeout
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_max_content_len 2048
requires_max_content_len 1024
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS fragmenting: proxy MTU, simple handshake, nbio (MTU=1024)" \
-p "$P_PXY mtu=1024" \
@@ -10411,7 +10572,7 @@ run_test "DTLS fragmenting: proxy MTU, simple handshake, nbio (MTU=1024)" \
not_with_valgrind # spurious autoreduction due to timeout
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_max_content_len 2048
requires_max_content_len 512
run_test "DTLS fragmenting: proxy MTU, simple handshake, nbio (MTU=512)" \
-p "$P_PXY mtu=512" \
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -10444,7 +10605,7 @@ run_test "DTLS fragmenting: proxy MTU, simple handshake, nbio (MTU=512)" \
not_with_valgrind # spurious autoreduction due to timeout
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_max_content_len 2048
requires_max_content_len 1450
run_test "DTLS fragmenting: proxy MTU, resumed handshake" \
-p "$P_PXY mtu=1450" \
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -10471,7 +10632,7 @@ requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_hash_alg SHA_256
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
requires_max_content_len 2048
requires_max_content_len 512
run_test "DTLS fragmenting: proxy MTU, ChachaPoly renego" \
-p "$P_PXY mtu=512" \
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -10500,7 +10661,7 @@ requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_hash_alg SHA_256
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
requires_max_content_len 2048
requires_max_content_len 512
run_test "DTLS fragmenting: proxy MTU, AES-GCM renego" \
-p "$P_PXY mtu=512" \
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -10529,7 +10690,7 @@ requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_hash_alg SHA_256
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
requires_max_content_len 2048
requires_max_content_len 1024
run_test "DTLS fragmenting: proxy MTU, AES-CCM renego" \
-p "$P_PXY mtu=1024" \
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -10559,7 +10720,7 @@ requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_hash_alg SHA_256
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
requires_config_enabled MBEDTLS_SSL_ENCRYPT_THEN_MAC
requires_max_content_len 2048
requires_max_content_len 1024
run_test "DTLS fragmenting: proxy MTU, AES-CBC EtM renego" \
-p "$P_PXY mtu=1024" \
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -10588,7 +10749,7 @@ requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_hash_alg SHA_256
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
requires_max_content_len 2048
requires_max_content_len 1024
run_test "DTLS fragmenting: proxy MTU, AES-CBC non-EtM renego" \
-p "$P_PXY mtu=1024" \
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -10614,7 +10775,7 @@ run_test "DTLS fragmenting: proxy MTU, AES-CBC non-EtM renego" \
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
client_needs_more_time 2
requires_max_content_len 2048
requires_max_content_len 512
run_test "DTLS fragmenting: proxy MTU + 3d" \
-p "$P_PXY mtu=512 drop=8 delay=8 duplicate=8" \
"$P_SRV dgram_packing=0 dtls=1 debug_level=2 auth_mode=required \
@@ -10635,7 +10796,7 @@ run_test "DTLS fragmenting: proxy MTU + 3d" \
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
client_needs_more_time 2
requires_max_content_len 2048
requires_max_content_len 512
run_test "DTLS fragmenting: proxy MTU + 3d, nbio" \
-p "$P_PXY mtu=512 drop=8 delay=8 duplicate=8" \
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
@@ -10660,16 +10821,32 @@ requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_gnutls
requires_max_content_len 2048
run_test "DTLS fragmenting: gnutls server, DTLS 1.2" \
run_test "DTLS fragmenting: MTU=501, gnutls server, DTLS 1.2" \
"$G_SRV -u" \
"$P_CLI dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server8_int-ca2.crt \
key_file=$DATA_FILES_PATH/server8.key \
mtu=512 force_version=dtls12" \
mtu=501 force_version=dtls12" \
0 \
-c "fragmenting Certificate handshake message" \
-C "error"
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_gnutls
requires_max_content_len 2048
run_test "DTLS fragmenting: MTU=110, gnutls server, DTLS 1.2" \
"$G_NEXT_SRV -u" \
"$P_CLI dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server8_int-ca2.crt \
key_file=$DATA_FILES_PATH/server8.key \
request_size=35 \
mtu=110 force_version=dtls12" \
0 \
-c "fragmenting ClientHello handshake message" \
-c "fragmenting Certificate handshake message" \
-C "error"
# We use --insecure for the GnuTLS client because it expects
# the hostname / IP it connects to to be the name used in the
# certificate obtained from the server. Here, however, it
@@ -10682,11 +10859,25 @@ requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_gnutls
requires_not_i686
requires_max_content_len 2048
run_test "DTLS fragmenting: gnutls client, DTLS 1.2" \
run_test "DTLS fragmenting: MTU=536, gnutls client, DTLS 1.2" \
"$P_SRV dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server7_int-ca.crt \
key_file=$DATA_FILES_PATH/server7.key \
mtu=512 force_version=dtls12" \
mtu=536 force_version=dtls12" \
"$G_CLI -u --insecure 127.0.0.1" \
0 \
-s "fragmenting Certificate handshake message"
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_gnutls
requires_not_i686
requires_max_content_len 2048
run_test "DTLS fragmenting: MTU=149, gnutls client, DTLS 1.2" \
"$P_SRV dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server7_int-ca.crt \
key_file=$DATA_FILES_PATH/server7.key \
mtu=149 force_version=dtls12" \
"$G_CLI -u --insecure 127.0.0.1" \
0 \
-s "fragmenting Certificate handshake message"
@@ -10694,20 +10885,39 @@ run_test "DTLS fragmenting: gnutls client, DTLS 1.2" \
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_max_content_len 2048
run_test "DTLS fragmenting: openssl server, DTLS 1.2" \
run_test "DTLS fragmenting: MTU=525, openssl server, DTLS 1.2" \
"$O_SRV -dtls1_2 -verify 10" \
"$P_CLI dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server8_int-ca2.crt \
key_file=$DATA_FILES_PATH/server8.key \
mtu=512 force_version=dtls12" \
mtu=525 force_version=dtls12" \
0 \
-c "fragmenting Certificate handshake message" \
-C "error"
# Depending on the ciphersuite selected to encrypt the application data, the
# maximum application data payload per record may be small with an MTU of 128.
# For example, with TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384, this maximum is
# 35 bytes. We therefore reduce the size of the client request in this test.
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_max_content_len 2048
run_test "DTLS fragmenting: MTU=130, openssl server, DTLS 1.2" \
"$O_NEXT_SRV -dtls1_2 -verify 10" \
"$P_CLI dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server8_int-ca2.crt \
key_file=$DATA_FILES_PATH/server8.key \
request_size=8 \
mtu=130 force_version=dtls12" \
0 \
-c "fragmenting ClientHello handshake message" \
-c "fragmenting Certificate handshake message" \
-C "error"
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_max_content_len 2048
run_test "DTLS fragmenting: openssl client, DTLS 1.2" \
run_test "DTLS fragmenting: MTU=512, openssl client, DTLS 1.2" \
"$P_SRV dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server7_int-ca.crt \
key_file=$DATA_FILES_PATH/server7.key \
@@ -10716,6 +10926,18 @@ run_test "DTLS fragmenting: openssl client, DTLS 1.2" \
0 \
-s "fragmenting Certificate handshake message"
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
requires_max_content_len 2048
run_test "DTLS fragmenting: MTU=131, openssl client, DTLS 1.2" \
"$P_SRV dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server7_int-ca.crt \
key_file=$DATA_FILES_PATH/server7.key \
mtu=131 force_version=dtls12" \
"$O_CLI -dtls1_2" \
0 \
-s "fragmenting Certificate handshake message"
# interop tests for DTLS fragmentating with unreliable connection
#
# again we just want to test that the we fragment in a way that
@@ -10725,28 +10947,61 @@ requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
client_needs_more_time 4
requires_max_content_len 2048
run_test "DTLS fragmenting: 3d, gnutls server, DTLS 1.2" \
run_test "DTLS fragmenting: 3d, MTU=434, gnutls server, DTLS 1.2" \
-p "$P_PXY drop=8 delay=8 duplicate=8" \
"$G_NEXT_SRV -u" \
"$P_CLI dgram_packing=0 dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server8_int-ca2.crt \
key_file=$DATA_FILES_PATH/server8.key \
hs_timeout=250-60000 mtu=512 force_version=dtls12" \
hs_timeout=250-60000 mtu=434 force_version=dtls12" \
0 \
-c "fragmenting Certificate handshake message" \
-C "error"
requires_gnutls_next
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
client_needs_more_time 6
requires_max_content_len 2048
run_test "DTLS fragmenting: 3d, MTU=103, gnutls server, DTLS 1.2" \
-p "$P_PXY drop=8 delay=8 duplicate=8" \
"$G_NEXT_SRV -u" \
"$P_CLI dgram_packing=0 dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server8_int-ca2.crt \
key_file=$DATA_FILES_PATH/server8.key \
request_size=35 \
hs_timeout=250-60000 mtu=103 force_version=dtls12" \
0 \
-c "fragmenting ClientHello handshake message" \
-c "fragmenting Certificate handshake message" \
-C "error"
requires_gnutls_next
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
client_needs_more_time 4
requires_max_content_len 2048
run_test "DTLS fragmenting: 3d, gnutls client, DTLS 1.2" \
run_test "DTLS fragmenting: 3d, MTU=614, gnutls client, DTLS 1.2" \
-p "$P_PXY drop=8 delay=8 duplicate=8" \
"$P_SRV dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server7_int-ca.crt \
key_file=$DATA_FILES_PATH/server7.key \
hs_timeout=250-60000 mtu=512 force_version=dtls12" \
hs_timeout=250-60000 mtu=614 force_version=dtls12" \
"$G_NEXT_CLI -u --insecure 127.0.0.1" \
0 \
-s "fragmenting Certificate handshake message"
requires_gnutls_next
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
client_needs_more_time 4
requires_max_content_len 2048
run_test "DTLS fragmenting: 3d, MTU=116, gnutls client, DTLS 1.2" \
-p "$P_PXY drop=8 delay=8 duplicate=8" \
"$P_SRV dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server7_int-ca.crt \
key_file=$DATA_FILES_PATH/server7.key \
hs_timeout=250-60000 mtu=116 force_version=dtls12" \
"$G_NEXT_CLI -u --insecure 127.0.0.1" \
0 \
-s "fragmenting Certificate handshake message"
@@ -10758,17 +11013,39 @@ requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
client_needs_more_time 4
requires_max_content_len 2048
run_test "DTLS fragmenting: 3d, openssl server, DTLS 1.2" \
run_test "DTLS fragmenting: 3d, MTU=541, openssl server, DTLS 1.2" \
-p "$P_PXY drop=8 delay=8 duplicate=8" \
"$O_NEXT_SRV -dtls1_2 -verify 10" \
"$P_CLI dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server8_int-ca2.crt \
key_file=$DATA_FILES_PATH/server8.key \
hs_timeout=250-60000 mtu=512 force_version=dtls12" \
hs_timeout=250-60000 mtu=541 force_version=dtls12" \
0 \
-c "fragmenting Certificate handshake message" \
-C "error"
# Depending on the ciphersuite selected to encrypt the application data, the
# maximum application data payload per record may be small with an MTU of 128.
# For example, with TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384, this maximum is
# 35 bytes. We therefore reduce the size of the client request in this test.
requires_openssl_next
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
client_needs_more_time 4
requires_max_content_len 2048
run_test "DTLS fragmenting: 3d, MTU=108, openssl server, DTLS 1.2" \
-p "$P_PXY drop=8 delay=8 duplicate=8" \
"$O_NEXT_SRV -dtls1_2 -verify 10" \
"$P_CLI dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server8_int-ca2.crt \
key_file=$DATA_FILES_PATH/server8.key \
request_size=8 \
hs_timeout=250-60000 mtu=108 force_version=dtls12" \
0 \
-c "fragmenting ClientHello handshake message" \
-c "fragmenting Certificate handshake message" \
-C "error"
## the test below will time out with certain seed.
## The cause is an openssl bug (https://github.com/openssl/openssl/issues/18887)
skip_next_test
@@ -10776,7 +11053,7 @@ requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
requires_config_enabled PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC
client_needs_more_time 4
requires_max_content_len 2048
run_test "DTLS fragmenting: 3d, openssl client, DTLS 1.2" \
run_test "DTLS fragmenting: 3d, MTU=512, openssl client, DTLS 1.2" \
-p "$P_PXY drop=8 delay=8 duplicate=8" \
"$P_SRV dtls=1 debug_level=2 \
crt_file=$DATA_FILES_PATH/server7_int-ca.crt \
@@ -11863,7 +12140,7 @@ not_with_valgrind # risk of non-mbedtls peer timing out
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS proxy: 3d, openssl server, fragmentation" \
-p "$P_PXY drop=5 delay=5 duplicate=5 protect_hvr=1" \
"$O_NEXT_SRV -dtls1_2 -mtu 256" \
"$O_NEXT_SRV -dtls1_2 -mtu 277" \
"$P_CLI dgram_packing=0 dtls=1 debug_level=2 hs_timeout=500-60000 tickets=0" \
0 \
-c "HTTP/1.0 200 OK" \
@@ -11875,12 +12152,49 @@ not_with_valgrind # risk of non-mbedtls peer timing out
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS proxy: 3d, openssl server, fragmentation, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5 protect_hvr=1" \
"$O_NEXT_SRV -dtls1_2 -mtu 256" \
"$O_NEXT_SRV -dtls1_2 -mtu 268" \
"$P_CLI dgram_packing=0 dtls=1 debug_level=2 hs_timeout=500-60000 nbio=2 tickets=0" \
0 \
-c "HTTP/1.0 200 OK" \
-c "Certificate handshake message has been buffered and reassembled"
requires_openssl_next
client_needs_more_time 6
not_with_valgrind # risk of non-mbedtls peer timing out
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS proxy: 3d, openssl client" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dgram_packing=0 dtls=1 hs_timeout=500-60000 tickets=0" \
"$O_NEXT_CLI -dtls1_2 -mtu 2048" \
0 \
-s "HTTP/1.0 200 OK"
requires_openssl_next
client_needs_more_time 8
not_with_valgrind # risk of non-mbedtls peer timing out
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS proxy: 3d, openssl client, fragmentation" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV debug_level=2 dgram_packing=0 auth_mode=required dtls=1 hs_timeout=500-60000 tickets=0" \
"$O_NEXT_CLI -dtls1_2 -mtu 260 -cert $DATA_FILES_PATH/server5.crt -key $DATA_FILES_PATH/server5.key" \
0 \
-s "HTTP/1.0 200 OK" \
-s "found fragmented DTLS handshake message" \
-s "Certificate handshake message has been buffered and reassembled"
requires_openssl_next
client_needs_more_time 8
not_with_valgrind # risk of non-mbedtls peer timing out
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS proxy: 3d, openssl client, fragmentation, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV debug_level=2 dgram_packing=0 auth_mode=required dtls=1 hs_timeout=500-60000 nbio=2 tickets=0" \
"$O_NEXT_CLI -dtls1_2 -mtu 259 -cert $DATA_FILES_PATH/server5.crt -key $DATA_FILES_PATH/server5.key" \
0 \
-s "HTTP/1.0 200 OK" \
-s "found fragmented DTLS handshake message" \
-s "Certificate handshake message has been buffered and reassembled"
requires_gnutls
client_needs_more_time 6
not_with_valgrind # risk of non-mbedtls peer timing out
@@ -11899,7 +12213,7 @@ not_with_valgrind # risk of non-mbedtls peer timing out
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS proxy: 3d, gnutls server, fragmentation" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$G_NEXT_SRV -u --mtu 512" \
"$G_NEXT_SRV -u --mtu 499" \
"$P_CLI dgram_packing=0 dtls=1 debug_level=2 hs_timeout=500-60000" \
0 \
-s "Extra-header:" \
@@ -11912,13 +12226,54 @@ not_with_valgrind # risk of non-mbedtls peer timing out
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS proxy: 3d, gnutls server, fragmentation, nbio" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$G_NEXT_SRV -u --mtu 512" \
"$G_NEXT_SRV -u --mtu 528" \
"$P_CLI dgram_packing=0 dtls=1 debug_level=2 hs_timeout=500-60000 nbio=2" \
0 \
-s "Extra-header:" \
-c "Extra-header:" \
-c "Certificate handshake message has been buffered and reassembled"
requires_gnutls
client_needs_more_time 6
not_with_valgrind # risk of non-mbedtls peer timing out
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS proxy: 3d, gnutls client" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dgram_packing=0 dtls=1" \
"$G_NEXT_CLI -u --mtu 2048 --insecure 127.0.0.1" \
0 \
-s "HTTP/1.0 200 OK"
# Set the MTU to 131 bytes. The ClientHello is not guaranteed to be surely
# fragmented but it is very likely. For example, the ClientHello sent by the
# GnuTLS 3.7.2 client is 206 bytes in this test. We expect ClientHello
# fragmentation to remain the case across GnuTLS version updates. Avoid using a
# smaller MTU, as the smaller the MTU, the more likely the handshake is to fail
# in this very unreliable connection emulation.
requires_gnutls
client_needs_more_time 8
not_with_valgrind # risk of non-mbedtls peer timing out
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS proxy: 3d, gnutls client, fragmentation" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dgram_packing=0 dtls=1 debug_level=2" \
"$G_NEXT_CLI -u --mtu 131 --insecure 127.0.0.1" \
0 \
-s "HTTP/1.0 200 OK" \
-s "ClientHello handshake message has been buffered and reassembled"
requires_gnutls
client_needs_more_time 8
not_with_valgrind # risk of non-mbedtls peer timing out
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "DTLS proxy: 3d, gnutls client, fragmentation, nbio=2" \
-p "$P_PXY drop=5 delay=5 duplicate=5" \
"$P_SRV dgram_packing=0 dtls=1 debug_level=2 nbio=2" \
"$G_NEXT_CLI -u --mtu 135 --insecure 127.0.0.1" \
0 \
-s "HTTP/1.0 200 OK" \
-s "ClientHello handshake message has been buffered and reassembled"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
run_test "export keys functionality" \
"$P_SRV eap_tls=1 debug_level=3" \
@@ -13826,7 +14181,6 @@ run_test "Handshake defragmentation on server: len=256, client-initiated rene
-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" \
@@ -13843,7 +14197,6 @@ run_test "Handshake defragmentation on server: len=128, client-initiated rene
-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" \
@@ -13860,7 +14213,6 @@ run_test "Handshake defragmentation on server: len=4, client-initiated renego
-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" \