From b422cab052b51ec84758638d6783d6ba4fc60613 Mon Sep 17 00:00:00 2001 From: Yanray Wang Date: Fri, 1 Dec 2023 16:18:10 +0800 Subject: [PATCH 001/123] tls: check RNG in ssl_conf_check when calling mbedtls_ssl_setup Signed-off-by: Yanray Wang --- library/ssl_tls.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 6678b7133a..28be8a6fba 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1355,6 +1355,11 @@ static int ssl_conf_check(const mbedtls_ssl_context *ssl) } #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ + if (ssl->conf->f_rng == NULL) { + MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided")); + return MBEDTLS_ERR_SSL_NO_RNG; + } + /* Space for further checks */ return 0; From f88e529de348c18467c84925298167fedde86844 Mon Sep 17 00:00:00 2001 From: Yanray Wang Date: Fri, 1 Dec 2023 16:39:34 +0800 Subject: [PATCH 002/123] ssl_helpers: make rng_get available for other test cases This is a pre-step to configure random number generator in some TLS tests. Signed-off-by: Yanray Wang --- tests/include/test/ssl_helpers.h | 4 ++++ tests/src/test_helpers/ssl_helpers.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/include/test/ssl_helpers.h b/tests/include/test/ssl_helpers.h index d03c62414b..b45e9695f7 100644 --- a/tests/include/test/ssl_helpers.h +++ b/tests/include/test/ssl_helpers.h @@ -193,6 +193,10 @@ typedef struct mbedtls_test_ssl_endpoint { #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ +#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) +int rng_get(void *p_rng, unsigned char *output, size_t output_len); +#endif + /* * This function can be passed to mbedtls to receive output logs from it. In * this case, it will count the instances of a mbedtls_test_ssl_log_pattern diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index d02d305394..549a4ffc66 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -14,7 +14,7 @@ #if defined(MBEDTLS_SSL_TLS_C) #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) static int rng_seed = 0xBEEF; -static int rng_get(void *p_rng, unsigned char *output, size_t output_len) +int rng_get(void *p_rng, unsigned char *output, size_t output_len) { (void) p_rng; for (size_t i = 0; i < output_len; i++) { From d6128e9ab94ded4879771cf9e6371ca041713cc5 Mon Sep 17 00:00:00 2001 From: Yanray Wang Date: Fri, 1 Dec 2023 17:08:56 +0800 Subject: [PATCH 003/123] test_suite_ssl.function: configure RNG to address test failure Signed-off-by: Yanray Wang --- tests/suites/test_suite_ssl.function | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 05571a1dc8..050e525a21 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -1121,6 +1121,8 @@ void ssl_dtls_replay(data_t *prevs, data_t *new, int ret) mbedtls_ssl_config_init(&conf); MD_OR_USE_PSA_INIT(); + mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + TEST_ASSERT(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_DATAGRAM, @@ -2892,6 +2894,7 @@ void conf_version(int endpoint, int transport, mbedtls_ssl_conf_transport(&conf, transport); mbedtls_ssl_conf_min_tls_version(&conf, min_tls_version); mbedtls_ssl_conf_max_tls_version(&conf, max_tls_version); + mbedtls_ssl_conf_rng(&conf, rng_get, NULL); TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == expected_ssl_setup_result); TEST_EQUAL(mbedtls_ssl_conf_get_endpoint( @@ -2933,6 +2936,8 @@ void conf_curve() mbedtls_ssl_init(&ssl); MD_OR_USE_PSA_INIT(); + mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0); TEST_ASSERT(ssl.handshake != NULL && ssl.handshake->group_list != NULL); @@ -2964,6 +2969,7 @@ void conf_group() mbedtls_ssl_config conf; mbedtls_ssl_config_init(&conf); + mbedtls_ssl_conf_rng(&conf, rng_get, NULL); mbedtls_ssl_conf_max_tls_version(&conf, MBEDTLS_SSL_VERSION_TLS1_2); mbedtls_ssl_conf_min_tls_version(&conf, MBEDTLS_SSL_VERSION_TLS1_2); @@ -3069,6 +3075,8 @@ void cookie_parsing(data_t *cookie, int exp_ret) mbedtls_ssl_config_init(&conf); USE_PSA_INIT(); + mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT), @@ -3122,6 +3130,8 @@ void cid_sanity() mbedtls_ssl_config_init(&conf); MD_OR_USE_PSA_INIT(); + mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + TEST_ASSERT(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, @@ -3380,6 +3390,8 @@ void ssl_ecjpake_set_password(int use_opaque_arg) mbedtls_ssl_config_init(&conf); + mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, From 5b60b424b7a7ecc366c3e8abf59a62d03cb7921a Mon Sep 17 00:00:00 2001 From: Yanray Wang Date: Fri, 1 Dec 2023 17:20:22 +0800 Subject: [PATCH 004/123] test_suite_debug.function: configure RNG to address test failure Signed-off-by: Yanray Wang --- tests/suites/test_suite_debug.function | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/suites/test_suite_debug.function b/tests/suites/test_suite_debug.function index b9610406bb..c96e305d4f 100644 --- a/tests/suites/test_suite_debug.function +++ b/tests/suites/test_suite_debug.function @@ -2,6 +2,7 @@ #include "mbedtls/debug.h" #include "string.h" #include "mbedtls/pk.h" +#include struct buffer_data { char buf[2000]; @@ -65,6 +66,8 @@ void debug_print_msg_threshold(int threshold, int level, char *file, memset(buffer.buf, 0, 2000); buffer.ptr = buffer.buf; + mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, @@ -103,6 +106,8 @@ void mbedtls_debug_print_ret(char *file, int line, char *text, int value, memset(buffer.buf, 0, 2000); buffer.ptr = buffer.buf; + mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, @@ -138,6 +143,8 @@ void mbedtls_debug_print_buf(char *file, int line, char *text, memset(buffer.buf, 0, 2000); buffer.ptr = buffer.buf; + mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, @@ -175,6 +182,8 @@ void mbedtls_debug_print_crt(char *crt_file, char *file, int line, memset(buffer.buf, 0, 2000); buffer.ptr = buffer.buf; + mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, @@ -214,6 +223,8 @@ void mbedtls_debug_print_mpi(char *value, char *file, int line, memset(buffer.buf, 0, 2000); buffer.ptr = buffer.buf; + mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, From c83186effa97dfb03c373a5fdce45337fe7ec633 Mon Sep 17 00:00:00 2001 From: Yanray Wang Date: Fri, 1 Dec 2023 17:24:48 +0800 Subject: [PATCH 005/123] ssl_client: remove RNG check in `write_client_hello` RNG check is added in ssl_conf_check when calling mbedtls_ssl_setup, so there is no need to check it again. Signed-off-by: Yanray Wang --- library/ssl_client.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/library/ssl_client.c b/library/ssl_client.c index 55fe352fe4..bef7fc0846 100644 --- a/library/ssl_client.c +++ b/library/ssl_client.c @@ -764,11 +764,6 @@ static int ssl_prepare_client_hello(mbedtls_ssl_context *ssl) MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_HAVE_TIME */ - if (ssl->conf->f_rng == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided")); - return MBEDTLS_ERR_SSL_NO_RNG; - } - /* Bet on the highest configured version if we are not in a TLS 1.2 * renegotiation or session resumption. */ From 197199f154e9c7fd45c2f7ab1815db6718830a2f Mon Sep 17 00:00:00 2001 From: Yanray Wang Date: Fri, 1 Dec 2023 17:28:56 +0800 Subject: [PATCH 006/123] tls12 & tls13 server: remove RNG check in `write_server_hello` RNG check is added in ssl_conf_check when calling mbedtls_ssl_setup, so there is no need to check it again. Signed-off-by: Yanray Wang --- library/ssl_tls12_server.c | 5 ----- library/ssl_tls13_server.c | 4 ---- 2 files changed, 9 deletions(-) diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index a07d0fb346..72564ac2fb 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -2177,11 +2177,6 @@ static int ssl_write_server_hello(mbedtls_ssl_context *ssl) } #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ - if (ssl->conf->f_rng == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided")); - return MBEDTLS_ERR_SSL_NO_RNG; - } - /* * 0 . 0 handshake type * 1 . 3 handshake length diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index d983a00395..25a182c4ac 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -1948,10 +1948,6 @@ static int ssl_tls13_prepare_server_hello(mbedtls_ssl_context *ssl) int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char *server_randbytes = ssl->handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN; - if (ssl->conf->f_rng == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided")); - return MBEDTLS_ERR_SSL_NO_RNG; - } if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, server_randbytes, MBEDTLS_SERVER_HELLO_RANDOM_LEN)) != 0) { From a72bc9adf7fb345af59f7137a5389ef0ace67030 Mon Sep 17 00:00:00 2001 From: Yanray Wang Date: Fri, 1 Dec 2023 23:34:27 +0800 Subject: [PATCH 007/123] ssl_helpers: remove guard for rng_get() After adding a check in ssl_conf_check(), we have configured RNG via mbedtls_ssl_conf_rng() for TLS tests in both test_suite_ssl.function and test_suite_debug.function. As a result, rng_get() is not only available when MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED enabled. Therefore, we remove the guard for rng_get() to make it accessible for TLS tests which have call for mbedtls_ssl_setup(). Signed-off-by: Yanray Wang --- tests/include/test/ssl_helpers.h | 2 -- tests/src/test_helpers/ssl_helpers.c | 5 ++--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/include/test/ssl_helpers.h b/tests/include/test/ssl_helpers.h index b45e9695f7..9493b69ca7 100644 --- a/tests/include/test/ssl_helpers.h +++ b/tests/include/test/ssl_helpers.h @@ -193,9 +193,7 @@ typedef struct mbedtls_test_ssl_endpoint { #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) int rng_get(void *p_rng, unsigned char *output, size_t output_len); -#endif /* * This function can be passed to mbedtls to receive output logs from it. In diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index 549a4ffc66..de76b09935 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -12,8 +12,6 @@ #include "md_psa.h" #if defined(MBEDTLS_SSL_TLS_C) -#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) -static int rng_seed = 0xBEEF; int rng_get(void *p_rng, unsigned char *output, size_t output_len) { (void) p_rng; @@ -23,7 +21,6 @@ int rng_get(void *p_rng, unsigned char *output, size_t output_len) return 0; } -#endif void mbedtls_test_ssl_log_analyzer(void *ctx, int level, const char *file, int line, @@ -46,6 +43,8 @@ void mbedtls_test_init_handshake_options( mbedtls_test_handshake_test_options *opts) { #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) + int rng_seed = 0xBEEF; + srand(rng_seed); rng_seed += 0xD0; #endif From aad9449146f67ead757a663d27971b1a0f494dcc Mon Sep 17 00:00:00 2001 From: Yanray Wang Date: Mon, 4 Dec 2023 10:42:06 +0800 Subject: [PATCH 008/123] test_suite_debug.function: check return value for _config_defaults Signed-off-by: Yanray Wang --- tests/suites/test_suite_debug.function | 45 ++++++++++++++------------ 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/tests/suites/test_suite_debug.function b/tests/suites/test_suite_debug.function index c96e305d4f..fca7ea0615 100644 --- a/tests/suites/test_suite_debug.function +++ b/tests/suites/test_suite_debug.function @@ -68,10 +68,11 @@ void debug_print_msg_threshold(int threshold, int level, char *file, mbedtls_ssl_conf_rng(&conf, rng_get, NULL); - mbedtls_ssl_config_defaults(&conf, - MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_SSL_TRANSPORT_STREAM, - MBEDTLS_SSL_PRESET_DEFAULT); + TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, + MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT), + 0); mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer); @@ -108,10 +109,11 @@ void mbedtls_debug_print_ret(char *file, int line, char *text, int value, mbedtls_ssl_conf_rng(&conf, rng_get, NULL); - mbedtls_ssl_config_defaults(&conf, - MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_SSL_TRANSPORT_STREAM, - MBEDTLS_SSL_PRESET_DEFAULT); + TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, + MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT), + 0); mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer); @@ -145,10 +147,11 @@ void mbedtls_debug_print_buf(char *file, int line, char *text, mbedtls_ssl_conf_rng(&conf, rng_get, NULL); - mbedtls_ssl_config_defaults(&conf, - MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_SSL_TRANSPORT_STREAM, - MBEDTLS_SSL_PRESET_DEFAULT); + TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, + MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT), + 0); mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer); @@ -184,10 +187,11 @@ void mbedtls_debug_print_crt(char *crt_file, char *file, int line, mbedtls_ssl_conf_rng(&conf, rng_get, NULL); - mbedtls_ssl_config_defaults(&conf, - MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_SSL_TRANSPORT_STREAM, - MBEDTLS_SSL_PRESET_DEFAULT); + TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, + MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT), + 0); mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer); @@ -225,10 +229,11 @@ void mbedtls_debug_print_mpi(char *value, char *file, int line, mbedtls_ssl_conf_rng(&conf, rng_get, NULL); - mbedtls_ssl_config_defaults(&conf, - MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_SSL_TRANSPORT_STREAM, - MBEDTLS_SSL_PRESET_DEFAULT); + TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, + MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT), + 0); mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer); From 3e2c61dca2cb27c54f33ab1591802d8961a97f59 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 4 Jan 2024 16:20:20 +0000 Subject: [PATCH 009/123] Create quiet wrappers for make and cmake Signed-off-by: Dave Rodgman --- tests/scripts/quiet/cmake | 44 +++++++++++++++++++++++++++++++++++++++ tests/scripts/quiet/make | 44 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100755 tests/scripts/quiet/cmake create mode 100755 tests/scripts/quiet/make diff --git a/tests/scripts/quiet/cmake b/tests/scripts/quiet/cmake new file mode 100755 index 0000000000..ea1474f877 --- /dev/null +++ b/tests/scripts/quiet/cmake @@ -0,0 +1,44 @@ +#! /usr/bin/env bash +# +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +# +# This swallows the output of the wrapped tool, unless there is an error. +# This helps reduce excess logging in the CI. + +# If you are debugging a build / CI issue, you can get complete unsilenced logs +# by un-commenting the following line (or setting VERBOSE_LOGS in your environment): +# VERBOSE_LOGS=1 + +# don't silence invocations containing these arguments +NO_SILENCE=" --version " + +TOOL=$(basename "$0") + +# Locate original tool +ORIGINAL_TOOL=$(type -ap ${TOOL} | grep -v "$0" | head -n1 ) + +if [[ " $@ " =~ $NO_SILENCE || -n "${VERBOSE_LOGS}" ]]; then + ${ORIGINAL_TOOL} "$@" + EXIT_STATUS=$? +else + # Display the command being invoked - if it succeeds, this is all that will + # be displayed. + echo "${TOOL} $@" + + # Run original command and capture output & exit status + TMPFILE=$(mktemp /tmp/quiet-${TOOL}.XXXXXX) + ${ORIGINAL_TOOL} "$@" > ${TMPFILE} 2>&1 + EXIT_STATUS=$? + + if [[ $EXIT_STATUS -ne 0 ]]; then + # On error, display the full output + cat ${TMPFILE} + fi + + # Remove tmpfile + rm ${TMPFILE} +fi + +# Propagate the exit status +exit $EXIT_STATUS diff --git a/tests/scripts/quiet/make b/tests/scripts/quiet/make new file mode 100755 index 0000000000..633758ae6f --- /dev/null +++ b/tests/scripts/quiet/make @@ -0,0 +1,44 @@ +#! /usr/bin/env bash +# +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +# +# This swallows the output of the wrapped tool, unless there is an error. +# This helps reduce excess logging in the CI. + +# If you are debugging a build / CI issue, you can get complete unsilenced logs +# by un-commenting the following line (or setting VERBOSE_LOGS in your environment): +# VERBOSE_LOGS=1 + +# don't silence invocations containing these arguments +NO_SILENCE=" --version | test " + +TOOL=$(basename "$0") + +# Locate original tool +ORIGINAL_TOOL=$(type -ap ${TOOL} | grep -v "$0" | head -n1 ) + +if [[ " $@ " =~ $NO_SILENCE || -n "${VERBOSE_LOGS}" ]]; then + ${ORIGINAL_TOOL} "$@" + EXIT_STATUS=$? +else + # Display the command being invoked - if it succeeds, this is all that will + # be displayed. + echo "${TOOL} $@" + + # Run original command and capture output & exit status + TMPFILE=$(mktemp /tmp/quiet-${TOOL}.XXXXXX) + ${ORIGINAL_TOOL} "$@" > ${TMPFILE} 2>&1 + EXIT_STATUS=$? + + if [[ $EXIT_STATUS -ne 0 ]]; then + # On error, display the full output + cat ${TMPFILE} + fi + + # Remove tmpfile + rm ${TMPFILE} +fi + +# Propagate the exit status +exit $EXIT_STATUS From ad4b70586353411a9853bfcbe2967e3e60fe39a6 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 16 Jan 2024 17:33:27 +0000 Subject: [PATCH 010/123] Use quiet make wrappers from all.sh Signed-off-by: Dave Rodgman --- tests/scripts/all.sh | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 44930d28b5..9274c7b1fe 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -131,6 +131,25 @@ pre_check_environment () { } pre_initialize_variables () { + special_options="--list-components|--list-all-components|-h|--help" + if [[ ! "$@" =~ $special_options ]]; then + # skip wrappers for "special options" which don't actually run any tests + + # Pick up "quiet" wrappers for make and cmake, which don't output very much + # unless there is an error. This reduces logging overhead in the CI. + # + # Note that the cmake wrapper breaks unless we use an absolute path here. + export PATH=${PWD}/tests/scripts/quiet:$PATH + if [[ ! -x ${PWD}/tests/scripts/quiet/make ]]; then + echo "can't find quiet/make" + exit 1 + fi + if [[ ! -x ${PWD}/tests/scripts/quiet/cmake ]]; then + echo "can't find quiet/cmake" + exit 1 + fi + fi + if in_mbedtls_repo; then CONFIG_H='include/mbedtls/mbedtls_config.h' else @@ -6246,7 +6265,7 @@ run_component () { # Preliminary setup pre_check_environment -pre_initialize_variables +pre_initialize_variables "$@" pre_parse_command_line "$@" pre_check_git From 5f8e2a2b5faca5790bc06aefc21ea0d50d9bbee2 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 16 Jan 2024 17:33:34 +0000 Subject: [PATCH 011/123] Spelling fix Signed-off-by: Dave Rodgman --- tests/scripts/all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 9274c7b1fe..1694ee954d 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -231,7 +231,7 @@ pre_initialize_variables () { # defined in this script whose name starts with "component_". ALL_COMPONENTS=$(compgen -A function component_ | sed 's/component_//') - # Delay determinig SUPPORTED_COMPONENTS until the command line options have a chance to override + # Delay determining SUPPORTED_COMPONENTS until the command line options have a chance to override # the commands set by the environment } From 5c745fa7dae42759d2e0d095d4a2edb21784de14 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 17 Jan 2024 09:59:10 +0000 Subject: [PATCH 012/123] Pacify check_files Signed-off-by: Dave Rodgman --- tests/scripts/check_files.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/scripts/check_files.py b/tests/scripts/check_files.py index 65fbc9f070..4483f55737 100755 --- a/tests/scripts/check_files.py +++ b/tests/scripts/check_files.py @@ -173,6 +173,8 @@ class ShebangIssueTracker(FileIssueTracker): b'sh': 'sh', } + path_exemptions = re.compile(r'tests/scripts/quiet/.*') + def is_valid_shebang(self, first_line, filepath): m = re.match(self._shebang_re, first_line) if not m: From 0fa6b362574ac657de16443d70d0a638106f6ef1 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 15 Feb 2024 12:27:03 +0000 Subject: [PATCH 013/123] Always display make/cmake invocation command Signed-off-by: Dave Rodgman --- tests/scripts/quiet/cmake | 14 ++++++++++---- tests/scripts/quiet/make | 14 ++++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/tests/scripts/quiet/cmake b/tests/scripts/quiet/cmake index ea1474f877..2e95c6b938 100755 --- a/tests/scripts/quiet/cmake +++ b/tests/scripts/quiet/cmake @@ -18,14 +18,20 @@ TOOL=$(basename "$0") # Locate original tool ORIGINAL_TOOL=$(type -ap ${TOOL} | grep -v "$0" | head -n1 ) +if [[ ! " $@ " =~ " --version " ]]; then + # Display the command being invoked - if it succeeds, this is all that will + # be displayed. Don't do this for invocations with --version, because + # this output is often parsed by scripts, so we don't want to modify it. + echo -n "${TOOL} " + printf '%q ' "$@" + echo +fi + if [[ " $@ " =~ $NO_SILENCE || -n "${VERBOSE_LOGS}" ]]; then + # Run original command with no output supression ${ORIGINAL_TOOL} "$@" EXIT_STATUS=$? else - # Display the command being invoked - if it succeeds, this is all that will - # be displayed. - echo "${TOOL} $@" - # Run original command and capture output & exit status TMPFILE=$(mktemp /tmp/quiet-${TOOL}.XXXXXX) ${ORIGINAL_TOOL} "$@" > ${TMPFILE} 2>&1 diff --git a/tests/scripts/quiet/make b/tests/scripts/quiet/make index 633758ae6f..0c4869644e 100755 --- a/tests/scripts/quiet/make +++ b/tests/scripts/quiet/make @@ -18,14 +18,20 @@ TOOL=$(basename "$0") # Locate original tool ORIGINAL_TOOL=$(type -ap ${TOOL} | grep -v "$0" | head -n1 ) +if [[ ! " $@ " =~ " --version " ]]; then + # Display the command being invoked - if it succeeds, this is all that will + # be displayed. Don't do this for invocations with --version, because + # this output is often parsed by scripts, so we don't want to modify it. + echo -n "${TOOL} " + printf '%q ' "$@" + echo +fi + if [[ " $@ " =~ $NO_SILENCE || -n "${VERBOSE_LOGS}" ]]; then + # Run original command with no output supression ${ORIGINAL_TOOL} "$@" EXIT_STATUS=$? else - # Display the command being invoked - if it succeeds, this is all that will - # be displayed. - echo "${TOOL} $@" - # Run original command and capture output & exit status TMPFILE=$(mktemp /tmp/quiet-${TOOL}.XXXXXX) ${ORIGINAL_TOOL} "$@" > ${TMPFILE} 2>&1 From 90dbba5385f7e0eafa23648fd7aed2de9b524c4f Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 15 Feb 2024 14:39:48 +0000 Subject: [PATCH 014/123] Improve output from make/cmake wrapper Signed-off-by: Dave Rodgman --- tests/scripts/quiet/cmake | 25 ++++++++++++++++++++++--- tests/scripts/quiet/make | 25 ++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/tests/scripts/quiet/cmake b/tests/scripts/quiet/cmake index 2e95c6b938..e3114a86fc 100755 --- a/tests/scripts/quiet/cmake +++ b/tests/scripts/quiet/cmake @@ -18,13 +18,32 @@ TOOL=$(basename "$0") # Locate original tool ORIGINAL_TOOL=$(type -ap ${TOOL} | grep -v "$0" | head -n1 ) +quote_args() { + # similar to printf '%q' "$@" + # but produce more human-readable results for common/simple cases like "a b" + local args=("$@") + s="" + for a in "${args[@]}"; do + simple_pattern='^[[:alnum:] _=+-]*$' + if [[ $a =~ ' ' && $a =~ $simple_pattern ]]; then + # a has spaces, but no other special characters that need escaping + # (quoting after removing spaces yields no backslashes) + # simplify quoted form to "$a" - e.g. yield "a b c" instead of a\ b\ c + q="\"$a\"" + else + # get bash to do the quoting + q=$(printf '%q' "$a") + fi + s="$s $q" + done + echo $s +} + if [[ ! " $@ " =~ " --version " ]]; then # Display the command being invoked - if it succeeds, this is all that will # be displayed. Don't do this for invocations with --version, because # this output is often parsed by scripts, so we don't want to modify it. - echo -n "${TOOL} " - printf '%q ' "$@" - echo + echo "${TOOL} $(quote_args "$@")" fi if [[ " $@ " =~ $NO_SILENCE || -n "${VERBOSE_LOGS}" ]]; then diff --git a/tests/scripts/quiet/make b/tests/scripts/quiet/make index 0c4869644e..257703ec93 100755 --- a/tests/scripts/quiet/make +++ b/tests/scripts/quiet/make @@ -18,13 +18,32 @@ TOOL=$(basename "$0") # Locate original tool ORIGINAL_TOOL=$(type -ap ${TOOL} | grep -v "$0" | head -n1 ) +quote_args() { + # similar to printf '%q' "$@" + # but produce more human-readable results for common/simple cases like "a b" + local args=("$@") + s="" + for a in "${args[@]}"; do + simple_pattern='^[[:alnum:] _=+-]*$' + if [[ $a =~ ' ' && $a =~ $simple_pattern ]]; then + # a has spaces, but no other special characters that need escaping + # (quoting after removing spaces yields no backslashes) + # simplify quoted form to "$a" - e.g. yield "a b c" instead of a\ b\ c + q="\"$a\"" + else + # get bash to do the quoting + q=$(printf '%q' "$a") + fi + s="$s $q" + done + echo $s +} + if [[ ! " $@ " =~ " --version " ]]; then # Display the command being invoked - if it succeeds, this is all that will # be displayed. Don't do this for invocations with --version, because # this output is often parsed by scripts, so we don't want to modify it. - echo -n "${TOOL} " - printf '%q ' "$@" - echo + echo "${TOOL} $(quote_args "$@")" fi if [[ " $@ " =~ $NO_SILENCE || -n "${VERBOSE_LOGS}" ]]; then From 1110698ed9b59bf3ff3e0c5da3c189262f626b37 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 15 Feb 2024 16:04:36 +0000 Subject: [PATCH 015/123] Improve quote_args output readability Signed-off-by: Dave Rodgman --- tests/scripts/quiet/cmake | 8 +++++--- tests/scripts/quiet/make | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/scripts/quiet/cmake b/tests/scripts/quiet/cmake index e3114a86fc..a79d7578bf 100755 --- a/tests/scripts/quiet/cmake +++ b/tests/scripts/quiet/cmake @@ -24,12 +24,14 @@ quote_args() { local args=("$@") s="" for a in "${args[@]}"; do - simple_pattern='^[[:alnum:] _=+-]*$' + simple_pattern='^([[:alnum:]_+-]+=)?([[:alnum:] _=+-]*)$' if [[ $a =~ ' ' && $a =~ $simple_pattern ]]; then # a has spaces, but no other special characters that need escaping # (quoting after removing spaces yields no backslashes) - # simplify quoted form to "$a" - e.g. yield "a b c" instead of a\ b\ c - q="\"$a\"" + # simplify quoted form - e.g.: + # a b -> "a b" + # CFLAGS=a b -> CFLAGS="a b" + q="${BASH_REMATCH[1]}\"${BASH_REMATCH[2]}\"" else # get bash to do the quoting q=$(printf '%q' "$a") diff --git a/tests/scripts/quiet/make b/tests/scripts/quiet/make index 257703ec93..9722029083 100755 --- a/tests/scripts/quiet/make +++ b/tests/scripts/quiet/make @@ -24,12 +24,14 @@ quote_args() { local args=("$@") s="" for a in "${args[@]}"; do - simple_pattern='^[[:alnum:] _=+-]*$' + simple_pattern='^([[:alnum:]_+-]+=)?([[:alnum:] _=+-]*)$' if [[ $a =~ ' ' && $a =~ $simple_pattern ]]; then # a has spaces, but no other special characters that need escaping # (quoting after removing spaces yields no backslashes) - # simplify quoted form to "$a" - e.g. yield "a b c" instead of a\ b\ c - q="\"$a\"" + # simplify quoted form - e.g.: + # a b -> "a b" + # CFLAGS=a b -> CFLAGS="a b" + q="${BASH_REMATCH[1]}\"${BASH_REMATCH[2]}\"" else # get bash to do the quoting q=$(printf '%q' "$a") From 219006329da09f0c0821a34935953efc4d397c8f Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 26 Feb 2024 11:41:19 +0000 Subject: [PATCH 016/123] Move quiet wrapper setup Signed-off-by: Dave Rodgman --- tests/scripts/all.sh | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 1694ee954d..54917d32e6 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -131,25 +131,6 @@ pre_check_environment () { } pre_initialize_variables () { - special_options="--list-components|--list-all-components|-h|--help" - if [[ ! "$@" =~ $special_options ]]; then - # skip wrappers for "special options" which don't actually run any tests - - # Pick up "quiet" wrappers for make and cmake, which don't output very much - # unless there is an error. This reduces logging overhead in the CI. - # - # Note that the cmake wrapper breaks unless we use an absolute path here. - export PATH=${PWD}/tests/scripts/quiet:$PATH - if [[ ! -x ${PWD}/tests/scripts/quiet/make ]]; then - echo "can't find quiet/make" - exit 1 - fi - if [[ ! -x ${PWD}/tests/scripts/quiet/cmake ]]; then - echo "can't find quiet/cmake" - exit 1 - fi - fi - if in_mbedtls_repo; then CONFIG_H='include/mbedtls/mbedtls_config.h' else @@ -235,6 +216,23 @@ pre_initialize_variables () { # the commands set by the environment } +setup_quiet_wrappers() +{ + # Pick up "quiet" wrappers for make and cmake, which don't output very much + # unless there is an error. This reduces logging overhead in the CI. + # + # Note that the cmake wrapper breaks unless we use an absolute path here. + export PATH=${PWD}/tests/scripts/quiet:$PATH + if [[ ! -x ${PWD}/tests/scripts/quiet/make ]]; then + echo "can't find quiet/make" + exit 1 + fi + if [[ ! -x ${PWD}/tests/scripts/quiet/cmake ]]; then + echo "can't find quiet/cmake" + exit 1 + fi +} + # Test whether the component $1 is included in the command line patterns. is_component_included() { @@ -6268,6 +6266,7 @@ pre_check_environment pre_initialize_variables "$@" pre_parse_command_line "$@" +setup_quiet_wrappers pre_check_git pre_restore_files pre_back_up From 00bc790d79eb2d8ef3f0e1e2d3a67cfb1b8547c7 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 26 Feb 2024 11:43:11 +0000 Subject: [PATCH 017/123] Tidy up quiet wrappers Signed-off-by: Dave Rodgman --- tests/scripts/quiet/cmake | 39 ++++++++++++++++++------------------- tests/scripts/quiet/make | 41 +++++++++++++++++++-------------------- 2 files changed, 39 insertions(+), 41 deletions(-) diff --git a/tests/scripts/quiet/cmake b/tests/scripts/quiet/cmake index a79d7578bf..4804637f8e 100755 --- a/tests/scripts/quiet/cmake +++ b/tests/scripts/quiet/cmake @@ -16,15 +16,13 @@ NO_SILENCE=" --version " TOOL=$(basename "$0") # Locate original tool -ORIGINAL_TOOL=$(type -ap ${TOOL} | grep -v "$0" | head -n1 ) +ORIGINAL_TOOL=$(type -ap "${TOOL}" | grep -v -Fx "$0" | head -n1 ) -quote_args() { +print_quoted_args() { # similar to printf '%q' "$@" # but produce more human-readable results for common/simple cases like "a b" - local args=("$@") - s="" - for a in "${args[@]}"; do - simple_pattern='^([[:alnum:]_+-]+=)?([[:alnum:] _=+-]*)$' + for a in "$@"; do + simple_pattern='^([[:alnum:]_+-]+=)?([[:alnum:] _=+-./:@]*)$' if [[ $a =~ ' ' && $a =~ $simple_pattern ]]; then # a has spaces, but no other special characters that need escaping # (quoting after removing spaces yields no backslashes) @@ -33,39 +31,40 @@ quote_args() { # CFLAGS=a b -> CFLAGS="a b" q="${BASH_REMATCH[1]}\"${BASH_REMATCH[2]}\"" else - # get bash to do the quoting + # get bash to do the quoting (which may result in no quotes or escaping, + # if none is needed). q=$(printf '%q' "$a") fi - s="$s $q" + printf "%s " "$q" done - echo $s } -if [[ ! " $@ " =~ " --version " ]]; then +if [[ ! " $* " =~ " --version " ]]; then # Display the command being invoked - if it succeeds, this is all that will # be displayed. Don't do this for invocations with --version, because # this output is often parsed by scripts, so we don't want to modify it. - echo "${TOOL} $(quote_args "$@")" + printf %s "${TOOL} " + print_quoted_args "$@" + echo fi if [[ " $@ " =~ $NO_SILENCE || -n "${VERBOSE_LOGS}" ]]; then # Run original command with no output supression - ${ORIGINAL_TOOL} "$@" - EXIT_STATUS=$? + exec "${ORIGINAL_TOOL}" "$@" else # Run original command and capture output & exit status - TMPFILE=$(mktemp /tmp/quiet-${TOOL}.XXXXXX) - ${ORIGINAL_TOOL} "$@" > ${TMPFILE} 2>&1 + TMPFILE=$(mktemp "quiet-${TOOL}.XXXXXX") + "${ORIGINAL_TOOL}" "$@" > "${TMPFILE}" 2>&1 EXIT_STATUS=$? if [[ $EXIT_STATUS -ne 0 ]]; then # On error, display the full output - cat ${TMPFILE} + cat "${TMPFILE}" fi # Remove tmpfile - rm ${TMPFILE} -fi + rm "${TMPFILE}" -# Propagate the exit status -exit $EXIT_STATUS + # Propagate the exit status + exit $EXIT_STATUS +fi diff --git a/tests/scripts/quiet/make b/tests/scripts/quiet/make index 9722029083..3eae91c4f0 100755 --- a/tests/scripts/quiet/make +++ b/tests/scripts/quiet/make @@ -11,20 +11,18 @@ # VERBOSE_LOGS=1 # don't silence invocations containing these arguments -NO_SILENCE=" --version | test " +NO_SILENCE=" --version | test" TOOL=$(basename "$0") # Locate original tool -ORIGINAL_TOOL=$(type -ap ${TOOL} | grep -v "$0" | head -n1 ) +ORIGINAL_TOOL=$(type -ap "${TOOL}" | grep -v -Fx "$0" | head -n1 ) -quote_args() { +print_quoted_args() { # similar to printf '%q' "$@" # but produce more human-readable results for common/simple cases like "a b" - local args=("$@") - s="" - for a in "${args[@]}"; do - simple_pattern='^([[:alnum:]_+-]+=)?([[:alnum:] _=+-]*)$' + for a in "$@"; do + simple_pattern='^([[:alnum:]_+-]+=)?([[:alnum:] _=+-./:@]*)$' if [[ $a =~ ' ' && $a =~ $simple_pattern ]]; then # a has spaces, but no other special characters that need escaping # (quoting after removing spaces yields no backslashes) @@ -33,39 +31,40 @@ quote_args() { # CFLAGS=a b -> CFLAGS="a b" q="${BASH_REMATCH[1]}\"${BASH_REMATCH[2]}\"" else - # get bash to do the quoting + # get bash to do the quoting (which may result in no quotes or escaping, + # if none is needed). q=$(printf '%q' "$a") fi - s="$s $q" + printf "%s " "$q" done - echo $s } -if [[ ! " $@ " =~ " --version " ]]; then +if [[ ! " $* " =~ " --version " ]]; then # Display the command being invoked - if it succeeds, this is all that will # be displayed. Don't do this for invocations with --version, because # this output is often parsed by scripts, so we don't want to modify it. - echo "${TOOL} $(quote_args "$@")" + printf %s "${TOOL} " + print_quoted_args "$@" + echo fi if [[ " $@ " =~ $NO_SILENCE || -n "${VERBOSE_LOGS}" ]]; then # Run original command with no output supression - ${ORIGINAL_TOOL} "$@" - EXIT_STATUS=$? + exec "${ORIGINAL_TOOL}" "$@" else # Run original command and capture output & exit status - TMPFILE=$(mktemp /tmp/quiet-${TOOL}.XXXXXX) - ${ORIGINAL_TOOL} "$@" > ${TMPFILE} 2>&1 + TMPFILE=$(mktemp "quiet-${TOOL}.XXXXXX") + "${ORIGINAL_TOOL}" "$@" > "${TMPFILE}" 2>&1 EXIT_STATUS=$? if [[ $EXIT_STATUS -ne 0 ]]; then # On error, display the full output - cat ${TMPFILE} + cat "${TMPFILE}" fi # Remove tmpfile - rm ${TMPFILE} -fi + rm "${TMPFILE}" -# Propagate the exit status -exit $EXIT_STATUS + # Propagate the exit status + exit $EXIT_STATUS +fi From 98a79cdb238ee6b1b83167b2ce8aba9b6ffd13dd Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 26 Feb 2024 12:37:44 +0000 Subject: [PATCH 018/123] Extract common parts of quiet wrapper Signed-off-by: Dave Rodgman --- tests/scripts/quiet/cmake | 58 ++-------------------------------- tests/scripts/quiet/make | 58 ++-------------------------------- tests/scripts/quiet/quiet | 65 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 110 deletions(-) create mode 100755 tests/scripts/quiet/quiet diff --git a/tests/scripts/quiet/cmake b/tests/scripts/quiet/cmake index 4804637f8e..10a0b25f43 100755 --- a/tests/scripts/quiet/cmake +++ b/tests/scripts/quiet/cmake @@ -11,60 +11,8 @@ # VERBOSE_LOGS=1 # don't silence invocations containing these arguments -NO_SILENCE=" --version " +export NO_SILENCE=" --version " -TOOL=$(basename "$0") +export TOOL="cmake" -# Locate original tool -ORIGINAL_TOOL=$(type -ap "${TOOL}" | grep -v -Fx "$0" | head -n1 ) - -print_quoted_args() { - # similar to printf '%q' "$@" - # but produce more human-readable results for common/simple cases like "a b" - for a in "$@"; do - simple_pattern='^([[:alnum:]_+-]+=)?([[:alnum:] _=+-./:@]*)$' - if [[ $a =~ ' ' && $a =~ $simple_pattern ]]; then - # a has spaces, but no other special characters that need escaping - # (quoting after removing spaces yields no backslashes) - # simplify quoted form - e.g.: - # a b -> "a b" - # CFLAGS=a b -> CFLAGS="a b" - q="${BASH_REMATCH[1]}\"${BASH_REMATCH[2]}\"" - else - # get bash to do the quoting (which may result in no quotes or escaping, - # if none is needed). - q=$(printf '%q' "$a") - fi - printf "%s " "$q" - done -} - -if [[ ! " $* " =~ " --version " ]]; then - # Display the command being invoked - if it succeeds, this is all that will - # be displayed. Don't do this for invocations with --version, because - # this output is often parsed by scripts, so we don't want to modify it. - printf %s "${TOOL} " - print_quoted_args "$@" - echo -fi - -if [[ " $@ " =~ $NO_SILENCE || -n "${VERBOSE_LOGS}" ]]; then - # Run original command with no output supression - exec "${ORIGINAL_TOOL}" "$@" -else - # Run original command and capture output & exit status - TMPFILE=$(mktemp "quiet-${TOOL}.XXXXXX") - "${ORIGINAL_TOOL}" "$@" > "${TMPFILE}" 2>&1 - EXIT_STATUS=$? - - if [[ $EXIT_STATUS -ne 0 ]]; then - # On error, display the full output - cat "${TMPFILE}" - fi - - # Remove tmpfile - rm "${TMPFILE}" - - # Propagate the exit status - exit $EXIT_STATUS -fi +exec $(dirname "$0")/quiet "$@" diff --git a/tests/scripts/quiet/make b/tests/scripts/quiet/make index 3eae91c4f0..a1ef3e565d 100755 --- a/tests/scripts/quiet/make +++ b/tests/scripts/quiet/make @@ -11,60 +11,8 @@ # VERBOSE_LOGS=1 # don't silence invocations containing these arguments -NO_SILENCE=" --version | test" +export NO_SILENCE=" --version | test " -TOOL=$(basename "$0") +export TOOL="make" -# Locate original tool -ORIGINAL_TOOL=$(type -ap "${TOOL}" | grep -v -Fx "$0" | head -n1 ) - -print_quoted_args() { - # similar to printf '%q' "$@" - # but produce more human-readable results for common/simple cases like "a b" - for a in "$@"; do - simple_pattern='^([[:alnum:]_+-]+=)?([[:alnum:] _=+-./:@]*)$' - if [[ $a =~ ' ' && $a =~ $simple_pattern ]]; then - # a has spaces, but no other special characters that need escaping - # (quoting after removing spaces yields no backslashes) - # simplify quoted form - e.g.: - # a b -> "a b" - # CFLAGS=a b -> CFLAGS="a b" - q="${BASH_REMATCH[1]}\"${BASH_REMATCH[2]}\"" - else - # get bash to do the quoting (which may result in no quotes or escaping, - # if none is needed). - q=$(printf '%q' "$a") - fi - printf "%s " "$q" - done -} - -if [[ ! " $* " =~ " --version " ]]; then - # Display the command being invoked - if it succeeds, this is all that will - # be displayed. Don't do this for invocations with --version, because - # this output is often parsed by scripts, so we don't want to modify it. - printf %s "${TOOL} " - print_quoted_args "$@" - echo -fi - -if [[ " $@ " =~ $NO_SILENCE || -n "${VERBOSE_LOGS}" ]]; then - # Run original command with no output supression - exec "${ORIGINAL_TOOL}" "$@" -else - # Run original command and capture output & exit status - TMPFILE=$(mktemp "quiet-${TOOL}.XXXXXX") - "${ORIGINAL_TOOL}" "$@" > "${TMPFILE}" 2>&1 - EXIT_STATUS=$? - - if [[ $EXIT_STATUS -ne 0 ]]; then - # On error, display the full output - cat "${TMPFILE}" - fi - - # Remove tmpfile - rm "${TMPFILE}" - - # Propagate the exit status - exit $EXIT_STATUS -fi +exec $(dirname "$0")/quiet "$@" diff --git a/tests/scripts/quiet/quiet b/tests/scripts/quiet/quiet new file mode 100755 index 0000000000..2279e6a717 --- /dev/null +++ b/tests/scripts/quiet/quiet @@ -0,0 +1,65 @@ +#! /usr/bin/env bash +# +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +# +# This swallows the output of the wrapped tool, unless there is an error. +# This helps reduce excess logging in the CI. + +# If you are debugging a build / CI issue, you can get complete unsilenced logs +# by un-commenting the following line (or setting VERBOSE_LOGS in your environment): +# VERBOSE_LOGS=1 + +# Locate original tool +ORIGINAL_TOOL=$(type -ap "${TOOL}" | grep -v -Fx "$0" | head -n1) + +print_quoted_args() { + # similar to printf '%q' "$@" + # but produce more human-readable results for common/simple cases like "a b" + for a in "$@"; do + simple_pattern='^([[:alnum:]_+-]+=)?([[:alnum:] _=+-./:@]*)$' + if [[ $a =~ ' ' && $a =~ $simple_pattern ]]; then + # a has spaces, but no other special characters that need escaping + # (quoting after removing spaces yields no backslashes) + # simplify quoted form - e.g.: + # a b -> "a b" + # CFLAGS=a b -> CFLAGS="a b" + q="${BASH_REMATCH[1]}\"${BASH_REMATCH[2]}\"" + else + # get bash to do the quoting (which may result in no quotes or escaping, + # if none is needed). + q=$(printf '%q' "$a") + fi + printf "%s " "$q" + done +} + +if [[ ! " $* " =~ " --version " ]]; then + # Display the command being invoked - if it succeeds, this is all that will + # be displayed. Don't do this for invocations with --version, because + # this output is often parsed by scripts, so we don't want to modify it. + printf %s "${TOOL} " + print_quoted_args "$@" + echo +fi + +if [[ " $@ " =~ $NO_SILENCE || -n "${VERBOSE_LOGS}" ]]; then + # Run original command with no output supression + exec "${ORIGINAL_TOOL}" "$@" +else + # Run original command and capture output & exit status + TMPFILE=$(mktemp "quiet-${TOOL}.XXXXXX") + "${ORIGINAL_TOOL}" "$@" > "${TMPFILE}" 2>&1 + EXIT_STATUS=$? + + if [[ $EXIT_STATUS -ne 0 ]]; then + # On error, display the full output + cat "${TMPFILE}" + fi + + # Remove tmpfile + rm "${TMPFILE}" + + # Propagate the exit status + exit $EXIT_STATUS +fi From e03088b29eab0ba6cd0c40fb19ef5fd5904730e6 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 26 Feb 2024 12:48:49 +0000 Subject: [PATCH 019/123] Avoid infinite loop Signed-off-by: Dave Rodgman --- tests/scripts/quiet/quiet | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/scripts/quiet/quiet b/tests/scripts/quiet/quiet index 2279e6a717..bbc685cd8b 100755 --- a/tests/scripts/quiet/quiet +++ b/tests/scripts/quiet/quiet @@ -11,7 +11,8 @@ # VERBOSE_LOGS=1 # Locate original tool -ORIGINAL_TOOL=$(type -ap "${TOOL}" | grep -v -Fx "$0" | head -n1) +TOOL_WITH_PATH=$(dirname "$0")/$TOOL +ORIGINAL_TOOL=$(type -ap "${TOOL}" | grep -v -Fx "$TOOL_WITH_PATH" | head -n1) print_quoted_args() { # similar to printf '%q' "$@" From a9e8dbed14d487503d74cceb39df4e5f92ad06b7 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 26 Feb 2024 17:27:18 +0000 Subject: [PATCH 020/123] Allow wrappers to be missing; quote directory name from make Co-authored-by: Gilles Peskine Signed-off-by: Dave Rodgman --- tests/scripts/all.sh | 10 ++-------- tests/scripts/quiet/make | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 54917d32e6..a8a704c080 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -222,14 +222,8 @@ setup_quiet_wrappers() # unless there is an error. This reduces logging overhead in the CI. # # Note that the cmake wrapper breaks unless we use an absolute path here. - export PATH=${PWD}/tests/scripts/quiet:$PATH - if [[ ! -x ${PWD}/tests/scripts/quiet/make ]]; then - echo "can't find quiet/make" - exit 1 - fi - if [[ ! -x ${PWD}/tests/scripts/quiet/cmake ]]; then - echo "can't find quiet/cmake" - exit 1 + if [[ -e ${PWD}/tests/scripts/quiet ]]; then + export PATH=${PWD}/tests/scripts/quiet:$PATH fi } diff --git a/tests/scripts/quiet/make b/tests/scripts/quiet/make index a1ef3e565d..162d44de6c 100755 --- a/tests/scripts/quiet/make +++ b/tests/scripts/quiet/make @@ -15,4 +15,4 @@ export NO_SILENCE=" --version | test " export TOOL="make" -exec $(dirname "$0")/quiet "$@" +exec "$(dirname "$0")/quiet" "$@" From 30483dccc0df41bacb3ed38c682614666903fd95 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 26 Feb 2024 17:28:13 +0000 Subject: [PATCH 021/123] Undo not-needed change Signed-off-by: Dave Rodgman --- tests/scripts/all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index a8a704c080..ec201ce3c2 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -6257,7 +6257,7 @@ run_component () { # Preliminary setup pre_check_environment -pre_initialize_variables "$@" +pre_initialize_variables pre_parse_command_line "$@" setup_quiet_wrappers From c7f05490bb804569b43aca1bbafa2596b49a42ae Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 26 Feb 2024 17:28:42 +0000 Subject: [PATCH 022/123] Quote directory name from cmake wrapper Signed-off-by: Dave Rodgman --- tests/scripts/quiet/cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/quiet/cmake b/tests/scripts/quiet/cmake index 10a0b25f43..3723473f53 100755 --- a/tests/scripts/quiet/cmake +++ b/tests/scripts/quiet/cmake @@ -15,4 +15,4 @@ export NO_SILENCE=" --version " export TOOL="cmake" -exec $(dirname "$0")/quiet "$@" +exec "$(dirname "$0")/quiet" "$@" From d0e3827ea2020c4a7a870cf759fed254c79c1c5d Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 26 Feb 2024 17:28:56 +0000 Subject: [PATCH 023/123] Improve docs Signed-off-by: Dave Rodgman --- tests/scripts/quiet/quiet | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/scripts/quiet/quiet b/tests/scripts/quiet/quiet index bbc685cd8b..8f83d07638 100755 --- a/tests/scripts/quiet/quiet +++ b/tests/scripts/quiet/quiet @@ -9,6 +9,17 @@ # If you are debugging a build / CI issue, you can get complete unsilenced logs # by un-commenting the following line (or setting VERBOSE_LOGS in your environment): # VERBOSE_LOGS=1 +# +# This script provides most of the functionality for the adjacent make and cmake +# wrappers. +# +# It requires two variables to be set: +# +# TOOL - the name of the tool that is being wrapped (with no path), e.g. "make" +# +# NO_SILENCE - a regex that describes the commandline arguments for which output will not +# be silenced, e.g. " --version | test ". In this example, "make test" will +# not be silent, but "make lib" will be. # Locate original tool TOOL_WITH_PATH=$(dirname "$0")/$TOOL From bdf0a6d4318fe19b8a61d573b334ff447fa8bc66 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 26 Feb 2024 17:29:10 +0000 Subject: [PATCH 024/123] remove shebang from quiet Signed-off-by: Dave Rodgman --- tests/scripts/quiet/quiet | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/scripts/quiet/quiet b/tests/scripts/quiet/quiet index 8f83d07638..00e2f6342f 100755 --- a/tests/scripts/quiet/quiet +++ b/tests/scripts/quiet/quiet @@ -1,5 +1,3 @@ -#! /usr/bin/env bash -# # Copyright The Mbed TLS Contributors # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later # From dbc2e8d4ccad4ac7da8a27c34253a74bad34d20a Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 26 Feb 2024 17:29:31 +0000 Subject: [PATCH 025/123] Improve simplified quoting Signed-off-by: Dave Rodgman --- tests/scripts/quiet/quiet | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/tests/scripts/quiet/quiet b/tests/scripts/quiet/quiet index 00e2f6342f..7b54bdba86 100755 --- a/tests/scripts/quiet/quiet +++ b/tests/scripts/quiet/quiet @@ -27,18 +27,15 @@ print_quoted_args() { # similar to printf '%q' "$@" # but produce more human-readable results for common/simple cases like "a b" for a in "$@"; do - simple_pattern='^([[:alnum:]_+-]+=)?([[:alnum:] _=+-./:@]*)$' - if [[ $a =~ ' ' && $a =~ $simple_pattern ]]; then - # a has spaces, but no other special characters that need escaping - # (quoting after removing spaces yields no backslashes) - # simplify quoted form - e.g.: - # a b -> "a b" - # CFLAGS=a b -> CFLAGS="a b" - q="${BASH_REMATCH[1]}\"${BASH_REMATCH[2]}\"" - else - # get bash to do the quoting (which may result in no quotes or escaping, - # if none is needed). - q=$(printf '%q' "$a") + # Get bash to quote the string + q=$(printf '%q' "$a") + simple_pattern="^([-[:alnum:]_+./:@]+=)?([^']*)$" + if [[ "$a" != "$q" && $a =~ $simple_pattern ]]; then + # a requires some quoting (a != q), but has no single quotes, so we can + # simplify the quoted form - e.g.: + # a b -> 'a b' + # CFLAGS=a b -> CFLAGS='a b' + q="${BASH_REMATCH[1]}'${BASH_REMATCH[2]}'" fi printf "%s " "$q" done From 67126bbcea0f0486149ba3f8671a12e747924ceb Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 26 Feb 2024 17:30:37 +0000 Subject: [PATCH 026/123] remove trailing space from printed command Signed-off-by: Dave Rodgman --- tests/scripts/quiet/quiet | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/scripts/quiet/quiet b/tests/scripts/quiet/quiet index 7b54bdba86..9c4939ed24 100755 --- a/tests/scripts/quiet/quiet +++ b/tests/scripts/quiet/quiet @@ -37,7 +37,7 @@ print_quoted_args() { # CFLAGS=a b -> CFLAGS='a b' q="${BASH_REMATCH[1]}'${BASH_REMATCH[2]}'" fi - printf "%s " "$q" + printf " %s" "$q" done } @@ -45,7 +45,7 @@ if [[ ! " $* " =~ " --version " ]]; then # Display the command being invoked - if it succeeds, this is all that will # be displayed. Don't do this for invocations with --version, because # this output is often parsed by scripts, so we don't want to modify it. - printf %s "${TOOL} " + printf %s "${TOOL}" print_quoted_args "$@" echo fi From 2f94766a613500b6cdf79f2a438eef7faa975f2a Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 26 Feb 2024 17:30:56 +0000 Subject: [PATCH 027/123] Send printed command to stderr Signed-off-by: Dave Rodgman --- tests/scripts/quiet/quiet | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/scripts/quiet/quiet b/tests/scripts/quiet/quiet index 9c4939ed24..0f5bf06ecd 100755 --- a/tests/scripts/quiet/quiet +++ b/tests/scripts/quiet/quiet @@ -45,9 +45,9 @@ if [[ ! " $* " =~ " --version " ]]; then # Display the command being invoked - if it succeeds, this is all that will # be displayed. Don't do this for invocations with --version, because # this output is often parsed by scripts, so we don't want to modify it. - printf %s "${TOOL}" - print_quoted_args "$@" - echo + printf %s "${TOOL}" 1>&2 + print_quoted_args "$@" 1>&2 + echo 1>&2 fi if [[ " $@ " =~ $NO_SILENCE || -n "${VERBOSE_LOGS}" ]]; then From 1fa2f6e9afa99a01fb9854f4cdb0f1261335bdda Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 27 Feb 2024 08:11:25 +0100 Subject: [PATCH 028/123] test: remove usage of mbedtls_pk_wrap_as_opaque() from tests This is replaced with: mbedtls_pk_get_psa_attributes() + mbedtls_pk_import_into_psa() + mbedtls_pk_setup_opaque(). Signed-off-by: Valerio Setti --- tests/src/test_helpers/ssl_helpers.c | 21 ++++++++-- tests/suites/test_suite_pk.function | 49 +++++++++++++--------- tests/suites/test_suite_pkwrite.function | 22 ++++++---- tests/suites/test_suite_x509write.function | 47 +++++++-------------- 4 files changed, 78 insertions(+), 61 deletions(-) diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index 7a28bd8795..f6645d7dec 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -685,9 +685,24 @@ int mbedtls_test_ssl_endpoint_certificate_init(mbedtls_test_ssl_endpoint *ep, #if defined(MBEDTLS_USE_PSA_CRYPTO) if (opaque_alg != 0) { - TEST_EQUAL(mbedtls_pk_wrap_as_opaque(cert->pkey, &key_slot, - opaque_alg, opaque_usage, - opaque_alg2), 0); + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; + /* Use a fake key usage to get a successful initial guess for the PSA attributes. */ + TEST_EQUAL(mbedtls_pk_get_psa_attributes(cert->pkey, PSA_KEY_USAGE_VERIFY_HASH, + &key_attr), 0); + /* Then manually set type, usage, alg and alg2 as requested by the test. */ + psa_key_type_t key_type = psa_get_key_type(&key_attr); + if (PSA_KEY_TYPE_IS_PUBLIC_KEY(key_type)) { + psa_set_key_type(&key_attr, PSA_KEY_TYPE_KEY_PAIR_OF_PUBLIC_KEY(key_type)); + } + psa_set_key_usage_flags(&key_attr, opaque_usage); + psa_set_key_algorithm(&key_attr, opaque_alg); + if (opaque_alg2 != PSA_ALG_NONE) { + psa_set_key_enrollment_algorithm(&key_attr, opaque_alg2); + } + TEST_EQUAL(mbedtls_pk_import_into_psa(cert->pkey, &key_attr, &key_slot), 0); + mbedtls_pk_free(cert->pkey); + mbedtls_pk_init(cert->pkey); + TEST_EQUAL(mbedtls_pk_setup_opaque(cert->pkey, key_slot), 0); } #else (void) opaque_alg; diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 180cf76394..91b3337ff4 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -836,6 +836,7 @@ void mbedtls_pk_check_pair(char *pub_file, char *prv_file, int ret) mbedtls_pk_context pub, prv, alt; #if defined(MBEDTLS_USE_PSA_CRYPTO) mbedtls_svc_key_id_t opaque_key_id = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_attributes_t opaque_key_attr = PSA_KEY_ATTRIBUTES_INIT; #endif /* MBEDTLS_USE_PSA_CRYPTO */ mbedtls_pk_init(&pub); @@ -873,9 +874,13 @@ void mbedtls_pk_check_pair(char *pub_file, char *prv_file, int ret) #endif #if defined(MBEDTLS_USE_PSA_CRYPTO) if (mbedtls_pk_get_type(&prv) == MBEDTLS_PK_ECKEY) { - TEST_EQUAL(mbedtls_pk_wrap_as_opaque(&prv, &opaque_key_id, - PSA_ALG_ANY_HASH, - PSA_KEY_USAGE_EXPORT, 0), 0); + /* Turn the prv PK context into an opaque one.*/ + TEST_EQUAL(mbedtls_pk_get_psa_attributes(&prv, PSA_KEY_USAGE_SIGN_HASH, + &opaque_key_attr), 0); + TEST_EQUAL(mbedtls_pk_import_into_psa(&prv, &opaque_key_attr, &opaque_key_id), 0); + mbedtls_pk_free(&prv); + mbedtls_pk_init(&prv); + TEST_EQUAL(mbedtls_pk_setup_opaque(&prv, opaque_key_id), 0); TEST_EQUAL(mbedtls_pk_check_pair(&pub, &prv, mbedtls_test_rnd_std_rand, NULL), ret); } @@ -1395,7 +1400,8 @@ void pk_wrap_rsa_decrypt_test_vec(data_t *cipher, int mod, mbedtls_mpi N, P, Q, E; mbedtls_rsa_context *rsa; mbedtls_pk_context pk; - mbedtls_svc_key_id_t key_id; + mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; size_t olen; mbedtls_pk_init(&pk); @@ -1422,10 +1428,11 @@ void pk_wrap_rsa_decrypt_test_vec(data_t *cipher, int mod, TEST_EQUAL(mbedtls_rsa_complete(rsa), 0); /* Turn PK context into an opaque one. */ - TEST_EQUAL(mbedtls_pk_wrap_as_opaque(&pk, &key_id, - PSA_ALG_RSA_PKCS1V15_CRYPT, - PSA_KEY_USAGE_DECRYPT, - PSA_ALG_NONE), 0); + TEST_EQUAL(mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_DECRYPT, &key_attr), 0); + TEST_EQUAL(mbedtls_pk_import_into_psa(&pk, &key_attr, &key_id), 0); + mbedtls_pk_free(&pk); + mbedtls_pk_init(&pk); + TEST_EQUAL(mbedtls_pk_setup_opaque(&pk, key_id), 0); TEST_EQUAL(mbedtls_pk_get_bitlen(&pk), mod); @@ -1635,10 +1642,9 @@ void pk_psa_sign(int curve_or_keybits, int psa_type, int expected_bits) unsigned char pkey_legacy[200]; unsigned char pkey_psa[200]; unsigned char *pkey_legacy_start, *pkey_psa_start; - psa_algorithm_t alg_psa; size_t sig_len, klen_legacy, klen_psa; int ret; - mbedtls_svc_key_id_t key_id; + mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; /* @@ -1660,7 +1666,6 @@ void pk_psa_sign(int curve_or_keybits, int psa_type, int expected_bits) TEST_ASSERT(mbedtls_rsa_gen_key(mbedtls_pk_rsa(pk), mbedtls_test_rnd_std_rand, NULL, curve_or_keybits, 3) == 0); - alg_psa = PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256); } else #endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */ #if defined(MBEDTLS_PK_CAN_ECDSA_SIGN) @@ -1671,8 +1676,6 @@ void pk_psa_sign(int curve_or_keybits, int psa_type, int expected_bits) TEST_ASSERT(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)) == 0); TEST_ASSERT(pk_genkey(&pk, grpid) == 0); - - alg_psa = PSA_ALG_ECDSA(PSA_ALG_SHA_256); } else #endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */ { @@ -1699,9 +1702,11 @@ void pk_psa_sign(int curve_or_keybits, int psa_type, int expected_bits) #endif /* MBEDTLS_PK_WRITE_C */ /* Turn PK context into an opaque one. */ - TEST_ASSERT(mbedtls_pk_wrap_as_opaque(&pk, &key_id, alg_psa, - PSA_KEY_USAGE_SIGN_HASH, - PSA_ALG_NONE) == 0); + TEST_EQUAL(mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_SIGN_HASH, &attributes), 0); + TEST_EQUAL(mbedtls_pk_import_into_psa(&pk, &attributes, &key_id), 0); + mbedtls_pk_free(&pk); + mbedtls_pk_init(&pk); + TEST_EQUAL(mbedtls_pk_setup_opaque(&pk, key_id), 0); PSA_ASSERT(psa_get_key_attributes(key_id, &attributes)); TEST_EQUAL(psa_get_key_type(&attributes), (psa_key_type_t) psa_type); @@ -1822,6 +1827,7 @@ void pk_psa_wrap_sign_ext(int pk_type, int key_bits, int key_pk_type, int md_alg mbedtls_pk_context pk; size_t sig_len, pkey_len; mbedtls_svc_key_id_t key_id; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE]; unsigned char pkey[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; unsigned char *pkey_start; @@ -1861,9 +1867,14 @@ void pk_psa_wrap_sign_ext(int pk_type, int key_bits, int key_pk_type, int md_alg } /* Turn PK context into an opaque one. */ - TEST_EQUAL(mbedtls_pk_wrap_as_opaque(&pk, &key_id, psa_alg, - PSA_KEY_USAGE_SIGN_HASH, - PSA_ALG_NONE), 0); + TEST_EQUAL(mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_SIGN_HASH, &key_attr), 0); + /* Tweak the algorithm associated with the PSA key because get_psa_attributes() returns + * a PSA_ALG_RSA_PSS_ANY_SALT(), but mbedtls_pk_sign_ext() requires a PSA_ALG_RSA_PSS().*/ + psa_set_key_algorithm(&key_attr, psa_alg); + TEST_EQUAL(mbedtls_pk_import_into_psa(&pk, &key_attr, &key_id), 0); + mbedtls_pk_free(&pk); + mbedtls_pk_init(&pk); + TEST_EQUAL(mbedtls_pk_setup_opaque(&pk, key_id), 0); memset(hash, 0x2a, sizeof(hash)); memset(sig, 0, sizeof(sig)); diff --git a/tests/suites/test_suite_pkwrite.function b/tests/suites/test_suite_pkwrite.function index c7600903f1..735c12547c 100644 --- a/tests/suites/test_suite_pkwrite.function +++ b/tests/suites/test_suite_pkwrite.function @@ -75,6 +75,7 @@ static void pk_write_check_common(char *key_file, int is_public_key, int is_der) size_t buf_len, check_buf_len; #if defined(MBEDTLS_USE_PSA_CRYPTO) mbedtls_svc_key_id_t opaque_id = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; #endif /* MBEDTLS_USE_PSA_CRYPTO */ USE_PSA_INIT(); @@ -117,10 +118,13 @@ static void pk_write_check_common(char *key_file, int is_public_key, int is_der) /* Verify that pk_write works also for opaque private keys */ if (!is_public_key) { memset(buf, 0, check_buf_len); - TEST_EQUAL(mbedtls_pk_wrap_as_opaque(&key, &opaque_id, - PSA_ALG_NONE, - PSA_KEY_USAGE_EXPORT, - PSA_ALG_NONE), 0); + /* Turn the key PK context into an opaque one. + * Note: set some practical usage for the key to make get_psa_attributes() happy. */ + TEST_EQUAL(mbedtls_pk_get_psa_attributes(&key, PSA_KEY_USAGE_SIGN_MESSAGE, &key_attr), 0); + TEST_EQUAL(mbedtls_pk_import_into_psa(&key, &key_attr, &opaque_id), 0); + mbedtls_pk_free(&key); + mbedtls_pk_init(&key); + TEST_EQUAL(mbedtls_pk_setup_opaque(&key, opaque_id), 0); start_buf = buf; buf_len = check_buf_len; TEST_EQUAL(pk_write_any_key(&key, &start_buf, &buf_len, is_public_key, @@ -172,6 +176,7 @@ void pk_write_public_from_private(char *priv_key_file, char *pub_key_file) size_t pub_key_len = 0; #if defined(MBEDTLS_USE_PSA_CRYPTO) mbedtls_svc_key_id_t opaque_key_id = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; #endif /* MBEDTLS_USE_PSA_CRYPTO */ mbedtls_pk_init(&priv_key); @@ -194,9 +199,12 @@ void pk_write_public_from_private(char *priv_key_file, char *pub_key_file) #if defined(MBEDTLS_USE_PSA_CRYPTO) mbedtls_platform_zeroize(derived_key_raw, derived_key_len); - TEST_EQUAL(mbedtls_pk_wrap_as_opaque(&priv_key, &opaque_key_id, - PSA_ALG_NONE, PSA_KEY_USAGE_EXPORT, - PSA_ALG_NONE), 0); + /* Turn the priv_key PK context into an opaque one. */ + TEST_EQUAL(mbedtls_pk_get_psa_attributes(&priv_key, PSA_KEY_USAGE_SIGN_HASH, &key_attr), 0); + TEST_EQUAL(mbedtls_pk_import_into_psa(&priv_key, &key_attr, &opaque_key_id), 0); + mbedtls_pk_free(&priv_key); + mbedtls_pk_init(&priv_key); + TEST_EQUAL(mbedtls_pk_setup_opaque(&priv_key, opaque_key_id), 0); TEST_EQUAL(mbedtls_pk_write_pubkey_der(&priv_key, derived_key_raw, derived_key_len), pub_key_len); diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function index 3d84c729fe..1db7e1cff2 100644 --- a/tests/suites/test_suite_x509write.function +++ b/tests/suites/test_suite_x509write.function @@ -284,7 +284,7 @@ void x509_csr_check_opaque(char *key_file, int md_type, int key_usage, { mbedtls_pk_context key; mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; - psa_algorithm_t md_alg_psa, alg_psa; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; mbedtls_x509write_csr req; unsigned char buf[4096]; int ret; @@ -297,24 +297,16 @@ void x509_csr_check_opaque(char *key_file, int md_type, int key_usage, memset(&rnd_info, 0x2a, sizeof(mbedtls_test_rnd_pseudo_info)); - md_alg_psa = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) md_type); - TEST_ASSERT(md_alg_psa != MBEDTLS_MD_NONE); - mbedtls_pk_init(&key); TEST_ASSERT(mbedtls_pk_parse_keyfile(&key, key_file, NULL, mbedtls_test_rnd_std_rand, NULL) == 0); - if (mbedtls_pk_get_type(&key) == MBEDTLS_PK_ECKEY) { - alg_psa = PSA_ALG_ECDSA(md_alg_psa); - } else if (mbedtls_pk_get_type(&key) == MBEDTLS_PK_RSA) { - alg_psa = PSA_ALG_RSA_PKCS1V15_SIGN(md_alg_psa); - } else { - TEST_ASSUME(!"PK key type not supported in this configuration"); - } - - TEST_ASSERT(mbedtls_pk_wrap_as_opaque(&key, &key_id, alg_psa, - PSA_KEY_USAGE_SIGN_HASH, - PSA_ALG_NONE) == 0); + /* Turn the PK context into an opaque one. */ + TEST_EQUAL(mbedtls_pk_get_psa_attributes(&key, PSA_KEY_USAGE_SIGN_HASH, &key_attr), 0); + TEST_EQUAL(mbedtls_pk_import_into_psa(&key, &key_attr, &key_id), 0); + mbedtls_pk_free(&key); + mbedtls_pk_init(&key); + TEST_EQUAL(mbedtls_pk_setup_opaque(&key, key_id), 0); mbedtls_x509write_csr_set_md_alg(&req, md_type); mbedtls_x509write_csr_set_key(&req, &key); @@ -373,6 +365,7 @@ void x509_crt_check(char *subject_key_file, char *subject_pwd, mbedtls_test_rnd_pseudo_info rnd_info; #if defined(MBEDTLS_USE_PSA_CRYPTO) mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; #endif mbedtls_pk_type_t issuer_key_type; mbedtls_x509_san_list san_ip; @@ -451,24 +444,14 @@ void x509_crt_check(char *subject_key_file, char *subject_pwd, #endif #if defined(MBEDTLS_USE_PSA_CRYPTO) - /* For Opaque PK contexts, wrap key as an Opaque RSA context. */ + /* Turn the issuer PK context into an opaque one. */ if (pk_wrap == 2) { - psa_algorithm_t alg_psa, md_alg_psa; - - md_alg_psa = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) md_type); - TEST_ASSERT(md_alg_psa != MBEDTLS_MD_NONE); - - if (mbedtls_pk_get_type(&issuer_key) == MBEDTLS_PK_ECKEY) { - alg_psa = PSA_ALG_ECDSA(md_alg_psa); - } else if (mbedtls_pk_get_type(&issuer_key) == MBEDTLS_PK_RSA) { - alg_psa = PSA_ALG_RSA_PKCS1V15_SIGN(md_alg_psa); - } else { - TEST_ASSUME(!"PK key type not supported in this configuration"); - } - - TEST_ASSERT(mbedtls_pk_wrap_as_opaque(&issuer_key, &key_id, alg_psa, - PSA_KEY_USAGE_SIGN_HASH, - PSA_ALG_NONE) == 0); + TEST_EQUAL(mbedtls_pk_get_psa_attributes(&issuer_key, PSA_KEY_USAGE_SIGN_HASH, + &key_attr), 0); + TEST_EQUAL(mbedtls_pk_import_into_psa(&issuer_key, &key_attr, &key_id), 0); + mbedtls_pk_free(&issuer_key); + mbedtls_pk_init(&issuer_key); + TEST_EQUAL(mbedtls_pk_setup_opaque(&issuer_key, key_id), 0); } #endif /* MBEDTLS_USE_PSA_CRYPTO */ From 7541ebea52cc634c5dfc0ec459c477992915fde6 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 27 Feb 2024 10:44:33 +0100 Subject: [PATCH 029/123] programs: remove usage of mbedtls_pk_wrap_as_opaque() from tests This is replaced with: mbedtls_pk_get_psa_attributes() + mbedtls_pk_import_into_psa() + mbedtls_pk_setup_opaque(). Signed-off-by: Valerio Setti --- programs/ssl/ssl_client2.c | 5 ++--- programs/ssl/ssl_server2.c | 12 ++++-------- programs/ssl/ssl_test_lib.c | 29 +++++++++++++++++++++++++++++ programs/ssl/ssl_test_lib.h | 23 +++++++++++++++++++++++ 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 05bb2ffdd0..f5768b1195 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -1711,11 +1711,10 @@ usage: &psa_alg, &psa_alg2, &usage, mbedtls_pk_get_type(&pkey)) == 0) { - ret = mbedtls_pk_wrap_as_opaque(&pkey, &key_slot, psa_alg, - usage, psa_alg2); + ret = pk_wrap_as_opaque(&pkey, psa_alg, psa_alg2, usage, &key_slot); if (ret != 0) { mbedtls_printf(" failed\n ! " - "mbedtls_pk_wrap_as_opaque returned -0x%x\n\n", + "mbedtls_pk_get_psa_attributes returned -0x%x\n\n", (unsigned int) -ret); goto exit; } diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index abf33dec9d..f00a111fd1 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -2708,12 +2708,10 @@ usage: &psa_alg, &psa_alg2, &psa_usage, mbedtls_pk_get_type(&pkey)) == 0) { - ret = mbedtls_pk_wrap_as_opaque(&pkey, &key_slot, - psa_alg, psa_usage, psa_alg2); - + ret = pk_wrap_as_opaque(&pkey, psa_alg, psa_alg2, psa_usage, &key_slot); if (ret != 0) { mbedtls_printf(" failed\n ! " - "mbedtls_pk_wrap_as_opaque returned -0x%x\n\n", + "pk_wrap_as_opaque returned -0x%x\n\n", (unsigned int) -ret); goto exit; } @@ -2727,12 +2725,10 @@ usage: &psa_alg, &psa_alg2, &psa_usage, mbedtls_pk_get_type(&pkey2)) == 0) { - ret = mbedtls_pk_wrap_as_opaque(&pkey2, &key_slot2, - psa_alg, psa_usage, psa_alg2); - + ret = pk_wrap_as_opaque(&pkey2, psa_alg, psa_alg2, psa_usage, &key_slot2); if (ret != 0) { mbedtls_printf(" failed\n ! " - "mbedtls_pk_wrap_as_opaque returned -0x%x\n\n", + "mbedtls_pk_get_psa_attributes returned -0x%x\n\n", (unsigned int) -ret); goto exit; } diff --git a/programs/ssl/ssl_test_lib.c b/programs/ssl/ssl_test_lib.c index d3ac526f7e..ec02295904 100644 --- a/programs/ssl/ssl_test_lib.c +++ b/programs/ssl/ssl_test_lib.c @@ -274,6 +274,35 @@ int key_opaque_set_alg_usage(const char *alg1, const char *alg2, return 0; } + +int pk_wrap_as_opaque(mbedtls_pk_context *pk, psa_algorithm_t psa_alg, psa_algorithm_t psa_alg2, + psa_key_usage_t psa_usage, mbedtls_svc_key_id_t *key_id) +{ + int ret; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; + + ret = mbedtls_pk_get_psa_attributes(pk, PSA_KEY_USAGE_SIGN_HASH, &key_attr); + if (ret != 0) { + return ret; + } + psa_set_key_usage_flags(&key_attr, psa_usage); + psa_set_key_algorithm(&key_attr, psa_alg); + if (psa_alg2 != PSA_ALG_NONE) { + psa_set_key_enrollment_algorithm(&key_attr, psa_alg2); + } + ret = mbedtls_pk_import_into_psa(pk, &key_attr, key_id); + if (ret != 0) { + return ret; + } + mbedtls_pk_free(pk); + mbedtls_pk_init(pk); + ret = mbedtls_pk_setup_opaque(pk, *key_id); + if (ret != 0) { + return ret; + } + + return 0; +} #endif /* MBEDTLS_USE_PSA_CRYPTO */ #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h index d06e0997d1..5cb6a361a8 100644 --- a/programs/ssl/ssl_test_lib.h +++ b/programs/ssl/ssl_test_lib.h @@ -235,6 +235,29 @@ int key_opaque_set_alg_usage(const char *alg1, const char *alg2, psa_algorithm_t *psa_alg2, psa_key_usage_t *usage, mbedtls_pk_type_t key_type); + +/** Turn a non-opaque PK context into an opaque one with folowing steps: + * - extract the key data and attributes from the PK context. + * - import the key material into PSA. + * - free the provided PK context and re-initilize it as an opaque PK context + * wrapping the PSA key imported in the above step. + * + * \param[in/out] pk On input the non-opaque PK context which contains the + * key to be wrapped. On output the re-initialized PK + * context which represents the opaque version of the one + * provided as input. + * \param[in] psa_alg The primary algorithm that will be associated to the + * PSA key. + * \param[in] psa_alg2 The enrollment algorithm that will be associated to the + * PSA key. + * \param[in] psa_usage The PSA key usage policy. + * \param[out] key_id The PSA key identifier of the imported key. + * + * \return \c 0 on sucess. + * \return \c -1 on failure. + */ +int pk_wrap_as_opaque(mbedtls_pk_context *pk, psa_algorithm_t psa_alg, psa_algorithm_t psa_alg2, + psa_key_usage_t psa_usage, mbedtls_svc_key_id_t *key_id); #endif /* MBEDTLS_USE_PSA_CRYPTO */ #if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) From 4c6cea549c28d3dc9b7a23a5ed607009055f7e7f Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 27 Feb 2024 10:48:49 +0100 Subject: [PATCH 030/123] pk: deprecate mbedtls_pk_wrap_as_opaque() Signed-off-by: Valerio Setti --- include/mbedtls/pk.h | 23 ++++++++++++++--------- library/pk.c | 14 +++++++------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h index 534712b5ab..fff1912d1c 100644 --- a/include/mbedtls/pk.h +++ b/include/mbedtls/pk.h @@ -1213,12 +1213,17 @@ int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start, const mbedtls_pk_context *key); #endif /* MBEDTLS_PK_WRITE_C */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) /** * \brief Turn an EC or RSA key into an opaque one. * - * \warning This is a temporary utility function for tests. It might - * change or be removed at any time without notice. + * \warning This function is deprecated and will be removed in a + * future version of the library. + * To wrap a key into an opaque one the following functions + * should be used instead: + * - mbedtls_pk_get_psa_attributes() + * - mbedtls_pk_import_into_psa() + * - mbedtls_pk_setup_opaque(). * * \param pk Input: the EC or RSA key to import to a PSA key. * Output: a PK context wrapping that PSA key. @@ -1233,12 +1238,12 @@ int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start, * \return \c 0 if successful. * \return An Mbed TLS error code otherwise. */ -int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk, - mbedtls_svc_key_id_t *key, - psa_algorithm_t alg, - psa_key_usage_t usage, - psa_algorithm_t alg2); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ +MBEDTLS_DEPRECATED mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk, + mbedtls_svc_key_id_t *key, + psa_algorithm_t alg, + psa_key_usage_t usage, + psa_algorithm_t alg2); +#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ #ifdef __cplusplus } diff --git a/library/pk.c b/library/pk.c index 1ded4872f9..322cd583a9 100644 --- a/library/pk.c +++ b/library/pk.c @@ -1357,18 +1357,18 @@ mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx) return ctx->pk_info->type; } -#if defined(MBEDTLS_USE_PSA_CRYPTO) +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) /* * Load the key to a PSA key slot, * then turn the PK context into a wrapper for that key slot. * * Currently only works for EC & RSA private keys. */ -int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk, - mbedtls_svc_key_id_t *key, - psa_algorithm_t alg, - psa_key_usage_t usage, - psa_algorithm_t alg2) +MBEDTLS_DEPRECATED int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk, + mbedtls_svc_key_id_t *key, + psa_algorithm_t alg, + psa_key_usage_t usage, + psa_algorithm_t alg2) { #if !defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_RSA_C) ((void) pk); @@ -1476,5 +1476,5 @@ int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk, #endif /* !MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_RSA_C */ return MBEDTLS_ERR_PK_TYPE_MISMATCH; } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ +#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ #endif /* MBEDTLS_PK_C */ From 88ae0ef286b348910a76b3ba78d6b9cd90851382 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 27 Feb 2024 13:49:42 +0100 Subject: [PATCH 031/123] pk: completely remove mbedtls_pk_wrap_as_opaque Remove instead of deprecating it. Signed-off-by: Valerio Setti --- include/mbedtls/pk.h | 32 ------------ library/pk.c | 120 ------------------------------------------- 2 files changed, 152 deletions(-) diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h index fff1912d1c..ff80290059 100644 --- a/include/mbedtls/pk.h +++ b/include/mbedtls/pk.h @@ -1213,38 +1213,6 @@ int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start, const mbedtls_pk_context *key); #endif /* MBEDTLS_PK_WRITE_C */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) -/** - * \brief Turn an EC or RSA key into an opaque one. - * - * \warning This function is deprecated and will be removed in a - * future version of the library. - * To wrap a key into an opaque one the following functions - * should be used instead: - * - mbedtls_pk_get_psa_attributes() - * - mbedtls_pk_import_into_psa() - * - mbedtls_pk_setup_opaque(). - * - * \param pk Input: the EC or RSA key to import to a PSA key. - * Output: a PK context wrapping that PSA key. - * \param key Output: a PSA key identifier. - * It's the caller's responsibility to call - * psa_destroy_key() on that key identifier after calling - * mbedtls_pk_free() on the PK context. - * \param alg The algorithm to allow for use with that key. - * \param usage The usage to allow for use with that key. - * \param alg2 The secondary algorithm to allow for use with that key. - * - * \return \c 0 if successful. - * \return An Mbed TLS error code otherwise. - */ -MBEDTLS_DEPRECATED mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk, - mbedtls_svc_key_id_t *key, - psa_algorithm_t alg, - psa_key_usage_t usage, - psa_algorithm_t alg2); -#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ - #ifdef __cplusplus } #endif diff --git a/library/pk.c b/library/pk.c index 322cd583a9..7aee940902 100644 --- a/library/pk.c +++ b/library/pk.c @@ -1357,124 +1357,4 @@ mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx) return ctx->pk_info->type; } -#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) -/* - * Load the key to a PSA key slot, - * then turn the PK context into a wrapper for that key slot. - * - * Currently only works for EC & RSA private keys. - */ -MBEDTLS_DEPRECATED int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk, - mbedtls_svc_key_id_t *key, - psa_algorithm_t alg, - psa_key_usage_t usage, - psa_algorithm_t alg2) -{ -#if !defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_RSA_C) - ((void) pk); - ((void) key); - ((void) alg); - ((void) usage); - ((void) alg2); -#else /* !MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_RSA_C */ -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_ECKEY) { - size_t d_len; - psa_ecc_family_t curve_id; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_type_t key_type; - size_t bits; - psa_status_t status; - - /* export the private key material in the format PSA wants */ -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - unsigned char d[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH]; - status = psa_export_key(pk->priv_id, d, sizeof(d), &d_len); - if (status != PSA_SUCCESS) { - return psa_pk_status_to_mbedtls(status); - } - - curve_id = pk->ec_family; - bits = pk->ec_bits; -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ - unsigned char d[MBEDTLS_ECP_MAX_BYTES]; - mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk); - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - d_len = PSA_BITS_TO_BYTES(ec->grp.nbits); - if ((ret = mbedtls_ecp_write_key(ec, d, d_len)) != 0) { - return ret; - } - - curve_id = mbedtls_ecc_group_to_psa(ec->grp.id, &bits); -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ - key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(curve_id); - - /* prepare the key attributes */ - psa_set_key_type(&attributes, key_type); - psa_set_key_bits(&attributes, bits); - psa_set_key_usage_flags(&attributes, usage); - psa_set_key_algorithm(&attributes, alg); - if (alg2 != PSA_ALG_NONE) { - psa_set_key_enrollment_algorithm(&attributes, alg2); - } - - /* import private key into PSA */ - status = psa_import_key(&attributes, d, d_len, key); - mbedtls_platform_zeroize(d, sizeof(d)); - if (status != PSA_SUCCESS) { - return PSA_PK_TO_MBEDTLS_ERR(status); - } - - /* make PK context wrap the key slot */ - mbedtls_pk_free(pk); - mbedtls_pk_init(pk); - - return mbedtls_pk_setup_opaque(pk, *key); - } else -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ -#if defined(MBEDTLS_RSA_C) - if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA) { - unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES]; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - int key_len; - psa_status_t status; - - /* export the private key material in the format PSA wants */ - key_len = mbedtls_pk_write_key_der(pk, buf, sizeof(buf)); - if (key_len <= 0) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - /* prepare the key attributes */ - psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); - psa_set_key_bits(&attributes, mbedtls_pk_get_bitlen(pk)); - psa_set_key_usage_flags(&attributes, usage); - psa_set_key_algorithm(&attributes, alg); - if (alg2 != PSA_ALG_NONE) { - psa_set_key_enrollment_algorithm(&attributes, alg2); - } - - /* import private key into PSA */ - status = psa_import_key(&attributes, - buf + sizeof(buf) - key_len, - key_len, key); - - mbedtls_platform_zeroize(buf, sizeof(buf)); - - if (status != PSA_SUCCESS) { - return PSA_PK_TO_MBEDTLS_ERR(status); - } - - /* make PK context wrap the key slot */ - mbedtls_pk_free(pk); - mbedtls_pk_init(pk); - - return mbedtls_pk_setup_opaque(pk, *key); - } else -#endif /* MBEDTLS_RSA_C */ -#endif /* !MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_RSA_C */ - return MBEDTLS_ERR_PK_TYPE_MISMATCH; -} -#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ #endif /* MBEDTLS_PK_C */ From a9de9445b1c1373680fa1da105cc3ea774750816 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 27 Feb 2024 13:56:09 +0100 Subject: [PATCH 032/123] ssl_helpers: minor fix in mbedtls_test_ssl_endpoint_certificate_init() Signed-off-by: Valerio Setti --- tests/src/test_helpers/ssl_helpers.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index f6645d7dec..5d4cb1cf0d 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -687,13 +687,9 @@ int mbedtls_test_ssl_endpoint_certificate_init(mbedtls_test_ssl_endpoint *ep, if (opaque_alg != 0) { psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; /* Use a fake key usage to get a successful initial guess for the PSA attributes. */ - TEST_EQUAL(mbedtls_pk_get_psa_attributes(cert->pkey, PSA_KEY_USAGE_VERIFY_HASH, + TEST_EQUAL(mbedtls_pk_get_psa_attributes(cert->pkey, PSA_KEY_USAGE_SIGN_HASH, &key_attr), 0); - /* Then manually set type, usage, alg and alg2 as requested by the test. */ - psa_key_type_t key_type = psa_get_key_type(&key_attr); - if (PSA_KEY_TYPE_IS_PUBLIC_KEY(key_type)) { - psa_set_key_type(&key_attr, PSA_KEY_TYPE_KEY_PAIR_OF_PUBLIC_KEY(key_type)); - } + /* Then manually usage, alg and alg2 as requested by the test. */ psa_set_key_usage_flags(&key_attr, opaque_usage); psa_set_key_algorithm(&key_attr, opaque_alg); if (opaque_alg2 != PSA_ALG_NONE) { From 23e637a7c7cfcdbb4fcdc4ca944ea6896bf2a06d Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 27 Feb 2024 13:56:57 +0100 Subject: [PATCH 033/123] test_suite_pk: initialize all PSA key IDs and attributes Signed-off-by: Valerio Setti --- tests/suites/test_suite_pk.function | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 91b3337ff4..e1a0011b78 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -434,7 +434,7 @@ exit: */ mbedtls_svc_key_id_t pk_psa_genkey_ecc(void) { - mbedtls_svc_key_id_t key; + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; const psa_key_type_t type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1); @@ -456,7 +456,7 @@ exit: */ mbedtls_svc_key_id_t pk_psa_genkey_rsa(void) { - mbedtls_svc_key_id_t key; + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; const psa_key_type_t type = PSA_KEY_TYPE_RSA_KEY_PAIR; const size_t bits = 1024; @@ -482,7 +482,7 @@ exit: void pk_psa_utils(int key_is_rsa) { mbedtls_pk_context pk, pk2; - mbedtls_svc_key_id_t key; + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; const char * const name = "Opaque"; @@ -1826,7 +1826,7 @@ void pk_psa_wrap_sign_ext(int pk_type, int key_bits, int key_pk_type, int md_alg { mbedtls_pk_context pk; size_t sig_len, pkey_len; - mbedtls_svc_key_id_t key_id; + mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE]; unsigned char pkey[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; From 8988767b0ec7457999a3db107d2b458673fc7ed5 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 27 Feb 2024 23:45:10 +0100 Subject: [PATCH 034/123] Use attribute accessor functions in driver wrappers Fully automated: ``` perl -i -pe 's/(\w+)->core\.(\w+)/psa_get_key_$2($1)/g' scripts/data_files/driver_templates/*.jinja docs/psa-driver-example-and-guide.md ``` Signed-off-by: Gilles Peskine --- docs/psa-driver-example-and-guide.md | 6 +- .../psa_crypto_driver_wrappers.h.jinja | 86 +++++++++---------- ...a_crypto_driver_wrappers_no_static.c.jinja | 10 +-- 3 files changed, 51 insertions(+), 51 deletions(-) diff --git a/docs/psa-driver-example-and-guide.md b/docs/psa-driver-example-and-guide.md index d041723a05..aa825adcdd 100644 --- a/docs/psa-driver-example-and-guide.md +++ b/docs/psa-driver-example-and-guide.md @@ -157,11 +157,11 @@ The driver wrapper functions in `psa_crypto_driver_wrappers.h.jinja` for all fou ``` #if defined (MBEDTLS_PSA_P256M_DRIVER_ENABLED) - if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) && + if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) && PSA_ALG_IS_ECDSA(alg) && !PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) && - PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) == PSA_ECC_FAMILY_SECP_R1 && - attributes->core.bits == 256 ) + PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 && + psa_get_key_bits(attributes) == 256 ) { status = p256_transparent_sign_hash( attributes, key_buffer, diff --git a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja index 4f9764d1c0..8b91f0bb72 100644 --- a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja +++ b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja @@ -122,7 +122,7 @@ static inline psa_status_t psa_driver_wrapper_sign_message( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); switch( location ) { @@ -196,7 +196,7 @@ static inline psa_status_t psa_driver_wrapper_verify_message( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); switch( location ) { @@ -266,7 +266,7 @@ static inline psa_status_t psa_driver_wrapper_sign_hash( const psa_drv_se_t *drv; psa_drv_se_context_t *drv_context; - if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) ) + if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) ) { if( drv->asymmetric == NULL || drv->asymmetric->p_sign == NULL ) @@ -283,7 +283,7 @@ static inline psa_status_t psa_driver_wrapper_sign_hash( psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); switch( location ) { @@ -306,11 +306,11 @@ static inline psa_status_t psa_driver_wrapper_sign_hash( return( status ); #endif /* PSA_CRYPTO_DRIVER_TEST */ #if defined (MBEDTLS_PSA_P256M_DRIVER_ENABLED) - if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) && + if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) && PSA_ALG_IS_ECDSA(alg) && !PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) && - PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) == PSA_ECC_FAMILY_SECP_R1 && - attributes->core.bits == 256 ) + PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 && + psa_get_key_bits(attributes) == 256 ) { status = p256_transparent_sign_hash( attributes, key_buffer, @@ -370,7 +370,7 @@ static inline psa_status_t psa_driver_wrapper_verify_hash( const psa_drv_se_t *drv; psa_drv_se_context_t *drv_context; - if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) ) + if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) ) { if( drv->asymmetric == NULL || drv->asymmetric->p_verify == NULL ) @@ -387,7 +387,7 @@ static inline psa_status_t psa_driver_wrapper_verify_hash( psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); switch( location ) { @@ -410,11 +410,11 @@ static inline psa_status_t psa_driver_wrapper_verify_hash( return( status ); #endif /* PSA_CRYPTO_DRIVER_TEST */ #if defined (MBEDTLS_PSA_P256M_DRIVER_ENABLED) - if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) && + if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) && PSA_ALG_IS_ECDSA(alg) && !PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) && - PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) == PSA_ECC_FAMILY_SECP_R1 && - attributes->core.bits == 256 ) + PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 && + psa_get_key_bits(attributes) == 256 ) { status = p256_transparent_verify_hash( attributes, key_buffer, @@ -517,7 +517,7 @@ static inline psa_status_t psa_driver_wrapper_sign_hash_start( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( - attributes->core.lifetime ); + psa_get_key_lifetime(attributes) ); switch( location ) { @@ -609,7 +609,7 @@ static inline psa_status_t psa_driver_wrapper_verify_hash_start( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( - attributes->core.lifetime ); + psa_get_key_lifetime(attributes) ); switch( location ) { @@ -707,8 +707,8 @@ static inline psa_status_t psa_driver_wrapper_get_key_buffer_size_from_key_data( size_t *key_buffer_size ) { psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); - psa_key_type_t key_type = attributes->core.type; + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); + psa_key_type_t key_type = psa_get_key_type(attributes); *key_buffer_size = 0; switch( location ) @@ -736,7 +736,7 @@ static inline psa_status_t psa_driver_wrapper_generate_key( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION(attributes->core.lifetime); + PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(attributes)); #if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) int is_default_production = @@ -757,7 +757,7 @@ static inline psa_status_t psa_driver_wrapper_generate_key( const psa_drv_se_t *drv; psa_drv_se_context_t *drv_context; - if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) ) + if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) ) { size_t pubkey_length = 0; /* We don't support this feature yet */ if( drv->key_management == NULL || @@ -780,7 +780,7 @@ static inline psa_status_t psa_driver_wrapper_generate_key( /* Transparent drivers are limited to generating asymmetric keys. */ /* We don't support passing custom production parameters * to drivers yet. */ - if( PSA_KEY_TYPE_IS_ASYMMETRIC( attributes->core.type ) && + if( PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type(attributes) ) && is_default_production ) { /* Cycle through all known transparent accelerators */ @@ -793,9 +793,9 @@ static inline psa_status_t psa_driver_wrapper_generate_key( break; #endif /* PSA_CRYPTO_DRIVER_TEST */ #if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED) - if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) && - attributes->core.type == PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1) && - attributes->core.bits == 256 ) + if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) && + psa_get_key_type(attributes) == PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1) && + psa_get_key_bits(attributes) == 256 ) { status = p256_transparent_generate_key( attributes, key_buffer, @@ -862,7 +862,7 @@ bits const psa_drv_se_t *drv; psa_drv_se_context_t *drv_context; - if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) ) + if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) ) { if( drv->key_management == NULL || drv->key_management->p_import == NULL ) @@ -939,7 +939,7 @@ data_length const psa_drv_se_t *drv; psa_drv_se_context_t *drv_context; - if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) ) + if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) ) { if( ( drv->key_management == NULL ) || ( drv->key_management->p_export == NULL ) ) @@ -994,13 +994,13 @@ target_key_buffer_length {% endmacro %} psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); #if defined(MBEDTLS_PSA_CRYPTO_SE_C) const psa_drv_se_t *drv; psa_drv_se_context_t *drv_context; - if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) ) + if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) ) { /* Copying to a secure element is not implemented yet. */ return( PSA_ERROR_NOT_SUPPORTED ); @@ -1044,7 +1044,7 @@ static inline psa_status_t psa_driver_wrapper_cipher_encrypt( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); switch( location ) { @@ -1134,7 +1134,7 @@ static inline psa_status_t psa_driver_wrapper_cipher_decrypt( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); switch( location ) { @@ -1211,7 +1211,7 @@ static inline psa_status_t psa_driver_wrapper_cipher_encrypt_setup( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); switch( location ) { @@ -1284,7 +1284,7 @@ static inline psa_status_t psa_driver_wrapper_cipher_decrypt_setup( { psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); switch( location ) { @@ -1684,7 +1684,7 @@ static inline psa_status_t psa_driver_wrapper_aead_encrypt( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); switch( location ) { @@ -1736,7 +1736,7 @@ static inline psa_status_t psa_driver_wrapper_aead_decrypt( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); switch( location ) { @@ -1785,7 +1785,7 @@ static inline psa_status_t psa_driver_wrapper_aead_encrypt_setup( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); switch( location ) { @@ -1833,7 +1833,7 @@ static inline psa_status_t psa_driver_wrapper_aead_decrypt_setup( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); switch( location ) { @@ -2169,7 +2169,7 @@ static inline psa_status_t psa_driver_wrapper_mac_compute( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); switch( location ) { @@ -2233,7 +2233,7 @@ static inline psa_status_t psa_driver_wrapper_mac_sign_setup( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); switch( location ) { @@ -2305,7 +2305,7 @@ static inline psa_status_t psa_driver_wrapper_mac_verify_setup( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); switch( location ) { @@ -2505,7 +2505,7 @@ static inline psa_status_t psa_driver_wrapper_asymmetric_encrypt( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); switch( location ) { @@ -2563,7 +2563,7 @@ static inline psa_status_t psa_driver_wrapper_asymmetric_decrypt( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); switch( location ) { @@ -2627,7 +2627,7 @@ static inline psa_status_t psa_driver_wrapper_key_agreement( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); switch( location ) { @@ -2645,10 +2645,10 @@ static inline psa_status_t psa_driver_wrapper_key_agreement( return( status ); #endif /* PSA_CRYPTO_DRIVER_TEST */ #if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED) - if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) && + if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) && PSA_ALG_IS_ECDH(alg) && - PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) == PSA_ECC_FAMILY_SECP_R1 && - attributes->core.bits == 256 ) + PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 && + psa_get_key_bits(attributes) == 256 ) { status = p256_transparent_key_agreement( attributes, key_buffer, diff --git a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers_no_static.c.jinja b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers_no_static.c.jinja index 2aae628502..261cd2ab63 100644 --- a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers_no_static.c.jinja +++ b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers_no_static.c.jinja @@ -88,9 +88,9 @@ psa_status_t psa_driver_wrapper_get_key_buffer_size( const psa_key_attributes_t *attributes, size_t *key_buffer_size ) { - psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); - psa_key_type_t key_type = attributes->core.type; - size_t key_bits = attributes->core.bits; + psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); + psa_key_type_t key_type = psa_get_key_type(attributes); + size_t key_bits = psa_get_key_bits(attributes); *key_buffer_size = 0; switch( location ) @@ -144,7 +144,7 @@ data_length const psa_drv_se_t *drv; psa_drv_se_context_t *drv_context; - if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) ) + if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) ) { if( ( drv->key_management == NULL ) || ( drv->key_management->p_export_public == NULL ) ) @@ -203,7 +203,7 @@ key_buffer, key_buffer_size, key_buffer_length {% endmacro %} - psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) ); switch( location ) { #if defined(PSA_CRYPTO_DRIVER_TEST) From 0f40a41cea69cf781f44ca29e8df0d76bc4010da Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 27 Feb 2024 23:21:15 +0100 Subject: [PATCH 035/123] psa_key_attributes_t: move slot_number to core structure Move the `slot_number` field of `psa_key_attributes_t` to `psa_core_key_attributes_t`. This makes ``psa_core_key_attributes_t` core` the sole field of `psa_key_attributes_t`. This paves the way to unifying the two structures. Signed-off-by: Gilles Peskine --- include/psa/crypto_extra.h | 2 +- include/psa/crypto_struct.h | 24 ++++++++++-------------- library/psa_crypto.c | 2 +- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index ac21e3e449..388e829040 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -130,7 +130,7 @@ static inline void psa_set_key_slot_number( psa_key_slot_number_t slot_number) { attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(flags) |= MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER; - attributes->MBEDTLS_PRIVATE(slot_number) = slot_number; + attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(slot_number) = slot_number; } /** Remove the slot number attribute from a key attribute structure. diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 683d8417e8..a0218e3bcb 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -290,6 +290,9 @@ typedef uint16_t psa_key_attributes_flag_t; 0) typedef struct { +#if defined(MBEDTLS_PSA_CRYPTO_SE_C) + psa_key_slot_number_t MBEDTLS_PRIVATE(slot_number); +#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ psa_key_type_t MBEDTLS_PRIVATE(type); psa_key_bits_t MBEDTLS_PRIVATE(bits); psa_key_lifetime_t MBEDTLS_PRIVATE(lifetime); @@ -309,29 +312,22 @@ typedef struct { mbedtls_svc_key_id_t MBEDTLS_PRIVATE(id); } psa_core_key_attributes_t; -#define PSA_CORE_KEY_ATTRIBUTES_INIT { PSA_KEY_TYPE_NONE, 0, \ +#if defined(MBEDTLS_PSA_CRYPTO_SE_C) +#define PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER 0, +#else +#define PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER +#endif +#define PSA_CORE_KEY_ATTRIBUTES_INIT { PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER \ + PSA_KEY_TYPE_NONE, 0, \ PSA_KEY_LIFETIME_VOLATILE, \ PSA_KEY_POLICY_INIT, 0, \ MBEDTLS_SVC_KEY_ID_INIT } struct psa_key_attributes_s { -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - psa_key_slot_number_t MBEDTLS_PRIVATE(slot_number); -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - /* With client/service separation, struct psa_key_attributes_s is - * marshalled through a transport channel between the client and - * service side implementation of the PSA Crypto APIs, thus having - * the mbedtls_svc_key_id_t id as the last field of this structure - * allows for a more efficient marshalling/unmarshalling of parameters - */ psa_core_key_attributes_t MBEDTLS_PRIVATE(core); }; -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) -#define PSA_KEY_ATTRIBUTES_INIT { 0, PSA_CORE_KEY_ATTRIBUTES_INIT } -#else #define PSA_KEY_ATTRIBUTES_INIT { PSA_CORE_KEY_ATTRIBUTES_INIT } -#endif static inline struct psa_key_attributes_s psa_key_attributes_init(void) { diff --git a/library/psa_crypto.c b/library/psa_crypto.c index ca01e76491..7188b128ab 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1246,7 +1246,7 @@ psa_status_t psa_get_key_slot_number( psa_key_slot_number_t *slot_number) { if (attributes->core.flags & MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER) { - *slot_number = attributes->slot_number; + *slot_number = attributes->core.slot_number; return PSA_SUCCESS; } else { return PSA_ERROR_INVALID_ARGUMENT; From 7fad3ef3b5577e9b36ac9a25c9ad0e1ad9b97a63 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 28 Feb 2024 01:08:27 +0100 Subject: [PATCH 036/123] Switch key slots to psa_key_attributes_t Switch `psa_key_slot_t` to the full `psa_key_attributes_t`, now that this structure only has psa_core_key_attributes_t`. To minimize the diff without breaking the build much, temporarily make `psa_key_attributes_t` contain either the `core` field or all the fields. This allows both things like `slot->attr.core.type` and `slot->attr.type` to exist. The build breaks with compilers that don't support anonymous unions and structs, which are only standard C since C11. Signed-off-by: Gilles Peskine --- include/psa/crypto_struct.h | 34 ++++++++++++++++--- library/psa_crypto.c | 49 ++++++++++++++-------------- library/psa_crypto_core.h | 2 +- library/psa_crypto_slot_management.c | 2 +- library/psa_crypto_storage.c | 8 ++--- library/psa_crypto_storage.h | 8 ++--- 6 files changed, 64 insertions(+), 39 deletions(-) diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index a0218e3bcb..e4d85be9bf 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -312,6 +312,34 @@ typedef struct { mbedtls_svc_key_id_t MBEDTLS_PRIVATE(id); } psa_core_key_attributes_t; +struct psa_key_attributes_s { + union { + psa_core_key_attributes_t MBEDTLS_PRIVATE(core); + struct { +#if defined(MBEDTLS_PSA_CRYPTO_SE_C) + psa_key_slot_number_t MBEDTLS_PRIVATE(slot_number); +#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ + psa_key_type_t MBEDTLS_PRIVATE(type); + psa_key_bits_t MBEDTLS_PRIVATE(bits); + psa_key_lifetime_t MBEDTLS_PRIVATE(lifetime); + psa_key_policy_t MBEDTLS_PRIVATE(policy); + psa_key_attributes_flag_t MBEDTLS_PRIVATE(flags); + /* This type has a different layout in the client view wrt the + * service view of the key id, i.e. in service view usually is + * expected to have MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined + * thus adding an owner field to the standard psa_key_id_t. For + * implementations with client/service separation, this means the + * object will be marshalled through a transport channel and + * interpreted differently at each side of the transport. Placing + * it at the end of structures allows to interpret the structure + * at the client without reorganizing the memory layout of the + * struct + */ + mbedtls_svc_key_id_t MBEDTLS_PRIVATE(id); + }; + }; +}; + #if defined(MBEDTLS_PSA_CRYPTO_SE_C) #define PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER 0, #else @@ -323,11 +351,7 @@ typedef struct { PSA_KEY_POLICY_INIT, 0, \ MBEDTLS_SVC_KEY_ID_INIT } -struct psa_key_attributes_s { - psa_core_key_attributes_t MBEDTLS_PRIVATE(core); -}; - -#define PSA_KEY_ATTRIBUTES_INIT { PSA_CORE_KEY_ATTRIBUTES_INIT } +#define PSA_KEY_ATTRIBUTES_INIT { { PSA_CORE_KEY_ATTRIBUTES_INIT } } static inline struct psa_key_attributes_s psa_key_attributes_init(void) { diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 7188b128ab..fe0114ff03 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1226,9 +1226,9 @@ psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key, return status; } - attributes->core = slot->attr; - attributes->core.flags &= (MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY | - MBEDTLS_PSA_KA_MASK_DUAL_USE); + *attributes = slot->attr; + attributes->flags &= (MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY | + MBEDTLS_PSA_KA_MASK_DUAL_USE); #if defined(MBEDTLS_PSA_CRYPTO_SE_C) if (psa_get_se_driver_entry(slot->attr.lifetime) != NULL) { @@ -1325,7 +1325,7 @@ psa_status_t psa_export_key(mbedtls_svc_key_id_t key, } psa_key_attributes_t attributes = { - .core = slot->attr + .core = slot->attr.core }; status = psa_driver_wrapper_export_key(&attributes, slot->key.data, slot->key.bytes, @@ -1438,7 +1438,7 @@ psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key, } attributes = (psa_key_attributes_t) { - .core = slot->attr + .core = slot->attr.core }; status = psa_driver_wrapper_export_public_key( &attributes, slot->key.data, slot->key.bytes, @@ -1617,7 +1617,7 @@ static psa_status_t psa_start_key_creation( * volatile key identifier associated to the slot returned to contain its * definition. */ - slot->attr = attributes->core; + slot->attr = *attributes; if (PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) { #if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) slot->attr.id = volatile_key_id; @@ -2390,7 +2390,7 @@ static psa_status_t psa_mac_setup(psa_mac_operation_t *operation, } attributes = (psa_key_attributes_t) { - .core = slot->attr + .core = slot->attr.core }; status = psa_mac_finalize_alg_and_key_validation(alg, &attributes, @@ -2571,7 +2571,7 @@ static psa_status_t psa_mac_compute_internal(mbedtls_svc_key_id_t key, } attributes = (psa_key_attributes_t) { - .core = slot->attr + .core = slot->attr.core }; status = psa_mac_finalize_alg_and_key_validation(alg, &attributes, @@ -2729,7 +2729,7 @@ static psa_status_t psa_sign_internal(mbedtls_svc_key_id_t key, } attributes = (psa_key_attributes_t) { - .core = slot->attr + .core = slot->attr.core }; if (input_is_message) { @@ -2783,7 +2783,7 @@ static psa_status_t psa_verify_internal(mbedtls_svc_key_id_t key, } psa_key_attributes_t attributes = { - .core = slot->attr + .core = slot->attr.core }; if (input_is_message) { @@ -3057,7 +3057,7 @@ psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key, } attributes = (psa_key_attributes_t) { - .core = slot->attr + .core = slot->attr.core }; status = psa_driver_wrapper_asymmetric_encrypt( @@ -3108,7 +3108,7 @@ psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key, } attributes = (psa_key_attributes_t) { - .core = slot->attr + .core = slot->attr.core }; status = psa_driver_wrapper_asymmetric_decrypt( @@ -3209,7 +3209,7 @@ psa_status_t psa_sign_hash_start( } attributes = (psa_key_attributes_t) { - .core = slot->attr + .core = slot->attr.core }; /* Ensure ops count gets reset, in case of operation re-use. */ @@ -3354,7 +3354,7 @@ psa_status_t psa_verify_hash_start( } psa_key_attributes_t attributes = { - .core = slot->attr + .core = slot->attr.core }; /* Ensure ops count gets reset, in case of operation re-use. */ @@ -3920,7 +3920,7 @@ static psa_status_t psa_cipher_setup(psa_cipher_operation_t *operation, operation->default_iv_length = PSA_CIPHER_IV_LENGTH(slot->attr.type, alg); attributes = (psa_key_attributes_t) { - .core = slot->attr + .core = slot->attr.core }; /* Try doing the operation through a driver before using software fallback. */ @@ -4160,7 +4160,7 @@ psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, } attributes = (psa_key_attributes_t) { - .core = slot->attr + .core = slot->attr.core }; default_iv_length = PSA_CIPHER_IV_LENGTH(slot->attr.type, alg); @@ -4231,7 +4231,7 @@ psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key, } attributes = (psa_key_attributes_t) { - .core = slot->attr + .core = slot->attr.core }; if (alg == PSA_ALG_CCM_STAR_NO_TAG && @@ -4354,7 +4354,7 @@ psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key, } psa_key_attributes_t attributes = { - .core = slot->attr + .core = slot->attr.core }; status = psa_aead_check_nonce_length(alg, nonce_length); @@ -4409,7 +4409,7 @@ psa_status_t psa_aead_decrypt(mbedtls_svc_key_id_t key, } psa_key_attributes_t attributes = { - .core = slot->attr + .core = slot->attr.core }; status = psa_aead_check_nonce_length(alg, nonce_length); @@ -4515,7 +4515,7 @@ static psa_status_t psa_aead_setup(psa_aead_operation_t *operation, } attributes = (psa_key_attributes_t) { - .core = slot->attr + .core = slot->attr.core }; if ((status = psa_validate_tag_length(alg)) != PSA_SUCCESS) { @@ -5892,7 +5892,7 @@ static psa_status_t psa_generate_derived_key_internal( slot->attr.bits = (psa_key_bits_t) bits; attributes = (psa_key_attributes_t) { - .core = slot->attr + .core = slot->attr.core }; if (psa_key_lifetime_is_external(attributes.core.lifetime)) { @@ -7024,7 +7024,7 @@ static psa_status_t psa_key_agreement_raw_internal(psa_algorithm_t alg, } psa_key_attributes_t attributes = { - .core = private_key->attr + .core = private_key->attr.core }; return psa_driver_wrapper_key_agreement(&attributes, @@ -7839,7 +7839,7 @@ psa_status_t psa_pake_set_password_key( } attributes = (psa_key_attributes_t) { - .core = slot->attr + .core = slot->attr.core }; type = psa_get_key_type(&attributes); @@ -7858,7 +7858,8 @@ psa_status_t psa_pake_set_password_key( memcpy(operation->data.inputs.password, slot->key.data, slot->key.bytes); operation->data.inputs.password_len = slot->key.bytes; - operation->data.inputs.attributes = attributes; + operation->data.inputs.attributes = slot->attr; + exit: if (status != PSA_SUCCESS) { psa_pake_abort(operation); diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index afa8659aac..02c485e701 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -59,7 +59,7 @@ typedef enum { * and metadata for one key. */ typedef struct { - psa_core_key_attributes_t attr; + psa_key_attributes_t attr; /* * The current state of the key slot, as described in diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index b2a3c7e5a0..5dee32ffe3 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -329,7 +329,7 @@ static psa_status_t psa_load_builtin_key_into_slot(psa_key_slot_t *slot) /* Copy actual key length and core attributes into the slot on success */ slot->key.bytes = key_buffer_length; - slot->attr = attributes.core; + slot->attr = attributes; exit: if (status != PSA_SUCCESS) { psa_remove_key_data_from_memory(slot); diff --git a/library/psa_crypto_storage.c b/library/psa_crypto_storage.c index 13a3c8a905..7d1317b45a 100644 --- a/library/psa_crypto_storage.c +++ b/library/psa_crypto_storage.c @@ -235,7 +235,7 @@ typedef struct { void psa_format_key_data_for_storage(const uint8_t *data, const size_t data_length, - const psa_core_key_attributes_t *attr, + const psa_key_attributes_t *attr, uint8_t *storage_data) { psa_persistent_key_storage_format *storage_format = @@ -267,7 +267,7 @@ psa_status_t psa_parse_key_data_from_storage(const uint8_t *storage_data, size_t storage_data_length, uint8_t **key_data, size_t *key_data_length, - psa_core_key_attributes_t *attr) + psa_key_attributes_t *attr) { psa_status_t status; const psa_persistent_key_storage_format *storage_format = @@ -314,7 +314,7 @@ psa_status_t psa_parse_key_data_from_storage(const uint8_t *storage_data, return PSA_SUCCESS; } -psa_status_t psa_save_persistent_key(const psa_core_key_attributes_t *attr, +psa_status_t psa_save_persistent_key(const psa_key_attributes_t *attr, const uint8_t *data, const size_t data_length) { @@ -352,7 +352,7 @@ void psa_free_persistent_key_data(uint8_t *key_data, size_t key_data_length) mbedtls_zeroize_and_free(key_data, key_data_length); } -psa_status_t psa_load_persistent_key(psa_core_key_attributes_t *attr, +psa_status_t psa_load_persistent_key(psa_key_attributes_t *attr, uint8_t **data, size_t *data_length) { diff --git a/library/psa_crypto_storage.h b/library/psa_crypto_storage.h index b6b5e154ad..f1ea265b42 100644 --- a/library/psa_crypto_storage.h +++ b/library/psa_crypto_storage.h @@ -93,7 +93,7 @@ int psa_is_key_present_in_storage(const mbedtls_svc_key_id_t key); * \retval #PSA_ERROR_DATA_INVALID \emptydescription * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription */ -psa_status_t psa_save_persistent_key(const psa_core_key_attributes_t *attr, +psa_status_t psa_save_persistent_key(const psa_key_attributes_t *attr, const uint8_t *data, const size_t data_length); @@ -123,7 +123,7 @@ psa_status_t psa_save_persistent_key(const psa_core_key_attributes_t *attr, * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription * \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription */ -psa_status_t psa_load_persistent_key(psa_core_key_attributes_t *attr, +psa_status_t psa_load_persistent_key(psa_key_attributes_t *attr, uint8_t **data, size_t *data_length); @@ -163,7 +163,7 @@ void psa_free_persistent_key_data(uint8_t *key_data, size_t key_data_length); */ void psa_format_key_data_for_storage(const uint8_t *data, const size_t data_length, - const psa_core_key_attributes_t *attr, + const psa_key_attributes_t *attr, uint8_t *storage_data); /** @@ -186,7 +186,7 @@ psa_status_t psa_parse_key_data_from_storage(const uint8_t *storage_data, size_t storage_data_length, uint8_t **key_data, size_t *key_data_length, - psa_core_key_attributes_t *attr); + psa_key_attributes_t *attr); #if defined(MBEDTLS_PSA_CRYPTO_SE_C) /** This symbol is defined if transaction support is required. */ From 7a5d9201c12e60ea7baf140040498770228241ef Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 28 Feb 2024 01:18:23 +0100 Subject: [PATCH 037/123] Get rid of intermediate full-attributes local variables Now that a key slot contains the full `psa_key_attributes_t, the temporary local variables holding a copy of core attributes read from the slot are no longer needed. Signed-off-by: Gilles Peskine --- library/psa_crypto.c | 144 +++++++++---------------------------------- 1 file changed, 29 insertions(+), 115 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index fe0114ff03..7046a31d58 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1324,10 +1324,7 @@ psa_status_t psa_export_key(mbedtls_svc_key_id_t key, return status; } - psa_key_attributes_t attributes = { - .core = slot->attr.core - }; - status = psa_driver_wrapper_export_key(&attributes, + status = psa_driver_wrapper_export_key(&slot->attr, slot->key.data, slot->key.bytes, data, data_size, data_length); @@ -1411,7 +1408,6 @@ psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key, psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - psa_key_attributes_t attributes; /* Reject a zero-length output buffer now, since this can never be a * valid key representation. This way we know that data must be a valid @@ -1437,11 +1433,8 @@ psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key, goto exit; } - attributes = (psa_key_attributes_t) { - .core = slot->attr.core - }; status = psa_driver_wrapper_export_public_key( - &attributes, slot->key.data, slot->key.bytes, + &slot->attr, slot->key.data, slot->key.bytes, data, data_size, data_length); exit: @@ -2372,7 +2365,6 @@ static psa_status_t psa_mac_setup(psa_mac_operation_t *operation, psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot = NULL; - psa_key_attributes_t attributes; /* A context must be freshly initialized before it can be set up. */ if (operation->id != 0) { @@ -2389,11 +2381,7 @@ static psa_status_t psa_mac_setup(psa_mac_operation_t *operation, goto exit; } - attributes = (psa_key_attributes_t) { - .core = slot->attr.core - }; - - status = psa_mac_finalize_alg_and_key_validation(alg, &attributes, + status = psa_mac_finalize_alg_and_key_validation(alg, &slot->attr, &operation->mac_size); if (status != PSA_SUCCESS) { goto exit; @@ -2403,13 +2391,13 @@ static psa_status_t psa_mac_setup(psa_mac_operation_t *operation, /* Dispatch the MAC setup call with validated input */ if (is_sign) { status = psa_driver_wrapper_mac_sign_setup(operation, - &attributes, + &slot->attr, slot->key.data, slot->key.bytes, alg); } else { status = psa_driver_wrapper_mac_verify_setup(operation, - &attributes, + &slot->attr, slot->key.data, slot->key.bytes, alg); @@ -2559,7 +2547,6 @@ static psa_status_t psa_mac_compute_internal(mbedtls_svc_key_id_t key, psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; uint8_t operation_mac_size = 0; - psa_key_attributes_t attributes; status = psa_get_and_lock_key_slot_with_policy( key, @@ -2570,11 +2557,7 @@ static psa_status_t psa_mac_compute_internal(mbedtls_svc_key_id_t key, goto exit; } - attributes = (psa_key_attributes_t) { - .core = slot->attr.core - }; - - status = psa_mac_finalize_alg_and_key_validation(alg, &attributes, + status = psa_mac_finalize_alg_and_key_validation(alg, &slot->attr, &operation_mac_size); if (status != PSA_SUCCESS) { goto exit; @@ -2586,7 +2569,7 @@ static psa_status_t psa_mac_compute_internal(mbedtls_svc_key_id_t key, } status = psa_driver_wrapper_mac_compute( - &attributes, + &slot->attr, slot->key.data, slot->key.bytes, alg, input, input_length, @@ -2696,7 +2679,6 @@ static psa_status_t psa_sign_internal(mbedtls_svc_key_id_t key, psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - psa_key_attributes_t attributes; *signature_length = 0; @@ -2728,19 +2710,15 @@ static psa_status_t psa_sign_internal(mbedtls_svc_key_id_t key, goto exit; } - attributes = (psa_key_attributes_t) { - .core = slot->attr.core - }; - if (input_is_message) { status = psa_driver_wrapper_sign_message( - &attributes, slot->key.data, slot->key.bytes, + &slot->attr, slot->key.data, slot->key.bytes, alg, input, input_length, signature, signature_size, signature_length); } else { status = psa_driver_wrapper_sign_hash( - &attributes, slot->key.data, slot->key.bytes, + &slot->attr, slot->key.data, slot->key.bytes, alg, input, input_length, signature, signature_size, signature_length); } @@ -2782,18 +2760,14 @@ static psa_status_t psa_verify_internal(mbedtls_svc_key_id_t key, return status; } - psa_key_attributes_t attributes = { - .core = slot->attr.core - }; - if (input_is_message) { status = psa_driver_wrapper_verify_message( - &attributes, slot->key.data, slot->key.bytes, + &slot->attr, slot->key.data, slot->key.bytes, alg, input, input_length, signature, signature_length); } else { status = psa_driver_wrapper_verify_hash( - &attributes, slot->key.data, slot->key.bytes, + &slot->attr, slot->key.data, slot->key.bytes, alg, input, input_length, signature, signature_length); } @@ -3031,7 +3005,6 @@ psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key, psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - psa_key_attributes_t attributes; (void) input; (void) input_length; @@ -3056,12 +3029,8 @@ psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key, goto exit; } - attributes = (psa_key_attributes_t) { - .core = slot->attr.core - }; - status = psa_driver_wrapper_asymmetric_encrypt( - &attributes, slot->key.data, slot->key.bytes, + &slot->attr, slot->key.data, slot->key.bytes, alg, input, input_length, salt, salt_length, output, output_size, output_length); exit: @@ -3083,7 +3052,6 @@ psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key, psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - psa_key_attributes_t attributes; (void) input; (void) input_length; @@ -3107,12 +3075,8 @@ psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key, goto exit; } - attributes = (psa_key_attributes_t) { - .core = slot->attr.core - }; - status = psa_driver_wrapper_asymmetric_decrypt( - &attributes, slot->key.data, slot->key.bytes, + &slot->attr, slot->key.data, slot->key.bytes, alg, input, input_length, salt, salt_length, output, output_size, output_length); @@ -3181,7 +3145,6 @@ psa_status_t psa_sign_hash_start( psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - psa_key_attributes_t attributes; /* Check that start has not been previously called, or operation has not * previously errored. */ @@ -3208,14 +3171,10 @@ psa_status_t psa_sign_hash_start( goto exit; } - attributes = (psa_key_attributes_t) { - .core = slot->attr.core - }; - /* Ensure ops count gets reset, in case of operation re-use. */ operation->num_ops = 0; - status = psa_driver_wrapper_sign_hash_start(operation, &attributes, + status = psa_driver_wrapper_sign_hash_start(operation, &slot->attr, slot->key.data, slot->key.bytes, alg, hash, hash_length); @@ -3353,14 +3312,10 @@ psa_status_t psa_verify_hash_start( return status; } - psa_key_attributes_t attributes = { - .core = slot->attr.core - }; - /* Ensure ops count gets reset, in case of operation re-use. */ operation->num_ops = 0; - status = psa_driver_wrapper_verify_hash_start(operation, &attributes, + status = psa_driver_wrapper_verify_hash_start(operation, &slot->attr, slot->key.data, slot->key.bytes, alg, hash, hash_length, @@ -3889,7 +3844,6 @@ static psa_status_t psa_cipher_setup(psa_cipher_operation_t *operation, psa_key_usage_t usage = (cipher_operation == MBEDTLS_ENCRYPT ? PSA_KEY_USAGE_ENCRYPT : PSA_KEY_USAGE_DECRYPT); - psa_key_attributes_t attributes; /* A context must be freshly initialized before it can be set up. */ if (operation->id != 0) { @@ -3919,20 +3873,16 @@ static psa_status_t psa_cipher_setup(psa_cipher_operation_t *operation, } operation->default_iv_length = PSA_CIPHER_IV_LENGTH(slot->attr.type, alg); - attributes = (psa_key_attributes_t) { - .core = slot->attr.core - }; - /* Try doing the operation through a driver before using software fallback. */ if (cipher_operation == MBEDTLS_ENCRYPT) { status = psa_driver_wrapper_cipher_encrypt_setup(operation, - &attributes, + &slot->attr, slot->key.data, slot->key.bytes, alg); } else { status = psa_driver_wrapper_cipher_decrypt_setup(operation, - &attributes, + &slot->attr, slot->key.data, slot->key.bytes, alg); @@ -4145,7 +4095,6 @@ psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, psa_key_slot_t *slot = NULL; uint8_t local_iv[PSA_CIPHER_IV_MAX_SIZE]; size_t default_iv_length = 0; - psa_key_attributes_t attributes; if (!PSA_ALG_IS_CIPHER(alg)) { status = PSA_ERROR_INVALID_ARGUMENT; @@ -4159,10 +4108,6 @@ psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, goto exit; } - attributes = (psa_key_attributes_t) { - .core = slot->attr.core - }; - default_iv_length = PSA_CIPHER_IV_LENGTH(slot->attr.type, alg); if (default_iv_length > PSA_CIPHER_IV_MAX_SIZE) { status = PSA_ERROR_GENERIC_ERROR; @@ -4182,7 +4127,7 @@ psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, } status = psa_driver_wrapper_cipher_encrypt( - &attributes, slot->key.data, slot->key.bytes, + &slot->attr, slot->key.data, slot->key.bytes, alg, local_iv, default_iv_length, input, input_length, psa_crypto_buffer_offset(output, default_iv_length), output_size - default_iv_length, output_length); @@ -4216,7 +4161,6 @@ psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key, psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot = NULL; - psa_key_attributes_t attributes; if (!PSA_ALG_IS_CIPHER(alg)) { status = PSA_ERROR_INVALID_ARGUMENT; @@ -4230,10 +4174,6 @@ psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key, goto exit; } - attributes = (psa_key_attributes_t) { - .core = slot->attr.core - }; - if (alg == PSA_ALG_CCM_STAR_NO_TAG && input_length < PSA_BLOCK_CIPHER_BLOCK_LENGTH(slot->attr.type)) { status = PSA_ERROR_INVALID_ARGUMENT; @@ -4244,7 +4184,7 @@ psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key, } status = psa_driver_wrapper_cipher_decrypt( - &attributes, slot->key.data, slot->key.bytes, + &slot->attr, slot->key.data, slot->key.bytes, alg, input, input_length, output, output_size, output_length); @@ -4353,17 +4293,13 @@ psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key, return status; } - psa_key_attributes_t attributes = { - .core = slot->attr.core - }; - status = psa_aead_check_nonce_length(alg, nonce_length); if (status != PSA_SUCCESS) { goto exit; } status = psa_driver_wrapper_aead_encrypt( - &attributes, slot->key.data, slot->key.bytes, + &slot->attr, slot->key.data, slot->key.bytes, alg, nonce, nonce_length, additional_data, additional_data_length, @@ -4408,17 +4344,13 @@ psa_status_t psa_aead_decrypt(mbedtls_svc_key_id_t key, return status; } - psa_key_attributes_t attributes = { - .core = slot->attr.core - }; - status = psa_aead_check_nonce_length(alg, nonce_length); if (status != PSA_SUCCESS) { goto exit; } status = psa_driver_wrapper_aead_decrypt( - &attributes, slot->key.data, slot->key.bytes, + &slot->attr, slot->key.data, slot->key.bytes, alg, nonce, nonce_length, additional_data, additional_data_length, @@ -4484,7 +4416,6 @@ static psa_status_t psa_aead_setup(psa_aead_operation_t *operation, psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot = NULL; psa_key_usage_t key_usage = 0; - psa_key_attributes_t attributes; status = psa_aead_check_algorithm(alg); if (status != PSA_SUCCESS) { @@ -4514,23 +4445,19 @@ static psa_status_t psa_aead_setup(psa_aead_operation_t *operation, goto exit; } - attributes = (psa_key_attributes_t) { - .core = slot->attr.core - }; - if ((status = psa_validate_tag_length(alg)) != PSA_SUCCESS) { goto exit; } if (is_encrypt) { status = psa_driver_wrapper_aead_encrypt_setup(operation, - &attributes, + &slot->attr, slot->key.data, slot->key.bytes, alg); } else { status = psa_driver_wrapper_aead_decrypt_setup(operation, - &attributes, + &slot->attr, slot->key.data, slot->key.bytes, alg); @@ -4539,7 +4466,7 @@ static psa_status_t psa_aead_setup(psa_aead_operation_t *operation, goto exit; } - operation->key_type = psa_get_key_type(&attributes); + operation->key_type = psa_get_key_type(&slot->attr); exit: unlock_status = psa_unregister_read_under_mutex(slot); @@ -5842,7 +5769,6 @@ static psa_status_t psa_generate_derived_key_internal( size_t bytes = PSA_BITS_TO_BYTES(bits); size_t storage_size = bytes; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_attributes_t attributes; if (PSA_KEY_TYPE_IS_PUBLIC_KEY(slot->attr.type)) { return PSA_ERROR_INVALID_ARGUMENT; @@ -5891,12 +5817,9 @@ static psa_status_t psa_generate_derived_key_internal( } slot->attr.bits = (psa_key_bits_t) bits; - attributes = (psa_key_attributes_t) { - .core = slot->attr.core - }; - if (psa_key_lifetime_is_external(attributes.core.lifetime)) { - status = psa_driver_wrapper_get_key_buffer_size(&attributes, + if (psa_key_lifetime_is_external(slot->attr.core.lifetime)) { + status = psa_driver_wrapper_get_key_buffer_size(&slot->attr, &storage_size); if (status != PSA_SUCCESS) { goto exit; @@ -5907,7 +5830,7 @@ static psa_status_t psa_generate_derived_key_internal( goto exit; } - status = psa_driver_wrapper_import_key(&attributes, + status = psa_driver_wrapper_import_key(&slot->attr, data, bytes, slot->key.data, slot->key.bytes, @@ -7023,11 +6946,7 @@ static psa_status_t psa_key_agreement_raw_internal(psa_algorithm_t alg, return PSA_ERROR_NOT_SUPPORTED; } - psa_key_attributes_t attributes = { - .core = private_key->attr.core - }; - - return psa_driver_wrapper_key_agreement(&attributes, + return psa_driver_wrapper_key_agreement(&private_key->attr, private_key->key.data, private_key->key.bytes, alg, peer_key, peer_key_length, @@ -7823,7 +7742,6 @@ psa_status_t psa_pake_set_password_key( psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot = NULL; - psa_key_attributes_t attributes; psa_key_type_t type; if (operation->stage != PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) { @@ -7838,11 +7756,7 @@ psa_status_t psa_pake_set_password_key( goto exit; } - attributes = (psa_key_attributes_t) { - .core = slot->attr.core - }; - - type = psa_get_key_type(&attributes); + type = psa_get_key_type(&slot->attr); if (type != PSA_KEY_TYPE_PASSWORD && type != PSA_KEY_TYPE_PASSWORD_HASH) { From 2f107ae000c31ddddf4f941dcf782ca7deab0f8c Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 28 Feb 2024 01:26:46 +0100 Subject: [PATCH 038/123] Don't access psa_key_attributes_t.core Access the fields of `psa_key_attributes_t` directly rather than through the `core` field. This makes the `core` field obsolete. This commit is fully automated: ``` git ls-files '*.h' '*.c' '*.function' '*.jinja' | xargs perl -l -i -pe '$core = qr/\b(core\b|MBEDTLS_PRIVATE\(core\))/; s/->$core\./->/g; s/&(\w+)\.$core\./&$1./g; s/(\w+)\.$core/$1/g' ``` Signed-off-by: Gilles Peskine --- include/psa/crypto_extra.h | 10 +-- include/psa/crypto_struct.h | 36 ++++----- library/psa_crypto.c | 74 +++++++++---------- library/psa_crypto_aead.c | 8 +- library/psa_crypto_cipher.c | 4 +- library/psa_crypto_ecp.c | 30 ++++---- library/psa_crypto_ffdh.c | 6 +- library/psa_crypto_rsa.c | 22 +++--- tests/src/drivers/test_driver_signature.c | 8 +- ...t_suite_psa_crypto_persistent_key.function | 4 +- ...st_suite_psa_crypto_se_driver_hal.function | 2 +- ...te_psa_crypto_se_driver_hal_mocks.function | 24 +++--- ..._suite_psa_crypto_slot_management.function | 4 +- 13 files changed, 116 insertions(+), 116 deletions(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index 388e829040..d94e946f4c 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -59,7 +59,7 @@ static inline void psa_set_key_enrollment_algorithm( psa_key_attributes_t *attributes, psa_algorithm_t alg2) { - attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2) = alg2; + attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2) = alg2; } /** Retrieve the enrollment algorithm policy from key attributes. @@ -71,7 +71,7 @@ static inline void psa_set_key_enrollment_algorithm( static inline psa_algorithm_t psa_get_key_enrollment_algorithm( const psa_key_attributes_t *attributes) { - return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2); + return attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2); } #if defined(MBEDTLS_PSA_CRYPTO_SE_C) @@ -129,8 +129,8 @@ static inline void psa_set_key_slot_number( psa_key_attributes_t *attributes, psa_key_slot_number_t slot_number) { - attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(flags) |= MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER; - attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(slot_number) = slot_number; + attributes->MBEDTLS_PRIVATE(flags) |= MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER; + attributes->MBEDTLS_PRIVATE(slot_number) = slot_number; } /** Remove the slot number attribute from a key attribute structure. @@ -142,7 +142,7 @@ static inline void psa_set_key_slot_number( static inline void psa_clear_key_slot_number( psa_key_attributes_t *attributes) { - attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(flags) &= + attributes->MBEDTLS_PRIVATE(flags) &= ~MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER; } diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index e4d85be9bf..db85a1ab15 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -362,12 +362,12 @@ static inline struct psa_key_attributes_s psa_key_attributes_init(void) static inline void psa_set_key_id(psa_key_attributes_t *attributes, mbedtls_svc_key_id_t key) { - psa_key_lifetime_t lifetime = attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime); + psa_key_lifetime_t lifetime = attributes->MBEDTLS_PRIVATE(lifetime); - attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id) = key; + attributes->MBEDTLS_PRIVATE(id) = key; if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) { - attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime) = + attributes->MBEDTLS_PRIVATE(lifetime) = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( PSA_KEY_LIFETIME_PERSISTENT, PSA_KEY_LIFETIME_GET_LOCATION(lifetime)); @@ -377,26 +377,26 @@ static inline void psa_set_key_id(psa_key_attributes_t *attributes, static inline mbedtls_svc_key_id_t psa_get_key_id( const psa_key_attributes_t *attributes) { - return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id); + return attributes->MBEDTLS_PRIVATE(id); } #ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER static inline void mbedtls_set_key_owner_id(psa_key_attributes_t *attributes, mbedtls_key_owner_id_t owner) { - attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(owner) = owner; + attributes->MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(owner) = owner; } #endif static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes, psa_key_lifetime_t lifetime) { - attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime) = lifetime; + attributes->MBEDTLS_PRIVATE(lifetime) = lifetime; if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) { #ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER - attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(key_id) = 0; + attributes->MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(key_id) = 0; #else - attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id) = 0; + attributes->MBEDTLS_PRIVATE(id) = 0; #endif } } @@ -404,7 +404,7 @@ static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes, static inline psa_key_lifetime_t psa_get_key_lifetime( const psa_key_attributes_t *attributes) { - return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime); + return attributes->MBEDTLS_PRIVATE(lifetime); } static inline void psa_extend_key_usage_flags(psa_key_usage_t *usage_flags) @@ -422,53 +422,53 @@ static inline void psa_set_key_usage_flags(psa_key_attributes_t *attributes, psa_key_usage_t usage_flags) { psa_extend_key_usage_flags(&usage_flags); - attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage) = usage_flags; + attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage) = usage_flags; } static inline psa_key_usage_t psa_get_key_usage_flags( const psa_key_attributes_t *attributes) { - return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage); + return attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage); } static inline void psa_set_key_algorithm(psa_key_attributes_t *attributes, psa_algorithm_t alg) { - attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg) = alg; + attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg) = alg; } static inline psa_algorithm_t psa_get_key_algorithm( const psa_key_attributes_t *attributes) { - return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg); + return attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg); } static inline void psa_set_key_type(psa_key_attributes_t *attributes, psa_key_type_t type) { - attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(type) = type; + attributes->MBEDTLS_PRIVATE(type) = type; } static inline psa_key_type_t psa_get_key_type( const psa_key_attributes_t *attributes) { - return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(type); + return attributes->MBEDTLS_PRIVATE(type); } static inline void psa_set_key_bits(psa_key_attributes_t *attributes, size_t bits) { if (bits > PSA_MAX_KEY_BITS) { - attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits) = PSA_KEY_BITS_TOO_LARGE; + attributes->MBEDTLS_PRIVATE(bits) = PSA_KEY_BITS_TOO_LARGE; } else { - attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits) = (psa_key_bits_t) bits; + attributes->MBEDTLS_PRIVATE(bits) = (psa_key_bits_t) bits; } } static inline size_t psa_get_key_bits( const psa_key_attributes_t *attributes) { - return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits); + return attributes->MBEDTLS_PRIVATE(bits); } /** diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 7046a31d58..71535fa914 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -568,7 +568,7 @@ psa_status_t psa_import_key_into_slot( size_t *key_buffer_length, size_t *bits) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_type_t type = attributes->core.type; + psa_key_type_t type = attributes->type; /* zero-length keys are never supported. */ if (data_length == 0) { @@ -578,7 +578,7 @@ psa_status_t psa_import_key_into_slot( if (key_type_is_raw_bytes(type)) { *bits = PSA_BYTES_TO_BITS(data_length); - status = psa_validate_unstructured_key_bit_size(attributes->core.type, + status = psa_validate_unstructured_key_bit_size(attributes->type, *bits); if (status != PSA_SUCCESS) { return status; @@ -1245,8 +1245,8 @@ psa_status_t psa_get_key_slot_number( const psa_key_attributes_t *attributes, psa_key_slot_number_t *slot_number) { - if (attributes->core.flags & MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER) { - *slot_number = attributes->core.slot_number; + if (attributes->flags & MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER) { + *slot_number = attributes->slot_number; return PSA_SUCCESS; } else { return PSA_ERROR_INVALID_ARGUMENT; @@ -1275,7 +1275,7 @@ psa_status_t psa_export_key_internal( const uint8_t *key_buffer, size_t key_buffer_size, uint8_t *data, size_t data_size, size_t *data_length) { - psa_key_type_t type = attributes->core.type; + psa_key_type_t type = attributes->type; if (key_type_is_raw_bytes(type) || PSA_KEY_TYPE_IS_RSA(type) || @@ -1341,7 +1341,7 @@ psa_status_t psa_export_public_key_internal( size_t data_size, size_t *data_length) { - psa_key_type_t type = attributes->core.type; + psa_key_type_t type = attributes->type; if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) && (PSA_KEY_TYPE_IS_RSA(type) || PSA_KEY_TYPE_IS_ECC(type) || @@ -1518,7 +1518,7 @@ static psa_status_t psa_validate_key_attributes( } } - status = psa_validate_key_policy(&attributes->core.policy); + status = psa_validate_key_policy(&attributes->policy); if (status != PSA_SUCCESS) { return status; } @@ -1532,7 +1532,7 @@ static psa_status_t psa_validate_key_attributes( } /* Reject invalid flags. These should not be reachable through the API. */ - if (attributes->core.flags & ~(MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY | + if (attributes->flags & ~(MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY | MBEDTLS_PSA_KA_MASK_DUAL_USE)) { return PSA_ERROR_INVALID_ARGUMENT; } @@ -1652,7 +1652,7 @@ static psa_status_t psa_start_key_creation( return status; } - if (!PSA_KEY_LIFETIME_IS_VOLATILE(attributes->core.lifetime)) { + if (!PSA_KEY_LIFETIME_IS_VOLATILE(attributes->lifetime)) { psa_crypto_prepare_transaction(PSA_CRYPTO_TRANSACTION_CREATE_KEY); psa_crypto_transaction.key.lifetime = slot->attr.lifetime; psa_crypto_transaction.key.slot = slot_number; @@ -1852,14 +1852,14 @@ static psa_status_t psa_validate_optional_attributes( const psa_key_slot_t *slot, const psa_key_attributes_t *attributes) { - if (attributes->core.type != 0) { - if (attributes->core.type != slot->attr.type) { + if (attributes->type != 0) { + if (attributes->type != slot->attr.type) { return PSA_ERROR_INVALID_ARGUMENT; } } - if (attributes->core.bits != 0) { - if (attributes->core.bits != slot->attr.bits) { + if (attributes->bits != 0) { + if (attributes->bits != slot->attr.bits) { return PSA_ERROR_INVALID_ARGUMENT; } } @@ -1903,7 +1903,7 @@ psa_status_t psa_import_key(const psa_key_attributes_t *attributes, * with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a * buffer to hold the imported key material. */ if (slot->key.data == NULL) { - if (psa_key_lifetime_is_external(attributes->core.lifetime)) { + if (psa_key_lifetime_is_external(attributes->lifetime)) { status = psa_driver_wrapper_get_key_buffer_size_from_key_data( attributes, data, data_length, &storage_size); if (status != PSA_SUCCESS) { @@ -2023,12 +2023,12 @@ psa_status_t psa_copy_key(mbedtls_svc_key_id_t source_key, * equal to the ones of the source key. So it is safe to inherit * them from the source key now." * */ - actual_attributes.core.bits = source_slot->attr.bits; - actual_attributes.core.type = source_slot->attr.type; + actual_attributes.bits = source_slot->attr.bits; + actual_attributes.type = source_slot->attr.type; status = psa_restrict_key_policy(source_slot->attr.type, - &actual_attributes.core.policy, + &actual_attributes.policy, &source_slot->attr.policy); if (status != PSA_SUCCESS) { goto exit; @@ -2057,7 +2057,7 @@ psa_status_t psa_copy_key(mbedtls_svc_key_id_t source_key, * - For opaque keys this translates to an invocation of the drivers' * copy_key entry point through the dispatch layer. * */ - if (psa_key_lifetime_is_external(actual_attributes.core.lifetime)) { + if (psa_key_lifetime_is_external(actual_attributes.lifetime)) { status = psa_driver_wrapper_get_key_buffer_size(&actual_attributes, &storage_size); if (status != PSA_SUCCESS) { @@ -2878,7 +2878,7 @@ psa_status_t psa_sign_hash_builtin( psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, uint8_t *signature, size_t signature_size, size_t *signature_length) { - if (attributes->core.type == PSA_KEY_TYPE_RSA_KEY_PAIR) { + if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) { if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || PSA_ALG_IS_RSA_PSS(alg)) { #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \ @@ -2893,7 +2893,7 @@ psa_status_t psa_sign_hash_builtin( } else { return PSA_ERROR_INVALID_ARGUMENT; } - } else if (PSA_KEY_TYPE_IS_ECC(attributes->core.type)) { + } else if (PSA_KEY_TYPE_IS_ECC(attributes->type)) { if (PSA_ALG_IS_ECDSA(alg)) { #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) @@ -2939,7 +2939,7 @@ psa_status_t psa_verify_hash_builtin( psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, const uint8_t *signature, size_t signature_length) { - if (PSA_KEY_TYPE_IS_RSA(attributes->core.type)) { + if (PSA_KEY_TYPE_IS_RSA(attributes->type)) { if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || PSA_ALG_IS_RSA_PSS(alg)) { #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \ @@ -2954,7 +2954,7 @@ psa_status_t psa_verify_hash_builtin( } else { return PSA_ERROR_INVALID_ARGUMENT; } - } else if (PSA_KEY_TYPE_IS_ECC(attributes->core.type)) { + } else if (PSA_KEY_TYPE_IS_ECC(attributes->type)) { if (PSA_ALG_IS_ECDSA(alg)) { #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) @@ -3450,7 +3450,7 @@ psa_status_t mbedtls_psa_sign_hash_start( psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t required_hash_length; - if (!PSA_KEY_TYPE_IS_ECC(attributes->core.type)) { + if (!PSA_KEY_TYPE_IS_ECC(attributes->type)) { return PSA_ERROR_NOT_SUPPORTED; } @@ -3467,8 +3467,8 @@ psa_status_t mbedtls_psa_sign_hash_start( /* Ensure num_ops is zero'ed in case of context re-use. */ operation->num_ops = 0; - status = mbedtls_psa_ecp_load_representation(attributes->core.type, - attributes->core.bits, + status = mbedtls_psa_ecp_load_representation(attributes->type, + attributes->bits, key_buffer, key_buffer_size, &operation->ctx); @@ -3666,7 +3666,7 @@ psa_status_t mbedtls_psa_verify_hash_start( size_t coordinate_bytes = 0; size_t required_hash_length = 0; - if (!PSA_KEY_TYPE_IS_ECC(attributes->core.type)) { + if (!PSA_KEY_TYPE_IS_ECC(attributes->type)) { return PSA_ERROR_NOT_SUPPORTED; } @@ -3685,8 +3685,8 @@ psa_status_t mbedtls_psa_verify_hash_start( /* Ensure num_ops is zero'ed in case of context re-use. */ operation->num_ops = 0; - status = mbedtls_psa_ecp_load_representation(attributes->core.type, - attributes->core.bits, + status = mbedtls_psa_ecp_load_representation(attributes->type, + attributes->bits, key_buffer, key_buffer_size, &operation->ctx); @@ -5818,7 +5818,7 @@ static psa_status_t psa_generate_derived_key_internal( slot->attr.bits = (psa_key_bits_t) bits; - if (psa_key_lifetime_is_external(slot->attr.core.lifetime)) { + if (psa_key_lifetime_is_external(slot->attr.lifetime)) { status = psa_driver_wrapper_get_key_buffer_size(&slot->attr, &storage_size); if (status != PSA_SUCCESS) { @@ -5901,7 +5901,7 @@ psa_status_t psa_key_derivation_output_key_ext( #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ if (status == PSA_SUCCESS) { status = psa_generate_derived_key_internal(slot, - attributes->core.bits, + attributes->bits, operation); } if (status == PSA_SUCCESS) { @@ -7319,7 +7319,7 @@ psa_status_t psa_generate_key_internal( uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_type_t type = attributes->core.type; + psa_key_type_t type = attributes->type; /* Only used for RSA */ (void) params; @@ -7392,12 +7392,12 @@ psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, } /* Reject any attempt to create a public key. */ - if (PSA_KEY_TYPE_IS_PUBLIC_KEY(attributes->core.type)) { + if (PSA_KEY_TYPE_IS_PUBLIC_KEY(attributes->type)) { return PSA_ERROR_INVALID_ARGUMENT; } #if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) - if (attributes->core.type == PSA_KEY_TYPE_RSA_KEY_PAIR) { + if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) { if (params->flags != 0) { return PSA_ERROR_INVALID_ARGUMENT; } @@ -7418,17 +7418,17 @@ psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, * with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a * buffer to hold the generated key material. */ if (slot->key.data == NULL) { - if (PSA_KEY_LIFETIME_GET_LOCATION(attributes->core.lifetime) == + if (PSA_KEY_LIFETIME_GET_LOCATION(attributes->lifetime) == PSA_KEY_LOCATION_LOCAL_STORAGE) { status = psa_validate_key_type_and_size_for_key_generation( - attributes->core.type, attributes->core.bits); + attributes->type, attributes->bits); if (status != PSA_SUCCESS) { goto exit; } key_buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE( - attributes->core.type, - attributes->core.bits); + attributes->type, + attributes->bits); } else { status = psa_driver_wrapper_get_key_buffer_size( attributes, &key_buffer_size); diff --git a/library/psa_crypto_aead.c b/library/psa_crypto_aead.c index 49aa96193b..a201985b4f 100644 --- a/library/psa_crypto_aead.c +++ b/library/psa_crypto_aead.c @@ -33,10 +33,10 @@ static psa_status_t psa_aead_setup( psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; mbedtls_cipher_id_t cipher_id; mbedtls_cipher_mode_t mode; - size_t key_bits = attributes->core.bits; + size_t key_bits = attributes->bits; (void) key_buffer_size; - status = mbedtls_cipher_values_from_psa(alg, attributes->core.type, + status = mbedtls_cipher_values_from_psa(alg, attributes->type, &key_bits, &mode, &cipher_id); if (status != PSA_SUCCESS) { return status; @@ -49,7 +49,7 @@ static psa_status_t psa_aead_setup( /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16. * The call to mbedtls_ccm_encrypt_and_tag or * mbedtls_ccm_auth_decrypt will validate the tag length. */ - if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->core.type) != 16) { + if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) { return PSA_ERROR_INVALID_ARGUMENT; } @@ -69,7 +69,7 @@ static psa_status_t psa_aead_setup( /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16. * The call to mbedtls_gcm_crypt_and_tag or * mbedtls_gcm_auth_decrypt will validate the tag length. */ - if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->core.type) != 16) { + if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) { return PSA_ERROR_INVALID_ARGUMENT; } diff --git a/library/psa_crypto_cipher.c b/library/psa_crypto_cipher.c index 313285480b..a45fb0f09c 100644 --- a/library/psa_crypto_cipher.c +++ b/library/psa_crypto_cipher.c @@ -289,14 +289,14 @@ static psa_status_t psa_cipher_setup( int ret = 0; size_t key_bits; const mbedtls_cipher_info_t *cipher_info = NULL; - psa_key_type_t key_type = attributes->core.type; + psa_key_type_t key_type = attributes->type; (void) key_buffer_size; mbedtls_cipher_init(&operation->ctx.cipher); operation->alg = alg; - key_bits = attributes->core.bits; + key_bits = attributes->bits; cipher_info = mbedtls_cipher_info_from_psa(alg, key_type, key_bits, NULL); if (cipher_info == NULL) { diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c index 7edea81646..9d583aa376 100644 --- a/library/psa_crypto_ecp.c +++ b/library/psa_crypto_ecp.c @@ -216,8 +216,8 @@ psa_status_t mbedtls_psa_ecp_import_key( mbedtls_ecp_keypair *ecp = NULL; /* Parse input */ - status = mbedtls_psa_ecp_load_representation(attributes->core.type, - attributes->core.bits, + status = mbedtls_psa_ecp_load_representation(attributes->type, + attributes->bits, data, data_length, &ecp); @@ -225,7 +225,7 @@ psa_status_t mbedtls_psa_ecp_import_key( goto exit; } - if (PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) == + if (PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type) == PSA_ECC_FAMILY_MONTGOMERY) { *bits = ecp->grp.nbits + 1; } else { @@ -235,7 +235,7 @@ psa_status_t mbedtls_psa_ecp_import_key( /* Re-export the data to PSA export format. There is currently no support * for other input formats then the export format, so this is a 1-1 * copy operation. */ - status = mbedtls_psa_ecp_export_key(attributes->core.type, + status = mbedtls_psa_ecp_export_key(attributes->type, ecp, key_buffer, key_buffer_size, @@ -308,7 +308,7 @@ psa_status_t mbedtls_psa_ecp_export_public_key( mbedtls_ecp_keypair *ecp = NULL; status = mbedtls_psa_ecp_load_representation( - attributes->core.type, attributes->core.bits, + attributes->type, attributes->bits, key_buffer, key_buffer_size, &ecp); if (status != PSA_SUCCESS) { return status; @@ -316,7 +316,7 @@ psa_status_t mbedtls_psa_ecp_export_public_key( status = mbedtls_psa_ecp_export_key( PSA_KEY_TYPE_ECC_PUBLIC_KEY( - PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type)), + PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type)), ecp, data, data_size, data_length); mbedtls_ecp_keypair_free(ecp); @@ -337,9 +337,9 @@ psa_status_t mbedtls_psa_ecp_generate_key( int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( - attributes->core.type); + attributes->type); mbedtls_ecp_group_id grp_id = - mbedtls_ecc_group_from_psa(curve, attributes->core.bits); + mbedtls_ecc_group_from_psa(curve, attributes->bits); const mbedtls_ecp_curve_info *curve_info = mbedtls_ecp_curve_info_from_grp_id(grp_id); @@ -389,8 +389,8 @@ psa_status_t mbedtls_psa_ecdsa_sign_hash( size_t curve_bytes; mbedtls_mpi r, s; - status = mbedtls_psa_ecp_load_representation(attributes->core.type, - attributes->core.bits, + status = mbedtls_psa_ecp_load_representation(attributes->type, + attributes->bits, key_buffer, key_buffer_size, &ecp); @@ -476,8 +476,8 @@ psa_status_t mbedtls_psa_ecdsa_verify_hash( (void) alg; - status = mbedtls_psa_ecp_load_representation(attributes->core.type, - attributes->core.bits, + status = mbedtls_psa_ecp_load_representation(attributes->type, + attributes->bits, key_buffer, key_buffer_size, &ecp); @@ -541,14 +541,14 @@ psa_status_t mbedtls_psa_key_agreement_ecdh( size_t *shared_secret_length) { psa_status_t status; - if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->core.type) || + if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->type) || !PSA_ALG_IS_ECDH(alg)) { return PSA_ERROR_INVALID_ARGUMENT; } mbedtls_ecp_keypair *ecp = NULL; status = mbedtls_psa_ecp_load_representation( - attributes->core.type, - attributes->core.bits, + attributes->type, + attributes->bits, key_buffer, key_buffer_size, &ecp); diff --git a/library/psa_crypto_ffdh.c b/library/psa_crypto_ffdh.c index 0099d5f97c..ae38f6d7c6 100644 --- a/library/psa_crypto_ffdh.c +++ b/library/psa_crypto_ffdh.c @@ -151,7 +151,7 @@ psa_status_t mbedtls_psa_ffdh_export_public_key( int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; mbedtls_mpi GX, G, X, P; - psa_key_type_t type = attributes->core.type; + psa_key_type_t type = attributes->type; if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) { if (key_buffer_size > data_size) { @@ -167,7 +167,7 @@ psa_status_t mbedtls_psa_ffdh_export_public_key( mbedtls_mpi_init(&GX); mbedtls_mpi_init(&G); mbedtls_mpi_init(&X); mbedtls_mpi_init(&P); - size_t key_len = PSA_BITS_TO_BYTES(attributes->core.bits); + size_t key_len = PSA_BITS_TO_BYTES(attributes->bits); status = mbedtls_psa_ffdh_set_prime_generator(key_len, &P, &G); @@ -283,7 +283,7 @@ psa_status_t mbedtls_psa_ffdh_key_agreement( mbedtls_mpi_init(&K); status = mbedtls_psa_ffdh_set_prime_generator( - PSA_BITS_TO_BYTES(attributes->core.bits), &P, &G); + PSA_BITS_TO_BYTES(attributes->bits), &P, &G); if (status != PSA_SUCCESS) { goto cleanup; diff --git a/library/psa_crypto_rsa.c b/library/psa_crypto_rsa.c index 84a86679b3..2f613b32da 100644 --- a/library/psa_crypto_rsa.c +++ b/library/psa_crypto_rsa.c @@ -116,7 +116,7 @@ psa_status_t mbedtls_psa_rsa_import_key( mbedtls_rsa_context *rsa = NULL; /* Parse input */ - status = mbedtls_psa_rsa_load_representation(attributes->core.type, + status = mbedtls_psa_rsa_load_representation(attributes->type, data, data_length, &rsa); @@ -130,7 +130,7 @@ psa_status_t mbedtls_psa_rsa_import_key( * representation in the key slot. Export representation in case of RSA is * the smallest representation that's allowed as input, so a straight-up * allocation of the same size as the input buffer will be large enough. */ - status = mbedtls_psa_rsa_export_key(attributes->core.type, + status = mbedtls_psa_rsa_export_key(attributes->type, rsa, key_buffer, key_buffer_size, @@ -196,7 +196,7 @@ psa_status_t mbedtls_psa_rsa_export_public_key( mbedtls_rsa_context *rsa = NULL; status = mbedtls_psa_rsa_load_representation( - attributes->core.type, key_buffer, key_buffer_size, &rsa); + attributes->type, key_buffer, key_buffer_size, &rsa); if (status != PSA_SUCCESS) { return status; } @@ -261,13 +261,13 @@ psa_status_t mbedtls_psa_rsa_generate_key( ret = mbedtls_rsa_gen_key(&rsa, mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE, - (unsigned int) attributes->core.bits, + (unsigned int) attributes->bits, exponent); if (ret != 0) { return mbedtls_to_psa_error(ret); } - status = mbedtls_psa_rsa_export_key(attributes->core.type, + status = mbedtls_psa_rsa_export_key(attributes->type, &rsa, key_buffer, key_buffer_size, key_buffer_length); mbedtls_rsa_free(&rsa); @@ -325,7 +325,7 @@ psa_status_t mbedtls_psa_rsa_sign_hash( int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; mbedtls_md_type_t md_alg; - status = mbedtls_psa_rsa_load_representation(attributes->core.type, + status = mbedtls_psa_rsa_load_representation(attributes->type, key_buffer, key_buffer_size, &rsa); @@ -424,7 +424,7 @@ psa_status_t mbedtls_psa_rsa_verify_hash( int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; mbedtls_md_type_t md_alg; - status = mbedtls_psa_rsa_load_representation(attributes->core.type, + status = mbedtls_psa_rsa_load_representation(attributes->type, key_buffer, key_buffer_size, &rsa); @@ -536,11 +536,11 @@ psa_status_t mbedtls_psa_asymmetric_encrypt(const psa_key_attributes_t *attribut (void) output_size; (void) output_length; - if (PSA_KEY_TYPE_IS_RSA(attributes->core.type)) { + if (PSA_KEY_TYPE_IS_RSA(attributes->type)) { #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \ defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) mbedtls_rsa_context *rsa = NULL; - status = mbedtls_psa_rsa_load_representation(attributes->core.type, + status = mbedtls_psa_rsa_load_representation(attributes->type, key_buffer, key_buffer_size, &rsa); @@ -632,11 +632,11 @@ psa_status_t mbedtls_psa_asymmetric_decrypt(const psa_key_attributes_t *attribut *output_length = 0; - if (attributes->core.type == PSA_KEY_TYPE_RSA_KEY_PAIR) { + if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) { #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \ defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) mbedtls_rsa_context *rsa = NULL; - status = mbedtls_psa_rsa_load_representation(attributes->core.type, + status = mbedtls_psa_rsa_load_representation(attributes->type, key_buffer, key_buffer_size, &rsa); diff --git a/tests/src/drivers/test_driver_signature.c b/tests/src/drivers/test_driver_signature.c index 00dd3e2673..4fca5d178d 100644 --- a/tests/src/drivers/test_driver_signature.c +++ b/tests/src/drivers/test_driver_signature.c @@ -49,7 +49,7 @@ psa_status_t sign_hash( size_t signature_size, size_t *signature_length) { - if (attributes->core.type == PSA_KEY_TYPE_RSA_KEY_PAIR) { + if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) { if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || PSA_ALG_IS_RSA_PSS(alg)) { #if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \ @@ -71,7 +71,7 @@ psa_status_t sign_hash( } else { return PSA_ERROR_INVALID_ARGUMENT; } - } else if (PSA_KEY_TYPE_IS_ECC(attributes->core.type)) { + } else if (PSA_KEY_TYPE_IS_ECC(attributes->type)) { if (PSA_ALG_IS_ECDSA(alg)) { #if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \ (defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ @@ -116,7 +116,7 @@ psa_status_t verify_hash( const uint8_t *signature, size_t signature_length) { - if (PSA_KEY_TYPE_IS_RSA(attributes->core.type)) { + if (PSA_KEY_TYPE_IS_RSA(attributes->type)) { if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || PSA_ALG_IS_RSA_PSS(alg)) { #if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \ @@ -138,7 +138,7 @@ psa_status_t verify_hash( } else { return PSA_ERROR_INVALID_ARGUMENT; } - } else if (PSA_KEY_TYPE_IS_ECC(attributes->core.type)) { + } else if (PSA_KEY_TYPE_IS_ECC(attributes->type)) { if (PSA_ALG_IS_ECDSA(alg)) { #if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \ (defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function index c4e4c7dc05..ea8cb6bc8f 100644 --- a/tests/suites/test_suite_psa_crypto_persistent_key.function +++ b/tests/suites/test_suite_psa_crypto_persistent_key.function @@ -61,7 +61,7 @@ void format_storage_data_check(data_t *key_data, TEST_CALLOC(file_data, file_data_length); psa_format_key_data_for_storage(key_data->x, key_data->len, - &attributes.core, + &attributes, file_data); TEST_MEMORY_COMPARE(expected_file_data->x, expected_file_data->len, @@ -90,7 +90,7 @@ void parse_storage_data_check(data_t *file_data, status = psa_parse_key_data_from_storage(file_data->x, file_data->len, &key_data, &key_data_length, - &attributes.core); + &attributes); TEST_EQUAL(status, expected_status); if (status != PSA_SUCCESS) { diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal.function b/tests/suites/test_suite_psa_crypto_se_driver_hal.function index 8e96984439..e3681ba6e7 100644 --- a/tests/suites/test_suite_psa_crypto_se_driver_hal.function +++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.function @@ -952,7 +952,7 @@ void key_creation_import_export(int lifetime_arg, int min_slot, int restart) psa_set_key_slot_number(&attributes, min_slot); if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) { - attributes.core.id = returned_id; + attributes.id = returned_id; } else { psa_set_key_id(&attributes, returned_id); } diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function index 6f28f93e57..b6d3a3487d 100644 --- a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function +++ b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function @@ -359,19 +359,19 @@ void mock_import(int mock_alloc_return_value, if (mock_alloc_return_value == PSA_SUCCESS) { TEST_ASSERT(mbedtls_svc_key_id_equal( - mock_import_data.attributes.core.id, id)); + mock_import_data.attributes.id, id)); } else { TEST_ASSERT(MBEDTLS_SVC_KEY_ID_GET_KEY_ID( - mock_import_data.attributes.core.id) == 0); + mock_import_data.attributes.id) == 0); TEST_ASSERT(MBEDTLS_SVC_KEY_ID_GET_OWNER_ID( - mock_import_data.attributes.core.id) == 0); + mock_import_data.attributes.id) == 0); } - TEST_ASSERT(mock_import_data.attributes.core.lifetime == + TEST_ASSERT(mock_import_data.attributes.lifetime == (mock_alloc_return_value == PSA_SUCCESS ? lifetime : 0)); - TEST_ASSERT(mock_import_data.attributes.core.policy.usage == + TEST_ASSERT(mock_import_data.attributes.policy.usage == (mock_alloc_return_value == PSA_SUCCESS ? PSA_KEY_USAGE_EXPORT : 0)); - TEST_ASSERT(mock_import_data.attributes.core.type == + TEST_ASSERT(mock_import_data.attributes.type == (mock_alloc_return_value == PSA_SUCCESS ? PSA_KEY_TYPE_RAW_DATA : 0)); if (expected_result == PSA_SUCCESS) { @@ -474,19 +474,19 @@ void mock_generate(int mock_alloc_return_value, if (mock_alloc_return_value == PSA_SUCCESS) { TEST_ASSERT(mbedtls_svc_key_id_equal( - mock_generate_data.attributes.core.id, id)); + mock_generate_data.attributes.id, id)); } else { TEST_ASSERT(MBEDTLS_SVC_KEY_ID_GET_KEY_ID( - mock_generate_data.attributes.core.id) == 0); + mock_generate_data.attributes.id) == 0); TEST_ASSERT(MBEDTLS_SVC_KEY_ID_GET_OWNER_ID( - mock_generate_data.attributes.core.id) == 0); + mock_generate_data.attributes.id) == 0); } - TEST_ASSERT(mock_generate_data.attributes.core.lifetime == + TEST_ASSERT(mock_generate_data.attributes.lifetime == (mock_alloc_return_value == PSA_SUCCESS ? lifetime : 0)); - TEST_ASSERT(mock_generate_data.attributes.core.policy.usage == + TEST_ASSERT(mock_generate_data.attributes.policy.usage == (mock_alloc_return_value == PSA_SUCCESS ? PSA_KEY_USAGE_EXPORT : 0)); - TEST_ASSERT(mock_generate_data.attributes.core.type == + TEST_ASSERT(mock_generate_data.attributes.type == (mock_alloc_return_value == PSA_SUCCESS ? PSA_KEY_TYPE_RAW_DATA : 0)); if (expected_result == PSA_SUCCESS) { diff --git a/tests/suites/test_suite_psa_crypto_slot_management.function b/tests/suites/test_suite_psa_crypto_slot_management.function index 8564d352a4..94f26f6b42 100644 --- a/tests/suites/test_suite_psa_crypto_slot_management.function +++ b/tests/suites/test_suite_psa_crypto_slot_management.function @@ -458,7 +458,7 @@ void create_fail(int lifetime_arg, int id_arg, * PSA key attributes APIs thus accessing to the attributes * directly. */ - attributes.core.id = id; + attributes.id = id; } else { psa_set_key_id(&attributes, id); } @@ -992,7 +992,7 @@ void non_reusable_key_slots_integrity_in_case_of_key_slot_starvation() * Check that we can now access the persistent key again. */ PSA_ASSERT(psa_get_key_attributes(persistent_key, &attributes)); - TEST_ASSERT(mbedtls_svc_key_id_equal(attributes.core.id, + TEST_ASSERT(mbedtls_svc_key_id_equal(attributes.id, persistent_key)); /* From 2dc2bd70972710b44172007d560495d1191fb23b Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 28 Feb 2024 01:32:31 +0100 Subject: [PATCH 039/123] Get rid of psa_core_key_attributes_t The `psa_core_key_attributes_t` structure is no longer used. Remove it. Switch `psa_key_attributes_t` back to a simple struct, now containing the fields that were formerly inside its `psa_core_key_attributes_t core` member. This repairs the build with non-C11 compilers. Signed-off-by: Gilles Peskine --- include/psa/crypto_struct.h | 40 +++++-------------------------------- 1 file changed, 5 insertions(+), 35 deletions(-) diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index db85a1ab15..adb33ed214 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -289,33 +289,7 @@ typedef uint16_t psa_key_attributes_flag_t; #define MBEDTLS_PSA_KA_MASK_DUAL_USE ( \ 0) -typedef struct { -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - psa_key_slot_number_t MBEDTLS_PRIVATE(slot_number); -#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - psa_key_type_t MBEDTLS_PRIVATE(type); - psa_key_bits_t MBEDTLS_PRIVATE(bits); - psa_key_lifetime_t MBEDTLS_PRIVATE(lifetime); - psa_key_policy_t MBEDTLS_PRIVATE(policy); - psa_key_attributes_flag_t MBEDTLS_PRIVATE(flags); - /* This type has a different layout in the client view wrt the - * service view of the key id, i.e. in service view usually is - * expected to have MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined - * thus adding an owner field to the standard psa_key_id_t. For - * implementations with client/service separation, this means the - * object will be marshalled through a transport channel and - * interpreted differently at each side of the transport. Placing - * it at the end of structures allows to interpret the structure - * at the client without reorganizing the memory layout of the - * struct - */ - mbedtls_svc_key_id_t MBEDTLS_PRIVATE(id); -} psa_core_key_attributes_t; - struct psa_key_attributes_s { - union { - psa_core_key_attributes_t MBEDTLS_PRIVATE(core); - struct { #if defined(MBEDTLS_PSA_CRYPTO_SE_C) psa_key_slot_number_t MBEDTLS_PRIVATE(slot_number); #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ @@ -336,8 +310,6 @@ struct psa_key_attributes_s { * struct */ mbedtls_svc_key_id_t MBEDTLS_PRIVATE(id); - }; - }; }; #if defined(MBEDTLS_PSA_CRYPTO_SE_C) @@ -345,13 +317,11 @@ struct psa_key_attributes_s { #else #define PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER #endif -#define PSA_CORE_KEY_ATTRIBUTES_INIT { PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER \ - PSA_KEY_TYPE_NONE, 0, \ - PSA_KEY_LIFETIME_VOLATILE, \ - PSA_KEY_POLICY_INIT, 0, \ - MBEDTLS_SVC_KEY_ID_INIT } - -#define PSA_KEY_ATTRIBUTES_INIT { { PSA_CORE_KEY_ATTRIBUTES_INIT } } +#define PSA_KEY_ATTRIBUTES_INIT { PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER \ + PSA_KEY_TYPE_NONE, 0, \ + PSA_KEY_LIFETIME_VOLATILE, \ + PSA_KEY_POLICY_INIT, 0, \ + MBEDTLS_SVC_KEY_ID_INIT } static inline struct psa_key_attributes_s psa_key_attributes_init(void) { From 972539c2418c751d5974717c097d8667a16c7e5f Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 28 Feb 2024 01:49:45 +0100 Subject: [PATCH 040/123] In attributes, keep track of slot number through a dedicated field In `psa_key_attributes_t`, keep track of whether `slot_number` has been set through a dedicated field, rather than using a flag. This paves the way to removing `flags`, which is not used for anything else. Signed-off-by: Gilles Peskine --- include/psa/crypto_extra.h | 5 ++--- include/psa/crypto_struct.h | 3 ++- library/psa_crypto.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index d94e946f4c..6ed1f6c43a 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -129,7 +129,7 @@ static inline void psa_set_key_slot_number( psa_key_attributes_t *attributes, psa_key_slot_number_t slot_number) { - attributes->MBEDTLS_PRIVATE(flags) |= MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER; + attributes->MBEDTLS_PRIVATE(has_slot_number) = 1; attributes->MBEDTLS_PRIVATE(slot_number) = slot_number; } @@ -142,8 +142,7 @@ static inline void psa_set_key_slot_number( static inline void psa_clear_key_slot_number( psa_key_attributes_t *attributes) { - attributes->MBEDTLS_PRIVATE(flags) &= - ~MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER; + attributes->MBEDTLS_PRIVATE(has_slot_number) = 0; } /** Register a key that is already present in a secure element. diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index adb33ed214..e8f67d5d59 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -292,6 +292,7 @@ typedef uint16_t psa_key_attributes_flag_t; struct psa_key_attributes_s { #if defined(MBEDTLS_PSA_CRYPTO_SE_C) psa_key_slot_number_t MBEDTLS_PRIVATE(slot_number); + int MBEDTLS_PRIVATE(has_slot_number); #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ psa_key_type_t MBEDTLS_PRIVATE(type); psa_key_bits_t MBEDTLS_PRIVATE(bits); @@ -313,7 +314,7 @@ struct psa_key_attributes_s { }; #if defined(MBEDTLS_PSA_CRYPTO_SE_C) -#define PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER 0, +#define PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER 0, 0, #else #define PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER #endif diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 71535fa914..91f5f16162 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1245,7 +1245,7 @@ psa_status_t psa_get_key_slot_number( const psa_key_attributes_t *attributes, psa_key_slot_number_t *slot_number) { - if (attributes->flags & MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER) { + if (attributes->has_slot_number) { *slot_number = attributes->slot_number; return PSA_SUCCESS; } else { From e92796ef98651b3bdea611479a52cd6eb77ce026 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 28 Feb 2024 01:56:16 +0100 Subject: [PATCH 041/123] Get rid of flags in attributes The `flags` field in `psa_key_attributes_t` was a general mechanism that only ever got used for a single flag: to indicate that the `slot_number` field has been set. We have switched to a dedicated indicator for that, so we can now remove `flags`. Signed-off-by: Gilles Peskine --- include/psa/crypto_struct.h | 26 +----------------- library/psa_crypto.c | 25 ----------------- library/psa_crypto_core.h | 55 ------------------------------------- 3 files changed, 1 insertion(+), 105 deletions(-) diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index e8f67d5d59..4585a3e2a9 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -266,29 +266,6 @@ typedef uint16_t psa_key_bits_t; * conditionals. */ #define PSA_MAX_KEY_BITS 0xfff8 -/** A mask of flags that can be stored in key attributes. - * - * This type is also used internally to store flags in slots. Internal - * flags are defined in library/psa_crypto_core.h. Internal flags may have - * the same value as external flags if they are properly handled during - * key creation and in psa_get_key_attributes. - */ -typedef uint16_t psa_key_attributes_flag_t; - -#define MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER \ - ((psa_key_attributes_flag_t) 0x0001) - -/* A mask of key attribute flags used externally only. - * Only meant for internal checks inside the library. */ -#define MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ( \ - MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER | \ - 0) - -/* A mask of key attribute flags used both internally and externally. - * Currently there aren't any. */ -#define MBEDTLS_PSA_KA_MASK_DUAL_USE ( \ - 0) - struct psa_key_attributes_s { #if defined(MBEDTLS_PSA_CRYPTO_SE_C) psa_key_slot_number_t MBEDTLS_PRIVATE(slot_number); @@ -298,7 +275,6 @@ struct psa_key_attributes_s { psa_key_bits_t MBEDTLS_PRIVATE(bits); psa_key_lifetime_t MBEDTLS_PRIVATE(lifetime); psa_key_policy_t MBEDTLS_PRIVATE(policy); - psa_key_attributes_flag_t MBEDTLS_PRIVATE(flags); /* This type has a different layout in the client view wrt the * service view of the key id, i.e. in service view usually is * expected to have MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined @@ -321,7 +297,7 @@ struct psa_key_attributes_s { #define PSA_KEY_ATTRIBUTES_INIT { PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER \ PSA_KEY_TYPE_NONE, 0, \ PSA_KEY_LIFETIME_VOLATILE, \ - PSA_KEY_POLICY_INIT, 0, \ + PSA_KEY_POLICY_INIT, \ MBEDTLS_SVC_KEY_ID_INIT } static inline struct psa_key_attributes_s psa_key_attributes_init(void) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 91f5f16162..3c2b6a07ba 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1227,8 +1227,6 @@ psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key, } *attributes = slot->attr; - attributes->flags &= (MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY | - MBEDTLS_PSA_KA_MASK_DUAL_USE); #if defined(MBEDTLS_PSA_CRYPTO_SE_C) if (psa_get_se_driver_entry(slot->attr.lifetime) != NULL) { @@ -1443,16 +1441,6 @@ exit: return (status == PSA_SUCCESS) ? unlock_status : status; } -MBEDTLS_STATIC_ASSERT( - (MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE) == 0, - "One or more key attribute flag is listed as both external-only and dual-use") -MBEDTLS_STATIC_ASSERT( - (PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE) == 0, - "One or more key attribute flag is listed as both internal-only and dual-use") -MBEDTLS_STATIC_ASSERT( - (PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY) == 0, - "One or more key attribute flag is listed as both internal-only and external-only") - /** Validate that a key policy is internally well-formed. * * This function only rejects invalid policies. It does not validate the @@ -1531,12 +1519,6 @@ static psa_status_t psa_validate_key_attributes( return PSA_ERROR_NOT_SUPPORTED; } - /* Reject invalid flags. These should not be reachable through the API. */ - if (attributes->flags & ~(MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY | - MBEDTLS_PSA_KA_MASK_DUAL_USE)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - return PSA_SUCCESS; } @@ -1619,13 +1601,6 @@ static psa_status_t psa_start_key_creation( #endif } - /* Erase external-only flags from the internal copy. To access - * external-only flags, query `attributes`. Thanks to the check - * in psa_validate_key_attributes(), this leaves the dual-use - * flags and any internal flag that psa_reserve_free_key_slot() - * may have set. */ - slot->attr.flags &= ~MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY; - #if defined(MBEDTLS_PSA_CRYPTO_SE_C) /* For a key in a secure element, we need to do three things * when creating or registering a persistent key: diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 02c485e701..d4bdf920e6 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -159,11 +159,6 @@ typedef struct { } while (0); #endif -/* A mask of key attribute flags used only internally. - * Currently there aren't any. */ -#define PSA_KA_MASK_INTERNAL_ONLY ( \ - 0) - /** Test whether a key slot has any registered readers. * If multi-threading is enabled, the caller must hold the * global key slot mutex. @@ -177,56 +172,6 @@ static inline int psa_key_slot_has_readers(const psa_key_slot_t *slot) return slot->registered_readers > 0; } -/** Retrieve flags from psa_key_slot_t::attr::core::flags. - * - * \param[in] slot The key slot to query. - * \param mask The mask of bits to extract. - * - * \return The key attribute flags in the given slot, - * bitwise-anded with \p mask. - */ -static inline uint16_t psa_key_slot_get_flags(const psa_key_slot_t *slot, - uint16_t mask) -{ - return slot->attr.flags & mask; -} - -/** Set flags in psa_key_slot_t::attr::core::flags. - * - * \param[in,out] slot The key slot to modify. - * \param mask The mask of bits to modify. - * \param value The new value of the selected bits. - */ -static inline void psa_key_slot_set_flags(psa_key_slot_t *slot, - uint16_t mask, - uint16_t value) -{ - slot->attr.flags = ((~mask & slot->attr.flags) | - (mask & value)); -} - -/** Turn on flags in psa_key_slot_t::attr::core::flags. - * - * \param[in,out] slot The key slot to modify. - * \param mask The mask of bits to set. - */ -static inline void psa_key_slot_set_bits_in_flags(psa_key_slot_t *slot, - uint16_t mask) -{ - slot->attr.flags |= mask; -} - -/** Turn off flags in psa_key_slot_t::attr::core::flags. - * - * \param[in,out] slot The key slot to modify. - * \param mask The mask of bits to clear. - */ -static inline void psa_key_slot_clear_bits(psa_key_slot_t *slot, - uint16_t mask) -{ - slot->attr.flags &= ~mask; -} - #if defined(MBEDTLS_PSA_CRYPTO_SE_C) /** Get the SE slot number of a key from the key slot storing its description. * From b484e37d917a5af8e1fe204750d138b66d33b93a Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 27 Feb 2024 16:21:12 +0100 Subject: [PATCH 042/123] pk: fix alg selection in mbedtls_pk_sign_ext() for opaque keys This commit also fixes pk_psa_wrap_sign_ext() setting the RSA padding mode so that mbedtls_pk_get_psa_attributes() correctly guesses the PSA alg to be used. Signed-off-by: Valerio Setti --- library/pk.c | 25 ++++++++++++++++++++++++- tests/suites/test_suite_pk.function | 16 ++++------------ 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/library/pk.c b/library/pk.c index 7aee940902..8a5124f260 100644 --- a/library/pk.c +++ b/library/pk.c @@ -1188,9 +1188,32 @@ int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type, } if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_OPAQUE) { + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; + psa_algorithm_t psa_alg, psa_enrollment_alg, sign_alg; psa_status_t status; - status = psa_sign_hash(ctx->priv_id, PSA_ALG_RSA_PSS(psa_md_alg), + status = psa_get_key_attributes(ctx->priv_id, &key_attr); + if (status != PSA_SUCCESS) { + return PSA_PK_RSA_TO_MBEDTLS_ERR(status); + } + psa_alg = psa_get_key_algorithm(&key_attr); + psa_enrollment_alg = psa_get_key_enrollment_algorithm(&key_attr); + psa_reset_key_attributes(&key_attr); + + /* Since we're PK type is MBEDTLS_PK_RSASSA_PSS at least one between + * alg and enrollment alg should be of type RSA_PSS. */ + if (PSA_ALG_IS_RSA_PSS(psa_alg)) { + sign_alg = psa_alg; + } else if (PSA_ALG_IS_RSA_PSS(psa_enrollment_alg)) { + sign_alg = psa_enrollment_alg; + } else { + /* The opaque key has no RSA PSS algorithm associated. */ + return MBEDTLS_ERR_PK_BAD_INPUT_DATA; + } + /* Adjust the hashing algorithm. */ + sign_alg = (sign_alg & ~PSA_ALG_HASH_MASK) | PSA_ALG_GET_HASH(psa_md_alg); + + status = psa_sign_hash(ctx->priv_id, sign_alg, hash, hash_len, sig, sig_size, sig_len); return PSA_PK_RSA_TO_MBEDTLS_ERR(status); diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index e1a0011b78..3d75ad0e1c 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -1833,7 +1833,6 @@ void pk_psa_wrap_sign_ext(int pk_type, int key_bits, int key_pk_type, int md_alg unsigned char *pkey_start; unsigned char hash[PSA_HASH_MAX_SIZE]; psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); - psa_algorithm_t psa_alg; size_t hash_len = PSA_HASH_LENGTH(psa_md_alg); void const *options = NULL; mbedtls_pk_rsassa_pss_options rsassa_pss_options; @@ -1850,6 +1849,10 @@ void pk_psa_wrap_sign_ext(int pk_type, int key_bits, int key_pk_type, int md_alg mbedtls_test_rnd_std_rand, NULL, key_bits, 3), 0); + if (key_pk_type == MBEDTLS_PK_RSASSA_PSS) { + mbedtls_rsa_set_padding(mbedtls_pk_rsa(pk), MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_NONE); + } + /* Export underlying public key for re-importing in a legacy context. */ ret = mbedtls_pk_write_pubkey_der(&pk, pkey, sizeof(pkey)); TEST_ASSERT(ret >= 0); @@ -1858,19 +1861,8 @@ void pk_psa_wrap_sign_ext(int pk_type, int key_bits, int key_pk_type, int md_alg /* mbedtls_pk_write_pubkey_der() writes backwards in the data buffer. */ pkey_start = pkey + sizeof(pkey) - pkey_len; - if (key_pk_type == MBEDTLS_PK_RSA) { - psa_alg = PSA_ALG_RSA_PKCS1V15_SIGN(psa_md_alg); - } else if (key_pk_type == MBEDTLS_PK_RSASSA_PSS) { - psa_alg = PSA_ALG_RSA_PSS(psa_md_alg); - } else { - TEST_ASSUME(!"PK key type not supported in this configuration"); - } - /* Turn PK context into an opaque one. */ TEST_EQUAL(mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_SIGN_HASH, &key_attr), 0); - /* Tweak the algorithm associated with the PSA key because get_psa_attributes() returns - * a PSA_ALG_RSA_PSS_ANY_SALT(), but mbedtls_pk_sign_ext() requires a PSA_ALG_RSA_PSS().*/ - psa_set_key_algorithm(&key_attr, psa_alg); TEST_EQUAL(mbedtls_pk_import_into_psa(&pk, &key_attr, &key_id), 0); mbedtls_pk_free(&pk); mbedtls_pk_init(&pk); From 90eca2adb047823f82f3714edc26b93a7f0f7c09 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 28 Feb 2024 10:45:43 +0100 Subject: [PATCH 043/123] ssl_test_lib: add guards for pk_wrap_as_opaque() Signed-off-by: Valerio Setti --- programs/ssl/ssl_test_lib.c | 2 ++ programs/ssl/ssl_test_lib.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/programs/ssl/ssl_test_lib.c b/programs/ssl/ssl_test_lib.c index ec02295904..17d36b7de6 100644 --- a/programs/ssl/ssl_test_lib.c +++ b/programs/ssl/ssl_test_lib.c @@ -275,6 +275,7 @@ int key_opaque_set_alg_usage(const char *alg1, const char *alg2, return 0; } +#if defined(MBEDTLS_PK_C) int pk_wrap_as_opaque(mbedtls_pk_context *pk, psa_algorithm_t psa_alg, psa_algorithm_t psa_alg2, psa_key_usage_t psa_usage, mbedtls_svc_key_id_t *key_id) { @@ -303,6 +304,7 @@ int pk_wrap_as_opaque(mbedtls_pk_context *pk, psa_algorithm_t psa_alg, psa_algor return 0; } +#endif /* MBEDTLS_PK_C */ #endif /* MBEDTLS_USE_PSA_CRYPTO */ #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h index 5cb6a361a8..1da2dfb488 100644 --- a/programs/ssl/ssl_test_lib.h +++ b/programs/ssl/ssl_test_lib.h @@ -236,6 +236,7 @@ int key_opaque_set_alg_usage(const char *alg1, const char *alg2, psa_key_usage_t *usage, mbedtls_pk_type_t key_type); +#if defined(MBEDTLS_PK_C) /** Turn a non-opaque PK context into an opaque one with folowing steps: * - extract the key data and attributes from the PK context. * - import the key material into PSA. @@ -258,6 +259,7 @@ int key_opaque_set_alg_usage(const char *alg1, const char *alg2, */ int pk_wrap_as_opaque(mbedtls_pk_context *pk, psa_algorithm_t psa_alg, psa_algorithm_t psa_alg2, psa_key_usage_t psa_usage, mbedtls_svc_key_id_t *key_id); +#endif /* MBEDTLS_PK_C */ #endif /* MBEDTLS_USE_PSA_CRYPTO */ #if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) From 0eb4e7fb40cd8ff851ef32b82f353f3f21e308e5 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 28 Feb 2024 10:56:14 +0100 Subject: [PATCH 044/123] Fix code style Signed-off-by: Gilles Peskine --- include/psa/crypto_struct.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 4585a3e2a9..3913551aa8 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -295,10 +295,10 @@ struct psa_key_attributes_s { #define PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER #endif #define PSA_KEY_ATTRIBUTES_INIT { PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER \ - PSA_KEY_TYPE_NONE, 0, \ - PSA_KEY_LIFETIME_VOLATILE, \ - PSA_KEY_POLICY_INIT, \ - MBEDTLS_SVC_KEY_ID_INIT } + PSA_KEY_TYPE_NONE, 0, \ + PSA_KEY_LIFETIME_VOLATILE, \ + PSA_KEY_POLICY_INIT, \ + MBEDTLS_SVC_KEY_ID_INIT } static inline struct psa_key_attributes_s psa_key_attributes_init(void) { From e3fb4ccabf02784bbf41010b837b520a4b43c115 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 19 Feb 2024 16:27:35 +0100 Subject: [PATCH 045/123] mbedtls_ecp_write_key_ext(): new function Same as mbedtls_ecp_write_key(), but doesn't require the caller to figure out the length of the output and possibly distinguish between Weierstrass and Montgomery curves. Signed-off-by: Gilles Peskine --- ChangeLog.d/ecp_write_key.txt | 4 ++ include/mbedtls/ecp.h | 20 ++++++ library/ecp.c | 32 +++++++++ tests/suites/test_suite_ecp.data | 103 +++++++++++++++++++++++++++ tests/suites/test_suite_ecp.function | 36 ++++++++++ 5 files changed, 195 insertions(+) create mode 100644 ChangeLog.d/ecp_write_key.txt diff --git a/ChangeLog.d/ecp_write_key.txt b/ChangeLog.d/ecp_write_key.txt new file mode 100644 index 0000000000..19612396cb --- /dev/null +++ b/ChangeLog.d/ecp_write_key.txt @@ -0,0 +1,4 @@ +Features + * The new function mbedtls_ecp_write_key_ext() is similar to + mbedtls_ecp_write_key(), but can be used without separately calculating + the output length. diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index 0201963ab9..b46d6c3dcc 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -1370,6 +1370,26 @@ int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key, unsigned char *buf, size_t buflen); +/** + * \brief This function exports an elliptic curve private key. + * + * \param key The private key. + * \param olen On success, the length of the private key. + * This is always (`grp->nbits` + 7) / 8 bytes + * where `grp->nbits` is the private key size in bits. + * \param buf The output buffer for containing the binary representation + * of the key. + * \param buflen The total length of the buffer in bytes. + * #MBEDTLS_ECP_MAX_BYTES is always sufficient. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the \p key + * representation is larger than the available space in \p buf. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_ecp_write_key_ext(mbedtls_ecp_keypair *key, + size_t *olen, unsigned char *buf, size_t buflen); + /** * \brief This function exports an elliptic curve public key. * diff --git a/library/ecp.c b/library/ecp.c index 66b3dc1be1..930102f973 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -3333,6 +3333,38 @@ cleanup: return ret; } +int mbedtls_ecp_write_key_ext(mbedtls_ecp_keypair *key, + size_t *olen, unsigned char *buf, size_t buflen) +{ + size_t len = (key->grp.nbits + 7) / 8; + if (len > buflen) { + /* For robustness, ensure *olen <= buflen even on error. */ + *olen = 0; + return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; + } + *olen = len; + + /* Private key not set */ + if (key->d.n == 0) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + +#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) + if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { + return mbedtls_mpi_write_binary_le(&key->d, buf, len); + } +#endif + +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) + if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { + return mbedtls_mpi_write_binary(&key->d, buf, len); + } +#endif + + /* Private key set but no recognized curve type? This shouldn't happen. */ + return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; +} + /* * Write a public key. */ diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index 1dd963a23e..fd63657aab 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -888,6 +888,109 @@ ECP write key: Curve448, mostly-0 key, output_size=55 depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED ecp_write_key:MBEDTLS_ECP_DP_CURVE448:"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080":55:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL +ECP write key ext: secp256r1, nominal +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":32:0 + +ECP write key ext: secp256r1, output longer by 1 +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":33:0 + +ECP write key ext: secp256r1, output short by 1 +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":31:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL + +ECP write key ext: secp256r1, output_size=0 +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":0:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL + +ECP write key ext: secp256r1, top byte = 0, output_size=32 +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":32:0 + +ECP write key ext: secp256r1, top byte = 0, output_size=31 +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":31:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL + +ECP write key ext: secp256r1, top byte = 0, output_size=30 +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":30:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL + +ECP write key ext: secp256r1, mostly-0 key, output_size=32 +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"0000000000000000000000000000000000000000000000000000000000000001":32:0 + +ECP write key ext: secp256r1, mostly-0 key, output_size=1 +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"0000000000000000000000000000000000000000000000000000000000000001":1:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL + +ECP write key ext: secp256r1, private key not set +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"":32:MBEDTLS_ERR_ECP_BAD_INPUT_DATA + +ECP write key ext: secp384r1, nominal +depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_SECP384R1:"d27335ea71664af244dd14e9fd1260715dfd8a7965571c48d709ee7a7962a156d706a90cbcb5df2986f05feadb9376f1":48:0 + +ECP write key ext: secp384r1, output longer by 1 +depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_SECP384R1:"d27335ea71664af244dd14e9fd1260715dfd8a7965571c48d709ee7a7962a156d706a90cbcb5df2986f05feadb9376f1":49:0 + +ECP write key ext: secp384r1, output short by 1 +depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_SECP384R1:"d27335ea71664af244dd14e9fd1260715dfd8a7965571c48d709ee7a7962a156d706a90cbcb5df2986f05feadb9376f1":47:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL + +ECP write key ext: Curve25519, nominal +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"a046e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449a44":32:0 + +ECP write key ext: Curve25519, output longer by 1 +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"a046e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449a44":33:0 + +ECP write key ext: Curve25519, output short by 1 +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"a046e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449a44":31:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL + +ECP write key ext: Curve25519, output_size=0 +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"a046e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449a44":0:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL + +ECP write key ext: Curve25519, mostly-0 key, output_size=32 +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"0000000000000000000000000000000000000000000000000000000000000040":32:0 + +ECP write key ext: Curve25519, mostly-0 key, output_size=31 +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"0000000000000000000000000000000000000000000000000000000000000040":31:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL + +ECP write key ext: Curve25519, private key not set +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"":32:MBEDTLS_ERR_ECP_BAD_INPUT_DATA + +ECP write key ext: Curve448, nominal +depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE448:"3c262fddf9ec8e88495266fea19a34d28882acef045104d0d1aae121700a779c984c24f8cdd78fbff44943eba368f54b29259a4f1c600ad3":56:0 + +ECP write key ext: Curve448, output longer by 1 +depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE448:"3c262fddf9ec8e88495266fea19a34d28882acef045104d0d1aae121700a779c984c24f8cdd78fbff44943eba368f54b29259a4f1c600ad3":57:0 + +ECP write key ext: Curve448, output short by 1 +depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE448:"3c262fddf9ec8e88495266fea19a34d28882acef045104d0d1aae121700a779c984c24f8cdd78fbff44943eba368f54b29259a4f1c600ad3":55:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL + +ECP write key ext: Curve448, mostly-0 key, output_size=56 +depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE448:"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080":56:0 + +ECP write key ext: Curve448, mostly-0 key, output_size=55 +depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED +ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE448:"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080":55:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL + +ECP write key ext: group not set +ecp_write_key_ext:MBEDTLS_ECP_DP_NONE:"":32:MBEDTLS_ERR_ECP_BAD_INPUT_DATA + ECP mod p192 small (more than 192 bits, less limbs than 2 * 192 bits) depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED:MBEDTLS_ECP_NIST_OPTIM ecp_fast_mod:MBEDTLS_ECP_DP_SECP192R1:"0100000000000103010000000000010201000000000001010100000000000100" diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index 9cf0ce1b7a..c0612755ff 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -1296,6 +1296,42 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void ecp_write_key_ext(int grp_id, data_t *in_key, + int exported_size, int expected_ret) +{ + mbedtls_ecp_keypair key; + mbedtls_ecp_keypair_init(&key); + unsigned char *exported = NULL; + + if (in_key->len != 0) { + TEST_EQUAL(mbedtls_ecp_read_key(grp_id, &key, in_key->x, in_key->len), 0); + } else if (grp_id != MBEDTLS_ECP_DP_NONE) { + TEST_EQUAL(mbedtls_ecp_group_load(&key.grp, grp_id), 0); + } + + TEST_CALLOC(exported, exported_size); + size_t olen = 0xdeadbeef; + TEST_EQUAL(mbedtls_ecp_write_key_ext(&key, &olen, exported, exported_size), + expected_ret); + + if (expected_ret == 0) { + TEST_EQUAL(olen, (key.grp.nbits + 7) / 8); + TEST_LE_U(olen, MBEDTLS_ECP_MAX_BYTES); + TEST_MEMORY_COMPARE(in_key->x, in_key->len, + exported, olen); + } else { + /* Robustness check: even in the error case, insist that olen is less + * than the buffer size. */ + TEST_LE_U(olen, exported_size); + } + +exit: + mbedtls_ecp_keypair_free(&key); + mbedtls_free(exported); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_MONTGOMERY_ENABLED:MBEDTLS_ECP_LIGHT */ void genkey_mx_known_answer(int bits, data_t *seed, data_t *expected) { From acdc52e1543dfb1deb79de414758726538767dba Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 19 Feb 2024 16:42:54 +0100 Subject: [PATCH 046/123] mbedtls_ecp_write_key_ext(): recommend over the old function in documentation Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 10 +++++----- include/mbedtls/ecp.h | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index e89128cbdd..94b57eba9c 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -845,7 +845,6 @@ For an ECC private key (a future version of Mbed TLS [will provide a more direct ``` unsigned char buf[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; -size_t length = PSA_BITS_TO_BYTES(mbedtls_pk_bitlen(&pk)); mbedtls_ecp_keypair *ec = mbedtls_pk_ec(&pk); psa_ecc_curve_t curve; { @@ -862,7 +861,8 @@ psa_ecc_curve_t curve; mbedtls_ecp_point_free(&Q); mbedtls_mpi_free(&d); } -mbedtls_ecp_write_key(ec, buf, length); +size_t length; +mbedtls_ecp_write_key_ext(ec, &length, buf, sizeof(buf)); psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve)); psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_... | ...); @@ -900,8 +900,8 @@ mbedtls_ecp_keypair_init(&ec); // Omitted: fill ec with key material // (the public key will not be used and does not need to be set) unsigned char buf[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; -size_t length = PSA_BITS_TO_BYTES(mbedtls_pk_bitlen(&pk)); -mbedtls_ecp_write_key(&ec, buf, length); +size_t length; +mbedtls_ecp_write_key_ext(&ec, &length, buf, sizeof(buf)); psa_ecc_curve_t curve = ...; // need to determine the curve family manually psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_set_key_attributes(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve)); @@ -1300,7 +1300,7 @@ There is no PSA equivalent to the types `mbedtls_ecdsa_context` and `mbedtls_ecd The PSA API is a cryptography API, not an arithmetic API. As a consequence, there is no PSA equivalent for the ECC arithmetic functionality exposed by `ecp.h`: * Manipulation of point objects and input-output: the type `mbedtls_ecp_point` and functions operating on it (`mbedtls_ecp_point_xxx`, `mbedtls_ecp_copy`, `mbedtls_ecp_{set,is}_zero`, `mbedtls_ecp_tls_{read,write}_point`). Note that the PSA export format for public keys corresponds to the uncompressed point format (`MBEDTLS_ECP_PF_UNCOMPRESSED`), so [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b), [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) and [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) are equivalent to `mbedtls_ecp_point_read_binary` and `mbedtls_ecp_point_write_binary` for uncompressed points. The PSA API does not currently support compressed points, but it is likely that such support will be added in the future. -* Manipulation of key pairs as such, with a bridge to bignum arithmetic (`mbedtls_ecp_keypair` type, `mbedtls_ecp_export`). However, the PSA export format for ECC private keys used by [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b), [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) is the same as the format used by `mbedtls_ecp_read_key` and `mbedtls_ecp_write_key`. +* Manipulation of key pairs as such, with a bridge to bignum arithmetic (`mbedtls_ecp_keypair` type, `mbedtls_ecp_export`). However, the PSA export format for ECC private keys used by [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b), [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) is the same as the format used by `mbedtls_ecp_read_key` and `mbedtls_ecp_write_key_ext`. * Elliptic curve arithmetic (`mbedtls_ecp_mul`, `mbedtls_ecp_muladd` and their restartable variants). ### Additional information about RSA diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index b46d6c3dcc..58fc5e5557 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -1338,6 +1338,8 @@ int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, * checking that the output buffer is large enough. * See the description of the \p buflen parameter for * how to calculate the nominal length. + * To avoid this difficulty, use mbedtls_ecp_write_key_ext() + * instead. * * \note If the private key was not set in \p key, * the output is unspecified. Future versions From 84b9f1b0391ec748ab0565b4cd89b0f4a667187b Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 19 Feb 2024 16:44:29 +0100 Subject: [PATCH 047/123] mbedtls_ecp_write_key_ext(): migrate internally Stop using mbedtls_ecp_write_key() except to test it. Signed-off-by: Gilles Peskine --- library/pk.c | 3 +-- library/pkwrite.c | 2 +- library/psa_crypto_ecp.c | 21 +++-------------- library/ssl_tls12_server.c | 3 +-- tests/suites/test_suite_ecp.function | 35 +++++++++++++++++++--------- 5 files changed, 30 insertions(+), 34 deletions(-) diff --git a/library/pk.c b/library/pk.c index 1ded4872f9..c647b459a2 100644 --- a/library/pk.c +++ b/library/pk.c @@ -1401,8 +1401,7 @@ int mbedtls_pk_wrap_as_opaque(mbedtls_pk_context *pk, mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk); int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - d_len = PSA_BITS_TO_BYTES(ec->grp.nbits); - if ((ret = mbedtls_ecp_write_key(ec, d, d_len)) != 0) { + if ((ret = mbedtls_ecp_write_key_ext(ec, &d_len, d, sizeof(d))) != 0) { return ret; } diff --git a/library/pkwrite.c b/library/pkwrite.c index b9ddcf1d8d..5e009c565e 100644 --- a/library/pkwrite.c +++ b/library/pkwrite.c @@ -202,7 +202,7 @@ static int pk_write_ec_private(unsigned char **p, unsigned char *start, mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk); byte_length = (ec->grp.pbits + 7) / 8; - ret = mbedtls_ecp_write_key(ec, tmp, byte_length); + ret = mbedtls_ecp_write_key_ext(ec, &byte_length, tmp, sizeof(tmp)); if (ret != 0) { goto exit; } diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c index 7edea81646..e373ad9f66 100644 --- a/library/psa_crypto_ecp.c +++ b/library/psa_crypto_ecp.c @@ -281,20 +281,8 @@ psa_status_t mbedtls_psa_ecp_export_key(psa_key_type_t type, return status; } else { - if (data_size < PSA_BITS_TO_BYTES(ecp->grp.nbits)) { - return PSA_ERROR_BUFFER_TOO_SMALL; - } - status = mbedtls_to_psa_error( - mbedtls_ecp_write_key(ecp, - data, - PSA_BITS_TO_BYTES(ecp->grp.nbits))); - if (status == PSA_SUCCESS) { - *data_length = PSA_BITS_TO_BYTES(ecp->grp.nbits); - } else { - memset(data, 0, data_size); - } - + mbedtls_ecp_write_key_ext(ecp, data_length, data, data_size)); return status; } } @@ -359,14 +347,11 @@ psa_status_t mbedtls_psa_ecp_generate_key( } status = mbedtls_to_psa_error( - mbedtls_ecp_write_key(&ecp, key_buffer, key_buffer_size)); + mbedtls_ecp_write_key_ext(&ecp, key_buffer_length, + key_buffer, key_buffer_size)); mbedtls_ecp_keypair_free(&ecp); - if (status == PSA_SUCCESS) { - *key_buffer_length = key_buffer_size; - } - return status; } #endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE */ diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index 53a9ce206c..5bee188235 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -2703,8 +2703,7 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl) PSA_KEY_TYPE_ECC_KEY_PAIR(ssl->handshake->xxdh_psa_type)); psa_set_key_bits(&key_attributes, ssl->handshake->xxdh_psa_bits); - key_len = PSA_BITS_TO_BYTES(key->grp.pbits); - ret = mbedtls_ecp_write_key(key, buf, key_len); + ret = mbedtls_ecp_write_key_ext(key, &key_len, buf, sizeof(buf)); if (ret != 0) { mbedtls_platform_zeroize(buf, sizeof(buf)); break; diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index c0612755ff..ef0781bb77 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -1204,27 +1204,40 @@ void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonica TEST_EQUAL(mbedtls_mpi_cmp_int(&key.Q.Y, 2), 0); TEST_EQUAL(mbedtls_mpi_cmp_int(&key.Q.Z, 3), 0); - if (canonical) { + if (canonical && in_key->len == (key.grp.nbits + 7) / 8) { unsigned char buf[MBEDTLS_ECP_MAX_BYTES]; + size_t length = 0xdeadbeef; - ret = mbedtls_ecp_write_key(&key, buf, in_key->len); - TEST_ASSERT(ret == 0); + TEST_EQUAL(mbedtls_ecp_write_key_ext(&key, + &length, buf, in_key->len), 0); + TEST_MEMORY_COMPARE(in_key->x, in_key->len, + buf, length); + memset(buf, 0, sizeof(buf)); + TEST_EQUAL(mbedtls_ecp_write_key(&key, buf, in_key->len), 0); TEST_MEMORY_COMPARE(in_key->x, in_key->len, buf, in_key->len); } else { unsigned char export1[MBEDTLS_ECP_MAX_BYTES]; unsigned char export2[MBEDTLS_ECP_MAX_BYTES]; - ret = mbedtls_ecp_write_key(&key, export1, in_key->len); - TEST_ASSERT(ret == 0); - - ret = mbedtls_ecp_read_key(grp_id, &key2, export1, in_key->len); - TEST_ASSERT(ret == expected); - - ret = mbedtls_ecp_write_key(&key2, export2, in_key->len); - TEST_ASSERT(ret == 0); + size_t length1 = 0xdeadbeef; + TEST_EQUAL(mbedtls_ecp_write_key_ext(&key, &length1, + export1, sizeof(export1)), 0); + TEST_EQUAL(mbedtls_ecp_read_key(grp_id, &key2, export1, length1), + expected); + size_t length2 = 0xdeadbeef; + TEST_EQUAL(mbedtls_ecp_write_key_ext(&key2, &length2, + export2, sizeof(export2)), 0); + TEST_MEMORY_COMPARE(export1, length1, + export2, length2); + memset(export1, 0, sizeof(export1)); + memset(export2, 0, sizeof(export2)); + TEST_EQUAL(mbedtls_ecp_write_key(&key, export1, in_key->len), 0); + TEST_EQUAL(mbedtls_ecp_read_key(grp_id, &key2, export1, in_key->len), + expected); + TEST_EQUAL(mbedtls_ecp_write_key(&key2, export2, in_key->len), 0); TEST_MEMORY_COMPARE(export1, in_key->len, export2, in_key->len); } From c0f7a8680fe1b1a5346058fca7b6af38352dbe15 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 19 Feb 2024 16:50:39 +0100 Subject: [PATCH 048/123] mbedtls_ecp_write_key(): deprecate the old function Signed-off-by: Gilles Peskine --- ChangeLog.d/ecp_write_key.txt | 4 ++++ include/mbedtls/ecp.h | 11 ++++++++--- library/ecp.c | 2 ++ tests/suites/test_suite_ecp.function | 6 +++++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/ChangeLog.d/ecp_write_key.txt b/ChangeLog.d/ecp_write_key.txt index 19612396cb..73354c8633 100644 --- a/ChangeLog.d/ecp_write_key.txt +++ b/ChangeLog.d/ecp_write_key.txt @@ -2,3 +2,7 @@ Features * The new function mbedtls_ecp_write_key_ext() is similar to mbedtls_ecp_write_key(), but can be used without separately calculating the output length. + +New deprecations + * mbedtls_ecp_write_key() is deprecated in favor of + mbedtls_ecp_write_key_ext(). diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index 58fc5e5557..05778cdd15 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -24,6 +24,7 @@ #include "mbedtls/private_access.h" #include "mbedtls/build_info.h" +#include "mbedtls/platform_util.h" #include "mbedtls/bignum.h" @@ -1327,10 +1328,11 @@ int mbedtls_ecp_set_public_key(mbedtls_ecp_group_id grp_id, int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, const unsigned char *buf, size_t buflen); +#if !defined(MBEDTLS_DEPRECATED_REMOVED) /** * \brief This function exports an elliptic curve private key. * - * \note Note that although this function accepts an output + * \deprecated Note that although this function accepts an output * buffer that is smaller or larger than the key, most key * import interfaces require the output to have exactly * key's nominal length. It is generally simplest to @@ -1340,6 +1342,8 @@ int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, * how to calculate the nominal length. * To avoid this difficulty, use mbedtls_ecp_write_key_ext() * instead. + * mbedtls_ecp_write_key() is deprecated and will be + * removed in a future version of the library. * * \note If the private key was not set in \p key, * the output is unspecified. Future versions @@ -1369,8 +1373,9 @@ int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, * representation is larger than the available space in \p buf. * \return Another negative error code on different kinds of failure. */ -int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key, - unsigned char *buf, size_t buflen); +int MBEDTLS_DEPRECATED mbedtls_ecp_write_key(mbedtls_ecp_keypair *key, + unsigned char *buf, size_t buflen); +#endif /* MBEDTLS_DEPRECATED_REMOVED */ /** * \brief This function exports an elliptic curve private key. diff --git a/library/ecp.c b/library/ecp.c index 930102f973..0dadaeaac6 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -3302,6 +3302,7 @@ cleanup: /* * Write a private key. */ +#if !defined MBEDTLS_DEPRECATED_REMOVED int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key, unsigned char *buf, size_t buflen) { @@ -3332,6 +3333,7 @@ cleanup: return ret; } +#endif /* MBEDTLS_DEPRECATED_REMOVED */ int mbedtls_ecp_write_key_ext(mbedtls_ecp_keypair *key, size_t *olen, unsigned char *buf, size_t buflen) diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index ef0781bb77..9b5c86f979 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -1213,10 +1213,12 @@ void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonica TEST_MEMORY_COMPARE(in_key->x, in_key->len, buf, length); +#if defined(MBEDTLS_TEST_DEPRECATED) memset(buf, 0, sizeof(buf)); TEST_EQUAL(mbedtls_ecp_write_key(&key, buf, in_key->len), 0); TEST_MEMORY_COMPARE(in_key->x, in_key->len, buf, in_key->len); +#endif /* MBEDTLS_TEST_DEPRECATED */ } else { unsigned char export1[MBEDTLS_ECP_MAX_BYTES]; unsigned char export2[MBEDTLS_ECP_MAX_BYTES]; @@ -1232,6 +1234,7 @@ void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonica TEST_MEMORY_COMPARE(export1, length1, export2, length2); +#if defined(MBEDTLS_TEST_DEPRECATED) memset(export1, 0, sizeof(export1)); memset(export2, 0, sizeof(export2)); TEST_EQUAL(mbedtls_ecp_write_key(&key, export1, in_key->len), 0); @@ -1240,6 +1243,7 @@ void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonica TEST_EQUAL(mbedtls_ecp_write_key(&key2, export2, in_key->len), 0); TEST_MEMORY_COMPARE(export1, in_key->len, export2, in_key->len); +#endif /* MBEDTLS_TEST_DEPRECATED */ } } @@ -1249,7 +1253,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_TEST_DEPRECATED */ void ecp_write_key(int grp_id, data_t *in_key, int exported_size, int expected_ret) { From 04ae479b04eedc2a9cb7e720bd4ca51f87c91654 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 26 Feb 2024 09:15:08 +0100 Subject: [PATCH 049/123] mbedtls_ecp_write_key_ext: document error for no private key set Signed-off-by: Gilles Peskine --- include/mbedtls/ecp.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index 05778cdd15..e2ae074445 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -1392,6 +1392,8 @@ int MBEDTLS_DEPRECATED mbedtls_ecp_write_key(mbedtls_ecp_keypair *key, * \return \c 0 on success. * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the \p key * representation is larger than the available space in \p buf. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if no private key is + * set in \p key. * \return Another negative error code on different kinds of failure. */ int mbedtls_ecp_write_key_ext(mbedtls_ecp_keypair *key, From b395e74edd3cce58b692eefe3b5127e096030075 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 28 Feb 2024 14:18:28 +0100 Subject: [PATCH 050/123] mbedtls_ecp_write_key_ext(): make key const Having a non-const `key` parameter was anotherf defect of mbedtls_ecp_write_key(). Take this opportunity to fix it. Signed-off-by: Gilles Peskine --- include/mbedtls/ecp.h | 2 +- library/ecp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index e2ae074445..d8f73ae965 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -1396,7 +1396,7 @@ int MBEDTLS_DEPRECATED mbedtls_ecp_write_key(mbedtls_ecp_keypair *key, * set in \p key. * \return Another negative error code on different kinds of failure. */ -int mbedtls_ecp_write_key_ext(mbedtls_ecp_keypair *key, +int mbedtls_ecp_write_key_ext(const mbedtls_ecp_keypair *key, size_t *olen, unsigned char *buf, size_t buflen); /** diff --git a/library/ecp.c b/library/ecp.c index 0dadaeaac6..427059bb53 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -3335,7 +3335,7 @@ cleanup: } #endif /* MBEDTLS_DEPRECATED_REMOVED */ -int mbedtls_ecp_write_key_ext(mbedtls_ecp_keypair *key, +int mbedtls_ecp_write_key_ext(const mbedtls_ecp_keypair *key, size_t *olen, unsigned char *buf, size_t buflen) { size_t len = (key->grp.nbits + 7) / 8; From 84a7bfbd33a2df49235231ff3b9c49c22038bf30 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 28 Feb 2024 14:21:32 +0100 Subject: [PATCH 051/123] mbedtls_ecp_write_key_ext(): Upgrade import_pair_into_psa as well It wasn't done with the others because that code was added in a concurrent branch. Signed-off-by: Gilles Peskine --- library/pk.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/library/pk.c b/library/pk.c index c647b459a2..328bbe1eaa 100644 --- a/library/pk.c +++ b/library/pk.c @@ -675,10 +675,7 @@ static int import_pair_into_psa(const mbedtls_pk_context *pk, #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) psa_ecc_family_t from_family = pk->ec_family; #else /* MBEDTLS_PK_USE_PSA_EC_DATA */ - /* We're only reading the key, but mbedtls_ecp_write_key() - * is missing a const annotation on its key parameter, so - * we need the non-const accessor here. */ - mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk); + const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk); size_t from_bits = 0; psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id, &from_bits); @@ -704,12 +701,9 @@ static int import_pair_into_psa(const mbedtls_pk_context *pk, return MBEDTLS_ERR_PK_TYPE_MISMATCH; } unsigned char key_buffer[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; - /* Make sure to pass the exact key length to - * mbedtls_ecp_write_key(), because it writes Montgomery keys - * at the start of the buffer but Weierstrass keys at the - * end of the buffer. */ - size_t key_length = PSA_BITS_TO_BYTES(ec->grp.nbits); - int ret = mbedtls_ecp_write_key(ec, key_buffer, key_length); + size_t key_length = 0; + int ret = mbedtls_ecp_write_key_ext(ec, &key_length, + key_buffer, sizeof(key_buffer)); if (ret < 0) { return ret; } From d753738fc0f32368af0b284562d33ffc9d771cd2 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Fri, 23 Feb 2024 12:17:59 +0000 Subject: [PATCH 052/123] echd: Added `mbedtls_ecdh_get_grp_id` getter. Signed-off-by: Minos Galanakis --- include/mbedtls/ecdh.h | 13 +++++++++++++ library/ecdh.c | 9 +++++++++ 2 files changed, 22 insertions(+) diff --git a/include/mbedtls/ecdh.h b/include/mbedtls/ecdh.h index 792db79fd8..a0909d6b44 100644 --- a/include/mbedtls/ecdh.h +++ b/include/mbedtls/ecdh.h @@ -141,6 +141,19 @@ typedef struct mbedtls_ecdh_context { } mbedtls_ecdh_context; +/** + * \brief Return the ECP group for provided context. + * + * \note To access group specific fields, users should use + * `mbedtls_ecp_curve_info_from_grp_id` or + * `mbedtls_ecp_group_load` on the extracted `group_id`. + * + * \param ctx The ECDH context to parse. This must not be \c NULL. + * + * \return The \c mbedtls_ecp_group_id of the context. + */ +mbedtls_ecp_group_id mbedtls_ecdh_get_grp_id(mbedtls_ecdh_context *ctx); + /** * \brief Check whether a given group can be used for ECDH. * diff --git a/library/ecdh.c b/library/ecdh.c index 52b1617062..b276c6adad 100644 --- a/library/ecdh.c +++ b/library/ecdh.c @@ -144,6 +144,15 @@ static void ecdh_init_internal(mbedtls_ecdh_context_mbed *ctx) #endif } +mbedtls_ecp_group_id mbedtls_ecdh_get_grp_id(mbedtls_ecdh_context *ctx) +{ +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return ctx->MBEDTLS_PRIVATE(grp).id; +#else + return ctx->MBEDTLS_PRIVATE(grp_id); +#endif +} + /* * Initialize context */ From b4ce628b64140959cacaec430e3a2d2edde09e17 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Fri, 23 Feb 2024 16:55:33 +0000 Subject: [PATCH 053/123] tests: Added test for `mbedtls_ecdh_context_grp` Signed-off-by: Minos Galanakis --- tests/suites/test_suite_ecdh.data | 16 ++++++++++++++++ tests/suites/test_suite_ecdh.function | 17 +++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/tests/suites/test_suite_ecdh.data b/tests/suites/test_suite_ecdh.data index cc58432f57..8d0606704f 100644 --- a/tests/suites/test_suite_ecdh.data +++ b/tests/suites/test_suite_ecdh.data @@ -100,3 +100,19 @@ ecdh_exchange_get_params_fail:MBEDTLS_ECP_DP_BP256R1:"12345678123456781234567812 ECDH get_params with mismatched groups: their SECP256R1, our BP256R1 depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_BP256R1_ENABLED ecdh_exchange_get_params_fail:MBEDTLS_ECP_DP_BP256R1:"1234567812345678123456781234567812345678123456781234567812345678":MBEDTLS_ECP_DP_SECP256R1:"04dad0b65394221cf9b051e1feca5787d098dfe637fc90b9ef945d0c37725811805271a0461cdb8252d61f1c456fa3e59ab1f45b33accf5f58389e0577b8990bb3":1:MBEDTLS_ERR_ECP_BAD_INPUT_DATA + +Context get ECP Group #1 +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecdh_context_grp:MBEDTLS_ECP_DP_SECP256R1 + +Context get ECP Group #2 +depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED +ecdh_primitive_random:MBEDTLS_ECP_DP_SECP384R1 + +Context get ECP Group #3 +depends_on:MBEDTLS_ECP_DP_SECP521R1_ENABLED +ecdh_primitive_random:MBEDTLS_ECP_DP_SECP521R1 + +Context get ECP Group #4 +depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED +ecdh_primitive_random:MBEDTLS_ECP_DP_CURVE448 diff --git a/tests/suites/test_suite_ecdh.function b/tests/suites/test_suite_ecdh.function index cc193dacca..300916feaa 100644 --- a/tests/suites/test_suite_ecdh.function +++ b/tests/suites/test_suite_ecdh.function @@ -464,3 +464,20 @@ exit: mbedtls_ecp_keypair_free(&their_key); } /* END_CASE */ + +/* BEGIN_CASE */ +void ecdh_context_grp(int id) +{ + mbedtls_ecdh_context srv; + + mbedtls_ecdh_init(&srv); + TEST_ASSERT(mbedtls_ecdh_setup(&srv, id) == 0); + + /* Test the retrieved group id matches/*/ + TEST_ASSERT((int) mbedtls_ecdh_get_grp_id(&srv) == id); + +exit: + mbedtls_ecdh_free(&srv); + +} +/* END_CASE */ From 4ee6f811957511d6e9f88b6be6de747224430494 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 29 Feb 2024 15:01:21 +0100 Subject: [PATCH 054/123] add changelog Signed-off-by: Valerio Setti --- ChangeLog.d/8848.txt | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 ChangeLog.d/8848.txt diff --git a/ChangeLog.d/8848.txt b/ChangeLog.d/8848.txt new file mode 100644 index 0000000000..682f4f068f --- /dev/null +++ b/ChangeLog.d/8848.txt @@ -0,0 +1,5 @@ +New deprecations + * mbedtls_pk_wrap_as_opaque() is deprecated. To mimic the same behavior + mbedtls_pk_get_psa_attributes() and mbedtls_pk_import_into_psa() can be + used to import a PK key into PSA, while mbedtls_pk_setup_opaque() can + be used to wrap a PSA key into a opaque PK context. From 1f08a3248e201146c6a8f0bcba99647b37516e99 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 29 Feb 2024 14:00:58 +0000 Subject: [PATCH 055/123] Rename quiet to quiet.sh Signed-off-by: Dave Rodgman --- tests/scripts/quiet/cmake | 2 +- tests/scripts/quiet/make | 2 +- tests/scripts/quiet/{quiet => quiet.sh} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename tests/scripts/quiet/{quiet => quiet.sh} (100%) diff --git a/tests/scripts/quiet/cmake b/tests/scripts/quiet/cmake index 3723473f53..586397887f 100755 --- a/tests/scripts/quiet/cmake +++ b/tests/scripts/quiet/cmake @@ -15,4 +15,4 @@ export NO_SILENCE=" --version " export TOOL="cmake" -exec "$(dirname "$0")/quiet" "$@" +exec "$(dirname "$0")/quiet.sh" "$@" diff --git a/tests/scripts/quiet/make b/tests/scripts/quiet/make index 162d44de6c..24e77951c2 100755 --- a/tests/scripts/quiet/make +++ b/tests/scripts/quiet/make @@ -15,4 +15,4 @@ export NO_SILENCE=" --version | test " export TOOL="make" -exec "$(dirname "$0")/quiet" "$@" +exec "$(dirname "$0")/quiet.sh" "$@" diff --git a/tests/scripts/quiet/quiet b/tests/scripts/quiet/quiet.sh similarity index 100% rename from tests/scripts/quiet/quiet rename to tests/scripts/quiet/quiet.sh From 20964780347fcde5916cf2cd625049d587fba572 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 29 Feb 2024 14:06:19 +0000 Subject: [PATCH 056/123] Add editor hint for emacs Signed-off-by: Dave Rodgman --- tests/scripts/quiet/quiet.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/scripts/quiet/quiet.sh b/tests/scripts/quiet/quiet.sh index 0f5bf06ecd..be065f4d78 100755 --- a/tests/scripts/quiet/quiet.sh +++ b/tests/scripts/quiet/quiet.sh @@ -1,3 +1,5 @@ +# -*-mode: sh; sh-shell: bash -*- +# # Copyright The Mbed TLS Contributors # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later # From 63c94a36f19ceaf0f410ac5ca4f51f40dade8642 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 29 Feb 2024 14:06:36 +0000 Subject: [PATCH 057/123] improve docs Signed-off-by: Dave Rodgman --- tests/scripts/quiet/quiet.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/quiet/quiet.sh b/tests/scripts/quiet/quiet.sh index be065f4d78..5cdcd1ea64 100755 --- a/tests/scripts/quiet/quiet.sh +++ b/tests/scripts/quiet/quiet.sh @@ -19,7 +19,7 @@ # # NO_SILENCE - a regex that describes the commandline arguments for which output will not # be silenced, e.g. " --version | test ". In this example, "make test" will -# not be silent, but "make lib" will be. +# not be silent, but "make lib test" will be. # Locate original tool TOOL_WITH_PATH=$(dirname "$0")/$TOOL From a3e694c2ad0d915b545874b7ba3a0829997306e6 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 29 Feb 2024 14:06:49 +0000 Subject: [PATCH 058/123] simplify printf call Signed-off-by: Dave Rodgman --- tests/scripts/quiet/quiet.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/quiet/quiet.sh b/tests/scripts/quiet/quiet.sh index 5cdcd1ea64..5b341294f7 100755 --- a/tests/scripts/quiet/quiet.sh +++ b/tests/scripts/quiet/quiet.sh @@ -30,7 +30,7 @@ print_quoted_args() { # but produce more human-readable results for common/simple cases like "a b" for a in "$@"; do # Get bash to quote the string - q=$(printf '%q' "$a") + printf -v q '%q' "$a" simple_pattern="^([-[:alnum:]_+./:@]+=)?([^']*)$" if [[ "$a" != "$q" && $a =~ $simple_pattern ]]; then # a requires some quoting (a != q), but has no single quotes, so we can From 5f7862a56738607f5b5404306e480c293990b6c2 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 29 Feb 2024 14:14:37 +0000 Subject: [PATCH 059/123] Fix docs Co-authored-by: Gilles Peskine Signed-off-by: Dave Rodgman --- tests/scripts/quiet/quiet.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/scripts/quiet/quiet.sh b/tests/scripts/quiet/quiet.sh index 5b341294f7..01ef422e32 100755 --- a/tests/scripts/quiet/quiet.sh +++ b/tests/scripts/quiet/quiet.sh @@ -18,8 +18,8 @@ # TOOL - the name of the tool that is being wrapped (with no path), e.g. "make" # # NO_SILENCE - a regex that describes the commandline arguments for which output will not -# be silenced, e.g. " --version | test ". In this example, "make test" will -# not be silent, but "make lib test" will be. +# be silenced, e.g. " --version | test ". In this example, "make lib test" will +# not be silent, but "make lib" will be. # Locate original tool TOOL_WITH_PATH=$(dirname "$0")/$TOOL From 869e310456725ae18a32c7468f7777f002e998c4 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 29 Feb 2024 14:59:40 +0000 Subject: [PATCH 060/123] Use export to set VERBOSE_LOGS Signed-off-by: Dave Rodgman --- tests/scripts/quiet/cmake | 2 +- tests/scripts/quiet/make | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/scripts/quiet/cmake b/tests/scripts/quiet/cmake index 586397887f..854375ecb4 100755 --- a/tests/scripts/quiet/cmake +++ b/tests/scripts/quiet/cmake @@ -8,7 +8,7 @@ # If you are debugging a build / CI issue, you can get complete unsilenced logs # by un-commenting the following line (or setting VERBOSE_LOGS in your environment): -# VERBOSE_LOGS=1 +# export VERBOSE_LOGS=1 # don't silence invocations containing these arguments export NO_SILENCE=" --version " diff --git a/tests/scripts/quiet/make b/tests/scripts/quiet/make index 24e77951c2..b2323166df 100755 --- a/tests/scripts/quiet/make +++ b/tests/scripts/quiet/make @@ -8,7 +8,7 @@ # If you are debugging a build / CI issue, you can get complete unsilenced logs # by un-commenting the following line (or setting VERBOSE_LOGS in your environment): -# VERBOSE_LOGS=1 +# export VERBOSE_LOGS=1 # don't silence invocations containing these arguments export NO_SILENCE=" --version | test " From 87218b364dfa1ce1c92b1ef1c118a42cce2eace7 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 29 Feb 2024 15:01:29 +0000 Subject: [PATCH 061/123] blank line for readability Signed-off-by: Dave Rodgman --- tests/scripts/quiet/cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/scripts/quiet/cmake b/tests/scripts/quiet/cmake index 854375ecb4..930931d539 100755 --- a/tests/scripts/quiet/cmake +++ b/tests/scripts/quiet/cmake @@ -8,6 +8,7 @@ # If you are debugging a build / CI issue, you can get complete unsilenced logs # by un-commenting the following line (or setting VERBOSE_LOGS in your environment): + # export VERBOSE_LOGS=1 # don't silence invocations containing these arguments From d32dd08934b7e7b2e1c55f3641570d68695d9e68 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 29 Feb 2024 16:28:03 +0100 Subject: [PATCH 062/123] changelog: fix description Signed-off-by: Valerio Setti --- ChangeLog.d/8848.txt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ChangeLog.d/8848.txt b/ChangeLog.d/8848.txt index 682f4f068f..71bb7e3a68 100644 --- a/ChangeLog.d/8848.txt +++ b/ChangeLog.d/8848.txt @@ -1,5 +1,6 @@ -New deprecations - * mbedtls_pk_wrap_as_opaque() is deprecated. To mimic the same behavior - mbedtls_pk_get_psa_attributes() and mbedtls_pk_import_into_psa() can be - used to import a PK key into PSA, while mbedtls_pk_setup_opaque() can - be used to wrap a PSA key into a opaque PK context. +Removals + * Temporary function mbedtls_pk_wrap_as_opaque() is removed. To mimic the + same behavior mbedtls_pk_get_psa_attributes() and + mbedtls_pk_import_into_psa() can be used to import a PK key into PSA, + while mbedtls_pk_setup_opaque() can be used to wrap a PSA key into a opaque + PK context. From 5c5a32f52a6b0ec75dc071c26f14dc4592364098 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 13 Feb 2024 17:53:35 +0000 Subject: [PATCH 063/123] Add session config bit for KEEP_PEER_CERTIFICATE This config option decides whether the session stores the entire certificate or just a digest of it, but was missing from the serialization config bitflag. Signed-off-by: David Horstmann --- library/ssl_tls.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 5b0a4b97ab..f229360411 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3662,6 +3662,12 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, #define SSL_SERIALIZED_SESSION_CONFIG_CRT 0 #endif /* MBEDTLS_X509_CRT_PARSE_C */ +#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) +#define SSL_SERIALIZED_SESSION_KEEP_PEER_CRT 1 +#else +#define SSL_SERIALIZED_SESSION_KEEP_PEER_CRT 0 +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ + #if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_SESSION_TICKETS) #define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET 1 #else @@ -3692,6 +3698,7 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, #define SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT 3 #define SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT 4 #define SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT 5 +#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_CRT_BIT 6 #define SSL_SERIALIZED_SESSION_CONFIG_BITFLAG \ ((uint16_t) ( \ @@ -3701,7 +3708,8 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT) | \ (SSL_SERIALIZED_SESSION_CONFIG_MFL << SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT) | \ (SSL_SERIALIZED_SESSION_CONFIG_ETM << SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT) | \ - (SSL_SERIALIZED_SESSION_CONFIG_TICKET << SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT))) + (SSL_SERIALIZED_SESSION_CONFIG_TICKET << SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT) | \ + (SSL_SERIALIZED_SESSION_KEEP_PEER_CRT << SSL_SERIALIZED_SESSION_CONFIG_KEEP_CRT_BIT))) static const unsigned char ssl_serialized_session_header[] = { MBEDTLS_VERSION_MAJOR, From 92b258bb507ea43ad64b83323f8ddc4521ee2126 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 13 Feb 2024 17:23:34 +0000 Subject: [PATCH 064/123] Update ssl session serialization config bitflag Add config bits for server name indication, early data and record size limit, which all cause the serialized session to be structured differently. Signed-off-by: David Horstmann --- library/ssl_tls.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index f229360411..54db0a1f8b 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3692,6 +3692,24 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, #define SSL_SERIALIZED_SESSION_CONFIG_TICKET 0 #endif /* MBEDTLS_SSL_SESSION_TICKETS */ +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) +#define SSL_SERIALIZED_SESSION_CONFIG_SNI 1 +#else +#define SSL_SERIALIZED_SESSION_CONFIG_SNI 0 +#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ + +#if defined(MBEDTLS_SSL_EARLY_DATA) +#define SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA 1 +#else +#define SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA 0 +#endif /* MBEDTLS_SSL_EARLY_DATA */ + +#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) +#define SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE 1 +#else +#define SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE 0 +#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ + #define SSL_SERIALIZED_SESSION_CONFIG_TIME_BIT 0 #define SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT 1 #define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT 2 @@ -3699,6 +3717,9 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, #define SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT 4 #define SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT 5 #define SSL_SERIALIZED_SESSION_CONFIG_KEEP_CRT_BIT 6 +#define SSL_SERIALIZED_SESSION_CONFIG_SNI_BIT 7 +#define SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA_BIT 8 +#define SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE_BIT 9 #define SSL_SERIALIZED_SESSION_CONFIG_BITFLAG \ ((uint16_t) ( \ @@ -3709,7 +3730,12 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, (SSL_SERIALIZED_SESSION_CONFIG_MFL << SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT) | \ (SSL_SERIALIZED_SESSION_CONFIG_ETM << SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT) | \ (SSL_SERIALIZED_SESSION_CONFIG_TICKET << SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT) | \ - (SSL_SERIALIZED_SESSION_KEEP_PEER_CRT << SSL_SERIALIZED_SESSION_CONFIG_KEEP_CRT_BIT))) + (SSL_SERIALIZED_SESSION_KEEP_PEER_CRT << SSL_SERIALIZED_SESSION_CONFIG_KEEP_CRT_BIT) | \ + (SSL_SERIALIZED_SESSION_CONFIG_SNI << SSL_SERIALIZED_SESSION_CONFIG_SNI_BIT) | \ + (SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA << \ + SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA_BIT) | \ + (SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE << \ + SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE_BIT))) static const unsigned char ssl_serialized_session_header[] = { MBEDTLS_VERSION_MAJOR, From e59f970f2874260011f328085c2fbcdb31fb02fb Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 29 Feb 2024 16:08:57 +0000 Subject: [PATCH 065/123] Move session functions to same part of file Ensure that session save and load functions are not scattered throughout ssl_tls.c but are in the same part of the file. Signed-off-by: David Horstmann --- library/ssl_tls.c | 1317 ++++++++++++++++++++++----------------------- 1 file changed, 658 insertions(+), 659 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 54db0a1f8b..870f7d9388 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -432,10 +432,6 @@ static int ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *, unsigned char static int ssl_calc_finished_tls_sha384(mbedtls_ssl_context *, unsigned char *, int); #endif /* MBEDTLS_MD_CAN_SHA384*/ -static size_t ssl_tls12_session_save(const mbedtls_ssl_session *session, - unsigned char *buf, - size_t buf_len); - MBEDTLS_CHECK_RETURN_CRITICAL static int ssl_tls12_session_load(mbedtls_ssl_session *session, const unsigned char *buf, @@ -2448,282 +2444,6 @@ mbedtls_ssl_mode_t mbedtls_ssl_get_mode_from_ciphersuite( #if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3) -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) -/* Serialization of TLS 1.3 sessions: - * - * struct { - * opaque hostname<0..2^16-1>; - * uint64 ticket_reception_time; - * uint32 ticket_lifetime; - * opaque ticket<1..2^16-1>; - * } ClientOnlyData; - * - * struct { - * uint32 ticket_age_add; - * uint8 ticket_flags; - * opaque resumption_key<0..255>; - * uint32 max_early_data_size; - * uint16 record_size_limit; - * select ( endpoint ) { - * case client: ClientOnlyData; - * case server: uint64 ticket_creation_time; - * }; - * } serialized_session_tls13; - * - */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_session_save(const mbedtls_ssl_session *session, - unsigned char *buf, - size_t buf_len, - size_t *olen) -{ - unsigned char *p = buf; -#if defined(MBEDTLS_SSL_CLI_C) && \ - defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - size_t hostname_len = (session->hostname == NULL) ? - 0 : strlen(session->hostname) + 1; -#endif - size_t needed = 4 /* ticket_age_add */ - + 1 /* ticket_flags */ - + 1; /* resumption_key length */ - *olen = 0; - - if (session->resumption_key_len > MBEDTLS_SSL_TLS1_3_TICKET_RESUMPTION_KEY_LEN) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - needed += session->resumption_key_len; /* resumption_key */ - -#if defined(MBEDTLS_SSL_EARLY_DATA) - needed += 4; /* max_early_data_size */ -#endif -#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) - needed += 2; /* record_size_limit */ -#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ - -#if defined(MBEDTLS_HAVE_TIME) - needed += 8; /* ticket_creation_time or ticket_reception_time */ -#endif - -#if defined(MBEDTLS_SSL_CLI_C) - if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) { -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - needed += 2 /* hostname_len */ - + hostname_len; /* hostname */ -#endif - - needed += 4 /* ticket_lifetime */ - + 2; /* ticket_len */ - - /* Check size_t overflow */ - if (session->ticket_len > SIZE_MAX - needed) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - needed += session->ticket_len; /* ticket */ - } -#endif /* MBEDTLS_SSL_CLI_C */ - - *olen = needed; - if (needed > buf_len) { - return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - } - - MBEDTLS_PUT_UINT32_BE(session->ticket_age_add, p, 0); - p[4] = session->ticket_flags; - - /* save resumption_key */ - p[5] = session->resumption_key_len; - p += 6; - memcpy(p, session->resumption_key, session->resumption_key_len); - p += session->resumption_key_len; - -#if defined(MBEDTLS_SSL_EARLY_DATA) - MBEDTLS_PUT_UINT32_BE(session->max_early_data_size, p, 0); - p += 4; -#endif -#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) - MBEDTLS_PUT_UINT16_BE(session->record_size_limit, p, 0); - p += 2; -#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ - -#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C) - if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { - MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_creation_time, p, 0); - p += 8; - } -#endif /* MBEDTLS_HAVE_TIME */ - -#if defined(MBEDTLS_SSL_CLI_C) - if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) { -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - MBEDTLS_PUT_UINT16_BE(hostname_len, p, 0); - p += 2; - if (hostname_len > 0) { - /* save host name */ - memcpy(p, session->hostname, hostname_len); - p += hostname_len; - } -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_HAVE_TIME) - MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_reception_time, p, 0); - p += 8; -#endif - MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0); - p += 4; - - MBEDTLS_PUT_UINT16_BE(session->ticket_len, p, 0); - p += 2; - - if (session->ticket != NULL && session->ticket_len > 0) { - memcpy(p, session->ticket, session->ticket_len); - p += session->ticket_len; - } - } -#endif /* MBEDTLS_SSL_CLI_C */ - return 0; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_session_load(mbedtls_ssl_session *session, - const unsigned char *buf, - size_t len) -{ - const unsigned char *p = buf; - const unsigned char *end = buf + len; - - if (end - p < 6) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - session->ticket_age_add = MBEDTLS_GET_UINT32_BE(p, 0); - session->ticket_flags = p[4]; - - /* load resumption_key */ - session->resumption_key_len = p[5]; - p += 6; - - if (end - p < session->resumption_key_len) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (sizeof(session->resumption_key) < session->resumption_key_len) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - memcpy(session->resumption_key, p, session->resumption_key_len); - p += session->resumption_key_len; - -#if defined(MBEDTLS_SSL_EARLY_DATA) - if (end - p < 4) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - session->max_early_data_size = MBEDTLS_GET_UINT32_BE(p, 0); - p += 4; -#endif -#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) - if (end - p < 2) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - session->record_size_limit = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; -#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ - -#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C) - if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { - if (end - p < 8) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - session->ticket_creation_time = MBEDTLS_GET_UINT64_BE(p, 0); - p += 8; - } -#endif /* MBEDTLS_HAVE_TIME */ - -#if defined(MBEDTLS_SSL_CLI_C) - if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) { -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - size_t hostname_len; - /* load host name */ - if (end - p < 2) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - hostname_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - if (end - p < (long int) hostname_len) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - if (hostname_len > 0) { - session->hostname = mbedtls_calloc(1, hostname_len); - if (session->hostname == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - memcpy(session->hostname, p, hostname_len); - p += hostname_len; - } -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_HAVE_TIME) - if (end - p < 8) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - session->ticket_reception_time = MBEDTLS_GET_UINT64_BE(p, 0); - p += 8; -#endif - if (end - p < 4) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0); - p += 4; - - if (end - p < 2) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - session->ticket_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - if (end - p < (long int) session->ticket_len) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - if (session->ticket_len > 0) { - session->ticket = mbedtls_calloc(1, session->ticket_len); - if (session->ticket == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - memcpy(session->ticket, p, session->ticket_len); - p += session->ticket_len; - } - } -#endif /* MBEDTLS_SSL_CLI_C */ - - return 0; - -} -#else /* MBEDTLS_SSL_SESSION_TICKETS */ -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_session_save(const mbedtls_ssl_session *session, - unsigned char *buf, - size_t buf_len, - size_t *olen) -{ - ((void) session); - ((void) buf); - ((void) buf_len); - *olen = 0; - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; -} - -static int ssl_tls13_session_load(const mbedtls_ssl_session *session, - unsigned char *buf, - size_t buf_len) -{ - ((void) session); - ((void) buf); - ((void) buf_len); - return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; -} -#endif /* !MBEDTLS_SSL_SESSION_TICKETS */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ - psa_status_t mbedtls_ssl_cipher_to_psa(mbedtls_cipher_type_t mbedtls_cipher_type, size_t taglen, psa_algorithm_t *alg, @@ -3640,6 +3360,664 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_CLI_C */ +/* Serialization of TLS 1.2 sessions: + * + * struct { + * opaque ticket<0..2^24-1>; // length 0 means no ticket + * uint32 ticket_lifetime; + * } ClientOnlyData; + * + * struct { + * uint64 start_time; + * uint8 session_id_len; // at most 32 + * opaque session_id[32]; + * opaque master[48]; // fixed length in the standard + * uint32 verify_result; + * opaque peer_cert<0..2^24-1>; // length 0 means no peer cert + * select (endpoint) { + * case client: ClientOnlyData; + * case server: uint64 ticket_creation_time; + * }; + * uint8 mfl_code; // up to 255 according to standard + * uint8 encrypt_then_mac; // 0 or 1 + * } serialized_session_tls12; + */ +static size_t ssl_tls12_session_save(const mbedtls_ssl_session *session, + unsigned char *buf, + size_t buf_len) +{ + unsigned char *p = buf; + size_t used = 0; + +#if defined(MBEDTLS_HAVE_TIME) + uint64_t start; +#endif +#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) + size_t cert_len; +#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + + /* + * Time + */ +#if defined(MBEDTLS_HAVE_TIME) + used += 8; + + if (used <= buf_len) { + start = (uint64_t) session->start; + + MBEDTLS_PUT_UINT64_BE(start, p, 0); + p += 8; + } +#endif /* MBEDTLS_HAVE_TIME */ + + /* + * Basic mandatory fields + */ + used += 1 /* id_len */ + + sizeof(session->id) + + sizeof(session->master) + + 4; /* verify_result */ + + if (used <= buf_len) { + *p++ = MBEDTLS_BYTE_0(session->id_len); + memcpy(p, session->id, 32); + p += 32; + + memcpy(p, session->master, 48); + p += 48; + + MBEDTLS_PUT_UINT32_BE(session->verify_result, p, 0); + p += 4; + } + + /* + * Peer's end-entity certificate + */ +#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) + if (session->peer_cert == NULL) { + cert_len = 0; + } else { + cert_len = session->peer_cert->raw.len; + } + + used += 3 + cert_len; + + if (used <= buf_len) { + *p++ = MBEDTLS_BYTE_2(cert_len); + *p++ = MBEDTLS_BYTE_1(cert_len); + *p++ = MBEDTLS_BYTE_0(cert_len); + + if (session->peer_cert != NULL) { + memcpy(p, session->peer_cert->raw.p, cert_len); + p += cert_len; + } + } +#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ + if (session->peer_cert_digest != NULL) { + used += 1 /* type */ + 1 /* length */ + session->peer_cert_digest_len; + if (used <= buf_len) { + *p++ = (unsigned char) session->peer_cert_digest_type; + *p++ = (unsigned char) session->peer_cert_digest_len; + memcpy(p, session->peer_cert_digest, + session->peer_cert_digest_len); + p += session->peer_cert_digest_len; + } + } else { + used += 2; + if (used <= buf_len) { + *p++ = (unsigned char) MBEDTLS_MD_NONE; + *p++ = 0; + } + } +#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + + /* + * Session ticket if any, plus associated data + */ +#if defined(MBEDTLS_SSL_SESSION_TICKETS) +#if defined(MBEDTLS_SSL_CLI_C) + if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) { + used += 3 + session->ticket_len + 4; /* len + ticket + lifetime */ + + if (used <= buf_len) { + *p++ = MBEDTLS_BYTE_2(session->ticket_len); + *p++ = MBEDTLS_BYTE_1(session->ticket_len); + *p++ = MBEDTLS_BYTE_0(session->ticket_len); + + if (session->ticket != NULL) { + memcpy(p, session->ticket, session->ticket_len); + p += session->ticket_len; + } + + MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0); + p += 4; + } + } +#endif /* MBEDTLS_SSL_CLI_C */ +#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C) + if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { + used += 8; + + if (used <= buf_len) { + MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_creation_time, p, 0); + p += 8; + } + } +#endif /* MBEDTLS_HAVE_TIME && MBEDTLS_SSL_SRV_C */ +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ + + /* + * Misc extension-related info + */ +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) + used += 1; + + if (used <= buf_len) { + *p++ = session->mfl_code; + } +#endif + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + used += 1; + + if (used <= buf_len) { + *p++ = MBEDTLS_BYTE_0(session->encrypt_then_mac); + } +#endif + + return used; +} + +MBEDTLS_CHECK_RETURN_CRITICAL +static int ssl_tls12_session_load(mbedtls_ssl_session *session, + const unsigned char *buf, + size_t len) +{ +#if defined(MBEDTLS_HAVE_TIME) + uint64_t start; +#endif +#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) + size_t cert_len; +#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + + const unsigned char *p = buf; + const unsigned char * const end = buf + len; + + /* + * Time + */ +#if defined(MBEDTLS_HAVE_TIME) + if (8 > (size_t) (end - p)) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + start = MBEDTLS_GET_UINT64_BE(p, 0); + p += 8; + + session->start = (time_t) start; +#endif /* MBEDTLS_HAVE_TIME */ + + /* + * Basic mandatory fields + */ + if (1 + 32 + 48 + 4 > (size_t) (end - p)) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + session->id_len = *p++; + memcpy(session->id, p, 32); + p += 32; + + memcpy(session->master, p, 48); + p += 48; + + session->verify_result = MBEDTLS_GET_UINT32_BE(p, 0); + p += 4; + + /* Immediately clear invalid pointer values that have been read, in case + * we exit early before we replaced them with valid ones. */ +#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) + session->peer_cert = NULL; +#else + session->peer_cert_digest = NULL; +#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ +#endif /* MBEDTLS_X509_CRT_PARSE_C */ +#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) + session->ticket = NULL; +#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ + + /* + * Peer certificate + */ +#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) + /* Deserialize CRT from the end of the ticket. */ + if (3 > (size_t) (end - p)) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + cert_len = MBEDTLS_GET_UINT24_BE(p, 0); + p += 3; + + if (cert_len != 0) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + if (cert_len > (size_t) (end - p)) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + session->peer_cert = mbedtls_calloc(1, sizeof(mbedtls_x509_crt)); + + if (session->peer_cert == NULL) { + return MBEDTLS_ERR_SSL_ALLOC_FAILED; + } + + mbedtls_x509_crt_init(session->peer_cert); + + if ((ret = mbedtls_x509_crt_parse_der(session->peer_cert, + p, cert_len)) != 0) { + mbedtls_x509_crt_free(session->peer_cert); + mbedtls_free(session->peer_cert); + session->peer_cert = NULL; + return ret; + } + + p += cert_len; + } +#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ + /* Deserialize CRT digest from the end of the ticket. */ + if (2 > (size_t) (end - p)) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + session->peer_cert_digest_type = (mbedtls_md_type_t) *p++; + session->peer_cert_digest_len = (size_t) *p++; + + if (session->peer_cert_digest_len != 0) { + const mbedtls_md_info_t *md_info = + mbedtls_md_info_from_type(session->peer_cert_digest_type); + if (md_info == NULL) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + if (session->peer_cert_digest_len != mbedtls_md_get_size(md_info)) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + if (session->peer_cert_digest_len > (size_t) (end - p)) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + session->peer_cert_digest = + mbedtls_calloc(1, session->peer_cert_digest_len); + if (session->peer_cert_digest == NULL) { + return MBEDTLS_ERR_SSL_ALLOC_FAILED; + } + + memcpy(session->peer_cert_digest, p, + session->peer_cert_digest_len); + p += session->peer_cert_digest_len; + } +#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + + /* + * Session ticket and associated data + */ +#if defined(MBEDTLS_SSL_SESSION_TICKETS) +#if defined(MBEDTLS_SSL_CLI_C) + if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) { + if (3 > (size_t) (end - p)) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + session->ticket_len = MBEDTLS_GET_UINT24_BE(p, 0); + p += 3; + + if (session->ticket_len != 0) { + if (session->ticket_len > (size_t) (end - p)) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + session->ticket = mbedtls_calloc(1, session->ticket_len); + if (session->ticket == NULL) { + return MBEDTLS_ERR_SSL_ALLOC_FAILED; + } + + memcpy(session->ticket, p, session->ticket_len); + p += session->ticket_len; + } + + if (4 > (size_t) (end - p)) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0); + p += 4; + } +#endif /* MBEDTLS_SSL_CLI_C */ +#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C) + if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { + if (8 > (size_t) (end - p)) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + session->ticket_creation_time = MBEDTLS_GET_UINT64_BE(p, 0); + p += 8; + } +#endif /* MBEDTLS_HAVE_TIME && MBEDTLS_SSL_SRV_C */ +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ + + /* + * Misc extension-related info + */ +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) + if (1 > (size_t) (end - p)) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + session->mfl_code = *p++; +#endif + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + if (1 > (size_t) (end - p)) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + session->encrypt_then_mac = *p++; +#endif + + /* Done, should have consumed entire buffer */ + if (p != end) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + return 0; +} + +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1_3) +/* Serialization of TLS 1.3 sessions: + * + * struct { + * opaque hostname<0..2^16-1>; + * uint64 ticket_reception_time; + * uint32 ticket_lifetime; + * opaque ticket<1..2^16-1>; + * } ClientOnlyData; + * + * struct { + * uint32 ticket_age_add; + * uint8 ticket_flags; + * opaque resumption_key<0..255>; + * uint32 max_early_data_size; + * uint16 record_size_limit; + * select ( endpoint ) { + * case client: ClientOnlyData; + * case server: uint64 ticket_creation_time; + * }; + * } serialized_session_tls13; + * + */ +#if defined(MBEDTLS_SSL_SESSION_TICKETS) +MBEDTLS_CHECK_RETURN_CRITICAL +static int ssl_tls13_session_save(const mbedtls_ssl_session *session, + unsigned char *buf, + size_t buf_len, + size_t *olen) +{ + unsigned char *p = buf; +#if defined(MBEDTLS_SSL_CLI_C) && \ + defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + size_t hostname_len = (session->hostname == NULL) ? + 0 : strlen(session->hostname) + 1; +#endif + size_t needed = 4 /* ticket_age_add */ + + 1 /* ticket_flags */ + + 1; /* resumption_key length */ + *olen = 0; + + if (session->resumption_key_len > MBEDTLS_SSL_TLS1_3_TICKET_RESUMPTION_KEY_LEN) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + needed += session->resumption_key_len; /* resumption_key */ + +#if defined(MBEDTLS_SSL_EARLY_DATA) + needed += 4; /* max_early_data_size */ +#endif +#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) + needed += 2; /* record_size_limit */ +#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ + +#if defined(MBEDTLS_HAVE_TIME) + needed += 8; /* ticket_creation_time or ticket_reception_time */ +#endif + +#if defined(MBEDTLS_SSL_CLI_C) + if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) { +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + needed += 2 /* hostname_len */ + + hostname_len; /* hostname */ +#endif + + needed += 4 /* ticket_lifetime */ + + 2; /* ticket_len */ + + /* Check size_t overflow */ + if (session->ticket_len > SIZE_MAX - needed) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + needed += session->ticket_len; /* ticket */ + } +#endif /* MBEDTLS_SSL_CLI_C */ + + *olen = needed; + if (needed > buf_len) { + return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; + } + + MBEDTLS_PUT_UINT32_BE(session->ticket_age_add, p, 0); + p[4] = session->ticket_flags; + + /* save resumption_key */ + p[5] = session->resumption_key_len; + p += 6; + memcpy(p, session->resumption_key, session->resumption_key_len); + p += session->resumption_key_len; + +#if defined(MBEDTLS_SSL_EARLY_DATA) + MBEDTLS_PUT_UINT32_BE(session->max_early_data_size, p, 0); + p += 4; +#endif +#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) + MBEDTLS_PUT_UINT16_BE(session->record_size_limit, p, 0); + p += 2; +#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ + +#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C) + if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { + MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_creation_time, p, 0); + p += 8; + } +#endif /* MBEDTLS_HAVE_TIME */ + +#if defined(MBEDTLS_SSL_CLI_C) + if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) { +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + MBEDTLS_PUT_UINT16_BE(hostname_len, p, 0); + p += 2; + if (hostname_len > 0) { + /* save host name */ + memcpy(p, session->hostname, hostname_len); + p += hostname_len; + } +#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ + +#if defined(MBEDTLS_HAVE_TIME) + MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_reception_time, p, 0); + p += 8; +#endif + MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0); + p += 4; + + MBEDTLS_PUT_UINT16_BE(session->ticket_len, p, 0); + p += 2; + + if (session->ticket != NULL && session->ticket_len > 0) { + memcpy(p, session->ticket, session->ticket_len); + p += session->ticket_len; + } + } +#endif /* MBEDTLS_SSL_CLI_C */ + return 0; +} + +MBEDTLS_CHECK_RETURN_CRITICAL +static int ssl_tls13_session_load(mbedtls_ssl_session *session, + const unsigned char *buf, + size_t len) +{ + const unsigned char *p = buf; + const unsigned char *end = buf + len; + + if (end - p < 6) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + session->ticket_age_add = MBEDTLS_GET_UINT32_BE(p, 0); + session->ticket_flags = p[4]; + + /* load resumption_key */ + session->resumption_key_len = p[5]; + p += 6; + + if (end - p < session->resumption_key_len) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + if (sizeof(session->resumption_key) < session->resumption_key_len) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + memcpy(session->resumption_key, p, session->resumption_key_len); + p += session->resumption_key_len; + +#if defined(MBEDTLS_SSL_EARLY_DATA) + if (end - p < 4) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + session->max_early_data_size = MBEDTLS_GET_UINT32_BE(p, 0); + p += 4; +#endif +#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) + if (end - p < 2) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + session->record_size_limit = MBEDTLS_GET_UINT16_BE(p, 0); + p += 2; +#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ + +#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C) + if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { + if (end - p < 8) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + session->ticket_creation_time = MBEDTLS_GET_UINT64_BE(p, 0); + p += 8; + } +#endif /* MBEDTLS_HAVE_TIME */ + +#if defined(MBEDTLS_SSL_CLI_C) + if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) { +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + size_t hostname_len; + /* load host name */ + if (end - p < 2) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + hostname_len = MBEDTLS_GET_UINT16_BE(p, 0); + p += 2; + + if (end - p < (long int) hostname_len) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + if (hostname_len > 0) { + session->hostname = mbedtls_calloc(1, hostname_len); + if (session->hostname == NULL) { + return MBEDTLS_ERR_SSL_ALLOC_FAILED; + } + memcpy(session->hostname, p, hostname_len); + p += hostname_len; + } +#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ + +#if defined(MBEDTLS_HAVE_TIME) + if (end - p < 8) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + session->ticket_reception_time = MBEDTLS_GET_UINT64_BE(p, 0); + p += 8; +#endif + if (end - p < 4) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0); + p += 4; + + if (end - p < 2) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + session->ticket_len = MBEDTLS_GET_UINT16_BE(p, 0); + p += 2; + + if (end - p < (long int) session->ticket_len) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + if (session->ticket_len > 0) { + session->ticket = mbedtls_calloc(1, session->ticket_len); + if (session->ticket == NULL) { + return MBEDTLS_ERR_SSL_ALLOC_FAILED; + } + memcpy(session->ticket, p, session->ticket_len); + p += session->ticket_len; + } + } +#endif /* MBEDTLS_SSL_CLI_C */ + + return 0; + +} +#else /* MBEDTLS_SSL_SESSION_TICKETS */ +MBEDTLS_CHECK_RETURN_CRITICAL +static int ssl_tls13_session_save(const mbedtls_ssl_session *session, + unsigned char *buf, + size_t buf_len, + size_t *olen) +{ + ((void) session); + ((void) buf); + ((void) buf_len); + *olen = 0; + return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; +} + +static int ssl_tls13_session_load(const mbedtls_ssl_session *session, + unsigned char *buf, + size_t buf_len) +{ + ((void) session); + ((void) buf); + ((void) buf_len); + return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; +} +#endif /* !MBEDTLS_SSL_SESSION_TICKETS */ +#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ + /* * Define ticket header determining Mbed TLS version * and structure of the ticket. @@ -8982,385 +9360,6 @@ unsigned int mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg( #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ -/* Serialization of TLS 1.2 sessions: - * - * struct { - * opaque ticket<0..2^24-1>; // length 0 means no ticket - * uint32 ticket_lifetime; - * } ClientOnlyData; - * - * struct { - * uint64 start_time; - * uint8 session_id_len; // at most 32 - * opaque session_id[32]; - * opaque master[48]; // fixed length in the standard - * uint32 verify_result; - * opaque peer_cert<0..2^24-1>; // length 0 means no peer cert - * select (endpoint) { - * case client: ClientOnlyData; - * case server: uint64 ticket_creation_time; - * }; - * uint8 mfl_code; // up to 255 according to standard - * uint8 encrypt_then_mac; // 0 or 1 - * } serialized_session_tls12; - */ -static size_t ssl_tls12_session_save(const mbedtls_ssl_session *session, - unsigned char *buf, - size_t buf_len) -{ - unsigned char *p = buf; - size_t used = 0; - -#if defined(MBEDTLS_HAVE_TIME) - uint64_t start; -#endif -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - size_t cert_len; -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - /* - * Time - */ -#if defined(MBEDTLS_HAVE_TIME) - used += 8; - - if (used <= buf_len) { - start = (uint64_t) session->start; - - MBEDTLS_PUT_UINT64_BE(start, p, 0); - p += 8; - } -#endif /* MBEDTLS_HAVE_TIME */ - - /* - * Basic mandatory fields - */ - used += 1 /* id_len */ - + sizeof(session->id) - + sizeof(session->master) - + 4; /* verify_result */ - - if (used <= buf_len) { - *p++ = MBEDTLS_BYTE_0(session->id_len); - memcpy(p, session->id, 32); - p += 32; - - memcpy(p, session->master, 48); - p += 48; - - MBEDTLS_PUT_UINT32_BE(session->verify_result, p, 0); - p += 4; - } - - /* - * Peer's end-entity certificate - */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - if (session->peer_cert == NULL) { - cert_len = 0; - } else { - cert_len = session->peer_cert->raw.len; - } - - used += 3 + cert_len; - - if (used <= buf_len) { - *p++ = MBEDTLS_BYTE_2(cert_len); - *p++ = MBEDTLS_BYTE_1(cert_len); - *p++ = MBEDTLS_BYTE_0(cert_len); - - if (session->peer_cert != NULL) { - memcpy(p, session->peer_cert->raw.p, cert_len); - p += cert_len; - } - } -#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - if (session->peer_cert_digest != NULL) { - used += 1 /* type */ + 1 /* length */ + session->peer_cert_digest_len; - if (used <= buf_len) { - *p++ = (unsigned char) session->peer_cert_digest_type; - *p++ = (unsigned char) session->peer_cert_digest_len; - memcpy(p, session->peer_cert_digest, - session->peer_cert_digest_len); - p += session->peer_cert_digest_len; - } - } else { - used += 2; - if (used <= buf_len) { - *p++ = (unsigned char) MBEDTLS_MD_NONE; - *p++ = 0; - } - } -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - /* - * Session ticket if any, plus associated data - */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -#if defined(MBEDTLS_SSL_CLI_C) - if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) { - used += 3 + session->ticket_len + 4; /* len + ticket + lifetime */ - - if (used <= buf_len) { - *p++ = MBEDTLS_BYTE_2(session->ticket_len); - *p++ = MBEDTLS_BYTE_1(session->ticket_len); - *p++ = MBEDTLS_BYTE_0(session->ticket_len); - - if (session->ticket != NULL) { - memcpy(p, session->ticket, session->ticket_len); - p += session->ticket_len; - } - - MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0); - p += 4; - } - } -#endif /* MBEDTLS_SSL_CLI_C */ -#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C) - if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { - used += 8; - - if (used <= buf_len) { - MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_creation_time, p, 0); - p += 8; - } - } -#endif /* MBEDTLS_HAVE_TIME && MBEDTLS_SSL_SRV_C */ -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - - /* - * Misc extension-related info - */ -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - used += 1; - - if (used <= buf_len) { - *p++ = session->mfl_code; - } -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - used += 1; - - if (used <= buf_len) { - *p++ = MBEDTLS_BYTE_0(session->encrypt_then_mac); - } -#endif - - return used; -} - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls12_session_load(mbedtls_ssl_session *session, - const unsigned char *buf, - size_t len) -{ -#if defined(MBEDTLS_HAVE_TIME) - uint64_t start; -#endif -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - size_t cert_len; -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - const unsigned char *p = buf; - const unsigned char * const end = buf + len; - - /* - * Time - */ -#if defined(MBEDTLS_HAVE_TIME) - if (8 > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - start = MBEDTLS_GET_UINT64_BE(p, 0); - p += 8; - - session->start = (time_t) start; -#endif /* MBEDTLS_HAVE_TIME */ - - /* - * Basic mandatory fields - */ - if (1 + 32 + 48 + 4 > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - session->id_len = *p++; - memcpy(session->id, p, 32); - p += 32; - - memcpy(session->master, p, 48); - p += 48; - - session->verify_result = MBEDTLS_GET_UINT32_BE(p, 0); - p += 4; - - /* Immediately clear invalid pointer values that have been read, in case - * we exit early before we replaced them with valid ones. */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - session->peer_cert = NULL; -#else - session->peer_cert_digest = NULL; -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) - session->ticket = NULL; -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ - - /* - * Peer certificate - */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - /* Deserialize CRT from the end of the ticket. */ - if (3 > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - cert_len = MBEDTLS_GET_UINT24_BE(p, 0); - p += 3; - - if (cert_len != 0) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if (cert_len > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - session->peer_cert = mbedtls_calloc(1, sizeof(mbedtls_x509_crt)); - - if (session->peer_cert == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - mbedtls_x509_crt_init(session->peer_cert); - - if ((ret = mbedtls_x509_crt_parse_der(session->peer_cert, - p, cert_len)) != 0) { - mbedtls_x509_crt_free(session->peer_cert); - mbedtls_free(session->peer_cert); - session->peer_cert = NULL; - return ret; - } - - p += cert_len; - } -#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - /* Deserialize CRT digest from the end of the ticket. */ - if (2 > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - session->peer_cert_digest_type = (mbedtls_md_type_t) *p++; - session->peer_cert_digest_len = (size_t) *p++; - - if (session->peer_cert_digest_len != 0) { - const mbedtls_md_info_t *md_info = - mbedtls_md_info_from_type(session->peer_cert_digest_type); - if (md_info == NULL) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - if (session->peer_cert_digest_len != mbedtls_md_get_size(md_info)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - if (session->peer_cert_digest_len > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - session->peer_cert_digest = - mbedtls_calloc(1, session->peer_cert_digest_len); - if (session->peer_cert_digest == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - memcpy(session->peer_cert_digest, p, - session->peer_cert_digest_len); - p += session->peer_cert_digest_len; - } -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - /* - * Session ticket and associated data - */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -#if defined(MBEDTLS_SSL_CLI_C) - if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) { - if (3 > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - session->ticket_len = MBEDTLS_GET_UINT24_BE(p, 0); - p += 3; - - if (session->ticket_len != 0) { - if (session->ticket_len > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - session->ticket = mbedtls_calloc(1, session->ticket_len); - if (session->ticket == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - - memcpy(session->ticket, p, session->ticket_len); - p += session->ticket_len; - } - - if (4 > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0); - p += 4; - } -#endif /* MBEDTLS_SSL_CLI_C */ -#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C) - if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { - if (8 > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - session->ticket_creation_time = MBEDTLS_GET_UINT64_BE(p, 0); - p += 8; - } -#endif /* MBEDTLS_HAVE_TIME && MBEDTLS_SSL_SRV_C */ -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - - /* - * Misc extension-related info - */ -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - if (1 > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - session->mfl_code = *p++; -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - if (1 > (size_t) (end - p)) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - session->encrypt_then_mac = *p++; -#endif - - /* Done, should have consumed entire buffer */ - if (p != end) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - - return 0; -} #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ int mbedtls_ssl_validate_ciphersuite( From 80a9668762de6a3486b8addd334ca565f2a61712 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 29 Feb 2024 17:10:57 +0000 Subject: [PATCH 066/123] Add config guards to session struct comments This shows which fields of the session are dependent on which config options. Signed-off-by: David Horstmann --- library/ssl_tls.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 870f7d9388..699de40a7d 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3363,23 +3363,35 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, /* Serialization of TLS 1.2 sessions: * * struct { - * opaque ticket<0..2^24-1>; // length 0 means no ticket - * uint32 ticket_lifetime; + * #if defined(MBEDTLS_SSL_SESSION_TICKETS) + * opaque ticket<0..2^24-1>; // length 0 means no ticket + * uint32 ticket_lifetime; + * #endif * } ClientOnlyData; * * struct { - * uint64 start_time; + * #if defined(MBEDTLS_HAVE_TIME) + * uint64 start_time; + * #endif * uint8 session_id_len; // at most 32 * opaque session_id[32]; * opaque master[48]; // fixed length in the standard * uint32 verify_result; - * opaque peer_cert<0..2^24-1>; // length 0 means no peer cert + * #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE + * opaque peer_cert<0..2^24-1>; // length 0 means no peer cert + * #else + * opaque peer_cert_digest<0..2^8-1> + * #endif * select (endpoint) { * case client: ClientOnlyData; * case server: uint64 ticket_creation_time; * }; - * uint8 mfl_code; // up to 255 according to standard - * uint8 encrypt_then_mac; // 0 or 1 + * #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) + * uint8 mfl_code; // up to 255 according to standard + * #endif + * #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + * uint8 encrypt_then_mac; // 0 or 1 + * #endif * } serialized_session_tls12; */ static size_t ssl_tls12_session_save(const mbedtls_ssl_session *session, @@ -3746,8 +3758,12 @@ static int ssl_tls12_session_load(mbedtls_ssl_session *session, /* Serialization of TLS 1.3 sessions: * * struct { + * #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) * opaque hostname<0..2^16-1>; + * #endif + * #if defined(MBEDTLS_HAVE_TIME) * uint64 ticket_reception_time; + * #endif * uint32 ticket_lifetime; * opaque ticket<1..2^16-1>; * } ClientOnlyData; @@ -3756,11 +3772,17 @@ static int ssl_tls12_session_load(mbedtls_ssl_session *session, * uint32 ticket_age_add; * uint8 ticket_flags; * opaque resumption_key<0..255>; + * #if defined(MBEDTLS_SSL_EARLY_DATA) * uint32 max_early_data_size; + * #endif + * #if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) * uint16 record_size_limit; + * #endif * select ( endpoint ) { * case client: ClientOnlyData; + * #if defined(MBEDTLS_HAVE_TIME) * case server: uint64 ticket_creation_time; + * #endif * }; * } serialized_session_tls13; * From cb01b361e1f67cfa636615abd47f5946cc2df49d Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 29 Feb 2024 17:31:46 +0000 Subject: [PATCH 067/123] Move session descriptions into a single comment Describe the TLS 1.2, TLS 1.3 and full session structs in the same place for ease of reference. Signed-off-by: David Horstmann --- library/ssl_tls.c | 137 +++++++++++++++++++++++++--------------------- 1 file changed, 75 insertions(+), 62 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 699de40a7d..c56df86ddf 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3360,39 +3360,11 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_CLI_C */ -/* Serialization of TLS 1.2 sessions: +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + +/* Serialization of TLS 1.2 sessions * - * struct { - * #if defined(MBEDTLS_SSL_SESSION_TICKETS) - * opaque ticket<0..2^24-1>; // length 0 means no ticket - * uint32 ticket_lifetime; - * #endif - * } ClientOnlyData; - * - * struct { - * #if defined(MBEDTLS_HAVE_TIME) - * uint64 start_time; - * #endif - * uint8 session_id_len; // at most 32 - * opaque session_id[32]; - * opaque master[48]; // fixed length in the standard - * uint32 verify_result; - * #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE - * opaque peer_cert<0..2^24-1>; // length 0 means no peer cert - * #else - * opaque peer_cert_digest<0..2^8-1> - * #endif - * select (endpoint) { - * case client: ClientOnlyData; - * case server: uint64 ticket_creation_time; - * }; - * #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - * uint8 mfl_code; // up to 255 according to standard - * #endif - * #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - * uint8 encrypt_then_mac; // 0 or 1 - * #endif - * } serialized_session_tls12; + * For more detail, see the description of ssl_session_save(). */ static size_t ssl_tls12_session_save(const mbedtls_ssl_session *session, unsigned char *buf, @@ -3757,35 +3729,7 @@ static int ssl_tls12_session_load(mbedtls_ssl_session *session, #if defined(MBEDTLS_SSL_PROTO_TLS1_3) /* Serialization of TLS 1.3 sessions: * - * struct { - * #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - * opaque hostname<0..2^16-1>; - * #endif - * #if defined(MBEDTLS_HAVE_TIME) - * uint64 ticket_reception_time; - * #endif - * uint32 ticket_lifetime; - * opaque ticket<1..2^16-1>; - * } ClientOnlyData; - * - * struct { - * uint32 ticket_age_add; - * uint8 ticket_flags; - * opaque resumption_key<0..255>; - * #if defined(MBEDTLS_SSL_EARLY_DATA) - * uint32 max_early_data_size; - * #endif - * #if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) - * uint16 record_size_limit; - * #endif - * select ( endpoint ) { - * case client: ClientOnlyData; - * #if defined(MBEDTLS_HAVE_TIME) - * case server: uint64 ticket_creation_time; - * #endif - * }; - * } serialized_session_tls13; - * + * For more detail, see the description of ssl_session_save(). */ #if defined(MBEDTLS_SSL_SESSION_TICKETS) MBEDTLS_CHECK_RETURN_CRITICAL @@ -4149,7 +4093,76 @@ static const unsigned char ssl_serialized_session_header[] = { * Serialize a session in the following format: * (in the presentation language of TLS, RFC 8446 section 3) * - * struct { + * TLS 1.2 session: + * + * struct { + * #if defined(MBEDTLS_SSL_SESSION_TICKETS) + * opaque ticket<0..2^24-1>; // length 0 means no ticket + * uint32 ticket_lifetime; + * #endif + * } ClientOnlyData; + * + * struct { + * #if defined(MBEDTLS_HAVE_TIME) + * uint64 start_time; + * #endif + * uint8 session_id_len; // at most 32 + * opaque session_id[32]; + * opaque master[48]; // fixed length in the standard + * uint32 verify_result; + * #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE + * opaque peer_cert<0..2^24-1>; // length 0 means no peer cert + * #else + * opaque peer_cert_digest<0..2^8-1> + * #endif + * select (endpoint) { + * case client: ClientOnlyData; + * case server: uint64 ticket_creation_time; + * }; + * #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) + * uint8 mfl_code; // up to 255 according to standard + * #endif + * #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + * uint8 encrypt_then_mac; // 0 or 1 + * #endif + * } serialized_session_tls12; + * + * + * TLS 1.3 Session: + * + * struct { + * #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + * opaque hostname<0..2^16-1>; + * #endif + * #if defined(MBEDTLS_HAVE_TIME) + * uint64 ticket_reception_time; + * #endif + * uint32 ticket_lifetime; + * opaque ticket<1..2^16-1>; + * } ClientOnlyData; + * + * struct { + * uint32 ticket_age_add; + * uint8 ticket_flags; + * opaque resumption_key<0..255>; + * #if defined(MBEDTLS_SSL_EARLY_DATA) + * uint32 max_early_data_size; + * #endif + * #if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) + * uint16 record_size_limit; + * #endif + * select ( endpoint ) { + * case client: ClientOnlyData; + * #if defined(MBEDTLS_HAVE_TIME) + * case server: uint64 ticket_creation_time; + * #endif + * }; + * } serialized_session_tls13; + * + * + * SSL session: + * + * struct { * * opaque mbedtls_version[3]; // library version: major, minor, patch * opaque session_format[2]; // library-version specific 16-bit field From 531aca28103063dc75066346ee2a1e2bc2272218 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 29 Feb 2024 18:14:28 +0000 Subject: [PATCH 068/123] Fix missing fields in ssl session struct comment The endpoint and version were factorized out into the main session. Update the session struct comment to reflect these new fields, as was previously missed. Signed-off-by: David Horstmann --- library/ssl_tls.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index c56df86ddf..42bf670fda 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -4180,6 +4180,8 @@ static const unsigned char ssl_serialized_session_header[] = { * uint8_t minor_ver; // Protocol minor version. Possible values: * // - TLS 1.2 (0x0303) * // - TLS 1.3 (0x0304) + * uint8_t endpoint; + * uint16_t ciphersuite; * * select (serialized_session.tls_version) { * From 79aaaa46e9390d7752d2f76e941d69ec85c13441 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 29 Feb 2024 18:41:36 +0000 Subject: [PATCH 069/123] Fix formatting Signed-off-by: Dave Rodgman --- tests/scripts/quiet/make | 1 + tests/scripts/quiet/quiet.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/scripts/quiet/make b/tests/scripts/quiet/make index b2323166df..d022551df1 100755 --- a/tests/scripts/quiet/make +++ b/tests/scripts/quiet/make @@ -8,6 +8,7 @@ # If you are debugging a build / CI issue, you can get complete unsilenced logs # by un-commenting the following line (or setting VERBOSE_LOGS in your environment): + # export VERBOSE_LOGS=1 # don't silence invocations containing these arguments diff --git a/tests/scripts/quiet/quiet.sh b/tests/scripts/quiet/quiet.sh index 01ef422e32..30ee569a22 100755 --- a/tests/scripts/quiet/quiet.sh +++ b/tests/scripts/quiet/quiet.sh @@ -8,6 +8,7 @@ # If you are debugging a build / CI issue, you can get complete unsilenced logs # by un-commenting the following line (or setting VERBOSE_LOGS in your environment): +# # VERBOSE_LOGS=1 # # This script provides most of the functionality for the adjacent make and cmake From 5d3036e6d5f8269cb7c77b23128ff3be289e0d72 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 23 Feb 2024 07:43:45 +0100 Subject: [PATCH 070/123] tests: ssl: Add max_early_data_size option Signed-off-by: Ronald Cron --- tests/include/test/ssl_helpers.h | 1 + tests/src/test_helpers/ssl_helpers.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/tests/include/test/ssl_helpers.h b/tests/include/test/ssl_helpers.h index 5b071f75aa..71259d66f5 100644 --- a/tests/include/test/ssl_helpers.h +++ b/tests/include/test/ssl_helpers.h @@ -114,6 +114,7 @@ typedef struct mbedtls_test_handshake_test_options { void (*cli_log_fun)(void *, int, const char *, int, const char *); int resize_buffers; int early_data; + int max_early_data_size; #if defined(MBEDTLS_SSL_CACHE_C) mbedtls_ssl_cache_context *cache; #endif diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index 7a28bd8795..bf29b474a7 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -68,6 +68,7 @@ void mbedtls_test_init_handshake_options( opts->legacy_renegotiation = MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION; opts->resize_buffers = 1; opts->early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED; + opts->max_early_data_size = -1; #if defined(MBEDTLS_SSL_CACHE_C) TEST_CALLOC(opts->cache, 1); mbedtls_ssl_cache_init(opts->cache); @@ -815,6 +816,13 @@ int mbedtls_test_ssl_endpoint_init( #if defined(MBEDTLS_SSL_EARLY_DATA) mbedtls_ssl_conf_early_data(&(ep->conf), options->early_data); +#if defined(MBEDTLS_SSL_SRV_C) + if (endpoint_type == MBEDTLS_SSL_IS_SERVER && + (options->max_early_data_size >= 0)) { + mbedtls_ssl_conf_max_early_data_size(&(ep->conf), + options->max_early_data_size); + } +#endif #endif #if defined(MBEDTLS_SSL_CACHE_C) && defined(MBEDTLS_SSL_SRV_C) From 26a9811027cef5a8e87d033f56454a8dfe934d7c Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 23 Feb 2024 08:23:40 +0100 Subject: [PATCH 071/123] ssl: Add early_data_count field Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 5 ++++- library/ssl_tls.c | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 78395d2a67..15bd6fd7d3 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1859,7 +1859,8 @@ struct mbedtls_ssl_context { * within a single datagram. */ #endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C) +#if defined(MBEDTLS_SSL_EARLY_DATA) +#if defined(MBEDTLS_SSL_SRV_C) /* * One of: * MBEDTLS_SSL_EARLY_DATA_NO_DISCARD @@ -1868,6 +1869,8 @@ struct mbedtls_ssl_context { */ uint8_t MBEDTLS_PRIVATE(discard_early_data_record); #endif + uint32_t MBEDTLS_PRIVATE(early_data_count); /*!< Number of received/written early data bytes */ +#endif /* MBEDTLS_SSL_EARLY_DATA */ /* * Record layer (outgoing data) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 5b0a4b97ab..ee72179997 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1105,6 +1105,7 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl) #if defined(MBEDTLS_SSL_SRV_C) ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD; #endif + ssl->early_data_count = 0; #endif /* MBEDTLS_SSL_EARLY_DATA */ /* Initialize structures */ From c2865197478cddf22572c774481fb90db2c2f461 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 7 Feb 2024 14:01:03 +0100 Subject: [PATCH 072/123] tls13: srv: Do not forget to include max_early_data_size in the ticket Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 1 + 1 file changed, 1 insertion(+) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 3a968aa964..2391915357 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -3141,6 +3141,7 @@ static int ssl_tls13_prepare_new_session_ticket(mbedtls_ssl_context *ssl, ssl->conf->max_early_data_size > 0) { mbedtls_ssl_tls13_session_set_ticket_flags( session, MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA); + session->max_early_data_size = ssl->conf->max_early_data_size; } #endif /* MBEDTLS_SSL_EARLY_DATA */ From 85718043820d3dd9bd8922e269332430278b820c Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 22 Feb 2024 10:22:09 +0100 Subject: [PATCH 073/123] tls13: srv: Enforce maximum size of early data Signed-off-by: Ronald Cron --- library/ssl_misc.h | 3 +++ library/ssl_tls13_generic.c | 41 +++++++++++++++++++++++++++++++++++++ library/ssl_tls13_server.c | 13 +++++------- 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index d8844fcc32..883b98828d 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2150,6 +2150,9 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl, unsigned char *buf, const unsigned char *end, size_t *out_len); + +int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl, + size_t early_data_len); #endif /* MBEDTLS_SSL_EARLY_DATA */ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index bc737047a4..a3b4d355b4 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -1454,6 +1454,47 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl, return 0; } + +#if defined(MBEDTLS_SSL_SRV_C) +int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl, + size_t early_data_len) +{ + uint32_t uint32_early_data_len = (uint32_t) early_data_len; + + /* + * This function should be called only while an handshake is in progress + * and thus a session under negotiation. Add a sanity check to detect a + * misuse. + */ + if (ssl->session_negotiate == NULL) { + return MBEDTLS_ERR_SSL_INTERNAL_ERROR; + } + + /* RFC 8446 section 4.6.1 + * + * A server receiving more than max_early_data_size bytes of 0-RTT data + * SHOULD terminate the connection with an "unexpected_message" alert. + */ + if (uint32_early_data_len > + (ssl->session_negotiate->max_early_data_size - + ssl->early_data_count)) { + + MBEDTLS_SSL_DEBUG_MSG( + 2, ("EarlyData: Too many early data received, %u > %u", + ssl->early_data_count + uint32_early_data_len, + ssl->session_negotiate->max_early_data_size)); + + MBEDTLS_SSL_PEND_FATAL_ALERT( + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE, + MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE); + return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; + } + + ssl->early_data_count += uint32_early_data_len; + + return 0; +} +#endif /* MBEDTLS_SSL_SRV_C */ #endif /* MBEDTLS_SSL_EARLY_DATA */ /* Reset SSL context and update hash for handling HRR. diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 2391915357..449fa380f1 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -2913,17 +2913,14 @@ static int ssl_tls13_end_of_early_data_coordinate(mbedtls_ssl_context *ssl) } if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) { - MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data")); - /* RFC 8446 section 4.6.1 - * - * A server receiving more than max_early_data_size bytes of 0-RTT data - * SHOULD terminate the connection with an "unexpected_message" alert. - * - * TODO: Add received data size check here. - */ if (ssl->in_offt == NULL) { + MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data")); /* Set the reading pointer */ ssl->in_offt = ssl->in_msg; + ret = mbedtls_ssl_tls13_check_early_data_len(ssl, ssl->in_msglen); + if (ret != 0) { + return ret; + } } return SSL_GOT_EARLY_DATA; } From 2160bfe4e23af0c290c23a0c7d83637fb7adb658 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 7 Feb 2024 08:04:07 +0100 Subject: [PATCH 074/123] tests: ssl: Test enforcement of maximum early data size Signed-off-by: Ronald Cron --- tests/suites/test_suite_ssl.data | 9 ++ tests/suites/test_suite_ssl.function | 163 +++++++++++++++++++++++++++ 2 files changed, 172 insertions(+) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 385682ae12..1f705382b0 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3309,3 +3309,12 @@ tls13_write_early_data:TEST_EARLY_DATA_SERVER_REJECTS TLS 1.3 write early data, hello retry request tls13_write_early_data:TEST_EARLY_DATA_HRR + +TLS 1.3 srv, max early data size, default +tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:-1 + +TLS 1.3 srv, max early data size, max=3 (small but !0) +tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:3 + +TLS 1.3 srv, max early data size, max=97 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:97 diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index d327828bcd..1408361795 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4448,3 +4448,166 @@ exit: PSA_DONE(); } /* END_CASE */ + +/* + * The !MBEDTLS_SSL_PROTO_TLS1_2 dependency of tls13_early_data() below is + * a temporary workaround to not run the test in Windows-2013 where there is + * an issue with mbedtls_vsnprintf(). + */ +/* BEGIN_CASE depends_on:!MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */ +void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg) +{ + int ret = -1; + mbedtls_test_ssl_endpoint client_ep, server_ep; + mbedtls_test_handshake_test_options client_options; + mbedtls_test_handshake_test_options server_options; + mbedtls_ssl_session saved_session; + mbedtls_test_ssl_log_pattern server_pattern = { NULL, 0 }; + char pattern[128]; + unsigned char buf_write[64]; + size_t early_data_len = sizeof(buf_write); + uint32_t written_early_data_size = 0; + int write_early_data_flag = 1; + uint32_t max_early_data_size; + + mbedtls_platform_zeroize(&client_ep, sizeof(client_ep)); + mbedtls_platform_zeroize(&server_ep, sizeof(server_ep)); + mbedtls_test_init_handshake_options(&client_options); + mbedtls_test_init_handshake_options(&server_options); + mbedtls_ssl_session_init(&saved_session); + + PSA_INIT(); + + /* + * Run first handshake to get a ticket from the server. + */ + + client_options.pk_alg = MBEDTLS_PK_ECDSA; + client_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED; + server_options.pk_alg = MBEDTLS_PK_ECDSA; + server_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED; + server_options.max_early_data_size = max_early_data_size_arg; + + ret = mbedtls_test_get_tls13_ticket(&client_options, &server_options, + &saved_session); + TEST_EQUAL(ret, 0); + + /* + * Prepare for handshake with the ticket. + */ + server_options.srv_log_fun = mbedtls_test_ssl_log_analyzer; + server_options.srv_log_obj = &server_pattern; + server_pattern.pattern = pattern; + + switch (scenario) { + case TEST_EARLY_DATA_ACCEPTED: + break; + + default: + TEST_FAIL("Unknown scenario."); + } + + ret = mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT, + &client_options, NULL, NULL, NULL); + TEST_EQUAL(ret, 0); + + ret = mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER, + &server_options, NULL, NULL, NULL); + TEST_EQUAL(ret, 0); + + mbedtls_ssl_conf_session_tickets_cb(&server_ep.conf, + mbedtls_test_ticket_write, + mbedtls_test_ticket_parse, + NULL); + + ret = mbedtls_test_mock_socket_connect(&(client_ep.socket), + &(server_ep.socket), 1024); + TEST_EQUAL(ret, 0); + + max_early_data_size = saved_session.max_early_data_size; + + ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session); + TEST_EQUAL(ret, 0); + + /* + * Start an handshake based on the ticket up to the point where early data + * can be sent from client side. Then send in a loop as much early data as + * possible without going over the maximum permitted size for the ticket. + * Finally, do a last writting to go past that maximum permitted size and + * check that we detect it. + */ + TEST_EQUAL(mbedtls_test_move_handshake_to_state( + &(client_ep.ssl), &(server_ep.ssl), + MBEDTLS_SSL_SERVER_HELLO), 0); + + TEST_ASSERT(client_ep.ssl.early_data_status != + MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT); + + ret = mbedtls_ssl_handshake(&(server_ep.ssl)); + TEST_EQUAL(ret, MBEDTLS_ERR_SSL_WANT_READ); + + while (write_early_data_flag) { + unsigned char buf_read[23]; + uint32_t read_early_data_size = 0; + uint32_t remaining = max_early_data_size - + server_ep.ssl.early_data_count; + + /* Reach maximum early data exactly */ + if (early_data_len >= remaining) { + early_data_len = remaining; + write_early_data_flag = 0; + } + + for (size_t i = 0; i < early_data_len; i++) { + buf_write[i] = (unsigned char) (written_early_data_size + i); + } + + ret = write_early_data(&(client_ep.ssl), buf_write, early_data_len); + TEST_EQUAL(ret, early_data_len); + written_early_data_size += early_data_len; + + switch (scenario) { + case TEST_EARLY_DATA_ACCEPTED: + while (read_early_data_size < early_data_len) { + ret = mbedtls_ssl_handshake(&(server_ep.ssl)); + TEST_EQUAL(ret, MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA); + + ret = mbedtls_ssl_read_early_data(&(server_ep.ssl), + buf_read, + sizeof(buf_read)); + TEST_ASSERT(ret > 0); + + TEST_MEMORY_COMPARE(buf_read, ret, + buf_write + read_early_data_size, ret); + read_early_data_size += ret; + + TEST_EQUAL(server_ep.ssl.early_data_count, + written_early_data_size); + } + break; + } + TEST_ASSERT(server_ep.ssl.early_data_count <= max_early_data_size); + } + + mbedtls_debug_set_threshold(3); + ret = write_early_data(&(client_ep.ssl), buf_write, 1); + TEST_EQUAL(ret, 1); + + ret = mbedtls_snprintf(pattern, sizeof(pattern), + "EarlyData: Too many early data received"); + TEST_ASSERT(ret < (int) sizeof(pattern)); + + ret = mbedtls_ssl_handshake(&(server_ep.ssl)); + TEST_EQUAL(ret, MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE); + TEST_EQUAL(server_pattern.counter, 1); + +exit: + mbedtls_test_ssl_endpoint_free(&client_ep, NULL); + mbedtls_test_ssl_endpoint_free(&server_ep, NULL); + mbedtls_test_free_handshake_options(&client_options); + mbedtls_test_free_handshake_options(&server_options); + mbedtls_ssl_session_free(&saved_session); + mbedtls_debug_set_threshold(0); + PSA_DONE(); +} +/* END_CASE */ From 919e596c05c14f7754655b970c5fab47824a2bd5 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 8 Feb 2024 15:48:29 +0100 Subject: [PATCH 075/123] Enforce maximum size of early data when rejected Signed-off-by: Ronald Cron --- library/ssl_msg.c | 6 +++- tests/suites/test_suite_ssl.data | 9 ++++++ tests/suites/test_suite_ssl.function | 45 ++++++++++++++++++++++++++-- 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 2a6d4341be..6c508d6234 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -4005,7 +4005,11 @@ static int ssl_prepare_record_content(mbedtls_ssl_context *ssl, MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD)) { MBEDTLS_SSL_DEBUG_MSG( 3, ("EarlyData: deprotect and discard app data records.")); - /* TODO: Add max_early_data_size check here, see issue 6347 */ + + ret = mbedtls_ssl_tls13_check_early_data_len(ssl, rec->data_len); + if (ret != 0) { + return ret; + } ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; } #endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */ diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 1f705382b0..6fb3d837c0 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3318,3 +3318,12 @@ tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:3 TLS 1.3 srv, max early data size, max=97 tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:97 + +TLS 1.3 srv, max early data size, server rejects, default +tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:-1 + +TLS 1.3 srv, max early data size, server rejects, max=3 (very small) +tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:3 + +TLS 1.3 srv, max early data size, server rejects, max=97 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:97 diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 1408361795..0c1d606909 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4466,6 +4466,7 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg) char pattern[128]; unsigned char buf_write[64]; size_t early_data_len = sizeof(buf_write); + uint32_t expended_early_data_len = 0; uint32_t written_early_data_size = 0; int write_early_data_flag = 1; uint32_t max_early_data_size; @@ -4503,6 +4504,14 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg) case TEST_EARLY_DATA_ACCEPTED: break; + case TEST_EARLY_DATA_SERVER_REJECTS: + server_options.early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED; + ret = mbedtls_snprintf(pattern, sizeof(pattern), + "EarlyData: deprotect and discard app data records."); + TEST_ASSERT(ret < (int) sizeof(pattern)); + mbedtls_debug_set_threshold(3); + break; + default: TEST_FAIL("Unknown scenario."); } @@ -4552,7 +4561,7 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg) uint32_t remaining = max_early_data_size - server_ep.ssl.early_data_count; - /* Reach maximum early data exactly */ + /* In case of accepted early data, reach max_early_data_size exactly. */ if (early_data_len >= remaining) { early_data_len = remaining; write_early_data_flag = 0; @@ -4585,13 +4594,43 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg) written_early_data_size); } break; + + case TEST_EARLY_DATA_SERVER_REJECTS: + ret = mbedtls_ssl_handshake(&(server_ep.ssl)); + /* + * Can be the case if max_early_data_size is smaller then the + * smallest inner content or protected record. + */ + if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) { + /* Beyond 64 for max_early_data_size it is suspicious */ + TEST_ASSERT(max_early_data_size < 64); + goto exit; + } + + TEST_ASSERT(ret == MBEDTLS_ERR_SSL_WANT_READ); + + TEST_EQUAL(server_pattern.counter, 1); + server_pattern.counter = 0; + if (expended_early_data_len == 0) { + expended_early_data_len = server_ep.ssl.early_data_count; + } + remaining = max_early_data_size - server_ep.ssl.early_data_count; + + if (expended_early_data_len > remaining) { + write_early_data_flag = 0; + } + break; } TEST_ASSERT(server_ep.ssl.early_data_count <= max_early_data_size); } mbedtls_debug_set_threshold(3); - ret = write_early_data(&(client_ep.ssl), buf_write, 1); - TEST_EQUAL(ret, 1); + + early_data_len = (scenario == TEST_EARLY_DATA_ACCEPTED) ? + 1 : sizeof(buf_write); + + ret = write_early_data(&(client_ep.ssl), buf_write, early_data_len); + TEST_EQUAL(ret, early_data_len); ret = mbedtls_snprintf(pattern, sizeof(pattern), "EarlyData: Too many early data received"); From 01d273d31f40402dce5ec47dc43782702ad5c5c3 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 9 Feb 2024 16:17:10 +0100 Subject: [PATCH 076/123] Enforce maximum size of early data in case of HRR Signed-off-by: Ronald Cron --- library/ssl_msg.c | 7 ++++++- tests/suites/test_suite_ssl.data | 9 +++++++++ tests/suites/test_suite_ssl.function | 19 ++++++++++++++++++- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 6c508d6234..a8ff1c1a15 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -4135,7 +4135,12 @@ static int ssl_prepare_record_content(mbedtls_ssl_context *ssl, if (rec->type == MBEDTLS_SSL_MSG_APPLICATION_DATA) { MBEDTLS_SSL_DEBUG_MSG( 3, ("EarlyData: Ignore application message before 2nd ClientHello")); - /* TODO: Add max_early_data_size check here, see issue 6347 */ + + ret = mbedtls_ssl_tls13_check_early_data_len(ssl, rec->data_len); + if (ret != 0) { + return ret; + } + return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; } else if (rec->type == MBEDTLS_SSL_MSG_HANDSHAKE) { ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD; diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 6fb3d837c0..03de4a99f6 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3327,3 +3327,12 @@ tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:3 TLS 1.3 srv, max early data size, server rejects, max=97 tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:97 + +TLS 1.3 srv, max early data size, HRR, default +tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:-1 + +TLS 1.3 srv, max early data size, HRR, max=3 (very small) +tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:3 + +TLS 1.3 srv, max early data size, HRR, max=97 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:97 diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 0c1d606909..fc1bc3ee85 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4463,6 +4463,11 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg) mbedtls_test_handshake_test_options server_options; mbedtls_ssl_session saved_session; mbedtls_test_ssl_log_pattern server_pattern = { NULL, 0 }; + uint16_t group_list[3] = { + MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1, + MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1, + MBEDTLS_SSL_IANA_TLS_GROUP_NONE + }; char pattern[128]; unsigned char buf_write[64]; size_t early_data_len = sizeof(buf_write); @@ -4484,8 +4489,10 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg) */ client_options.pk_alg = MBEDTLS_PK_ECDSA; + client_options.group_list = group_list; client_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED; server_options.pk_alg = MBEDTLS_PK_ECDSA; + server_options.group_list = group_list; server_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED; server_options.max_early_data_size = max_early_data_size_arg; @@ -4512,6 +4519,15 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg) mbedtls_debug_set_threshold(3); break; + case TEST_EARLY_DATA_HRR: + server_options.group_list = group_list + 1; + ret = mbedtls_snprintf( + pattern, sizeof(pattern), + "EarlyData: Ignore application message before 2nd ClientHello"); + TEST_ASSERT(ret < (int) sizeof(pattern)); + mbedtls_debug_set_threshold(3); + break; + default: TEST_FAIL("Unknown scenario."); } @@ -4595,7 +4611,8 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg) } break; - case TEST_EARLY_DATA_SERVER_REJECTS: + case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */ + case TEST_EARLY_DATA_HRR: ret = mbedtls_ssl_handshake(&(server_ep.ssl)); /* * Can be the case if max_early_data_size is smaller then the From dc81b7343f325f7e62ec038330d4f7505a37ed96 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 26 Feb 2024 15:02:26 +0100 Subject: [PATCH 077/123] tests: srv max early data size: Add reach_max test arg Add the reach_max flag argument for the test13_srv_max_early_data_size test function. Non zero value only valid in case of TEST_EARLY_DATA_ACCEPTED scenario. Signed-off-by: Ronald Cron --- tests/suites/test_suite_ssl.data | 27 +++++++++++++------- tests/suites/test_suite_ssl.function | 37 ++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 03de4a99f6..f3d9ef05b4 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3311,28 +3311,37 @@ TLS 1.3 write early data, hello retry request tls13_write_early_data:TEST_EARLY_DATA_HRR TLS 1.3 srv, max early data size, default -tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:-1 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:-1:0 + +TLS 1.3 srv, max early data size, default, reach max +tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:-1:1 TLS 1.3 srv, max early data size, max=3 (small but !0) -tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:3 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:3:0 + +TLS 1.3 srv, max early data size, max=3 (small but !0), reach max +tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:3:1 TLS 1.3 srv, max early data size, max=97 -tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:97 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:97:0 + +TLS 1.3 srv, max early data size, max=97, reach max +tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:97:1 TLS 1.3 srv, max early data size, server rejects, default -tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:-1 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:-1:0 TLS 1.3 srv, max early data size, server rejects, max=3 (very small) -tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:3 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:3:0 TLS 1.3 srv, max early data size, server rejects, max=97 -tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:97 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:97:0 TLS 1.3 srv, max early data size, HRR, default -tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:-1 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:-1:0 TLS 1.3 srv, max early data size, HRR, max=3 (very small) -tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:3 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:3:0 TLS 1.3 srv, max early data size, HRR, max=97 -tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:97 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:97:0 diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index fc1bc3ee85..5f6029e225 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4455,7 +4455,7 @@ exit: * an issue with mbedtls_vsnprintf(). */ /* BEGIN_CASE depends_on:!MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */ -void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg) +void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, int reach_max) { int ret = -1; mbedtls_test_ssl_endpoint client_ep, server_ep; @@ -4470,7 +4470,7 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg) }; char pattern[128]; unsigned char buf_write[64]; - size_t early_data_len = sizeof(buf_write); + size_t early_data_len; uint32_t expended_early_data_len = 0; uint32_t written_early_data_size = 0; int write_early_data_flag = 1; @@ -4484,6 +4484,14 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg) PSA_INIT(); + /* + * Reach maximum early data size exactly option only available in case of + * TEST_EARLY_DATA_ACCEPTED scenario. + */ + if (reach_max) { + TEST_EQUAL(scenario, TEST_EARLY_DATA_ACCEPTED); + } + /* * Run first handshake to get a ticket from the server. */ @@ -4577,10 +4585,24 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg) uint32_t remaining = max_early_data_size - server_ep.ssl.early_data_count; - /* In case of accepted early data, reach max_early_data_size exactly. */ + early_data_len = sizeof(buf_write); + /* + * Adjust the length of next data to write depending on the remaining + * number of early data bytes we are allowed to write and if we want + * to reach the maximum exactly or not. + */ if (early_data_len >= remaining) { - early_data_len = remaining; - write_early_data_flag = 0; + if (reach_max) { + early_data_len = remaining; + write_early_data_flag = 0; + } else { + if (early_data_len == remaining) { + early_data_len /= 2; + } else { + early_data_len = remaining + 1; + break; + } + } } for (size_t i = 0; i < early_data_len; i++) { @@ -4643,8 +4665,9 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg) mbedtls_debug_set_threshold(3); - early_data_len = (scenario == TEST_EARLY_DATA_ACCEPTED) ? - 1 : sizeof(buf_write); + if (reach_max) { + TEST_EQUAL(server_ep.ssl.early_data_count, max_early_data_size); + } ret = write_early_data(&(client_ep.ssl), buf_write, early_data_len); TEST_EQUAL(ret, early_data_len); From 70eab45ba6c91a5a840d8beaf8d440b23dcb0867 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 26 Feb 2024 15:50:15 +0100 Subject: [PATCH 078/123] tls13: generic: Fix log Signed-off-by: Ronald Cron --- library/ssl_tls13_generic.c | 2 +- tests/suites/test_suite_ssl.function | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index a3b4d355b4..c5698f6ee4 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -1480,7 +1480,7 @@ int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl, ssl->early_data_count)) { MBEDTLS_SSL_DEBUG_MSG( - 2, ("EarlyData: Too many early data received, %u > %u", + 2, ("EarlyData: Too much early data received, %u > %u", ssl->early_data_count + uint32_early_data_len, ssl->session_negotiate->max_early_data_size)); diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 5f6029e225..aca8276e6e 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4673,7 +4673,7 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, in TEST_EQUAL(ret, early_data_len); ret = mbedtls_snprintf(pattern, sizeof(pattern), - "EarlyData: Too many early data received"); + "EarlyData: Too much early data received"); TEST_ASSERT(ret < (int) sizeof(pattern)); ret = mbedtls_ssl_handshake(&(server_ep.ssl)); From 19bfe0a6310acd686cbf70b429ed80b075f9a0d1 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 26 Feb 2024 16:43:01 +0100 Subject: [PATCH 079/123] tls13: Rename early_data_count to total_early_data_size Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 2 +- library/ssl_tls.c | 2 +- library/ssl_tls13_generic.c | 6 +++--- tests/suites/test_suite_ssl.function | 12 ++++++------ 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 15bd6fd7d3..9a66663318 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1869,7 +1869,7 @@ struct mbedtls_ssl_context { */ uint8_t MBEDTLS_PRIVATE(discard_early_data_record); #endif - uint32_t MBEDTLS_PRIVATE(early_data_count); /*!< Number of received/written early data bytes */ + uint32_t MBEDTLS_PRIVATE(total_early_data_size); /*!< Number of received/written early data bytes */ #endif /* MBEDTLS_SSL_EARLY_DATA */ /* diff --git a/library/ssl_tls.c b/library/ssl_tls.c index ee72179997..5bedd91389 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1105,7 +1105,7 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl) #if defined(MBEDTLS_SSL_SRV_C) ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD; #endif - ssl->early_data_count = 0; + ssl->total_early_data_size = 0; #endif /* MBEDTLS_SSL_EARLY_DATA */ /* Initialize structures */ diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index c5698f6ee4..eec2bb4b75 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -1477,11 +1477,11 @@ int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl, */ if (uint32_early_data_len > (ssl->session_negotiate->max_early_data_size - - ssl->early_data_count)) { + ssl->total_early_data_size)) { MBEDTLS_SSL_DEBUG_MSG( 2, ("EarlyData: Too much early data received, %u > %u", - ssl->early_data_count + uint32_early_data_len, + ssl->total_early_data_size + uint32_early_data_len, ssl->session_negotiate->max_early_data_size)); MBEDTLS_SSL_PEND_FATAL_ALERT( @@ -1490,7 +1490,7 @@ int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl, return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; } - ssl->early_data_count += uint32_early_data_len; + ssl->total_early_data_size += uint32_early_data_len; return 0; } diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index aca8276e6e..791386b276 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4583,7 +4583,7 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, in unsigned char buf_read[23]; uint32_t read_early_data_size = 0; uint32_t remaining = max_early_data_size - - server_ep.ssl.early_data_count; + server_ep.ssl.total_early_data_size; early_data_len = sizeof(buf_write); /* @@ -4628,7 +4628,7 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, in buf_write + read_early_data_size, ret); read_early_data_size += ret; - TEST_EQUAL(server_ep.ssl.early_data_count, + TEST_EQUAL(server_ep.ssl.total_early_data_size, written_early_data_size); } break; @@ -4651,22 +4651,22 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, in TEST_EQUAL(server_pattern.counter, 1); server_pattern.counter = 0; if (expended_early_data_len == 0) { - expended_early_data_len = server_ep.ssl.early_data_count; + expended_early_data_len = server_ep.ssl.total_early_data_size; } - remaining = max_early_data_size - server_ep.ssl.early_data_count; + remaining = max_early_data_size - server_ep.ssl.total_early_data_size; if (expended_early_data_len > remaining) { write_early_data_flag = 0; } break; } - TEST_ASSERT(server_ep.ssl.early_data_count <= max_early_data_size); + TEST_ASSERT(server_ep.ssl.total_early_data_size <= max_early_data_size); } mbedtls_debug_set_threshold(3); if (reach_max) { - TEST_EQUAL(server_ep.ssl.early_data_count, max_early_data_size); + TEST_EQUAL(server_ep.ssl.total_early_data_size, max_early_data_size); } ret = write_early_data(&(client_ep.ssl), buf_write, early_data_len); From 25ad10a920979c2236ca14494a055a596c21e93c Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 29 Feb 2024 00:39:23 +0100 Subject: [PATCH 080/123] tests: ssl: Improve tls13_srv_max_early_data_size() Signed-off-by: Ronald Cron --- tests/suites/test_suite_ssl.data | 46 +++++++------- tests/suites/test_suite_ssl.function | 93 ++++++++++++---------------- 2 files changed, 63 insertions(+), 76 deletions(-) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index f3d9ef05b4..c0c816c2db 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3310,38 +3310,38 @@ tls13_write_early_data:TEST_EARLY_DATA_SERVER_REJECTS TLS 1.3 write early data, hello retry request tls13_write_early_data:TEST_EARLY_DATA_HRR -TLS 1.3 srv, max early data size, default -tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:-1:0 +TLS 1.3 srv, max early data size, dflt, wsz=96 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:-1:96 -TLS 1.3 srv, max early data size, default, reach max -tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:-1:1 +TLS 1.3 srv, max early data size, dflt, wsz=128 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:-1:128 -TLS 1.3 srv, max early data size, max=3 (small but !0) -tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:3:0 +TLS 1.3 srv, max early data size, 3, wsz=2 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:3:2 -TLS 1.3 srv, max early data size, max=3 (small but !0), reach max -tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:3:1 +TLS 1.3 srv, max early data size, 3, wsz=3 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:3:3 -TLS 1.3 srv, max early data size, max=97 -tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:97:0 +TLS 1.3 srv, max early data size, 98, wsz=23 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:98:23 -TLS 1.3 srv, max early data size, max=97, reach max -tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:97:1 +TLS 1.3 srv, max early data size, 98, wsz=49 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:98:49 -TLS 1.3 srv, max early data size, server rejects, default -tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:-1:0 +TLS 1.3 srv, max early data size, server rejects, dflt, wsz=128 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:-1:128 -TLS 1.3 srv, max early data size, server rejects, max=3 (very small) -tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:3:0 +TLS 1.3 srv, max early data size, server rejects, 3, wsz=3 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:3:3 -TLS 1.3 srv, max early data size, server rejects, max=97 -tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:97:0 +TLS 1.3 srv, max early data size, server rejects, 98, wsz=49 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:98:49 -TLS 1.3 srv, max early data size, HRR, default -tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:-1:0 +TLS 1.3 srv, max early data size, HRR, dflt, wsz=128 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:-1:128 -TLS 1.3 srv, max early data size, HRR, max=3 (very small) -tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:3:0 +TLS 1.3 srv, max early data size, HRR, 3, wsz=3 +tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:3:3 -TLS 1.3 srv, max early data size, HRR, max=97 +TLS 1.3 srv, max early data size, HRR, 98, wsz=49 tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:97:0 diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 791386b276..d89d8ac8b2 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4455,7 +4455,7 @@ exit: * an issue with mbedtls_vsnprintf(). */ /* BEGIN_CASE depends_on:!MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */ -void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, int reach_max) +void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, int write_size_arg) { int ret = -1; mbedtls_test_ssl_endpoint client_ep, server_ep; @@ -4469,11 +4469,12 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, in MBEDTLS_SSL_IANA_TLS_GROUP_NONE }; char pattern[128]; - unsigned char buf_write[64]; - size_t early_data_len; + unsigned char *buf_write = NULL; + uint32_t write_size = (uint32_t) write_size_arg; + unsigned char *buf_read = NULL; + uint32_t read_size; uint32_t expended_early_data_len = 0; uint32_t written_early_data_size = 0; - int write_early_data_flag = 1; uint32_t max_early_data_size; mbedtls_platform_zeroize(&client_ep, sizeof(client_ep)); @@ -4481,16 +4482,16 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, in mbedtls_test_init_handshake_options(&client_options); mbedtls_test_init_handshake_options(&server_options); mbedtls_ssl_session_init(&saved_session); - - PSA_INIT(); + TEST_CALLOC(buf_write, write_size); /* - * Reach maximum early data size exactly option only available in case of - * TEST_EARLY_DATA_ACCEPTED scenario. + * Allocate a smaller buffer for early data reading to exercise the reading + * of data in one record in multiple calls. */ - if (reach_max) { - TEST_EQUAL(scenario, TEST_EARLY_DATA_ACCEPTED); - } + read_size = (write_size / 2) + 1; + TEST_CALLOC(buf_read, read_size); + + PSA_INIT(); /* * Run first handshake to get a ticket from the server. @@ -4579,49 +4580,45 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, in ret = mbedtls_ssl_handshake(&(server_ep.ssl)); TEST_EQUAL(ret, MBEDTLS_ERR_SSL_WANT_READ); - while (write_early_data_flag) { - unsigned char buf_read[23]; + /* + * Write and if possible read as much as possible chunks of write_size + * bytes data without getting over the max_early_data_size limit. + */ + do { uint32_t read_early_data_size = 0; - uint32_t remaining = max_early_data_size - - server_ep.ssl.total_early_data_size; - early_data_len = sizeof(buf_write); - /* - * Adjust the length of next data to write depending on the remaining - * number of early data bytes we are allowed to write and if we want - * to reach the maximum exactly or not. - */ - if (early_data_len >= remaining) { - if (reach_max) { - early_data_len = remaining; - write_early_data_flag = 0; - } else { - if (early_data_len == remaining) { - early_data_len /= 2; - } else { - early_data_len = remaining + 1; - break; - } - } + if ((written_early_data_size + write_size) > max_early_data_size) { + break; } - for (size_t i = 0; i < early_data_len; i++) { + /* + * If the server rejected early data, base the determination of when + * to stop the loop on the expended size (padding and encryption + * expansion) of early data on server side and the number of early data + * received so far by the server (multiple of the expended size). + */ + if ((expended_early_data_len != 0) && + ((server_ep.ssl.total_early_data_size + + expended_early_data_len) > max_early_data_size)) { + break; + } + + for (size_t i = 0; i < write_size; i++) { buf_write[i] = (unsigned char) (written_early_data_size + i); } - ret = write_early_data(&(client_ep.ssl), buf_write, early_data_len); - TEST_EQUAL(ret, early_data_len); - written_early_data_size += early_data_len; + ret = write_early_data(&(client_ep.ssl), buf_write, write_size); + TEST_EQUAL(ret, write_size); + written_early_data_size += write_size; switch (scenario) { case TEST_EARLY_DATA_ACCEPTED: - while (read_early_data_size < early_data_len) { + while (read_early_data_size < write_size) { ret = mbedtls_ssl_handshake(&(server_ep.ssl)); TEST_EQUAL(ret, MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA); ret = mbedtls_ssl_read_early_data(&(server_ep.ssl), - buf_read, - sizeof(buf_read)); + buf_read, read_size); TEST_ASSERT(ret > 0); TEST_MEMORY_COMPARE(buf_read, ret, @@ -4653,24 +4650,14 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, in if (expended_early_data_len == 0) { expended_early_data_len = server_ep.ssl.total_early_data_size; } - remaining = max_early_data_size - server_ep.ssl.total_early_data_size; - - if (expended_early_data_len > remaining) { - write_early_data_flag = 0; - } break; } TEST_ASSERT(server_ep.ssl.total_early_data_size <= max_early_data_size); - } + } while (1); mbedtls_debug_set_threshold(3); - - if (reach_max) { - TEST_EQUAL(server_ep.ssl.total_early_data_size, max_early_data_size); - } - - ret = write_early_data(&(client_ep.ssl), buf_write, early_data_len); - TEST_EQUAL(ret, early_data_len); + ret = write_early_data(&(client_ep.ssl), buf_write, write_size); + TEST_EQUAL(ret, write_size); ret = mbedtls_snprintf(pattern, sizeof(pattern), "EarlyData: Too much early data received"); From fcbf776d0661bdeee4c7b663c041e16561e8ca0e Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 1 Mar 2024 10:00:42 +0100 Subject: [PATCH 081/123] tests: ssl: Restore write_early_data test function For negative testing of early data (tests related to max_early_data_size in this PR), restore the test function to write early data that was first introduced to be able to test the reading of early data with the writing part and was removed (as not used anymore) by the PR 8760. Signed-off-by: Ronald Cron --- tests/suites/test_suite_ssl.function | 41 ++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index d89d8ac8b2..c1622e3484 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -18,6 +18,47 @@ #define TEST_EARLY_DATA_SERVER_REJECTS 2 #define TEST_EARLY_DATA_HRR 3 +#if (!defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \ + defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) && \ + defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_DEBUG_C) && \ + defined(MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE) && \ + defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) && \ + defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED) && \ + defined(MBEDTLS_MD_CAN_SHA256) && \ + defined(MBEDTLS_ECP_HAVE_SECP256R1) && defined(MBEDTLS_ECP_HAVE_SECP384R1) && \ + defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) && defined(MBEDTLS_SSL_SESSION_TICKETS) +/* + * Test function to write early data for negative tests where + * mbedtls_ssl_write_early_data() cannot be used. + */ +static int write_early_data(mbedtls_ssl_context *ssl, + unsigned char *buf, size_t len) +{ + int ret = mbedtls_ssl_get_max_out_record_payload(ssl); + + TEST_ASSERT(ret > 0); + TEST_ASSERT(len <= (size_t) ret); + + ret = mbedtls_ssl_flush_output(ssl); + TEST_EQUAL(ret, 0); + TEST_EQUAL(ssl->out_left, 0); + + ssl->out_msglen = len; + ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA; + if (len > 0) { + memcpy(ssl->out_msg, buf, len); + } + + ret = mbedtls_ssl_write_record(ssl, 1); + TEST_EQUAL(ret, 0); + + ret = len; + +exit: + return ret; +} +#endif + /* END_HEADER */ /* BEGIN_DEPENDENCIES From f686f1dc17958e7cd36edd24bb991fcdabb94f3e Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 1 Mar 2024 11:20:32 +0000 Subject: [PATCH 082/123] Fix naming inconsistencies in config bits Signed-off-by: David Horstmann --- library/ssl_tls.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 42bf670fda..97f34d0b03 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -4007,9 +4007,9 @@ static int ssl_tls13_session_load(const mbedtls_ssl_session *session, #endif /* MBEDTLS_X509_CRT_PARSE_C */ #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) -#define SSL_SERIALIZED_SESSION_KEEP_PEER_CRT 1 +#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT 1 #else -#define SSL_SERIALIZED_SESSION_KEEP_PEER_CRT 0 +#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT 0 #endif /* MBEDTLS_SSL_SESSION_TICKETS */ #if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_SESSION_TICKETS) @@ -4060,7 +4060,7 @@ static int ssl_tls13_session_load(const mbedtls_ssl_session *session, #define SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT 3 #define SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT 4 #define SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT 5 -#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_CRT_BIT 6 +#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT_BIT 6 #define SSL_SERIALIZED_SESSION_CONFIG_SNI_BIT 7 #define SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA_BIT 8 #define SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE_BIT 9 @@ -4074,7 +4074,7 @@ static int ssl_tls13_session_load(const mbedtls_ssl_session *session, (SSL_SERIALIZED_SESSION_CONFIG_MFL << SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT) | \ (SSL_SERIALIZED_SESSION_CONFIG_ETM << SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT) | \ (SSL_SERIALIZED_SESSION_CONFIG_TICKET << SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT) | \ - (SSL_SERIALIZED_SESSION_KEEP_PEER_CRT << SSL_SERIALIZED_SESSION_CONFIG_KEEP_CRT_BIT) | \ + (SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT << SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT_BIT) | \ (SSL_SERIALIZED_SESSION_CONFIG_SNI << SSL_SERIALIZED_SESSION_CONFIG_SNI_BIT) | \ (SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA << \ SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA_BIT) | \ From 7335082ef6fff182cabb4fda806c636e037ac3b2 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 1 Mar 2024 11:29:36 +0000 Subject: [PATCH 083/123] Add ChangeLog entry for ssl serialization bitflags Signed-off-by: David Horstmann --- ChangeLog.d/fix-ssl-session-serialization-config.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ChangeLog.d/fix-ssl-session-serialization-config.txt diff --git a/ChangeLog.d/fix-ssl-session-serialization-config.txt b/ChangeLog.d/fix-ssl-session-serialization-config.txt new file mode 100644 index 0000000000..ca1cc81f5e --- /dev/null +++ b/ChangeLog.d/fix-ssl-session-serialization-config.txt @@ -0,0 +1,4 @@ +Bugfix + * Fix missing bitflags in SSL session serialization headers. Their absence + allowed SSL sessions saved in one configuration to be loaded in a + different, incompatible configuration. From 76ba26a542908cec66a2fb0b324af7ea795bf9d3 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 1 Mar 2024 12:03:35 +0000 Subject: [PATCH 084/123] Fixup: add peer_cert_digest_type to comment Signed-off-by: David Horstmann --- library/ssl_tls.c | 1 + 1 file changed, 1 insertion(+) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 97f34d0b03..7dd8e4d763 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -4113,6 +4113,7 @@ static const unsigned char ssl_serialized_session_header[] = { * #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE * opaque peer_cert<0..2^24-1>; // length 0 means no peer cert * #else + * uint8 peer_cert_digest_type; * opaque peer_cert_digest<0..2^8-1> * #endif * select (endpoint) { From 71fa1a94e7781d1269eca79630fe3df0a1f6b2c4 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 1 Mar 2024 12:32:18 +0000 Subject: [PATCH 085/123] Fix code style Signed-off-by: David Horstmann --- library/ssl_tls.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 7dd8e4d763..b09db1e8b5 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -4074,7 +4074,8 @@ static int ssl_tls13_session_load(const mbedtls_ssl_session *session, (SSL_SERIALIZED_SESSION_CONFIG_MFL << SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT) | \ (SSL_SERIALIZED_SESSION_CONFIG_ETM << SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT) | \ (SSL_SERIALIZED_SESSION_CONFIG_TICKET << SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT) | \ - (SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT << SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT_BIT) | \ + (SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT << \ + SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT_BIT) | \ (SSL_SERIALIZED_SESSION_CONFIG_SNI << SSL_SERIALIZED_SESSION_CONFIG_SNI_BIT) | \ (SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA << \ SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA_BIT) | \ From 10b040fa6f7433849208c66ef29e714869138975 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 5 Feb 2024 09:38:09 +0100 Subject: [PATCH 086/123] tests: ssl_helpers: Rename rng_get to mbedtls_test_random mbedtls_test_ as the prefix for test APIs _random like in mbedtls_ctr/hmac_drbg_random Signed-off-by: Ronald Cron --- tests/include/test/ssl_helpers.h | 7 ++++++- tests/src/test_helpers/ssl_helpers.c | 4 ++-- tests/suites/test_suite_debug.function | 10 +++++----- tests/suites/test_suite_ssl.function | 14 +++++++------- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/tests/include/test/ssl_helpers.h b/tests/include/test/ssl_helpers.h index 9493b69ca7..f214ce0246 100644 --- a/tests/include/test/ssl_helpers.h +++ b/tests/include/test/ssl_helpers.h @@ -193,7 +193,12 @@ typedef struct mbedtls_test_ssl_endpoint { #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */ -int rng_get(void *p_rng, unsigned char *output, size_t output_len); +/* + * Random number generator aimed for TLS unitary tests. Its main purpose is to + * simplify the set-up of a random number generator for TLS + * unitary tests: no need to set up a good entropy source for example. + */ +int mbedtls_test_random(void *p_rng, unsigned char *output, size_t output_len); /* * This function can be passed to mbedtls to receive output logs from it. In diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index de76b09935..860b0a39f4 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -12,7 +12,7 @@ #include "md_psa.h" #if defined(MBEDTLS_SSL_TLS_C) -int rng_get(void *p_rng, unsigned char *output, size_t output_len) +int mbedtls_test_random(void *p_rng, unsigned char *output, size_t output_len) { (void) p_rng; for (size_t i = 0; i < output_len; i++) { @@ -754,7 +754,7 @@ int mbedtls_test_ssl_endpoint_init( mbedtls_ssl_init(&(ep->ssl)); mbedtls_ssl_config_init(&(ep->conf)); - mbedtls_ssl_conf_rng(&(ep->conf), rng_get, NULL); + mbedtls_ssl_conf_rng(&(ep->conf), mbedtls_test_random, NULL); TEST_ASSERT(mbedtls_ssl_conf_get_user_data_p(&ep->conf) == NULL); TEST_EQUAL(mbedtls_ssl_conf_get_user_data_n(&ep->conf), 0); diff --git a/tests/suites/test_suite_debug.function b/tests/suites/test_suite_debug.function index fca7ea0615..426d835ceb 100644 --- a/tests/suites/test_suite_debug.function +++ b/tests/suites/test_suite_debug.function @@ -66,7 +66,7 @@ void debug_print_msg_threshold(int threshold, int level, char *file, memset(buffer.buf, 0, 2000); buffer.ptr = buffer.buf; - mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, @@ -107,7 +107,7 @@ void mbedtls_debug_print_ret(char *file, int line, char *text, int value, memset(buffer.buf, 0, 2000); buffer.ptr = buffer.buf; - mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, @@ -145,7 +145,7 @@ void mbedtls_debug_print_buf(char *file, int line, char *text, memset(buffer.buf, 0, 2000); buffer.ptr = buffer.buf; - mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, @@ -185,7 +185,7 @@ void mbedtls_debug_print_crt(char *crt_file, char *file, int line, memset(buffer.buf, 0, 2000); buffer.ptr = buffer.buf; - mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, @@ -227,7 +227,7 @@ void mbedtls_debug_print_mpi(char *value, char *file, int line, memset(buffer.buf, 0, 2000); buffer.ptr = buffer.buf; - mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 050e525a21..82b541c620 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -1121,7 +1121,7 @@ void ssl_dtls_replay(data_t *prevs, data_t *new, int ret) mbedtls_ssl_config_init(&conf); MD_OR_USE_PSA_INIT(); - mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); TEST_ASSERT(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, @@ -2894,7 +2894,7 @@ void conf_version(int endpoint, int transport, mbedtls_ssl_conf_transport(&conf, transport); mbedtls_ssl_conf_min_tls_version(&conf, min_tls_version); mbedtls_ssl_conf_max_tls_version(&conf, max_tls_version); - mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == expected_ssl_setup_result); TEST_EQUAL(mbedtls_ssl_conf_get_endpoint( @@ -2936,7 +2936,7 @@ void conf_curve() mbedtls_ssl_init(&ssl); MD_OR_USE_PSA_INIT(); - mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0); @@ -2969,7 +2969,7 @@ void conf_group() mbedtls_ssl_config conf; mbedtls_ssl_config_init(&conf); - mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); mbedtls_ssl_conf_max_tls_version(&conf, MBEDTLS_SSL_VERSION_TLS1_2); mbedtls_ssl_conf_min_tls_version(&conf, MBEDTLS_SSL_VERSION_TLS1_2); @@ -3075,7 +3075,7 @@ void cookie_parsing(data_t *cookie, int exp_ret) mbedtls_ssl_config_init(&conf); USE_PSA_INIT(); - mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_DATAGRAM, @@ -3130,7 +3130,7 @@ void cid_sanity() mbedtls_ssl_config_init(&conf); MD_OR_USE_PSA_INIT(); - mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); TEST_ASSERT(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, @@ -3390,7 +3390,7 @@ void ssl_ecjpake_set_password(int use_opaque_arg) mbedtls_ssl_config_init(&conf); - mbedtls_ssl_conf_rng(&conf, rng_get, NULL); + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, From aab4a546bf1637294b0d3f07d068b6a12d05c497 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 23 Feb 2024 18:51:11 +0100 Subject: [PATCH 087/123] tests: Set the default conf then customize Set the default conf then customize, not the other way around. Signed-off-by: Ronald Cron --- tests/suites/test_suite_debug.function | 20 +++++--------------- tests/suites/test_suite_ssl.function | 13 +++++-------- 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/tests/suites/test_suite_debug.function b/tests/suites/test_suite_debug.function index 426d835ceb..fd5d1f5269 100644 --- a/tests/suites/test_suite_debug.function +++ b/tests/suites/test_suite_debug.function @@ -66,14 +66,12 @@ void debug_print_msg_threshold(int threshold, int level, char *file, memset(buffer.buf, 0, 2000); buffer.ptr = buffer.buf; - mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); - TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT), 0); - + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer); TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0); @@ -107,14 +105,12 @@ void mbedtls_debug_print_ret(char *file, int line, char *text, int value, memset(buffer.buf, 0, 2000); buffer.ptr = buffer.buf; - mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); - TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT), 0); - + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer); TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0); @@ -145,14 +141,12 @@ void mbedtls_debug_print_buf(char *file, int line, char *text, memset(buffer.buf, 0, 2000); buffer.ptr = buffer.buf; - mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); - TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT), 0); - + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer); TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0); @@ -185,14 +179,12 @@ void mbedtls_debug_print_crt(char *crt_file, char *file, int line, memset(buffer.buf, 0, 2000); buffer.ptr = buffer.buf; - mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); - TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT), 0); - + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer); TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0); @@ -227,14 +219,12 @@ void mbedtls_debug_print_mpi(char *value, char *file, int line, memset(buffer.buf, 0, 2000); buffer.ptr = buffer.buf; - mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); - TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT), 0); - + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer); TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0); diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 82b541c620..528897cb45 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -1121,12 +1121,12 @@ void ssl_dtls_replay(data_t *prevs, data_t *new, int ret) mbedtls_ssl_config_init(&conf); MD_OR_USE_PSA_INIT(); - mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); - TEST_ASSERT(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT) == 0); + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); + TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0); /* Read previous record numbers */ @@ -3075,12 +3075,11 @@ void cookie_parsing(data_t *cookie, int exp_ret) mbedtls_ssl_config_init(&conf); USE_PSA_INIT(); - mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); - TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT), 0); + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); TEST_EQUAL(mbedtls_ssl_setup(&ssl, &conf), 0); TEST_EQUAL(mbedtls_ssl_check_dtls_clihlo_cookie(&ssl, ssl.cli_id, @@ -3130,13 +3129,12 @@ void cid_sanity() mbedtls_ssl_config_init(&conf); MD_OR_USE_PSA_INIT(); - mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); - TEST_ASSERT(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) == 0); + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0); @@ -3390,12 +3388,11 @@ void ssl_ecjpake_set_password(int use_opaque_arg) mbedtls_ssl_config_init(&conf); - mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); - TEST_EQUAL(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT), 0); + mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL); TEST_EQUAL(mbedtls_ssl_setup(&ssl, &conf), 0); From e93cd1b5805e2ee52ab7a1aefd1634f6cb90c0e1 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 1 Mar 2024 19:30:00 +0100 Subject: [PATCH 088/123] tests: ssl: Free write/read test buffers Signed-off-by: Ronald Cron --- tests/suites/test_suite_ssl.function | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index c1622e3484..c381860f95 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4523,6 +4523,8 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, in mbedtls_test_init_handshake_options(&client_options); mbedtls_test_init_handshake_options(&server_options); mbedtls_ssl_session_init(&saved_session); + PSA_INIT(); + TEST_CALLOC(buf_write, write_size); /* @@ -4532,8 +4534,6 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, in read_size = (write_size / 2) + 1; TEST_CALLOC(buf_read, read_size); - PSA_INIT(); - /* * Run first handshake to get a ticket from the server. */ @@ -4714,6 +4714,8 @@ exit: mbedtls_test_free_handshake_options(&client_options); mbedtls_test_free_handshake_options(&server_options); mbedtls_ssl_session_free(&saved_session); + mbedtls_free(buf_write); + mbedtls_free(buf_read); mbedtls_debug_set_threshold(0); PSA_DONE(); } From 3cfdd73dfac81dfca138640e6c41dfe03684a291 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Sat, 2 Mar 2024 09:14:13 +0000 Subject: [PATCH 089/123] Changelog: Added changelog for `mbedtls_ecdh_get_grp_id`. Signed-off-by: Minos Galanakis --- ChangeLog.d/add_get_ecp_group_id.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 ChangeLog.d/add_get_ecp_group_id.txt diff --git a/ChangeLog.d/add_get_ecp_group_id.txt b/ChangeLog.d/add_get_ecp_group_id.txt new file mode 100644 index 0000000000..3328062a7e --- /dev/null +++ b/ChangeLog.d/add_get_ecp_group_id.txt @@ -0,0 +1,3 @@ +Features + * Add new accessor to expose the private group id member of + `mbedtls_ecdh_context` structure. From 2abbac74dc89f5367eabed0bc03ad3e42499d206 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Thu, 18 Jan 2024 17:05:21 +0000 Subject: [PATCH 090/123] x509: Added `mbedtls_x509_crt_get_ca_istrue()` API accessor. Signed-off-by: Minos Galanakis --- include/mbedtls/x509_crt.h | 12 ++++++++++++ library/x509_crt.c | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h index 3f1a1e7619..fc1d0bc7b1 100644 --- a/include/mbedtls/x509_crt.h +++ b/include/mbedtls/x509_crt.h @@ -916,6 +916,18 @@ static inline int mbedtls_x509_crt_has_ext_type(const mbedtls_x509_crt *ctx, return ctx->MBEDTLS_PRIVATE(ext_types) & ext_type; } +/** + * \brief Access the ca_istrue field + * + * \param[in] crt Certificate to be queried, must not be \c NULL + * + * \return \c 1 if this a CA certificate \c 0 otherwise. + * \return MBEDTLS_ERR_X509_INVALID_EXTENSIONS if the certificate does not support + * the Optional Basic Constraint extension. + * + */ +int mbedtls_x509_crt_get_ca_istrue(const mbedtls_x509_crt *crt); + /** \} name Structures and functions for parsing and writing X.509 certificates */ #if defined(MBEDTLS_X509_CRT_WRITE_C) diff --git a/library/x509_crt.c b/library/x509_crt.c index 7f0160a00f..2fd56fbd79 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -3290,4 +3290,12 @@ void mbedtls_x509_crt_restart_free(mbedtls_x509_crt_restart_ctx *ctx) } #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ +int mbedtls_x509_crt_get_ca_istrue(const mbedtls_x509_crt *crt) +{ + if ((crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS) != 0) { + return crt->MBEDTLS_PRIVATE(ca_istrue); + } + return MBEDTLS_ERR_X509_INVALID_EXTENSIONS; +} + #endif /* MBEDTLS_X509_CRT_PARSE_C */ From a83ada4eba4f32f012a638a52890559f6d634970 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Fri, 19 Jan 2024 10:59:07 +0000 Subject: [PATCH 091/123] tests: Added test for `mbedtls_x509_crt_get_ca_istrue()` Signed-off-by: Minos Galanakis --- tests/suites/test_suite_x509parse.data | 8 ++++++++ tests/suites/test_suite_x509parse.function | 15 +++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index 2b0920d807..7519d82d2b 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -3155,6 +3155,14 @@ X509 File parse (conforms to RFC 5480 / RFC 5758 - AlgorithmIdentifier's paramet depends_on:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_MD_CAN_SHA256 x509parse_crt_file:"data_files/parse_input/server5.crt":0 +X509 File parse & read the ca_istrue field (Not Set) +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_HAVE_TIME_DATE:MBEDTLS_MD_CAN_SHA1 +mbedtls_x509_get_ca_istrue:"data_files/parse_input/server1.crt":0 + +X509 File parse & read the ca_istrue field (Set) +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_HAVE_TIME_DATE:MBEDTLS_MD_CAN_SHA1 +mbedtls_x509_get_ca_istrue:"data_files/test-ca.crt":1 + X509 Get time (UTC no issues) depends_on:MBEDTLS_X509_USE_C x509_get_time:MBEDTLS_ASN1_UTC_TIME:"500101000000Z":0:1950:1:1:0:0:0 diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function index 66477e0d16..f3ae0f4d0a 100644 --- a/tests/suites/test_suite_x509parse.function +++ b/tests/suites/test_suite_x509parse.function @@ -1083,6 +1083,21 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_FS_IO */ +void mbedtls_x509_get_ca_istrue(char *crt_file, int result) +{ + mbedtls_x509_crt crt; + mbedtls_x509_crt_init(&crt); + USE_PSA_INIT(); + + TEST_EQUAL(mbedtls_x509_crt_parse_file(&crt, crt_file), 0); + TEST_EQUAL(mbedtls_x509_crt_get_ca_istrue(&crt), result); +exit: + mbedtls_x509_crt_free(&crt); + USE_PSA_DONE(); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C */ void x509parse_crt(data_t *buf, char *result_str, int result) { From 79ee110446e9ac37c3fdef5cd3c3c72bbce8b2cd Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Wed, 14 Feb 2024 21:34:21 +0000 Subject: [PATCH 092/123] Added changelog Signed-off-by: Minos Galanakis --- ChangeLog.d/x509-add-ca_istrue.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ChangeLog.d/x509-add-ca_istrue.txt diff --git a/ChangeLog.d/x509-add-ca_istrue.txt b/ChangeLog.d/x509-add-ca_istrue.txt new file mode 100644 index 0000000000..4594c2296b --- /dev/null +++ b/ChangeLog.d/x509-add-ca_istrue.txt @@ -0,0 +1,4 @@ +Features + * Add new accessor to expose the `MBEDTLS_PRIVATE(ca_istrue)` member of + `mbedtls_x509_crt` structure. This requires setting + MBEDTLS_X509_EXT_BASIC_CONSTRAINTS. From 987cf898db9bff52ec13b08a67f85517cab26fd2 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 4 Mar 2024 10:24:27 +0100 Subject: [PATCH 093/123] ssl_helpers: Restore rng_seed incrementation Signed-off-by: Ronald Cron --- tests/src/test_helpers/ssl_helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index 860b0a39f4..53003b2232 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -43,7 +43,7 @@ void mbedtls_test_init_handshake_options( mbedtls_test_handshake_test_options *opts) { #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) - int rng_seed = 0xBEEF; + static int rng_seed = 0xBEEF; srand(rng_seed); rng_seed += 0xD0; From 87b4f6d86c17fa4f6f08ff1df71b78001b85e883 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Tue, 5 Mar 2024 11:05:51 +0000 Subject: [PATCH 094/123] x509: Reworded documentation bits. Signed-off-by: Minos Galanakis --- ChangeLog.d/x509-add-ca_istrue.txt | 3 ++- include/mbedtls/x509_crt.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ChangeLog.d/x509-add-ca_istrue.txt b/ChangeLog.d/x509-add-ca_istrue.txt index 4594c2296b..c950dbc08b 100644 --- a/ChangeLog.d/x509-add-ca_istrue.txt +++ b/ChangeLog.d/x509-add-ca_istrue.txt @@ -1,4 +1,5 @@ Features * Add new accessor to expose the `MBEDTLS_PRIVATE(ca_istrue)` member of `mbedtls_x509_crt` structure. This requires setting - MBEDTLS_X509_EXT_BASIC_CONSTRAINTS. + the MBEDTLS_X509_EXT_BASIC_CONSTRAINTS bit in the certificate's + ext_types field. diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h index fc1d0bc7b1..1ce0d23619 100644 --- a/include/mbedtls/x509_crt.h +++ b/include/mbedtls/x509_crt.h @@ -922,7 +922,7 @@ static inline int mbedtls_x509_crt_has_ext_type(const mbedtls_x509_crt *ctx, * \param[in] crt Certificate to be queried, must not be \c NULL * * \return \c 1 if this a CA certificate \c 0 otherwise. - * \return MBEDTLS_ERR_X509_INVALID_EXTENSIONS if the certificate does not support + * \return MBEDTLS_ERR_X509_INVALID_EXTENSIONS if the certificate does not contain * the Optional Basic Constraint extension. * */ From 2e7dfd518121f483f20c06ac58f0a6062b1c7e4a Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 5 Mar 2024 10:54:33 +0100 Subject: [PATCH 095/123] tls13: Remove unnecessary cast from size_t to uint32_t Signed-off-by: Ronald Cron --- library/ssl_tls13_generic.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index eec2bb4b75..9fbd3ac276 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -1459,8 +1459,6 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl, int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl, size_t early_data_len) { - uint32_t uint32_early_data_len = (uint32_t) early_data_len; - /* * This function should be called only while an handshake is in progress * and thus a session under negotiation. Add a sanity check to detect a @@ -1475,13 +1473,13 @@ int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl, * A server receiving more than max_early_data_size bytes of 0-RTT data * SHOULD terminate the connection with an "unexpected_message" alert. */ - if (uint32_early_data_len > + if (early_data_len > (ssl->session_negotiate->max_early_data_size - ssl->total_early_data_size)) { MBEDTLS_SSL_DEBUG_MSG( - 2, ("EarlyData: Too much early data received, %u > %u", - ssl->total_early_data_size + uint32_early_data_len, + 2, ("EarlyData: Too much early data received, %u + %" MBEDTLS_PRINTF_SIZET " > %u", + ssl->total_early_data_size, early_data_len, ssl->session_negotiate->max_early_data_size)); MBEDTLS_SSL_PEND_FATAL_ALERT( @@ -1490,7 +1488,13 @@ int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl, return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; } - ssl->total_early_data_size += uint32_early_data_len; + /* + * The check just above implies that early_data_len is lower than + * UINT32_MAX thus its cast to an uint32_t below is safe. We need it + * to appease some compilers. + */ + + ssl->total_early_data_size += (uint32_t) early_data_len; return 0; } From 053b7886e5620be4910ba915d527d4b73a98849c Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Tue, 5 Mar 2024 11:46:32 +0000 Subject: [PATCH 096/123] Ensure drivers have threading enabled if required Signed-off-by: Paul Elliott --- tests/include/test/drivers/config_test_driver.h | 2 ++ tests/scripts/all.sh | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/tests/include/test/drivers/config_test_driver.h b/tests/include/test/drivers/config_test_driver.h index 4eb27f024e..ec8bcb6135 100644 --- a/tests/include/test/drivers/config_test_driver.h +++ b/tests/include/test/drivers/config_test_driver.h @@ -40,5 +40,7 @@ //#define MBEDTLS_MD_C //#define MBEDTLS_PEM_PARSE_C //#define MBEDTLS_BASE64_C +//#define MBEDTLS_THREADING_C +//#define MBEDTLS_THREADING_PTHREAD #endif /* MBEDTLS_CONFIG_H */ diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index c25f044409..37cf6af8fc 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -889,6 +889,16 @@ helper_libtestdriver1_adjust_config() { # Dynamic secure element support is a deprecated feature and needs to be disabled here. # This is done to have the same form of psa_key_attributes_s for libdriver and library. scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C + + # If threading is enabled on the normal build, then we need to enable it in the drivers as well, + # otherwise we will end up running multithreaded tests without mutexes to protect them. + if scripts/config.py get MBEDTLS_THREADING_C; then + scripts/config.py -f "$CONFIG_TEST_DRIVER_H" set MBEDTLS_THREADING_C + fi + + if scripts/config.py get MBEDTLS_THREADING_PTHREAD; then + scripts/config.py -f "$CONFIG_TEST_DRIVER_H" set MBEDTLS_THREADING_PTHREAD + fi } # When called with no parameter this function disables all builtin curves. From 581e63637acec0e4b5e14ef909124ce0a2f2a947 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Tue, 5 Mar 2024 11:46:22 +0000 Subject: [PATCH 097/123] test_suite_x509parse: Added test-case for legacy certificate Signed-off-by: Minos Galanakis --- tests/suites/test_suite_x509parse.data | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index 7519d82d2b..754660c56f 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -3163,6 +3163,10 @@ X509 File parse & read the ca_istrue field (Set) depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_HAVE_TIME_DATE:MBEDTLS_MD_CAN_SHA1 mbedtls_x509_get_ca_istrue:"data_files/test-ca.crt":1 +X509 File parse & read the ca_istrue field (Legacy Certificate) +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_HAVE_TIME_DATE:MBEDTLS_MD_CAN_SHA1:MBEDTLS_MD_CAN_SHA256 +mbedtls_x509_get_ca_istrue:"data_files/server1-v1.crt":MBEDTLS_ERR_X509_INVALID_EXTENSIONS + X509 Get time (UTC no issues) depends_on:MBEDTLS_X509_USE_C x509_get_time:MBEDTLS_ASN1_UTC_TIME:"500101000000Z":0:1950:1:1:0:0:0 From 967f8cde843675d6ecf88f53440c55a7be49bf54 Mon Sep 17 00:00:00 2001 From: Moritz Fischer Date: Sat, 2 Mar 2024 00:55:06 +0000 Subject: [PATCH 098/123] library: psa_crypto: Explicitly initialize shared_secret When building with -Og (specifically Zephyr with CONFIG_DEBUG_OPTIMIZATIONS=y) one observes the following warning: 'shared_secret' may be used uninitialized [-Werror=maybe-uninitialized] Fix this by zero initializing 'shared_secret' similar to the issue addressed in commit 2fab5c960 ("Work around for GCC bug"). Signed-off-by: Moritz Fischer --- library/psa_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index ca01e76491..96b8250efb 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -7046,7 +7046,7 @@ static psa_status_t psa_key_agreement_internal(psa_key_derivation_operation_t *o size_t peer_key_length) { psa_status_t status; - uint8_t shared_secret[PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE]; + uint8_t shared_secret[PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE] = { 0 }; size_t shared_secret_length = 0; psa_algorithm_t ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE(operation->alg); From 93795f2639a4ab68ced9b9211fc55bf1d5343108 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 7 Mar 2024 09:24:56 +0100 Subject: [PATCH 099/123] tls13: Improve comment about cast to uint32_t Signed-off-by: Ronald Cron --- library/ssl_tls13_generic.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index 9fbd3ac276..d448a054a9 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -1472,6 +1472,10 @@ int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl, * * A server receiving more than max_early_data_size bytes of 0-RTT data * SHOULD terminate the connection with an "unexpected_message" alert. + * Note that if it is still possible to send early_data_len bytes of early + * data, it means that early_data_len is smaller than max_early_data_size + * (type uint32_t) and can fit in an uint32_t. We use this further + * down. */ if (early_data_len > (ssl->session_negotiate->max_early_data_size - @@ -1489,11 +1493,10 @@ int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl, } /* - * The check just above implies that early_data_len is lower than - * UINT32_MAX thus its cast to an uint32_t below is safe. We need it - * to appease some compilers. + * early_data_len has been checked to be less than max_early_data_size + * that is uint32_t. Its cast to an uint32_t below is thus safe. We need + * the cast to appease some compilers. */ - ssl->total_early_data_size += (uint32_t) early_data_len; return 0; From 6e31127f08908101f8ed750a62a0cc6786c7c8ba Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 5 Dec 2023 17:57:01 +0100 Subject: [PATCH 100/123] tls13: srv: Define specific return macros for binder check Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 3a968aa964..6fcf8a23cd 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -324,6 +324,8 @@ static int ssl_tls13_offered_psks_check_identity_match( return SSL_TLS1_3_OFFERED_PSK_NOT_MATCH; } +#define SSL_TLS1_3_BINDER_DOES_NOT_MATCH 1 +#define SSL_TLS1_3_BINDER_MATCH 0 MBEDTLS_CHECK_RETURN_CRITICAL static int ssl_tls13_offered_psks_check_binder_match( mbedtls_ssl_context *ssl, @@ -368,12 +370,12 @@ static int ssl_tls13_offered_psks_check_binder_match( MBEDTLS_SSL_DEBUG_BUF(3, "psk binder ( received ): ", binder, binder_len); if (mbedtls_ct_memcmp(server_computed_binder, binder, binder_len) == 0) { - return SSL_TLS1_3_OFFERED_PSK_MATCH; + return SSL_TLS1_3_BINDER_MATCH; } mbedtls_platform_zeroize(server_computed_binder, sizeof(server_computed_binder)); - return SSL_TLS1_3_OFFERED_PSK_NOT_MATCH; + return SSL_TLS1_3_BINDER_DOES_NOT_MATCH; } MBEDTLS_CHECK_RETURN_CRITICAL @@ -626,7 +628,7 @@ static int ssl_tls13_parse_pre_shared_key_ext( ret = ssl_tls13_offered_psks_check_binder_match( ssl, binder, binder_len, psk_type, mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac)); - if (ret != SSL_TLS1_3_OFFERED_PSK_MATCH) { + if (ret != SSL_TLS1_3_BINDER_MATCH) { /* For security reasons, the handshake should be aborted when we * fail to validate a binder value. See RFC 8446 section 4.2.11.2 * and appendix E.6. */ From 3cdcac564721f3ab0283e7f341d0be26696e3c52 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 5 Dec 2023 17:43:02 +0100 Subject: [PATCH 101/123] tls13: srv: Fix return value Fix the value returned by ssl_tls13_offered_psks_check_identity_match_ticket() when there is no ticket parser function defined or no time. Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 6fcf8a23cd..f23ba767e9 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -123,7 +123,7 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket( /* Ticket parser is not configured, Skip */ if (ssl->conf->f_ticket_parse == NULL || identity_len == 0) { - return 0; + return SSL_TLS1_3_OFFERED_PSK_NOT_MATCH; } /* We create a copy of the encrypted ticket since the ticket parsing @@ -171,7 +171,6 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket( * * We regard the ticket with incompatible key exchange modes as not match. */ - ret = MBEDTLS_ERR_ERROR_GENERIC_ERROR; MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags); key_exchanges = 0; @@ -186,11 +185,12 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket( if (key_exchanges == 0) { MBEDTLS_SSL_DEBUG_MSG(3, ("No suitable key exchange mode")); + ret = MBEDTLS_ERR_ERROR_GENERIC_ERROR; goto exit; } - ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED; #if defined(MBEDTLS_HAVE_TIME) + ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED; now = mbedtls_ms_time(); if (now < session->ticket_creation_time) { @@ -244,7 +244,6 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket( } ret = 0; - #endif /* MBEDTLS_HAVE_TIME */ exit: From fbae94a52f5835a1eedb1fdc7bdfff326cf217ae Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 5 Dec 2023 18:15:14 +0100 Subject: [PATCH 102/123] tls13: srv: Improve ticket identity check return values Improve the values returned by ssl_tls13_offered_psks_check_identity_match_ticket(). Distinguish between the two following cases: 1) the PSK identity is not a valid ticket identity 2) the PSK identity is a valid ticket identity but the ticket cannot be used for session resumption. Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 61 +++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index f23ba767e9..ca5e112cad 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -90,8 +90,9 @@ static int ssl_tls13_parse_key_exchange_modes_ext(mbedtls_ssl_context *ssl, return 0; } -#define SSL_TLS1_3_OFFERED_PSK_NOT_MATCH 1 -#define SSL_TLS1_3_OFFERED_PSK_MATCH 0 +#define SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH 2 +#define SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE 1 +#define SSL_TLS1_3_PSK_IDENTITY_MATCH 0 #if defined(MBEDTLS_SSL_SESSION_TICKETS) MBEDTLS_CHECK_RETURN_CRITICAL @@ -123,7 +124,7 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket( /* Ticket parser is not configured, Skip */ if (ssl->conf->f_ticket_parse == NULL || identity_len == 0) { - return SSL_TLS1_3_OFFERED_PSK_NOT_MATCH; + return SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH; } /* We create a copy of the encrypted ticket since the ticket parsing @@ -138,28 +139,36 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket( } memcpy(ticket_buffer, identity, identity_len); - if ((ret = ssl->conf->f_ticket_parse(ssl->conf->p_ticket, - session, - ticket_buffer, identity_len)) != 0) { - if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) { - MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is not authentic")); - } else if (ret == MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) { + ret = ssl->conf->f_ticket_parse(ssl->conf->p_ticket, + session, + ticket_buffer, identity_len); + if (ret == 0) { + ret = SSL_TLS1_3_PSK_IDENTITY_MATCH; + } else { + if (ret == MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) { MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is expired")); + ret = SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE; } else { - MBEDTLS_SSL_DEBUG_RET(1, "ticket_parse", ret); + if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) { + MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is not authentic")); + } else { + MBEDTLS_SSL_DEBUG_RET(1, "ticket_parse", ret); + } + ret = SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH; } } /* We delete the temporary buffer */ mbedtls_free(ticket_buffer); - if (ret == 0 && session->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) { - MBEDTLS_SSL_DEBUG_MSG(3, ("Ticket TLS version is not 1.3.")); - /* TODO: Define new return value for this case. */ - ret = MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION; + if (ret != SSL_TLS1_3_PSK_IDENTITY_MATCH) { + goto exit; } - if (ret != 0) { + ret = SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE; + + if (session->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) { + MBEDTLS_SSL_DEBUG_MSG(3, ("Ticket TLS version is not 1.3.")); goto exit; } @@ -185,12 +194,10 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket( if (key_exchanges == 0) { MBEDTLS_SSL_DEBUG_MSG(3, ("No suitable key exchange mode")); - ret = MBEDTLS_ERR_ERROR_GENERIC_ERROR; goto exit; } #if defined(MBEDTLS_HAVE_TIME) - ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED; now = mbedtls_ms_time(); if (now < session->ticket_creation_time) { @@ -242,12 +249,12 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket( age_diff)); goto exit; } - - ret = 0; #endif /* MBEDTLS_HAVE_TIME */ + ret = SSL_TLS1_3_PSK_IDENTITY_MATCH; + exit: - if (ret != 0) { + if (ret != SSL_TLS1_3_PSK_IDENTITY_MATCH) { mbedtls_ssl_session_free(session); } @@ -277,7 +284,7 @@ static int ssl_tls13_offered_psks_check_identity_match( #if defined(MBEDTLS_SSL_SESSION_TICKETS) if (ssl_tls13_offered_psks_check_identity_match_ticket( ssl, identity, identity_len, obfuscated_ticket_age, - session) == SSL_TLS1_3_OFFERED_PSK_MATCH) { + session) == SSL_TLS1_3_PSK_IDENTITY_MATCH) { ssl->handshake->resume = 1; *psk_type = MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION; ret = mbedtls_ssl_set_hs_psk(ssl, @@ -293,7 +300,7 @@ static int ssl_tls13_offered_psks_check_identity_match( session->resumption_key_len); MBEDTLS_SSL_DEBUG_MSG(4, ("ticket: obfuscated_ticket_age: %u", (unsigned) obfuscated_ticket_age)); - return SSL_TLS1_3_OFFERED_PSK_MATCH; + return SSL_TLS1_3_PSK_IDENTITY_MATCH; } #endif /* MBEDTLS_SSL_SESSION_TICKETS */ @@ -301,9 +308,9 @@ static int ssl_tls13_offered_psks_check_identity_match( if (ssl->conf->f_psk != NULL) { if (ssl->conf->f_psk( ssl->conf->p_psk, ssl, identity, identity_len) == 0) { - return SSL_TLS1_3_OFFERED_PSK_MATCH; + return SSL_TLS1_3_PSK_IDENTITY_MATCH; } - return SSL_TLS1_3_OFFERED_PSK_NOT_MATCH; + return SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH; } MBEDTLS_SSL_DEBUG_BUF(5, "identity", identity, identity_len); @@ -317,10 +324,10 @@ static int ssl_tls13_offered_psks_check_identity_match( MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_set_hs_psk", ret); return ret; } - return SSL_TLS1_3_OFFERED_PSK_MATCH; + return SSL_TLS1_3_PSK_IDENTITY_MATCH; } - return SSL_TLS1_3_OFFERED_PSK_NOT_MATCH; + return SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH; } #define SSL_TLS1_3_BINDER_DOES_NOT_MATCH 1 @@ -588,7 +595,7 @@ static int ssl_tls13_parse_pre_shared_key_ext( ret = ssl_tls13_offered_psks_check_identity_match( ssl, identity, identity_len, obfuscated_ticket_age, &psk_type, &session); - if (ret != SSL_TLS1_3_OFFERED_PSK_MATCH) { + if (ret != SSL_TLS1_3_PSK_IDENTITY_MATCH) { continue; } From 7a30cf595437cea6119041a1a5cfef9ca394d227 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 23 Feb 2024 14:38:59 +0100 Subject: [PATCH 103/123] tls13: srv: Stop earlier identity check If an identity has been determined as a ticket identity but the ticket is not usable, do not try to check if the identity is that of an external provided PSK. Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index ca5e112cad..873f909793 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -282,9 +282,9 @@ static int ssl_tls13_offered_psks_check_identity_match( ssl->handshake->resume = 0; #if defined(MBEDTLS_SSL_SESSION_TICKETS) - if (ssl_tls13_offered_psks_check_identity_match_ticket( - ssl, identity, identity_len, obfuscated_ticket_age, - session) == SSL_TLS1_3_PSK_IDENTITY_MATCH) { + ret = ssl_tls13_offered_psks_check_identity_match_ticket( + ssl, identity, identity_len, obfuscated_ticket_age, session); + if (ret == SSL_TLS1_3_PSK_IDENTITY_MATCH) { ssl->handshake->resume = 1; *psk_type = MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION; ret = mbedtls_ssl_set_hs_psk(ssl, @@ -301,6 +301,8 @@ static int ssl_tls13_offered_psks_check_identity_match( MBEDTLS_SSL_DEBUG_MSG(4, ("ticket: obfuscated_ticket_age: %u", (unsigned) obfuscated_ticket_age)); return SSL_TLS1_3_PSK_IDENTITY_MATCH; + } else if (ret == SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE) { + return SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE; } #endif /* MBEDTLS_SSL_SESSION_TICKETS */ From 12e72f16646e43a07dad19ffeeae5f8db92e8313 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 14 Feb 2024 15:49:38 +0100 Subject: [PATCH 104/123] tls13: srv: Always parse the pre-shared key extension Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 7 ++++--- tests/opt-testcases/tls13-kex-modes.sh | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 873f909793..3b7fc831f7 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -1744,10 +1744,11 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, /* Update checksum with either * - The entire content of the CH message, if no PSK extension is present * - The content up to but excluding the PSK extension, if present. + * Always parse the pre-shared key extension when present in the + * ClientHello even if some pre-requisites for PSK key exchange modes are + * not met. That way we always validate the syntax of the extension. */ - /* If we've settled on a PSK-based exchange, parse PSK identity ext */ - if (ssl_tls13_key_exchange_is_psk_available(ssl) || - ssl_tls13_key_exchange_is_psk_ephemeral_available(ssl)) { + if (handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY)) { ret = handshake->update_checksum(ssl, buf, pre_shared_key_ext - buf); if (0 != ret) { diff --git a/tests/opt-testcases/tls13-kex-modes.sh b/tests/opt-testcases/tls13-kex-modes.sh index 4581bc5e30..6556cd4b45 100755 --- a/tests/opt-testcases/tls13-kex-modes.sh +++ b/tests/opt-testcases/tls13-kex-modes.sh @@ -550,7 +550,7 @@ run_test "TLS 1.3: G->m: psk_or_ephemeral/ephemeral_all, good" \ -s "found pre_shared_key extension" \ -S "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ - -S "Pre shared key found" \ + -s "Pre shared key found" \ -S "No matched PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ @@ -733,7 +733,7 @@ run_test "TLS 1.3: G->m: ephemeral_all/psk_or_ephemeral, good" \ -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ - -S "Pre shared key found" \ + -s "Pre shared key found" \ -S "No matched PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ @@ -1413,7 +1413,7 @@ run_test "TLS 1.3: O->m: ephemeral_all/psk_or_ephemeral, good" \ -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ - -S "Pre shared key found" \ + -s "Pre shared key found" \ -S "No matched PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ From f7e9916b3d46e84d873591802e8bd95540e800c1 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 14 Feb 2024 16:04:02 +0100 Subject: [PATCH 105/123] tls13: srv: Fix MBEDTLS_SSL_SESSION_TICKETS guard position Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 3b7fc831f7..d0e819537e 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -608,18 +608,16 @@ static int ssl_tls13_parse_pre_shared_key_ext( ssl, ciphersuites, ciphersuites_end, &cipher_suite, &ciphersuite_info); break; - case MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION: #if defined(MBEDTLS_SSL_SESSION_TICKETS) + case MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION: ret = ssl_tls13_select_ciphersuite_for_resumption( ssl, ciphersuites, ciphersuites_end, &session, &cipher_suite, &ciphersuite_info); if (ret != 0) { mbedtls_ssl_session_free(&session); } -#else - ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; -#endif break; +#endif default: return MBEDTLS_ERR_SSL_INTERNAL_ERROR; } From 89089cc69beceb78c698da9c789b111dc06dafb2 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 14 Feb 2024 18:18:08 +0100 Subject: [PATCH 106/123] tls13: srv: Factorize ciphersuite selection code Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 213 +++++++++++++++---------------------- 1 file changed, 88 insertions(+), 125 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index d0e819537e..25279b3e34 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -39,6 +39,62 @@ static const mbedtls_ssl_ciphersuite_t *ssl_tls13_validate_peer_ciphersuite( return ciphersuite_info; } +static void ssl_tls13_select_ciphersuite( + mbedtls_ssl_context *ssl, + const unsigned char *cipher_suites, + const unsigned char *cipher_suites_end, + int psk_ciphersuite_id, + psa_algorithm_t psk_hash_alg, + const mbedtls_ssl_ciphersuite_t **selected_ciphersuite_info) +{ + *selected_ciphersuite_info = NULL; + + /* + * This function assumes that the length of the list of ciphersuites is + * even and it should have been checked it is so in the main ClientHello + * parsing function. Double check here. + */ + if ((cipher_suites_end - cipher_suites) & 1) { + return; + } + + for (const unsigned char *p = cipher_suites; + p < cipher_suites_end; p += 2) { + /* + * "cipher_suites_end - p is even" is an invariant of the loop. As + * cipher_suites_end - p > 0, we have cipher_suites_end - p >= 2 and it + * is thus safe to read two bytes. + */ + uint16_t id = MBEDTLS_GET_UINT16_BE(p, 0); + + const mbedtls_ssl_ciphersuite_t *info = + ssl_tls13_validate_peer_ciphersuite(ssl, id); + if (info == NULL) { + continue; + } + + /* + * If a valid PSK ciphersuite identifier has been passed in, we seek + * for an exact match. + */ + if (psk_ciphersuite_id != 0) { + if (id != psk_ciphersuite_id) { + continue; + } + } else if (psk_hash_alg != PSA_ALG_NONE) { + if (mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) info->mac) != + psk_hash_alg) { + continue; + } + } + + *selected_ciphersuite_info = info; + return; + } + + MBEDTLS_SSL_DEBUG_MSG(2, ("No matched ciphersuite")); +} + #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) /* From RFC 8446: * @@ -386,91 +442,7 @@ static int ssl_tls13_offered_psks_check_binder_match( return SSL_TLS1_3_BINDER_DOES_NOT_MATCH; } -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_select_ciphersuite_for_psk( - mbedtls_ssl_context *ssl, - const unsigned char *cipher_suites, - const unsigned char *cipher_suites_end, - uint16_t *selected_ciphersuite, - const mbedtls_ssl_ciphersuite_t **selected_ciphersuite_info) -{ - psa_algorithm_t psk_hash_alg = PSA_ALG_SHA_256; - - *selected_ciphersuite = 0; - *selected_ciphersuite_info = NULL; - - /* RFC 8446, page 55. - * - * For externally established PSKs, the Hash algorithm MUST be set when the - * PSK is established or default to SHA-256 if no such algorithm is defined. - * - */ - - /* - * Search for a matching ciphersuite - */ - for (const unsigned char *p = cipher_suites; - p < cipher_suites_end; p += 2) { - uint16_t cipher_suite; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - - cipher_suite = MBEDTLS_GET_UINT16_BE(p, 0); - ciphersuite_info = ssl_tls13_validate_peer_ciphersuite(ssl, - cipher_suite); - if (ciphersuite_info == NULL) { - continue; - } - - /* MAC of selected ciphersuite MUST be same with PSK binder if exist. - * Otherwise, client should reject. - */ - if (psk_hash_alg == - mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac)) { - *selected_ciphersuite = cipher_suite; - *selected_ciphersuite_info = ciphersuite_info; - return 0; - } - } - MBEDTLS_SSL_DEBUG_MSG(2, ("No matched ciphersuite")); - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; -} - #if defined(MBEDTLS_SSL_SESSION_TICKETS) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_select_ciphersuite_for_resumption( - mbedtls_ssl_context *ssl, - const unsigned char *cipher_suites, - const unsigned char *cipher_suites_end, - mbedtls_ssl_session *session, - uint16_t *selected_ciphersuite, - const mbedtls_ssl_ciphersuite_t **selected_ciphersuite_info) -{ - - *selected_ciphersuite = 0; - *selected_ciphersuite_info = NULL; - for (const unsigned char *p = cipher_suites; p < cipher_suites_end; p += 2) { - uint16_t cipher_suite = MBEDTLS_GET_UINT16_BE(p, 0); - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - - if (cipher_suite != session->ciphersuite) { - continue; - } - - ciphersuite_info = ssl_tls13_validate_peer_ciphersuite(ssl, - cipher_suite); - if (ciphersuite_info == NULL) { - continue; - } - - *selected_ciphersuite = cipher_suite; - *selected_ciphersuite_info = ciphersuite_info; - - return 0; - } - - return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; -} - MBEDTLS_CHECK_RETURN_CRITICAL static int ssl_tls13_session_copy_ticket(mbedtls_ssl_session *dst, const mbedtls_ssl_session *src) @@ -569,7 +541,8 @@ static int ssl_tls13_parse_pre_shared_key_ext( const unsigned char *binder; size_t binder_len; int psk_type; - uint16_t cipher_suite; + int psk_ciphersuite_id; + psa_algorithm_t psk_hash_alg; const mbedtls_ssl_ciphersuite_t *ciphersuite_info; #if defined(MBEDTLS_SSL_SESSION_TICKETS) mbedtls_ssl_session session; @@ -602,33 +575,39 @@ static int ssl_tls13_parse_pre_shared_key_ext( } MBEDTLS_SSL_DEBUG_MSG(4, ("found matched identity")); + switch (psk_type) { case MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL: - ret = ssl_tls13_select_ciphersuite_for_psk( - ssl, ciphersuites, ciphersuites_end, - &cipher_suite, &ciphersuite_info); + psk_ciphersuite_id = 0; + psk_hash_alg = PSA_ALG_SHA_256; break; #if defined(MBEDTLS_SSL_SESSION_TICKETS) case MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION: - ret = ssl_tls13_select_ciphersuite_for_resumption( - ssl, ciphersuites, ciphersuites_end, &session, - &cipher_suite, &ciphersuite_info); - if (ret != 0) { - mbedtls_ssl_session_free(&session); - } + psk_ciphersuite_id = session.ciphersuite; + psk_hash_alg = PSA_ALG_NONE; break; #endif default: return MBEDTLS_ERR_SSL_INTERNAL_ERROR; } - if (ret != 0) { - /* See below, no cipher_suite available, abort handshake */ + + ssl_tls13_select_ciphersuite(ssl, ciphersuites, ciphersuites_end, + psk_ciphersuite_id, psk_hash_alg, + &ciphersuite_info); + + if (ciphersuite_info == NULL) { +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + mbedtls_ssl_session_free(&session); +#endif + /* + * We consider finding a ciphersuite suitable for the PSK as part + * of the validation of its binder. Thus if we do not find one, we + * abort the handshake with a decrypt_error alert. + */ MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR, MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE); - MBEDTLS_SSL_DEBUG_RET( - 2, "ssl_tls13_select_ciphersuite", ret); - return ret; + return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; } ret = ssl_tls13_offered_psks_check_binder_match( @@ -654,9 +633,10 @@ static int ssl_tls13_parse_pre_shared_key_ext( /* Update handshake parameters */ ssl->handshake->ciphersuite_info = ciphersuite_info; - ssl->session_negotiate->ciphersuite = cipher_suite; + ssl->session_negotiate->ciphersuite = ciphersuite_info->id; MBEDTLS_SSL_DEBUG_MSG(2, ("overwrite ciphersuite: %04x - %s", - cipher_suite, ciphersuite_info->name)); + ((unsigned) ciphersuite_info->id), + ciphersuite_info->name)); #if defined(MBEDTLS_SSL_SESSION_TICKETS) if (psk_type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) { ret = ssl_tls13_session_copy_ticket(ssl->session_negotiate, @@ -1472,37 +1452,20 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, */ MBEDTLS_SSL_DEBUG_BUF(3, "client hello, list of cipher suites", cipher_suites, cipher_suites_len); - for (const unsigned char *cipher_suites_p = cipher_suites; - cipher_suites_p < cipher_suites_end; cipher_suites_p += 2) { - uint16_t cipher_suite; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - /* - * "cipher_suites_end - cipher_suites_p is even" is an invariant of the - * loop. As cipher_suites_end - cipher_suites_p > 0, we have - * cipher_suites_end - cipher_suites_p >= 2 and it is thus safe to read - * two bytes. - */ - cipher_suite = MBEDTLS_GET_UINT16_BE(cipher_suites_p, 0); - ciphersuite_info = ssl_tls13_validate_peer_ciphersuite( - ssl, cipher_suite); - if (ciphersuite_info == NULL) { - continue; - } - - ssl->session_negotiate->ciphersuite = cipher_suite; - handshake->ciphersuite_info = ciphersuite_info; - MBEDTLS_SSL_DEBUG_MSG(2, ("selected ciphersuite: %04x - %s", - cipher_suite, - ciphersuite_info->name)); - break; - } + ssl_tls13_select_ciphersuite(ssl, cipher_suites, cipher_suites_end, + 0, PSA_ALG_NONE, &handshake->ciphersuite_info); if (handshake->ciphersuite_info == NULL) { MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE, MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE); return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; } + ssl->session_negotiate->ciphersuite = handshake->ciphersuite_info->id; + + MBEDTLS_SSL_DEBUG_MSG(2, ("selected ciphersuite: %04x - %s", + ((unsigned) handshake->ciphersuite_info->id), + handshake->ciphersuite_info->name)); /* ... * opaque legacy_compression_methods<1..2^8-1>; From cf284565c5aa4ccc64ac3959f1b35bbf04792064 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 16 Feb 2024 18:54:10 +0100 Subject: [PATCH 107/123] tls13: srv: Determine best key exchange mode for a PSK Determine best key exchange for for ticket based and external PSKs. Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 51 +++++---- tests/opt-testcases/tls13-kex-modes.sh | 143 +++++++++++++------------ tests/opt-testcases/tls13-misc.sh | 34 +++--- 3 files changed, 114 insertions(+), 114 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 25279b3e34..9b273b834c 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -166,7 +166,6 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket( { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char *ticket_buffer; - unsigned int key_exchanges; #if defined(MBEDTLS_HAVE_TIME) mbedtls_ms_time_t now; mbedtls_ms_time_t server_age; @@ -228,31 +227,6 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket( goto exit; } - /* RFC 8446 section 4.2.9 - * - * Servers SHOULD NOT send NewSessionTicket with tickets that are not - * compatible with the advertised modes; however, if a server does so, - * the impact will just be that the client's attempts at resumption fail. - * - * We regard the ticket with incompatible key exchange modes as not match. - */ - MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags); - - key_exchanges = 0; - if (mbedtls_ssl_tls13_session_ticket_allow_psk_ephemeral(session) && - ssl_tls13_key_exchange_is_psk_ephemeral_available(ssl)) { - key_exchanges |= MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL; - } - if (mbedtls_ssl_tls13_session_ticket_allow_psk(session) && - ssl_tls13_key_exchange_is_psk_available(ssl)) { - key_exchanges |= MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK; - } - - if (key_exchanges == 0) { - MBEDTLS_SSL_DEBUG_MSG(3, ("No suitable key exchange mode")); - goto exit; - } - #if defined(MBEDTLS_HAVE_TIME) now = mbedtls_ms_time(); @@ -543,6 +517,8 @@ static int ssl_tls13_parse_pre_shared_key_ext( int psk_type; int psk_ciphersuite_id; psa_algorithm_t psk_hash_alg; + int allowed_key_exchange_modes; + int key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE; const mbedtls_ssl_ciphersuite_t *ciphersuite_info; #if defined(MBEDTLS_SSL_SESSION_TICKETS) mbedtls_ssl_session session; @@ -580,17 +556,38 @@ static int ssl_tls13_parse_pre_shared_key_ext( case MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL: psk_ciphersuite_id = 0; psk_hash_alg = PSA_ALG_SHA_256; + allowed_key_exchange_modes = + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL; break; #if defined(MBEDTLS_SSL_SESSION_TICKETS) case MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION: psk_ciphersuite_id = session.ciphersuite; psk_hash_alg = PSA_ALG_NONE; + ssl->session_negotiate->ticket_flags = session.ticket_flags; + allowed_key_exchange_modes = + session.ticket_flags & + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL; break; #endif default: return MBEDTLS_ERR_SSL_INTERNAL_ERROR; } + if ((allowed_key_exchange_modes & + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL) && + ssl_tls13_key_exchange_is_psk_ephemeral_available(ssl)) { + key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL; + } else if ((allowed_key_exchange_modes & + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) && + ssl_tls13_key_exchange_is_psk_available(ssl)) { + key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK; + } + + if (key_exchange_mode == MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE) { + MBEDTLS_SSL_DEBUG_MSG(3, ("No suitable PSK key exchange mode")); + continue; + } + ssl_tls13_select_ciphersuite(ssl, ciphersuites, ciphersuites_end, psk_ciphersuite_id, psk_hash_alg, &ciphersuite_info); @@ -664,7 +661,7 @@ static int ssl_tls13_parse_pre_shared_key_ext( return ret; } if (matched_identity == -1) { - MBEDTLS_SSL_DEBUG_MSG(3, ("No matched PSK or ticket.")); + MBEDTLS_SSL_DEBUG_MSG(3, ("No usable PSK or ticket.")); return MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY; } diff --git a/tests/opt-testcases/tls13-kex-modes.sh b/tests/opt-testcases/tls13-kex-modes.sh index 6556cd4b45..49f06e0715 100755 --- a/tests/opt-testcases/tls13-kex-modes.sh +++ b/tests/opt-testcases/tls13-kex-modes.sh @@ -23,7 +23,7 @@ run_test "TLS 1.3: G->m: all/psk, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -s "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -41,7 +41,7 @@ run_test "TLS 1.3: G->m: all/psk, fail, key id mismatch" \ -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -78,7 +78,7 @@ run_test "TLS 1.3: G->m: psk_or_ephemeral/psk, good" \ -S "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -s "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -96,7 +96,7 @@ run_test "TLS 1.3: G->m: psk_or_ephemeral/psk, fail, key id mismatch" \ -s "found pre_shared_key extension" \ -S "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -133,7 +133,7 @@ run_test "TLS 1.3: G->m: ephemeral_all/psk_ephemeral, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -s "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -151,7 +151,7 @@ run_test "TLS 1.3: G->m: ephemeral_all/psk_ephemeral, fail, key id mismatch" -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -188,7 +188,7 @@ run_test "TLS 1.3: G->m: all/psk_ephemeral, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -s "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -206,7 +206,7 @@ run_test "TLS 1.3: G->m: all/psk_ephemeral, fail, key id mismatch" \ -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -261,7 +261,7 @@ run_test "TLS 1.3: G->m: ephemeral_all/psk_all, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -s "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -280,7 +280,7 @@ run_test "TLS 1.3: G->m: ephemeral_all/psk_all, fail, key id mismatch" \ -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -319,7 +319,7 @@ run_test "TLS 1.3: G->m: all/psk_all, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -s "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -338,7 +338,7 @@ run_test "TLS 1.3: G->m: all/psk_all, fail, key id mismatch" \ -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -377,7 +377,7 @@ run_test "TLS 1.3: G->m: psk_or_ephemeral/psk_all, good" \ -S "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -s "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -396,7 +396,7 @@ run_test "TLS 1.3: G->m: psk_or_ephemeral/psk_all, fail, key id mismatch" \ -s "found pre_shared_key extension" \ -S "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -435,7 +435,7 @@ run_test "TLS 1.3: G->m: ephemeral_all/ephemeral_all, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -s "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -454,7 +454,7 @@ run_test "TLS 1.3: G->m: ephemeral_all/ephemeral_all, good, key id mismatch, -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -s "key exchange mode: ephemeral" @@ -493,7 +493,7 @@ run_test "TLS 1.3: G->m: all/ephemeral_all, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -s "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -512,7 +512,7 @@ run_test "TLS 1.3: G->m: all/ephemeral_all, good, key id mismatch, dhe." \ -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -s "key exchange mode: ephemeral" @@ -550,8 +550,9 @@ run_test "TLS 1.3: G->m: psk_or_ephemeral/ephemeral_all, good" \ -s "found pre_shared_key extension" \ -S "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ - -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -s "No suitable PSK key exchange mode" \ + -S "Pre shared key found" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -s "key exchange mode: ephemeral" @@ -572,7 +573,7 @@ run_test "TLS 1.3: G->m: ephemeral_all/all, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -s "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -592,7 +593,7 @@ run_test "TLS 1.3: G->m: ephemeral_all/all, good, key id mismatch, dhe." \ -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -s "key exchange mode: ephemeral" @@ -633,7 +634,7 @@ run_test "TLS 1.3: G->m: all/all, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -s "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -653,7 +654,7 @@ run_test "TLS 1.3: G->m: all/all, good, key id mismatch, dhe." \ -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -s "key exchange mode: ephemeral" @@ -694,7 +695,7 @@ run_test "TLS 1.3: G->m: psk_or_ephemeral/all, good" \ -S "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -s "key exchange mode: ephemeral" @@ -733,8 +734,9 @@ run_test "TLS 1.3: G->m: ephemeral_all/psk_or_ephemeral, good" \ -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ - -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -s "No suitable PSK key exchange mode" \ + -S "Pre shared key found" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -s "key exchange mode: ephemeral" @@ -754,7 +756,7 @@ run_test "TLS 1.3: G->m: all/psk_or_ephemeral, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -s "key exchange mode: ephemeral" @@ -793,7 +795,7 @@ run_test "TLS 1.3: G->m: psk_or_ephemeral/psk_or_ephemeral, good" \ -S "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -s "key exchange mode: ephemeral" @@ -921,7 +923,7 @@ run_test "TLS 1.3: O->m: all/psk, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -s "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -938,7 +940,7 @@ run_test "TLS 1.3: O->m: all/psk, fail, key id mismatch" \ -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -973,7 +975,7 @@ run_test "TLS 1.3: O->m: ephemeral_all/psk_ephemeral, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -s "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -990,7 +992,7 @@ run_test "TLS 1.3: O->m: ephemeral_all/psk_ephemeral, fail, key id mismatch" -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -1025,7 +1027,7 @@ run_test "TLS 1.3: O->m: all/psk_ephemeral, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -s "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -1042,7 +1044,7 @@ run_test "TLS 1.3: O->m: all/psk_ephemeral, fail, key id mismatch" \ -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -1078,7 +1080,7 @@ run_test "TLS 1.3: O->m: ephemeral_all/psk_all, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -s "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -1096,7 +1098,7 @@ run_test "TLS 1.3: O->m: ephemeral_all/psk_all, fail, key id mismatch" \ -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -1133,7 +1135,7 @@ run_test "TLS 1.3: O->m: all/psk_all, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -s "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -1151,7 +1153,7 @@ run_test "TLS 1.3: O->m: all/psk_all, fail, key id mismatch" \ -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -1188,7 +1190,7 @@ run_test "TLS 1.3: O->m: ephemeral_all/ephemeral_all, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -s "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -1206,7 +1208,7 @@ run_test "TLS 1.3: O->m: ephemeral_all/ephemeral_all, good, key id mismatch, -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -s "key exchange mode: ephemeral" @@ -1243,7 +1245,7 @@ run_test "TLS 1.3: O->m: all/ephemeral_all, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -s "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -1261,7 +1263,7 @@ run_test "TLS 1.3: O->m: all/ephemeral_all, good, key id mismatch, dhe." \ -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -s "key exchange mode: ephemeral" @@ -1299,7 +1301,7 @@ run_test "TLS 1.3: O->m: ephemeral_all/all, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -s "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -1318,7 +1320,7 @@ run_test "TLS 1.3: O->m: ephemeral_all/all, good, key id mismatch, dhe." \ -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -s "key exchange mode: ephemeral" @@ -1357,7 +1359,7 @@ run_test "TLS 1.3: O->m: all/all, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -s "key exchange mode: psk_ephemeral" \ -S "key exchange mode: ephemeral" @@ -1376,7 +1378,7 @@ run_test "TLS 1.3: O->m: all/all, good, key id mismatch, dhe." \ -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -s "key exchange mode: ephemeral" @@ -1413,8 +1415,9 @@ run_test "TLS 1.3: O->m: ephemeral_all/psk_or_ephemeral, good" \ -s "found pre_shared_key extension" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -S "Found PSK KEX MODE" \ - -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -s "No suitable PSK key exchange mode" \ + -S "Pre shared key found" \ + -s "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -s "key exchange mode: ephemeral" @@ -1433,7 +1436,7 @@ run_test "TLS 1.3: O->m: all/psk_or_ephemeral, good" \ -s "Found PSK_EPHEMERAL KEX MODE" \ -s "Found PSK KEX MODE" \ -s "Pre shared key found" \ - -S "No matched PSK or ticket" \ + -S "No usable PSK or ticket" \ -S "key exchange mode: psk$" \ -S "key exchange mode: psk_ephemeral" \ -s "key exchange mode: ephemeral" @@ -1580,7 +1583,7 @@ run_test "TLS 1.3: m->m: psk/psk, fail, key id mismatch" \ -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" + -s "No usable PSK or ticket" requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 requires_config_enabled MBEDTLS_SSL_SRV_C @@ -1665,7 +1668,7 @@ run_test "TLS 1.3: m->m: psk/psk_all, fail, key id mismatch" \ -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -s "ClientHello message misses mandatory extensions." requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 @@ -1711,7 +1714,7 @@ run_test "TLS 1.3: m->m: psk/all, fail, key id mismatch" \ -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -s "ClientHello message misses mandatory extensions." requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 @@ -1769,7 +1772,7 @@ run_test "TLS 1.3: m->m: psk_ephemeral/psk_ephemeral, fail, key id mismatch" -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -s "ClientHello message misses mandatory extensions." requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 @@ -1827,7 +1830,7 @@ run_test "TLS 1.3: m->m: psk_ephemeral/ephemeral_all, fail, key id mismatch" -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" + -s "No usable PSK or ticket" requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 requires_config_enabled MBEDTLS_SSL_SRV_C @@ -1870,7 +1873,7 @@ run_test "TLS 1.3: m->m: psk_ephemeral/psk_all, fail, key id mismatch" \ -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -s "ClientHello message misses mandatory extensions." requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 @@ -1916,7 +1919,7 @@ run_test "TLS 1.3: m->m: psk_ephemeral/all, fail, key id mismatch" \ -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 requires_config_enabled MBEDTLS_SSL_SRV_C @@ -2047,7 +2050,7 @@ run_test "TLS 1.3: m->m: ephemeral_all/psk_ephemeral, fail, key id mismatch" -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" + -s "No usable PSK or ticket" requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 requires_config_enabled MBEDTLS_SSL_SRV_C @@ -2106,7 +2109,7 @@ run_test "TLS 1.3: m->m: ephemeral_all/ephemeral_all,good,key id mismatch,fal -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -s "key exchange mode: ephemeral" requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 @@ -2152,7 +2155,7 @@ run_test "TLS 1.3: m->m: ephemeral_all/psk_all, fail, key id mismatch" \ -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -s "ClientHello message misses mandatory extensions." requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 @@ -2199,7 +2202,7 @@ run_test "TLS 1.3: m->m: ephemeral_all/all, good, key id mismatch, fallback" -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -s "key exchange mode: ephemeral" requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 @@ -2288,7 +2291,7 @@ run_test "TLS 1.3: m->m: psk_all/psk_ephemeral, fail, key id mismatch" \ -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -s "ClientHello message misses mandatory extensions." requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 @@ -2348,7 +2351,7 @@ run_test "TLS 1.3: m->m: psk_all/ephemeral_all, fail, key id mismatch" \ -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" + -s "No usable PSK or ticket" requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 requires_config_enabled MBEDTLS_SSL_SRV_C @@ -2392,7 +2395,7 @@ run_test "TLS 1.3: m->m: psk_all/psk_all, fail, key id mismatch" \ -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -s "ClientHello message misses mandatory extensions." requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 @@ -2438,7 +2441,7 @@ run_test "TLS 1.3: m->m: psk_all/all, fail, key id mismatch" \ -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" + -s "No usable PSK or ticket" requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 requires_config_enabled MBEDTLS_SSL_SRV_C @@ -2485,7 +2488,7 @@ run_test "TLS 1.3: m->m: all/psk, fail, key id mismatch" \ -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -s "ClientHello message misses mandatory extensions." requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 @@ -2532,7 +2535,7 @@ run_test "TLS 1.3: m->m: all/psk_ephemeral, fail, key id mismatch" \ -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -s "ClientHello message misses mandatory extensions." requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 @@ -2595,7 +2598,7 @@ run_test "TLS 1.3: m->m: all/ephemeral_all, good, key id mismatch, fallback" -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -c "Selected key exchange mode: ephemeral" \ -c "HTTP/1.0 200 OK" @@ -2643,7 +2646,7 @@ run_test "TLS 1.3: m->m: all/psk_all, fail, key id mismatch" \ -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -s "ClientHello message misses mandatory extensions." requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 @@ -2690,7 +2693,7 @@ run_test "TLS 1.3: m->m: all/all, good, key id mismatch, fallback" \ -c "client hello, adding pre_shared_key extension, omitting PSK binder list" \ -c "client hello, adding psk_key_exchange_modes extension" \ -c "client hello, adding PSK binder list" \ - -s "No matched PSK or ticket" \ + -s "No usable PSK or ticket" \ -s "key exchange mode: ephemeral" requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh index ad062dccfb..3a21a745f3 100755 --- a/tests/opt-testcases/tls13-misc.sh +++ b/tests/opt-testcases/tls13-misc.sh @@ -353,8 +353,8 @@ run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/none." \ -s "key exchange mode: ephemeral" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: psk$" \ - -s "No suitable key exchange mode" \ - -s "No matched PSK or ticket" + -s "No suitable PSK key exchange mode" \ + -s "No usable PSK or ticket" requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ @@ -365,7 +365,7 @@ run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk." \ "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \ 0 \ -c "Pre-configured PSK number = 1" \ - -S "No suitable key exchange mode" \ + -S "No suitable PSK key exchange mode" \ -s "found matched identity" requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ @@ -381,8 +381,8 @@ run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk_ephemeral." \ -s "key exchange mode: ephemeral" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: psk$" \ - -s "No suitable key exchange mode" \ - -s "No matched PSK or ticket" + -s "No suitable PSK key exchange mode" \ + -s "No usable PSK or ticket" requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ @@ -393,7 +393,7 @@ run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk_all." \ "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \ 0 \ -c "Pre-configured PSK number = 1" \ - -S "No suitable key exchange mode" \ + -S "No suitable PSK key exchange mode" \ -s "found matched identity" requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ @@ -409,8 +409,8 @@ run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/none." \ -s "key exchange mode: ephemeral" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: psk$" \ - -s "No suitable key exchange mode" \ - -s "No matched PSK or ticket" + -s "No suitable PSK key exchange mode" \ + -s "No usable PSK or ticket" requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ @@ -425,8 +425,8 @@ run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk." \ -s "key exchange mode: ephemeral" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: psk$" \ - -s "No suitable key exchange mode" \ - -s "No matched PSK or ticket" + -s "No suitable PSK key exchange mode" \ + -s "No usable PSK or ticket" requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ @@ -437,7 +437,7 @@ run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk_ephemera "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \ 0 \ -c "Pre-configured PSK number = 1" \ - -S "No suitable key exchange mode" \ + -S "No suitable PSK key exchange mode" \ -s "found matched identity" \ -s "key exchange mode: psk_ephemeral" @@ -450,7 +450,7 @@ run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk_all." \ "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \ 0 \ -c "Pre-configured PSK number = 1" \ - -S "No suitable key exchange mode" \ + -S "No suitable PSK key exchange mode" \ -s "found matched identity" \ -s "key exchange mode: psk_ephemeral" @@ -468,8 +468,8 @@ run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/none." \ -s "key exchange mode: ephemeral" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: psk$" \ - -s "No suitable key exchange mode" \ - -s "No matched PSK or ticket" + -s "No suitable PSK key exchange mode" \ + -s "No usable PSK or ticket" requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ @@ -481,7 +481,7 @@ run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk." \ "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \ 0 \ -c "Pre-configured PSK number = 1" \ - -S "No suitable key exchange mode" \ + -S "No suitable PSK key exchange mode" \ -s "found matched identity" requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ @@ -494,7 +494,7 @@ run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk_ephemeral." \ "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \ 0 \ -c "Pre-configured PSK number = 1" \ - -S "No suitable key exchange mode" \ + -S "No suitable PSK key exchange mode" \ -s "found matched identity" \ -s "key exchange mode: psk_ephemeral" @@ -508,7 +508,7 @@ run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk_all." \ "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \ 0 \ -c "Pre-configured PSK number = 1" \ - -S "No suitable key exchange mode" \ + -S "No suitable PSK key exchange mode" \ -s "found matched identity" \ -s "key exchange mode: psk_ephemeral" From 1f63fe4d74520a031f3beb62866e47901203ca09 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 23 Feb 2024 15:49:12 +0100 Subject: [PATCH 108/123] tls13: srv: Fix resume flag in case of cancelled PSK If we prefer ephemeral key exchange mode over the pure PSK one, make sure the resume flag is disabled as eventually we are not going to resume a session even if we aimed to at some point. Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 1 + tests/opt-testcases/tls13-misc.sh | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 9b273b834c..9aec2275b1 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -1074,6 +1074,7 @@ static int ssl_tls13_determine_key_exchange_mode(mbedtls_ssl_context *ssl) MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: psk_ephemeral")); } else if (ssl_tls13_key_exchange_is_ephemeral_available(ssl)) { + ssl->handshake->resume = 0; ssl->handshake->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL; MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: ephemeral")); diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh index 3a21a745f3..90c0fb2a37 100755 --- a/tests/opt-testcases/tls13-misc.sh +++ b/tests/opt-testcases/tls13-misc.sh @@ -535,3 +535,18 @@ run_test "TLS 1.3 G->m: EarlyData: feature is enabled, good." \ -s "$( tail -1 $EARLY_DATA_INPUT )" \ -s "200 early data bytes read" \ -s "106 early data bytes read" + +requires_all_configs_enabled MBEDTLS_SSL_EARLY_DATA MBEDTLS_SSL_SESSION_TICKETS \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: Ephemeral over PSK kex with early data enabled" \ + "$P_SRV force_version=tls13 debug_level=4 max_early_data_size=1024" \ + "$P_CLI debug_level=4 early_data=$EARLY_DATA_INPUT tls13_kex_modes=psk_or_ephemeral reco_mode=1 reconnect=1" \ + 0 \ + -s "key exchange mode: ephemeral" \ + -S "key exchange mode: psk" \ + -s "found matched identity" \ + -s "EarlyData: rejected, not a session resumption" \ + -C "EncryptedExtensions: early_data(42) extension exists." From 79cdd4156ffcd4ac85272d6a8856092a4e6aa8eb Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 20 Feb 2024 17:19:28 +0100 Subject: [PATCH 109/123] tls13: srv: Improve key exchange mode determination For PSK based key exchange modes do not check twice anymore if they can be selected or not. Check it only when looping over the offered PSKs to select one. Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 157 +++++++++++++++++++------------------ 1 file changed, 82 insertions(+), 75 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 9aec2275b1..d6dd4810d9 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -437,6 +437,12 @@ static int ssl_tls13_session_copy_ticket(mbedtls_ssl_session *dst, } #endif /* MBEDTLS_SSL_SESSION_TICKETS */ +struct psk_attributes { + int type; + int key_exchange_mode; +}; +#define PSK_ATTRIBUTES_INIT { 0, 0 } + /* Parser for pre_shared_key extension in client hello * struct { * opaque identity<1..2^16-1>; @@ -463,7 +469,8 @@ static int ssl_tls13_parse_pre_shared_key_ext( const unsigned char *pre_shared_key_ext, const unsigned char *pre_shared_key_ext_end, const unsigned char *ciphersuites, - const unsigned char *ciphersuites_end) + const unsigned char *ciphersuites_end, + struct psk_attributes *psk) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; const unsigned char *identities = pre_shared_key_ext; @@ -514,11 +521,9 @@ static int ssl_tls13_parse_pre_shared_key_ext( uint32_t obfuscated_ticket_age; const unsigned char *binder; size_t binder_len; - int psk_type; int psk_ciphersuite_id; psa_algorithm_t psk_hash_alg; int allowed_key_exchange_modes; - int key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE; const mbedtls_ssl_ciphersuite_t *ciphersuite_info; #if defined(MBEDTLS_SSL_SESSION_TICKETS) mbedtls_ssl_session session; @@ -545,14 +550,14 @@ static int ssl_tls13_parse_pre_shared_key_ext( ret = ssl_tls13_offered_psks_check_identity_match( ssl, identity, identity_len, obfuscated_ticket_age, - &psk_type, &session); + &psk->type, &session); if (ret != SSL_TLS1_3_PSK_IDENTITY_MATCH) { continue; } MBEDTLS_SSL_DEBUG_MSG(4, ("found matched identity")); - switch (psk_type) { + switch (psk->type) { case MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL: psk_ciphersuite_id = 0; psk_hash_alg = PSA_ALG_SHA_256; @@ -573,17 +578,19 @@ static int ssl_tls13_parse_pre_shared_key_ext( return MBEDTLS_ERR_SSL_INTERNAL_ERROR; } + psk->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE; + if ((allowed_key_exchange_modes & MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL) && ssl_tls13_key_exchange_is_psk_ephemeral_available(ssl)) { - key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL; + psk->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL; } else if ((allowed_key_exchange_modes & MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) && ssl_tls13_key_exchange_is_psk_available(ssl)) { - key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK; + psk->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK; } - if (key_exchange_mode == MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE) { + if (psk->key_exchange_mode == MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE) { MBEDTLS_SSL_DEBUG_MSG(3, ("No suitable PSK key exchange mode")); continue; } @@ -608,7 +615,7 @@ static int ssl_tls13_parse_pre_shared_key_ext( } ret = ssl_tls13_offered_psks_check_binder_match( - ssl, binder, binder_len, psk_type, + ssl, binder, binder_len, psk->type, mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac)); if (ret != SSL_TLS1_3_BINDER_MATCH) { /* For security reasons, the handshake should be aborted when we @@ -635,7 +642,7 @@ static int ssl_tls13_parse_pre_shared_key_ext( ((unsigned) ciphersuite_info->id), ciphersuite_info->name)); #if defined(MBEDTLS_SSL_SESSION_TICKETS) - if (psk_type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) { + if (psk->type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) { ret = ssl_tls13_session_copy_ticket(ssl->session_negotiate, &session); mbedtls_ssl_session_free(&session); @@ -1004,19 +1011,6 @@ static int ssl_tls13_ticket_is_kex_mode_permitted(mbedtls_ssl_context *ssl, #endif return 1; } -#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */ - -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_key_exchange_is_ephemeral_available(mbedtls_ssl_context *ssl) -{ -#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) - return mbedtls_ssl_conf_tls13_is_ephemeral_enabled(ssl) && - ssl_tls13_client_hello_has_exts_for_ephemeral_key_exchange(ssl); -#else - ((void) ssl); - return 0; -#endif -} MBEDTLS_CHECK_RETURN_CRITICAL static int ssl_tls13_key_exchange_is_psk_available(mbedtls_ssl_context *ssl) @@ -1047,53 +1041,18 @@ static int ssl_tls13_key_exchange_is_psk_ephemeral_available(mbedtls_ssl_context return 0; #endif } +#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */ -static int ssl_tls13_determine_key_exchange_mode(mbedtls_ssl_context *ssl) +MBEDTLS_CHECK_RETURN_CRITICAL +static int ssl_tls13_key_exchange_is_ephemeral_available(mbedtls_ssl_context *ssl) { - /* - * Determine the key exchange algorithm to use. - * There are three types of key exchanges supported in TLS 1.3: - * - (EC)DH with ECDSA, - * - (EC)DH with PSK, - * - plain PSK. - * - * The PSK-based key exchanges may additionally be used with 0-RTT. - * - * Our built-in order of preference is - * 1 ) (EC)DHE-PSK Mode ( psk_ephemeral ) - * 2 ) Certificate Mode ( ephemeral ) - * 3 ) Plain PSK Mode ( psk ) - */ - - ssl->handshake->key_exchange_mode = - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE; - - if (ssl_tls13_key_exchange_is_psk_ephemeral_available(ssl)) { - ssl->handshake->key_exchange_mode = - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL; - MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: psk_ephemeral")); - } else - if (ssl_tls13_key_exchange_is_ephemeral_available(ssl)) { - ssl->handshake->resume = 0; - ssl->handshake->key_exchange_mode = - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL; - MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: ephemeral")); - } else - if (ssl_tls13_key_exchange_is_psk_available(ssl)) { - ssl->handshake->key_exchange_mode = - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK; - MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: psk")); - } else { - MBEDTLS_SSL_DEBUG_MSG( - 1, - ("ClientHello message misses mandatory extensions.")); - MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_MISSING_EXTENSION, - MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); - return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; - } - +#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) + return mbedtls_ssl_conf_tls13_is_ephemeral_enabled(ssl) && + ssl_tls13_client_hello_has_exts_for_ephemeral_key_exchange(ssl); +#else + ((void) ssl); return 0; - +#endif } #if defined(MBEDTLS_X509_CRT_PARSE_C) && \ @@ -1287,6 +1246,8 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, int no_usable_share_for_key_agreement = 0; #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) + int got_psk = 0; + struct psk_attributes psk = PSK_ATTRIBUTES_INIT; const unsigned char *pre_shared_key_ext = NULL; const unsigned char *pre_shared_key_ext_end = NULL; #endif @@ -1718,10 +1679,11 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, pre_shared_key_ext, pre_shared_key_ext_end, cipher_suites, - cipher_suites_end); - if (ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) { - handshake->received_extensions &= ~MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY); - } else if (ret != 0) { + cipher_suites_end, + &psk); + if (ret == 0) { + got_psk = 1; + } else if (ret != MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) { MBEDTLS_SSL_DEBUG_RET( 1, "ssl_tls13_parse_pre_shared_key_ext", ret); return ret; @@ -1736,12 +1698,57 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, } } - ret = ssl_tls13_determine_key_exchange_mode(ssl); - if (ret < 0) { - return ret; + /* + * Determine the key exchange algorithm to use. + * There are three types of key exchanges supported in TLS 1.3: + * - (EC)DH with ECDSA, + * - (EC)DH with PSK, + * - plain PSK. + * + * The PSK-based key exchanges may additionally be used with 0-RTT. + * + * Our built-in order of preference is + * 1 ) (EC)DHE-PSK Mode ( psk_ephemeral ) + * 2 ) Certificate Mode ( ephemeral ) + * 3 ) Plain PSK Mode ( psk ) + */ +#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) + if (got_psk && (psk.key_exchange_mode == + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL)) { + handshake->key_exchange_mode = + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL; + MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: psk_ephemeral")); + + } else +#endif + if (ssl_tls13_key_exchange_is_ephemeral_available(ssl)) { + handshake->key_exchange_mode = + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL; + MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: ephemeral")); + + } +#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) + else if (got_psk && (psk.key_exchange_mode == + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK)) { + handshake->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK; + MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: psk")); + } +#endif + else { + MBEDTLS_SSL_DEBUG_MSG( + 1, + ("ClientHello message misses mandatory extensions.")); + MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_MISSING_EXTENSION, + MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER); + return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; } - if (ssl->handshake->key_exchange_mode != + if (handshake->key_exchange_mode == + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL) { + handshake->resume = 0; + } + + if (handshake->key_exchange_mode != MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) { hrr_required = (no_usable_share_for_key_agreement != 0); } From e8c162d7ba89ed7fc32e1797d829ecaa24f818c0 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 21 Feb 2024 10:15:44 +0100 Subject: [PATCH 110/123] tls13: srv: Simplify kex availability checks Regarding the possibility of selecting a key exchange mode, the check of the ticket flags is now separated from the check of the ClientHello content and server configuration. Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index d6dd4810d9..a496981828 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -994,31 +994,11 @@ static int ssl_tls13_client_hello_has_exts_for_psk_ephemeral_key_exchange( #endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED */ #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_ticket_is_kex_mode_permitted(mbedtls_ssl_context *ssl, - unsigned int kex_mode) -{ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - if (ssl->handshake->resume) { - if (!mbedtls_ssl_tls13_session_ticket_has_flags( - ssl->session_negotiate, kex_mode)) { - return 0; - } - } -#else - ((void) ssl); - ((void) kex_mode); -#endif - return 1; -} - MBEDTLS_CHECK_RETURN_CRITICAL static int ssl_tls13_key_exchange_is_psk_available(mbedtls_ssl_context *ssl) { #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED) - return ssl_tls13_ticket_is_kex_mode_permitted( - ssl, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) && - mbedtls_ssl_conf_tls13_is_psk_enabled(ssl) && + return mbedtls_ssl_conf_tls13_is_psk_enabled(ssl) && mbedtls_ssl_tls13_is_psk_supported(ssl) && ssl_tls13_client_hello_has_exts_for_psk_key_exchange(ssl); #else @@ -1031,9 +1011,7 @@ MBEDTLS_CHECK_RETURN_CRITICAL static int ssl_tls13_key_exchange_is_psk_ephemeral_available(mbedtls_ssl_context *ssl) { #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED) - return ssl_tls13_ticket_is_kex_mode_permitted( - ssl, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL) && - mbedtls_ssl_conf_tls13_is_psk_ephemeral_enabled(ssl) && + return mbedtls_ssl_conf_tls13_is_psk_ephemeral_enabled(ssl) && mbedtls_ssl_tls13_is_psk_ephemeral_supported(ssl) && ssl_tls13_client_hello_has_exts_for_psk_ephemeral_key_exchange(ssl); #else From 3e47eec4311b1d3e3d45b8e4b1864b4338f5426d Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 21 Feb 2024 10:29:24 +0100 Subject: [PATCH 111/123] tls13: srv: Simplify resumption detection Avoid marking we resume and then cancelling it. Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index a496981828..391b8d42c2 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -309,13 +309,11 @@ static int ssl_tls13_offered_psks_check_identity_match( *psk_type = MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL; MBEDTLS_SSL_DEBUG_BUF(4, "identity", identity, identity_len); - ssl->handshake->resume = 0; #if defined(MBEDTLS_SSL_SESSION_TICKETS) ret = ssl_tls13_offered_psks_check_identity_match_ticket( ssl, identity, identity_len, obfuscated_ticket_age, session); if (ret == SSL_TLS1_3_PSK_IDENTITY_MATCH) { - ssl->handshake->resume = 1; *psk_type = MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION; ret = mbedtls_ssl_set_hs_psk(ssl, session->resumption_key, @@ -1721,10 +1719,13 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; } - if (handshake->key_exchange_mode == - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL) { - handshake->resume = 0; +#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) + if ((handshake->key_exchange_mode != + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL) && + (psk.type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION)) { + handshake->resume = 1; } +#endif if (handshake->key_exchange_mode != MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) { From 74a1629231362268ec2e3a34391499511ef22172 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 23 Feb 2024 17:07:41 +0100 Subject: [PATCH 112/123] tls13: srv: Move PSK ciphersuite selection up Move PSK ciphersuite selection up to the main ClientHello parsing function. That way the ciphersuite selection only happens in this function. Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 391b8d42c2..ad1be2f229 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -438,8 +438,9 @@ static int ssl_tls13_session_copy_ticket(mbedtls_ssl_session *dst, struct psk_attributes { int type; int key_exchange_mode; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info; }; -#define PSK_ATTRIBUTES_INIT { 0, 0 } +#define PSK_ATTRIBUTES_INIT { 0, 0, 0 } /* Parser for pre_shared_key extension in client hello * struct { @@ -522,7 +523,7 @@ static int ssl_tls13_parse_pre_shared_key_ext( int psk_ciphersuite_id; psa_algorithm_t psk_hash_alg; int allowed_key_exchange_modes; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; + #if defined(MBEDTLS_SSL_SESSION_TICKETS) mbedtls_ssl_session session; mbedtls_ssl_session_init(&session); @@ -595,9 +596,9 @@ static int ssl_tls13_parse_pre_shared_key_ext( ssl_tls13_select_ciphersuite(ssl, ciphersuites, ciphersuites_end, psk_ciphersuite_id, psk_hash_alg, - &ciphersuite_info); + &psk->ciphersuite_info); - if (ciphersuite_info == NULL) { + if (psk->ciphersuite_info == NULL) { #if defined(MBEDTLS_SSL_SESSION_TICKETS) mbedtls_ssl_session_free(&session); #endif @@ -614,7 +615,7 @@ static int ssl_tls13_parse_pre_shared_key_ext( ret = ssl_tls13_offered_psks_check_binder_match( ssl, binder, binder_len, psk->type, - mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac)); + mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) psk->ciphersuite_info->mac)); if (ret != SSL_TLS1_3_BINDER_MATCH) { /* For security reasons, the handshake should be aborted when we * fail to validate a binder value. See RFC 8446 section 4.2.11.2 @@ -633,12 +634,6 @@ static int ssl_tls13_parse_pre_shared_key_ext( matched_identity = identity_id; - /* Update handshake parameters */ - ssl->handshake->ciphersuite_info = ciphersuite_info; - ssl->session_negotiate->ciphersuite = ciphersuite_info->id; - MBEDTLS_SSL_DEBUG_MSG(2, ("overwrite ciphersuite: %04x - %s", - ((unsigned) ciphersuite_info->id), - ciphersuite_info->name)); #if defined(MBEDTLS_SSL_SESSION_TICKETS) if (psk->type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) { ret = ssl_tls13_session_copy_ticket(ssl->session_negotiate, @@ -1720,10 +1715,18 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, } #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) - if ((handshake->key_exchange_mode != - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL) && - (psk.type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION)) { - handshake->resume = 1; + if (handshake->key_exchange_mode & + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL) { + handshake->ciphersuite_info = psk.ciphersuite_info; + ssl->session_negotiate->ciphersuite = psk.ciphersuite_info->id; + + MBEDTLS_SSL_DEBUG_MSG(2, ("Select PSK ciphersuite: %04x - %s", + ((unsigned) psk.ciphersuite_info->id), + psk.ciphersuite_info->name)); + + if (psk.type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) { + handshake->resume = 1; + } } #endif From 3811765c0c919787f85602f37f89e4f1cbf9fc08 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 5 Mar 2024 09:05:46 +0100 Subject: [PATCH 113/123] tls13: srv: Add/Improve comments Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 40 +++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index ad1be2f229..4b6845d6c5 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -50,9 +50,9 @@ static void ssl_tls13_select_ciphersuite( *selected_ciphersuite_info = NULL; /* - * This function assumes that the length of the list of ciphersuites is - * even and it should have been checked it is so in the main ClientHello - * parsing function. Double check here. + * In a compliant ClientHello the byte-length of the list of ciphersuites + * is even and this function relies on this fact. This should have been + * checked in the main ClientHello parsing function. Double check here. */ if ((cipher_suites_end - cipher_suites) & 1) { return; @@ -146,6 +146,27 @@ static int ssl_tls13_parse_key_exchange_modes_ext(mbedtls_ssl_context *ssl, return 0; } +/* + * Non-error return values of + * ssl_tls13_offered_psks_check_identity_match_ticket() and + * ssl_tls13_offered_psks_check_identity_match(). They are positive to + * not collide with error codes that are negative. Zero + * (SSL_TLS1_3_PSK_IDENTITY_MATCH) in case of success as it may be propagated + * up by the callers of this function as a generic success condition. + * + * The return value SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE means + * that the pre-shared-key identity matches that of a ticket or an external + * provisioned pre-shared-key. We have thus been able to retrieve the + * attributes of the pre-shared-key but at least one of them does not meet + * some criteria and the pre-shared-key cannot be used. For example, a ticket + * is expired or its version is not TLS 1.3. Note eventually that the return + * value SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE does not have + * anything to do with binder check. A binder check is done only when a + * suitable pre-shared-key has been selected and only for that selected + * pre-shared-key: if the binder check fails, we fail the handshake and we do + * not try to find another pre-shared-key for which the binder check would + * succeed as recommended by the specification. + */ #define SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH 2 #define SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE 1 #define SSL_TLS1_3_PSK_IDENTITY_MATCH 0 @@ -220,6 +241,10 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket( goto exit; } + /* + * The identity matches that of a ticket. Now check that it has suitable + * attributes and bet it will not be the case. + */ ret = SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE; if (session->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) { @@ -281,6 +306,9 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket( } #endif /* MBEDTLS_HAVE_TIME */ + /* + * All good, we have found a suitable ticket. + */ ret = SSL_TLS1_3_PSK_IDENTITY_MATCH; exit: @@ -360,6 +388,12 @@ static int ssl_tls13_offered_psks_check_identity_match( return SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH; } +/* + * Non-error return values of ssl_tls13_offered_psks_check_binder_match(). + * They are positive to not collide with error codes that are negative. Zero + * (SSL_TLS1_3_BINDER_MATCH) in case of success as it may be propagated up + * by the callers of this function as a generic success condition. + */ #define SSL_TLS1_3_BINDER_DOES_NOT_MATCH 1 #define SSL_TLS1_3_BINDER_MATCH 0 MBEDTLS_CHECK_RETURN_CRITICAL From f602f7ba5092a04edc4febcbbcf2239383f5b21c Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 5 Mar 2024 09:11:55 +0100 Subject: [PATCH 114/123] tls13: srv: Code improvements Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 4b6845d6c5..94ceee622e 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -218,20 +218,24 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket( ret = ssl->conf->f_ticket_parse(ssl->conf->p_ticket, session, ticket_buffer, identity_len); - if (ret == 0) { - ret = SSL_TLS1_3_PSK_IDENTITY_MATCH; - } else { - if (ret == MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) { + switch (ret) { + case 0: + ret = SSL_TLS1_3_PSK_IDENTITY_MATCH; + break; + + case MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED: MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is expired")); ret = SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE; - } else { - if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) { - MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is not authentic")); - } else { - MBEDTLS_SSL_DEBUG_RET(1, "ticket_parse", ret); - } + break; + + case MBEDTLS_ERR_SSL_INVALID_MAC: + MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is not authentic")); + ret = SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH; + break; + + default: + MBEDTLS_SSL_DEBUG_RET(1, "ticket_parse", ret); ret = SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH; - } } /* We delete the temporary buffer */ From 16cc3704239f44e59e8d7017e11676a3eee8c10a Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 7 Mar 2024 15:04:56 +0100 Subject: [PATCH 115/123] tls13: srv: Fix initialization value Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 94ceee622e..f7b3401a87 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -478,7 +478,7 @@ struct psk_attributes { int key_exchange_mode; const mbedtls_ssl_ciphersuite_t *ciphersuite_info; }; -#define PSK_ATTRIBUTES_INIT { 0, 0, 0 } +#define PSK_ATTRIBUTES_INIT { 0, 0, NULL } /* Parser for pre_shared_key extension in client hello * struct { From 7cab4f885b17ed365408a28f9a8c57d1e96d830c Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 7 Mar 2024 15:09:09 +0100 Subject: [PATCH 116/123] tls13: srv: Fix/Improve comments Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index f7b3401a87..9f9347852c 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -74,8 +74,8 @@ static void ssl_tls13_select_ciphersuite( } /* - * If a valid PSK ciphersuite identifier has been passed in, we seek - * for an exact match. + * If a valid PSK ciphersuite identifier has been passed in, we want + * an exact match. */ if (psk_ciphersuite_id != 0) { if (id != psk_ciphersuite_id) { @@ -155,7 +155,7 @@ static int ssl_tls13_parse_key_exchange_modes_ext(mbedtls_ssl_context *ssl, * up by the callers of this function as a generic success condition. * * The return value SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE means - * that the pre-shared-key identity matches that of a ticket or an external + * that the pre-shared-key identity matches that of a ticket or an externally- * provisioned pre-shared-key. We have thus been able to retrieve the * attributes of the pre-shared-key but at least one of them does not meet * some criteria and the pre-shared-key cannot be used. For example, a ticket @@ -1673,7 +1673,7 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, /* Update checksum with either * - The entire content of the CH message, if no PSK extension is present * - The content up to but excluding the PSK extension, if present. - * Always parse the pre-shared key extension when present in the + * Always parse the pre-shared-key extension when present in the * ClientHello even if some pre-requisites for PSK key exchange modes are * not met. That way we always validate the syntax of the extension. */ From 19521ddc36c04bbf963f24c050a8017cbba532dd Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 7 Mar 2024 15:09:41 +0100 Subject: [PATCH 117/123] tls13: srv: Fix/Improve debug logs Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 9f9347852c..7b66820d3a 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -92,7 +92,8 @@ static void ssl_tls13_select_ciphersuite( return; } - MBEDTLS_SSL_DEBUG_MSG(2, ("No matched ciphersuite")); + MBEDTLS_SSL_DEBUG_MSG(2, ("No matched ciphersuite, psk_ciphersuite_id=%x, psk_hash_alg=%x", + (unsigned) psk_ciphersuite_id, psk_hash_alg)); } #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) @@ -210,7 +211,6 @@ static int ssl_tls13_offered_psks_check_identity_match_ticket( */ ticket_buffer = mbedtls_calloc(1, identity_len); if (ticket_buffer == NULL) { - MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small")); return MBEDTLS_ERR_SSL_ALLOC_FAILED; } memcpy(ticket_buffer, identity, identity_len); From e14770fc420fa0744ed30fc45c3408f26959a7f6 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 8 Mar 2024 08:57:36 +0100 Subject: [PATCH 118/123] ssl-opt.sh: Fix early data test option Signed-off-by: Ronald Cron --- tests/opt-testcases/tls13-misc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh index 90c0fb2a37..066fa3fae0 100755 --- a/tests/opt-testcases/tls13-misc.sh +++ b/tests/opt-testcases/tls13-misc.sh @@ -543,7 +543,7 @@ requires_all_configs_enabled MBEDTLS_SSL_EARLY_DATA MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED run_test "TLS 1.3 m->m: Ephemeral over PSK kex with early data enabled" \ "$P_SRV force_version=tls13 debug_level=4 max_early_data_size=1024" \ - "$P_CLI debug_level=4 early_data=$EARLY_DATA_INPUT tls13_kex_modes=psk_or_ephemeral reco_mode=1 reconnect=1" \ + "$P_CLI debug_level=4 early_data=1 tls13_kex_modes=psk_or_ephemeral reco_mode=1 reconnect=1" \ 0 \ -s "key exchange mode: ephemeral" \ -S "key exchange mode: psk" \ From db944a78636de2e18b77a911a20d9ee20f06dee9 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 8 Mar 2024 11:32:53 +0100 Subject: [PATCH 119/123] ssl_msg.c: Fix log position Signed-off-by: Ronald Cron --- library/ssl_msg.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/ssl_msg.c b/library/ssl_msg.c index a8ff1c1a15..0c711571d5 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -4133,14 +4133,15 @@ static int ssl_prepare_record_content(mbedtls_ssl_context *ssl, */ if (ssl->discard_early_data_record == MBEDTLS_SSL_EARLY_DATA_DISCARD) { if (rec->type == MBEDTLS_SSL_MSG_APPLICATION_DATA) { - MBEDTLS_SSL_DEBUG_MSG( - 3, ("EarlyData: Ignore application message before 2nd ClientHello")); ret = mbedtls_ssl_tls13_check_early_data_len(ssl, rec->data_len); if (ret != 0) { return ret; } + MBEDTLS_SSL_DEBUG_MSG( + 3, ("EarlyData: Ignore application message before 2nd ClientHello")); + return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; } else if (rec->type == MBEDTLS_SSL_MSG_HANDSHAKE) { ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD; From 1a13e2f43ee62c626ef794bb9896cc543fc29777 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 8 Mar 2024 14:44:35 +0100 Subject: [PATCH 120/123] tests: ssl: Improve test code for very small max_early_data_size Signed-off-by: Ronald Cron --- tests/suites/test_suite_ssl.function | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index c381860f95..7ba5670a98 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4675,12 +4675,27 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, in case TEST_EARLY_DATA_HRR: ret = mbedtls_ssl_handshake(&(server_ep.ssl)); /* - * Can be the case if max_early_data_size is smaller then the - * smallest inner content or protected record. + * In this write loop we try to always stay below the + * max_early_data_size limit but if max_early_data_size is very + * small we may exceed the max_early_data_size limit on the + * first write. In TEST_EARLY_DATA_SERVER_REJECTS/ + * TEST_EARLY_DATA_HRR scenario, this is for sure the case if + * max_early_data_size is smaller than the smallest possible + * inner content/protected record. Take into account this + * possibility here but only for max_early_data_size values + * that are close to write_size. Below, chosen 1 for one byte + * of inner type and 16 bytes for AEAD expansion (IV, ...). */ if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) { - /* Beyond 64 for max_early_data_size it is suspicious */ - TEST_ASSERT(max_early_data_size < 64); + if (scenario == TEST_EARLY_DATA_SERVER_REJECTS) { + TEST_LE_U(max_early_data_size, + write_size + 1 + + MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY); + } else { + TEST_LE_U(max_early_data_size, + write_size + 1 + 16 + + MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY); + } goto exit; } From 4facb0a9cd27ace3ee681a63bb107d509830bab7 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 8 Mar 2024 11:40:07 +0100 Subject: [PATCH 121/123] tests: ssl: Improve early data test code Signed-off-by: Ronald Cron --- tests/suites/test_suite_ssl.function | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 7ba5670a98..f4288d1830 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -37,7 +37,7 @@ static int write_early_data(mbedtls_ssl_context *ssl, int ret = mbedtls_ssl_get_max_out_record_payload(ssl); TEST_ASSERT(ret > 0); - TEST_ASSERT(len <= (size_t) ret); + TEST_LE_U(len, (size_t) ret); ret = mbedtls_ssl_flush_output(ssl); TEST_EQUAL(ret, 0); @@ -4514,7 +4514,7 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, in uint32_t write_size = (uint32_t) write_size_arg; unsigned char *buf_read = NULL; uint32_t read_size; - uint32_t expended_early_data_len = 0; + uint32_t expanded_early_data_chunk_size = 0; uint32_t written_early_data_size = 0; uint32_t max_early_data_size; @@ -4634,13 +4634,13 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, in /* * If the server rejected early data, base the determination of when - * to stop the loop on the expended size (padding and encryption + * to stop the loop on the expanded size (padding and encryption * expansion) of early data on server side and the number of early data - * received so far by the server (multiple of the expended size). + * received so far by the server (multiple of the expanded size). */ - if ((expended_early_data_len != 0) && + if ((expanded_early_data_chunk_size != 0) && ((server_ep.ssl.total_early_data_size + - expended_early_data_len) > max_early_data_size)) { + expanded_early_data_chunk_size) > max_early_data_size)) { break; } @@ -4703,12 +4703,12 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, in TEST_EQUAL(server_pattern.counter, 1); server_pattern.counter = 0; - if (expended_early_data_len == 0) { - expended_early_data_len = server_ep.ssl.total_early_data_size; + if (expanded_early_data_chunk_size == 0) { + expanded_early_data_chunk_size = server_ep.ssl.total_early_data_size; } break; } - TEST_ASSERT(server_ep.ssl.total_early_data_size <= max_early_data_size); + TEST_LE_U(server_ep.ssl.total_early_data_size, max_early_data_size); } while (1); mbedtls_debug_set_threshold(3); From 52472104a24637e94abe5926abe7682476006913 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 8 Mar 2024 11:29:28 +0100 Subject: [PATCH 122/123] tests: suite: early data: Add comments Signed-off-by: Ronald Cron --- tests/suites/test_suite_ssl.function | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index f4288d1830..64ee0f711c 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4200,6 +4200,10 @@ void tls13_write_early_data(int scenario) break; case TEST_EARLY_DATA_HRR: + /* + * Remove server support for the group negotiated in + * mbedtls_test_get_tls13_ticket() forcing an HelloRetryRequest. + */ server_options.group_list = group_list + 1; break; @@ -4570,6 +4574,10 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, in break; case TEST_EARLY_DATA_HRR: + /* + * Remove server support for the group negotiated in + * mbedtls_test_get_tls13_ticket() forcing an HelloRetryRequest. + */ server_options.group_list = group_list + 1; ret = mbedtls_snprintf( pattern, sizeof(pattern), @@ -4628,6 +4636,11 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, in do { uint32_t read_early_data_size = 0; + /* + * The contents of the early data are not very important, write a + * pattern that varies byte-by-byte and is different for every chunk of + * early data. + */ if ((written_early_data_size + write_size) > max_early_data_size) { break; } From e1295fabaf39abd5cadea749a6c1e07fee2b7de3 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 8 Mar 2024 17:03:16 +0100 Subject: [PATCH 123/123] tests: ssl: early data: Fix comments Signed-off-by: Ronald Cron --- tests/suites/test_suite_ssl.function | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 64ee0f711c..20f80379be 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4202,7 +4202,7 @@ void tls13_write_early_data(int scenario) case TEST_EARLY_DATA_HRR: /* * Remove server support for the group negotiated in - * mbedtls_test_get_tls13_ticket() forcing an HelloRetryRequest. + * mbedtls_test_get_tls13_ticket() forcing a HelloRetryRequest. */ server_options.group_list = group_list + 1; break; @@ -4696,8 +4696,9 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, in * max_early_data_size is smaller than the smallest possible * inner content/protected record. Take into account this * possibility here but only for max_early_data_size values - * that are close to write_size. Below, chosen 1 for one byte - * of inner type and 16 bytes for AEAD expansion (IV, ...). + * that are close to write_size. Below, '1' is for the inner + * type byte and '16' is to take into account some AEAD + * expansion (tag, ...). */ if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) { if (scenario == TEST_EARLY_DATA_SERVER_REJECTS) {