From 3c170d32985e65f51cf86de4b5ae195bc274802e Mon Sep 17 00:00:00 2001 From: Pengyu Lv Date: Wed, 29 Nov 2023 13:53:34 +0800 Subject: [PATCH 001/211] Print suite name when listing test cases When a test script has multiple suites, it is not true to determine the suite name from the file name of the script. We need the script to list the suite name for every test cases. Signed-off-by: Pengyu Lv --- tests/compat.sh | 2 +- tests/ssl-opt.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/compat.sh b/tests/compat.sh index ac29e50c35..a101ffd138 100755 --- a/tests/compat.sh +++ b/tests/compat.sh @@ -125,7 +125,7 @@ print_usage() { print_test_case() { for i in $3; do uniform_title $1 $2 $i - echo $TITLE + echo "compat;$TITLE" done } diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 42f9f5e5a7..43a8863558 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -1620,7 +1620,7 @@ run_test() { fi if [ "$LIST_TESTS" -gt 0 ]; then - printf "%s\n" "$NAME" + printf "%s\n" "${TEST_SUITE_NAME:-ssl-opt};$NAME" return fi From 443c479fafa80489fbd579259c93a60f63dfa745 Mon Sep 17 00:00:00 2001 From: Pengyu Lv Date: Wed, 29 Nov 2023 14:24:52 +0800 Subject: [PATCH 002/211] Use the outputs as keys if the test case is defined in a script Signed-off-by: Pengyu Lv --- tests/scripts/check_test_cases.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/scripts/check_test_cases.py b/tests/scripts/check_test_cases.py index 68e7e690a8..deebbd3882 100755 --- a/tests/scripts/check_test_cases.py +++ b/tests/scripts/check_test_cases.py @@ -137,8 +137,14 @@ class TestDescriptions(TestDescriptionExplorer): def process_test_case(self, _per_file_state, file_name, _line_number, description): """Record an available test case.""" - base_name = re.sub(r'\.[^.]*$', '', re.sub(r'.*/', '', file_name)) - key = ';'.join([base_name, description.decode('utf-8')]) + if file_name.endswith('.data'): + base_name = re.sub(r'\.[^.]*$', '', re.sub(r'.*/', '', file_name)) + key = ';'.join([base_name, description.decode('utf-8')]) + else: + # For test cases defined in scripts (i.e. ssl-op.sh and compat.sh), + # we need the script to list the suite name, and use the outputs + # as keys directly. + key = description.decode('utf-8') self.descriptions.add(key) def collect_available_test_cases(): From 2978c6c24ea1521fdc5b021c3b2fdedbe494f007 Mon Sep 17 00:00:00 2001 From: Pengyu Lv Date: Wed, 29 Nov 2023 17:35:38 +0800 Subject: [PATCH 003/211] Add rules to check script test case listing Signed-off-by: Pengyu Lv --- tests/scripts/check_test_cases.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/scripts/check_test_cases.py b/tests/scripts/check_test_cases.py index deebbd3882..5cac96049e 100755 --- a/tests/scripts/check_test_cases.py +++ b/tests/scripts/check_test_cases.py @@ -172,6 +172,15 @@ class DescriptionChecker(TestDescriptionExplorer): """Check test case descriptions for errors.""" results = self.results seen = per_file_state + if not file_name.endswith('.data'): + script_output = description.split(b';', 1) + if len(script_output) == 2: + description = script_output[1] + else: + results.error(file_name, line_number, + '"{}" should be listed in ' + '";" format', + description.decode('ascii')) if description in seen: results.error(file_name, line_number, 'Duplicate description (also line {})', From ce980e61cc40123a37b2af05f1de5021698f5224 Mon Sep 17 00:00:00 2001 From: Pengyu Lv Date: Thu, 30 Nov 2023 16:53:31 +0800 Subject: [PATCH 004/211] Move script outputs handling to collect_from_script To simplify the logic, `collect_from_script` should take the responsiblity to parse script outputs to suite name and test case description. Also define new Error class ScriptOutputError for error handling. Signed-off-by: Pengyu Lv --- tests/scripts/check_test_cases.py | 59 +++++++++++++++++++------------ 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/tests/scripts/check_test_cases.py b/tests/scripts/check_test_cases.py index 5cac96049e..39bf73c838 100755 --- a/tests/scripts/check_test_cases.py +++ b/tests/scripts/check_test_cases.py @@ -16,6 +16,23 @@ import re import subprocess import sys +class ScriptOutputError(ValueError): + """A kind of ValueError that indicates we found + the script doesn't list test cases in an expected + pattern. + """ + + @property + def script_name(self): + return super().args[0] + + @property + def idx(self): + return super().args[1] + + @property + def line(self): + return super().args[2] class Results: """Store file and line information about errors or warnings in test suites.""" @@ -86,19 +103,27 @@ state may override this method. data_file_name, line_number, line) in_paragraph = True - def collect_from_script(self, file_name): + def collect_from_script(self, script_name): """Collect the test cases in a script by calling its listing test cases option""" descriptions = self.new_per_file_state() # pylint: disable=assignment-from-none - listed = subprocess.check_output(['sh', file_name, '--list-test-cases']) + listed = subprocess.check_output(['sh', script_name, '--list-test-cases']) # Assume test file is responsible for printing identical format of # test case description between --list-test-cases and its OUTCOME.CSV # # idx indicates the number of test case since there is no line number # in the script for each test case. - for idx, description in enumerate(listed.splitlines()): + for idx, line in enumerate(listed.splitlines()): + # We are expecting the script to list the test cases in + # `;` pattern. + script_outputs = line.split(b';', 1) + if len(script_outputs) == 2: + suite_name, description = script_outputs + else: + raise ScriptOutputError(script_name, idx, line.decode("utf-8")) + self.process_test_case(descriptions, - file_name, + suite_name.decode('utf-8'), idx, description.rstrip()) @@ -137,14 +162,8 @@ class TestDescriptions(TestDescriptionExplorer): def process_test_case(self, _per_file_state, file_name, _line_number, description): """Record an available test case.""" - if file_name.endswith('.data'): - base_name = re.sub(r'\.[^.]*$', '', re.sub(r'.*/', '', file_name)) - key = ';'.join([base_name, description.decode('utf-8')]) - else: - # For test cases defined in scripts (i.e. ssl-op.sh and compat.sh), - # we need the script to list the suite name, and use the outputs - # as keys directly. - key = description.decode('utf-8') + base_name = re.sub(r'\.[^.]*$', '', re.sub(r'.*/', '', file_name)) + key = ';'.join([base_name, description.decode('utf-8')]) self.descriptions.add(key) def collect_available_test_cases(): @@ -172,15 +191,6 @@ class DescriptionChecker(TestDescriptionExplorer): """Check test case descriptions for errors.""" results = self.results seen = per_file_state - if not file_name.endswith('.data'): - script_output = description.split(b';', 1) - if len(script_output) == 2: - description = script_output[1] - else: - results.error(file_name, line_number, - '"{}" should be listed in ' - '";" format', - description.decode('ascii')) if description in seen: results.error(file_name, line_number, 'Duplicate description (also line {})', @@ -217,7 +227,12 @@ def main(): return results = Results(options) checker = DescriptionChecker(results) - checker.walk_all() + try: + checker.walk_all() + except ScriptOutputError as e: + results.error(e.script_name, e.idx, + '"{}" should be listed as ";"', + e.line) if (results.warnings or results.errors) and not options.quiet: sys.stderr.write('{}: {} errors, {} warnings\n' .format(sys.argv[0], results.errors, results.warnings)) From c353c5cfd5adecbb8774780bf3202a3a31473470 Mon Sep 17 00:00:00 2001 From: Pengyu Lv Date: Thu, 30 Nov 2023 16:57:08 +0800 Subject: [PATCH 005/211] Catch ScriptOutputError in analyze_outcomes.py Signed-off-by: Pengyu Lv --- tests/scripts/analyze_outcomes.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py index ca349d38e9..ab983ec697 100755 --- a/tests/scripts/analyze_outcomes.py +++ b/tests/scripts/analyze_outcomes.py @@ -85,7 +85,12 @@ def execute_reference_driver_tests(results: Results, ref_component: str, driver_ def analyze_coverage(results: Results, outcomes: Outcomes, allow_list: typing.List[str], full_coverage: bool) -> None: """Check that all available test cases are executed at least once.""" - available = check_test_cases.collect_available_test_cases() + try: + available = check_test_cases.collect_available_test_cases() + except check_test_cases.ScriptOutputError: + results.error("fail to collect available test cases") + return + for suite_case in available: hit = any(suite_case in comp_outcomes.successes or suite_case in comp_outcomes.failures From 5bde6bd8a6da0628233e9169e6ec24a09cde683e Mon Sep 17 00:00:00 2001 From: Pengyu Lv Date: Fri, 8 Dec 2023 12:22:56 +0800 Subject: [PATCH 006/211] Revert "Catch ScriptOutputError in analyze_outcomes.py" Just abort the program if there is exception raised when collecting available test cases, so that we could easily found out what's going wrong. This reverts commit c353c5cfd5adecbb8774780bf3202a3a31473470. Signed-off-by: Pengyu Lv --- tests/scripts/analyze_outcomes.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py index ab983ec697..ca349d38e9 100755 --- a/tests/scripts/analyze_outcomes.py +++ b/tests/scripts/analyze_outcomes.py @@ -85,12 +85,7 @@ def execute_reference_driver_tests(results: Results, ref_component: str, driver_ def analyze_coverage(results: Results, outcomes: Outcomes, allow_list: typing.List[str], full_coverage: bool) -> None: """Check that all available test cases are executed at least once.""" - try: - available = check_test_cases.collect_available_test_cases() - except check_test_cases.ScriptOutputError: - results.error("fail to collect available test cases") - return - + available = check_test_cases.collect_available_test_cases() for suite_case in available: hit = any(suite_case in comp_outcomes.successes or suite_case in comp_outcomes.failures From 7166434ad82a8fe4aa506242d05c541b9a14bb20 Mon Sep 17 00:00:00 2001 From: Pengyu Lv Date: Fri, 8 Dec 2023 13:06:54 +0800 Subject: [PATCH 007/211] Error out if script is missing when collecting test cases Signed-off-by: Pengyu Lv --- tests/scripts/check_test_cases.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/scripts/check_test_cases.py b/tests/scripts/check_test_cases.py index 39bf73c838..d67e6781b4 100755 --- a/tests/scripts/check_test_cases.py +++ b/tests/scripts/check_test_cases.py @@ -149,8 +149,7 @@ option""" for sh_file in ['ssl-opt.sh', 'compat.sh']: sh_file = os.path.join(directory, sh_file) - if os.path.exists(sh_file): - self.collect_from_script(sh_file) + self.collect_from_script(sh_file) class TestDescriptions(TestDescriptionExplorer): """Collect the available test cases.""" From 35178fe7ecd473328248c3f0cc0dc3a0603d2a21 Mon Sep 17 00:00:00 2001 From: BensonLiou Date: Thu, 11 Jan 2024 15:28:17 +0800 Subject: [PATCH 008/211] Do not generate new random number while receiving HRR Signed-off-by: BensonLiou --- library/ssl_client.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/library/ssl_client.c b/library/ssl_client.c index 270db41683..dd10d72fc6 100644 --- a/library/ssl_client.c +++ b/library/ssl_client.c @@ -797,10 +797,15 @@ static int ssl_prepare_client_hello(mbedtls_ssl_context *ssl) (ssl->handshake->cookie == NULL)) #endif { - ret = ssl_generate_random(ssl); - if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "Random bytes generation failed", ret); - return ret; +#if defined(MBEDTLS_SSL_PROTO_TLS1_3) + if (ssl->handshake->hello_retry_request_count == 0) +#endif + { + ret = ssl_generate_random(ssl); + if (ret != 0) { + MBEDTLS_SSL_DEBUG_RET(1, "Random bytes generation failed", ret); + return ret; + } } } From 60bbfe63a1c40021b44150c385194fc885237dca Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Tue, 13 Feb 2024 15:06:10 +0000 Subject: [PATCH 009/211] Add metatests for failing TEST_EQUAL and TEST_LE_* After getting caught with deadlock issues when these tests fail, add a metatest to test them failing. Signed-off-by: Paul Elliott --- programs/test/metatest.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/programs/test/metatest.c b/programs/test/metatest.c index 8e798cd4cd..b68fdf78c5 100644 --- a/programs/test/metatest.c +++ b/programs/test/metatest.c @@ -71,6 +71,41 @@ void meta_test_fail(const char *name) mbedtls_test_fail("Forced test failure", __LINE__, __FILE__); } +void meta_test_not_equal(const char *name) +{ + int left = 20; + int right = 10; + + (void) name; + + TEST_EQUAL(left, right); +exit: + ; +} + +void meta_test_not_le_s(const char *name) +{ + int left = 20; + int right = 10; + + (void) name; + + TEST_LE_S(left, right); +exit: + ; +} + +void meta_test_not_le_u(const char *name) +{ + size_t left = 20; + size_t right = 10; + + (void) name; + + TEST_LE_U(left, right); +exit: + ; +} /****************************************************************/ /* Platform features */ @@ -286,6 +321,9 @@ typedef struct { */ metatest_t metatests[] = { { "test_fail", "any", meta_test_fail }, + { "test_not_equal", "any", meta_test_not_equal }, + { "test_not_le_s", "any", meta_test_not_le_s }, + { "test_not_le_u", "any", meta_test_not_le_u }, { "null_dereference", "any", null_pointer_dereference }, { "null_call", "any", null_pointer_call }, { "read_after_free", "asan", read_after_free }, From 41bed383ec9454d882b2a820b95aadb41a38a1f4 Mon Sep 17 00:00:00 2001 From: BensonLiou Date: Fri, 16 Feb 2024 16:07:53 +0800 Subject: [PATCH 010/211] To check if client random number is unchanged while receiving HRR Signed-off-by: BensonLiou --- tests/suites/test_suite_ssl.function | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 2751e58c16..41f8bb7669 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -3802,6 +3802,7 @@ void tls13_cli_early_data_status(int scenario) MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1, MBEDTLS_SSL_IANA_TLS_GROUP_NONE }; + uint8_t client_random[MBEDTLS_CLIENT_HELLO_RANDOM_LEN]; mbedtls_platform_zeroize(&client_ep, sizeof(client_ep)); mbedtls_platform_zeroize(&server_ep, sizeof(server_ep)); @@ -3931,9 +3932,11 @@ void tls13_cli_early_data_status(int scenario) if (client_ep.ssl.handshake->hello_retry_request_count == 0) { TEST_EQUAL(client_ep.ssl.early_data_status, MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE); + memcpy(client_random, client_ep.ssl.handshake->randbytes, MBEDTLS_CLIENT_HELLO_RANDOM_LEN); } else { TEST_EQUAL(client_ep.ssl.early_data_status, MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED); + TEST_MEMORY_COMPARE(client_random, MBEDTLS_CLIENT_HELLO_RANDOM_LEN, client_ep.ssl.handshake->randbytes, MBEDTLS_CLIENT_HELLO_RANDOM_LEN); } break; } From 469f7811fac98617e544aac2b1b2db56040c95db Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 29 Feb 2024 18:19:56 +0100 Subject: [PATCH 011/211] Require framework directory to exist when building The framework directory will be provided by a submodule. Signed-off-by: Gilles Peskine --- CMakeLists.txt | 2 ++ Makefile | 2 ++ library/Makefile | 1 + scripts/common.make | 2 ++ 4 files changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5585c78fa7..154c84af64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -277,6 +277,8 @@ if(LIB_INSTALL_DIR) set(CMAKE_INSTALL_LIBDIR "${LIB_INSTALL_DIR}") endif() +add_subdirectory(framework) + add_subdirectory(include) add_subdirectory(3rdparty) diff --git a/Makefile b/Makefile index 885948c112..2e41abaec4 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,8 @@ DESTDIR=/usr/local PREFIX=mbedtls_ PERL ?= perl +include framework/exported.make + .SILENT: .PHONY: all no_test programs lib tests install uninstall clean test check lcov apidoc apidoc_clean diff --git a/library/Makefile b/library/Makefile index d11a98df01..d5e4f64cea 100644 --- a/library/Makefile +++ b/library/Makefile @@ -1,3 +1,4 @@ +include ../framework/exported.make # Also see "include/mbedtls/mbedtls_config.h" diff --git a/scripts/common.make b/scripts/common.make index 2714bcd327..2da58d00e3 100644 --- a/scripts/common.make +++ b/scripts/common.make @@ -4,6 +4,8 @@ ifndef MBEDTLS_PATH MBEDTLS_PATH := .. endif +include $(MBEDTLS_PATH)/framework/exported.make + CFLAGS ?= -O2 WARNING_CFLAGS ?= -Wall -Wextra -Wformat=2 -Wno-format-nonliteral WARNING_CXXFLAGS ?= -Wall -Wextra -Wformat=2 -Wno-format-nonliteral From 5c4fc9156bedc69d053e21e2da23c4d386cf0a39 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 23 Feb 2024 07:43:45 +0100 Subject: [PATCH 012/211] 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 a4f0a71a012122c3b9e3bf61cdaf1186bb478c89 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 23 Feb 2024 08:23:40 +0100 Subject: [PATCH 013/211] 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 62f971aa60af9c1d845eff90498388f248c48958 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 23 Feb 2024 08:24:12 +0100 Subject: [PATCH 014/211] tls13: cli: Enforce maximum size of early data Signed-off-by: Ronald Cron --- library/ssl_msg.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 2a6d4341be..c61a7bf44d 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -6065,6 +6065,7 @@ int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl, int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; const struct mbedtls_ssl_config *conf; int written_data_len = 0; + uint32_t remaining; MBEDTLS_SSL_DEBUG_MSG(2, ("=> write early_data")); @@ -6114,18 +6115,27 @@ int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl, return ret; } } + remaining = ssl->session_negotiate->max_early_data_size; } else { /* - * If we are past the point where we can send early data, return - * immediatly. Otherwise, progress the handshake as much as possible to - * not delay it too much. If we reach a point where we can still send - * early data, then we will send some. + * If we are past the point where we can send early data or we have + * already reached the maximum early data size, return immediatly. + * Otherwise, progress the handshake as much as possible to not delay + * it too much. If we reach a point where we can still send early data, + * then we will send some. */ if ((ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE) && (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED)) { return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA; } + remaining = ssl->session_negotiate->max_early_data_size - + ssl->early_data_count; + + if (remaining == 0) { + return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA; + } + ret = mbedtls_ssl_handshake(ssl); if ((ret != 0) && (ret != MBEDTLS_ERR_SSL_WANT_READ)) { MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret); @@ -6133,12 +6143,18 @@ int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl, } } - if ((ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE) && - (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED)) { + if (((ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE) && + (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED)) + || (remaining == 0)) { return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA; } + if (len > remaining) { + len = remaining; + } + written_data_len = ssl_write_real(ssl, buf, len); + ssl->early_data_count += written_data_len; MBEDTLS_SSL_DEBUG_MSG(2, ("<= write early_data, len=%d", written_data_len)); From aad8523764e2d48a2e7f814f98caa4ba45413015 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 7 Feb 2024 08:04:07 +0100 Subject: [PATCH 015/211] tests: ssl: Test enforcement of maximum early data size Signed-off-by: Ronald Cron --- tests/suites/test_suite_ssl.data | 12 +++ tests/suites/test_suite_ssl.function | 150 +++++++++++++++++++++++++++ 2 files changed, 162 insertions(+) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 385682ae12..03ba09b737 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3309,3 +3309,15 @@ 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 cli, maximum early data size, default size +tls13_cli_max_early_data_size:-1 + +TLS 1.3 cli, maximum early data size, zero +tls13_cli_max_early_data_size:0 + +TLS 1.3 cli, maximum early data size, very small but not 0 +tls13_cli_max_early_data_size:3 + +TLS 1.3 cli, maximum early data size, 93 +tls13_cli_max_early_data_size:93 diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index d327828bcd..682de08de1 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4448,3 +4448,153 @@ exit: PSA_DONE(); } /* END_CASE */ + +/* BEGIN_CASE depends_on: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_cli_max_early_data_size(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; + unsigned char buf[64]; + uint32_t max_early_data_size; + uint32_t written_early_data_size = 0; + uint32_t read_early_data_size = 0; + + 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. + */ + 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); + + max_early_data_size = saved_session.max_early_data_size; + /* + * (max_early_data_size + 1024) for the size of the socket buffers for the + * server one to be able to contain the maximum number of early data bytes + * plus the first flight client messages. Needed because we cannot initiate + * the handshake on server side before doing all the calls to + * mbedtls_ssl_write_early_data() we want to test. See below for more + * information. + */ + ret = mbedtls_test_mock_socket_connect(&(client_ep.socket), + &(server_ep.socket), + max_early_data_size + 1024); + TEST_EQUAL(ret, 0); + + /* If our server is configured with max_early_data_size equal to zero, it + * does not set the MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA flag for + * the tickets it creates. To be able to test early data with a ticket + * allowing early data in its flags but with max_early_data_size equal to + * zero (case supported by our client) tweak the ticket flags here. + */ + if (max_early_data_size == 0) { + saved_session.ticket_flags |= MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA; + } + + ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session); + TEST_EQUAL(ret, 0); + + while (written_early_data_size < max_early_data_size) { + size_t early_data_len = sizeof(buf); + uint32_t remaining = max_early_data_size - written_early_data_size; + + for (size_t i = 0; i < early_data_len; i++) { + buf[i] = (unsigned char) (written_early_data_size + i); + } + + ret = mbedtls_ssl_write_early_data(&(client_ep.ssl), + buf, + early_data_len); + + if (early_data_len <= remaining) { + TEST_EQUAL(ret, early_data_len); + } else { + TEST_EQUAL(ret, remaining); + } + written_early_data_size += early_data_len; + } + + /* In case we reached exactly the limit in the loop above, do another one + * byte early data write. + */ + ret = mbedtls_ssl_write_early_data(&(client_ep.ssl), buf, 1); + TEST_EQUAL(ret, MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA); + TEST_EQUAL(client_ep.ssl.early_data_count, max_early_data_size); + TEST_EQUAL(client_ep.ssl.early_data_status, + MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE); + + /* + * Now, check data on server side. It is not done in the previous loop as + * in the first call to mbedtls_ssl_handshake(), the server ends up sending + * its Finished message and then in the following call to + * mbedtls_ssl_write_early_data() we go past the early data writing window + * and we cannot test multiple calls to the API is this writing window. + */ + while (read_early_data_size < max_early_data_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, + sizeof(buf)); + TEST_ASSERT(ret > 0); + + for (size_t i = 0; i < (size_t) ret; i++) { + TEST_EQUAL(buf[i], (unsigned char) (read_early_data_size + i)); + } + + read_early_data_size += ret; + } + TEST_EQUAL(read_early_data_size, max_early_data_size); + + ret = mbedtls_ssl_handshake(&(server_ep.ssl)); + TEST_EQUAL(ret, MBEDTLS_ERR_SSL_WANT_READ); + + ret = mbedtls_ssl_write_early_data(&(client_ep.ssl), buf, 1); + TEST_EQUAL(ret, MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA); + TEST_EQUAL(client_ep.ssl.early_data_count, max_early_data_size); + TEST_EQUAL(client_ep.ssl.early_data_status, + MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE); + +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); + PSA_DONE(); +} +/* END_CASE */ From de9b03dcbaf998b58fd4aa28743b8a2883695dec Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 1 Mar 2024 15:14:17 +0100 Subject: [PATCH 016/211] tls13: Rename early_data_count to total_early_data_size Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 2 +- library/ssl_msg.c | 4 ++-- library/ssl_tls.c | 2 +- tests/suites/test_suite_ssl.function | 4 ++-- 4 files changed, 6 insertions(+), 6 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_msg.c b/library/ssl_msg.c index c61a7bf44d..52bd826b91 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -6130,7 +6130,7 @@ int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl, } remaining = ssl->session_negotiate->max_early_data_size - - ssl->early_data_count; + ssl->total_early_data_size; if (remaining == 0) { return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA; @@ -6154,7 +6154,7 @@ int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl, } written_data_len = ssl_write_real(ssl, buf, len); - ssl->early_data_count += written_data_len; + ssl->total_early_data_size += written_data_len; MBEDTLS_SSL_DEBUG_MSG(2, ("<= write early_data, len=%d", written_data_len)); 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/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 682de08de1..6895efa5e5 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4552,7 +4552,7 @@ void tls13_cli_max_early_data_size(int max_early_data_size_arg) */ ret = mbedtls_ssl_write_early_data(&(client_ep.ssl), buf, 1); TEST_EQUAL(ret, MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA); - TEST_EQUAL(client_ep.ssl.early_data_count, max_early_data_size); + TEST_EQUAL(client_ep.ssl.total_early_data_size, max_early_data_size); TEST_EQUAL(client_ep.ssl.early_data_status, MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE); @@ -4585,7 +4585,7 @@ void tls13_cli_max_early_data_size(int max_early_data_size_arg) ret = mbedtls_ssl_write_early_data(&(client_ep.ssl), buf, 1); TEST_EQUAL(ret, MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA); - TEST_EQUAL(client_ep.ssl.early_data_count, max_early_data_size); + TEST_EQUAL(client_ep.ssl.total_early_data_size, max_early_data_size); TEST_EQUAL(client_ep.ssl.early_data_status, MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE); From 5dbfcceb8197d53f5a8c1df83db13d75e33133cd Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 26 Feb 2024 17:50:38 +0100 Subject: [PATCH 017/211] tls13: cli: Fix error code not checked Signed-off-by: Ronald Cron --- library/ssl_msg.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 52bd826b91..ef8ba1a467 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -6064,7 +6064,6 @@ int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl, { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; const struct mbedtls_ssl_config *conf; - int written_data_len = 0; uint32_t remaining; MBEDTLS_SSL_DEBUG_MSG(2, ("=> write early_data")); @@ -6153,12 +6152,14 @@ int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl, len = remaining; } - written_data_len = ssl_write_real(ssl, buf, len); - ssl->total_early_data_size += written_data_len; + ret = ssl_write_real(ssl, buf, len); + if (ret >= 0) { + ssl->total_early_data_size += ret; + } - MBEDTLS_SSL_DEBUG_MSG(2, ("<= write early_data, len=%d", written_data_len)); + MBEDTLS_SSL_DEBUG_MSG(2, ("<= write early_data, ret=%d", ret)); - return written_data_len; + return ret; } #endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */ From ae6f9a58a94301d67927015cc5292e28f6956370 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 1 Mar 2024 16:05:59 +0100 Subject: [PATCH 018/211] tests: write early data: Allocate buffer to write/read Allocate the buffer to write/read early data. That way in ASan builds. buffer overwrite/overread can be detected. Signed-off-by: Ronald Cron --- tests/suites/test_suite_ssl.function | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 6895efa5e5..d1b694f81e 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4457,7 +4457,8 @@ void tls13_cli_max_early_data_size(int max_early_data_size_arg) mbedtls_test_handshake_test_options client_options; mbedtls_test_handshake_test_options server_options; mbedtls_ssl_session saved_session; - unsigned char buf[64]; + unsigned char *buf = NULL; + uint32_t buf_size = 64; uint32_t max_early_data_size; uint32_t written_early_data_size = 0; uint32_t read_early_data_size = 0; @@ -4469,6 +4470,7 @@ void tls13_cli_max_early_data_size(int max_early_data_size_arg) mbedtls_ssl_session_init(&saved_session); PSA_INIT(); + TEST_CALLOC(buf, buf_size); /* * Run first handshake to get a ticket from the server. @@ -4528,23 +4530,22 @@ void tls13_cli_max_early_data_size(int max_early_data_size_arg) TEST_EQUAL(ret, 0); while (written_early_data_size < max_early_data_size) { - size_t early_data_len = sizeof(buf); uint32_t remaining = max_early_data_size - written_early_data_size; - for (size_t i = 0; i < early_data_len; i++) { + for (size_t i = 0; i < buf_size; i++) { buf[i] = (unsigned char) (written_early_data_size + i); } ret = mbedtls_ssl_write_early_data(&(client_ep.ssl), buf, - early_data_len); + buf_size); - if (early_data_len <= remaining) { - TEST_EQUAL(ret, early_data_len); + if (buf_size <= remaining) { + TEST_EQUAL(ret, buf_size); } else { TEST_EQUAL(ret, remaining); } - written_early_data_size += early_data_len; + written_early_data_size += buf_size; } /* In case we reached exactly the limit in the loop above, do another one @@ -4569,7 +4570,7 @@ void tls13_cli_max_early_data_size(int max_early_data_size_arg) ret = mbedtls_ssl_read_early_data(&(server_ep.ssl), buf, - sizeof(buf)); + buf_size); TEST_ASSERT(ret > 0); for (size_t i = 0; i < (size_t) ret; i++) { @@ -4595,6 +4596,7 @@ exit: mbedtls_test_free_handshake_options(&client_options); mbedtls_test_free_handshake_options(&server_options); mbedtls_ssl_session_free(&saved_session); + mbedtls_free(buf); PSA_DONE(); } /* END_CASE */ From 7c07aab72e1fbeac5b897da6145145f4fefe6119 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 1 Mar 2024 16:01:27 +0100 Subject: [PATCH 019/211] tests: write early data: Improve tls13_cli_max_early_data_size Signed-off-by: Ronald Cron --- tests/suites/test_suite_ssl.function | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index d1b694f81e..8a626219ea 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4506,8 +4506,8 @@ void tls13_cli_max_early_data_size(int max_early_data_size_arg) /* * (max_early_data_size + 1024) for the size of the socket buffers for the * server one to be able to contain the maximum number of early data bytes - * plus the first flight client messages. Needed because we cannot initiate - * the handshake on server side before doing all the calls to + * plus the first flight of client messages. Needed because we cannot + * initiate the handshake on server side before doing all the calls to * mbedtls_ssl_write_early_data() we want to test. See below for more * information. */ @@ -4547,10 +4547,8 @@ void tls13_cli_max_early_data_size(int max_early_data_size_arg) } written_early_data_size += buf_size; } + TEST_EQUAL(client_ep.ssl.total_early_data_size, max_early_data_size); - /* In case we reached exactly the limit in the loop above, do another one - * byte early data write. - */ ret = mbedtls_ssl_write_early_data(&(client_ep.ssl), buf, 1); TEST_EQUAL(ret, MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA); TEST_EQUAL(client_ep.ssl.total_early_data_size, max_early_data_size); @@ -4584,11 +4582,9 @@ void tls13_cli_max_early_data_size(int max_early_data_size_arg) ret = mbedtls_ssl_handshake(&(server_ep.ssl)); TEST_EQUAL(ret, MBEDTLS_ERR_SSL_WANT_READ); - ret = mbedtls_ssl_write_early_data(&(client_ep.ssl), buf, 1); - TEST_EQUAL(ret, MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA); - TEST_EQUAL(client_ep.ssl.total_early_data_size, max_early_data_size); - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE); + TEST_ASSERT(mbedtls_test_move_handshake_to_state( + &(client_ep.ssl), &(server_ep.ssl), MBEDTLS_SSL_HANDSHAKE_OVER) + == 0); exit: mbedtls_test_ssl_endpoint_free(&client_ep, NULL); From 2c8c364ac20657d8df7162f025f3549be11b3aaa Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Mon, 4 Mar 2024 15:15:06 +0000 Subject: [PATCH 020/211] ssl: Added getter methods for session id and len. Signed-off-by: Minos Galanakis --- include/mbedtls/ssl.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 78395d2a67..78ea4da8b8 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -2717,6 +2717,30 @@ static inline int mbedtls_ssl_session_get_ticket_creation_time( #endif /* MBEDTLS_HAVE_TIME */ #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ +/** + * \brief Get the session-id buffer. + * + * \param session SSL session. + * + * \return The address of the session-id buffer. + */ +static inline const unsigned char[32]* mbedtls_ssl_session_get_id(const mbedtls_ssl_session *session) +{ + return &session->MBEDTLS_PRIVATE(id); +} + +/** + * \brief Get the size of the session-id. + * + * \param session SSL session. + * + * \return size_t size of session-id buffer. + */ +static inline const size_t mbedtls_ssl_session_get_id_len(const mbedtls_ssl_session *session) +{ + return session->MBEDTLS_PRIVATE(id_len); +} + /** * \brief Configure a key export callback. * (Default: none.) From 358b448d7255fa7d2f5708a26f330276cc0c2d8b Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Mon, 4 Mar 2024 02:19:31 +0000 Subject: [PATCH 021/211] ssl_ciphersuite: Added getter methods for ciphersuite id. Signed-off-by: Minos Galanakis --- include/mbedtls/ssl.h | 5 +++-- include/mbedtls/ssl_ciphersuites.h | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 78ea4da8b8..4c085b0c76 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -2724,7 +2724,8 @@ static inline int mbedtls_ssl_session_get_ticket_creation_time( * * \return The address of the session-id buffer. */ -static inline const unsigned char[32]* mbedtls_ssl_session_get_id(const mbedtls_ssl_session *session) +static inline unsigned const char (*mbedtls_ssl_session_get_id(const mbedtls_ssl_session * + session))[32] { return &session->MBEDTLS_PRIVATE(id); } @@ -2736,7 +2737,7 @@ static inline const unsigned char[32]* mbedtls_ssl_session_get_id(const mbedtls_ * * \return size_t size of session-id buffer. */ -static inline const size_t mbedtls_ssl_session_get_id_len(const mbedtls_ssl_session *session) +static inline size_t mbedtls_ssl_session_get_id_len(const mbedtls_ssl_session *session) { return session->MBEDTLS_PRIVATE(id_len); } diff --git a/include/mbedtls/ssl_ciphersuites.h b/include/mbedtls/ssl_ciphersuites.h index f755ef3042..01865b6c4e 100644 --- a/include/mbedtls/ssl_ciphersuites.h +++ b/include/mbedtls/ssl_ciphersuites.h @@ -468,6 +468,11 @@ static inline const char *mbedtls_ssl_ciphersuite_get_name(const mbedtls_ssl_cip return info->MBEDTLS_PRIVATE(name); } +static inline const int mbedtls_ssl_ciphersuite_get_id(const mbedtls_ssl_ciphersuite_t *info) +{ + return info->MBEDTLS_PRIVATE(id); +} + size_t mbedtls_ssl_ciphersuite_get_cipher_key_bitlen(const mbedtls_ssl_ciphersuite_t *info); #ifdef __cplusplus From 40d4708f17d8d9a9f8dc580969160d94107894df Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Mon, 4 Mar 2024 15:24:51 +0000 Subject: [PATCH 022/211] ssl: Added session getter for ciphersuite_id. Signed-off-by: Minos Galanakis --- include/mbedtls/ssl.h | 12 ++++++++++++ include/mbedtls/ssl_ciphersuites.h | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 4c085b0c76..cdc0996db9 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -2742,6 +2742,18 @@ static inline size_t mbedtls_ssl_session_get_id_len(const mbedtls_ssl_session *s return session->MBEDTLS_PRIVATE(id_len); } +/** + * \brief Get the ciphersuite-id. + * + * \param session SSL session. + * + * \return int represetation for ciphersuite. + */ +static inline int mbedtls_ssl_session_get_ciphersuite_id(const mbedtls_ssl_session *session) +{ + return session->MBEDTLS_PRIVATE(ciphersuite); +} + /** * \brief Configure a key export callback. * (Default: none.) diff --git a/include/mbedtls/ssl_ciphersuites.h b/include/mbedtls/ssl_ciphersuites.h index 01865b6c4e..12d446200f 100644 --- a/include/mbedtls/ssl_ciphersuites.h +++ b/include/mbedtls/ssl_ciphersuites.h @@ -468,7 +468,7 @@ static inline const char *mbedtls_ssl_ciphersuite_get_name(const mbedtls_ssl_cip return info->MBEDTLS_PRIVATE(name); } -static inline const int mbedtls_ssl_ciphersuite_get_id(const mbedtls_ssl_ciphersuite_t *info) +static inline int mbedtls_ssl_ciphersuite_get_id(const mbedtls_ssl_ciphersuite_t *info) { return info->MBEDTLS_PRIVATE(id); } From 456a54da8ef44c8b725b524567c08cffec6a7214 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 29 Feb 2024 18:38:12 +0100 Subject: [PATCH 023/211] Add framework submodule with makefiles Signed-off-by: Gilles Peskine --- .gitmodules | 3 +++ framework | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 framework diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..4fb26b555e --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "framework"] + path = framework + url = https://github.com/Mbed-TLS/mbedtls-framework diff --git a/framework b/framework new file mode 160000 index 0000000000..2c29c56c10 --- /dev/null +++ b/framework @@ -0,0 +1 @@ +Subproject commit 2c29c56c1095044dd78d6ea5d804fe1f61f946bf From 1c13aa78c2938bebe3c8a7a7f2b0ca945ddbaebe Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 4 Mar 2024 11:06:56 +0100 Subject: [PATCH 024/211] Framework submodule: fix the libtestdriver1 build `make -C tests libtestdriver1` copies `library/Makefile` to `tests/libtestdriver1/library/Makefile`, where `../framework` does not point to the framework submodule. Signed-off-by: Gilles Peskine --- library/Makefile | 6 +++++- tests/Makefile | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/library/Makefile b/library/Makefile index d5e4f64cea..67f91f6b42 100644 --- a/library/Makefile +++ b/library/Makefile @@ -1,4 +1,8 @@ -include ../framework/exported.make +ifndef MBEDTLS_PATH +MBEDTLS_PATH := .. +endif + +include $(MBEDTLS_PATH)/framework/exported.make # Also see "include/mbedtls/mbedtls_config.h" diff --git a/tests/Makefile b/tests/Makefile index f82c267ac5..c2a0b84f07 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -208,6 +208,7 @@ define libtestdriver1_rewrite := s/\b(?=mbedtls_|psa_)/libtestdriver1_/g; endef +libtestdriver1.a: export MBEDTLS_PATH := $(patsubst ../..//%,/%,../../$(MBEDTLS_PATH)) libtestdriver1.a: # Copy the library and fake a 3rdparty Makefile include. rm -Rf ./libtestdriver1 From 2aa63ea48c1acb8b811aac167aa54d60941ee15a Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 4 Mar 2024 11:08:19 +0100 Subject: [PATCH 025/211] Support Git submodules Signed-off-by: Gilles Peskine --- tests/scripts/check_files.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/scripts/check_files.py b/tests/scripts/check_files.py index 65fbc9f070..5e4a7247ec 100755 --- a/tests/scripts/check_files.py +++ b/tests/scripts/check_files.py @@ -321,6 +321,7 @@ class TabIssueTracker(LineIssueTracker): ".make", ".pem", # some openssl dumps have tabs ".sln", + "/.gitmodules", "/Makefile", "/Makefile.inc", "/generate_visualc_files.pl", @@ -481,6 +482,12 @@ class IntegrityChecker: bytes_output = subprocess.check_output(['git', 'ls-files', '-z']) bytes_filepaths = bytes_output.split(b'\0')[:-1] ascii_filepaths = map(lambda fp: fp.decode('ascii'), bytes_filepaths) + # Filter out directories. Normally Git doesn't list directories + # (it only knows about the files inside them), but there is + # at least one case where 'git ls-files' includes a directory: + # submodules. Just skip submodules (and any other directories). + ascii_filepaths = [fp for fp in ascii_filepaths + if os.path.isfile(fp)] # Prepend './' to files in the top-level directory so that # something like `'/Makefile' in fp` matches in the top-level # directory as well as in subdirectories. From 8cbbc5f4e6cf3578c082fecfbdd68429f0689ffa Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 4 Mar 2024 14:52:06 +0000 Subject: [PATCH 026/211] Tell ReadTheDocs to include framework submodule Signed-off-by: David Horstmann --- .readthedocs.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 72f126fa20..2b10f863f2 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -5,6 +5,11 @@ # Required version: 2 +# Include the framework submodule in the build +submodules: + include: + - framework + # Set the version of Python and other tools you might need build: os: ubuntu-20.04 From de047b09fe1f7c2ee878a0cc7b6f75f4cf429649 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 4 Mar 2024 11:51:31 +0100 Subject: [PATCH 027/211] Add docstrings to pacify pylint Signed-off-by: Gilles Peskine --- tests/scripts/check_files.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/scripts/check_files.py b/tests/scripts/check_files.py index 5e4a7247ec..a15a058f0e 100755 --- a/tests/scripts/check_files.py +++ b/tests/scripts/check_files.py @@ -468,6 +468,7 @@ class IntegrityChecker: ] def setup_logger(self, log_file, level=logging.INFO): + """Log to log_file if provided, or to stderr if None.""" self.logger = logging.getLogger() self.logger.setLevel(level) if log_file: @@ -479,6 +480,10 @@ class IntegrityChecker: @staticmethod def collect_files(): + """Return the list of files to check. + + These are the regular files commited into Git. + """ bytes_output = subprocess.check_output(['git', 'ls-files', '-z']) bytes_filepaths = bytes_output.split(b'\0')[:-1] ascii_filepaths = map(lambda fp: fp.decode('ascii'), bytes_filepaths) @@ -495,12 +500,17 @@ class IntegrityChecker: for fp in ascii_filepaths] def check_files(self): + """Check all files for all issues.""" for issue_to_check in self.issues_to_check: for filepath in self.collect_files(): if issue_to_check.should_check_file(filepath): issue_to_check.check_file_for_issue(filepath) def output_issues(self): + """Log the issues found and their locations. + + Return 1 if there were issues, 0 otherwise. + """ integrity_return_code = 0 for issue_to_check in self.issues_to_check: if issue_to_check.files_with_issues: From 0c3f0e998d584ac4ca01caa398bcf777ee802f5e Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 4 Mar 2024 15:54:54 +0100 Subject: [PATCH 028/211] Note the need to tell git to set up the submodule Signed-off-by: Gilles Peskine --- README.md | 4 ++++ framework | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2505d8fd9c..7d3894e8b2 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,10 @@ You need the following tools to build the library with the provided makefiles: * Microsoft Visual Studio 2013 or later (if using Visual Studio). * Doxygen 1.8.11 or later (if building the documentation; slightly older versions should work). +### Git usage + +The `development` branch and the `mbedtls-3.6` long-term support of Mbed TLS use a [Git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules#_cloning_submodules) ([framework](https://github.com/Mbed-TLS/mbedtls-framework)). This is not needed to merely compile the library at a release tag. This is not needed to consume a release archive (zip or tar). + ### Generated source files in the development branch The source code of Mbed TLS includes some files that are automatically generated by scripts and whose content depends only on the Mbed TLS source, not on the platform or on the library configuration. These files are not included in the development branch of Mbed TLS, but the generated files are included in official releases. This section explains how to generate the missing files in the development branch. diff --git a/framework b/framework index 2c29c56c10..26ab40de58 160000 --- a/framework +++ b/framework @@ -1 +1 @@ -Subproject commit 2c29c56c1095044dd78d6ea5d804fe1f61f946bf +Subproject commit 26ab40de5887c872b5108981fece907104e8409c From f9bbe0de4c97ca532d052106bb471756e55742ae Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 4 Mar 2024 16:25:14 +0100 Subject: [PATCH 029/211] Show guidance if the framework is not found Signed-off-by: Gilles Peskine --- CMakeLists.txt | 3 +++ library/Makefile | 8 ++++++++ scripts/common.make | 10 ++++++++++ 3 files changed, 21 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 154c84af64..174a99f6a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -277,6 +277,9 @@ if(LIB_INSTALL_DIR) set(CMAKE_INSTALL_LIBDIR "${LIB_INSTALL_DIR}") endif() +if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/framework/CMakeLists.txt") + message(FATAL_ERROR "${CMAKE_CURRENT_SOURCE_DIR}/framework/CMakeLists.txt not found. Run `git submodule update --init` from the source tree to fetch the submodule contents.") +endif() add_subdirectory(framework) add_subdirectory(include) diff --git a/library/Makefile b/library/Makefile index 67f91f6b42..2f42124742 100644 --- a/library/Makefile +++ b/library/Makefile @@ -2,6 +2,14 @@ ifndef MBEDTLS_PATH MBEDTLS_PATH := .. endif +ifeq (,$(wildcard $(MBEDTLS_PATH)/framework/exported.make)) +define error_message +$(MBEDTLS_PATH)/framework/exported.make not found. +Run `git submodule update --init` to fetch the submodule contents. +This is a fatal error +endef +$(error $(error_message)) +endif include $(MBEDTLS_PATH)/framework/exported.make # Also see "include/mbedtls/mbedtls_config.h" diff --git a/scripts/common.make b/scripts/common.make index 2da58d00e3..9908a3c265 100644 --- a/scripts/common.make +++ b/scripts/common.make @@ -4,6 +4,16 @@ ifndef MBEDTLS_PATH MBEDTLS_PATH := .. endif +ifeq (,$(wildcard $(MBEDTLS_PATH)/framework/exported.make)) + # Use the define keyword to get a multi-line message. + # GNU make appends ". Stop.", so tweak the ending of our message accordingly. + define error_message +$(MBEDTLS_PATH)/framework/exported.make not found. +Run `git submodule update --init` to fetch the submodule contents. +This is a fatal error + endef + $(error $(error_message)) +endif include $(MBEDTLS_PATH)/framework/exported.make CFLAGS ?= -O2 From 48230e84cb36b0d413f28122b153094f0f04574e Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 4 Mar 2024 16:42:54 +0100 Subject: [PATCH 030/211] In library, with make, only require the framework for generated files This way, `make lib` will work in the absence of the framework, as long as generated files are present. Signed-off-by: Gilles Peskine --- Makefile | 14 +++++++++++++- library/Makefile | 25 +++++++++++++++---------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 2e41abaec4..47a3895b8a 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,19 @@ DESTDIR=/usr/local PREFIX=mbedtls_ PERL ?= perl -include framework/exported.make +ifneq (,$(filter-out lib library/%,$(or $(MAKECMDGOALS),all))) + ifeq (,$(wildcard framework/exported.make)) + # Use the define keyword to get a multi-line message. + # GNU make appends ". Stop.", so tweak the ending of our message accordingly. + define error_message +$(MBEDTLS_PATH)/framework/exported.make not found. +Run `git submodule update --init` to fetch the submodule contents. +This is a fatal error + endef + $(error $(error_message)) + endif + include framework/exported.make +endif .SILENT: diff --git a/library/Makefile b/library/Makefile index 2f42124742..77cfe077ac 100644 --- a/library/Makefile +++ b/library/Makefile @@ -2,15 +2,25 @@ ifndef MBEDTLS_PATH MBEDTLS_PATH := .. endif -ifeq (,$(wildcard $(MBEDTLS_PATH)/framework/exported.make)) -define error_message +GENERATED_FILES := \ + error.c version_features.c \ + ssl_debug_helpers_generated.c \ + psa_crypto_driver_wrappers.h \ + psa_crypto_driver_wrappers_no_static.c + +ifneq ($(GENERATED_FILES),$(wildcard $(GENERATED_FILES))) + ifeq (,$(wildcard $(MBEDTLS_PATH)/framework/exported.make)) + # Use the define keyword to get a multi-line message. + # GNU make appends ". Stop.", so tweak the ending of our message accordingly. + define error_message $(MBEDTLS_PATH)/framework/exported.make not found. Run `git submodule update --init` to fetch the submodule contents. This is a fatal error -endef -$(error $(error_message)) + endef + $(error $(error_message)) + endif + include $(MBEDTLS_PATH)/framework/exported.make endif -include $(MBEDTLS_PATH)/framework/exported.make # Also see "include/mbedtls/mbedtls_config.h" @@ -327,11 +337,6 @@ libmbedcrypto.dll: $(OBJS_CRYPTO) $(CC) $(LOCAL_CFLAGS) $(CFLAGS) -o $@ -c $< .PHONY: generated_files -GENERATED_FILES = \ - error.c version_features.c \ - ssl_debug_helpers_generated.c \ - psa_crypto_driver_wrappers.h \ - psa_crypto_driver_wrappers_no_static.c generated_files: $(GENERATED_FILES) # See root Makefile From 4ba34c0d888b57db1f9470f8e90c0281c067cb0a Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 4 Mar 2024 16:57:58 +0100 Subject: [PATCH 031/211] Update submodule after PR merge Signed-off-by: Gilles Peskine --- framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework b/framework index 26ab40de58..750634d3a5 160000 --- a/framework +++ b/framework @@ -1 +1 @@ -Subproject commit 26ab40de5887c872b5108981fece907104e8409c +Subproject commit 750634d3a51eb9d61b59fd5d801546927c946588 From 492d4a8ef9668fbc7655b6c0bc71de11a3804553 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 4 Mar 2024 14:06:29 +0100 Subject: [PATCH 032/211] Mention psa_generate_key_ext() Replaces the recommendation to use mbedtls_rsa_gen_key() for RSA key generation with a custom public exponent. Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 94b57eba9c..d4c7b6420e 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -779,7 +779,7 @@ A finite-field Diffie-Hellman key can be used for key agreement with the algorit The easiest way to create a key pair object is by randomly generating it with [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5). Compared with the low-level functions from the legacy API (`mbedtls_rsa_gen_key`, `mbedtls_ecp_gen_privkey`, `mbedtls_ecp_gen_keypair`, `mbedtls_ecp_gen_keypair_base`, `mbedtls_ecdsa_genkey`), this directly creates an object that can be used with high-level APIs, but removes some of the flexibility. Note that if you want to export the generated private key, you must pass the flag [`PSA_KEY_USAGE_EXPORT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga7dddccdd1303176e87a4d20c87b589ed) to [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de); exporting the public key with [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) is always permitted. -For RSA keys, `psa_generate_key` always uses 65537 as the public exponent. If you need a different public exponent, use the legacy interface to create the key then import it as described in “[Importing legacy keys via the PK module](#importing-legacy-keys-via-the-pk-module)”. +For RSA keys, `psa_generate_key` uses 65537 as the public exponent. You can use [`psa_generate_key_ext`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga6776360ae8046a4456a5f990f997da58) to select a different public exponent. As of Mbed TLS 3.6.0, selecting a different public exponent is only supported with the built-in RSA implementation, not with PSA drivers. To create a key object from existing material, use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b). While this function has the same basic goal as the PK parse functions (`mbedtls_pk_parse_key`, `mbedtls_pk_parse_public_key`, `mbedtls_pk_parse_subpubkey`), it is limited to a single format that just contains the number(s) that make up the key, with very little metadata. This format is a substring of one of the formats accepted by the PK functions (except for finite-field Diffie-Hellman which the PK module does not support). The table below summarizes the PSA import/export format for key pairs and public keys; see the documentation of [`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) for more details. @@ -804,7 +804,6 @@ You can use glue functions in the PK module to create a key object using the leg * Parsing a key in a format with metadata without knowing its type ahead of time. * Importing a key which you have in the form of a list of numbers, rather than the binary encoding required by `psa_import_key`. * Importing a key with less information than what the PSA API needs, for example an ECC public key in a compressed format, an RSA private key without the private exponent, or an RSA private key without the CRT parameters. -* Generating an RSA key with $e \ne 65537$. #### Importing a PK key by wrapping @@ -819,7 +818,6 @@ You can use this workflow to import an RSA key via an `mbedtls_rsa_context` obje 2. Call `mbedtls_pk_rsa` or `mbedtls_pk_ec` to obtain the underlying low-level context. 3. Call `mbedtls_rsa_xxx` or `mbedtls_ecp_xxx` functions to construct the desired key. For example: * `mbedtls_rsa_import` or `mbedtls_rsa_import_raw` followed by `mbedtls_rsa_complete` to create an RSA private key without all the parameters required by the PSA API. - * `mbedtls_rsa_gen_key` to generate an RSA private key with a custom public exponent. 4. Call `mbedtls_pk_wrap_as_opaque` as described above to create a corresponding PSA key object. 5. Call `mbedtls_pk_free` to free the resources associated with the PK object. From 9d04f0872fe29e9f076d4eb58e60ab8acb84beec Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 4 Mar 2024 19:04:26 +0100 Subject: [PATCH 033/211] Document mbedtls_pk_import_into_psa Explain how to use mbedtls_pk_get_psa_attributes() and mbedtls_pk_import_into_psa() to make a PSA key from a PK key. Remove the discussion of how to do the same manually. Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 102 +++++++++++------------------------------ 1 file changed, 27 insertions(+), 75 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index d4c7b6420e..cc81acc587 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -781,7 +781,7 @@ The easiest way to create a key pair object is by randomly generating it with [` For RSA keys, `psa_generate_key` uses 65537 as the public exponent. You can use [`psa_generate_key_ext`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga6776360ae8046a4456a5f990f997da58) to select a different public exponent. As of Mbed TLS 3.6.0, selecting a different public exponent is only supported with the built-in RSA implementation, not with PSA drivers. -To create a key object from existing material, use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b). While this function has the same basic goal as the PK parse functions (`mbedtls_pk_parse_key`, `mbedtls_pk_parse_public_key`, `mbedtls_pk_parse_subpubkey`), it is limited to a single format that just contains the number(s) that make up the key, with very little metadata. This format is a substring of one of the formats accepted by the PK functions (except for finite-field Diffie-Hellman which the PK module does not support). The table below summarizes the PSA import/export format for key pairs and public keys; see the documentation of [`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) for more details. +To create a key object from existing material, use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b). This function has the same basic goal as the PK parse functions (`mbedtls_pk_parse_key`, `mbedtls_pk_parse_public_key`, `mbedtls_pk_parse_subpubkey`), but only supports a single format that just contains the number(s) that make up the key, with very little metadata. The table below summarizes the PSA import/export format for key pairs and public keys; see the documentation of [`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) for more details. | Key type | PSA import/export format | | -------- | ------------------------ | @@ -795,93 +795,45 @@ To create a key object from existing material, use [`psa_import_key`](https://mb There is no equivalent of `mbedtls_pk_parse_keyfile` and `mbedtls_pk_parse_public_keyfile`. Either call the legacy function or load the file data manually. -A future extension of the PSA API will support other import formats. Until those are implemented, see the following subsections for ways to use the PK module for key parsing and construct a PSA key object from the PK object. +A future extension of the PSA API will support other import formats. Until those are implemented, see the following subsection for how to use the PK module for key parsing and construct a PSA key object from the PK object. -#### Importing legacy keys via the PK module +### Creating a PSA key via PK -You can use glue functions in the PK module to create a key object using the legacy API, then import that object into the PSA subsystem. This is useful for use cases that the PSA API does not currently cover, such as: +You can use the PK module as an intermediate step to create an RSA or ECC key for use with PSA. This is useful for use cases that the PSA API does not currently cover, such as: * Parsing a key in a format with metadata without knowing its type ahead of time. +* Parsing a key in a format that the PK module supports, but`psa_import_key` doesn't. * Importing a key which you have in the form of a list of numbers, rather than the binary encoding required by `psa_import_key`. * Importing a key with less information than what the PSA API needs, for example an ECC public key in a compressed format, an RSA private key without the private exponent, or an RSA private key without the CRT parameters. -#### Importing a PK key by wrapping +For such use cases: -If you have a PK object, you can call `mbedtls_pk_wrap_as_opaque` to create a PSA key object with the same key material. (This function is only present in builds with `MBEDTLS_USE_PSA_CRYPTO` enabled. It is experimental and [will likely be replaced by a slightly different interface in a future version of Mbed TLS](https://github.com/Mbed-TLS/mbedtls/issues/7760)). This function automatically determines the PSA key type and lets you specify the usage policy (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). Once you've called this function, you can destroy the PK object. This function calls `psa_import_key` internally; call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) to destroy the PSA key object once your application no longer needs it. Common scenarios where this workflow is useful are: +1. First create a PK object with the desired key material. +2. Call [`mbedtls_pk_get_psa_attributes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a7aa7b33cffb6981d95d1632631de9244) to fill PSA attributes corresponding to the PK key. Pass one of the following values as the `usage` parameter: + * `PSA_KEY_USAGE_SIGN_HASH` or `PSA_KEY_USAGE_SIGN_MESSAGE` for a key pair used for signing. + * `PSA_KEY_USAGE_DECRYPT` for a key pair used for decryption. + * `PSA_KEY_USAGE_DERIVE` for a key pair used for key agreement. + * `PSA_KEY_USAGE_VERIFY_HASH` or `PSA_KEY_USAGE_VERIFY_MESSAGE` for a public key pair used for signature verification. + * `PSA_KEY_USAGE_ENCRYPT` for a key pair used for encryption. +3. Optionally, tweak the attributes (this is rarely necessary). For example: + * Call [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de), [`psa_set_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaeb8341ca52baa0279475ea3fd3bcdc98) and/or [`psa_set_key_enrollment_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__extra_8h/#group__attributes_1gaffa134b74aa52aa3ed9397fcab4005aa) to change the key's policy (by default, it allows what can be done through the PK module). + · Call [`psa_set_key_id`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gae48fcfdc72a23e7499957d7f54ff5a64) and perhaps [`psa_set_key_lifetime`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gac03ccf09ca6d36cc3d5b43f8303db6f7) to create a PSA persistent key. +4. Call [`mbedtls_pk_import_into_psa`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1ad59835d14832daf0f4b4bd0a4555abb9) to import the key into the PSA key store. +5. You can now free the PK object with `mbedtls_pk_free`. -* You have working code that's calling `mbedtls_pk_parse_key`, `mbedtls_pk_parse_public_key`, `mbedtls_pk_parse_subpubkey`, `mbedtls_pk_parse_keyfile` or `mbedtls_pk_parse_public_keyfile` to create a PK object. -* You have working code that's using the `rsa.h` or `ecp.h` API to create a key object, and there is no PSA equivalent. - -You can use this workflow to import an RSA key via an `mbedtls_rsa_context` object or an ECC key via an `mbedtls_ecp_keypair` object: - -1. Call `mbedtls_pk_init` then `mbedtls_pk_setup` to set up a PK context for the desired key type (`MBEDTLS_PK_RSA` or `MBEDTLS_PK_ECKEY`). -2. Call `mbedtls_pk_rsa` or `mbedtls_pk_ec` to obtain the underlying low-level context. -3. Call `mbedtls_rsa_xxx` or `mbedtls_ecp_xxx` functions to construct the desired key. For example: - * `mbedtls_rsa_import` or `mbedtls_rsa_import_raw` followed by `mbedtls_rsa_complete` to create an RSA private key without all the parameters required by the PSA API. -4. Call `mbedtls_pk_wrap_as_opaque` as described above to create a corresponding PSA key object. -5. Call `mbedtls_pk_free` to free the resources associated with the PK object. - -#### Importing a PK key by export-import - -This section explains how to export a PK object in the PSA import format. The process depends on the key type. You can use `mbedtls_pk_get_type` or `mbedtls_pk_can_do` to distinguish between RSA and ECC keys. The snippets below assume that the key is in an `mbedtls_pk_context pk`, and omit error checking. - -For an RSA private key: +Here is some sample code illustrating the above process, with error checking omitted. ``` -unsigned char buf[PSA_EXPORT_KEY_PAIR_MAX_SIZE]; -size_t length = mbedtls_pk_write_key_der(&pk, buf, sizeof(buf)); +mbedtls_pk_context pk; +mbedtls_pk_init(&pk); +mbedtls_pk_parse_key(&pk, key_buffer, key_buffer_length, NULL, 0, + mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE); psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; -psa_set_key_attributes(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); -psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_... | ...); -psa_set_key_algorithm(&attributes, PSA_ALGORITHM_...); -psa_key_id_t key_id = 0; -psa_import_key(&attributes, buf + sizeof(buf) - length, length, &key_id); -mbedtls_pk_free(&pk); -``` - -For an ECC private key (a future version of Mbed TLS [will provide a more direct way to find the curve family](https://github.com/Mbed-TLS/mbedtls/issues/7764)): - -``` -unsigned char buf[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; -mbedtls_ecp_keypair *ec = mbedtls_pk_ec(&pk); -psa_ecc_curve_t curve; -{ - mbedtls_ecp_group grp; - mbedtls_ecp_group_init(&grp); - mbedtls_ecp_point Q; - mbedtls_ecp_point_init(&Q); - mbedtls_mpi d; - mbedtls_mpi_init(&d); - mbedtls_ecp_export(ec, &grp, &d, &Q); - size_t bits; - curve = mbedtls_ecc_group_to_psa(grp.id, &bits); - mbedtls_ecp_group_free(&grp); - mbedtls_ecp_point_free(&Q); - mbedtls_mpi_free(&d); -} -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_... | ...); -psa_set_key_algorithm(&attributes, PSA_ALGORITHM_...); -psa_key_id_t key_id = 0; -psa_import_key(&attributes, buf, length, &key_id); -mbedtls_pk_free(&pk); -``` - -For an RSA or ECC public key: - -``` -unsigned char buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; -size_t length = mbedtls_pk_write_pubkey(&pk, buf, sizeof(buf)); -psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; -psa_set_key_attributes(&attributes, ...); // need to determine the type manually -psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_... | ...); -psa_set_key_algorithm(&attributes, PSA_ALGORITHM_...); -psa_key_id_t key_id = 0; -psa_import_key(&attributes, buf + sizeof(buf) - length, length, &key_id); +mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_SIGN_HASH, &attributes); +psa_key_id_t key_id; +mbedtls_pk_import_into_psa(&pk, &attributes, &key_id); mbedtls_pk_free(&pk); +psa_sign_hash(key_id, ...); ``` #### Importing an elliptic curve key from ECP From 0612adc0f7dec712563a8cc1b048d67131084006 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 4 Mar 2024 19:20:15 +0100 Subject: [PATCH 034/211] Document mbedtls_pk_setup_opaque and mbedtls_pk_copy_from_psa Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index cc81acc587..f86845bbc2 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -902,11 +902,32 @@ To export a PSA public key or to export the public key of a PSA key pair object, The export format is the same format used for `psa_import_key`, described in “[Creating keys for asymmetric cryptography](#creating-keys-for-asymmetric-cryptography)” above. -A future extension of the PSA API will support other export formats. Until those are implemented, see “[Exporting a PK key by wrapping](#exporting-a-pk-key-by-wrapping)” for ways to use the PK module to format a PSA key. +A future extension of the PSA API will support other export formats. Until those are implemented, see “[Exposing a PSA key via PK](#exposing-a-psa-key-via-pk)” for ways to use the PK module to format a PSA key. -#### Exporting a PK key by wrapping +#### Exposing a PSA key via PK -You can wrap a PSA key object in a PK key context with `mbedtls_pk_setup_opaque`. This allows you to call functions such as `mbedtls_pk_write_key_der`, `mbedtls_pk_write_pubkey_der`, `mbedtls_pk_write_pubkey_pem`, `mbedtls_pk_write_key_pem` or `mbedtls_pk_write_pubkey` to export the key data in various formats. +This section discusses how to use a PSA key in a context that requires a PK object, such as PK formatting functions (`mbedtls_pk_write_key_der`, `mbedtls_pk_write_pubkey_der`, `mbedtls_pk_write_pubkey_pem`, `mbedtls_pk_write_key_pem` or `mbedtls_pk_write_pubkey`), Mbed TLS X.509 functions, Mbed TLS SSL functions, or another API that involves `mbedtls_pk_context` objects. Two functions from `pk.h` help with that: + +* [`mbedtls_pk_copy_from_psa`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1ab8e88836fd9ee344ffe630c40447bd08) copies a PSA key into a PK object. The PSA key must be exportable. The PK object remains valid even if the PSA key is destroyed. +* [`mbedtls_pk_setup_opaque`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a4c04ac22ab9c1ae09cc29438c308bf05) sets up a PK object that wraps the PSA key. The PK object can only be used as permitted by the PSA key's policy. The PK object contains a reference to the PSA key identifier, therefore PSA key must not be destroyed as long as the PK object remains alive. + +Here is some sample code illustrating how to use the PK module to format a PSA public key or the public key of a PSA key pair. +``` +int write_psa_pubkey(psa_key_id_t key_id, + unsigned char *buf, size_t size, size_t *len) { + mbedtls_pk_context pk; + mbedtls_pk_init(&pk); + int ret = mbedtls_pk_setup_opaque(&pk, key_id); + if (ret != 0) goto exit; + ret = mbedtls_pk_write_pubkey_der(&pk, buf, size); + if (ret < 0) goto exit; + *len = ret; + memmove(buf, buf + size - ret, ret); + ret = 0; +exit: + mbedtls_pk_free(&pk); +} +``` ### Signature operations From 634d60ce0a2de7823daf6c0843575da7d8832897 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 4 Mar 2024 19:23:18 +0100 Subject: [PATCH 035/211] List ECDSA signature conversion functions Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index f86845bbc2..e65507f270 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -954,7 +954,8 @@ The following subsections describe the PSA signature mechanisms that correspond #### ECDSA signature -**Note: in the PSA API, the format of an ECDSA signature is the raw fixed-size format. This is different from the legacy API** which uses the ASN.1 DER format for ECDSA signatures. A future version of Mbed TLS [will provide a way to convert between the two formats](https://github.com/Mbed-TLS/mbedtls/issues/7765). +**Note: in the PSA API, the format of an ECDSA signature is the raw fixed-size format. This is different from the legacy API** which uses the ASN.1 DER format for ECDSA signatures. To convert between the two formats, use [`mbedtls_ecdsa_raw_to_der`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/psa__util_8h/#group__psa__tls__helpers_1ga9295799b5437bdff8ce8abd524c5ef2e) or [`mbedtls_ecdsa_der_to_raw`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/psa__util_8h/#group__psa__tls__helpers_1ga33b3cf65d5992ccc724b7ee00186ae61). + ECDSA is the mechanism provided by `mbedtls_pk_sign` and `mbedtls_pk_verify` for ECDSA keys, as well as by `mbedtls_ecdsa_sign`, `mbedtls_ecdsa_sign_det_ext`, `mbedtls_ecdsa_write_signature`, `mbedtls_ecdsa_verify` and `mbedtls_ecdsa_read_signature`. From 0b14d1407d4d2b067f075c877fcc2002225ce20f Mon Sep 17 00:00:00 2001 From: Ryan Date: Tue, 5 Mar 2024 13:55:33 +0000 Subject: [PATCH 036/211] Document deprecated transaction system as non thread safe Not all of the writes to this field are protected by a mutex. There is no also no protection in place to stop another thread from overwriting the current transaction Signed-off-by: Ryan Everett --- library/psa_crypto_storage.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto_storage.h b/library/psa_crypto_storage.h index f1ea265b42..d7f5b18953 100644 --- a/library/psa_crypto_storage.h +++ b/library/psa_crypto_storage.h @@ -231,8 +231,9 @@ typedef uint16_t psa_crypto_transaction_type_t; * This type is designed to be serialized by writing the memory representation * and reading it back on the same device. * - * \note The transaction mechanism is designed for a single active transaction - * at a time. The transaction object is #psa_crypto_transaction. + * \note The transaction mechanism is not thread-safe. There can only be one + * single active transaction at a time. + * The transaction object is #psa_crypto_transaction. * * \note If an API call starts a transaction, it must complete this transaction * before returning to the application. From 6caf84f71740630fe33883cb0cec97a70a827e1d Mon Sep 17 00:00:00 2001 From: Ryan Date: Tue, 5 Mar 2024 13:57:00 +0000 Subject: [PATCH 037/211] Explicitely remove the deprecated driver interface from the TSan config Signed-off-by: Ryan Everett --- tests/scripts/all.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index c25f044409..007f8e684f 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -2178,6 +2178,9 @@ component_test_tsan () { scripts/config.py set MBEDTLS_THREADING_C scripts/config.py set MBEDTLS_THREADING_PTHREAD + # The deprecated MBEDTLS_PSA_CRYPTO_SE_C interface is not thread safe. + scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C + CC=clang cmake -D CMAKE_BUILD_TYPE:String=TSan . make From 32a64588803711174947f9853bac9869c6da3aeb Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 5 Mar 2024 18:16:18 +0000 Subject: [PATCH 038/211] Add a warning to the definition of MBEDTLS_PSA_CRYPTO_SE_C Signed-off-by: Ryan Everett --- include/mbedtls/mbedtls_config.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h index 7cf4153b11..feb2054902 100644 --- a/include/mbedtls/mbedtls_config.h +++ b/include/mbedtls/mbedtls_config.h @@ -3201,6 +3201,9 @@ * \deprecated This feature is deprecated. Please switch to the PSA driver * interface. * + * \warning This feature is not thread-safe, and should not be used in a + * multi-threaded environment. + * * Module: library/psa_crypto_se.c * * Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_PSA_CRYPTO_STORAGE_C From 7f86d356b19dbb4f567805f2c814d92ba01db080 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 5 Mar 2024 15:35:59 +0000 Subject: [PATCH 039/211] Improve PBKDF2 with CMAC perf by ~16% 10x perf in cmac_multiply_by_u; 2% uplift in AES-CMAC benchmarks Signed-off-by: Dave Rodgman --- library/cmac.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/library/cmac.c b/library/cmac.c index f40cae20c4..f9f606f16a 100644 --- a/library/cmac.c +++ b/library/cmac.c @@ -58,7 +58,7 @@ static int cmac_multiply_by_u(unsigned char *output, const unsigned char R_128 = 0x87; const unsigned char R_64 = 0x1B; unsigned char R_n, mask; - unsigned char overflow = 0x00; + uint32_t overflow = 0x00; int i; if (blocksize == MBEDTLS_AES_BLOCK_SIZE) { @@ -69,9 +69,12 @@ static int cmac_multiply_by_u(unsigned char *output, return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; } - for (i = (int) blocksize - 1; i >= 0; i--) { - output[i] = input[i] << 1 | overflow; - overflow = input[i] >> 7; + for (i = (int) blocksize - 4; i >= 0; i -= 4) { + uint32_t i32 = MBEDTLS_GET_UINT32_BE(&input[i], 0); + uint32_t new_overflow = i32 >> 31; + i32 = (i32 << 1) | overflow; + MBEDTLS_PUT_UINT32_BE(i32, &output[i], 0); + overflow = new_overflow; } /* mask = ( input[0] >> 7 ) ? 0xff : 0x00 From 5ba2b2b8cce57f2809dcf02b2a9886c6ee971a5d Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 6 Mar 2024 11:38:49 +0000 Subject: [PATCH 040/211] Ensure blocksize is compile-time const when DES not present Signed-off-by: Dave Rodgman --- library/cmac.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/library/cmac.c b/library/cmac.c index f9f606f16a..cd3bd3ae40 100644 --- a/library/cmac.c +++ b/library/cmac.c @@ -56,16 +56,20 @@ static int cmac_multiply_by_u(unsigned char *output, size_t blocksize) { const unsigned char R_128 = 0x87; - const unsigned char R_64 = 0x1B; unsigned char R_n, mask; uint32_t overflow = 0x00; int i; if (blocksize == MBEDTLS_AES_BLOCK_SIZE) { R_n = R_128; - } else if (blocksize == MBEDTLS_DES3_BLOCK_SIZE) { + } +#if defined(MBEDTLS_DES_C) + else if (blocksize == MBEDTLS_DES3_BLOCK_SIZE) { + const unsigned char R_64 = 0x1B; R_n = R_64; - } else { + } +#endif + else { return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; } From 411cb6c30f9b37ea4e463c1b98ce77c12bae643e Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Mon, 4 Mar 2024 17:33:52 +0000 Subject: [PATCH 041/211] test_suite_ssl: Added ssl_session_id_accessors_check. Signed-off-by: Minos Galanakis --- tests/suites/test_suite_ssl.data | 8 +++++ tests/suites/test_suite_ssl.function | 48 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 385682ae12..3d73e7344a 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -961,6 +961,14 @@ TLS 1.3: SRV: session serialization: Wrong config depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_SRV_C ssl_session_serialize_version_check:0:0:0:1:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_3 +Test Session id & Ciphersuite accesors TLS 1.2 +depends_on:MBEDTLS_SSL_PROTO_TLS1_2 +ssl_session_id_accessors_check:MBEDTLS_SSL_VERSION_TLS1_2 + +Test Session id & Ciphersuite accesors TLS 1.3 +depends_on:MBEDTLS_SSL_PROTO_TLS1_3 +ssl_session_id_accessors_check:MBEDTLS_SSL_VERSION_TLS1_3 + Record crypt, AES-128-CBC, 1.2, SHA-384 depends_on:MBEDTLS_SSL_HAVE_AES:MBEDTLS_SSL_HAVE_CBC:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_MD_CAN_SHA384 ssl_crypt_record:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_MD_SHA384:0:0:MBEDTLS_SSL_VERSION_TLS1_2:0:0 diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index d327828bcd..af2dc2515a 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -2379,6 +2379,54 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void ssl_session_id_accessors_check(int tls_version) +{ + mbedtls_ssl_session session; + int ciphersuite_id; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info; + + mbedtls_ssl_session_init(&session); + USE_PSA_INIT(); + + switch (tls_version) { +#if defined(MBEDTLS_SSL_PROTO_TLS1_3) + case MBEDTLS_SSL_VERSION_TLS1_3: + ciphersuite_id = MBEDTLS_TLS1_3_AES_128_GCM_SHA256; + TEST_ASSERT(mbedtls_test_ssl_tls13_populate_session( + &session, 0, MBEDTLS_SSL_IS_SERVER) == 0); + break; +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + case MBEDTLS_SSL_VERSION_TLS1_2: + ciphersuite_id = MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256; + TEST_ASSERT(mbedtls_test_ssl_tls12_populate_session( + &session, 0, MBEDTLS_SSL_IS_SERVER, NULL) == 0); + + break; +#endif + default: + /* should never happen */ + TEST_ASSERT(0); + break; + } + TEST_ASSERT(*mbedtls_ssl_session_get_id(&session) == session.id); + TEST_ASSERT(mbedtls_ssl_session_get_id_len(&session) == session.id_len); + /* mbedtls_test_ssl_tls1x_populate_session sets a mock suite-id of 0xabcd */ + TEST_ASSERT(mbedtls_ssl_session_get_ciphersuite_id(&session) == 0xabcd); + + /* Test setting a reference id for tls1.3 and tls1.2 */ + ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(ciphersuite_id); + if (ciphersuite_info != NULL) { + TEST_ASSERT(mbedtls_ssl_ciphersuite_get_id(ciphersuite_info) == ciphersuite_id); + } + +exit: + mbedtls_ssl_session_free(&session); + USE_PSA_DONE(); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:MBEDTLS_RSA_C:MBEDTLS_ECP_HAVE_SECP384R1:!MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256 */ void mbedtls_endpoint_sanity(int endpoint_type) { From c02c5b1520a2d48e7cbb534ea820d489b2541237 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 5 Mar 2024 18:09:35 +0000 Subject: [PATCH 042/211] Follow-up for less verbose logging Signed-off-by: Dave Rodgman --- tests/scripts/quiet/cmake | 2 +- tests/scripts/quiet/make | 2 +- tests/scripts/quiet/quiet.sh | 0 3 files changed, 2 insertions(+), 2 deletions(-) mode change 100755 => 100644 tests/scripts/quiet/quiet.sh diff --git a/tests/scripts/quiet/cmake b/tests/scripts/quiet/cmake index 930931d539..c03d8c3e3e 100755 --- a/tests/scripts/quiet/cmake +++ b/tests/scripts/quiet/cmake @@ -16,4 +16,4 @@ export NO_SILENCE=" --version " export TOOL="cmake" -exec "$(dirname "$0")/quiet.sh" "$@" +. "$(dirname "$0")/quiet.sh" diff --git a/tests/scripts/quiet/make b/tests/scripts/quiet/make index d022551df1..6af3a57ce4 100755 --- a/tests/scripts/quiet/make +++ b/tests/scripts/quiet/make @@ -16,4 +16,4 @@ export NO_SILENCE=" --version | test " export TOOL="make" -exec "$(dirname "$0")/quiet.sh" "$@" +. "$(dirname "$0")/quiet.sh" diff --git a/tests/scripts/quiet/quiet.sh b/tests/scripts/quiet/quiet.sh old mode 100755 new mode 100644 From 4c4f1f1428df289c7c22378b30d5ea3c29948de7 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 7 Mar 2024 16:50:33 +0000 Subject: [PATCH 043/211] Avoid recursion for relative paths Signed-off-by: Dave Rodgman --- tests/scripts/quiet/quiet.sh | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/scripts/quiet/quiet.sh b/tests/scripts/quiet/quiet.sh index 30ee569a22..b1432301de 100644 --- a/tests/scripts/quiet/quiet.sh +++ b/tests/scripts/quiet/quiet.sh @@ -22,9 +22,16 @@ # 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 -ORIGINAL_TOOL=$(type -ap "${TOOL}" | grep -v -Fx "$TOOL_WITH_PATH" | head -n1) +# Function to normalise paths +get_real_filename() { + leafname="$(basename "$1")" + ( cd $(dirname "$1"); echo "$(pwd)/$leafname" ) +} + +# Normalise path to wrapper script +WRAPPER_WITH_PATH=$(get_real_filename "$0") +# Identify original tool (compare normalised path to WRAPPER_WITH_PATH to avoid recursively calling the same wrapper script) +ORIGINAL_TOOL="$(for p in $(type -ap "$TOOL"); do get_real_filename "$p" ; done | grep -v -Fx "$WRAPPER_WITH_PATH" | head -n1)" print_quoted_args() { # similar to printf '%q' "$@" From 7201bc6b05e2f8db8c4cfd6268d007059a416e02 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 8 Mar 2024 15:45:36 +0100 Subject: [PATCH 044/211] ssl_client2: Fix early data log Signed-off-by: Ronald Cron --- programs/ssl/ssl_client2.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 332befdf93..43133d901c 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -3072,16 +3072,16 @@ reconnect: frags++; written += ret; } while (written < len); - } end_of_early_data: - buf[written] = '\0'; - mbedtls_printf( - " %" MBEDTLS_PRINTF_SIZET " bytes of early data written in %" MBEDTLS_PRINTF_SIZET " fragments\n\n%s\n", - written, - frags, - (char *) buf); + buf[written] = '\0'; + mbedtls_printf( + " %" MBEDTLS_PRINTF_SIZET " bytes of early data written in %" MBEDTLS_PRINTF_SIZET " fragments\n\n%s\n", + written, + frags, + (char *) buf); + } #endif /* MBEDTLS_SSL_EARLY_DATA */ while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) { From 0050dff6ab9015cd80ba12a296d965bbabe06b01 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 8 Mar 2024 16:30:22 +0100 Subject: [PATCH 045/211] ssl_ticket.h: Fix note in API documentation Since the merge of #8574 it is not the case anymore that the lifetime of keys is twice the lifetime of tickets. Signed-off-by: Ronald Cron --- include/mbedtls/ssl_ticket.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/mbedtls/ssl_ticket.h b/include/mbedtls/ssl_ticket.h index 58420495a1..a1e70d4656 100644 --- a/include/mbedtls/ssl_ticket.h +++ b/include/mbedtls/ssl_ticket.h @@ -108,8 +108,7 @@ void mbedtls_ssl_ticket_init(mbedtls_ssl_ticket_context *ctx); * least as strong as the strongest ciphersuite * supported. Usually that means a 256-bit key. * - * \note The lifetime of the keys is twice the lifetime of tickets. - * It is recommended to pick a reasonable lifetime so as not + * \note It is recommended to pick a reasonable lifetime so as not * to negate the benefits of forward secrecy. * * \return 0 if successful, @@ -145,8 +144,7 @@ int mbedtls_ssl_ticket_setup(mbedtls_ssl_ticket_context *ctx, * \note \c klength must be sufficient for use by cipher specified * to \c mbedtls_ssl_ticket_setup * - * \note The lifetime of the keys is twice the lifetime of tickets. - * It is recommended to pick a reasonable lifetime so as not + * \note It is recommended to pick a reasonable lifetime so as not * to negate the benefits of forward secrecy. * * \return 0 if successful, From 97dfc726f342131ad99f8d7f5a7b03dc6789ee9c Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 8 Mar 2024 16:34:59 +0100 Subject: [PATCH 046/211] ssl_ticket.c: Fix ticket lifetime when parsing This is the lifetime of the key used to decrypt the ticket that should be used when parsing a ticket, not the ticket module lifetime that may have been changed since the key was created. Signed-off-by: Ronald Cron --- library/ssl_ticket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c index 5da3887b81..6a31b0bee6 100644 --- a/library/ssl_ticket.c +++ b/library/ssl_ticket.c @@ -504,7 +504,7 @@ int mbedtls_ssl_ticket_parse(void *p_ticket, #if defined(MBEDTLS_HAVE_TIME) mbedtls_ms_time_t ticket_creation_time, ticket_age; mbedtls_ms_time_t ticket_lifetime = - (mbedtls_ms_time_t) ctx->ticket_lifetime * 1000; + (mbedtls_ms_time_t) key->lifetime * 1000; ret = mbedtls_ssl_session_get_ticket_creation_time(session, &ticket_creation_time); From ce79488dd544be0081c13b301a9b0bfc946adb08 Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Wed, 22 Nov 2023 15:01:18 +0800 Subject: [PATCH 047/211] tls13: srv: Fail connection if ticket lifetime exceed 7 days Signed-off-by: Jerry Yu Signed-off-by: Ronald Cron --- include/mbedtls/ssl_ticket.h | 14 ++++++++++++++ library/ssl_tls13_server.c | 21 +++++++++++---------- tests/ssl-opt.sh | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/include/mbedtls/ssl_ticket.h b/include/mbedtls/ssl_ticket.h index a1e70d4656..2ee1400210 100644 --- a/include/mbedtls/ssl_ticket.h +++ b/include/mbedtls/ssl_ticket.h @@ -111,6 +111,13 @@ void mbedtls_ssl_ticket_init(mbedtls_ssl_ticket_context *ctx); * \note It is recommended to pick a reasonable lifetime so as not * to negate the benefits of forward secrecy. * + * \note The TLS 1.3 specification states that ticket lifetime must + * be smaller than seven days. If ticket lifetime has been + * set to a value greater than seven days in this module then + * if the TLS 1.3 is configured to send tickets after the + * handshake it will fail the connection when trying to send + * the first ticket. + * * \return 0 if successful, * or a specific MBEDTLS_ERR_XXX error code */ @@ -147,6 +154,13 @@ int mbedtls_ssl_ticket_setup(mbedtls_ssl_ticket_context *ctx, * \note It is recommended to pick a reasonable lifetime so as not * to negate the benefits of forward secrecy. * + * \note The TLS 1.3 specification states that ticket lifetime must + * be smaller than seven days. If ticket lifetime has been + * set to a value greater than seven days in this module then + * if the TLS 1.3 is configured to send tickets after the + * handshake it will fail the connection when trying to send + * the first ticket. + * * \return 0 if successful, * or a specific MBEDTLS_ERR_XXX error code */ diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 5c24657af6..13ae61df72 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -3271,20 +3271,21 @@ static int ssl_tls13_write_new_session_ticket_body(mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_RET(1, "write_ticket", ret); return ret; } - /* RFC 8446 4.6.1 + + /* RFC 8446 section 4.6.1 + * * ticket_lifetime: Indicates the lifetime in seconds as a 32-bit - * unsigned integer in network byte order from the time of ticket - * issuance. Servers MUST NOT use any value greater than - * 604800 seconds (7 days). The value of zero indicates that the - * ticket should be discarded immediately. Clients MUST NOT cache - * tickets for longer than 7 days, regardless of the ticket_lifetime, - * and MAY delete tickets earlier based on local policy. A server - * MAY treat a ticket as valid for a shorter period of time than what - * is stated in the ticket_lifetime. + * unsigned integer in network byte order from the time of ticket + * issuance. Servers MUST NOT use any value greater than + * 604800 seconds (7 days) ... */ if (ticket_lifetime > MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME) { - ticket_lifetime = MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME; + MBEDTLS_SSL_DEBUG_MSG( + 1, ("Ticket lifetime (%u) is greater than 7 days.", + (unsigned int) ticket_lifetime)); + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; } + MBEDTLS_PUT_UINT32_BE(ticket_lifetime, p, 0); MBEDTLS_SSL_DEBUG_MSG(3, ("ticket_lifetime: %u", (unsigned int) ticket_lifetime)); diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index fd2fc0a1b1..3d76501e27 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -13532,6 +13532,42 @@ run_test "TLS 1.3: NewSessionTicket: Basic check, m->m" \ -s "key exchange mode: psk_ephemeral" \ -s "found pre_shared_key extension" +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: NewSessionTicket: Ticket lifetime max value (7d)" \ + "$P_SRV debug_level=1 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=604800 tickets=1" \ + "$P_CLI reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "HTTP/1.0 200 OK" \ + -c "got new session ticket" \ + -c "Reconnecting with saved session... ok" \ + -s "Protocol is TLSv1.3" \ + -S "Ticket lifetime (604800) is greater than 7 days." + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: NewSessionTicket: Ticket lifetime too long (7d + 1s)" \ + "$P_SRV debug_level=1 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=604801 tickets=1" \ + "$P_CLI reco_mode=1 reconnect=1" \ + 1 \ + -c "Protocol is TLSv1.3" \ + -C "HTTP/1.0 200 OK" \ + -C "got new session ticket" \ + -C "Reconnecting with saved session... ok" \ + -S "Protocol is TLSv1.3" \ + -s "Ticket lifetime (604801) is greater than 7 days." + requires_openssl_tls1_3_with_compatible_ephemeral requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 requires_config_enabled MBEDTLS_DEBUG_C From 9422725abafebb93ccda200010c0f2ee8e7a4c4d Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 8 Mar 2024 17:51:23 +0100 Subject: [PATCH 048/211] tls13: cli: Discard ticket with zero lifetime Signed-off-by: Ronald Cron --- library/ssl_tls13_client.c | 50 ++++++++++++++++++++++++++++++-------- tests/ssl-opt.sh | 19 +++++++++++++++ 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 88d6c9e019..367009c0c8 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -2916,12 +2916,17 @@ static int ssl_tls13_parse_new_session_ticket(mbedtls_ssl_context *ssl, return ret; } - /* session has been updated, allow export */ - session->exported = 0; - return 0; } +/* Non negative return values for ssl_tls13_postprocess_new_session_ticket(). + * - POSTPROCESS_NEW_SESSION_TICKET_SIGNAL, all good, we have to signal the + * application that a valid ticket has been received. + * - POSTPROCESS_NEW_SESSION_TICKET_DISCARD, no fatal error, we keep the + * connection alive but we do not signal the ticket to the application. + */ +#define POSTPROCESS_NEW_SESSION_TICKET_SIGNAL 0 +#define POSTPROCESS_NEW_SESSION_TICKET_DISCARD 1 MBEDTLS_CHECK_RETURN_CRITICAL static int ssl_tls13_postprocess_new_session_ticket(mbedtls_ssl_context *ssl, unsigned char *ticket_nonce, @@ -2933,6 +2938,10 @@ static int ssl_tls13_postprocess_new_session_ticket(mbedtls_ssl_context *ssl, psa_algorithm_t psa_hash_alg; int hash_length; + if (session->ticket_lifetime == 0) { + return POSTPROCESS_NEW_SESSION_TICKET_DISCARD; + } + #if defined(MBEDTLS_HAVE_TIME) /* Store ticket creation time */ session->ticket_reception_time = mbedtls_ms_time(); @@ -2989,7 +2998,7 @@ static int ssl_tls13_postprocess_new_session_ticket(mbedtls_ssl_context *ssl, session, ssl->conf->tls13_kex_modes); MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags); - return 0; + return POSTPROCESS_NEW_SESSION_TICKET_SIGNAL; } /* @@ -3010,12 +3019,37 @@ static int ssl_tls13_process_new_session_ticket(mbedtls_ssl_context *ssl) ssl, MBEDTLS_SSL_HS_NEW_SESSION_TICKET, &buf, &buf_len)); + /* + * We are about to update (maybe only partially) ticket data thus block + * any session export for the time being. + */ + ssl->session->exported = 1; + MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_new_session_ticket( ssl, buf, buf + buf_len, &ticket_nonce, &ticket_nonce_len)); - MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_new_session_ticket( - ssl, ticket_nonce, ticket_nonce_len)); + MBEDTLS_SSL_PROC_CHK_NEG(ssl_tls13_postprocess_new_session_ticket( + ssl, ticket_nonce, ticket_nonce_len)); + + switch (ret) { + case POSTPROCESS_NEW_SESSION_TICKET_SIGNAL: + /* + * All good, we have received a new valid ticket, session data can + * be exported now and we signal the ticket to the application. + */ + ssl->session->exported = 0; + ret = MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET; + break; + + case POSTPROCESS_NEW_SESSION_TICKET_DISCARD: + ret = 0; + MBEDTLS_SSL_DEBUG_MSG(2, ("Discard new session ticket")); + break; + + default: + ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; + } mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER); @@ -3132,10 +3166,6 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl) #if defined(MBEDTLS_SSL_SESSION_TICKETS) case MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET: ret = ssl_tls13_process_new_session_ticket(ssl); - if (ret != 0) { - break; - } - ret = MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET; break; #endif /* MBEDTLS_SSL_SESSION_TICKETS */ diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 3d76501e27..a846e6ab0b 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -13568,6 +13568,25 @@ run_test "TLS 1.3 m->m: NewSessionTicket: Ticket lifetime too long (7d + 1s)" -S "Protocol is TLSv1.3" \ -s "Ticket lifetime (604801) is greater than 7 days." +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: NewSessionTicket: ticket lifetime=0" \ + "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=0 tickets=1" \ + "$P_CLI debug_level=2 reco_mode=1 reconnect=1" \ + 1 \ + -c "Protocol is TLSv1.3" \ + -c "HTTP/1.0 200 OK" \ + -c "Discard new session ticket" \ + -C "got new session ticket" \ + -c "Reconnecting with saved session... failed" \ + -s "Protocol is TLSv1.3" \ + -s "<= write new session ticket" + requires_openssl_tls1_3_with_compatible_ephemeral requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 requires_config_enabled MBEDTLS_DEBUG_C From 3bfad3a8dcf65dc843855e46a6c512b21b86c78b Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 1 Feb 2024 11:28:27 +0100 Subject: [PATCH 049/211] pkparse: make EC/RSA setup functions internally available Signed-off-by: Valerio Setti --- library/pk_internal.h | 7 +++++++ library/pkparse.c | 40 +++++++++++++++++++--------------------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/library/pk_internal.h b/library/pk_internal.h index f5924adf38..a1a34ad1b6 100644 --- a/library/pk_internal.h +++ b/library/pk_internal.h @@ -127,6 +127,13 @@ static inline int mbedtls_pk_is_rfc8410(const mbedtls_pk_context *pk) return MBEDTLS_PK_IS_RFC8410_GROUP_ID(id); } + +int mbedtls_pk_ecc_set_group(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id); +int mbedtls_pk_ecc_set_key(mbedtls_pk_context *pk, unsigned char *key, size_t key_len); +int mbedtls_pk_ecc_set_pubkey(mbedtls_pk_context *pk, const unsigned char *pub, size_t pub_len); +int mbedtls_pk_ecc_set_pubkey_from_prv(mbedtls_pk_context *pk, + const unsigned char *prv, size_t prv_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ /* Helper for (deterministic) ECDSA */ diff --git a/library/pkparse.c b/library/pkparse.c index 5a3d3b2590..e4a812a634 100644 --- a/library/pkparse.c +++ b/library/pkparse.c @@ -61,7 +61,7 @@ * out: will have group (curve) information set * [in] grp_in: a supported group ID (not NONE) */ -static int pk_ecc_set_group(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id) +int mbedtls_pk_ecc_set_group(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id) { #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) size_t ec_bits; @@ -95,12 +95,11 @@ static int pk_ecc_set_group(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id) /* * Set the private key material * - * [in/out] pk: in: must have the group set already, see pk_ecc_set_group(). + * [in/out] pk: in: must have the group set already, see mbedtls_pk_ecc_set_group(). * out: will have the private key set. * [in] key, key_len: the raw private key (no ASN.1 wrapping). */ -static int pk_ecc_set_key(mbedtls_pk_context *pk, - unsigned char *key, size_t key_len) +int mbedtls_pk_ecc_set_key(mbedtls_pk_context *pk, unsigned char *key, size_t key_len) { #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; @@ -140,7 +139,7 @@ static int pk_ecc_set_key(mbedtls_pk_context *pk, * Derive a public key from its private counterpart. * Computationally intensive, only use when public key is not available. * - * [in/out] pk: in: must have the private key set, see pk_ecc_set_key(). + * [in/out] pk: in: must have the private key set, see mbedtls_pk_ecc_set_key(). * out: will have the public key set. * [in] prv, prv_len: the raw private key (see note below). * [in] f_rng, p_rng: RNG function and context. @@ -155,9 +154,9 @@ static int pk_ecc_set_key(mbedtls_pk_context *pk, * 2. MBEDTLS_USE_PSA_CRYPTO but not MBEDTLS_PK_USE_PSA_EC_DATA, * 3. not MBEDTLS_USE_PSA_CRYPTO. */ -static int pk_ecc_set_pubkey_from_prv(mbedtls_pk_context *pk, - const unsigned char *prv, size_t prv_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) +int mbedtls_pk_ecc_set_pubkey_from_prv(mbedtls_pk_context *pk, + const unsigned char *prv, size_t prv_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) { #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) @@ -226,7 +225,7 @@ static int pk_ecc_set_pubkey_from_prv(mbedtls_pk_context *pk, * this fallback uses ECP functions to get the job done. This is the reason * why MBEDTLS_PK_PARSE_EC_COMPRESSED auto-enables MBEDTLS_ECP_LIGHT. * - * [in/out] pk: in: must have the group set, see pk_ecc_set_group(). + * [in/out] pk: in: must have the group set, see mbedtls_pk_ecc_set_group(). * out: will have the public key set. * [in] pub, pub_len: the public key as an ECPoint, * in any format supported by ECP. @@ -278,7 +277,7 @@ exit: /* * Set the public key. * - * [in/out] pk: in: must have its group set, see pk_ecc_set_group(). + * [in/out] pk: in: must have its group set, see mbedtls_pk_ecc_set_group(). * out: will have the public key set. * [in] pub, pub_len: the raw public key (an ECPoint). * @@ -288,8 +287,7 @@ exit: * but not supported; * - another error code otherwise. */ -static int pk_ecc_set_pubkey(mbedtls_pk_context *pk, - const unsigned char *pub, size_t pub_len) +int mbedtls_pk_ecc_set_pubkey(mbedtls_pk_context *pk, const unsigned char *pub, size_t pub_len) { #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) @@ -698,7 +696,7 @@ static int pk_use_ecparams(const mbedtls_asn1_buf *params, mbedtls_pk_context *p } } - return pk_ecc_set_group(pk, grp_id); + return mbedtls_pk_ecc_set_group(pk, grp_id); } #if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES) @@ -714,7 +712,7 @@ static int pk_use_ecparams_rfc8410(const mbedtls_asn1_buf *params, return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; } - return pk_ecc_set_group(pk, grp_id); + return mbedtls_pk_ecc_set_group(pk, grp_id); } /* @@ -740,7 +738,7 @@ static int pk_parse_key_rfc8410_der(mbedtls_pk_context *pk, /* * Load the private key */ - ret = pk_ecc_set_key(pk, key, len); + ret = mbedtls_pk_ecc_set_key(pk, key, len); if (ret != 0) { return ret; } @@ -748,7 +746,7 @@ static int pk_parse_key_rfc8410_der(mbedtls_pk_context *pk, /* pk_parse_key_pkcs8_unencrypted_der() only supports version 1 PKCS8 keys, * which never contain a public key. As such, derive the public key * unconditionally. */ - if ((ret = pk_ecc_set_pubkey_from_prv(pk, key, len, f_rng, p_rng)) != 0) { + if ((ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, key, len, f_rng, p_rng)) != 0) { return ret; } @@ -874,7 +872,7 @@ int mbedtls_pk_parse_subpubkey(unsigned char **p, const unsigned char *end, ret = pk_use_ecparams(&alg_params, pk); } if (ret == 0) { - ret = pk_ecc_set_pubkey(pk, *p, (size_t) (end - *p)); + ret = mbedtls_pk_ecc_set_pubkey(pk, *p, (size_t) (end - *p)); *p += end - *p; } } else @@ -966,7 +964,7 @@ static int pk_parse_key_sec1_der(mbedtls_pk_context *pk, /* * Load the private key */ - ret = pk_ecc_set_key(pk, d, d_len); + ret = mbedtls_pk_ecc_set_key(pk, d, d_len); if (ret != 0) { return ret; } @@ -990,11 +988,11 @@ static int pk_parse_key_sec1_der(mbedtls_pk_context *pk, MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); } - if ((ret = pk_ecc_set_pubkey(pk, p, (size_t) (end2 - p))) == 0) { + if ((ret = mbedtls_pk_ecc_set_pubkey(pk, p, (size_t) (end2 - p))) == 0) { pubkey_done = 1; } else { /* - * The only acceptable failure mode of pk_ecc_set_pubkey() above + * The only acceptable failure mode of mbedtls_pk_ecc_set_pubkey() above * is if the point format is not recognized. */ if (ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) { @@ -1007,7 +1005,7 @@ static int pk_parse_key_sec1_der(mbedtls_pk_context *pk, } if (!pubkey_done) { - if ((ret = pk_ecc_set_pubkey_from_prv(pk, d, d_len, f_rng, p_rng)) != 0) { + if ((ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, d, d_len, f_rng, p_rng)) != 0) { return ret; } } From 070d95e95842e69e9131415085baa13b30393fdd Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 1 Feb 2024 11:29:15 +0100 Subject: [PATCH 050/211] pk: add mbedtls_pk_copy_from_psa() Signed-off-by: Valerio Setti --- include/mbedtls/pk.h | 41 ++++++++++++++ library/pk.c | 130 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+) diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h index ff80290059..6447a15e8d 100644 --- a/include/mbedtls/pk.h +++ b/include/mbedtls/pk.h @@ -390,6 +390,47 @@ int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx, const mbedtls_svc_key_id_t key); #endif /* MBEDTLS_USE_PSA_CRYPTO */ +#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) +/** + * \brief Create a PK context starting from a key stored in PSA. + * This key: + * - must have PSA_KEY_USAGE_EXPORT attribute set and + * - must be a either a RSA or EC (DH is not managed in PK) and + * - must be either a key pair or a public key. + * + * The resulting PK object will be a transparent type: + * - MBEDTLS_PK_RSA for RSA keys or + * - MBEDTLS_PK_ECKEY for EC keys. + * Once this functions returns the PK object will be completely + * independent from the original PSA key that it was generated + * from. + * Calling `mbedtls_pk_sign`, `mbedtls_pk_verify`, + * `mbedtls_pk_encrypt`, `mbedtls_pk_decrypt` on the resulting + * PK context will perform an algorithm that is compatible with + * the PSA key's primary algorithm policy if that is a matching + * operation type (sign/verify, encrypt/decrypt), but with no + * restriction on the hash (as if the policy had + * `PSA_ALG_ANY_HASH` instead of a specific hash, and with + * `PSA_ALG_RSA_PKCS1V15_SIGN_RAW` merged with + * `PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)`). + * * For ECDSA, the choice of deterministic vs randomized will + * be based on the compile-time setting `MBEDTLS_ECDSA_DETERMINISTIC`. + * * For an RSA key, the output key will allow both encrypt/decrypt + * and sign/verify regardless of the original key's policy. + * The original key's policy determines the output key's padding + * mode. + * + * \param key_id The ID of the key stored in PSA. + * \param pk The PK context that will be filled. It must be initialized, + * but not setup. + * + * \return 0 on success. + * \return MBEDTLS_ERR_PK_BAD_INPUT_DATA in case the provided input + * parameters are not correct. + */ +int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk); +#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ + #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) /** * \brief Initialize an RSA-alt context diff --git a/library/pk.c b/library/pk.c index 003ef4aac2..ffe350efea 100644 --- a/library/pk.c +++ b/library/pk.c @@ -35,6 +35,10 @@ #include #include +#define PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE \ + (PSA_EXPORT_KEY_PAIR_MAX_SIZE > PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) ? \ + PSA_EXPORT_KEY_PAIR_MAX_SIZE : PSA_EXPORT_PUBLIC_KEY_MAX_SIZE + /* * Initialise a mbedtls_pk_context */ @@ -1374,4 +1378,130 @@ mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx) return ctx->pk_info->type; } +#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) +int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk) +{ + psa_status_t status; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; + psa_key_type_t key_type; + psa_algorithm_t alg_type; + size_t key_bits; + /* Use a buffer size large enough to contain either a key pair or public key. */ + unsigned char exp_key[PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE]; + size_t exp_key_len; + int ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; + + if (pk == NULL) { + return MBEDTLS_ERR_PK_BAD_INPUT_DATA; + } + + status = psa_get_key_attributes(key_id, &key_attr); + if (status != PSA_SUCCESS) { + return MBEDTLS_ERR_PK_BAD_INPUT_DATA; + } + + if ((psa_get_key_usage_flags(&key_attr) & PSA_KEY_USAGE_EXPORT) != PSA_KEY_USAGE_EXPORT) { + ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; + goto exit; + } + + status = psa_export_key(key_id, exp_key, sizeof(exp_key), &exp_key_len); + if (status != PSA_SUCCESS) { + ret = psa_generic_status_to_mbedtls(status); + goto exit; + } + + key_type = psa_get_key_type(&key_attr); + key_bits = psa_get_key_bits(&key_attr); + alg_type = psa_get_key_algorithm(&key_attr); + +#if defined(MBEDTLS_RSA_C) + if ((key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) || + (key_type == PSA_KEY_TYPE_RSA_PUBLIC_KEY)) { + if (!PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg_type) && + (alg_type != PSA_ALG_RSA_PKCS1V15_CRYPT) && + !PSA_ALG_IS_RSA_OAEP(alg_type) && + !PSA_ALG_IS_RSA_PSS(alg_type)) { + return MBEDTLS_ERR_PK_BAD_INPUT_DATA; + } + + ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)); + if (ret != 0) { + goto exit; + } + + if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) { + ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), exp_key, exp_key_len); + } else { + ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*pk), exp_key, exp_key_len); + } + if (ret != 0) { + goto exit; + } + + mbedtls_md_type_t md_type = MBEDTLS_MD_NONE; + if ((alg_type != PSA_ALG_RSA_PKCS1V15_CRYPT) && + (PSA_ALG_GET_HASH(alg_type) != PSA_ALG_ANY_HASH)) { + md_type = mbedtls_md_type_from_psa_alg(alg_type); + } + + if (PSA_ALG_IS_RSA_OAEP(alg_type) || PSA_ALG_IS_RSA_PSS(alg_type)) { + ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V21, md_type); + } else { + ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V15, md_type); + } + if (ret != 0) { + goto exit; + } + } else +#endif /* MBEDTLS_RSA_C */ +#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) + if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) || + PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type)) { + mbedtls_ecp_group_id grp_id; + + if (!PSA_ALG_IS_ECDSA(alg_type)) { + ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; + goto exit; + } + + ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); + if (ret != 0) { + goto exit; + } + + grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(key_type), key_bits); + ret = mbedtls_pk_ecc_set_group(pk, grp_id); + if (ret != 0) { + goto exit; + } + + if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type)) { + ret = mbedtls_pk_ecc_set_key(pk, exp_key, exp_key_len); + if (ret != 0) { + goto exit; + } + ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, exp_key, exp_key_len, + mbedtls_psa_get_random, + MBEDTLS_PSA_RANDOM_STATE); + } else { + ret = mbedtls_pk_ecc_set_pubkey(pk, exp_key, exp_key_len); + } + if (ret != 0) { + goto exit; + } + } else +#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ + { + return MBEDTLS_ERR_PK_BAD_INPUT_DATA; + } + +exit: + psa_reset_key_attributes(&key_attr); + mbedtls_platform_zeroize(exp_key, sizeof(exp_key)); + + return ret; +} +#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ + #endif /* MBEDTLS_PK_C */ From 452d2d2ccb223714e093826fc7923d0efdf0d5fc Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 1 Feb 2024 11:31:30 +0100 Subject: [PATCH 051/211] test_suite_pk: add some initial testing for mbedtls_pk_copy_from_psa() Signed-off-by: Valerio Setti --- tests/suites/test_suite_pk.data | 54 ++++++ tests/suites/test_suite_pk.function | 290 +++++++++++++++++++++++++--- 2 files changed, 321 insertions(+), 23 deletions(-) diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data index 989235dec7..4637f3721c 100644 --- a/tests/suites/test_suite_pk.data +++ b/tests/suites/test_suite_pk.data @@ -1451,3 +1451,57 @@ pk_import_into_psa_opaque:PSA_KEY_TYPE_ECC_KEY_PAIR(MBEDTLS_TEST_PSA_ECC_ONE_FAM PSA import into PSA: opaque ECC to public, different family (bad) depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:MBEDTLS_TEST_PSA_ECC_HAVE_TWO_FAMILIES:PSA_WANT_ALG_ECDSA pk_import_into_psa_opaque:PSA_KEY_TYPE_ECC_KEY_PAIR(MBEDTLS_TEST_PSA_ECC_ONE_FAMILY):MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE:0:PSA_KEY_TYPE_ECC_PUBLIC_KEY(MBEDTLS_TEST_PSA_ECC_ANOTHER_FAMILY):MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE:0:MBEDTLS_ERR_PK_TYPE_MISMATCH +Copy from PSA: use wrong parameters +pk_copy_from_psa_fail: + +Copy from PSA: valid EC (SECP_R1_256 + ANY_HASH) +depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 +pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH) + +Copy from PSA: valid EC (SECP_R1_256 + SHA_256) +depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 +pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA(PSA_ALG_SHA_256) + +Copy from PSA: valid EC (SECP_R1_256 + SHA_512) +depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA512 +pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA(PSA_ALG_SHA_512) + +Copy from PSA: valid RSA (PKCS1V15_SIGN + ANY_HASH) +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256 +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH) + +Copy from PSA: valid RSA (PKCS1V15_SIGN + SHA_256) +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256 +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256) + +Copy from PSA: valid RSA (PKCS1V15_SIGN + SHA_512) +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA512 +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_512) + +Copy from PSA: valid RSA (PKCS1V15_CRYPT) +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256 +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_CRYPT + +Copy from PSA: valid RSA (OAEP + ANY_HASH) +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256 +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_OAEP(PSA_ALG_ANY_HASH) + +Copy from PSA: valid RSA (OAEP + SHA_256) +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256 +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256) + +Copy from PSA: valid RSA (OAEP + SHA_512) +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA512 +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_512) + +Copy from PSA: valid RSA (PSS_ANY_SALT + ANY_HASH) +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256 +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH) + +Copy from PSA: valid RSA (PSS_ANY_SALT + SHA_256) +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256 +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256) + +Copy from PSA: valid RSA (PSS_ANY_SALT + SHA_512) +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA512 +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_512) diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 3d75ad0e1c..3710e3df43 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -1,5 +1,6 @@ /* BEGIN_HEADER */ #include "mbedtls/pk.h" +#include "mbedtls/psa_util.h" #include "pk_internal.h" /* For error codes */ @@ -425,7 +426,65 @@ exit: } #endif -#if defined(MBEDTLS_USE_PSA_CRYPTO) +#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) +mbedtls_svc_key_id_t pk_psa_pub_key_from_priv(mbedtls_svc_key_id_t priv_id, + psa_key_type_t type, psa_key_usage_t usage, + psa_algorithm_t alg, size_t bits) +{ + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + unsigned char pub_key_buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; + size_t pub_key_len; + mbedtls_svc_key_id_t pub_key = MBEDTLS_SVC_KEY_ID_INIT; + + PSA_ASSERT(psa_export_public_key(priv_id, pub_key_buf, sizeof(pub_key_buf), &pub_key_len)); + + psa_set_key_usage_flags(&attributes, usage); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, type); + psa_set_key_bits(&attributes, bits); + + PSA_ASSERT(psa_import_key(&attributes, pub_key_buf, pub_key_len, &pub_key)); + +exit: + return pub_key; +} + +psa_status_t pk_psa_import_key(unsigned char *key_data, size_t key_len, + psa_key_type_t type, psa_key_usage_t usage, + psa_algorithm_t alg, size_t bits, + mbedtls_svc_key_id_t *key) +{ + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status; + + *key = MBEDTLS_SVC_KEY_ID_INIT; + + psa_set_key_usage_flags(&attributes, usage); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, type); + psa_set_key_bits(&attributes, bits); + status = psa_import_key(&attributes, key_data, key_len, key); + + return status; +} + +psa_status_t pk_psa_genkey_generic(psa_key_type_t type, psa_key_usage_t usage, + psa_algorithm_t alg, size_t bits, + mbedtls_svc_key_id_t *key) +{ + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status; + + *key = MBEDTLS_SVC_KEY_ID_INIT; + + psa_set_key_usage_flags(&attributes, usage); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, type); + psa_set_key_bits(&attributes, bits); + status = psa_generate_key(&attributes, key); + + return status; +} /* * Generate an ECC key using PSA and return the key identifier of that key, @@ -434,19 +493,12 @@ exit: */ mbedtls_svc_key_id_t pk_psa_genkey_ecc(void) { - 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); - const size_t bits = 256; + mbedtls_svc_key_id_t key; - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); - psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); - psa_set_key_type(&attributes, type); - psa_set_key_bits(&attributes, bits); - PSA_ASSERT(psa_generate_key(&attributes, &key)); + pk_psa_genkey_generic(PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), + PSA_KEY_USAGE_SIGN_HASH, PSA_ALG_ECDSA(PSA_ALG_SHA_256), + 256, &key); -exit: return key; } @@ -456,21 +508,14 @@ exit: */ mbedtls_svc_key_id_t pk_psa_genkey_rsa(void) { - 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; + mbedtls_svc_key_id_t key; - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); - psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_SIGN_RAW); - psa_set_key_type(&attributes, type); - psa_set_key_bits(&attributes, bits); - PSA_ASSERT(psa_generate_key(&attributes, &key)); + pk_psa_genkey_generic(PSA_KEY_TYPE_RSA_KEY_PAIR, PSA_KEY_USAGE_SIGN_HASH, + PSA_ALG_RSA_PKCS1V15_SIGN_RAW, 1024, &key); -exit: return key; } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ +#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -2199,3 +2244,202 @@ exit: PSA_DONE(); } /* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_CLIENT*/ +void pk_copy_from_psa_fail(void) +{ + mbedtls_pk_context pk_ctx; + mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; +#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_RSA_C) && \ + defined(MBEDTLS_MD_CAN_SHA256) && defined(MBEDTLS_PKCS1_V21) + unsigned char in_buf[32]; /* Only SHA256 is used here. */ + unsigned char out_buf[256]; /* Only 2048 RSA bit size is used here. */ + size_t out_buf_len; +#endif /* MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_RSA_C && + MBEDTLS_MD_CAN_SHA256 && MBEDTLS_PKCS1_V21 */ + + mbedtls_pk_init(&pk_ctx); + PSA_INIT(); + + /* Null pk pointer. */ + TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, NULL), + MBEDTLS_ERR_PK_BAD_INPUT_DATA); + + /* Invalid key ID. */ + TEST_EQUAL(mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_make(0, 0), &pk_ctx), + MBEDTLS_ERR_PK_BAD_INPUT_DATA); + +#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE) + /* Generate a key type that is not handled by the PK module. */ + PSA_ASSERT(pk_psa_genkey_generic(PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919), + PSA_KEY_USAGE_EXPORT, PSA_ALG_NONE, 2048, &key_id)); + TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, &pk_ctx), MBEDTLS_ERR_PK_BAD_INPUT_DATA); + psa_destroy_key(key_id); +#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE */ + +#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && defined(PSA_WANT_ECC_SECP_R1_256) && \ + defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) + /* Generate an EC key which cannot be exported. */ + PSA_ASSERT(pk_psa_genkey_generic(PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), + 0, PSA_ALG_NONE, 256, &key_id)); + TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, &pk_ctx), MBEDTLS_ERR_PK_BAD_INPUT_DATA); + psa_destroy_key(key_id); + + /* Use valid exportable EC key with wrong alorithm. */ + PSA_ASSERT(pk_psa_genkey_generic(PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), + PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH, + PSA_ALG_ECDH, 256, &key_id)); + TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, &pk_ctx), MBEDTLS_ERR_PK_BAD_INPUT_DATA); + psa_destroy_key(key_id); +#endif /* MBEDTLS_PK_HAVE_ECC_KEYS && PSA_WANT_ECC_SECP_R1_256 && + PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE */ + +#if defined(MBEDTLS_RSA_C) && defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) + /* Use valid exportable RSA key with wrong alorithm. */ + PSA_ASSERT(pk_psa_genkey_generic(PSA_KEY_TYPE_RSA_KEY_PAIR, + PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH, + PSA_ALG_CMAC, 2048, &key_id)); + TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, &pk_ctx), MBEDTLS_ERR_PK_BAD_INPUT_DATA); + psa_destroy_key(key_id); + + /* Try to encrypt with a RSA key in PKCS1V21 format. */ +#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_MD_CAN_SHA256) && defined(MBEDTLS_PKCS1_V21) + PSA_ASSERT(pk_psa_genkey_generic(PSA_KEY_TYPE_RSA_KEY_PAIR, + PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT, + PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256), 2048, &key_id)); + TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, &pk_ctx), 0); + TEST_EQUAL(mbedtls_pk_encrypt(&pk_ctx, in_buf, sizeof(in_buf), + out_buf, &out_buf_len, sizeof(out_buf), + mbedtls_test_rnd_std_rand, NULL), + MBEDTLS_ERR_RSA_INVALID_PADDING); + psa_destroy_key(key_id); +#endif /* MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_MD_CAN_SHA256 && MBEDTLS_PKCS1_V21*/ +#endif /* MBEDTLS_RSA_C && PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE */ + +exit: + mbedtls_pk_free(&pk_ctx); + psa_destroy_key(key_id); + PSA_DONE(); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_CLIENT*/ +void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, + int key_bits_arg, int key_usage_arg, + int key_alg_arg) +{ + psa_key_type_t key_type = key_type_arg; + psa_key_type_t pub_key_type; + size_t key_bits = key_bits_arg; + psa_key_usage_t key_usage = key_usage_arg; + psa_algorithm_t key_alg = key_alg_arg; + mbedtls_pk_context pk_ctx, pk_ctx2; + mbedtls_svc_key_id_t priv_key_id = MBEDTLS_SVC_KEY_ID_INIT; + mbedtls_svc_key_id_t pub_key_id = MBEDTLS_SVC_KEY_ID_INIT; + unsigned char *in_buf = NULL; + size_t in_buf_len = MBEDTLS_MD_MAX_SIZE; + unsigned char out_buf[MBEDTLS_PK_SIGNATURE_MAX_SIZE]; + unsigned char out_buf2[MBEDTLS_PK_SIGNATURE_MAX_SIZE]; + size_t out_buf_len, out_buf2_len; + + /* Get the MD type to be used for the tests below from the provided key policy. */ + mbedtls_md_type_t md_for_test = MBEDTLS_MD_SHA256; /* Default */ + if ((PSA_ALG_GET_HASH(key_alg) != 0) && + (PSA_ALG_GET_HASH(key_alg) != PSA_ALG_ANY_HASH)) { + md_for_test = mbedtls_md_type_from_psa_alg(key_alg); + } + + in_buf_len = mbedtls_md_get_size_from_type(md_for_test); + TEST_CALLOC(in_buf, in_buf_len); + memset(in_buf, 0x1, in_buf_len); + + mbedtls_pk_init(&pk_ctx); + mbedtls_pk_init(&pk_ctx2); + PSA_INIT(); + + /* Generate a private key in PSA and create a PK context from it. */ + PSA_ASSERT(pk_psa_import_key(priv_key_data->x, priv_key_data->len, + key_type, key_usage, key_alg, key_bits, &priv_key_id)); + TEST_EQUAL(mbedtls_pk_copy_from_psa(priv_key_id, &pk_ctx), 0); + + /* Starting from the private key above, create another PSA slot for the public + * one and create a new PK context from it. */ + if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type)) { + pub_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_KEY_TYPE_ECC_GET_FAMILY(key_type)); + } else if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) { + pub_key_type = PSA_KEY_TYPE_RSA_PUBLIC_KEY; + } else { + TEST_FAIL("Key type can only be EC or RSA key pair"); + } + + /* Generate a 2nd PK contex using only the public key derived from its private + * counterpart generated above. */ + pub_key_id = pk_psa_pub_key_from_priv(priv_key_id, pub_key_type, key_usage, key_alg, key_bits); + TEST_EQUAL(mbedtls_pk_copy_from_psa(pub_key_id, &pk_ctx2), 0); + + /* Test sign/verify with the following parttern: + * - Sign using the PK context generated from the private key. + * - Verify from the same PK context used for signature. + * - Verify with the PK context generated using public key. + */ + if ((PSA_ALG_IS_RSA_OAEP(key_alg) || PSA_ALG_IS_RSA_PSS(key_alg))) { + mbedtls_pk_rsassa_pss_options pss_opt = { + .mgf1_hash_id = md_for_test, + .expected_salt_len = MBEDTLS_RSA_SALT_LEN_ANY, + }; + + TEST_EQUAL(mbedtls_pk_sign_ext(MBEDTLS_PK_RSASSA_PSS, &pk_ctx, md_for_test, + in_buf, in_buf_len, + out_buf, sizeof(out_buf), &out_buf_len, + mbedtls_test_rnd_std_rand, NULL), 0); + TEST_EQUAL(mbedtls_pk_verify_ext(MBEDTLS_PK_RSASSA_PSS, &pss_opt, + &pk_ctx, md_for_test, in_buf, in_buf_len, + out_buf, out_buf_len), 0); + TEST_EQUAL(mbedtls_pk_verify_ext(MBEDTLS_PK_RSASSA_PSS, &pss_opt, + &pk_ctx2, md_for_test, in_buf, in_buf_len, + out_buf, out_buf_len), 0); + } else { + TEST_EQUAL(mbedtls_pk_sign(&pk_ctx, md_for_test, in_buf, in_buf_len, + out_buf, sizeof(out_buf), &out_buf_len, + mbedtls_test_rnd_std_rand, NULL), 0); + TEST_EQUAL(mbedtls_pk_verify(&pk_ctx, md_for_test, in_buf, in_buf_len, + out_buf, out_buf_len), 0); + TEST_EQUAL(mbedtls_pk_verify(&pk_ctx2, md_for_test, in_buf, in_buf_len, + out_buf, out_buf_len), 0); + } + + int test_encryption = 0; + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + test_encryption = (PSA_ALG_IS_RSA_PKCS1V15_SIGN(key_alg) || + (key_alg == PSA_ALG_RSA_PKCS1V15_CRYPT)); +#else + test_encryption = ((PSA_ALG_GET_HASH(key_alg) != 0) && + (PSA_ALG_GET_HASH(key_alg) != PSA_ALG_ANY_HASH)); +#endif + + /* In case of RSA key pair try also encryption/decryption. */ + if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) { + if (test_encryption) { + /* Encrypt with the 2nd PK context (public key only). */ + TEST_EQUAL(mbedtls_pk_encrypt(&pk_ctx2, in_buf, in_buf_len, + out_buf, &out_buf_len, sizeof(out_buf), + mbedtls_test_rnd_std_rand, NULL), 0); + + /* Decrypt with 1st PK context and compare with original data. */ + TEST_EQUAL(mbedtls_pk_decrypt(&pk_ctx, out_buf, out_buf_len, + out_buf2, &out_buf2_len, sizeof(out_buf2), + mbedtls_test_rnd_std_rand, NULL), 0); + TEST_MEMORY_COMPARE(in_buf, in_buf_len, out_buf2, out_buf2_len); + } + } + +exit: + mbedtls_free(in_buf); + mbedtls_pk_free(&pk_ctx); + mbedtls_pk_free(&pk_ctx2); + psa_destroy_key(priv_key_id); + psa_destroy_key(pub_key_id); + PSA_DONE(); +} +/* END_CASE */ From 851f190da784d8740a7353e6d001e414634e459e Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 8 Feb 2024 09:35:05 +0100 Subject: [PATCH 052/211] pk: move ECC setters to a separate file - These functions are used both in pkparse.c for key parsing as well as pk.c for managing copy_from_psa(). As as consequence they should belong to pk.c, but that would make that module messier, so that's why a new separate module is added. - Their guard can be changed from PKPARSE_C to PK_C. Signed-off-by: Valerio Setti --- library/CMakeLists.txt | 1 + library/Makefile | 1 + library/pk_ecc.c | 304 +++++++++++++++++++++++++++++++++++++++++ library/pkparse.c | 294 --------------------------------------- 4 files changed, 306 insertions(+), 294 deletions(-) create mode 100644 library/pk_ecc.c diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 47ecf17be6..835604ff14 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -56,6 +56,7 @@ set(src_crypto padlock.c pem.c pk.c + pk_ecc.c pk_wrap.c pkcs12.c pkcs5.c diff --git a/library/Makefile b/library/Makefile index d11a98df01..bef433505a 100644 --- a/library/Makefile +++ b/library/Makefile @@ -125,6 +125,7 @@ OBJS_CRYPTO= \ padlock.o \ pem.o \ pk.o \ + pk_ecc.o \ pk_wrap.o \ pkcs12.o \ pkcs5.o \ diff --git a/library/pk_ecc.c b/library/pk_ecc.c new file mode 100644 index 0000000000..a103f46e8a --- /dev/null +++ b/library/pk_ecc.c @@ -0,0 +1,304 @@ +#include "common.h" + +#include "mbedtls/pk.h" +#include "mbedtls/error.h" +#include "mbedtls/ecp.h" +#include "pk_internal.h" + +/*********************************************************************** + * + * ECC setters + * + * 1. This is an abstraction layer around MBEDTLS_PK_USE_PSA_EC_DATA: + * this macro will not appear outside this section. + * 2. All inputs are raw (no metadata). + * + **********************************************************************/ + +#if defined(MBEDTLS_PK_C) && defined(MBEDTLS_PK_HAVE_ECC_KEYS) + +/* + * Set the group used by this key. + * + * [in/out] pk: in: must have been pk_setup() to an ECC type + * out: will have group (curve) information set + * [in] grp_in: a supported group ID (not NONE) + */ +int mbedtls_pk_ecc_set_group(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id) +{ +#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) + size_t ec_bits; + psa_ecc_family_t ec_family = mbedtls_ecc_group_to_psa(grp_id, &ec_bits); + + /* group may already be initialized; if so, make sure IDs match */ + if ((pk->ec_family != 0 && pk->ec_family != ec_family) || + (pk->ec_bits != 0 && pk->ec_bits != ec_bits)) { + return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; + } + + /* set group */ + pk->ec_family = ec_family; + pk->ec_bits = ec_bits; + + return 0; +#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ + mbedtls_ecp_keypair *ecp = mbedtls_pk_ec_rw(*pk); + + /* grp may already be initialized; if so, make sure IDs match */ + if (mbedtls_pk_ec_ro(*pk)->grp.id != MBEDTLS_ECP_DP_NONE && + mbedtls_pk_ec_ro(*pk)->grp.id != grp_id) { + return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; + } + + /* set group */ + return mbedtls_ecp_group_load(&(ecp->grp), grp_id); +#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ +} + +/* + * Set the private key material + * + * [in/out] pk: in: must have the group set already, see mbedtls_pk_ecc_set_group(). + * out: will have the private key set. + * [in] key, key_len: the raw private key (no ASN.1 wrapping). + */ +int mbedtls_pk_ecc_set_key(mbedtls_pk_context *pk, unsigned char *key, size_t key_len) +{ +#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_usage_t flags; + psa_status_t status; + + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(pk->ec_family)); + if (pk->ec_family == PSA_ECC_FAMILY_MONTGOMERY) { + /* Do not set algorithm here because Montgomery keys cannot do ECDSA and + * the PK module cannot do ECDH. When the key will be used in TLS for + * ECDH, it will be exported and then re-imported with proper flags + * and algorithm. */ + flags = PSA_KEY_USAGE_EXPORT; + } else { + psa_set_key_algorithm(&attributes, + MBEDTLS_PK_PSA_ALG_ECDSA_MAYBE_DET(PSA_ALG_ANY_HASH)); + flags = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | + PSA_KEY_USAGE_EXPORT; + } + psa_set_key_usage_flags(&attributes, flags); + + status = psa_import_key(&attributes, key, key_len, &pk->priv_id); + return psa_pk_status_to_mbedtls(status); + +#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ + + mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk); + int ret = mbedtls_ecp_read_key(eck->grp.id, eck, key, key_len); + if (ret != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); + } + return 0; +#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ +} + +/* + * Derive a public key from its private counterpart. + * Computationally intensive, only use when public key is not available. + * + * [in/out] pk: in: must have the private key set, see mbedtls_pk_ecc_set_key(). + * out: will have the public key set. + * [in] prv, prv_len: the raw private key (see note below). + * [in] f_rng, p_rng: RNG function and context. + * + * Note: the private key information is always available from pk, + * however for convenience the serialized version is also passed, + * as it's available at each calling site, and useful in some configs + * (as otherwise we would have to re-serialize it from the pk context). + * + * There are three implementations of this function: + * 1. MBEDTLS_PK_USE_PSA_EC_DATA, + * 2. MBEDTLS_USE_PSA_CRYPTO but not MBEDTLS_PK_USE_PSA_EC_DATA, + * 3. not MBEDTLS_USE_PSA_CRYPTO. + */ +int mbedtls_pk_ecc_set_pubkey_from_prv(mbedtls_pk_context *pk, + const unsigned char *prv, size_t prv_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) +{ +#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) + + (void) f_rng; + (void) p_rng; + (void) prv; + (void) prv_len; + psa_status_t status; + + status = psa_export_public_key(pk->priv_id, pk->pub_raw, sizeof(pk->pub_raw), + &pk->pub_raw_len); + return psa_pk_status_to_mbedtls(status); + +#elif defined(MBEDTLS_USE_PSA_CRYPTO) /* && !MBEDTLS_PK_USE_PSA_EC_DATA */ + + (void) f_rng; + (void) p_rng; + psa_status_t status; + + mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx; + size_t curve_bits; + psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(eck->grp.id, &curve_bits); + + /* Import private key into PSA, from serialized input */ + mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve)); + psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT); + status = psa_import_key(&key_attr, prv, prv_len, &key_id); + if (status != PSA_SUCCESS) { + return psa_pk_status_to_mbedtls(status); + } + + /* Export public key from PSA */ + unsigned char pub[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH]; + size_t pub_len; + status = psa_export_public_key(key_id, pub, sizeof(pub), &pub_len); + psa_status_t destruction_status = psa_destroy_key(key_id); + if (status != PSA_SUCCESS) { + return psa_pk_status_to_mbedtls(status); + } else if (destruction_status != PSA_SUCCESS) { + return psa_pk_status_to_mbedtls(destruction_status); + } + + /* Load serialized public key into ecp_keypair structure */ + return mbedtls_ecp_point_read_binary(&eck->grp, &eck->Q, pub, pub_len); + +#else /* MBEDTLS_USE_PSA_CRYPTO */ + + (void) prv; + (void) prv_len; + + mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx; + return mbedtls_ecp_mul(&eck->grp, &eck->Q, &eck->d, &eck->grp.G, f_rng, p_rng); + +#endif /* MBEDTLS_USE_PSA_CRYPTO */ +} + +#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) +/* + * Set the public key: fallback using ECP_LIGHT in the USE_PSA_EC_DATA case. + * + * Normally, when MBEDTLS_PK_USE_PSA_EC_DATA is enabled, we only use PSA + * functions to handle keys. However, currently psa_import_key() does not + * support compressed points. In case that support was explicitly requested, + * this fallback uses ECP functions to get the job done. This is the reason + * why MBEDTLS_PK_PARSE_EC_COMPRESSED auto-enables MBEDTLS_ECP_LIGHT. + * + * [in/out] pk: in: must have the group set, see mbedtls_pk_ecc_set_group(). + * out: will have the public key set. + * [in] pub, pub_len: the public key as an ECPoint, + * in any format supported by ECP. + * + * Return: + * - 0 on success; + * - MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the format is potentially valid + * but not supported; + * - another error code otherwise. + */ +static int pk_ecc_set_pubkey_psa_ecp_fallback(mbedtls_pk_context *pk, + const unsigned char *pub, + size_t pub_len) +{ +#if !defined(MBEDTLS_PK_PARSE_EC_COMPRESSED) + (void) pk; + (void) pub; + (void) pub_len; + return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; +#else /* MBEDTLS_PK_PARSE_EC_COMPRESSED */ + mbedtls_ecp_keypair ecp_key; + mbedtls_ecp_group_id ecp_group_id; + int ret; + + ecp_group_id = mbedtls_ecc_group_from_psa(pk->ec_family, pk->ec_bits); + + mbedtls_ecp_keypair_init(&ecp_key); + ret = mbedtls_ecp_group_load(&(ecp_key.grp), ecp_group_id); + if (ret != 0) { + goto exit; + } + ret = mbedtls_ecp_point_read_binary(&(ecp_key.grp), &ecp_key.Q, + pub, pub_len); + if (ret != 0) { + goto exit; + } + ret = mbedtls_ecp_point_write_binary(&(ecp_key.grp), &ecp_key.Q, + MBEDTLS_ECP_PF_UNCOMPRESSED, + &pk->pub_raw_len, pk->pub_raw, + sizeof(pk->pub_raw)); + +exit: + mbedtls_ecp_keypair_free(&ecp_key); + return ret; +#endif /* MBEDTLS_PK_PARSE_EC_COMPRESSED */ +} +#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ + +/* + * Set the public key. + * + * [in/out] pk: in: must have its group set, see mbedtls_pk_ecc_set_group(). + * out: will have the public key set. + * [in] pub, pub_len: the raw public key (an ECPoint). + * + * Return: + * - 0 on success; + * - MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the format is potentially valid + * but not supported; + * - another error code otherwise. + */ +int mbedtls_pk_ecc_set_pubkey(mbedtls_pk_context *pk, const unsigned char *pub, size_t pub_len) +{ +#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) + + /* Load the key */ + if (!PSA_ECC_FAMILY_IS_WEIERSTRASS(pk->ec_family) || *pub == 0x04) { + /* Format directly supported by PSA: + * - non-Weierstrass curves that only have one format; + * - uncompressed format for Weierstrass curves. */ + if (pub_len > sizeof(pk->pub_raw)) { + return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; + } + memcpy(pk->pub_raw, pub, pub_len); + pk->pub_raw_len = pub_len; + } else { + /* Other format, try the fallback */ + int ret = pk_ecc_set_pubkey_psa_ecp_fallback(pk, pub, pub_len); + if (ret != 0) { + return ret; + } + } + + /* Validate the key by trying to import it */ + mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_attributes_t key_attrs = PSA_KEY_ATTRIBUTES_INIT; + + psa_set_key_usage_flags(&key_attrs, 0); + psa_set_key_type(&key_attrs, PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family)); + psa_set_key_bits(&key_attrs, pk->ec_bits); + + if ((psa_import_key(&key_attrs, pk->pub_raw, pk->pub_raw_len, + &key_id) != PSA_SUCCESS) || + (psa_destroy_key(key_id) != PSA_SUCCESS)) { + return MBEDTLS_ERR_PK_INVALID_PUBKEY; + } + + return 0; + +#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ + + int ret; + mbedtls_ecp_keypair *ec_key = (mbedtls_ecp_keypair *) pk->pk_ctx; + ret = mbedtls_ecp_point_read_binary(&ec_key->grp, &ec_key->Q, pub, pub_len); + if (ret != 0) { + return ret; + } + return mbedtls_ecp_check_pubkey(&ec_key->grp, &ec_key->Q); + +#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ +} + +#endif /* MBEDTLS_PK_C && MBEDTLS_PK_HAVE_ECC_KEYS */ diff --git a/library/pkparse.c b/library/pkparse.c index e4a812a634..4f6ee13986 100644 --- a/library/pkparse.c +++ b/library/pkparse.c @@ -44,300 +44,6 @@ #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) -/*********************************************************************** - * - * ECC setters - * - * 1. This is an abstraction layer around MBEDTLS_PK_USE_PSA_EC_DATA: - * this macro will not appear outside this section. - * 2. All inputs are raw: no metadata, no ASN.1 until the next section. - * - **********************************************************************/ - -/* - * Set the group used by this key. - * - * [in/out] pk: in: must have been pk_setup() to an ECC type - * out: will have group (curve) information set - * [in] grp_in: a supported group ID (not NONE) - */ -int mbedtls_pk_ecc_set_group(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id) -{ -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - size_t ec_bits; - psa_ecc_family_t ec_family = mbedtls_ecc_group_to_psa(grp_id, &ec_bits); - - /* group may already be initialized; if so, make sure IDs match */ - if ((pk->ec_family != 0 && pk->ec_family != ec_family) || - (pk->ec_bits != 0 && pk->ec_bits != ec_bits)) { - return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; - } - - /* set group */ - pk->ec_family = ec_family; - pk->ec_bits = ec_bits; - - return 0; -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ - mbedtls_ecp_keypair *ecp = mbedtls_pk_ec_rw(*pk); - - /* grp may already be initialized; if so, make sure IDs match */ - if (mbedtls_pk_ec_ro(*pk)->grp.id != MBEDTLS_ECP_DP_NONE && - mbedtls_pk_ec_ro(*pk)->grp.id != grp_id) { - return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; - } - - /* set group */ - return mbedtls_ecp_group_load(&(ecp->grp), grp_id); -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ -} - -/* - * Set the private key material - * - * [in/out] pk: in: must have the group set already, see mbedtls_pk_ecc_set_group(). - * out: will have the private key set. - * [in] key, key_len: the raw private key (no ASN.1 wrapping). - */ -int mbedtls_pk_ecc_set_key(mbedtls_pk_context *pk, unsigned char *key, size_t key_len) -{ -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_usage_t flags; - psa_status_t status; - - psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(pk->ec_family)); - if (pk->ec_family == PSA_ECC_FAMILY_MONTGOMERY) { - /* Do not set algorithm here because Montgomery keys cannot do ECDSA and - * the PK module cannot do ECDH. When the key will be used in TLS for - * ECDH, it will be exported and then re-imported with proper flags - * and algorithm. */ - flags = PSA_KEY_USAGE_EXPORT; - } else { - psa_set_key_algorithm(&attributes, - MBEDTLS_PK_PSA_ALG_ECDSA_MAYBE_DET(PSA_ALG_ANY_HASH)); - flags = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | - PSA_KEY_USAGE_EXPORT; - } - psa_set_key_usage_flags(&attributes, flags); - - status = psa_import_key(&attributes, key, key_len, &pk->priv_id); - return psa_pk_status_to_mbedtls(status); - -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ - - mbedtls_ecp_keypair *eck = mbedtls_pk_ec_rw(*pk); - int ret = mbedtls_ecp_read_key(eck->grp.id, eck, key, key_len); - if (ret != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); - } - return 0; -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ -} - -/* - * Derive a public key from its private counterpart. - * Computationally intensive, only use when public key is not available. - * - * [in/out] pk: in: must have the private key set, see mbedtls_pk_ecc_set_key(). - * out: will have the public key set. - * [in] prv, prv_len: the raw private key (see note below). - * [in] f_rng, p_rng: RNG function and context. - * - * Note: the private key information is always available from pk, - * however for convenience the serialized version is also passed, - * as it's available at each calling site, and useful in some configs - * (as otherwise we would have to re-serialize it from the pk context). - * - * There are three implementations of this function: - * 1. MBEDTLS_PK_USE_PSA_EC_DATA, - * 2. MBEDTLS_USE_PSA_CRYPTO but not MBEDTLS_PK_USE_PSA_EC_DATA, - * 3. not MBEDTLS_USE_PSA_CRYPTO. - */ -int mbedtls_pk_ecc_set_pubkey_from_prv(mbedtls_pk_context *pk, - const unsigned char *prv, size_t prv_len, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) -{ -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - - (void) f_rng; - (void) p_rng; - (void) prv; - (void) prv_len; - psa_status_t status; - - status = psa_export_public_key(pk->priv_id, pk->pub_raw, sizeof(pk->pub_raw), - &pk->pub_raw_len); - return psa_pk_status_to_mbedtls(status); - -#elif defined(MBEDTLS_USE_PSA_CRYPTO) /* && !MBEDTLS_PK_USE_PSA_EC_DATA */ - - (void) f_rng; - (void) p_rng; - psa_status_t status; - - mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx; - size_t curve_bits; - psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(eck->grp.id, &curve_bits); - - /* Import private key into PSA, from serialized input */ - mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; - psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; - psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_KEY_PAIR(curve)); - psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_EXPORT); - status = psa_import_key(&key_attr, prv, prv_len, &key_id); - if (status != PSA_SUCCESS) { - return psa_pk_status_to_mbedtls(status); - } - - /* Export public key from PSA */ - unsigned char pub[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH]; - size_t pub_len; - status = psa_export_public_key(key_id, pub, sizeof(pub), &pub_len); - psa_status_t destruction_status = psa_destroy_key(key_id); - if (status != PSA_SUCCESS) { - return psa_pk_status_to_mbedtls(status); - } else if (destruction_status != PSA_SUCCESS) { - return psa_pk_status_to_mbedtls(destruction_status); - } - - /* Load serialized public key into ecp_keypair structure */ - return mbedtls_ecp_point_read_binary(&eck->grp, &eck->Q, pub, pub_len); - -#else /* MBEDTLS_USE_PSA_CRYPTO */ - - (void) prv; - (void) prv_len; - - mbedtls_ecp_keypair *eck = (mbedtls_ecp_keypair *) pk->pk_ctx; - return mbedtls_ecp_mul(&eck->grp, &eck->Q, &eck->d, &eck->grp.G, f_rng, p_rng); - -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -} - -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) -/* - * Set the public key: fallback using ECP_LIGHT in the USE_PSA_EC_DATA case. - * - * Normally, when MBEDTLS_PK_USE_PSA_EC_DATA is enabled, we only use PSA - * functions to handle keys. However, currently psa_import_key() does not - * support compressed points. In case that support was explicitly requested, - * this fallback uses ECP functions to get the job done. This is the reason - * why MBEDTLS_PK_PARSE_EC_COMPRESSED auto-enables MBEDTLS_ECP_LIGHT. - * - * [in/out] pk: in: must have the group set, see mbedtls_pk_ecc_set_group(). - * out: will have the public key set. - * [in] pub, pub_len: the public key as an ECPoint, - * in any format supported by ECP. - * - * Return: - * - 0 on success; - * - MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the format is potentially valid - * but not supported; - * - another error code otherwise. - */ -static int pk_ecc_set_pubkey_psa_ecp_fallback(mbedtls_pk_context *pk, - const unsigned char *pub, - size_t pub_len) -{ -#if !defined(MBEDTLS_PK_PARSE_EC_COMPRESSED) - (void) pk; - (void) pub; - (void) pub_len; - return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; -#else /* MBEDTLS_PK_PARSE_EC_COMPRESSED */ - mbedtls_ecp_keypair ecp_key; - mbedtls_ecp_group_id ecp_group_id; - int ret; - - ecp_group_id = mbedtls_ecc_group_from_psa(pk->ec_family, pk->ec_bits); - - mbedtls_ecp_keypair_init(&ecp_key); - ret = mbedtls_ecp_group_load(&(ecp_key.grp), ecp_group_id); - if (ret != 0) { - goto exit; - } - ret = mbedtls_ecp_point_read_binary(&(ecp_key.grp), &ecp_key.Q, - pub, pub_len); - if (ret != 0) { - goto exit; - } - ret = mbedtls_ecp_point_write_binary(&(ecp_key.grp), &ecp_key.Q, - MBEDTLS_ECP_PF_UNCOMPRESSED, - &pk->pub_raw_len, pk->pub_raw, - sizeof(pk->pub_raw)); - -exit: - mbedtls_ecp_keypair_free(&ecp_key); - return ret; -#endif /* MBEDTLS_PK_PARSE_EC_COMPRESSED */ -} -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ - -/* - * Set the public key. - * - * [in/out] pk: in: must have its group set, see mbedtls_pk_ecc_set_group(). - * out: will have the public key set. - * [in] pub, pub_len: the raw public key (an ECPoint). - * - * Return: - * - 0 on success; - * - MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the format is potentially valid - * but not supported; - * - another error code otherwise. - */ -int mbedtls_pk_ecc_set_pubkey(mbedtls_pk_context *pk, const unsigned char *pub, size_t pub_len) -{ -#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - - /* Load the key */ - if (!PSA_ECC_FAMILY_IS_WEIERSTRASS(pk->ec_family) || *pub == 0x04) { - /* Format directly supported by PSA: - * - non-Weierstrass curves that only have one format; - * - uncompressed format for Weierstrass curves. */ - if (pub_len > sizeof(pk->pub_raw)) { - return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; - } - memcpy(pk->pub_raw, pub, pub_len); - pk->pub_raw_len = pub_len; - } else { - /* Other format, try the fallback */ - int ret = pk_ecc_set_pubkey_psa_ecp_fallback(pk, pub, pub_len); - if (ret != 0) { - return ret; - } - } - - /* Validate the key by trying to import it */ - mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; - psa_key_attributes_t key_attrs = PSA_KEY_ATTRIBUTES_INIT; - - psa_set_key_usage_flags(&key_attrs, 0); - psa_set_key_type(&key_attrs, PSA_KEY_TYPE_ECC_PUBLIC_KEY(pk->ec_family)); - psa_set_key_bits(&key_attrs, pk->ec_bits); - - if ((psa_import_key(&key_attrs, pk->pub_raw, pk->pub_raw_len, - &key_id) != PSA_SUCCESS) || - (psa_destroy_key(key_id) != PSA_SUCCESS)) { - return MBEDTLS_ERR_PK_INVALID_PUBKEY; - } - - return 0; - -#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ - - int ret; - mbedtls_ecp_keypair *ec_key = (mbedtls_ecp_keypair *) pk->pk_ctx; - ret = mbedtls_ecp_point_read_binary(&ec_key->grp, &ec_key->Q, pub, pub_len); - if (ret != 0) { - return ret; - } - return mbedtls_ecp_check_pubkey(&ec_key->grp, &ec_key->Q); - -#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ -} - /*********************************************************************** * * Low-level ECC parsing: optional support for SpecifiedECDomain From a41654d5b125bbd2d0e02c62d4f95fdcadcbec33 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 8 Feb 2024 10:33:11 +0100 Subject: [PATCH 053/211] all.sh: add test component based on full config without PK_[PARSE|WRITE]_C Signed-off-by: Valerio Setti --- tests/scripts/all.sh | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index fcb465e0e4..e101bb657b 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -1552,6 +1552,28 @@ component_test_sw_inet_pton () { make test } +component_full_no_pkparse_pkwrite() { + msg "build: full without pkparse and pkwrite" + + scripts/config.py crypto_full + scripts/config.py unset MBEDTLS_PK_PARSE_C + scripts/config.py unset MBEDTLS_PK_WRITE_C + + # Disable features that re-enable PK_PARSE_C + scripts/config.py unset MBEDTLS_RSA_C + scripts/config.py -f "$CRYPTO_CONFIG_H" unset-all PSA_WANT_ALG_RSA + scripts/config.py -f "$CRYPTO_CONFIG_H" unset-all PSA_WANT_KEY_TYPE_RSA + + make CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" + + # Ensure that PK_[PARSE|WRITE]_C were not re-enabled accidentally (additive config). + not grep mbedtls_pk_parse_key library/pkparse.o + not grep mbedtls_pk_write_key_der library/pkwrite.o + + msg "test: full without pkparse and pkwrite" + make test +} + component_test_crypto_full_md_light_only () { msg "build: crypto_full with only the light subset of MD" scripts/config.py crypto_full From 01ba66d56ecba1bd4df9d47bb6b5a73ceb5a084c Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 9 Feb 2024 11:35:42 +0100 Subject: [PATCH 054/211] pk: replace CRYPTO_CLIENT guards with CRYPTO_C Signed-off-by: Valerio Setti --- include/mbedtls/pk.h | 4 ++-- library/pk.c | 6 +++--- tests/suites/test_suite_pk.function | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h index 6447a15e8d..20be7e6737 100644 --- a/include/mbedtls/pk.h +++ b/include/mbedtls/pk.h @@ -390,7 +390,7 @@ int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx, const mbedtls_svc_key_id_t key); #endif /* MBEDTLS_USE_PSA_CRYPTO */ -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) +#if defined(MBEDTLS_PSA_CRYPTO_C) /** * \brief Create a PK context starting from a key stored in PSA. * This key: @@ -429,7 +429,7 @@ int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx, * parameters are not correct. */ int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk); -#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ +#endif /* MBEDTLS_PSA_CRYPTO_C */ #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) /** diff --git a/library/pk.c b/library/pk.c index ffe350efea..2c0ef6873a 100644 --- a/library/pk.c +++ b/library/pk.c @@ -27,7 +27,7 @@ #include "mbedtls/ecdsa.h" #endif -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) +#if defined(MBEDTLS_PSA_CRYPTO_C) #include "psa_util_internal.h" #include "mbedtls/psa_util.h" #endif @@ -1378,7 +1378,7 @@ mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx) return ctx->pk_info->type; } -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) +#if defined(MBEDTLS_PSA_CRYPTO_C) int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk) { psa_status_t status; @@ -1502,6 +1502,6 @@ exit: return ret; } -#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ +#endif /* MBEDTLS_PSA_CRYPTO_C */ #endif /* MBEDTLS_PK_C */ diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 3710e3df43..1521008e1f 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -426,7 +426,7 @@ exit: } #endif -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) +#if defined(MBEDTLS_PSA_CRYPTO_C) mbedtls_svc_key_id_t pk_psa_pub_key_from_priv(mbedtls_svc_key_id_t priv_id, psa_key_type_t type, psa_key_usage_t usage, psa_algorithm_t alg, size_t bits) @@ -515,7 +515,7 @@ mbedtls_svc_key_id_t pk_psa_genkey_rsa(void) return key; } -#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ +#endif /* MBEDTLS_PSA_CRYPTO_C */ /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -2245,7 +2245,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_CLIENT*/ +/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C*/ void pk_copy_from_psa_fail(void) { mbedtls_pk_context pk_ctx; @@ -2323,7 +2323,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_CLIENT*/ +/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C*/ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, int key_bits_arg, int key_usage_arg, int key_alg_arg) From 1346075cfd21c27571e642121ee740e65a2e5d5e Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 14 Feb 2024 08:14:27 +0100 Subject: [PATCH 055/211] pk_ecc: fix documentation Signed-off-by: Valerio Setti --- library/pk_ecc.c | 63 +++++-------------------------------------- library/pk_internal.h | 49 +++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 56 deletions(-) diff --git a/library/pk_ecc.c b/library/pk_ecc.c index a103f46e8a..86218fffc8 100644 --- a/library/pk_ecc.c +++ b/library/pk_ecc.c @@ -1,3 +1,10 @@ +/* + * ECC setters for PK. + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + #include "common.h" #include "mbedtls/pk.h" @@ -5,25 +12,8 @@ #include "mbedtls/ecp.h" #include "pk_internal.h" -/*********************************************************************** - * - * ECC setters - * - * 1. This is an abstraction layer around MBEDTLS_PK_USE_PSA_EC_DATA: - * this macro will not appear outside this section. - * 2. All inputs are raw (no metadata). - * - **********************************************************************/ - #if defined(MBEDTLS_PK_C) && defined(MBEDTLS_PK_HAVE_ECC_KEYS) -/* - * Set the group used by this key. - * - * [in/out] pk: in: must have been pk_setup() to an ECC type - * out: will have group (curve) information set - * [in] grp_in: a supported group ID (not NONE) - */ int mbedtls_pk_ecc_set_group(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id) { #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) @@ -55,13 +45,6 @@ int mbedtls_pk_ecc_set_group(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ } -/* - * Set the private key material - * - * [in/out] pk: in: must have the group set already, see mbedtls_pk_ecc_set_group(). - * out: will have the private key set. - * [in] key, key_len: the raw private key (no ASN.1 wrapping). - */ int mbedtls_pk_ecc_set_key(mbedtls_pk_context *pk, unsigned char *key, size_t key_len) { #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) @@ -98,25 +81,6 @@ int mbedtls_pk_ecc_set_key(mbedtls_pk_context *pk, unsigned char *key, size_t ke #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ } -/* - * Derive a public key from its private counterpart. - * Computationally intensive, only use when public key is not available. - * - * [in/out] pk: in: must have the private key set, see mbedtls_pk_ecc_set_key(). - * out: will have the public key set. - * [in] prv, prv_len: the raw private key (see note below). - * [in] f_rng, p_rng: RNG function and context. - * - * Note: the private key information is always available from pk, - * however for convenience the serialized version is also passed, - * as it's available at each calling site, and useful in some configs - * (as otherwise we would have to re-serialize it from the pk context). - * - * There are three implementations of this function: - * 1. MBEDTLS_PK_USE_PSA_EC_DATA, - * 2. MBEDTLS_USE_PSA_CRYPTO but not MBEDTLS_PK_USE_PSA_EC_DATA, - * 3. not MBEDTLS_USE_PSA_CRYPTO. - */ int mbedtls_pk_ecc_set_pubkey_from_prv(mbedtls_pk_context *pk, const unsigned char *prv, size_t prv_len, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) @@ -237,19 +201,6 @@ exit: } #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ -/* - * Set the public key. - * - * [in/out] pk: in: must have its group set, see mbedtls_pk_ecc_set_group(). - * out: will have the public key set. - * [in] pub, pub_len: the raw public key (an ECPoint). - * - * Return: - * - 0 on success; - * - MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the format is potentially valid - * but not supported; - * - another error code otherwise. - */ int mbedtls_pk_ecc_set_pubkey(mbedtls_pk_context *pk, const unsigned char *pub, size_t pub_len) { #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) diff --git a/library/pk_internal.h b/library/pk_internal.h index a1a34ad1b6..e86a3a09d2 100644 --- a/library/pk_internal.h +++ b/library/pk_internal.h @@ -128,9 +128,58 @@ static inline int mbedtls_pk_is_rfc8410(const mbedtls_pk_context *pk) return MBEDTLS_PK_IS_RFC8410_GROUP_ID(id); } +/* + * Set the group used by this key. + * + * [in/out] pk: in: must have been pk_setup() to an ECC type + * out: will have group (curve) information set + * [in] grp_in: a supported group ID (not NONE) + */ int mbedtls_pk_ecc_set_group(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id); + +/* + * Set the private key material + * + * [in/out] pk: in: must have the group set already, see mbedtls_pk_ecc_set_group(). + * out: will have the private key set. + * [in] key, key_len: the raw private key (no ASN.1 wrapping). + */ int mbedtls_pk_ecc_set_key(mbedtls_pk_context *pk, unsigned char *key, size_t key_len); + +/* + * Set the public key. + * + * [in/out] pk: in: must have its group set, see mbedtls_pk_ecc_set_group(). + * out: will have the public key set. + * [in] pub, pub_len: the raw public key (an ECPoint). + * + * Return: + * - 0 on success; + * - MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the format is potentially valid + * but not supported; + * - another error code otherwise. + */ int mbedtls_pk_ecc_set_pubkey(mbedtls_pk_context *pk, const unsigned char *pub, size_t pub_len); + +/* + * Derive a public key from its private counterpart. + * Computationally intensive, only use when public key is not available. + * + * [in/out] pk: in: must have the private key set, see mbedtls_pk_ecc_set_key(). + * out: will have the public key set. + * [in] prv, prv_len: the raw private key (see note below). + * [in] f_rng, p_rng: RNG function and context. + * + * Note: the private key information is always available from pk, + * however for convenience the serialized version is also passed, + * as it's available at each calling site, and useful in some configs + * (as otherwise we would have to re-serialize it from the pk context). + * + * There are three implementations of this function: + * 1. MBEDTLS_PK_USE_PSA_EC_DATA, + * 2. MBEDTLS_USE_PSA_CRYPTO but not MBEDTLS_PK_USE_PSA_EC_DATA, + * 3. not MBEDTLS_USE_PSA_CRYPTO. + */ int mbedtls_pk_ecc_set_pubkey_from_prv(mbedtls_pk_context *pk, const unsigned char *prv, size_t prv_len, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); From 61532e9a6b92b5bbcbffaae1cf1c5170e799fe80 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 14 Feb 2024 08:17:09 +0100 Subject: [PATCH 056/211] test_suite_pk: fix typos Signed-off-by: Valerio Setti --- tests/suites/test_suite_pk.function | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 1521008e1f..43f9e4f482 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -2377,7 +2377,7 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, pub_key_id = pk_psa_pub_key_from_priv(priv_key_id, pub_key_type, key_usage, key_alg, key_bits); TEST_EQUAL(mbedtls_pk_copy_from_psa(pub_key_id, &pk_ctx2), 0); - /* Test sign/verify with the following parttern: + /* Test sign/verify with the following pattern: * - Sign using the PK context generated from the private key. * - Verify from the same PK context used for signature. * - Verify with the PK context generated using public key. From f9a6893b55001e9ed6ef0c1afd7b9d48eddd6f71 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Wed, 6 Mar 2024 13:49:57 +0000 Subject: [PATCH 057/211] Changelog: Added entry for ssl_session accessors. Signed-off-by: Minos Galanakis --- ChangeLog.d/add_ssl_session_accessors.txt | 6 ++++++ tests/suites/test_suite_ssl.data | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 ChangeLog.d/add_ssl_session_accessors.txt diff --git a/ChangeLog.d/add_ssl_session_accessors.txt b/ChangeLog.d/add_ssl_session_accessors.txt new file mode 100644 index 0000000000..516a3bf448 --- /dev/null +++ b/ChangeLog.d/add_ssl_session_accessors.txt @@ -0,0 +1,6 @@ +Features + * Add new accessors to expose the private session-id, + session-id length, and ciphersuite-id members of + `mbedtls_ssl_session` structure. + Add new accessor to expose the ciphersuite-id of + `mbedtls_ssl_ciphersuite_t` structure.Design ref: #8529 diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 3d73e7344a..80800ade0e 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -961,11 +961,11 @@ TLS 1.3: SRV: session serialization: Wrong config depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_SRV_C ssl_session_serialize_version_check:0:0:0:1:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_VERSION_TLS1_3 -Test Session id & Ciphersuite accesors TLS 1.2 +Test Session id & Ciphersuite accessors TLS 1.2 depends_on:MBEDTLS_SSL_PROTO_TLS1_2 ssl_session_id_accessors_check:MBEDTLS_SSL_VERSION_TLS1_2 -Test Session id & Ciphersuite accesors TLS 1.3 +Test Session id & Ciphersuite accessors TLS 1.3 depends_on:MBEDTLS_SSL_PROTO_TLS1_3 ssl_session_id_accessors_check:MBEDTLS_SSL_VERSION_TLS1_3 From 3a815cbd2f519232e58f690d27b9d987060ce71d Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 14 Feb 2024 09:54:18 +0100 Subject: [PATCH 058/211] all.sh: keep RSA_C enabled in component_full_no_pkparse_pkwrite() This is possible because after #8740 RSA_C no longer depends on PK to parse and write private/public keys. This commit also solves related issues that arose after this change in "pk.c" and "test_suite_pk". In particular now we can use rsa's module functions for parsing and writing keys without need to rely on pk_parse and pk_write functions. Signed-off-by: Valerio Setti --- library/pk.c | 2 +- tests/scripts/all.sh | 5 ----- tests/suites/test_suite_pk.function | 11 ++++++++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/library/pk.c b/library/pk.c index 2c0ef6873a..580fa0e34b 100644 --- a/library/pk.c +++ b/library/pk.c @@ -1021,7 +1021,7 @@ int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options, psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_algorithm_t psa_sig_alg = PSA_ALG_RSA_PSS_ANY_SALT(psa_md_alg); p = buf + sizeof(buf); - key_len = mbedtls_pk_write_pubkey(&p, buf, ctx); + key_len = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*ctx), buf, &p); if (key_len < 0) { return key_len; diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index e101bb657b..6f47a5e9af 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -1559,11 +1559,6 @@ component_full_no_pkparse_pkwrite() { scripts/config.py unset MBEDTLS_PK_PARSE_C scripts/config.py unset MBEDTLS_PK_WRITE_C - # Disable features that re-enable PK_PARSE_C - scripts/config.py unset MBEDTLS_RSA_C - scripts/config.py -f "$CRYPTO_CONFIG_H" unset-all PSA_WANT_ALG_RSA - scripts/config.py -f "$CRYPTO_CONFIG_H" unset-all PSA_WANT_KEY_TYPE_RSA - make CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" # Ensure that PK_[PARSE|WRITE]_C were not re-enabled accidentally (additive config). diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 43f9e4f482..2b3711009b 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -9,6 +9,7 @@ #include "mbedtls/ecp.h" #include "mbedtls/error.h" #include "mbedtls/rsa.h" +#include "rsa_internal.h" #include "pk_internal.h" #include @@ -1898,8 +1899,10 @@ void pk_psa_wrap_sign_ext(int pk_type, int key_bits, int key_pk_type, int md_alg 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)); + /* Export underlying public key for re-importing in a legacy context. + * Note: mbedtls_rsa_write_key() writes backwards in the data buffer. */ + pkey_start = pkey + sizeof(pkey); + ret = mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(pk), pkey, &pkey_start); TEST_ASSERT(ret >= 0); pkey_len = (size_t) ret; @@ -1924,7 +1927,9 @@ void pk_psa_wrap_sign_ext(int pk_type, int key_bits, int key_pk_type, int md_alg TEST_EQUAL(PSA_SUCCESS, psa_destroy_key(key_id)); mbedtls_pk_init(&pk); - TEST_EQUAL(mbedtls_pk_parse_public_key(&pk, pkey_start, pkey_len), 0); + TEST_EQUAL(mbedtls_pk_setup(&pk, + mbedtls_pk_info_from_type(pk_type)), 0); + TEST_EQUAL(mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(pk), pkey_start, pkey_len), 0); if (key_pk_type == MBEDTLS_PK_RSASSA_PSS) { rsassa_pss_options.mgf1_hash_id = md_alg; From 5ac511b45a06e64c241518a079652b002ddf22b5 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 14 Feb 2024 10:17:08 +0100 Subject: [PATCH 059/211] pk: let psa_export_key() check if the key is exportable or not Signed-off-by: Valerio Setti --- library/pk.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/library/pk.c b/library/pk.c index 580fa0e34b..56f8bb10b9 100644 --- a/library/pk.c +++ b/library/pk.c @@ -1400,14 +1400,9 @@ int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk return MBEDTLS_ERR_PK_BAD_INPUT_DATA; } - if ((psa_get_key_usage_flags(&key_attr) & PSA_KEY_USAGE_EXPORT) != PSA_KEY_USAGE_EXPORT) { - ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; - goto exit; - } - status = psa_export_key(key_id, exp_key, sizeof(exp_key), &exp_key_len); if (status != PSA_SUCCESS) { - ret = psa_generic_status_to_mbedtls(status); + ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; goto exit; } From e8fe3e76c4a9882b7f4266f80304b0c6c3533f8e Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 19 Feb 2024 08:00:50 +0100 Subject: [PATCH 060/211] test_suite_pk: add key pair check in pk_copy_from_psa_success() Signed-off-by: Valerio Setti --- tests/suites/test_suite_pk.function | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 2b3711009b..251a13a972 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -2382,6 +2382,9 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, pub_key_id = pk_psa_pub_key_from_priv(priv_key_id, pub_key_type, key_usage, key_alg, key_bits); TEST_EQUAL(mbedtls_pk_copy_from_psa(pub_key_id, &pk_ctx2), 0); + /* Check that the 2 generated PK contexts form a valid private/public key pair. */ + TEST_EQUAL(mbedtls_pk_check_pair(&pk_ctx2, &pk_ctx, mbedtls_test_rnd_std_rand, NULL), 0); + /* Test sign/verify with the following pattern: * - Sign using the PK context generated from the private key. * - Verify from the same PK context used for signature. From 88e2dac6d6f8c1405eb8b01edb50782d7a2bbd08 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 19 Feb 2024 14:48:00 +0100 Subject: [PATCH 061/211] test_suite_pk: rename PK context variables Signed-off-by: Valerio Setti --- tests/suites/test_suite_pk.function | 32 ++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 251a13a972..4f28500ac0 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -2338,7 +2338,7 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, size_t key_bits = key_bits_arg; psa_key_usage_t key_usage = key_usage_arg; psa_algorithm_t key_alg = key_alg_arg; - mbedtls_pk_context pk_ctx, pk_ctx2; + mbedtls_pk_context pk_priv, pk_pub; mbedtls_svc_key_id_t priv_key_id = MBEDTLS_SVC_KEY_ID_INIT; mbedtls_svc_key_id_t pub_key_id = MBEDTLS_SVC_KEY_ID_INIT; unsigned char *in_buf = NULL; @@ -2358,14 +2358,14 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, TEST_CALLOC(in_buf, in_buf_len); memset(in_buf, 0x1, in_buf_len); - mbedtls_pk_init(&pk_ctx); - mbedtls_pk_init(&pk_ctx2); + mbedtls_pk_init(&pk_priv); + mbedtls_pk_init(&pk_pub); PSA_INIT(); /* Generate a private key in PSA and create a PK context from it. */ PSA_ASSERT(pk_psa_import_key(priv_key_data->x, priv_key_data->len, key_type, key_usage, key_alg, key_bits, &priv_key_id)); - TEST_EQUAL(mbedtls_pk_copy_from_psa(priv_key_id, &pk_ctx), 0); + TEST_EQUAL(mbedtls_pk_copy_from_psa(priv_key_id, &pk_priv), 0); /* Starting from the private key above, create another PSA slot for the public * one and create a new PK context from it. */ @@ -2380,10 +2380,10 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, /* Generate a 2nd PK contex using only the public key derived from its private * counterpart generated above. */ pub_key_id = pk_psa_pub_key_from_priv(priv_key_id, pub_key_type, key_usage, key_alg, key_bits); - TEST_EQUAL(mbedtls_pk_copy_from_psa(pub_key_id, &pk_ctx2), 0); + TEST_EQUAL(mbedtls_pk_copy_from_psa(pub_key_id, &pk_pub), 0); /* Check that the 2 generated PK contexts form a valid private/public key pair. */ - TEST_EQUAL(mbedtls_pk_check_pair(&pk_ctx2, &pk_ctx, mbedtls_test_rnd_std_rand, NULL), 0); + TEST_EQUAL(mbedtls_pk_check_pair(&pk_pub, &pk_priv, mbedtls_test_rnd_std_rand, NULL), 0); /* Test sign/verify with the following pattern: * - Sign using the PK context generated from the private key. @@ -2396,23 +2396,23 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, .expected_salt_len = MBEDTLS_RSA_SALT_LEN_ANY, }; - TEST_EQUAL(mbedtls_pk_sign_ext(MBEDTLS_PK_RSASSA_PSS, &pk_ctx, md_for_test, + TEST_EQUAL(mbedtls_pk_sign_ext(MBEDTLS_PK_RSASSA_PSS, &pk_priv, md_for_test, in_buf, in_buf_len, out_buf, sizeof(out_buf), &out_buf_len, mbedtls_test_rnd_std_rand, NULL), 0); TEST_EQUAL(mbedtls_pk_verify_ext(MBEDTLS_PK_RSASSA_PSS, &pss_opt, - &pk_ctx, md_for_test, in_buf, in_buf_len, + &pk_priv, md_for_test, in_buf, in_buf_len, out_buf, out_buf_len), 0); TEST_EQUAL(mbedtls_pk_verify_ext(MBEDTLS_PK_RSASSA_PSS, &pss_opt, - &pk_ctx2, md_for_test, in_buf, in_buf_len, + &pk_pub, md_for_test, in_buf, in_buf_len, out_buf, out_buf_len), 0); } else { - TEST_EQUAL(mbedtls_pk_sign(&pk_ctx, md_for_test, in_buf, in_buf_len, + TEST_EQUAL(mbedtls_pk_sign(&pk_priv, md_for_test, in_buf, in_buf_len, out_buf, sizeof(out_buf), &out_buf_len, mbedtls_test_rnd_std_rand, NULL), 0); - TEST_EQUAL(mbedtls_pk_verify(&pk_ctx, md_for_test, in_buf, in_buf_len, + TEST_EQUAL(mbedtls_pk_verify(&pk_priv, md_for_test, in_buf, in_buf_len, out_buf, out_buf_len), 0); - TEST_EQUAL(mbedtls_pk_verify(&pk_ctx2, md_for_test, in_buf, in_buf_len, + TEST_EQUAL(mbedtls_pk_verify(&pk_pub, md_for_test, in_buf, in_buf_len, out_buf, out_buf_len), 0); } @@ -2430,12 +2430,12 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) { if (test_encryption) { /* Encrypt with the 2nd PK context (public key only). */ - TEST_EQUAL(mbedtls_pk_encrypt(&pk_ctx2, in_buf, in_buf_len, + TEST_EQUAL(mbedtls_pk_encrypt(&pk_pub, in_buf, in_buf_len, out_buf, &out_buf_len, sizeof(out_buf), mbedtls_test_rnd_std_rand, NULL), 0); /* Decrypt with 1st PK context and compare with original data. */ - TEST_EQUAL(mbedtls_pk_decrypt(&pk_ctx, out_buf, out_buf_len, + TEST_EQUAL(mbedtls_pk_decrypt(&pk_priv, out_buf, out_buf_len, out_buf2, &out_buf2_len, sizeof(out_buf2), mbedtls_test_rnd_std_rand, NULL), 0); TEST_MEMORY_COMPARE(in_buf, in_buf_len, out_buf2, out_buf2_len); @@ -2444,8 +2444,8 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, exit: mbedtls_free(in_buf); - mbedtls_pk_free(&pk_ctx); - mbedtls_pk_free(&pk_ctx2); + mbedtls_pk_free(&pk_priv); + mbedtls_pk_free(&pk_pub); psa_destroy_key(priv_key_id); psa_destroy_key(pub_key_id); PSA_DONE(); From aeeefef64e8fd1b96380bef8f5940e0af4de7a24 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 22 Feb 2024 07:59:37 +0100 Subject: [PATCH 062/211] pk_wrap: use correct PSA alg in rsa_encrypt_wrap() when USE_PSA This bugfix was due in PR #8826, but we didn't catch that. This commit also add proper testing in test_suite_pk that was not implemented in #8826. Signed-off-by: Valerio Setti --- library/pk_wrap.c | 9 +++++---- tests/suites/test_suite_pk.data | 8 ++++++-- tests/suites/test_suite_pk.function | 8 +++++--- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/library/pk_wrap.c b/library/pk_wrap.c index 846175e5f7..256863a5a5 100644 --- a/library/pk_wrap.c +++ b/library/pk_wrap.c @@ -368,7 +368,7 @@ static int rsa_encrypt_wrap(mbedtls_pk_context *pk, int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; - psa_algorithm_t psa_md_alg; + psa_algorithm_t psa_md_alg, psa_encrypt_alg; psa_status_t status; int key_len; unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES]; @@ -389,10 +389,11 @@ static int rsa_encrypt_wrap(mbedtls_pk_context *pk, psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); if (mbedtls_rsa_get_padding_mode(rsa) == MBEDTLS_RSA_PKCS_V21) { psa_md_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) mbedtls_rsa_get_md_alg(rsa)); - psa_set_key_algorithm(&attributes, PSA_ALG_RSA_OAEP(psa_md_alg)); + psa_encrypt_alg = PSA_ALG_RSA_OAEP(psa_md_alg); } else { - psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT); + psa_encrypt_alg = PSA_ALG_RSA_PKCS1V15_CRYPT; } + psa_set_key_algorithm(&attributes, psa_encrypt_alg); psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY); status = psa_import_key(&attributes, @@ -403,7 +404,7 @@ static int rsa_encrypt_wrap(mbedtls_pk_context *pk, goto cleanup; } - status = psa_asymmetric_encrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT, + status = psa_asymmetric_encrypt(key_id, psa_encrypt_alg, input, ilen, NULL, 0, output, osize, olen); diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data index 4637f3721c..785b2fb88e 100644 --- a/tests/suites/test_suite_pk.data +++ b/tests/suites/test_suite_pk.data @@ -450,9 +450,13 @@ RSA sign-verify, PKCS1v2.1, SHA256 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_GENPRIME:MBEDTLS_RSA_GEN_KEY_MIN_BITS >= 512:MBEDTLS_MD_CAN_SHA256 pk_sign_verify:MBEDTLS_PK_RSA:MBEDTLS_RSA_GEN_KEY_MIN_BITS:MBEDTLS_RSA_PKCS_V21:MBEDTLS_MD_SHA256:0:0 -RSA encrypt-decrypt test +RSA encrypt-decrypt test PKCS1 v1.5 depends_on:MBEDTLS_PKCS1_V15 -pk_rsa_encrypt_decrypt_test:"4E636AF98E40F3ADCFCCB698F4E80B9F":2048:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"3":0 +pk_rsa_encrypt_decrypt_test:"4E636AF98E40F3ADCFCCB698F4E80B9F":2048:MBEDTLS_RSA_PKCS_V15:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"3":0 + +RSA encrypt-decrypt test PKCS1 v2.1 +depends_on:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA1 +pk_rsa_encrypt_decrypt_test:"4E636AF98E40F3ADCFCCB698F4E80B9F":2048:MBEDTLS_RSA_PKCS_V21:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17":"c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89":"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"3":0 RSA decrypt test vector - PKCS1v1.5 depends_on:MBEDTLS_PKCS1_V15 diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 4f28500ac0..8e32eeae8f 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -1296,7 +1296,7 @@ exit: /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_RSA_C */ -void pk_rsa_encrypt_decrypt_test(data_t *message, int mod, +void pk_rsa_encrypt_decrypt_test(data_t *message, int mod, int padding, char *input_P, char *input_Q, char *input_N, char *input_E, int ret) @@ -1311,7 +1311,7 @@ void pk_rsa_encrypt_decrypt_test(data_t *message, int mod, mbedtls_pk_init(&pk); mbedtls_mpi_init(&N); mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q); mbedtls_mpi_init(&E); - USE_PSA_INIT(); + MD_OR_USE_PSA_INIT(); memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info)); memset(output, 0, sizeof(output)); @@ -1321,6 +1321,7 @@ void pk_rsa_encrypt_decrypt_test(data_t *message, int mod, /* init pk-rsa context */ TEST_ASSERT(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == 0); rsa = mbedtls_pk_rsa(pk); + mbedtls_rsa_set_padding(rsa, padding, MBEDTLS_MD_SHA1); /* load public key */ rsa->len = (mod + 7) / 8; @@ -1340,6 +1341,7 @@ void pk_rsa_encrypt_decrypt_test(data_t *message, int mod, TEST_ASSERT(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == 0); rsa = mbedtls_pk_rsa(pk); + mbedtls_rsa_set_padding(rsa, padding, MBEDTLS_MD_SHA1); /* load public key */ TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0); @@ -1369,7 +1371,7 @@ exit: mbedtls_mpi_free(&N); mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q); mbedtls_mpi_free(&E); mbedtls_pk_free(&pk); - USE_PSA_DONE(); + MD_OR_USE_PSA_DONE(); } /* END_CASE */ From 61a47a46ea71fb8c18b7e065272e87f88b33f5ff Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 22 Feb 2024 09:57:42 +0100 Subject: [PATCH 063/211] test_suite_pk: extend testing in pk_copy_from_psa() Signed-off-by: Valerio Setti --- tests/suites/test_suite_pk.data | 26 +++--- tests/suites/test_suite_pk.function | 139 ++++++++++++++++++---------- 2 files changed, 101 insertions(+), 64 deletions(-) diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data index 785b2fb88e..69d861c2d3 100644 --- a/tests/suites/test_suite_pk.data +++ b/tests/suites/test_suite_pk.data @@ -1460,52 +1460,52 @@ pk_copy_from_psa_fail: Copy from PSA: valid EC (SECP_R1_256 + ANY_HASH) depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 -pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH) +pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH) Copy from PSA: valid EC (SECP_R1_256 + SHA_256) depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 -pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA(PSA_ALG_SHA_256) +pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA(PSA_ALG_SHA_256) Copy from PSA: valid EC (SECP_R1_256 + SHA_512) depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA512 -pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA(PSA_ALG_SHA_512) +pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA(PSA_ALG_SHA_512) Copy from PSA: valid RSA (PKCS1V15_SIGN + ANY_HASH) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH) +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH) Copy from PSA: valid RSA (PKCS1V15_SIGN + SHA_256) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256) +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256) Copy from PSA: valid RSA (PKCS1V15_SIGN + SHA_512) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA512 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_512) +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_512) Copy from PSA: valid RSA (PKCS1V15_CRYPT) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_CRYPT +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_CRYPT Copy from PSA: valid RSA (OAEP + ANY_HASH) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_OAEP(PSA_ALG_ANY_HASH) +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_OAEP(PSA_ALG_ANY_HASH) Copy from PSA: valid RSA (OAEP + SHA_256) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256) +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256) Copy from PSA: valid RSA (OAEP + SHA_512) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA512 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_512) +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_512) Copy from PSA: valid RSA (PSS_ANY_SALT + ANY_HASH) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH) +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH) Copy from PSA: valid RSA (PSS_ANY_SALT + SHA_256) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256) +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256) Copy from PSA: valid RSA (PSS_ANY_SALT + SHA_512) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA512 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_512) +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_512) diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 8e32eeae8f..e08751e79e 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -2257,13 +2257,6 @@ void pk_copy_from_psa_fail(void) { mbedtls_pk_context pk_ctx; mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; -#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_RSA_C) && \ - defined(MBEDTLS_MD_CAN_SHA256) && defined(MBEDTLS_PKCS1_V21) - unsigned char in_buf[32]; /* Only SHA256 is used here. */ - unsigned char out_buf[256]; /* Only 2048 RSA bit size is used here. */ - size_t out_buf_len; -#endif /* MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_RSA_C && - MBEDTLS_MD_CAN_SHA256 && MBEDTLS_PKCS1_V21 */ mbedtls_pk_init(&pk_ctx); PSA_INIT(); @@ -2308,19 +2301,6 @@ void pk_copy_from_psa_fail(void) PSA_ALG_CMAC, 2048, &key_id)); TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, &pk_ctx), MBEDTLS_ERR_PK_BAD_INPUT_DATA); psa_destroy_key(key_id); - - /* Try to encrypt with a RSA key in PKCS1V21 format. */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_MD_CAN_SHA256) && defined(MBEDTLS_PKCS1_V21) - PSA_ASSERT(pk_psa_genkey_generic(PSA_KEY_TYPE_RSA_KEY_PAIR, - PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT, - PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256), 2048, &key_id)); - TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, &pk_ctx), 0); - TEST_EQUAL(mbedtls_pk_encrypt(&pk_ctx, in_buf, sizeof(in_buf), - out_buf, &out_buf_len, sizeof(out_buf), - mbedtls_test_rnd_std_rand, NULL), - MBEDTLS_ERR_RSA_INVALID_PADDING); - psa_destroy_key(key_id); -#endif /* MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_MD_CAN_SHA256 && MBEDTLS_PKCS1_V21*/ #endif /* MBEDTLS_RSA_C && PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE */ exit: @@ -2351,9 +2331,11 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, /* Get the MD type to be used for the tests below from the provided key policy. */ mbedtls_md_type_t md_for_test = MBEDTLS_MD_SHA256; /* Default */ - if ((PSA_ALG_GET_HASH(key_alg) != 0) && + int is_psa_hash_alg_specified = 0; + if ((PSA_ALG_GET_HASH(key_alg) != PSA_ALG_NONE) && (PSA_ALG_GET_HASH(key_alg) != PSA_ALG_ANY_HASH)) { md_for_test = mbedtls_md_type_from_psa_alg(key_alg); + is_psa_hash_alg_specified = 1; } in_buf_len = mbedtls_md_get_size_from_type(md_for_test); @@ -2380,63 +2362,118 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, } /* Generate a 2nd PK contex using only the public key derived from its private - * counterpart generated above. */ + * counterpart generated above. */ pub_key_id = pk_psa_pub_key_from_priv(priv_key_id, pub_key_type, key_usage, key_alg, key_bits); TEST_EQUAL(mbedtls_pk_copy_from_psa(pub_key_id, &pk_pub), 0); - /* Check that the 2 generated PK contexts form a valid private/public key pair. */ + /* Test #1: check that the 2 generated PK contexts form a valid private/public key pair. */ TEST_EQUAL(mbedtls_pk_check_pair(&pk_pub, &pk_priv, mbedtls_test_rnd_std_rand, NULL), 0); - /* Test sign/verify with the following pattern: + /* Test #2: sign/verify with the following pattern: * - Sign using the PK context generated from the private key. * - Verify from the same PK context used for signature. * - Verify with the PK context generated using public key. + * - Verify using the public PSA key directly. + * + * Note: mbedtls_pk_verify_ext() is tested only for RSA keys with PKCS1 v2.1 + * padding. For other key types this functions works the same as + * mbedtls_pk_verify(). + * + * Note: PSS requires the hash to be specified on sign operation (i.e. not + * null or any), so in case PSA_ALG_ANY_HASH is provided as input, we + * use mbedtls_pk_sign_ext() instead of mbedtls_pk_sign(). */ - if ((PSA_ALG_IS_RSA_OAEP(key_alg) || PSA_ALG_IS_RSA_PSS(key_alg))) { - mbedtls_pk_rsassa_pss_options pss_opt = { - .mgf1_hash_id = md_for_test, - .expected_salt_len = MBEDTLS_RSA_SALT_LEN_ANY, - }; + mbedtls_pk_rsassa_pss_options pss_opt = { + .mgf1_hash_id = md_for_test, + .expected_salt_len = MBEDTLS_RSA_SALT_LEN_ANY, + }; + if ((PSA_ALG_IS_RSA_OAEP(key_alg) || PSA_ALG_IS_RSA_PSS(key_alg)) && + (!is_psa_hash_alg_specified)) { TEST_EQUAL(mbedtls_pk_sign_ext(MBEDTLS_PK_RSASSA_PSS, &pk_priv, md_for_test, in_buf, in_buf_len, out_buf, sizeof(out_buf), &out_buf_len, mbedtls_test_rnd_std_rand, NULL), 0); + } else { + TEST_EQUAL(mbedtls_pk_sign(&pk_priv, md_for_test, in_buf, in_buf_len, + out_buf, sizeof(out_buf), &out_buf_len, + mbedtls_test_rnd_std_rand, NULL), 0); + } + + TEST_EQUAL(mbedtls_pk_verify(&pk_priv, md_for_test, in_buf, in_buf_len, + out_buf, out_buf_len), 0); + TEST_EQUAL(mbedtls_pk_verify(&pk_pub, md_for_test, in_buf, in_buf_len, + out_buf, out_buf_len), 0); + + if (PSA_ALG_IS_RSA_OAEP(key_alg) || PSA_ALG_IS_RSA_PSS(key_alg)) { TEST_EQUAL(mbedtls_pk_verify_ext(MBEDTLS_PK_RSASSA_PSS, &pss_opt, &pk_priv, md_for_test, in_buf, in_buf_len, out_buf, out_buf_len), 0); TEST_EQUAL(mbedtls_pk_verify_ext(MBEDTLS_PK_RSASSA_PSS, &pss_opt, &pk_pub, md_for_test, in_buf, in_buf_len, out_buf, out_buf_len), 0); - } else { - TEST_EQUAL(mbedtls_pk_sign(&pk_priv, md_for_test, in_buf, in_buf_len, - out_buf, sizeof(out_buf), &out_buf_len, - mbedtls_test_rnd_std_rand, NULL), 0); - TEST_EQUAL(mbedtls_pk_verify(&pk_priv, md_for_test, in_buf, in_buf_len, - out_buf, out_buf_len), 0); + } + +#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA) + if (PSA_ALG_IS_SIGN(key_alg) && is_psa_hash_alg_specified) { + /* ECDSA signature requires PK->PSA format conversion. */ + if (PSA_ALG_IS_ECDSA(key_alg)) { + TEST_EQUAL(mbedtls_ecdsa_der_to_raw(mbedtls_pk_get_bitlen(&pk_pub), + out_buf, out_buf_len, out_buf, + sizeof(out_buf), &out_buf_len), 0); + } + PSA_ASSERT(psa_verify_hash(pub_key_id, key_alg, in_buf, in_buf_len, + out_buf, out_buf_len)); + } + + /* Test #3: check sign/verify interoperability also in the opposite direction: + * sign with PSA and verify with PK. Key's policy must include a valid hash + * algorithm (not any). + */ + if (PSA_ALG_IS_SIGN(key_alg) && is_psa_hash_alg_specified) { + PSA_ASSERT(psa_sign_hash(priv_key_id, key_alg, in_buf, in_buf_len, + out_buf, sizeof(out_buf), &out_buf_len)); + /* ECDSA signature requires PSA->PK format conversion */ + if (PSA_ALG_IS_ECDSA(key_alg)) { + TEST_EQUAL(mbedtls_ecdsa_raw_to_der(mbedtls_pk_get_bitlen(&pk_pub), + out_buf, out_buf_len, out_buf, + sizeof(out_buf), &out_buf_len), 0); + } TEST_EQUAL(mbedtls_pk_verify(&pk_pub, md_for_test, in_buf, in_buf_len, out_buf, out_buf_len), 0); } +#endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */ - int test_encryption = 0; + /* Test #4: in case of RSA key pair try also encryption/decryption. + * Hash algorithm does not matter when padding mode is PKCS1 v1.5, whereas + * it must be not null or any in case of v2.1 (OAEP). */ + int test_encryption = (PSA_ALG_IS_RSA_PKCS1V15_SIGN(key_alg) || + (key_alg == PSA_ALG_RSA_PKCS1V15_CRYPT) || + is_psa_hash_alg_specified); + if ((key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) && test_encryption) { + /* Encrypt with the public key only PK context. */ + TEST_EQUAL(mbedtls_pk_encrypt(&pk_pub, in_buf, in_buf_len, + out_buf, &out_buf_len, sizeof(out_buf), + mbedtls_test_rnd_std_rand, NULL), 0); -#if defined(MBEDTLS_USE_PSA_CRYPTO) - test_encryption = (PSA_ALG_IS_RSA_PKCS1V15_SIGN(key_alg) || - (key_alg == PSA_ALG_RSA_PKCS1V15_CRYPT)); -#else - test_encryption = ((PSA_ALG_GET_HASH(key_alg) != 0) && - (PSA_ALG_GET_HASH(key_alg) != PSA_ALG_ANY_HASH)); -#endif + /* Decrypt with key pair PK context and compare with original data. */ + TEST_EQUAL(mbedtls_pk_decrypt(&pk_priv, out_buf, out_buf_len, + out_buf2, &out_buf2_len, sizeof(out_buf2), + mbedtls_test_rnd_std_rand, NULL), 0); + TEST_MEMORY_COMPARE(in_buf, in_buf_len, out_buf2, out_buf2_len); - /* In case of RSA key pair try also encryption/decryption. */ - if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) { - if (test_encryption) { - /* Encrypt with the 2nd PK context (public key only). */ - TEST_EQUAL(mbedtls_pk_encrypt(&pk_pub, in_buf, in_buf_len, - out_buf, &out_buf_len, sizeof(out_buf), - mbedtls_test_rnd_std_rand, NULL), 0); + if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(key_alg)) { + /* Decrypt with PSA private key directly and compare with original data. */ + PSA_ASSERT(psa_asymmetric_decrypt(priv_key_id, key_alg, out_buf, out_buf_len, + NULL, 0, + out_buf2, sizeof(out_buf2), &out_buf2_len)); + TEST_MEMORY_COMPARE(in_buf, in_buf_len, out_buf2, out_buf2_len); - /* Decrypt with 1st PK context and compare with original data. */ + /* Encrypt with PSA public key directly, decrypt with public key PK context + * and compare with original data. */ + PSA_ASSERT(psa_asymmetric_encrypt(pub_key_id, key_alg, in_buf, in_buf_len, + NULL, 0, + out_buf, sizeof(out_buf), &out_buf_len)); TEST_EQUAL(mbedtls_pk_decrypt(&pk_priv, out_buf, out_buf_len, out_buf2, &out_buf2_len, sizeof(out_buf2), mbedtls_test_rnd_std_rand, NULL), 0); From 2f08f4cdb878f205764228f692c4dbeafa481de7 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 22 Feb 2024 15:28:59 +0100 Subject: [PATCH 064/211] add changelog Signed-off-by: Valerio Setti --- ChangeLog.d/8709.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 ChangeLog.d/8709.txt diff --git a/ChangeLog.d/8709.txt b/ChangeLog.d/8709.txt new file mode 100644 index 0000000000..52b96096c4 --- /dev/null +++ b/ChangeLog.d/8709.txt @@ -0,0 +1,3 @@ +Features + * The new function mbedtls_pk_copy_from_psa() provides a way to setup + a PK context starting from a PSA key. From 8fb0fe8e129382ba78c97c00b0f1eb7a32fd9e49 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 23 Feb 2024 07:06:49 +0100 Subject: [PATCH 065/211] pk: fixed documentation of mbedtls_pk_copy_from_psa() Signed-off-by: Valerio Setti --- include/mbedtls/pk.h | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h index 20be7e6737..90f4ac63a1 100644 --- a/include/mbedtls/pk.h +++ b/include/mbedtls/pk.h @@ -394,35 +394,36 @@ int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx, /** * \brief Create a PK context starting from a key stored in PSA. * This key: - * - must have PSA_KEY_USAGE_EXPORT attribute set and - * - must be a either a RSA or EC (DH is not managed in PK) and + * - must be exportabel and + * - must be a either an RSA or EC key (DH is not managed in PK) and * - must be either a key pair or a public key. * * The resulting PK object will be a transparent type: - * - MBEDTLS_PK_RSA for RSA keys or - * - MBEDTLS_PK_ECKEY for EC keys. + * - #MBEDTLS_PK_RSA for RSA keys or + * - #MBEDTLS_PK_ECKEY for EC keys. + * * Once this functions returns the PK object will be completely * independent from the original PSA key that it was generated * from. - * Calling `mbedtls_pk_sign`, `mbedtls_pk_verify`, - * `mbedtls_pk_encrypt`, `mbedtls_pk_decrypt` on the resulting + * Calling mbedtls_pk_sign(), mbedtls_pk_verify(), + * mbedtls_pk_encrypt(), mbedtls_pk_decrypt() on the resulting * PK context will perform an algorithm that is compatible with * the PSA key's primary algorithm policy if that is a matching * operation type (sign/verify, encrypt/decrypt), but with no * restriction on the hash (as if the policy had - * `PSA_ALG_ANY_HASH` instead of a specific hash, and with - * `PSA_ALG_RSA_PKCS1V15_SIGN_RAW` merged with - * `PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)`). + * #PSA_ALG_ANY_HASH instead of a specific hash, and with + * #PSA_ALG_RSA_PKCS1V15_SIGN_RAW merged with + * #PSA_ALG_RSA_PKCS1V15_SIGN(\c hash_alg)). * * For ECDSA, the choice of deterministic vs randomized will - * be based on the compile-time setting `MBEDTLS_ECDSA_DETERMINISTIC`. + * be based on the compile-time setting #MBEDTLS_ECDSA_DETERMINISTIC. * * For an RSA key, the output key will allow both encrypt/decrypt * and sign/verify regardless of the original key's policy. * The original key's policy determines the output key's padding * mode. * - * \param key_id The ID of the key stored in PSA. + * \param key_id The key identifier of the key stored in PSA. * \param pk The PK context that will be filled. It must be initialized, - * but not setup. + * but not set up. * * \return 0 on success. * \return MBEDTLS_ERR_PK_BAD_INPUT_DATA in case the provided input From d2ccc2f468160635701ea7c898e78554fc74a01f Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 23 Feb 2024 08:49:45 +0100 Subject: [PATCH 066/211] test_suite_pk: various minor fixes - removed redundant info from data file (i.e. informations that can be extrapolated somehow) - removed unecessary parameters in functions - added some extra check on the generated PK contexts - etc... Signed-off-by: Valerio Setti --- tests/suites/test_suite_pk.data | 28 +++-- tests/suites/test_suite_pk.function | 159 +++++++++++++--------------- 2 files changed, 85 insertions(+), 102 deletions(-) diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data index 69d861c2d3..55dea93f82 100644 --- a/tests/suites/test_suite_pk.data +++ b/tests/suites/test_suite_pk.data @@ -1460,52 +1460,48 @@ pk_copy_from_psa_fail: Copy from PSA: valid EC (SECP_R1_256 + ANY_HASH) depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 -pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH) +pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDSA(PSA_ALG_ANY_HASH) Copy from PSA: valid EC (SECP_R1_256 + SHA_256) depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 -pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA(PSA_ALG_SHA_256) +pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDSA(PSA_ALG_SHA_256) Copy from PSA: valid EC (SECP_R1_256 + SHA_512) depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA512 -pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA(PSA_ALG_SHA_512) +pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDSA(PSA_ALG_SHA_512) Copy from PSA: valid RSA (PKCS1V15_SIGN + ANY_HASH) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH) +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH) Copy from PSA: valid RSA (PKCS1V15_SIGN + SHA_256) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256) +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256) Copy from PSA: valid RSA (PKCS1V15_SIGN + SHA_512) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA512 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_512) +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_512) Copy from PSA: valid RSA (PKCS1V15_CRYPT) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_CRYPT - -Copy from PSA: valid RSA (OAEP + ANY_HASH) -depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_OAEP(PSA_ALG_ANY_HASH) +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_CRYPT Copy from PSA: valid RSA (OAEP + SHA_256) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256) +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256) Copy from PSA: valid RSA (OAEP + SHA_512) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA512 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_512) +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_512) Copy from PSA: valid RSA (PSS_ANY_SALT + ANY_HASH) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH) +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH) Copy from PSA: valid RSA (PSS_ANY_SALT + SHA_256) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256) +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256) Copy from PSA: valid RSA (PSS_ANY_SALT + SHA_512) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA512 -pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:2048:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_512) +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_512) diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index e08751e79e..69546b20f5 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -428,49 +428,67 @@ exit: #endif #if defined(MBEDTLS_PSA_CRYPTO_C) -mbedtls_svc_key_id_t pk_psa_pub_key_from_priv(mbedtls_svc_key_id_t priv_id, - psa_key_type_t type, psa_key_usage_t usage, - psa_algorithm_t alg, size_t bits) +static mbedtls_svc_key_id_t psa_pub_key_from_priv(mbedtls_svc_key_id_t priv_id) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_type_t type; + psa_algorithm_t alg; + psa_key_usage_t usage; unsigned char pub_key_buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; size_t pub_key_len; mbedtls_svc_key_id_t pub_key = MBEDTLS_SVC_KEY_ID_INIT; + /* Get attributes from the private key. */ + PSA_ASSERT(psa_get_key_attributes(priv_id, &attributes)); + type = psa_get_key_type(&attributes); + usage = psa_get_key_usage_flags(&attributes); + alg = psa_get_key_algorithm(&attributes); + psa_reset_key_attributes(&attributes); + + /* Export the public key and then import it in a new slot. */ PSA_ASSERT(psa_export_public_key(priv_id, pub_key_buf, sizeof(pub_key_buf), &pub_key_len)); + /* Notes: + * - psa_import_key() automatically determines the key's bit length + * from the provided key data. That's why psa_set_key_bits() is not used + * below. + * - public keys are always exportable by default even if PSA_KEY_USAGE_EXPORT + * is not set. + */ + type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type); + usage &= ~PSA_KEY_USAGE_EXPORT; + psa_set_key_type(&attributes, type); psa_set_key_usage_flags(&attributes, usage); psa_set_key_algorithm(&attributes, alg); - psa_set_key_type(&attributes, type); - psa_set_key_bits(&attributes, bits); PSA_ASSERT(psa_import_key(&attributes, pub_key_buf, pub_key_len, &pub_key)); exit: + psa_reset_key_attributes(&attributes); return pub_key; } psa_status_t pk_psa_import_key(unsigned char *key_data, size_t key_len, psa_key_type_t type, psa_key_usage_t usage, - psa_algorithm_t alg, size_t bits, - mbedtls_svc_key_id_t *key) + psa_algorithm_t alg, mbedtls_svc_key_id_t *key) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_status_t status; *key = MBEDTLS_SVC_KEY_ID_INIT; + /* Note: psa_import_key() automatically determines the key's bit length + * from the provided key data. That's why psa_set_key_bits() is not used below. */ psa_set_key_usage_flags(&attributes, usage); psa_set_key_algorithm(&attributes, alg); psa_set_key_type(&attributes, type); - psa_set_key_bits(&attributes, bits); status = psa_import_key(&attributes, key_data, key_len, key); return status; } -psa_status_t pk_psa_genkey_generic(psa_key_type_t type, psa_key_usage_t usage, - psa_algorithm_t alg, size_t bits, +psa_status_t pk_psa_genkey_generic(psa_key_type_t type, size_t bits, + psa_key_usage_t usage, psa_algorithm_t alg, mbedtls_svc_key_id_t *key) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; @@ -496,9 +514,9 @@ mbedtls_svc_key_id_t pk_psa_genkey_ecc(void) { mbedtls_svc_key_id_t key; - pk_psa_genkey_generic(PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), + pk_psa_genkey_generic(PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 256, PSA_KEY_USAGE_SIGN_HASH, PSA_ALG_ECDSA(PSA_ALG_SHA_256), - 256, &key); + &key); return key; } @@ -511,8 +529,8 @@ mbedtls_svc_key_id_t pk_psa_genkey_rsa(void) { mbedtls_svc_key_id_t key; - pk_psa_genkey_generic(PSA_KEY_TYPE_RSA_KEY_PAIR, PSA_KEY_USAGE_SIGN_HASH, - PSA_ALG_RSA_PKCS1V15_SIGN_RAW, 1024, &key); + pk_psa_genkey_generic(PSA_KEY_TYPE_RSA_KEY_PAIR, 1024, PSA_KEY_USAGE_SIGN_HASH, + PSA_ALG_RSA_PKCS1V15_SIGN_RAW, &key); return key; } @@ -2271,8 +2289,8 @@ void pk_copy_from_psa_fail(void) #if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE) /* Generate a key type that is not handled by the PK module. */ - PSA_ASSERT(pk_psa_genkey_generic(PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919), - PSA_KEY_USAGE_EXPORT, PSA_ALG_NONE, 2048, &key_id)); + PSA_ASSERT(pk_psa_genkey_generic(PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919), 2048, + PSA_KEY_USAGE_EXPORT, PSA_ALG_NONE, &key_id)); TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, &pk_ctx), MBEDTLS_ERR_PK_BAD_INPUT_DATA); psa_destroy_key(key_id); #endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE */ @@ -2280,29 +2298,13 @@ void pk_copy_from_psa_fail(void) #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && defined(PSA_WANT_ECC_SECP_R1_256) && \ defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) /* Generate an EC key which cannot be exported. */ - PSA_ASSERT(pk_psa_genkey_generic(PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), - 0, PSA_ALG_NONE, 256, &key_id)); - TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, &pk_ctx), MBEDTLS_ERR_PK_BAD_INPUT_DATA); - psa_destroy_key(key_id); - - /* Use valid exportable EC key with wrong alorithm. */ - PSA_ASSERT(pk_psa_genkey_generic(PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), - PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH, - PSA_ALG_ECDH, 256, &key_id)); + PSA_ASSERT(pk_psa_genkey_generic(PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 256, + 0, PSA_ALG_NONE, &key_id)); TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, &pk_ctx), MBEDTLS_ERR_PK_BAD_INPUT_DATA); psa_destroy_key(key_id); #endif /* MBEDTLS_PK_HAVE_ECC_KEYS && PSA_WANT_ECC_SECP_R1_256 && PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE */ -#if defined(MBEDTLS_RSA_C) && defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) - /* Use valid exportable RSA key with wrong alorithm. */ - PSA_ASSERT(pk_psa_genkey_generic(PSA_KEY_TYPE_RSA_KEY_PAIR, - PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH, - PSA_ALG_CMAC, 2048, &key_id)); - TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, &pk_ctx), MBEDTLS_ERR_PK_BAD_INPUT_DATA); - psa_destroy_key(key_id); -#endif /* MBEDTLS_RSA_C && PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE */ - exit: mbedtls_pk_free(&pk_ctx); psa_destroy_key(key_id); @@ -2312,14 +2314,12 @@ exit: /* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C*/ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, - int key_bits_arg, int key_usage_arg, int key_alg_arg) { psa_key_type_t key_type = key_type_arg; - psa_key_type_t pub_key_type; - size_t key_bits = key_bits_arg; - psa_key_usage_t key_usage = key_usage_arg; psa_algorithm_t key_alg = key_alg_arg; + psa_key_usage_t key_usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | + PSA_KEY_USAGE_EXPORT; mbedtls_pk_context pk_priv, pk_pub; mbedtls_svc_key_id_t priv_key_id = MBEDTLS_SVC_KEY_ID_INIT; mbedtls_svc_key_id_t pub_key_id = MBEDTLS_SVC_KEY_ID_INIT; @@ -2329,6 +2329,10 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, unsigned char out_buf2[MBEDTLS_PK_SIGNATURE_MAX_SIZE]; size_t out_buf_len, out_buf2_len; + mbedtls_pk_init(&pk_priv); + mbedtls_pk_init(&pk_pub); + PSA_INIT(); + /* Get the MD type to be used for the tests below from the provided key policy. */ mbedtls_md_type_t md_for_test = MBEDTLS_MD_SHA256; /* Default */ int is_psa_hash_alg_specified = 0; @@ -2342,54 +2346,49 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, TEST_CALLOC(in_buf, in_buf_len); memset(in_buf, 0x1, in_buf_len); - mbedtls_pk_init(&pk_priv); - mbedtls_pk_init(&pk_pub); - PSA_INIT(); - - /* Generate a private key in PSA and create a PK context from it. */ - PSA_ASSERT(pk_psa_import_key(priv_key_data->x, priv_key_data->len, - key_type, key_usage, key_alg, key_bits, &priv_key_id)); - TEST_EQUAL(mbedtls_pk_copy_from_psa(priv_key_id, &pk_priv), 0); - - /* Starting from the private key above, create another PSA slot for the public - * one and create a new PK context from it. */ - if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type)) { - pub_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_KEY_TYPE_ECC_GET_FAMILY(key_type)); - } else if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) { - pub_key_type = PSA_KEY_TYPE_RSA_PUBLIC_KEY; - } else { - TEST_FAIL("Key type can only be EC or RSA key pair"); + if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) { + key_usage |= PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT; } + /* Create a private key in PSA and create a PK context from it. */ + PSA_ASSERT(pk_psa_import_key(priv_key_data->x, priv_key_data->len, + key_type, key_usage, key_alg, &priv_key_id)); + TEST_EQUAL(mbedtls_pk_copy_from_psa(priv_key_id, &pk_priv), 0); + /* Generate a 2nd PK contex using only the public key derived from its private * counterpart generated above. */ - pub_key_id = pk_psa_pub_key_from_priv(priv_key_id, pub_key_type, key_usage, key_alg, key_bits); + pub_key_id = psa_pub_key_from_priv(priv_key_id); TEST_EQUAL(mbedtls_pk_copy_from_psa(pub_key_id, &pk_pub), 0); - /* Test #1: check that the 2 generated PK contexts form a valid private/public key pair. */ + /* Test #1: check that the generated PK contexts are of the correct type. */ + if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type)) { + TEST_EQUAL(mbedtls_pk_get_type(&pk_priv), MBEDTLS_PK_ECKEY); + TEST_EQUAL(mbedtls_pk_get_type(&pk_pub), MBEDTLS_PK_ECKEY); + } else { + TEST_EQUAL(mbedtls_pk_get_type(&pk_priv), MBEDTLS_PK_RSA); + TEST_EQUAL(mbedtls_pk_get_type(&pk_pub), MBEDTLS_PK_RSA); + } + + /* Test #2: check that the 2 generated PK contexts form a valid private/public key pair. */ TEST_EQUAL(mbedtls_pk_check_pair(&pk_pub, &pk_priv, mbedtls_test_rnd_std_rand, NULL), 0); - /* Test #2: sign/verify with the following pattern: + /* Test #3: sign/verify with the following pattern: * - Sign using the PK context generated from the private key. * - Verify from the same PK context used for signature. * - Verify with the PK context generated using public key. * - Verify using the public PSA key directly. * - * Note: mbedtls_pk_verify_ext() is tested only for RSA keys with PKCS1 v2.1 - * padding. For other key types this functions works the same as - * mbedtls_pk_verify(). - * * Note: PSS requires the hash to be specified on sign operation (i.e. not * null or any), so in case PSA_ALG_ANY_HASH is provided as input, we * use mbedtls_pk_sign_ext() instead of mbedtls_pk_sign(). */ - mbedtls_pk_rsassa_pss_options pss_opt = { - .mgf1_hash_id = md_for_test, - .expected_salt_len = MBEDTLS_RSA_SALT_LEN_ANY, - }; - if ((PSA_ALG_IS_RSA_OAEP(key_alg) || PSA_ALG_IS_RSA_PSS(key_alg)) && (!is_psa_hash_alg_specified)) { + /* Ensure pk_sign() fails without crashing. */ + TEST_EQUAL(mbedtls_pk_sign(&pk_priv, md_for_test, in_buf, in_buf_len, + out_buf, sizeof(out_buf), &out_buf_len, + mbedtls_test_rnd_std_rand, NULL), + MBEDTLS_ERR_RSA_BAD_INPUT_DATA); TEST_EQUAL(mbedtls_pk_sign_ext(MBEDTLS_PK_RSASSA_PSS, &pk_priv, md_for_test, in_buf, in_buf_len, out_buf, sizeof(out_buf), &out_buf_len, @@ -2405,52 +2404,40 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, TEST_EQUAL(mbedtls_pk_verify(&pk_pub, md_for_test, in_buf, in_buf_len, out_buf, out_buf_len), 0); - if (PSA_ALG_IS_RSA_OAEP(key_alg) || PSA_ALG_IS_RSA_PSS(key_alg)) { - TEST_EQUAL(mbedtls_pk_verify_ext(MBEDTLS_PK_RSASSA_PSS, &pss_opt, - &pk_priv, md_for_test, in_buf, in_buf_len, - out_buf, out_buf_len), 0); - TEST_EQUAL(mbedtls_pk_verify_ext(MBEDTLS_PK_RSASSA_PSS, &pss_opt, - &pk_pub, md_for_test, in_buf, in_buf_len, - out_buf, out_buf_len), 0); - } - -#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA) if (PSA_ALG_IS_SIGN(key_alg) && is_psa_hash_alg_specified) { +#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA) /* ECDSA signature requires PK->PSA format conversion. */ if (PSA_ALG_IS_ECDSA(key_alg)) { TEST_EQUAL(mbedtls_ecdsa_der_to_raw(mbedtls_pk_get_bitlen(&pk_pub), out_buf, out_buf_len, out_buf, sizeof(out_buf), &out_buf_len), 0); } +#endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */ PSA_ASSERT(psa_verify_hash(pub_key_id, key_alg, in_buf, in_buf_len, out_buf, out_buf_len)); } - /* Test #3: check sign/verify interoperability also in the opposite direction: + /* Test #4: check sign/verify interoperability also in the opposite direction: * sign with PSA and verify with PK. Key's policy must include a valid hash * algorithm (not any). */ if (PSA_ALG_IS_SIGN(key_alg) && is_psa_hash_alg_specified) { PSA_ASSERT(psa_sign_hash(priv_key_id, key_alg, in_buf, in_buf_len, out_buf, sizeof(out_buf), &out_buf_len)); +#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA) /* ECDSA signature requires PSA->PK format conversion */ if (PSA_ALG_IS_ECDSA(key_alg)) { TEST_EQUAL(mbedtls_ecdsa_raw_to_der(mbedtls_pk_get_bitlen(&pk_pub), out_buf, out_buf_len, out_buf, sizeof(out_buf), &out_buf_len), 0); } +#endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */ TEST_EQUAL(mbedtls_pk_verify(&pk_pub, md_for_test, in_buf, in_buf_len, out_buf, out_buf_len), 0); } -#endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */ - /* Test #4: in case of RSA key pair try also encryption/decryption. - * Hash algorithm does not matter when padding mode is PKCS1 v1.5, whereas - * it must be not null or any in case of v2.1 (OAEP). */ - int test_encryption = (PSA_ALG_IS_RSA_PKCS1V15_SIGN(key_alg) || - (key_alg == PSA_ALG_RSA_PKCS1V15_CRYPT) || - is_psa_hash_alg_specified); - if ((key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) && test_encryption) { + /* Test #5: in case of RSA key pair try also encryption/decryption. */ + if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(key_alg)) { /* Encrypt with the public key only PK context. */ TEST_EQUAL(mbedtls_pk_encrypt(&pk_pub, in_buf, in_buf_len, out_buf, &out_buf_len, sizeof(out_buf), From 1015985d8a1b1805a4d7d9ecb729663f68caa2a2 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 23 Feb 2024 16:54:07 +0100 Subject: [PATCH 067/211] test_suite_pk: add more test cases for pk_copy_from_psa_success() Signed-off-by: Valerio Setti --- tests/suites/test_suite_pk.data | 43 ++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data index 55dea93f82..85f290470a 100644 --- a/tests/suites/test_suite_pk.data +++ b/tests/suites/test_suite_pk.data @@ -1455,21 +1455,46 @@ pk_import_into_psa_opaque:PSA_KEY_TYPE_ECC_KEY_PAIR(MBEDTLS_TEST_PSA_ECC_ONE_FAM PSA import into PSA: opaque ECC to public, different family (bad) depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:MBEDTLS_TEST_PSA_ECC_HAVE_TWO_FAMILIES:PSA_WANT_ALG_ECDSA pk_import_into_psa_opaque:PSA_KEY_TYPE_ECC_KEY_PAIR(MBEDTLS_TEST_PSA_ECC_ONE_FAMILY):MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE:0:PSA_KEY_TYPE_ECC_PUBLIC_KEY(MBEDTLS_TEST_PSA_ECC_ANOTHER_FAMILY):MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE:0:MBEDTLS_ERR_PK_TYPE_MISMATCH + Copy from PSA: use wrong parameters pk_copy_from_psa_fail: -Copy from PSA: valid EC (SECP_R1_256 + ANY_HASH) +Copy from PSA: valid EC (SECP_R1_256 + ECDSA + ANY_HASH) depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDSA(PSA_ALG_ANY_HASH) -Copy from PSA: valid EC (SECP_R1_256 + SHA_256) +Copy from PSA: valid EC (SECP_R1_256 + ECDSA + SHA_256) depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDSA(PSA_ALG_SHA_256) -Copy from PSA: valid EC (SECP_R1_256 + SHA_512) +Copy from PSA: valid EC (SECP_R1_256 + ECDSA + SHA_512) depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA512 pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDSA(PSA_ALG_SHA_512) +Copy from PSA: valid EC (SECP_R1_256 + DET_ECDSA + ANY_HASH) +depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 +pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH) + +Copy from PSA: valid EC (SECP_R1_256 + DET_ECDSA + SHA_256) +depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 +pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256) + +Copy from PSA: valid EC (SECP_R1_256 + DET_ECDSA + SHA_512) +depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA512 +pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_512) + +Copy from PSA: valid EC (SECP_R1_256 + ECDSA_ANY) +depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 +pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDSA_ANY + +Copy from PSA: valid EC (SECP_R1_521 + ECDSA + SHA_256) +depends_on:MBEDTLS_ECP_HAVE_SECP521R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 +pk_copy_from_psa_success:"005dbb8e12240a62932b88cdd93c31cdd8873a2c15e40cc3c9f8e695b77fae015a44fe5267ef7868cb28cfb9579282fe060de44fe6de26f74a0d94afdaa870befbc5":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDSA(PSA_ALG_SHA_256) + +Copy from PSA: valid EC (SECP_K1_256 + ECDSA + SHA_256) +depends_on:MBEDTLS_ECP_HAVE_SECP256K1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 +pk_copy_from_psa_success:"7154f04fcc79ac9df1652dcf99031610592b2b27f74f5985690a987357ba0428":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_K1):PSA_ALG_ECDSA(PSA_ALG_SHA_256) + Copy from PSA: valid RSA (PKCS1V15_SIGN + ANY_HASH) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256 pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH) @@ -1505,3 +1530,15 @@ pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1 Copy from PSA: valid RSA (PSS_ANY_SALT + SHA_512) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA512 pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_512) + +Copy from PSA: valid RSA (PSS + ANY_HASH) +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256 +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH) + +Copy from PSA: valid RSA (PSS + SHA_256) +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256 +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256) + +Copy from PSA: valid RSA (PSS + SHA_512) +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA512 +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PSS(PSA_ALG_SHA_512) From a657ae388a3247d4d633b6afcf6d56bfef477536 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 23 Feb 2024 17:55:28 +0100 Subject: [PATCH 068/211] pk: pk_copy_from_psa() performs the conversion even if the algorithm doesn't match This commit also: - fixes existing tests and add new ones - updates documentation. Signed-off-by: Valerio Setti --- include/mbedtls/pk.h | 19 ++++++++----------- library/pk.c | 15 ++------------- tests/suites/test_suite_pk.data | 18 ++++++++++++++++++ tests/suites/test_suite_pk.function | 16 +++++++++++++++- 4 files changed, 43 insertions(+), 25 deletions(-) diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h index 90f4ac63a1..3bd4f80f01 100644 --- a/include/mbedtls/pk.h +++ b/include/mbedtls/pk.h @@ -394,7 +394,7 @@ int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx, /** * \brief Create a PK context starting from a key stored in PSA. * This key: - * - must be exportabel and + * - must be exportable and * - must be a either an RSA or EC key (DH is not managed in PK) and * - must be either a key pair or a public key. * @@ -407,19 +407,16 @@ int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx, * from. * Calling mbedtls_pk_sign(), mbedtls_pk_verify(), * mbedtls_pk_encrypt(), mbedtls_pk_decrypt() on the resulting - * PK context will perform an algorithm that is compatible with - * the PSA key's primary algorithm policy if that is a matching - * operation type (sign/verify, encrypt/decrypt), but with no - * restriction on the hash (as if the policy had - * #PSA_ALG_ANY_HASH instead of a specific hash, and with - * #PSA_ALG_RSA_PKCS1V15_SIGN_RAW merged with - * #PSA_ALG_RSA_PKCS1V15_SIGN(\c hash_alg)). + * PK context will perform the corresponding algorithm for that + * PK context type. * * For ECDSA, the choice of deterministic vs randomized will * be based on the compile-time setting #MBEDTLS_ECDSA_DETERMINISTIC. - * * For an RSA key, the output key will allow both encrypt/decrypt - * and sign/verify regardless of the original key's policy. + * * For an RSA key, the output PK context will allow both + * encrypt/decrypt and sign/verify regardless of the original + * key's policy. * The original key's policy determines the output key's padding - * mode. + * mode: PCKS1 v2.1 is set if the PSA key policy is OAEP or PSS, + * otherwise PKCS1 v1.5 is set. * * \param key_id The key identifier of the key stored in PSA. * \param pk The PK context that will be filled. It must be initialized, diff --git a/library/pk.c b/library/pk.c index 56f8bb10b9..b25dd28c0b 100644 --- a/library/pk.c +++ b/library/pk.c @@ -27,7 +27,7 @@ #include "mbedtls/ecdsa.h" #endif -#if defined(MBEDTLS_PSA_CRYPTO_C) +#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) #include "psa_util_internal.h" #include "mbedtls/psa_util.h" #endif @@ -1413,12 +1413,6 @@ int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk #if defined(MBEDTLS_RSA_C) if ((key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) || (key_type == PSA_KEY_TYPE_RSA_PUBLIC_KEY)) { - if (!PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg_type) && - (alg_type != PSA_ALG_RSA_PKCS1V15_CRYPT) && - !PSA_ALG_IS_RSA_OAEP(alg_type) && - !PSA_ALG_IS_RSA_PSS(alg_type)) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)); if (ret != 0) { @@ -1435,7 +1429,7 @@ int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk } mbedtls_md_type_t md_type = MBEDTLS_MD_NONE; - if ((alg_type != PSA_ALG_RSA_PKCS1V15_CRYPT) && + if ((PSA_ALG_GET_HASH(alg_type) != PSA_ALG_NONE) && (PSA_ALG_GET_HASH(alg_type) != PSA_ALG_ANY_HASH)) { md_type = mbedtls_md_type_from_psa_alg(alg_type); } @@ -1455,11 +1449,6 @@ int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type)) { mbedtls_ecp_group_id grp_id; - if (!PSA_ALG_IS_ECDSA(alg_type)) { - ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; - goto exit; - } - ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); if (ret != 0) { goto exit; diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data index 85f290470a..83b21ea5e4 100644 --- a/tests/suites/test_suite_pk.data +++ b/tests/suites/test_suite_pk.data @@ -1495,6 +1495,18 @@ Copy from PSA: valid EC (SECP_K1_256 + ECDSA + SHA_256) depends_on:MBEDTLS_ECP_HAVE_SECP256K1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 pk_copy_from_psa_success:"7154f04fcc79ac9df1652dcf99031610592b2b27f74f5985690a987357ba0428":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_K1):PSA_ALG_ECDSA(PSA_ALG_SHA_256) +# The key's algorithm only allows ECDH, but pk_copy_from_psa() ignores this information +# when building the PK context. +Copy from PSA: valid EC, wrong alg (SECP_R1_256 + ECDH) +depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 +pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDH + +# The key's algorithm is absolutely wrong for an EC key, but pk_copy_from_psa() +# ignores this information when building the PK context. +Copy from PSA: valid EC, wrong alg (SECP_R1_256 + CMAC) +depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY +pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_CMAC + Copy from PSA: valid RSA (PKCS1V15_SIGN + ANY_HASH) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256 pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH) @@ -1542,3 +1554,9 @@ pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1 Copy from PSA: valid RSA (PSS + SHA_512) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA512 pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PSS(PSA_ALG_SHA_512) + +# Key's algorithm is wrong for an RSA key, but pk_copy_from_psa() ignores +# this information when building the PK context. +Copy from PSA: valid RSA, wrong alg (CMAC) +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_CMAC diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 69546b20f5..169bef895d 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -2360,13 +2360,27 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, pub_key_id = psa_pub_key_from_priv(priv_key_id); TEST_EQUAL(mbedtls_pk_copy_from_psa(pub_key_id, &pk_pub), 0); - /* Test #1: check that the generated PK contexts are of the correct type. */ + /* Test #1: + * - check that the generated PK contexts are of the correct type. + * - [only for RSA] check that the padding mode is correct. + */ if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type)) { TEST_EQUAL(mbedtls_pk_get_type(&pk_priv), MBEDTLS_PK_ECKEY); TEST_EQUAL(mbedtls_pk_get_type(&pk_pub), MBEDTLS_PK_ECKEY); } else { TEST_EQUAL(mbedtls_pk_get_type(&pk_priv), MBEDTLS_PK_RSA); TEST_EQUAL(mbedtls_pk_get_type(&pk_pub), MBEDTLS_PK_RSA); +#if defined(MBEDTLS_RSA_C) + mbedtls_rsa_context *rsa_priv = mbedtls_pk_rsa(pk_priv); + mbedtls_rsa_context *rsa_pub = mbedtls_pk_rsa(pk_pub); + if (PSA_ALG_IS_RSA_OAEP(key_alg) || PSA_ALG_IS_RSA_PSS(key_alg)) { + TEST_EQUAL(mbedtls_rsa_get_padding_mode(rsa_priv), MBEDTLS_RSA_PKCS_V21); + TEST_EQUAL(mbedtls_rsa_get_padding_mode(rsa_pub), MBEDTLS_RSA_PKCS_V21); + } else { + TEST_EQUAL(mbedtls_rsa_get_padding_mode(rsa_priv), MBEDTLS_RSA_PKCS_V15); + TEST_EQUAL(mbedtls_rsa_get_padding_mode(rsa_pub), MBEDTLS_RSA_PKCS_V15); + } +#endif /* MBEDTLS_RSA_C */ } /* Test #2: check that the 2 generated PK contexts form a valid private/public key pair. */ From f22eff99a6813b12c0b4d8bbca8ba9c0bfa69d40 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 23 Feb 2024 18:26:07 +0100 Subject: [PATCH 069/211] test_suite_pk: add new test case for an algorithm only avaible in driver Signed-off-by: Valerio Setti --- tests/suites/test_suite_pk.data | 3 +++ tests/suites/test_suite_pk.function | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data index 83b21ea5e4..570acb057d 100644 --- a/tests/suites/test_suite_pk.data +++ b/tests/suites/test_suite_pk.data @@ -1459,6 +1459,9 @@ pk_import_into_psa_opaque:PSA_KEY_TYPE_ECC_KEY_PAIR(MBEDTLS_TEST_PSA_ECC_ONE_FAM Copy from PSA: use wrong parameters pk_copy_from_psa_fail: +Copy from PSA: accelerated key only, not available as built-in +pk_copy_from_psa_builtin_fail: + Copy from PSA: valid EC (SECP_R1_256 + ECDSA + ANY_HASH) depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDSA(PSA_ALG_ANY_HASH) diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 169bef895d..ad26caaea8 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -2312,6 +2312,28 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN:MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_BASIC:!RSA_C */ +void pk_copy_from_psa_builtin_fail() +{ + mbedtls_pk_context pk_ctx; + mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; + + mbedtls_pk_init(&pk_ctx); + PSA_INIT(); + + PSA_ASSERT(pk_psa_genkey_generic(PSA_KEY_TYPE_RSA_KEY_PAIR, + PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS, + PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT, + PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256), + &key_id)); + TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, &pk_ctx), MBEDTLS_ERR_PK_BAD_INPUT_DATA); +exit: + mbedtls_pk_free(&pk_ctx); + psa_destroy_key(key_id); + PSA_DONE(); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C*/ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, int key_alg_arg) From e700d8086e9ee8a7f3bd5dcf1fb4e9dd386672b3 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 26 Feb 2024 13:52:34 +0100 Subject: [PATCH 070/211] rsa: rsa_rsassa_pss_sign() to check MD alg both in parameters and RSA context This helps fixing a disparity between the legacy and the USE_PSA case for rsa_sign_wrap() in pk_wrap.c. Signed-off-by: Valerio Setti --- library/rsa.c | 2 +- tests/suites/test_suite_pk.function | 23 +++-------------------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/library/rsa.c b/library/rsa.c index 5debc69b3d..7eb4a259ea 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -2231,7 +2231,7 @@ static int rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx, if (ctx->padding != MBEDTLS_RSA_PKCS_V21) { return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; } - if (ctx->hash_id == MBEDTLS_MD_NONE) { + if ((ctx->hash_id == MBEDTLS_MD_NONE) && (md_alg == MBEDTLS_MD_NONE)) { return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; } return rsa_rsassa_pss_sign_no_mode_check(ctx, f_rng, p_rng, md_alg, hashlen, hash, saltlen, diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index ad26caaea8..9112397d3f 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -2413,27 +2413,10 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, * - Verify from the same PK context used for signature. * - Verify with the PK context generated using public key. * - Verify using the public PSA key directly. - * - * Note: PSS requires the hash to be specified on sign operation (i.e. not - * null or any), so in case PSA_ALG_ANY_HASH is provided as input, we - * use mbedtls_pk_sign_ext() instead of mbedtls_pk_sign(). */ - if ((PSA_ALG_IS_RSA_OAEP(key_alg) || PSA_ALG_IS_RSA_PSS(key_alg)) && - (!is_psa_hash_alg_specified)) { - /* Ensure pk_sign() fails without crashing. */ - TEST_EQUAL(mbedtls_pk_sign(&pk_priv, md_for_test, in_buf, in_buf_len, - out_buf, sizeof(out_buf), &out_buf_len, - mbedtls_test_rnd_std_rand, NULL), - MBEDTLS_ERR_RSA_BAD_INPUT_DATA); - TEST_EQUAL(mbedtls_pk_sign_ext(MBEDTLS_PK_RSASSA_PSS, &pk_priv, md_for_test, - in_buf, in_buf_len, - out_buf, sizeof(out_buf), &out_buf_len, - mbedtls_test_rnd_std_rand, NULL), 0); - } else { - TEST_EQUAL(mbedtls_pk_sign(&pk_priv, md_for_test, in_buf, in_buf_len, - out_buf, sizeof(out_buf), &out_buf_len, - mbedtls_test_rnd_std_rand, NULL), 0); - } + TEST_EQUAL(mbedtls_pk_sign(&pk_priv, md_for_test, in_buf, in_buf_len, + out_buf, sizeof(out_buf), &out_buf_len, + mbedtls_test_rnd_std_rand, NULL), 0); TEST_EQUAL(mbedtls_pk_verify(&pk_priv, md_for_test, in_buf, in_buf_len, out_buf, out_buf_len), 0); From 42a58a52494a979cf6f8f9b542975b874ade3ae6 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 27 Feb 2024 13:38:57 +0100 Subject: [PATCH 071/211] test_suite_pk: minor fixes for test failures Signed-off-by: Valerio Setti --- tests/suites/test_suite_pk.data | 10 +++++----- tests/suites/test_suite_pk.function | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data index 570acb057d..76b4a77417 100644 --- a/tests/suites/test_suite_pk.data +++ b/tests/suites/test_suite_pk.data @@ -1475,15 +1475,15 @@ depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_E pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDSA(PSA_ALG_SHA_512) Copy from PSA: valid EC (SECP_R1_256 + DET_ECDSA + ANY_HASH) -depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 +depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_ECDSA_DETERMINISTIC:MBEDTLS_MD_CAN_SHA256 pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH) Copy from PSA: valid EC (SECP_R1_256 + DET_ECDSA + SHA_256) -depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 +depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_ECDSA_DETERMINISTIC:MBEDTLS_MD_CAN_SHA256 pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256) Copy from PSA: valid EC (SECP_R1_256 + DET_ECDSA + SHA_512) -depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA512 +depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_ECDSA_DETERMINISTIC:MBEDTLS_MD_CAN_SHA512 pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_512) Copy from PSA: valid EC (SECP_R1_256 + ECDSA_ANY) @@ -1507,7 +1507,7 @@ pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F # The key's algorithm is absolutely wrong for an EC key, but pk_copy_from_psa() # ignores this information when building the PK context. Copy from PSA: valid EC, wrong alg (SECP_R1_256 + CMAC) -depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY +depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_CMAC Copy from PSA: valid RSA (PKCS1V15_SIGN + ANY_HASH) @@ -1561,5 +1561,5 @@ pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1 # Key's algorithm is wrong for an RSA key, but pk_copy_from_psa() ignores # this information when building the PK context. Copy from PSA: valid RSA, wrong alg (CMAC) -depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256 pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_CMAC diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 9112397d3f..4ec73a3b04 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -2312,7 +2312,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN:MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_BASIC:!RSA_C */ +/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN:MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_BASIC:!MBEDTLS_RSA_C */ void pk_copy_from_psa_builtin_fail() { mbedtls_pk_context pk_ctx; From 4114a54403e66dd136b289704c981572e4d306fd Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 28 Feb 2024 16:32:01 +0100 Subject: [PATCH 072/211] test_suite_pk: add description for psa_pub_key_from_priv() Signed-off-by: Valerio Setti --- tests/suites/test_suite_pk.function | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 4ec73a3b04..4ad0113337 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -428,6 +428,14 @@ exit: #endif #if defined(MBEDTLS_PSA_CRYPTO_C) +/* Create a new PSA key which will contain only the public part of the private + * key which is provided in input. For this new key: + * - Type is the public counterpart of the private key. + * - Usage is the copied from the original private key, but the PSA_KEY_USAGE_EXPORT + * flag is removed. This is to prove that public keys are always exportable + * even if the EXPORT flag is not explicitly set. + * - Algorithm is copied from the original key pair. + */ static mbedtls_svc_key_id_t psa_pub_key_from_priv(mbedtls_svc_key_id_t priv_id) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; @@ -452,8 +460,6 @@ static mbedtls_svc_key_id_t psa_pub_key_from_priv(mbedtls_svc_key_id_t priv_id) * - psa_import_key() automatically determines the key's bit length * from the provided key data. That's why psa_set_key_bits() is not used * below. - * - public keys are always exportable by default even if PSA_KEY_USAGE_EXPORT - * is not set. */ type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type); usage &= ~PSA_KEY_USAGE_EXPORT; From 039bbbac3397a0d8b6b3d199b659a77acb88b816 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 29 Feb 2024 07:24:26 +0100 Subject: [PATCH 073/211] test_suite_pk: destroy original xkey after pk_copy_from_psa() in pk_copy_from_psa_success() Signed-off-by: Valerio Setti --- tests/suites/test_suite_pk.function | 37 ++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 4ad0113337..5cc924c0c0 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -474,6 +474,27 @@ exit: return pub_key; } +/* Create a copy of a PSA key with same usage and algorithm policy and destroy + * the original one. */ +mbedtls_svc_key_id_t psa_copy_and_destroy(mbedtls_svc_key_id_t orig_key_id) +{ + psa_key_attributes_t orig_attr = PSA_KEY_ATTRIBUTES_INIT; + psa_key_attributes_t new_attr = PSA_KEY_ATTRIBUTES_INIT; + mbedtls_svc_key_id_t new_key_id = MBEDTLS_SVC_KEY_ID_INIT; + + PSA_ASSERT(psa_get_key_attributes(orig_key_id, &orig_attr)); + psa_set_key_usage_flags(&new_attr, psa_get_key_usage_flags(&orig_attr)); + psa_set_key_algorithm(&new_attr, psa_get_key_algorithm(&orig_attr)); + + PSA_ASSERT(psa_copy_key(orig_key_id, &new_attr, &new_key_id)); + psa_destroy_key(orig_key_id); + +exit: + psa_reset_key_attributes(&orig_attr); + psa_reset_key_attributes(&new_attr); + return new_key_id; +} + psa_status_t pk_psa_import_key(unsigned char *key_data, size_t key_len, psa_key_type_t type, psa_key_usage_t usage, psa_algorithm_t alg, mbedtls_svc_key_id_t *key) @@ -2347,7 +2368,7 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, psa_key_type_t key_type = key_type_arg; psa_algorithm_t key_alg = key_alg_arg; psa_key_usage_t key_usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | - PSA_KEY_USAGE_EXPORT; + PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY; mbedtls_pk_context pk_priv, pk_pub; mbedtls_svc_key_id_t priv_key_id = MBEDTLS_SVC_KEY_ID_INIT; mbedtls_svc_key_id_t pub_key_id = MBEDTLS_SVC_KEY_ID_INIT; @@ -2378,16 +2399,20 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, key_usage |= PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT; } - /* Create a private key in PSA and create a PK context from it. */ + /* Create both a private key and its public counterpart in PSA. */ PSA_ASSERT(pk_psa_import_key(priv_key_data->x, priv_key_data->len, key_type, key_usage, key_alg, &priv_key_id)); - TEST_EQUAL(mbedtls_pk_copy_from_psa(priv_key_id, &pk_priv), 0); - - /* Generate a 2nd PK contex using only the public key derived from its private - * counterpart generated above. */ pub_key_id = psa_pub_key_from_priv(priv_key_id); + + /* Generate 2 PK contexts starting from the PSA keys we just created. */ + TEST_EQUAL(mbedtls_pk_copy_from_psa(priv_key_id, &pk_priv), 0); TEST_EQUAL(mbedtls_pk_copy_from_psa(pub_key_id, &pk_pub), 0); + /* Destoy both PSA keys to prove that generated PK contexts are independent + * from them. */ + priv_key_id = psa_copy_and_destroy(priv_key_id); + pub_key_id = psa_copy_and_destroy(pub_key_id); + /* Test #1: * - check that the generated PK contexts are of the correct type. * - [only for RSA] check that the padding mode is correct. From 3433f832fb3db6adf2548662917c169d2ebcbac1 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 29 Feb 2024 09:03:08 +0100 Subject: [PATCH 074/211] test_suite_pk: improve PSA alg selection in pk_copy_from_psa_success() Use the same hashing algorithm as md_for_test. Signed-off-by: Valerio Setti --- tests/suites/test_suite_pk.function | 37 ++++++++++++++++------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 5cc924c0c0..cac86ca8a4 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -2382,19 +2382,6 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, mbedtls_pk_init(&pk_pub); PSA_INIT(); - /* Get the MD type to be used for the tests below from the provided key policy. */ - mbedtls_md_type_t md_for_test = MBEDTLS_MD_SHA256; /* Default */ - int is_psa_hash_alg_specified = 0; - if ((PSA_ALG_GET_HASH(key_alg) != PSA_ALG_NONE) && - (PSA_ALG_GET_HASH(key_alg) != PSA_ALG_ANY_HASH)) { - md_for_test = mbedtls_md_type_from_psa_alg(key_alg); - is_psa_hash_alg_specified = 1; - } - - in_buf_len = mbedtls_md_get_size_from_type(md_for_test); - TEST_CALLOC(in_buf, in_buf_len); - memset(in_buf, 0x1, in_buf_len); - if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) { key_usage |= PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT; } @@ -2439,6 +2426,22 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, /* Test #2: check that the 2 generated PK contexts form a valid private/public key pair. */ TEST_EQUAL(mbedtls_pk_check_pair(&pk_pub, &pk_priv, mbedtls_test_rnd_std_rand, NULL), 0); + /* Get the MD alg to be used for the tests below from the provided key policy. */ + mbedtls_md_type_t md_for_test = MBEDTLS_MD_SHA256; /* Default */ + if ((PSA_ALG_GET_HASH(key_alg) != PSA_ALG_NONE) && + (PSA_ALG_GET_HASH(key_alg) != PSA_ALG_ANY_HASH)) { + md_for_test = mbedtls_md_type_from_psa_alg(key_alg); + } + /* Use also the same MD algorithm for PSA sign/verify checks. This is helpful + * for the cases in which the key policy algorithm is ANY_HASH type. */ + psa_algorithm_t psa_alg_for_test = + (key_alg & ~PSA_ALG_HASH_MASK) | + (mbedtls_md_psa_alg_from_type(md_for_test) & PSA_ALG_HASH_MASK); + + in_buf_len = mbedtls_md_get_size_from_type(md_for_test); + TEST_CALLOC(in_buf, in_buf_len); + memset(in_buf, 0x1, in_buf_len); + /* Test #3: sign/verify with the following pattern: * - Sign using the PK context generated from the private key. * - Verify from the same PK context used for signature. @@ -2454,7 +2457,7 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, TEST_EQUAL(mbedtls_pk_verify(&pk_pub, md_for_test, in_buf, in_buf_len, out_buf, out_buf_len), 0); - if (PSA_ALG_IS_SIGN(key_alg) && is_psa_hash_alg_specified) { + if (PSA_ALG_IS_HASH_AND_SIGN(key_alg)) { #if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA) /* ECDSA signature requires PK->PSA format conversion. */ if (PSA_ALG_IS_ECDSA(key_alg)) { @@ -2463,7 +2466,7 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, sizeof(out_buf), &out_buf_len), 0); } #endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */ - PSA_ASSERT(psa_verify_hash(pub_key_id, key_alg, in_buf, in_buf_len, + PSA_ASSERT(psa_verify_hash(pub_key_id, psa_alg_for_test, in_buf, in_buf_len, out_buf, out_buf_len)); } @@ -2471,8 +2474,8 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, * sign with PSA and verify with PK. Key's policy must include a valid hash * algorithm (not any). */ - if (PSA_ALG_IS_SIGN(key_alg) && is_psa_hash_alg_specified) { - PSA_ASSERT(psa_sign_hash(priv_key_id, key_alg, in_buf, in_buf_len, + if (PSA_ALG_IS_HASH_AND_SIGN(key_alg)) { + PSA_ASSERT(psa_sign_hash(priv_key_id, psa_alg_for_test, in_buf, in_buf_len, out_buf, sizeof(out_buf), &out_buf_len)); #if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA) /* ECDSA signature requires PSA->PK format conversion */ From ab7ddbc8121f11c8df53547ea73f821708ec777c Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 29 Feb 2024 09:30:05 +0100 Subject: [PATCH 075/211] test_suite_pk: when ANY_HASH is used then pick any available MD alg in the build Signed-off-by: Valerio Setti --- tests/suites/test_suite_pk.data | 16 ++++++++-------- tests/suites/test_suite_pk.function | 15 ++++++++++++++- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data index 76b4a77417..f2e2c62ac1 100644 --- a/tests/suites/test_suite_pk.data +++ b/tests/suites/test_suite_pk.data @@ -1463,7 +1463,7 @@ Copy from PSA: accelerated key only, not available as built-in pk_copy_from_psa_builtin_fail: Copy from PSA: valid EC (SECP_R1_256 + ECDSA + ANY_HASH) -depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 +depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_ALG_FOR_TEST pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDSA(PSA_ALG_ANY_HASH) Copy from PSA: valid EC (SECP_R1_256 + ECDSA + SHA_256) @@ -1475,7 +1475,7 @@ depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_E pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDSA(PSA_ALG_SHA_512) Copy from PSA: valid EC (SECP_R1_256 + DET_ECDSA + ANY_HASH) -depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_ECDSA_DETERMINISTIC:MBEDTLS_MD_CAN_SHA256 +depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_ECDSA_DETERMINISTIC:MBEDTLS_MD_ALG_FOR_TEST pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH) Copy from PSA: valid EC (SECP_R1_256 + DET_ECDSA + SHA_256) @@ -1487,7 +1487,7 @@ depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_E pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_512) Copy from PSA: valid EC (SECP_R1_256 + ECDSA_ANY) -depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256 +depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_ALG_FOR_TEST pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_ECDSA_ANY Copy from PSA: valid EC (SECP_R1_521 + ECDSA + SHA_256) @@ -1511,7 +1511,7 @@ depends_on:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_PK_CAN_E pk_copy_from_psa_success:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):PSA_ALG_CMAC Copy from PSA: valid RSA (PKCS1V15_SIGN + ANY_HASH) -depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256 +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_ALG_FOR_TEST pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH) Copy from PSA: valid RSA (PKCS1V15_SIGN + SHA_256) @@ -1523,7 +1523,7 @@ depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA512 pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_512) Copy from PSA: valid RSA (PKCS1V15_CRYPT) -depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256 +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_ALG_FOR_TEST pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_CRYPT Copy from PSA: valid RSA (OAEP + SHA_256) @@ -1535,7 +1535,7 @@ depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA512 pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_512) Copy from PSA: valid RSA (PSS_ANY_SALT + ANY_HASH) -depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256 +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_ALG_FOR_TEST pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH) Copy from PSA: valid RSA (PSS_ANY_SALT + SHA_256) @@ -1547,7 +1547,7 @@ depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA512 pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_512) Copy from PSA: valid RSA (PSS + ANY_HASH) -depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256 +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_ALG_FOR_TEST pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH) Copy from PSA: valid RSA (PSS + SHA_256) @@ -1561,5 +1561,5 @@ pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1 # Key's algorithm is wrong for an RSA key, but pk_copy_from_psa() ignores # this information when building the PK context. Copy from PSA: valid RSA, wrong alg (CMAC) -depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256 +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_ALG_FOR_TEST pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_CMAC diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index cac86ca8a4..b22f20c599 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -169,6 +169,19 @@ #define MBEDTLS_TEST_PSA_ECC_ANOTHER_CURVE_BITS 0 #endif +/* Get an available MD alg to be used in sign/verify tests. */ +#if defined(MBEDTLS_MD_CAN_SHA1) +#define MBEDTLS_MD_ALG_FOR_TEST MBEDTLS_MD_SHA1 +#elif defined(MBEDTLS_MD_CAN_SHA224) +#define MBEDTLS_MD_ALG_FOR_TEST MBEDTLS_MD_SHA224 +#elif defined(MBEDTLS_MD_CAN_SHA256) +#define MBEDTLS_MD_ALG_FOR_TEST MBEDTLS_MD_SHA256 +#elif defined(MBEDTLS_MD_CAN_SHA384) +#define MBEDTLS_MD_ALG_FOR_TEST MBEDTLS_MD_SHA384 +#elif defined(MBEDTLS_MD_CAN_SHA512) +#define MBEDTLS_MD_ALG_FOR_TEST MBEDTLS_MD_SHA512 +#endif + #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) static int pk_genkey_ec(mbedtls_pk_context *pk, mbedtls_ecp_group_id grp_id) { @@ -2427,7 +2440,7 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, TEST_EQUAL(mbedtls_pk_check_pair(&pk_pub, &pk_priv, mbedtls_test_rnd_std_rand, NULL), 0); /* Get the MD alg to be used for the tests below from the provided key policy. */ - mbedtls_md_type_t md_for_test = MBEDTLS_MD_SHA256; /* Default */ + mbedtls_md_type_t md_for_test = MBEDTLS_MD_ALG_FOR_TEST; /* Default */ if ((PSA_ALG_GET_HASH(key_alg) != PSA_ALG_NONE) && (PSA_ALG_GET_HASH(key_alg) != PSA_ALG_ANY_HASH)) { md_for_test = mbedtls_md_type_from_psa_alg(key_alg); From 4f1650d4af72952080c2471d91403e6658b77532 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 29 Feb 2024 11:37:10 +0100 Subject: [PATCH 076/211] changelog: enhance description Signed-off-by: Valerio Setti --- ChangeLog.d/8709.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog.d/8709.txt b/ChangeLog.d/8709.txt index 52b96096c4..a95cedf138 100644 --- a/ChangeLog.d/8709.txt +++ b/ChangeLog.d/8709.txt @@ -1,3 +1,5 @@ Features * The new function mbedtls_pk_copy_from_psa() provides a way to setup - a PK context starting from a PSA key. + a PK context starting from a PSA key. In contrast to + mbedtls_pk_setup_opaque() the resulting PK context is a normal context + that's independent from the original PSA key. From 64d5fc0070cf6a1fe7e09d773df9dd2e3be961c6 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 11 Mar 2024 09:52:59 +0100 Subject: [PATCH 077/211] changelog: fix text and typos Signed-off-by: Valerio Setti --- ChangeLog.d/8709.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ChangeLog.d/8709.txt b/ChangeLog.d/8709.txt index a95cedf138..8c1579755d 100644 --- a/ChangeLog.d/8709.txt +++ b/ChangeLog.d/8709.txt @@ -1,5 +1,5 @@ Features - * The new function mbedtls_pk_copy_from_psa() provides a way to setup - a PK context starting from a PSA key. In contrast to - mbedtls_pk_setup_opaque() the resulting PK context is a normal context - that's independent from the original PSA key. + * The new function mbedtls_pk_copy_from_psa() provides a way to set up + a PK context starting from a PSA key. The new function + mbedtls_pk_copy_from_psa() provides a way to set up a PK context with the + same content as a PSA key. From 3b98c640ce8df941259ffde780c83138b337ff8e Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 11 Mar 2024 09:54:25 +0100 Subject: [PATCH 078/211] pk: fix documentation for mbedtls_pk_copy_from_psa() Signed-off-by: Valerio Setti --- include/mbedtls/pk.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h index 3bd4f80f01..87e6f63928 100644 --- a/include/mbedtls/pk.h +++ b/include/mbedtls/pk.h @@ -395,8 +395,7 @@ int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx, * \brief Create a PK context starting from a key stored in PSA. * This key: * - must be exportable and - * - must be a either an RSA or EC key (DH is not managed in PK) and - * - must be either a key pair or a public key. + * - must be an RSA or EC key pair or public key (FFDH is not supported in PK). * * The resulting PK object will be a transparent type: * - #MBEDTLS_PK_RSA for RSA keys or @@ -423,7 +422,7 @@ int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx, * but not set up. * * \return 0 on success. - * \return MBEDTLS_ERR_PK_BAD_INPUT_DATA in case the provided input + * \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA in case the provided input * parameters are not correct. */ int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk); From 6f5f9f5ce8ebb68ba65f528ca90b5b59d20a3e6a Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 11 Mar 2024 10:04:54 +0100 Subject: [PATCH 079/211] test_suite_pk: fix some comments Signed-off-by: Valerio Setti --- tests/suites/test_suite_pk.function | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index b22f20c599..d9ea0be0bf 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -445,8 +445,8 @@ exit: * key which is provided in input. For this new key: * - Type is the public counterpart of the private key. * - Usage is the copied from the original private key, but the PSA_KEY_USAGE_EXPORT - * flag is removed. This is to prove that public keys are always exportable - * even if the EXPORT flag is not explicitly set. + * flag is removed. This is to prove that mbedtls_pk_copy_from_psa() doesn't + * require the key to have the EXPORT flag. * - Algorithm is copied from the original key pair. */ static mbedtls_svc_key_id_t psa_pub_key_from_priv(mbedtls_svc_key_id_t priv_id) @@ -2404,7 +2404,7 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, key_type, key_usage, key_alg, &priv_key_id)); pub_key_id = psa_pub_key_from_priv(priv_key_id); - /* Generate 2 PK contexts starting from the PSA keys we just created. */ + /* Create 2 PK contexts starting from the PSA keys we just created. */ TEST_EQUAL(mbedtls_pk_copy_from_psa(priv_key_id, &pk_priv), 0); TEST_EQUAL(mbedtls_pk_copy_from_psa(pub_key_id, &pk_pub), 0); From e095a67bb249d48cb72ef9a0c8575941366017ff Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 11 Mar 2024 10:09:32 +0100 Subject: [PATCH 080/211] pk: improve mbedtls_pk_copy_from_psa() Signed-off-by: Valerio Setti --- library/pk.c | 5 ++--- tests/suites/test_suite_pk.function | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/library/pk.c b/library/pk.c index b25dd28c0b..4345ea2f69 100644 --- a/library/pk.c +++ b/library/pk.c @@ -1402,7 +1402,7 @@ int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk status = psa_export_key(key_id, exp_key, sizeof(exp_key), &exp_key_len); if (status != PSA_SUCCESS) { - ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; + ret = PSA_PK_TO_MBEDTLS_ERR(status); goto exit; } @@ -1429,8 +1429,7 @@ int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk } mbedtls_md_type_t md_type = MBEDTLS_MD_NONE; - if ((PSA_ALG_GET_HASH(alg_type) != PSA_ALG_NONE) && - (PSA_ALG_GET_HASH(alg_type) != PSA_ALG_ANY_HASH)) { + if (PSA_ALG_GET_HASH(alg_type) != PSA_ALG_ANY_HASH) { md_type = mbedtls_md_type_from_psa_alg(alg_type); } diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index d9ea0be0bf..ccdab094f0 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -2340,7 +2340,7 @@ void pk_copy_from_psa_fail(void) /* Generate an EC key which cannot be exported. */ PSA_ASSERT(pk_psa_genkey_generic(PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 256, 0, PSA_ALG_NONE, &key_id)); - TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, &pk_ctx), MBEDTLS_ERR_PK_BAD_INPUT_DATA); + TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, &pk_ctx), MBEDTLS_ERR_PK_TYPE_MISMATCH); psa_destroy_key(key_id); #endif /* MBEDTLS_PK_HAVE_ECC_KEYS && PSA_WANT_ECC_SECP_R1_256 && PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE */ From d286491ed72d0fcd78bf7e545cf1205eea3f13b6 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 11 Mar 2024 15:46:40 +0100 Subject: [PATCH 081/211] changelog: fix text Signed-off-by: Valerio Setti --- ChangeLog.d/8709.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ChangeLog.d/8709.txt b/ChangeLog.d/8709.txt index 8c1579755d..a9b2751898 100644 --- a/ChangeLog.d/8709.txt +++ b/ChangeLog.d/8709.txt @@ -1,5 +1,3 @@ Features - * The new function mbedtls_pk_copy_from_psa() provides a way to set up - a PK context starting from a PSA key. The new function - mbedtls_pk_copy_from_psa() provides a way to set up a PK context with the - same content as a PSA key. + * The new function mbedtls_pk_copy_from_psa() provides a way to set up a PK + context with the same content as a PSA key. From 8b3c6fffa7319f0264de7605b820a45c6cc541b5 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 12 Mar 2024 06:05:03 +0100 Subject: [PATCH 082/211] test_suite_pk: add comment for pk_copy_from_psa_builtin_fail Explain why this kind of test is possible for RSA keys, while it is not possible for EC ones. Signed-off-by: Valerio Setti --- tests/suites/test_suite_pk.data | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data index f2e2c62ac1..18a1bb2063 100644 --- a/tests/suites/test_suite_pk.data +++ b/tests/suites/test_suite_pk.data @@ -1459,6 +1459,15 @@ pk_import_into_psa_opaque:PSA_KEY_TYPE_ECC_KEY_PAIR(MBEDTLS_TEST_PSA_ECC_ONE_FAM Copy from PSA: use wrong parameters pk_copy_from_psa_fail: +# The following test is only possible for RSA keys and not for EC ones: +# - for the former it is possible to have an accelerated RSA key in PSA while +# having RSA_C disabled. Since RSA path is guarded by RSA_C in mbedtls_pk_copy_from_psa(), +# any attempt to copy that key will fail. +# - for the latter instead the guard is PK_HAVE_ECC_KEYS which is enabled as soon +# as there is any curve supported either builtin or in a driver. In a scenario +# in which a certain EC key is only available through a driver and not as +# builtin mbedtls_pk_copy_from_psa() uses functions that will all succeed +# and therefore it will succeed. Copy from PSA: accelerated key only, not available as built-in pk_copy_from_psa_builtin_fail: From 6fbde6e242c55ec8456074ea98fef32994bedda8 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 12 Mar 2024 11:00:39 +0100 Subject: [PATCH 083/211] test_suite_pk: revert erroneous missing initialization of PSA key IDs Signed-off-by: Valerio Setti --- tests/suites/test_suite_pk.function | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index ccdab094f0..75dc4acae3 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -552,7 +552,7 @@ psa_status_t pk_psa_genkey_generic(psa_key_type_t type, size_t bits, */ 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; pk_psa_genkey_generic(PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 256, PSA_KEY_USAGE_SIGN_HASH, PSA_ALG_ECDSA(PSA_ALG_SHA_256), @@ -567,7 +567,7 @@ mbedtls_svc_key_id_t pk_psa_genkey_ecc(void) */ 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; pk_psa_genkey_generic(PSA_KEY_TYPE_RSA_KEY_PAIR, 1024, PSA_KEY_USAGE_SIGN_HASH, PSA_ALG_RSA_PKCS1V15_SIGN_RAW, &key); From 7caf2dc964a517f637cb47694b25998b52c7f869 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 12 Mar 2024 13:02:18 +0100 Subject: [PATCH 084/211] Discuss mbedtls_pk_copy_public_from_psa Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index e65507f270..f9ea3821d2 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -906,10 +906,11 @@ A future extension of the PSA API will support other export formats. Until those #### Exposing a PSA key via PK -This section discusses how to use a PSA key in a context that requires a PK object, such as PK formatting functions (`mbedtls_pk_write_key_der`, `mbedtls_pk_write_pubkey_der`, `mbedtls_pk_write_pubkey_pem`, `mbedtls_pk_write_key_pem` or `mbedtls_pk_write_pubkey`), Mbed TLS X.509 functions, Mbed TLS SSL functions, or another API that involves `mbedtls_pk_context` objects. Two functions from `pk.h` help with that: +This section discusses how to use a PSA key in a context that requires a PK object, such as PK formatting functions (`mbedtls_pk_write_key_der`, `mbedtls_pk_write_pubkey_der`, `mbedtls_pk_write_pubkey_pem`, `mbedtls_pk_write_key_pem` or `mbedtls_pk_write_pubkey`), Mbed TLS X.509 functions, Mbed TLS SSL functions, or another API that involves `mbedtls_pk_context` objects. Three functions from `pk.h` help with that: * [`mbedtls_pk_copy_from_psa`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1ab8e88836fd9ee344ffe630c40447bd08) copies a PSA key into a PK object. The PSA key must be exportable. The PK object remains valid even if the PSA key is destroyed. * [`mbedtls_pk_setup_opaque`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a4c04ac22ab9c1ae09cc29438c308bf05) sets up a PK object that wraps the PSA key. The PK object can only be used as permitted by the PSA key's policy. The PK object contains a reference to the PSA key identifier, therefore PSA key must not be destroyed as long as the PK object remains alive. +* [`mbedtls_pk_copy_public_from_psa`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a2a50247a528889c12ea0ddddb8b15a4e) copies a PSA key into a PK object. The PSA key must be exportable. The PK object remains valid even if the PSA key is destroyed. Here is some sample code illustrating how to use the PK module to format a PSA public key or the public key of a PSA key pair. ``` @@ -917,7 +918,7 @@ int write_psa_pubkey(psa_key_id_t key_id, unsigned char *buf, size_t size, size_t *len) { mbedtls_pk_context pk; mbedtls_pk_init(&pk); - int ret = mbedtls_pk_setup_opaque(&pk, key_id); + int ret = mbedtls_pk_copy_public_from_psa(key_id, &pk); if (ret != 0) goto exit; ret = mbedtls_pk_write_pubkey_der(&pk, buf, size); if (ret < 0) goto exit; From 0cff1116f77effb920d8a7e9047afef44f842f6e Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 12 Mar 2024 13:02:58 +0100 Subject: [PATCH 085/211] Remind the reader that PK doesn't support DH Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index f9ea3821d2..2c0e129b46 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -906,7 +906,7 @@ A future extension of the PSA API will support other export formats. Until those #### Exposing a PSA key via PK -This section discusses how to use a PSA key in a context that requires a PK object, such as PK formatting functions (`mbedtls_pk_write_key_der`, `mbedtls_pk_write_pubkey_der`, `mbedtls_pk_write_pubkey_pem`, `mbedtls_pk_write_key_pem` or `mbedtls_pk_write_pubkey`), Mbed TLS X.509 functions, Mbed TLS SSL functions, or another API that involves `mbedtls_pk_context` objects. Three functions from `pk.h` help with that: +This section discusses how to use a PSA key in a context that requires a PK object, such as PK formatting functions (`mbedtls_pk_write_key_der`, `mbedtls_pk_write_pubkey_der`, `mbedtls_pk_write_pubkey_pem`, `mbedtls_pk_write_key_pem` or `mbedtls_pk_write_pubkey`), Mbed TLS X.509 functions, Mbed TLS SSL functions, or another API that involves `mbedtls_pk_context` objects. The PSA key must be an RSA or ECC key since the PK module does not support DH keys. Three functions from `pk.h` help with that: * [`mbedtls_pk_copy_from_psa`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1ab8e88836fd9ee344ffe630c40447bd08) copies a PSA key into a PK object. The PSA key must be exportable. The PK object remains valid even if the PSA key is destroyed. * [`mbedtls_pk_setup_opaque`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a4c04ac22ab9c1ae09cc29438c308bf05) sets up a PK object that wraps the PSA key. The PK object can only be used as permitted by the PSA key's policy. The PK object contains a reference to the PSA key identifier, therefore PSA key must not be destroyed as long as the PK object remains alive. From e4220fef2f7bd686ebde8924025e6d6b6a37aba0 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 12 Mar 2024 13:03:12 +0100 Subject: [PATCH 086/211] MBEDTLS_USE_PSA_CRYPTO: most pk bridge functions don't require it mbedtls_setup_pk_opaque does require it. Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 2c0e129b46..77d75b36f6 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -50,7 +50,7 @@ Then use the [summary of API modules](#summary-of-api-modules), the table of con To make the PSA API available, make sure that the configuration option [`MBEDTLS_PSA_CRYPTO_C`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#c.MBEDTLS_PSA_CRYPTO_C) is enabled. (It is enabled in the default configuration.) -You should probably enable [`MBEDTLS_USE_PSA_CRYPTO`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#mbedtls__config_8h_1a70fd7b97d5f11170546583f2095942a6) as well (it is disabled by default). This option causes the PK, X.509 and TLS modules to use PSA crypto under the hood. Some functions that facilitate the transition (for example, to convert between metadata encodings or between key representations) are only available when `MBEDTLS_USE_PSA_CRYPTO` is enabled. +You should probably enable [`MBEDTLS_USE_PSA_CRYPTO`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#mbedtls__config_8h_1a70fd7b97d5f11170546583f2095942a6) as well (it is disabled by default). This option causes the PK, X.509 and TLS modules to use PSA crypto under the hood. By default, the PSA crypto API offers a similar set of cryptographic mechanisms as those offered by the legacy API (configured by `MBEDTLS_XXX` macros). The PSA crypto API also has its own configuration mechanism; see “[Cryptographic mechanism availability](#cryptographic-mechanism-availability)”. @@ -909,8 +909,8 @@ A future extension of the PSA API will support other export formats. Until those This section discusses how to use a PSA key in a context that requires a PK object, such as PK formatting functions (`mbedtls_pk_write_key_der`, `mbedtls_pk_write_pubkey_der`, `mbedtls_pk_write_pubkey_pem`, `mbedtls_pk_write_key_pem` or `mbedtls_pk_write_pubkey`), Mbed TLS X.509 functions, Mbed TLS SSL functions, or another API that involves `mbedtls_pk_context` objects. The PSA key must be an RSA or ECC key since the PK module does not support DH keys. Three functions from `pk.h` help with that: * [`mbedtls_pk_copy_from_psa`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1ab8e88836fd9ee344ffe630c40447bd08) copies a PSA key into a PK object. The PSA key must be exportable. The PK object remains valid even if the PSA key is destroyed. -* [`mbedtls_pk_setup_opaque`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a4c04ac22ab9c1ae09cc29438c308bf05) sets up a PK object that wraps the PSA key. The PK object can only be used as permitted by the PSA key's policy. The PK object contains a reference to the PSA key identifier, therefore PSA key must not be destroyed as long as the PK object remains alive. * [`mbedtls_pk_copy_public_from_psa`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a2a50247a528889c12ea0ddddb8b15a4e) copies a PSA key into a PK object. The PSA key must be exportable. The PK object remains valid even if the PSA key is destroyed. +* [`mbedtls_pk_setup_opaque`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a4c04ac22ab9c1ae09cc29438c308bf05) sets up a PK object that wraps the PSA key. This functionality is only available when `MBEDTLS_USE_PSA_CRYPTO` is enabled. The PK object has the type `MBEDTLS_PK_OPAQUE` regardless of whether the key is an RSA or ECC key. The PK object can only be used as permitted by the PSA key's policy. The PK object contains a reference to the PSA key identifier, therefore PSA key must not be destroyed as long as the PK object remains alive. Here is some sample code illustrating how to use the PK module to format a PSA public key or the public key of a PSA key pair. ``` From 294a3c2ccb55c399d6b1a878412e7d82cf79cccf Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 12 Mar 2024 13:32:36 +0000 Subject: [PATCH 087/211] Remove unnecessary use of export Signed-off-by: Dave Rodgman --- tests/scripts/quiet/cmake | 4 ++-- tests/scripts/quiet/make | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/scripts/quiet/cmake b/tests/scripts/quiet/cmake index c03d8c3e3e..a34365bea6 100755 --- a/tests/scripts/quiet/cmake +++ b/tests/scripts/quiet/cmake @@ -12,8 +12,8 @@ # export VERBOSE_LOGS=1 # don't silence invocations containing these arguments -export NO_SILENCE=" --version " +NO_SILENCE=" --version " -export TOOL="cmake" +TOOL="cmake" . "$(dirname "$0")/quiet.sh" diff --git a/tests/scripts/quiet/make b/tests/scripts/quiet/make index 6af3a57ce4..920e5b875f 100755 --- a/tests/scripts/quiet/make +++ b/tests/scripts/quiet/make @@ -12,8 +12,8 @@ # export VERBOSE_LOGS=1 # don't silence invocations containing these arguments -export NO_SILENCE=" --version | test " +NO_SILENCE=" --version | test " -export TOOL="make" +TOOL="make" . "$(dirname "$0")/quiet.sh" From 235799bc2309daa7d688ab5d33043da331223204 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 12 Mar 2024 13:33:09 +0000 Subject: [PATCH 088/211] Simplify locating original tool Signed-off-by: Dave Rodgman --- tests/scripts/quiet/quiet.sh | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/tests/scripts/quiet/quiet.sh b/tests/scripts/quiet/quiet.sh index b1432301de..0f26184d0d 100644 --- a/tests/scripts/quiet/quiet.sh +++ b/tests/scripts/quiet/quiet.sh @@ -22,16 +22,13 @@ # be silenced, e.g. " --version | test ". In this example, "make lib test" will # not be silent, but "make lib" will be. -# Function to normalise paths -get_real_filename() { - leafname="$(basename "$1")" - ( cd $(dirname "$1"); echo "$(pwd)/$leafname" ) -} - -# Normalise path to wrapper script -WRAPPER_WITH_PATH=$(get_real_filename "$0") -# Identify original tool (compare normalised path to WRAPPER_WITH_PATH to avoid recursively calling the same wrapper script) -ORIGINAL_TOOL="$(for p in $(type -ap "$TOOL"); do get_real_filename "$p" ; done | grep -v -Fx "$WRAPPER_WITH_PATH" | head -n1)" +# Identify path to original tool. There is an edge-case here where the quiet wrapper is on the path via +# a symlink or relative path, but "type -ap" yields the wrapper with it's normalised path. We use +# the -ef operator to compare paths, to avoid picking the wrapper in this case (to avoid infinitely +# recursing). +while IFS= read -r ORIGINAL_TOOL; do + if ! [[ $ORIGINAL_TOOL -ef "$0" ]]; then break; fi +done < <(type -ap -- "$TOOL") print_quoted_args() { # similar to printf '%q' "$@" From bf69f2e682cd220aede2f70eaa88acb1acf60e37 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 6 Mar 2024 13:39:01 +0100 Subject: [PATCH 089/211] New function mbedtls_pk_copy_public_from_psa Document and implement mbedtls_pk_copy_public_from_psa() to export the public key of a PSA key into PK. Unit-test it alongside mbedtls_pk_copy_from_psa(). Signed-off-by: Gilles Peskine --- ChangeLog.d/8709.txt | 5 +- include/mbedtls/pk.h | 33 ++++++++++ library/pk.c | 26 +++++++- tests/suites/test_suite_pk.function | 99 ++++++++++++++++++++++++++++- 4 files changed, 157 insertions(+), 6 deletions(-) diff --git a/ChangeLog.d/8709.txt b/ChangeLog.d/8709.txt index a9b2751898..e0bea44120 100644 --- a/ChangeLog.d/8709.txt +++ b/ChangeLog.d/8709.txt @@ -1,3 +1,4 @@ Features - * The new function mbedtls_pk_copy_from_psa() provides a way to set up a PK - context with the same content as a PSA key. + * The new functions mbedtls_pk_copy_from_psa() and + mbedtls_pk_copy_public_from_psa() provide ways to set up a PK context + with the same content as a PSA key. diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h index c1fb6056c1..d2e8674b21 100644 --- a/include/mbedtls/pk.h +++ b/include/mbedtls/pk.h @@ -426,6 +426,39 @@ int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx, * parameters are not correct. */ int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk); + +/** + * \brief Create a PK context for the public key of a PSA key. + * + * The key must be an RSA or ECC key. It can be either a + * public key or a key pair, and only the public key is copied. + * The resulting PK object will be a transparent type: + * - #MBEDTLS_PK_RSA for RSA keys or + * - #MBEDTLS_PK_ECKEY for EC keys. + * + * Once this functions returns the PK object will be completely + * independent from the original PSA key that it was generated + * from. + * Calling mbedtls_pk_verify() or + * mbedtls_pk_encrypt() on the resulting + * PK context will perform the corresponding algorithm for that + * PK context type. + * + * For an RSA key, the output PK context will allow both + * encrypt and verify regardless of the original key's policy. + * The original key's policy determines the output key's padding + * mode: PCKS1 v2.1 is set if the PSA key policy is OAEP or PSS, + * otherwise PKCS1 v1.5 is set. + * + * \param key_id The key identifier of the key stored in PSA. + * \param pk The PK context that will be filled. It must be initialized, + * but not set up. + * + * \return 0 on success. + * \return MBEDTLS_ERR_PK_BAD_INPUT_DATA in case the provided input + * parameters are not correct. + */ +int mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk); #endif /* MBEDTLS_PSA_CRYPTO_C */ #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) diff --git a/library/pk.c b/library/pk.c index 4345ea2f69..7bc1da8b66 100644 --- a/library/pk.c +++ b/library/pk.c @@ -1379,7 +1379,9 @@ mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx) } #if defined(MBEDTLS_PSA_CRYPTO_C) -int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk) +static int copy_from_psa(mbedtls_svc_key_id_t key_id, + mbedtls_pk_context *pk, + int public_only) { psa_status_t status; psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; @@ -1400,13 +1402,20 @@ int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk return MBEDTLS_ERR_PK_BAD_INPUT_DATA; } - status = psa_export_key(key_id, exp_key, sizeof(exp_key), &exp_key_len); + if (public_only) { + status = psa_export_public_key(key_id, exp_key, sizeof(exp_key), &exp_key_len); + } else { + status = psa_export_key(key_id, exp_key, sizeof(exp_key), &exp_key_len); + } if (status != PSA_SUCCESS) { ret = PSA_PK_TO_MBEDTLS_ERR(status); goto exit; } key_type = psa_get_key_type(&key_attr); + if (public_only) { + key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type); + } key_bits = psa_get_key_bits(&key_attr); alg_type = psa_get_key_algorithm(&key_attr); @@ -1485,6 +1494,19 @@ exit: return ret; } + + +int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, + mbedtls_pk_context *pk) +{ + return copy_from_psa(key_id, pk, 0); +} + +int mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_t key_id, + mbedtls_pk_context *pk) +{ + return copy_from_psa(key_id, pk, 1); +} #endif /* MBEDTLS_PSA_CRYPTO_C */ #endif /* MBEDTLS_PK_C */ diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 75dc4acae3..d955ab6fe6 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -322,6 +322,83 @@ static psa_key_usage_t pk_get_psa_attributes_implied_usage( expected_usage |= PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY; return expected_usage; } + +#define RSA_WRITE_PUBKEY_MAX_SIZE \ + PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) +#define ECP_WRITE_PUBKEY_MAX_SIZE \ + PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) +static int pk_public_same(const mbedtls_pk_context *pk1, + const mbedtls_pk_context *pk2) +{ + int ok = 0; + + mbedtls_pk_type_t type = mbedtls_pk_get_type(pk1); + TEST_EQUAL(type, mbedtls_pk_get_type(pk2)); + + switch (type) { +#if defined(MBEDTLS_RSA_C) + case MBEDTLS_PK_RSA: + { + const mbedtls_rsa_context *rsa1 = mbedtls_pk_rsa(*pk1); + const mbedtls_rsa_context *rsa2 = mbedtls_pk_rsa(*pk2); + TEST_EQUAL(mbedtls_rsa_get_padding_mode(rsa1), + mbedtls_rsa_get_padding_mode(rsa2)); + TEST_EQUAL(mbedtls_rsa_get_md_alg(rsa1), + mbedtls_rsa_get_md_alg(rsa2)); + unsigned char buf1[RSA_WRITE_PUBKEY_MAX_SIZE]; + unsigned char *p1 = buf1 + sizeof(buf1); + int len1 = mbedtls_rsa_write_pubkey(rsa1, buf1, &p1); + TEST_LE_U(0, len1); + unsigned char buf2[RSA_WRITE_PUBKEY_MAX_SIZE]; + unsigned char *p2 = buf2 + sizeof(buf2); + int len2 = mbedtls_rsa_write_pubkey(rsa2, buf2, &p2); + TEST_LE_U(0, len2); + TEST_MEMORY_COMPARE(p1, len1, p2, len2); + break; + } +#endif /* MBEDTLS_RSA_C */ + +#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) + case MBEDTLS_PK_ECKEY: + case MBEDTLS_PK_ECKEY_DH: + case MBEDTLS_PK_ECDSA: + { +#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) + TEST_MEMORY_COMPARE(pk1->pub_raw, pk1->pub_raw_len, + pk2->pub_raw, pk2->pub_raw_len); + TEST_EQUAL(pk1->ec_family, pk2->ec_family); + TEST_EQUAL(pk1->ec_bits, pk2->ec_bits); + +#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ + const mbedtls_ecp_keypair *ec1 = mbedtls_pk_ec_ro(*pk1); + const mbedtls_ecp_keypair *ec2 = mbedtls_pk_ec_ro(*pk2); + TEST_EQUAL(mbedtls_ecp_keypair_get_group_id(ec1), + mbedtls_ecp_keypair_get_group_id(ec2)); + unsigned char buf1[ECP_WRITE_PUBKEY_MAX_SIZE]; + size_t len1 = 99999991; + TEST_EQUAL(mbedtls_ecp_write_public_key( + ec1, MBEDTLS_ECP_PF_UNCOMPRESSED, + &len1, buf1, sizeof(buf1)), 0); + unsigned char buf2[ECP_WRITE_PUBKEY_MAX_SIZE]; + size_t len2 = 99999992; + TEST_EQUAL(mbedtls_ecp_write_public_key( + ec2, MBEDTLS_ECP_PF_UNCOMPRESSED, + &len2, buf2, sizeof(buf2)), 0); + TEST_MEMORY_COMPARE(buf1, len1, buf2, len2); +#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ + } + break; +#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ + + default: + TEST_FAIL("Unsupported pk type in pk_public_same"); + } + + ok = 1; + +exit: + return ok; +} #endif /* MBEDTLS_PSA_CRYPTO_C */ #if defined(MBEDTLS_RSA_C) @@ -2322,16 +2399,21 @@ void pk_copy_from_psa_fail(void) /* Null pk pointer. */ TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, NULL), MBEDTLS_ERR_PK_BAD_INPUT_DATA); + TEST_EQUAL(mbedtls_pk_copy_public_from_psa(key_id, NULL), + MBEDTLS_ERR_PK_BAD_INPUT_DATA); /* Invalid key ID. */ TEST_EQUAL(mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_make(0, 0), &pk_ctx), MBEDTLS_ERR_PK_BAD_INPUT_DATA); + TEST_EQUAL(mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_make(0, 0), &pk_ctx), + MBEDTLS_ERR_PK_BAD_INPUT_DATA); #if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE) /* Generate a key type that is not handled by the PK module. */ PSA_ASSERT(pk_psa_genkey_generic(PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919), 2048, PSA_KEY_USAGE_EXPORT, PSA_ALG_NONE, &key_id)); TEST_EQUAL(mbedtls_pk_copy_from_psa(key_id, &pk_ctx), MBEDTLS_ERR_PK_BAD_INPUT_DATA); + TEST_EQUAL(mbedtls_pk_copy_public_from_psa(key_id, &pk_ctx), MBEDTLS_ERR_PK_BAD_INPUT_DATA); psa_destroy_key(key_id); #endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE */ @@ -2382,7 +2464,7 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, psa_algorithm_t key_alg = key_alg_arg; psa_key_usage_t key_usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY; - mbedtls_pk_context pk_priv, pk_pub; + mbedtls_pk_context pk_priv, pk_priv_copy_public, pk_pub, pk_pub_copy_public; mbedtls_svc_key_id_t priv_key_id = MBEDTLS_SVC_KEY_ID_INIT; mbedtls_svc_key_id_t pub_key_id = MBEDTLS_SVC_KEY_ID_INIT; unsigned char *in_buf = NULL; @@ -2392,7 +2474,9 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, size_t out_buf_len, out_buf2_len; mbedtls_pk_init(&pk_priv); + mbedtls_pk_init(&pk_priv_copy_public); mbedtls_pk_init(&pk_pub); + mbedtls_pk_init(&pk_pub_copy_public); PSA_INIT(); if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) { @@ -2404,9 +2488,11 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, key_type, key_usage, key_alg, &priv_key_id)); pub_key_id = psa_pub_key_from_priv(priv_key_id); - /* Create 2 PK contexts starting from the PSA keys we just created. */ + /* Create 4 PK contexts starting from the PSA keys we just created. */ TEST_EQUAL(mbedtls_pk_copy_from_psa(priv_key_id, &pk_priv), 0); + TEST_EQUAL(mbedtls_pk_copy_public_from_psa(pub_key_id, &pk_priv_copy_public), 0); TEST_EQUAL(mbedtls_pk_copy_from_psa(pub_key_id, &pk_pub), 0); + TEST_EQUAL(mbedtls_pk_copy_public_from_psa(pub_key_id, &pk_pub_copy_public), 0); /* Destoy both PSA keys to prove that generated PK contexts are independent * from them. */ @@ -2534,10 +2620,19 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, } } + /* Test that the keys from mbedtls_pk_copy_public_from_psa() are identical + * to the public key from mbedtls_pk_copy_from_psa(). */ + mbedtls_test_set_step(1); + TEST_ASSERT(pk_public_same(&pk_pub, &pk_priv_copy_public)); + mbedtls_test_set_step(2); + TEST_ASSERT(pk_public_same(&pk_pub, &pk_pub_copy_public)); + exit: mbedtls_free(in_buf); mbedtls_pk_free(&pk_priv); + mbedtls_pk_free(&pk_priv_copy_public); mbedtls_pk_free(&pk_pub); + mbedtls_pk_free(&pk_pub_copy_public); psa_destroy_key(priv_key_id); psa_destroy_key(pub_key_id); PSA_DONE(); From 17d5b6bda203455eb6a3f0a2fd3d006383920815 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 6 Mar 2024 13:40:01 +0100 Subject: [PATCH 090/211] Test mbedtls_pk_copy_public_from_psa on non-exportable keys Signed-off-by: Gilles Peskine --- tests/suites/test_suite_pk.data | 12 +++++++ tests/suites/test_suite_pk.function | 55 +++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data index 18a1bb2063..a1fe5db84e 100644 --- a/tests/suites/test_suite_pk.data +++ b/tests/suites/test_suite_pk.data @@ -1572,3 +1572,15 @@ pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1 Copy from PSA: valid RSA, wrong alg (CMAC) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_ALG_FOR_TEST pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_CMAC + +Copy from PSA: non-exportable -> public, RSA +depends_on:MBEDTLS_RSA_C +pk_copy_public_from_psa:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR + +Copy from PSA: non-exportable -> public, SECP_R1_256 +depends_on:MBEDTLS_PK_HAVE_ECC_KEYS:MBEDTLS_ECP_HAVE_SECP256R1 +pk_copy_public_from_psa:"587CF7C57EB7C6254CBF80CC59846521B4FBCBA8BC4B362A9B043F0DEB49CCA1":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1) + +Copy from PSA: non-exportable -> public, Curve25519 +depends_on:MBEDTLS_PK_HAVE_ECC_KEYS:MBEDTLS_ECP_HAVE_CURVE25519 +pk_copy_public_from_psa:"a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY) diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index d955ab6fe6..81d6dd5d3a 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -2638,3 +2638,58 @@ exit: PSA_DONE(); } /* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C*/ +void pk_copy_public_from_psa(data_t *priv_key_data, int key_type_arg) +{ + psa_key_type_t key_type = key_type_arg; + mbedtls_pk_context pk_from_exportable; + mbedtls_pk_init(&pk_from_exportable); + mbedtls_pk_context pk_from_non_exportable; + mbedtls_pk_init(&pk_from_non_exportable); + mbedtls_pk_context pk_private; + mbedtls_pk_init(&pk_private); + mbedtls_svc_key_id_t non_exportable_key_id = MBEDTLS_SVC_KEY_ID_INIT; + mbedtls_svc_key_id_t exportable_key_id = MBEDTLS_SVC_KEY_ID_INIT; + + PSA_INIT(); + + PSA_ASSERT(pk_psa_import_key(priv_key_data->x, priv_key_data->len, + key_type, + PSA_KEY_USAGE_EXPORT, + PSA_ALG_NONE, + &exportable_key_id)); + PSA_ASSERT(pk_psa_import_key(priv_key_data->x, priv_key_data->len, + key_type, + 0, + PSA_ALG_NONE, + &non_exportable_key_id)); + + TEST_EQUAL(mbedtls_pk_copy_public_from_psa(exportable_key_id, + &pk_from_exportable), 0); + TEST_EQUAL(mbedtls_pk_copy_public_from_psa(non_exportable_key_id, + &pk_from_non_exportable), 0); + + /* Check that the non-exportable key really is non-exportable */ + TEST_EQUAL(mbedtls_pk_copy_from_psa(non_exportable_key_id, &pk_private), + MBEDTLS_ERR_PK_TYPE_MISMATCH); + + psa_destroy_key(exportable_key_id); + psa_destroy_key(non_exportable_key_id); + + /* The goal of this test function is mostly to check that + * mbedtls_pk_copy_public_from_psa works with a non-exportable key pair. + * We check that the resulting key is the same as for an exportable + * key pair. We rely on pk_copy_from_psa_success tests to validate that + * the result is correct. */ + TEST_ASSERT(pk_public_same(&pk_from_non_exportable, &pk_from_exportable)); + +exit: + mbedtls_pk_free(&pk_from_non_exportable); + mbedtls_pk_free(&pk_from_exportable); + mbedtls_pk_free(&pk_private); + psa_destroy_key(exportable_key_id); + psa_destroy_key(non_exportable_key_id); + PSA_DONE(); +} +/* END_CASE */ From 0dc79a754dc0dfbe06465549a9c7a1094a992a01 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 11 Mar 2024 15:23:12 +0100 Subject: [PATCH 091/211] Fix and test pk_copy_from_psa with an unsupported algorithm Fix mbedtls_pk_copy_from_psa() and mbedtls_pk_copy_public_from_psa() to still work when the algorithm in the key policy is not an RSA algorithm (typically PSA_ALG_NONE). Add a dedicated test case and adjust the test code. Fixes the test case "Copy from PSA: non-exportable -> public, RSA" when MBEDTLS_PKCS1_V15 is disabled. Signed-off-by: Gilles Peskine --- library/pk.c | 3 ++- tests/suites/test_suite_pk.data | 10 +++++--- tests/suites/test_suite_pk.function | 36 +++++++++++++++++++++++------ 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/library/pk.c b/library/pk.c index 7bc1da8b66..1d85c9217f 100644 --- a/library/pk.c +++ b/library/pk.c @@ -1444,7 +1444,8 @@ static int copy_from_psa(mbedtls_svc_key_id_t key_id, if (PSA_ALG_IS_RSA_OAEP(alg_type) || PSA_ALG_IS_RSA_PSS(alg_type)) { ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V21, md_type); - } else { + } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg_type) || + alg_type == PSA_ALG_RSA_PKCS1V15_CRYPT) { ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V15, md_type); } if (ret != 0) { diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data index a1fe5db84e..561297c7ea 100644 --- a/tests/suites/test_suite_pk.data +++ b/tests/suites/test_suite_pk.data @@ -1567,10 +1567,14 @@ Copy from PSA: valid RSA (PSS + SHA_512) depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA512 pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PSS(PSA_ALG_SHA_512) -# Key's algorithm is wrong for an RSA key, but pk_copy_from_psa() ignores -# this information when building the PK context. +Copy from PSA: valid RSA, PSA_ALG_NONE +depends_on:MBEDTLS_RSA_C:MBEDTLS_MD_ALG_FOR_TEST +pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_NONE + +# Key's algorithm is wrong for an RSA key, but pk_copy_from_psa() accepts +# it anyway. Copy from PSA: valid RSA, wrong alg (CMAC) -depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_MD_ALG_FOR_TEST +depends_on:MBEDTLS_RSA_C:MBEDTLS_MD_ALG_FOR_TEST pk_copy_from_psa_success:"308204a40201000282010100ef24d80f6b7a0f62ab2f750a8370c1c39781abe2f7ae5cbc698ebbc51067af68c8b02e5bfafe0b296a2fdca8ee5327bf3370bd26c529d173c4356d8ad51f606ac730e3be509d8535c9c51927222d6c4e770efec4d9b0bd11410e5e2e01e093700d358aab8292297483c65870ea6d4ca9299f4347790f6223480732726a97b34bb4d53cb3f188e3c97115b029fa9a2cce4c6d935977a90737ac8b2a2c5691ad928b22681ca05ee38ddba2278c854f51281c5e4856090aca59bf719a167e63bb932580ae2b599e1a297194696e637a919bc9d2caf214e59d46ed1a12e591b608f2031744111551430d9ac39082957ae1ce03a88068896701e6ce19a83890ff5761020301000102820100706fb53a02c13fcc9749d7d09a9e002c12e6bfc715c6a00961e3defab74cd896fe8c7f2f75e1cda3aa2e58a400718e65822d0671dd0f5d4ffdb7550a8a4b974c7cdccaa72745f864a2ba0daa6d9247b2d89d6f41644c89883c3b2222a5754e3cc7a91dcaa7b84acf6249763998aeccf558016e638352ad44835006f2ee94e691d0070ce561677f2a22a12f357bd762c57f80f1f4921f0f26b3ed758478d11086c182874355ef5039e8d854291b9ce7f8b284ec81f141b7255313507f5ea159d6b1c0ee176e7743d3c65d536e1e4aaf24089c1e00c8021012b8846a4971a0695030504ace362077e8b2fcb4fbdd70bfb734a3fe7d9e1a25bdd0cb0f2fcb56ecc502818100f8fdfbac1c033911b5a184980d081f700f4d450cebf18cbdc68f160a5abd580e6f8f5800fd0b60521dbe2d549e82617afe70d2ad004c2f45405d94e4418e8c2b8da6bcaa407bbfa5477b5a6fceccfcb99f51c6c16bd17202d997bdcaec83b870e3e101acc05e0754020ec207ef5ec9934ac81cd617af72cd94b2bb400eb2078302818100f5dfe74a548c04950178f50130d5aadbe5d1f4b52527c0bfad9aa0d73731fb24219cb5ea5c4b4fa56133d5ea9225fa7d0ccc9bdcc78b77303a2e73c17e9a46b9b09020604496a849f069d0d87713e06a5d374271b2629f5ba220506b606a101828d20da9fcfa3a7e75b135987260be6d37622fc3f4bf4fd2dfd9655da5ff0c4b02818100d4d797c959f0cf59fa1f65ceec64e32ad189c5daf3ddf9e747d28c8eb15e65e5812bd19896b6a0d1d126fe6cf54a92b5a6c71ef04feed001acb1d253044f2c3716d14f396201e6a30c65bfbb0fd65ebaf61bdb80ffff7c2c3f80dcf69813491907531231700770d0392a1066e411ecd201fce9d98149b32355572b85e889faad028181009d898bc165709d52f7b18f91e6bf508d3ab08ed12df04da0c2d40b7039ce4d72b61299c082c8424cdd7dfff71f13346ec12fac42069cc68e6108f86427012485bfaa6904258e3e5fb9a9a305bf2e3e21087eea94bcce51fabd63650397affd85ed49c1358480b3cfe90ad5234b4dcf555d220d26c9ff765ecfcc94152fd1be070281804bf77b4bae8386772de830cc75f2d1d4b8221b3f817208e08c002ac0549902677e4f0e7bce5ba1b3da74fbbe138758e6853b4a5b7bf0672bc1170c64fa502a5e24e3472db433b4e30761eab6ebb9e207235fd88b97b1b30e14f364b628219d6e17056543a4e29a4de1e41ad37927ce23d0442623744bc35a1874296960029044":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_CMAC Copy from PSA: non-exportable -> public, RSA diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 81d6dd5d3a..2feb9c494c 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -2547,14 +2547,36 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, * - Verify with the PK context generated using public key. * - Verify using the public PSA key directly. */ - TEST_EQUAL(mbedtls_pk_sign(&pk_priv, md_for_test, in_buf, in_buf_len, - out_buf, sizeof(out_buf), &out_buf_len, - mbedtls_test_rnd_std_rand, NULL), 0); - TEST_EQUAL(mbedtls_pk_verify(&pk_priv, md_for_test, in_buf, in_buf_len, - out_buf, out_buf_len), 0); - TEST_EQUAL(mbedtls_pk_verify(&pk_pub, md_for_test, in_buf, in_buf_len, - out_buf, out_buf_len), 0); + /* Edge cases: in a build with RSA key support but not RSA padding modes, + * or with ECDSA verify support but not signature, the signature might be + * impossible. */ + int pk_can_sign = 0; +#if defined(MBEDTLS_PKCS1_V15) + if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(key_alg) || key_alg == PSA_ALG_RSA_PKCS1V15_CRYPT) { + pk_can_sign = 1; + } +#endif +#if defined(MBEDTLS_PKCS1_V21) + if (PSA_ALG_IS_RSA_PSS(key_alg) || PSA_ALG_IS_RSA_OAEP(key_alg)) { + pk_can_sign = 1; + } +#endif +#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN) + if (PSA_ALG_IS_ECDSA(key_alg) || PSA_ALG_IS_DETERMINISTIC_ECDSA(key_alg)) { + pk_can_sign = 1; + } +#endif + if (pk_can_sign) { + TEST_EQUAL(mbedtls_pk_sign(&pk_priv, md_for_test, in_buf, in_buf_len, + out_buf, sizeof(out_buf), &out_buf_len, + mbedtls_test_rnd_std_rand, NULL), 0); + + TEST_EQUAL(mbedtls_pk_verify(&pk_priv, md_for_test, in_buf, in_buf_len, + out_buf, out_buf_len), 0); + TEST_EQUAL(mbedtls_pk_verify(&pk_pub, md_for_test, in_buf, in_buf_len, + out_buf, out_buf_len), 0); + } if (PSA_ALG_IS_HASH_AND_SIGN(key_alg)) { #if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA) From d6a710a3973c1dcb5eab57e1c620ecda437bb845 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 12 Mar 2024 12:39:28 +0100 Subject: [PATCH 092/211] Fix copypasta Signed-off-by: Gilles Peskine --- tests/suites/test_suite_pk.function | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 2feb9c494c..089202bb4d 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -2490,7 +2490,7 @@ void pk_copy_from_psa_success(data_t *priv_key_data, int key_type_arg, /* Create 4 PK contexts starting from the PSA keys we just created. */ TEST_EQUAL(mbedtls_pk_copy_from_psa(priv_key_id, &pk_priv), 0); - TEST_EQUAL(mbedtls_pk_copy_public_from_psa(pub_key_id, &pk_priv_copy_public), 0); + TEST_EQUAL(mbedtls_pk_copy_public_from_psa(priv_key_id, &pk_priv_copy_public), 0); TEST_EQUAL(mbedtls_pk_copy_from_psa(pub_key_id, &pk_pub), 0); TEST_EQUAL(mbedtls_pk_copy_public_from_psa(pub_key_id, &pk_pub_copy_public), 0); From 077fd87748fdf19df979d6501cf42fa8eaac9222 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Thu, 22 Feb 2024 16:55:03 +0000 Subject: [PATCH 093/211] Add new global mutex for PSA global_data Signed-off-by: Paul Elliott --- include/mbedtls/threading.h | 7 +++++++ library/threading.c | 3 +++ 2 files changed, 10 insertions(+) diff --git a/include/mbedtls/threading.h b/include/mbedtls/threading.h index b4e050241b..fbd7ad2e47 100644 --- a/include/mbedtls/threading.h +++ b/include/mbedtls/threading.h @@ -112,6 +112,13 @@ extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex; * psa_key_slot_state_transition(), psa_register_read(), psa_unregister_read(), * psa_key_slot_has_readers() and psa_wipe_key_slot(). */ extern mbedtls_threading_mutex_t mbedtls_threading_key_slot_mutex; + +/* + * A mutex used to make the PSA global_data struct members thread safe. + * + * This mutex must be held when any read or write to a any of the PSA + * global_data structure members. */ +extern mbedtls_threading_mutex_t mbedtls_threading_psa_globaldata_mutex; #endif #endif /* MBEDTLS_THREADING_C */ diff --git a/library/threading.c b/library/threading.c index c28290fb76..06b474726c 100644 --- a/library/threading.c +++ b/library/threading.c @@ -150,6 +150,7 @@ void mbedtls_threading_set_alt(void (*mutex_init)(mbedtls_threading_mutex_t *), #endif #if defined(MBEDTLS_PSA_CRYPTO_C) mbedtls_mutex_init(&mbedtls_threading_key_slot_mutex); + mbedtls_mutex_init(&mbedtls_threading_psa_globaldata_mutex); #endif } @@ -166,6 +167,7 @@ void mbedtls_threading_free_alt(void) #endif #if defined(MBEDTLS_PSA_CRYPTO_C) mbedtls_mutex_free(&mbedtls_threading_key_slot_mutex); + mbedtls_mutex_free(&mbedtls_threading_psa_globaldata_mutex); #endif } #endif /* MBEDTLS_THREADING_ALT */ @@ -184,6 +186,7 @@ mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT; #endif #if defined(MBEDTLS_PSA_CRYPTO_C) mbedtls_threading_mutex_t mbedtls_threading_key_slot_mutex MUTEX_INIT; +mbedtls_threading_mutex_t mbedtls_threading_psa_globaldata_mutex MUTEX_INIT; #endif #endif /* MBEDTLS_THREADING_C */ From b8e38e0e27b0dc2e5932fbef3b6c352500a44fb7 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Mon, 11 Mar 2024 12:09:49 +0000 Subject: [PATCH 094/211] Add new mutex for PSA global rng data Signed-off-by: Paul Elliott --- include/mbedtls/threading.h | 13 ++++++++++--- library/threading.c | 3 +++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/include/mbedtls/threading.h b/include/mbedtls/threading.h index fbd7ad2e47..d50d04ead1 100644 --- a/include/mbedtls/threading.h +++ b/include/mbedtls/threading.h @@ -114,11 +114,18 @@ extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex; extern mbedtls_threading_mutex_t mbedtls_threading_key_slot_mutex; /* - * A mutex used to make the PSA global_data struct members thread safe. + * A mutex used to make the non-rng PSA global_data struct members thread safe. * - * This mutex must be held when any read or write to a any of the PSA - * global_data structure members. */ + * This mutex must be held when reading or writing to any of the PSA global_data + * structure members, other than the rng_state or rng struct. */ extern mbedtls_threading_mutex_t mbedtls_threading_psa_globaldata_mutex; + +/* + * A mutex used to make the PSA global_data rng data thread safe. + * + * This mutex must be held when reading or writing to the PSA + * global_data rng_state or rng struct members. */ +extern mbedtls_threading_mutex_t mbedtls_threading_psa_rngdata_mutex; #endif #endif /* MBEDTLS_THREADING_C */ diff --git a/library/threading.c b/library/threading.c index 06b474726c..85db243f21 100644 --- a/library/threading.c +++ b/library/threading.c @@ -151,6 +151,7 @@ void mbedtls_threading_set_alt(void (*mutex_init)(mbedtls_threading_mutex_t *), #if defined(MBEDTLS_PSA_CRYPTO_C) mbedtls_mutex_init(&mbedtls_threading_key_slot_mutex); mbedtls_mutex_init(&mbedtls_threading_psa_globaldata_mutex); + mbedtls_mutex_init(&mbedtls_threading_psa_rngdata_mutex); #endif } @@ -168,6 +169,7 @@ void mbedtls_threading_free_alt(void) #if defined(MBEDTLS_PSA_CRYPTO_C) mbedtls_mutex_free(&mbedtls_threading_key_slot_mutex); mbedtls_mutex_free(&mbedtls_threading_psa_globaldata_mutex); + mbedtls_mutex_free(&mbedtls_threading_psa_rngdata_mutex); #endif } #endif /* MBEDTLS_THREADING_ALT */ @@ -187,6 +189,7 @@ mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT; #if defined(MBEDTLS_PSA_CRYPTO_C) mbedtls_threading_mutex_t mbedtls_threading_key_slot_mutex MUTEX_INIT; mbedtls_threading_mutex_t mbedtls_threading_psa_globaldata_mutex MUTEX_INIT; +mbedtls_threading_mutex_t mbedtls_threading_psa_rngdata_mutex MUTEX_INIT; #endif #endif /* MBEDTLS_THREADING_C */ From 600472b4438601029e2f77c8336840306b2119db Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Fri, 23 Feb 2024 17:26:58 +0000 Subject: [PATCH 095/211] Protect PSA global initialized flag with mutex. Unfortunately this requires holding the mutex for the entire psa_crypto_init() function, as calling psa_crypto_free() from another thread should block until init has ended, then run. Signed-off-by: Paul Elliott --- library/psa_crypto.c | 55 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index ec9d115b3b..3019522f29 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -71,6 +71,7 @@ #include "mbedtls/sha256.h" #include "mbedtls/sha512.h" #include "mbedtls/psa_util.h" +#include "mbedtls/threading.h" #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \ defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) || \ @@ -101,8 +102,25 @@ typedef struct { static psa_global_data_t global_data; +static uint8_t psa_get_initialized(void) +{ + uint8_t initialized; + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + + initialized = global_data.initialized; + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + + return initialized; +} + #define GUARD_MODULE_INITIALIZED \ - if (global_data.initialized == 0) \ + if (psa_get_initialized() == 0) \ return PSA_ERROR_BAD_STATE; int psa_can_do_hash(psa_algorithm_t hash_alg) @@ -7189,7 +7207,7 @@ psa_status_t psa_generate_random(uint8_t *output, psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed, size_t seed_size) { - if (global_data.initialized) { + if (psa_get_initialized()) { return PSA_ERROR_NOT_PERMITTED; } @@ -7442,15 +7460,27 @@ psa_status_t mbedtls_psa_crypto_configure_entropy_sources( void mbedtls_psa_crypto_free(void) { + /* Need to hold the mutex here to prevent this going ahead before + * psa_crypto_init() has completed, and to ensure integrity of + * global_data. */ +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + psa_wipe_all_key_slots(); if (global_data.rng_state != RNG_NOT_INITIALIZED) { mbedtls_psa_random_free(&global_data.rng); } + /* Wipe all remaining data, including configuration. * In particular, this sets all state indicator to the value * indicating "uninitialized". */ mbedtls_platform_zeroize(&global_data, sizeof(global_data)); +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + /* Terminate drivers */ psa_driver_wrapper_free(); } @@ -7484,8 +7514,20 @@ psa_status_t psa_crypto_init(void) { psa_status_t status; - /* Double initialization is explicitly allowed. */ - if (global_data.initialized != 0) { + /* Need to hold the mutex for the entire function to prevent incomplete + * initialisation before someone calls psa_crypto_free() or calls this + * function again before we set global_data.initialised to 1. */ + #if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + + /* We cannot use psa_get_initialized() here as we already hold the mutex. */ + if (global_data.initialized == 1) { +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + + /* Double initialization is explicitly allowed. */ return PSA_SUCCESS; } @@ -7528,6 +7570,11 @@ psa_status_t psa_crypto_init(void) global_data.initialized = 1; exit: + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + if (status != PSA_SUCCESS) { mbedtls_psa_crypto_free(); } From 8e15153637a226f46b4301a706f6abdce1d7bb34 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Fri, 23 Feb 2024 17:35:29 +0000 Subject: [PATCH 096/211] Protect PSA global rng data with mutex. Reads and writes of rng_state in psa_crypto_init() and psa_crypto_free() were already covered by mutex. Signed-off-by: Paul Elliott --- library/psa_crypto.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 3019522f29..8f41641325 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -7449,12 +7449,25 @@ psa_status_t mbedtls_psa_crypto_configure_entropy_sources( void (* entropy_init)(mbedtls_entropy_context *ctx), void (* entropy_free)(mbedtls_entropy_context *ctx)) { + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + if (global_data.rng_state != RNG_NOT_INITIALIZED) { - return PSA_ERROR_BAD_STATE; + status = PSA_ERROR_BAD_STATE; + } else { + global_data.rng.entropy_init = entropy_init; + global_data.rng.entropy_free = entropy_free; + status = PSA_SUCCESS; } - global_data.rng.entropy_init = entropy_init; - global_data.rng.entropy_free = entropy_free; - return PSA_SUCCESS; + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + + return status; } #endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */ From 358165246b39222edbb3e2ef51282a71e99a6897 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Fri, 23 Feb 2024 17:47:42 +0000 Subject: [PATCH 097/211] Protect PSA drivers_initialized with mutex Writes to this in psa_crypto_init() were again already covered. Signed-off-by: Paul Elliott --- library/psa_crypto.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 8f41641325..63fd05c59b 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -119,6 +119,23 @@ static uint8_t psa_get_initialized(void) return initialized; } +static uint8_t psa_get_drivers_initialized(void) +{ + uint8_t initialized; + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + + initialized = global_data.drivers_initialized; + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + + return initialized; +} + #define GUARD_MODULE_INITIALIZED \ if (psa_get_initialized() == 0) \ return PSA_ERROR_BAD_STATE; @@ -126,14 +143,14 @@ static uint8_t psa_get_initialized(void) int psa_can_do_hash(psa_algorithm_t hash_alg) { (void) hash_alg; - return global_data.drivers_initialized; + return psa_get_drivers_initialized(); } int psa_can_do_cipher(psa_key_type_t key_type, psa_algorithm_t cipher_alg) { (void) key_type; (void) cipher_alg; - return global_data.drivers_initialized; + return psa_get_drivers_initialized(); } From cd1370e8d857e6d170c69d59b7872624ac646a87 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 12 Mar 2024 16:07:48 +0100 Subject: [PATCH 098/211] ssl-opt.sh: Group G->m server version selection checks Signed-off-by: Ronald Cron --- tests/ssl-opt.sh | 118 ++++++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 58 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index fd2fc0a1b1..8ca2312593 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -2047,64 +2047,6 @@ run_test "Default, DTLS" \ -s "Protocol is DTLSv1.2" \ -s "Ciphersuite is TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256" -# GnuTLS can be setup to send a ClientHello containing a supported versions -# extension proposing TLS 1.2 (preferred) and then TLS 1.3. In that case, -# a TLS 1.3 and TLS 1.2 capable server is supposed to negotiate TLS 1.2 and -# to indicate in the ServerHello that it downgrades from TLS 1.3. The GnuTLS -# client then detects the downgrade indication and aborts the handshake even -# if TLS 1.2 was its preferred version. Keeping the test even if the -# handshake fails eventually as it exercices parts of the Mbed TLS -# implementation that are otherwise not exercised. -requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 -requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED -run_test "Server selecting TLS 1.2 over TLS 1.3" \ - "$P_SRV crt_file=data_files/server5.crt key_file=data_files/server5.key" \ - "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3" \ - 1 \ - -c "Detected downgrade to TLS 1.2 from TLS 1.3" - -requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 -requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_3 -requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED -run_test "Server selecting TLS 1.2" \ - "$P_SRV crt_file=data_files/server5.crt key_file=data_files/server5.key" \ - "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3" \ - 0 \ - -s "Protocol is TLSv1.2" \ - -c "HTTP/1.0 200 OK" - -requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 -requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED -run_test "Server selecting TLS 1.3, over TLS 1.2 if supported" \ - "$P_SRV crt_file=data_files/server5.crt key_file=data_files/server5.key" \ - "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:%DISABLE_TLS13_COMPAT_MODE" \ - 0 \ - -s "Protocol is TLSv1.3" \ - -c "HTTP/1.0 200 OK" - -requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 -requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED -requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE -run_test "Server selecting TLS 1.3, over TLS 1.2 if supported - compat mode enabled" \ - "$P_SRV crt_file=data_files/server5.crt key_file=data_files/server5.key" \ - "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2" \ - 0 \ - -s "Protocol is TLSv1.3" \ - -c "HTTP/1.0 200 OK" - requires_key_exchange_with_cert_in_tls12_or_tls13_enabled run_test "TLS client auth: required" \ "$P_SRV auth_mode=required" \ @@ -6940,6 +6882,66 @@ run_test "Version check: all -> 1.2" \ -s "Protocol is TLSv1.2" \ -c "Protocol is TLSv1.2" +# Tests of version negotiation on server side against GnuTLS client + +requires_gnutls_tls1_3 +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 +requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED +run_test "Server selecting TLS 1.2" \ + "$P_SRV crt_file=data_files/server5.crt key_file=data_files/server5.key" \ + "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3" \ + 0 \ + -s "Protocol is TLSv1.2" \ + -c "HTTP/1.0 200 OK" + +requires_gnutls_tls1_3 +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +run_test "Server selecting TLS 1.3, over TLS 1.2 if supported - compat mode enabled" \ + "$P_SRV crt_file=data_files/server5.crt key_file=data_files/server5.key" \ + "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2" \ + 0 \ + -s "Protocol is TLSv1.3" \ + -c "HTTP/1.0 200 OK" + +requires_gnutls_tls1_3 +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +run_test "Server selecting TLS 1.3, over TLS 1.2 if supported" \ + "$P_SRV crt_file=data_files/server5.crt key_file=data_files/server5.key" \ + "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:%DISABLE_TLS13_COMPAT_MODE" \ + 0 \ + -s "Protocol is TLSv1.3" \ + -c "HTTP/1.0 200 OK" + +# GnuTLS can be setup to send a ClientHello containing a supported versions +# extension proposing TLS 1.2 (preferred) and then TLS 1.3. In that case, +# a TLS 1.3 and TLS 1.2 capable server is supposed to negotiate TLS 1.2 and +# to indicate in the ServerHello that it downgrades from TLS 1.3. The GnuTLS +# client then detects the downgrade indication and aborts the handshake even +# if TLS 1.2 was its preferred version. Keeping the test even if the +# handshake fails eventually as it exercices parts of the Mbed TLS +# implementation that are otherwise not exercised. +requires_gnutls_tls1_3 +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED +run_test "Server selecting TLS 1.2 over TLS 1.3" \ + "$P_SRV crt_file=data_files/server5.crt key_file=data_files/server5.key" \ + "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3" \ + 1 \ + -c "Detected downgrade to TLS 1.2 from TLS 1.3" + requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 run_test "Not supported version check: cli TLS 1.0" \ "$P_SRV" \ From 98bdcc4f29e776e2d898a11bb9761bf9a977ab51 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 6 Mar 2024 15:00:42 +0100 Subject: [PATCH 099/211] ssl-opt.sh: Change G->m server version selection tests Change description and dependencies before to expand G->m server version selection tests. Signed-off-by: Ronald Cron --- tests/ssl-opt.sh | 81 ++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 48 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 8ca2312593..24ff82d474 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -6884,43 +6884,35 @@ run_test "Version check: all -> 1.2" \ # Tests of version negotiation on server side against GnuTLS client -requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_DEBUG_C requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_3 -requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED -run_test "Server selecting TLS 1.2" \ - "$P_SRV crt_file=data_files/server5.crt key_file=data_files/server5.key" \ - "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3" \ +requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT +run_test "Server version nego check G->m: 1.2+1.3 / 1.2 -> 1.2" \ + "$P_SRV" \ + "$G_NEXT_CLI localhost --priority=NORMAL" \ 0 \ - -s "Protocol is TLSv1.2" \ - -c "HTTP/1.0 200 OK" + -S "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.2" -requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 -requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED -requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE -run_test "Server selecting TLS 1.3, over TLS 1.2 if supported - compat mode enabled" \ - "$P_SRV crt_file=data_files/server5.crt key_file=data_files/server5.key" \ - "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2" \ +requires_all_configs_enabled MBEDTLS_SSL_SRV_C MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +run_test "Server version nego check G->m: 1.2+1.3 / (1.2)+1.3 -> 1.3" \ + "$P_SRV" \ + "$G_NEXT_CLI localhost --priority=NORMAL" \ 0 \ - -s "Protocol is TLSv1.3" \ - -c "HTTP/1.0 200 OK" + -S "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.3" -requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 -requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED -run_test "Server selecting TLS 1.3, over TLS 1.2 if supported" \ - "$P_SRV crt_file=data_files/server5.crt key_file=data_files/server5.key" \ - "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:%DISABLE_TLS13_COMPAT_MODE" \ +requires_gnutls_next_disable_tls13_compat +requires_all_configs_enabled MBEDTLS_SSL_SRV_C MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +run_test "Server version nego check G->m (no compat): 1.2+1.3 / (1.2)+1.3 -> 1.3" \ + "$P_SRV" \ + "$G_NEXT_CLI localhost --priority=NORMAL:%DISABLE_TLS13_COMPAT_MODE" \ 0 \ - -s "Protocol is TLSv1.3" \ - -c "HTTP/1.0 200 OK" + -S "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.3" # GnuTLS can be setup to send a ClientHello containing a supported versions # extension proposing TLS 1.2 (preferred) and then TLS 1.3. In that case, @@ -6930,37 +6922,30 @@ run_test "Server selecting TLS 1.3, over TLS 1.2 if supported" \ # if TLS 1.2 was its preferred version. Keeping the test even if the # handshake fails eventually as it exercices parts of the Mbed TLS # implementation that are otherwise not exercised. -requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 -requires_config_enabled MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED -run_test "Server selecting TLS 1.2 over TLS 1.3" \ - "$P_SRV crt_file=data_files/server5.crt key_file=data_files/server5.key" \ +requires_all_configs_enabled MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +run_test "Server version nego check G->m: [1.2]+1.3 / 1.2+1.3 -> 1.2" \ + "$P_SRV" \ "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3" \ 1 \ -c "Detected downgrade to TLS 1.2 from TLS 1.3" -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 -run_test "Not supported version check: cli TLS 1.0" \ +requires_config_enabled MBEDTLS_SSL_SRV_C +run_test "Not supported version check G->m: 1.0 / (1.2)+(1.3)" \ "$P_SRV" \ "$G_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.0" \ 1 \ -s "Handshake protocol not within min/max boundaries" \ - -c "Error in protocol version" \ - -S "Protocol is TLSv1.0" \ - -C "Handshake was completed" + -S "Protocol is TLSv1.0" -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 -run_test "Not supported version check: cli TLS 1.1" \ +requires_config_enabled MBEDTLS_SSL_SRV_C +run_test "Not supported version check G->m: 1.1 / (1.2)+(1.3)" \ "$P_SRV" \ "$G_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.1" \ 1 \ -s "Handshake protocol not within min/max boundaries" \ - -c "Error in protocol version" \ - -S "Protocol is TLSv1.1" \ - -C "Handshake was completed" + -S "Protocol is TLSv1.1" requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 run_test "Not supported version check: srv max TLS 1.0" \ From dfad493e8b699389589f1db045f2c96aadccbe0e Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 6 Mar 2024 15:05:14 +0100 Subject: [PATCH 100/211] ssl-opt.sh: Expand G->m server version selection tests Signed-off-by: Ronald Cron --- tests/ssl-opt.sh | 109 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 105 insertions(+), 4 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 24ff82d474..99066aae3f 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -6884,16 +6884,46 @@ run_test "Version check: all -> 1.2" \ # Tests of version negotiation on server side against GnuTLS client -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_all_configs_enabled MBEDTLS_SSL_SRV_C MBEDTLS_SSL_PROTO_TLS1_2 requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT -run_test "Server version nego check G->m: 1.2+1.3 / 1.2 -> 1.2" \ +run_test "Server version nego check G->m: 1.2 / 1.2+(1.3) -> 1.2" \ "$P_SRV" \ - "$G_NEXT_CLI localhost --priority=NORMAL" \ + "$G_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2" \ 0 \ -S "mbedtls_ssl_handshake returned" \ -s "Protocol is TLSv1.2" +requires_all_configs_enabled MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 +requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT +run_test "Server version nego check G->m: 1.2 / 1.2 (max=1.2) -> 1.2" \ + "$P_SRV max_version=tls12" \ + "$G_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.2" + +requires_all_configs_enabled MBEDTLS_SSL_SRV_C MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +run_test "Server version nego check G->m: 1.3 / (1.2)+1.3 -> 1.3" \ + "$P_SRV" \ + "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.3" + +requires_all_configs_enabled MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +run_test "Server version nego check G->m: 1.3 / 1.3 (min=1.3) -> 1.3" \ + "$P_SRV min_version=tls13" \ + "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.3" + requires_all_configs_enabled MBEDTLS_SSL_SRV_C MBEDTLS_SSL_PROTO_TLS1_3 \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE @@ -6931,6 +6961,37 @@ run_test "Server version nego check G->m: [1.2]+1.3 / 1.2+1.3 -> 1.2" \ 1 \ -c "Detected downgrade to TLS 1.2 from TLS 1.3" +requires_all_configs_enabled MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +run_test "Server version nego check G->m: 1.2+1.3 / 1.3 (min=1.3) -> 1.3" \ + "$P_SRV min_version=tls13" \ + "$G_NEXT_CLI localhost --priority=NORMAL" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.3" + +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT +run_test "Server version nego check G->m: 1.2+1.3 / 1.2 -> 1.2" \ + "$P_SRV" \ + "$G_NEXT_CLI localhost --priority=NORMAL" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.2" + +requires_all_configs_enabled MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 +requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT +run_test "Server version nego check G->m: 1.2+1.3 / 1.2 (max=1.2) -> 1.2" \ + "$P_SRV max_version=tls12" \ + "$G_NEXT_CLI localhost --priority=NORMAL" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.2" + requires_config_enabled MBEDTLS_SSL_SRV_C run_test "Not supported version check G->m: 1.0 / (1.2)+(1.3)" \ "$P_SRV" \ @@ -6947,6 +7008,46 @@ run_test "Not supported version check G->m: 1.1 / (1.2)+(1.3)" \ -s "Handshake protocol not within min/max boundaries" \ -S "Protocol is TLSv1.1" +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_2 +run_test "Not supported version check G->m: 1.2 / 1.3" \ + "$P_SRV" \ + "$G_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2" \ + 1 \ + -s "Handshake protocol not within min/max boundaries" \ + -S "Protocol is TLSv1.2" + +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_3 +run_test "Not supported version check G->m: 1.3 / 1.2" \ + "$P_SRV" \ + "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3" \ + 1 \ + -S "Handshake protocol not within min/max boundaries" \ + -s "The handshake negotiation failed" \ + -S "Protocol is TLSv1.3" + +requires_all_configs_enabled MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 +run_test "Not supported version check G->m: 1.2 / 1.3 (min=1.3)" \ + "$P_SRV min_version=tls13" \ + "$G_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.2" \ + 1 \ + -s "Handshake protocol not within min/max boundaries" \ + -S "Protocol is TLSv1.2" + +requires_all_configs_enabled MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 +run_test "Not supported version check G->m: 1.3 / 1.2 (max=1.2)" \ + "$P_SRV max_version=tls12" \ + "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3" \ + 1 \ + -S "Handshake protocol not within min/max boundaries" \ + -s "The handshake negotiation failed" \ + -S "Protocol is TLSv1.3" + +# Tests of version negotiation on client side against GnuTLS server + requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 run_test "Not supported version check: srv max TLS 1.0" \ "$G_SRV --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0" \ From a1e7b6a66aaed9e426304352c0a0417008155778 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 6 Mar 2024 15:13:49 +0100 Subject: [PATCH 101/211] ssl-opt.sh: Group cli ver nego tests against GnuTLS and OpenSSL Signed-off-by: Ronald Cron --- tests/ssl-opt.sh | 166 +++++++++++++++++++++++------------------------ 1 file changed, 83 insertions(+), 83 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 99066aae3f..43cbeaf3d6 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -7046,7 +7046,7 @@ run_test "Not supported version check G->m: 1.3 / 1.2 (max=1.2)" \ -s "The handshake negotiation failed" \ -S "Protocol is TLSv1.3" -# Tests of version negotiation on client side against GnuTLS server +# Tests of version negotiation on client side against GnuTLS and OpenSSL server requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 run_test "Not supported version check: srv max TLS 1.0" \ @@ -7068,6 +7068,88 @@ run_test "Not supported version check: srv max TLS 1.1" \ -S "Version: TLS1.1" \ -C "Protocol is TLSv1.1" +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_CLI_C +skip_handshake_stage_check +requires_gnutls_tls1_3 +run_test "TLS 1.3: Not supported version check:gnutls: srv max TLS 1.0" \ + "$G_NEXT_SRV --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0 -d 4" \ + "$P_CLI debug_level=4" \ + 1 \ + -s "Client's version: 3.3" \ + -S "Version: TLS1.0" \ + -C "Protocol is TLSv1.0" + +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_CLI_C +skip_handshake_stage_check +requires_gnutls_tls1_3 +run_test "TLS 1.3: Not supported version check:gnutls: srv max TLS 1.1" \ + "$G_NEXT_SRV --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.1 -d 4" \ + "$P_CLI debug_level=4" \ + 1 \ + -s "Client's version: 3.3" \ + -S "Version: TLS1.1" \ + -C "Protocol is TLSv1.1" + +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_CLI_C +skip_handshake_stage_check +requires_gnutls_tls1_3 +run_test "TLS 1.3: Not supported version check:gnutls: srv max TLS 1.2" \ + "$G_NEXT_SRV --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.2 -d 4" \ + "$P_CLI force_version=tls13 debug_level=4" \ + 1 \ + -s "Client's version: 3.3" \ + -c "is a fatal alert message (msg 40)" \ + -S "Version: TLS1.2" \ + -C "Protocol is TLSv1.2" + +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_CLI_C +skip_handshake_stage_check +requires_openssl_next +run_test "TLS 1.3: Not supported version check:openssl: srv max TLS 1.0" \ + "$O_NEXT_SRV -msg -tls1" \ + "$P_CLI debug_level=4" \ + 1 \ + -s "fatal protocol_version" \ + -c "is a fatal alert message (msg 70)" \ + -S "Version: TLS1.0" \ + -C "Protocol : TLSv1.0" + +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_CLI_C +skip_handshake_stage_check +requires_openssl_next +run_test "TLS 1.3: Not supported version check:openssl: srv max TLS 1.1" \ + "$O_NEXT_SRV -msg -tls1_1" \ + "$P_CLI debug_level=4" \ + 1 \ + -s "fatal protocol_version" \ + -c "is a fatal alert message (msg 70)" \ + -S "Version: TLS1.1" \ + -C "Protocol : TLSv1.1" + +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_CLI_C +skip_handshake_stage_check +requires_openssl_next +run_test "TLS 1.3: Not supported version check:openssl: srv max TLS 1.2" \ + "$O_NEXT_SRV -msg -tls1_2" \ + "$P_CLI force_version=tls13 debug_level=4" \ + 1 \ + -s "fatal protocol_version" \ + -c "is a fatal alert message (msg 70)" \ + -S "Version: TLS1.2" \ + -C "Protocol : TLSv1.2" + # Tests for ALPN extension requires_key_exchange_with_cert_in_tls12_or_tls13_enabled @@ -11954,88 +12036,6 @@ run_test "TLS 1.3: server alpn - gnutls" \ -s "HTTP/1.0 200 OK" \ -s "Application Layer Protocol is h2" -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_CLI_C -skip_handshake_stage_check -requires_gnutls_tls1_3 -run_test "TLS 1.3: Not supported version check:gnutls: srv max TLS 1.0" \ - "$G_NEXT_SRV --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0 -d 4" \ - "$P_CLI debug_level=4" \ - 1 \ - -s "Client's version: 3.3" \ - -S "Version: TLS1.0" \ - -C "Protocol is TLSv1.0" - -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_CLI_C -skip_handshake_stage_check -requires_gnutls_tls1_3 -run_test "TLS 1.3: Not supported version check:gnutls: srv max TLS 1.1" \ - "$G_NEXT_SRV --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.1 -d 4" \ - "$P_CLI debug_level=4" \ - 1 \ - -s "Client's version: 3.3" \ - -S "Version: TLS1.1" \ - -C "Protocol is TLSv1.1" - -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_CLI_C -skip_handshake_stage_check -requires_gnutls_tls1_3 -run_test "TLS 1.3: Not supported version check:gnutls: srv max TLS 1.2" \ - "$G_NEXT_SRV --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.2 -d 4" \ - "$P_CLI force_version=tls13 debug_level=4" \ - 1 \ - -s "Client's version: 3.3" \ - -c "is a fatal alert message (msg 40)" \ - -S "Version: TLS1.2" \ - -C "Protocol is TLSv1.2" - -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_CLI_C -skip_handshake_stage_check -requires_openssl_next -run_test "TLS 1.3: Not supported version check:openssl: srv max TLS 1.0" \ - "$O_NEXT_SRV -msg -tls1" \ - "$P_CLI debug_level=4" \ - 1 \ - -s "fatal protocol_version" \ - -c "is a fatal alert message (msg 70)" \ - -S "Version: TLS1.0" \ - -C "Protocol : TLSv1.0" - -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_CLI_C -skip_handshake_stage_check -requires_openssl_next -run_test "TLS 1.3: Not supported version check:openssl: srv max TLS 1.1" \ - "$O_NEXT_SRV -msg -tls1_1" \ - "$P_CLI debug_level=4" \ - 1 \ - -s "fatal protocol_version" \ - -c "is a fatal alert message (msg 70)" \ - -S "Version: TLS1.1" \ - -C "Protocol : TLSv1.1" - -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_CLI_C -skip_handshake_stage_check -requires_openssl_next -run_test "TLS 1.3: Not supported version check:openssl: srv max TLS 1.2" \ - "$O_NEXT_SRV -msg -tls1_2" \ - "$P_CLI force_version=tls13 debug_level=4" \ - 1 \ - -s "fatal protocol_version" \ - -c "is a fatal alert message (msg 70)" \ - -S "Version: TLS1.2" \ - -C "Protocol : TLSv1.2" - requires_config_enabled MBEDTLS_DEBUG_C requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 requires_config_enabled MBEDTLS_SSL_CLI_C From fe18d8db76468813a15cd1f421718997868ad785 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 6 Mar 2024 15:19:55 +0100 Subject: [PATCH 102/211] ssl-opt.sh: Group MbedTLS only version negotiation tests Signed-off-by: Ronald Cron --- tests/ssl-opt.sh | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 43cbeaf3d6..bcaa9d2292 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -6871,7 +6871,7 @@ run_test "Event-driven I/O, DTLS: session-id resume, UDP packing" \ 0 \ -c "Read from server: .* bytes read" -# Tests for version negotiation +# Tests for version negotiation, MbedTLS client and server run_test "Version check: all -> 1.2" \ "$P_SRV" \ @@ -6882,6 +6882,21 @@ run_test "Version check: all -> 1.2" \ -s "Protocol is TLSv1.2" \ -c "Protocol is TLSv1.2" +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_SSL_SRV_C +run_test "TLS 1.3 m->m: Not supported version check: cli TLS 1.2 only, srv TLS 1.3 only, fail" \ + "$P_SRV debug_level=4 max_version=tls13 min_version=tls13" \ + "$P_CLI debug_level=4 max_version=tls12 min_version=tls12" \ + 1 \ + -c "The SSL configuration is tls12 only" \ + -c "supported_versions(43) extension does not exist." \ + -c "A fatal alert message was received from our peer" \ + -s "The SSL configuration is tls13 only" \ + -s "TLS 1.2 not supported." + # Tests of version negotiation on server side against GnuTLS client requires_all_configs_enabled MBEDTLS_SSL_SRV_C MBEDTLS_SSL_PROTO_TLS1_2 @@ -12036,21 +12051,6 @@ run_test "TLS 1.3: server alpn - gnutls" \ -s "HTTP/1.0 200 OK" \ -s "Application Layer Protocol is h2" -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 -requires_config_enabled MBEDTLS_SSL_SRV_C -run_test "TLS 1.3 m->m: Not supported version check: cli TLS 1.2 only, srv TLS 1.3 only, fail" \ - "$P_SRV debug_level=4 max_version=tls13 min_version=tls13" \ - "$P_CLI debug_level=4 max_version=tls12 min_version=tls12" \ - 1 \ - -c "The SSL configuration is tls12 only" \ - -c "supported_versions(43) extension does not exist." \ - -c "A fatal alert message was received from our peer" \ - -s "The SSL configuration is tls13 only" \ - -s "TLS 1.2 not supported." - requires_openssl_tls1_3_with_compatible_ephemeral requires_config_enabled MBEDTLS_DEBUG_C requires_config_enabled MBEDTLS_SSL_CLI_C From dcfd00c128b3f9aa4647d2bbd70b27fa3654ea81 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 6 Mar 2024 15:58:50 +0100 Subject: [PATCH 103/211] ssl-opt.sh: Change MbedTLS only version negotiation tests Change description and dependencies before to expand MbedTLS only version negotiation tests. Signed-off-by: Ronald Cron --- tests/ssl-opt.sh | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index bcaa9d2292..451b5beff4 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -6873,29 +6873,30 @@ run_test "Event-driven I/O, DTLS: session-id resume, UDP packing" \ # Tests for version negotiation, MbedTLS client and server -run_test "Version check: all -> 1.2" \ +requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +run_test "Version negotiation check m->m: 1.2 (max=1.2) / 1.2+1.3 -> 1.2" \ "$P_SRV" \ - "$P_CLI force_version=tls12" \ + "$P_CLI max_version=tls12" \ 0 \ -S "mbedtls_ssl_handshake returned" \ -C "mbedtls_ssl_handshake returned" \ -s "Protocol is TLSv1.2" \ -c "Protocol is TLSv1.2" -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 -requires_config_enabled MBEDTLS_SSL_SRV_C -run_test "TLS 1.3 m->m: Not supported version check: cli TLS 1.2 only, srv TLS 1.3 only, fail" \ - "$P_SRV debug_level=4 max_version=tls13 min_version=tls13" \ - "$P_CLI debug_level=4 max_version=tls12 min_version=tls12" \ - 1 \ - -c "The SSL configuration is tls12 only" \ - -c "supported_versions(43) extension does not exist." \ - -c "A fatal alert message was received from our peer" \ - -s "The SSL configuration is tls13 only" \ - -s "TLS 1.2 not supported." +requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +run_test "Not supported version check m->m: 1.2 (max=1.2) / 1.3 (min=1.3)" \ + "$P_SRV min_version=tls13" \ + "$P_CLI max_version=tls12" \ + 1 \ + -s "Handshake protocol not within min/max boundaries" \ + -S "Protocol is TLSv1.2" \ + -C "Protocol is TLSv1.2" \ + -S "Protocol is TLSv1.3" \ + -C "Protocol is TLSv1.3" # Tests of version negotiation on server side against GnuTLS client From 114c5f0321828661260e83bec656fbfddfd7852c Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 6 Mar 2024 15:24:41 +0100 Subject: [PATCH 104/211] ssl-opt.sh: Expand MbedTLS only version negotiation tests Signed-off-by: Ronald Cron --- tests/ssl-opt.sh | 107 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 451b5beff4..aea029546e 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -6873,9 +6873,93 @@ run_test "Event-driven I/O, DTLS: session-id resume, UDP packing" \ # Tests for version negotiation, MbedTLS client and server +requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C +requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT +run_test "Version negotiation check m->m: 1.2 / 1.2 -> 1.2" \ + "$P_SRV" \ + "$P_CLI" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -C "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.2" \ + -c "Protocol is TLSv1.2" + +requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 +requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT +run_test "Version negotiation check m->m: 1.2 (max=1.2) / 1.2 (max=1.2) -> 1.2" \ + "$P_SRV max_version=tls12" \ + "$P_CLI max_version=tls12" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -C "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.2" \ + -c "Protocol is TLSv1.2" + +requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_2 +run_test "Version negotiation check m->m: 1.3 / 1.3 -> 1.3" \ + "$P_SRV" \ + "$P_CLI" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -C "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.3" \ + -c "Protocol is TLSv1.3" + requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +run_test "Version negotiation check m->m: 1.3 (min=1.3) / 1.3 (min=1.3) -> 1.3" \ + "$P_SRV min_version=tls13" \ + "$P_CLI min_version=tls13" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -C "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.3" \ + -c "Protocol is TLSv1.3" + +requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +run_test "Version negotiation check m->m: 1.2+1.3 / 1.2+1.3 -> 1.3" \ + "$P_SRV" \ + "$P_CLI" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -C "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.3" \ + -c "Protocol is TLSv1.3" + +requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +run_test "Version negotiation check m->m: 1.2+1.3 / 1.3 (min=1.3) -> 1.3" \ + "$P_SRV min_version=tls13" \ + "$P_CLI" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -C "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.3" \ + -c "Protocol is TLSv1.3" + +requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 +requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT +run_test "Version negotiation check m->m: 1.2+1.3 / 1.2 (max=1.2) -> 1.2" \ + "$P_SRV max_version=tls12" \ + "$P_CLI" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -C "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.2" \ + -c "Protocol is TLSv1.2" + +requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 +requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT run_test "Version negotiation check m->m: 1.2 (max=1.2) / 1.2+1.3 -> 1.2" \ "$P_SRV" \ "$P_CLI max_version=tls12" \ @@ -6888,6 +6972,17 @@ run_test "Version negotiation check m->m: 1.2 (max=1.2) / 1.2+1.3 -> 1.2" \ requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +run_test "Version negotiation check m->m: 1.3 (min=1.3) / 1.2+1.3 -> 1.3" \ + "$P_SRV" \ + "$P_CLI min_version=tls13" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -C "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.3" \ + -c "Protocol is TLSv1.3" + +requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 run_test "Not supported version check m->m: 1.2 (max=1.2) / 1.3 (min=1.3)" \ "$P_SRV min_version=tls13" \ "$P_CLI max_version=tls12" \ @@ -6898,6 +6993,18 @@ run_test "Not supported version check m->m: 1.2 (max=1.2) / 1.3 (min=1.3)" \ -S "Protocol is TLSv1.3" \ -C "Protocol is TLSv1.3" +requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 +run_test "Not supported version check m->m: 1.3 (min=1.3) / 1.2 (max=1.2)" \ + "$P_SRV max_version=tls12" \ + "$P_CLI min_version=tls13" \ + 1 \ + -s "The handshake negotiation failed" \ + -S "Protocol is TLSv1.2" \ + -C "Protocol is TLSv1.2" \ + -S "Protocol is TLSv1.3" \ + -C "Protocol is TLSv1.3" + # Tests of version negotiation on server side against GnuTLS client requires_all_configs_enabled MBEDTLS_SSL_SRV_C MBEDTLS_SSL_PROTO_TLS1_2 From 10797e3da15efe3ab6b498554e28663c04bca926 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 7 Mar 2024 08:27:24 +0100 Subject: [PATCH 105/211] ssl-opt.sh: Add O->m server version selection tests Signed-off-by: Ronald Cron --- tests/ssl-opt.sh | 151 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index aea029546e..178aa5087e 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -7169,6 +7169,157 @@ run_test "Not supported version check G->m: 1.3 / 1.2 (max=1.2)" \ -s "The handshake negotiation failed" \ -S "Protocol is TLSv1.3" +# Tests of version negotiation on server side against OpenSSL client + +requires_all_configs_enabled MBEDTLS_SSL_SRV_C MBEDTLS_SSL_PROTO_TLS1_2 +requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT +run_test "Server version nego check O->m: 1.2 / 1.2+(1.3) -> 1.2" \ + "$P_SRV" \ + "$O_NEXT_CLI -tls1_2" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.2" + +requires_all_configs_enabled MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 +requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT +run_test "Server version nego check O->m: 1.2 / 1.2 (max=1.2) -> 1.2" \ + "$P_SRV max_version=tls12" \ + "$O_NEXT_CLI -tls1_2" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.2" + +requires_openssl_tls1_3_with_compatible_ephemeral +requires_all_configs_enabled MBEDTLS_SSL_SRV_C MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +run_test "Server version nego check O->m: 1.3 / (1.2)+1.3 -> 1.3" \ + "$P_SRV" \ + "$O_NEXT_CLI -tls1_3" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.3" + +requires_openssl_tls1_3_with_compatible_ephemeral +requires_all_configs_enabled MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +run_test "Server version nego check O->m: 1.3 / 1.3 (min=1.3) -> 1.3" \ + "$P_SRV min_version=tls13" \ + "$O_NEXT_CLI -tls1_3" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.3" + +requires_openssl_tls1_3_with_compatible_ephemeral +requires_all_configs_enabled MBEDTLS_SSL_SRV_C MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +run_test "Server version nego check O->m: 1.2+1.3 / (1.2)+1.3 -> 1.3" \ + "$P_SRV" \ + "$O_NEXT_CLI" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.3" + +requires_openssl_tls1_3_with_compatible_ephemeral +requires_all_configs_enabled MBEDTLS_SSL_SRV_C MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +run_test "Server version nego check O->m (no compat): 1.2+1.3 / (1.2)+1.3 -> 1.3" \ + "$P_SRV" \ + "$O_NEXT_CLI -no_middlebox" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.3" + +requires_openssl_tls1_3_with_compatible_ephemeral +requires_all_configs_enabled MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +run_test "Server version nego check O->m: 1.2+1.3 / 1.3 (min=1.3) -> 1.3" \ + "$P_SRV min_version=tls13" \ + "$O_NEXT_CLI" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.3" + +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT +run_test "Server version nego check O->m: 1.2+1.3 / 1.2 -> 1.2" \ + "$P_SRV" \ + "$O_NEXT_CLI" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.2" + +requires_all_configs_enabled MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 +requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT +run_test "Server version nego check O->m: 1.2+1.3 / 1.2 (max=1.2) -> 1.2" \ + "$P_SRV max_version=tls12" \ + "$O_NEXT_CLI" \ + 0 \ + -S "mbedtls_ssl_handshake returned" \ + -s "Protocol is TLSv1.2" + +requires_config_enabled MBEDTLS_SSL_SRV_C +run_test "Not supported version check O->m: 1.0 / (1.2)+(1.3)" \ + "$P_SRV" \ + "$O_CLI -tls1" \ + 1 \ + -s "Handshake protocol not within min/max boundaries" \ + -S "Protocol is TLSv1.0" + +requires_config_enabled MBEDTLS_SSL_SRV_C +run_test "Not supported version check O->m: 1.1 / (1.2)+(1.3)" \ + "$P_SRV" \ + "$O_CLI -tls1_1" \ + 1 \ + -s "Handshake protocol not within min/max boundaries" \ + -S "Protocol is TLSv1.1" + +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_2 +run_test "Not supported version check O->m: 1.2 / 1.3" \ + "$P_SRV" \ + "$O_NEXT_CLI -tls1_2" \ + 1 \ + -s "Handshake protocol not within min/max boundaries" \ + -S "Protocol is TLSv1.2" + +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_disabled MBEDTLS_SSL_PROTO_TLS1_3 +run_test "Not supported version check O->m: 1.3 / 1.2" \ + "$P_SRV" \ + "$O_NEXT_CLI -tls1_3" \ + 1 \ + -S "Handshake protocol not within min/max boundaries" \ + -s "The handshake negotiation failed" \ + -S "Protocol is TLSv1.3" + +requires_all_configs_enabled MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 +run_test "Not supported version check O->m: 1.2 / 1.3 (min=1.3)" \ + "$P_SRV min_version=tls13" \ + "$O_NEXT_CLI -tls1_2" \ + 1 \ + -s "Handshake protocol not within min/max boundaries" \ + -S "Protocol is TLSv1.2" + +requires_all_configs_enabled MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_3 +run_test "Not supported version check O->m: 1.3 / 1.2 (max=1.2)" \ + "$P_SRV max_version=tls12" \ + "$O_NEXT_CLI -tls1_3" \ + 1 \ + -S "Handshake protocol not within min/max boundaries" \ + -s "The handshake negotiation failed" \ + -S "Protocol is TLSv1.3" + # Tests of version negotiation on client side against GnuTLS and OpenSSL server requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 From 4faa34dc8680523e3c4f9fc31d068b04f4ac1952 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 12 Mar 2024 16:34:43 +0000 Subject: [PATCH 106/211] Fix gcc -O3 warnings Signed-off-by: Dave Rodgman --- library/cmac.c | 5 +++++ library/gcm.c | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/library/cmac.c b/library/cmac.c index cd3bd3ae40..c4f0b5408f 100644 --- a/library/cmac.c +++ b/library/cmac.c @@ -224,6 +224,10 @@ int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx, block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info); state = ctx->cmac_ctx->state; + /* Without the MBEDTLS_ASSUME below, gcc -O3 will generate a warning of the form + * error: writing 16 bytes into a region of size 0 [-Werror=stringop-overflow=] */ + MBEDTLS_ASSUME(block_size <= MBEDTLS_CMAC_MAX_BLOCK_SIZE); + /* Is there data still to process from the last call, that's greater in * size than a block? */ if (cmac_ctx->unprocessed_len > 0 && @@ -291,6 +295,7 @@ int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx, cmac_ctx = ctx->cmac_ctx; block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info); + MBEDTLS_ASSUME(block_size <= MBEDTLS_CMAC_MAX_BLOCK_SIZE); // silence GCC warning state = cmac_ctx->state; mbedtls_platform_zeroize(K1, sizeof(K1)); diff --git a/library/gcm.c b/library/gcm.c index 90c1d1d4ed..976d6d76de 100644 --- a/library/gcm.c +++ b/library/gcm.c @@ -412,8 +412,17 @@ int mbedtls_gcm_starts(mbedtls_gcm_context *ctx, while (iv_len > 0) { use_len = (iv_len < 16) ? iv_len : 16; +#if defined(MBEDTLS_COMPILER_IS_GCC) +#pragma GCC diagnostic push +#pragma GCC diagnostic warning "-Wstringop-overflow=0" +#endif + mbedtls_xor(ctx->y, ctx->y, p, use_len); +#if defined(MBEDTLS_COMPILER_IS_GCC) +#pragma GCC diagnostic pop +#endif + gcm_mult(ctx, ctx->y, ctx->y); iv_len -= use_len; From d2884662c13484d7392997cf2a8673699cc704cb Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Sun, 3 Mar 2024 15:03:22 +0100 Subject: [PATCH 107/211] tls13: cli: Split early data user status and internal state Do not use the return values of mbedtls_ssl_get_early_data_status() (MBEDTLS_SSL_EARLY_DATA_STATUS_ macros) for the state of the negotiation and transfer of early data during the handshake. Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 46 +++++++--- library/ssl_debug_helpers.h | 1 + library/ssl_msg.c | 28 +++--- library/ssl_tls.c | 2 +- library/ssl_tls13_client.c | 42 ++++----- tests/suites/test_suite_ssl.data | 16 ++-- tests/suites/test_suite_ssl.function | 122 +++++++++++++-------------- 7 files changed, 138 insertions(+), 119 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 9a66663318..df81e926b9 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -740,18 +740,37 @@ mbedtls_ssl_states; #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) typedef enum { -/* - * The client has not sent the first ClientHello yet, it is unknown if the - * client will send an early data indication extension or not. - */ - MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN, - /* * See documentation of mbedtls_ssl_get_early_data_status(). */ MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT, MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED, MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED, +} mbedtls_ssl_early_data_status; + +typedef enum { +/* + * The client has not sent the first ClientHello yet, it is unknown if the + * client will send an early data indication extension or not. + */ + MBEDTLS_SSL_EARLY_DATA_STATE_UNKNOWN, + +/* + * The client has not indicated the use of early data to the server. + */ + MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT, + +/* + * The client has indicated the use of early data and the server has accepted + * it. + */ + MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED, + +/* + * The client has indicated the use of early data but the server has rejected + * it. + */ + MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED, /* * The client has sent an early data indication extension in its first @@ -759,7 +778,7 @@ typedef enum { * HelloRetryRequest) from the server yet. The transform to protect early data * is not set and early data cannot be sent yet. */ - MBEDTLS_SSL_EARLY_DATA_STATUS_SENT, + MBEDTLS_SSL_EARLY_DATA_STATE_SENT, /* * The client has sent an early data indication extension in its first @@ -767,16 +786,15 @@ typedef enum { * HelloRetryRequest) from the server yet. The transform to protect early data * has been set and early data can be written now. */ - MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE, + MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE, /* * The client has sent an early data indication extension in its first * ClientHello, the server has accepted them and the client has received the * server Finished message. It cannot send early data to the server anymore. */ - MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED, -} mbedtls_ssl_early_data_status; - + MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED, +} mbedtls_ssl_early_data_state; #endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */ /** @@ -1737,10 +1755,10 @@ struct mbedtls_ssl_context { #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) /** - * Status of the negotiation of the use of early data. Reset to - * MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN when the context is reset. + * State of the negotiation and transfer of early data. Reset to + * MBEDTLS_SSL_EARLY_DATA_STATE_UNKNOWN when the context is reset. */ - mbedtls_ssl_early_data_status MBEDTLS_PRIVATE(early_data_status); + mbedtls_ssl_early_data_state MBEDTLS_PRIVATE(early_data_state); #endif unsigned MBEDTLS_PRIVATE(badmac_seen); /*!< records with a bad MAC received */ diff --git a/library/ssl_debug_helpers.h b/library/ssl_debug_helpers.h index a8e31409f8..4889e77e04 100644 --- a/library/ssl_debug_helpers.h +++ b/library/ssl_debug_helpers.h @@ -23,6 +23,7 @@ const char *mbedtls_ssl_states_str(mbedtls_ssl_states in); #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) const char *mbedtls_ssl_early_data_status_str(mbedtls_ssl_early_data_status in); +const char *mbedtls_ssl_early_data_state_str(mbedtls_ssl_early_data_state in); #endif const char *mbedtls_ssl_protocol_version_str(mbedtls_ssl_protocol_version in); diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 4949306498..ccced0a1e8 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -6097,21 +6097,21 @@ int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl, } /* - * If we are at the beginning of the handshake, the early data status being - * equal to MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN or - * MBEDTLS_SSL_EARLY_DATA_STATUS_SENT advance the handshake just + * If we are at the beginning of the handshake, the early data state being + * equal to MBEDTLS_SSL_EARLY_DATA_STATE_UNKNOWN or + * MBEDTLS_SSL_EARLY_DATA_STATE_SENT advance the handshake just * enough to be able to send early data if possible. That way, we can * guarantee that when starting the handshake with this function we will - * send at least one record of early data. Note that when the status is - * MBEDTLS_SSL_EARLY_DATA_STATUS_SENT and not yet - * MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE, we cannot send early data yet + * send at least one record of early data. Note that when the state is + * MBEDTLS_SSL_EARLY_DATA_STATE_SENT and not yet + * MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE, we cannot send early data yet * as the early data outbound transform has not been set as we may have to * first send a dummy CCS in clear. */ - if ((ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN) || - (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_SENT)) { - while ((ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN) || - (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_SENT)) { + if ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_UNKNOWN) || + (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_SENT)) { + while ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_UNKNOWN) || + (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_SENT)) { ret = mbedtls_ssl_handshake_step(ssl); if (ret != 0) { MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake_step", ret); @@ -6133,8 +6133,8 @@ int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl, * it too much. If we reach a point where we can still send early data, * then we will send some. */ - if ((ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE) && - (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED)) { + if ((ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE) && + (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED)) { return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA; } @@ -6152,8 +6152,8 @@ int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl, } } - if (((ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE) && - (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED)) + if (((ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE) && + (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED)) || (remaining == 0)) { return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA; } diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 1bfd18001e..97235ef53b 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1096,7 +1096,7 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl) #if defined(MBEDTLS_SSL_EARLY_DATA) #if defined(MBEDTLS_SSL_CLI_C) - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN; + ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_UNKNOWN; #endif #if defined(MBEDTLS_SSL_SRV_C) ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD; diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 88d6c9e019..8234e9af66 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -1181,12 +1181,12 @@ int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl, #if defined(MBEDTLS_SSL_EARLY_DATA) /* In the first ClientHello, write the early data indication extension if - * necessary and update the early data status. + * necessary and update the early data state. * If an HRR has been received and thus we are currently writing the * second ClientHello, the second ClientHello must not contain an early - * data extension and the early data status must stay as it is: - * MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT or - * MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED. + * data extension and the early data state must stay as it is: + * MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT or + * MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED. */ if (!ssl->handshake->hello_retry_request_flag) { if (mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl) && @@ -1199,9 +1199,9 @@ int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl, } p += ext_len; - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_SENT; + ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_SENT; } else { - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT; + ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT; } } #endif /* MBEDTLS_SSL_EARLY_DATA */ @@ -1239,7 +1239,7 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl) size_t psk_len; const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_SENT) { + if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_SENT) { MBEDTLS_SSL_DEBUG_MSG( 1, ("Set hs psk for early data when writing the first psk")); @@ -1302,7 +1302,7 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl) 1, ("Switch to early data keys for outbound traffic")); mbedtls_ssl_set_outbound_transform( ssl, ssl->handshake->transform_earlydata); - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE; + ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE; #endif } #endif /* MBEDTLS_SSL_EARLY_DATA */ @@ -1919,7 +1919,7 @@ static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl) * cases we compute it here. */ #if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT || + if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT || handshake->key_exchange_mode == MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL) #endif @@ -1975,8 +1975,8 @@ static int ssl_tls13_postprocess_hrr(mbedtls_ssl_context *ssl) ssl->session_negotiate->ciphersuite = ssl->handshake->ciphersuite_info->id; #if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT) { - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED; + if (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT) { + ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED; } #endif @@ -2238,9 +2238,9 @@ static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl) return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; } - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED; - } else if (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT) { - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED; + ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED; + } else if (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT) { + ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED; } #endif @@ -2324,16 +2324,16 @@ int mbedtls_ssl_get_early_data_status(mbedtls_ssl_context *ssl) return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; } - switch (ssl->early_data_status) { - case MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT: + switch (ssl->early_data_state) { + case MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT: return MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT; break; - case MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED: + case MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED: return MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED; break; - case MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED: + case MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED: return MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED; break; @@ -2604,8 +2604,8 @@ static int ssl_tls13_process_server_finished(mbedtls_ssl_context *ssl) } #if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) { - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED; + if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED) { + ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED; mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_END_OF_EARLY_DATA); } else #endif /* MBEDTLS_SSL_EARLY_DATA */ @@ -3123,7 +3123,7 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl) 1, ("Switch to early data keys for outbound traffic")); mbedtls_ssl_set_outbound_transform( ssl, ssl->handshake->transform_earlydata); - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE; + ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE; } break; #endif /* MBEDTLS_SSL_EARLY_DATA */ diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index e95aada0ec..eef5cf1645 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3286,17 +3286,17 @@ tls13_read_early_data:TEST_EARLY_DATA_SERVER_REJECTS TLS 1.3 read early data, discard after HRR tls13_read_early_data:TEST_EARLY_DATA_HRR -TLS 1.3 cli, early data status, early data accepted -tls13_cli_early_data_status:TEST_EARLY_DATA_ACCEPTED +TLS 1.3 cli, early data state, early data accepted +tls13_cli_early_data_state:TEST_EARLY_DATA_ACCEPTED -TLS 1.3 cli, early data status, no early data indication -tls13_cli_early_data_status:TEST_EARLY_DATA_NO_INDICATION_SENT +TLS 1.3 cli, early data state, no early data indication +tls13_cli_early_data_state:TEST_EARLY_DATA_NO_INDICATION_SENT -TLS 1.3 cli, early data status, server rejects early data -tls13_cli_early_data_status:TEST_EARLY_DATA_SERVER_REJECTS +TLS 1.3 cli, early data state, server rejects early data +tls13_cli_early_data_state:TEST_EARLY_DATA_SERVER_REJECTS -TLS 1.3 cli, early data status, hello retry request -tls13_cli_early_data_status:TEST_EARLY_DATA_HRR +TLS 1.3 cli, early data state, hello retry request +tls13_cli_early_data_state:TEST_EARLY_DATA_HRR TLS 1.3 write early data, early data accepted tls13_write_early_data:TEST_EARLY_DATA_ACCEPTED diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 0c9ccf1695..d470cd8e10 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -3738,8 +3738,8 @@ void tls13_read_early_data(int scenario) (unsigned char *) early_data, early_data_len); - if (client_ep.ssl.early_data_status != - MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT) { + if (client_ep.ssl.early_data_state != + MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT) { TEST_EQUAL(ret, early_data_len); } else { TEST_EQUAL(ret, MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA); @@ -3790,7 +3790,7 @@ exit: /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_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_cli_early_data_status(int scenario) +void tls13_cli_early_data_state(int scenario) { int ret = -1; mbedtls_test_ssl_endpoint client_ep, server_ep; @@ -3903,17 +3903,17 @@ void tls13_cli_early_data_status(int scenario) case TEST_EARLY_DATA_ACCEPTED: /* Intentional fallthrough */ case TEST_EARLY_DATA_NO_INDICATION_SENT: /* Intentional fallthrough */ case TEST_EARLY_DATA_SERVER_REJECTS: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_UNKNOWN); break; case TEST_EARLY_DATA_HRR: if (!client_ep.ssl.handshake->hello_retry_request_flag) { - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_UNKNOWN); } else { - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED); } break; @@ -3926,22 +3926,22 @@ void tls13_cli_early_data_status(int scenario) switch (scenario) { case TEST_EARLY_DATA_ACCEPTED: /* Intentional fallthrough */ case TEST_EARLY_DATA_SERVER_REJECTS: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE); break; case TEST_EARLY_DATA_NO_INDICATION_SENT: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT); break; case TEST_EARLY_DATA_HRR: if (!client_ep.ssl.handshake->hello_retry_request_flag) { - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE); } else { - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED); } break; @@ -3954,18 +3954,18 @@ void tls13_cli_early_data_status(int scenario) switch (scenario) { case TEST_EARLY_DATA_ACCEPTED: /* Intentional fallthrough */ case TEST_EARLY_DATA_SERVER_REJECTS: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE); break; case TEST_EARLY_DATA_NO_INDICATION_SENT: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT); break; case TEST_EARLY_DATA_HRR: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED); break; default: @@ -3976,19 +3976,19 @@ void tls13_cli_early_data_status(int scenario) case MBEDTLS_SSL_SERVER_FINISHED: switch (scenario) { case TEST_EARLY_DATA_ACCEPTED: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED); break; case TEST_EARLY_DATA_NO_INDICATION_SENT: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT); break; case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */ case TEST_EARLY_DATA_HRR: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED); break; default: @@ -3998,26 +3998,26 @@ void tls13_cli_early_data_status(int scenario) case MBEDTLS_SSL_END_OF_EARLY_DATA: TEST_EQUAL(scenario, TEST_EARLY_DATA_ACCEPTED); - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED); break; case MBEDTLS_SSL_CLIENT_CERTIFICATE: switch (scenario) { case TEST_EARLY_DATA_ACCEPTED: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED); break; case TEST_EARLY_DATA_NO_INDICATION_SENT: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT); break; case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */ case TEST_EARLY_DATA_HRR: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED); break; default: @@ -4028,19 +4028,19 @@ void tls13_cli_early_data_status(int scenario) case MBEDTLS_SSL_CLIENT_FINISHED: switch (scenario) { case TEST_EARLY_DATA_ACCEPTED: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED); break; case TEST_EARLY_DATA_NO_INDICATION_SENT: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT); break; case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */ case TEST_EARLY_DATA_HRR: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED); break; default: @@ -4054,8 +4054,8 @@ void tls13_cli_early_data_status(int scenario) case TEST_EARLY_DATA_ACCEPTED: /* Intentional fallthrough */ case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */ case TEST_EARLY_DATA_HRR: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_SENT); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_SENT); break; default: @@ -4065,21 +4065,21 @@ void tls13_cli_early_data_status(int scenario) case MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO: TEST_ASSERT(scenario == TEST_EARLY_DATA_HRR); - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED); break; case MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED: switch (scenario) { case TEST_EARLY_DATA_NO_INDICATION_SENT: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT); break; case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */ case TEST_EARLY_DATA_HRR: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED); break; default: @@ -4093,19 +4093,19 @@ void tls13_cli_early_data_status(int scenario) case MBEDTLS_SSL_HANDSHAKE_OVER: switch (scenario) { case TEST_EARLY_DATA_ACCEPTED: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED); break; case TEST_EARLY_DATA_NO_INDICATION_SENT: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT); break; case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */ case TEST_EARLY_DATA_HRR: - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED); break; default: @@ -4606,8 +4606,8 @@ void tls13_cli_max_early_data_size(int max_early_data_size_arg) ret = mbedtls_ssl_write_early_data(&(client_ep.ssl), buf, 1); TEST_EQUAL(ret, MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA); TEST_EQUAL(client_ep.ssl.total_early_data_size, max_early_data_size); - TEST_EQUAL(client_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE); + TEST_EQUAL(client_ep.ssl.early_data_state, + MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE); /* * Now, check data on server side. It is not done in the previous loop as @@ -4780,8 +4780,8 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, in &(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); + TEST_ASSERT(client_ep.ssl.early_data_state != + MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT); ret = mbedtls_ssl_handshake(&(server_ep.ssl)); TEST_EQUAL(ret, MBEDTLS_ERR_SSL_WANT_READ); From 05d7cfbd9cb409b6f3a0bcc00821b05e09eeeee3 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Sun, 3 Mar 2024 15:39:30 +0100 Subject: [PATCH 108/211] tls13: cli: Rename STATE_UNKNOWN to STATE_IDLE Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 8 ++++---- library/ssl_msg.c | 6 +++--- library/ssl_tls.c | 2 +- tests/suites/test_suite_ssl.function | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index df81e926b9..bd860feff5 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -750,10 +750,10 @@ typedef enum { typedef enum { /* - * The client has not sent the first ClientHello yet, it is unknown if the - * client will send an early data indication extension or not. + * The client has not sent the first ClientHello yet, the negotiation of early + * data has not started yet. */ - MBEDTLS_SSL_EARLY_DATA_STATE_UNKNOWN, + MBEDTLS_SSL_EARLY_DATA_STATE_IDLE, /* * The client has not indicated the use of early data to the server. @@ -1756,7 +1756,7 @@ struct mbedtls_ssl_context { #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) /** * State of the negotiation and transfer of early data. Reset to - * MBEDTLS_SSL_EARLY_DATA_STATE_UNKNOWN when the context is reset. + * MBEDTLS_SSL_EARLY_DATA_STATE_IDLE when the context is reset. */ mbedtls_ssl_early_data_state MBEDTLS_PRIVATE(early_data_state); #endif diff --git a/library/ssl_msg.c b/library/ssl_msg.c index ccced0a1e8..56e5514f3c 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -6098,7 +6098,7 @@ int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl, /* * If we are at the beginning of the handshake, the early data state being - * equal to MBEDTLS_SSL_EARLY_DATA_STATE_UNKNOWN or + * equal to MBEDTLS_SSL_EARLY_DATA_STATE_IDLE or * MBEDTLS_SSL_EARLY_DATA_STATE_SENT advance the handshake just * enough to be able to send early data if possible. That way, we can * guarantee that when starting the handshake with this function we will @@ -6108,9 +6108,9 @@ int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl, * as the early data outbound transform has not been set as we may have to * first send a dummy CCS in clear. */ - if ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_UNKNOWN) || + if ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IDLE) || (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_SENT)) { - while ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_UNKNOWN) || + while ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IDLE) || (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_SENT)) { ret = mbedtls_ssl_handshake_step(ssl); if (ret != 0) { diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 97235ef53b..681ccab441 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1096,7 +1096,7 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl) #if defined(MBEDTLS_SSL_EARLY_DATA) #if defined(MBEDTLS_SSL_CLI_C) - ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_UNKNOWN; + ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_IDLE; #endif #if defined(MBEDTLS_SSL_SRV_C) ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD; diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index d470cd8e10..49609575bb 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -3904,13 +3904,13 @@ void tls13_cli_early_data_state(int scenario) case TEST_EARLY_DATA_NO_INDICATION_SENT: /* Intentional fallthrough */ case TEST_EARLY_DATA_SERVER_REJECTS: TEST_EQUAL(client_ep.ssl.early_data_state, - MBEDTLS_SSL_EARLY_DATA_STATE_UNKNOWN); + MBEDTLS_SSL_EARLY_DATA_STATE_IDLE); break; case TEST_EARLY_DATA_HRR: if (!client_ep.ssl.handshake->hello_retry_request_flag) { TEST_EQUAL(client_ep.ssl.early_data_state, - MBEDTLS_SSL_EARLY_DATA_STATE_UNKNOWN); + MBEDTLS_SSL_EARLY_DATA_STATE_IDLE); } else { TEST_EQUAL(client_ep.ssl.early_data_state, MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED); From 0c80dc1ed517494f78f7b2115337f363735ad15e Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Sun, 3 Mar 2024 16:40:06 +0100 Subject: [PATCH 109/211] tls13: cli: Rename STATUS_NOT_SENT to STATUS_NO_IND_SENT Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 4 ++-- library/ssl_tls13_client.c | 2 +- tests/suites/test_suite_ssl.function | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index bd860feff5..b3f73518af 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -743,7 +743,7 @@ typedef enum { /* * See documentation of mbedtls_ssl_get_early_data_status(). */ - MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT, + MBEDTLS_SSL_EARLY_DATA_STATUS_NO_IND_SENT, MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED, MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED, } mbedtls_ssl_early_data_status; @@ -5358,7 +5358,7 @@ int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl, * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if this function is called * prior to completion of the handshake. * - * \return #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT if the client has + * \return #MBEDTLS_SSL_EARLY_DATA_STATUS_NO_IND_SENT if the client has * not indicated the use of early data to the server. * * \return #MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED if the client has diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 8234e9af66..d9b4ff282e 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -2326,7 +2326,7 @@ int mbedtls_ssl_get_early_data_status(mbedtls_ssl_context *ssl) switch (ssl->early_data_state) { case MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT: - return MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT; + return MBEDTLS_SSL_EARLY_DATA_STATUS_NO_IND_SENT; break; case MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED: diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 49609575bb..22bd09f9b3 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4125,7 +4125,7 @@ void tls13_cli_early_data_state(int scenario) break; case TEST_EARLY_DATA_NO_INDICATION_SENT: - TEST_EQUAL(ret, MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT); + TEST_EQUAL(ret, MBEDTLS_SSL_EARLY_DATA_STATUS_NO_IND_SENT); break; case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */ From 3c5a68339ba8d07428027ffbc1f9a974bfdf7b74 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Sun, 3 Mar 2024 15:46:57 +0100 Subject: [PATCH 110/211] tls13: cli: Rename STATE_NOT_SENT to STATE_NO_IND_SENT Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 5 +++-- library/ssl_tls13_client.c | 13 +++++++------ tests/suites/test_suite_ssl.function | 18 +++++++++--------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index b3f73518af..f86bc4270f 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -756,9 +756,10 @@ typedef enum { MBEDTLS_SSL_EARLY_DATA_STATE_IDLE, /* - * The client has not indicated the use of early data to the server. + * In its ClientHello, the client has not included an early data indication + * extension. */ - MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT, + MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT, /* * The client has indicated the use of early data and the server has accepted diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index d9b4ff282e..221b05de0f 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -1185,7 +1185,7 @@ int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl, * If an HRR has been received and thus we are currently writing the * second ClientHello, the second ClientHello must not contain an early * data extension and the early data state must stay as it is: - * MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT or + * MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT or * MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED. */ if (!ssl->handshake->hello_retry_request_flag) { @@ -1201,7 +1201,7 @@ int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl, ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_SENT; } else { - ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT; + ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT; } } #endif /* MBEDTLS_SSL_EARLY_DATA */ @@ -1919,7 +1919,7 @@ static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl) * cases we compute it here. */ #if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT || + if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT || handshake->key_exchange_mode == MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL) #endif @@ -1975,7 +1975,7 @@ static int ssl_tls13_postprocess_hrr(mbedtls_ssl_context *ssl) ssl->session_negotiate->ciphersuite = ssl->handshake->ciphersuite_info->id; #if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT) { + if (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT) { ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED; } #endif @@ -2239,7 +2239,8 @@ static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl) } ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED; - } else if (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT) { + } else if (ssl->early_data_state != + MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT) { ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED; } #endif @@ -2325,7 +2326,7 @@ int mbedtls_ssl_get_early_data_status(mbedtls_ssl_context *ssl) } switch (ssl->early_data_state) { - case MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT: + case MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT: return MBEDTLS_SSL_EARLY_DATA_STATUS_NO_IND_SENT; break; diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 22bd09f9b3..dc7f7c27e5 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -3739,7 +3739,7 @@ void tls13_read_early_data(int scenario) early_data_len); if (client_ep.ssl.early_data_state != - MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT) { + MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT) { TEST_EQUAL(ret, early_data_len); } else { TEST_EQUAL(ret, MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA); @@ -3932,7 +3932,7 @@ void tls13_cli_early_data_state(int scenario) case TEST_EARLY_DATA_NO_INDICATION_SENT: TEST_EQUAL(client_ep.ssl.early_data_state, - MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT); + MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT); break; case TEST_EARLY_DATA_HRR: @@ -3960,7 +3960,7 @@ void tls13_cli_early_data_state(int scenario) case TEST_EARLY_DATA_NO_INDICATION_SENT: TEST_EQUAL(client_ep.ssl.early_data_state, - MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT); + MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT); break; case TEST_EARLY_DATA_HRR: @@ -3982,7 +3982,7 @@ void tls13_cli_early_data_state(int scenario) case TEST_EARLY_DATA_NO_INDICATION_SENT: TEST_EQUAL(client_ep.ssl.early_data_state, - MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT); + MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT); break; case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */ @@ -4011,7 +4011,7 @@ void tls13_cli_early_data_state(int scenario) case TEST_EARLY_DATA_NO_INDICATION_SENT: TEST_EQUAL(client_ep.ssl.early_data_state, - MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT); + MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT); break; case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */ @@ -4034,7 +4034,7 @@ void tls13_cli_early_data_state(int scenario) case TEST_EARLY_DATA_NO_INDICATION_SENT: TEST_EQUAL(client_ep.ssl.early_data_state, - MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT); + MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT); break; case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */ @@ -4073,7 +4073,7 @@ void tls13_cli_early_data_state(int scenario) switch (scenario) { case TEST_EARLY_DATA_NO_INDICATION_SENT: TEST_EQUAL(client_ep.ssl.early_data_state, - MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT); + MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT); break; case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */ @@ -4099,7 +4099,7 @@ void tls13_cli_early_data_state(int scenario) case TEST_EARLY_DATA_NO_INDICATION_SENT: TEST_EQUAL(client_ep.ssl.early_data_state, - MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT); + MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT); break; case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */ @@ -4781,7 +4781,7 @@ void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, in MBEDTLS_SSL_SERVER_HELLO), 0); TEST_ASSERT(client_ep.ssl.early_data_state != - MBEDTLS_SSL_EARLY_DATA_STATE_NOT_SENT); + MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT); ret = mbedtls_ssl_handshake(&(server_ep.ssl)); TEST_EQUAL(ret, MBEDTLS_ERR_SSL_WANT_READ); From 3641df2980e121bae8fe1de2493e28a6678aeab2 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Sun, 3 Mar 2024 16:10:58 +0100 Subject: [PATCH 111/211] tls13: cli: Rename STATE_SENT to STATE_IND_SENT Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 5 +++-- library/ssl_msg.c | 10 +++++----- library/ssl_tls13_client.c | 4 ++-- tests/suites/test_suite_ssl.function | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index f86bc4270f..8ad6bb0c38 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -777,9 +777,10 @@ typedef enum { * The client has sent an early data indication extension in its first * ClientHello, it has not received the response (ServerHello or * HelloRetryRequest) from the server yet. The transform to protect early data - * is not set and early data cannot be sent yet. + * is not set either as for middlebox compatibility a dummy CCs may have to be + * sent in clear. Early data cannot be sent to the server yet. */ - MBEDTLS_SSL_EARLY_DATA_STATE_SENT, + MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT, /* * The client has sent an early data indication extension in its first diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 56e5514f3c..b07cd96f1b 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -6099,19 +6099,19 @@ int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl, /* * If we are at the beginning of the handshake, the early data state being * equal to MBEDTLS_SSL_EARLY_DATA_STATE_IDLE or - * MBEDTLS_SSL_EARLY_DATA_STATE_SENT advance the handshake just + * MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT advance the handshake just * enough to be able to send early data if possible. That way, we can * guarantee that when starting the handshake with this function we will * send at least one record of early data. Note that when the state is - * MBEDTLS_SSL_EARLY_DATA_STATE_SENT and not yet - * MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE, we cannot send early data yet + * MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT and not yet + * MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE, we cannot send early data * as the early data outbound transform has not been set as we may have to * first send a dummy CCS in clear. */ if ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IDLE) || - (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_SENT)) { + (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT)) { while ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IDLE) || - (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_SENT)) { + (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT)) { ret = mbedtls_ssl_handshake_step(ssl); if (ret != 0) { MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake_step", ret); diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 221b05de0f..1ebbc7677d 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -1199,7 +1199,7 @@ int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl, } p += ext_len; - ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_SENT; + ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT; } else { ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT; } @@ -1239,7 +1239,7 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl) size_t psk_len; const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_SENT) { + if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT) { MBEDTLS_SSL_DEBUG_MSG( 1, ("Set hs psk for early data when writing the first psk")); diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index dc7f7c27e5..6f022eb70a 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4055,7 +4055,7 @@ void tls13_cli_early_data_state(int scenario) case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */ case TEST_EARLY_DATA_HRR: TEST_EQUAL(client_ep.ssl.early_data_state, - MBEDTLS_SSL_EARLY_DATA_STATE_SENT); + MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT); break; default: From 894df384f4369cb62792cd1fea070f1eb64638a5 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Sun, 3 Mar 2024 16:23:13 +0100 Subject: [PATCH 112/211] tls13: cli: Re-order early data states Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 8ad6bb0c38..766ad791ae 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -761,18 +761,6 @@ typedef enum { */ MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT, -/* - * The client has indicated the use of early data and the server has accepted - * it. - */ - MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED, - -/* - * The client has indicated the use of early data but the server has rejected - * it. - */ - MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED, - /* * The client has sent an early data indication extension in its first * ClientHello, it has not received the response (ServerHello or @@ -790,12 +778,25 @@ typedef enum { */ MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE, +/* + * The client has indicated the use of early data and the server has accepted + * it. + */ + MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED, + +/* + * The client has indicated the use of early data but the server has rejected + * it. + */ + MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED, + /* * The client has sent an early data indication extension in its first * ClientHello, the server has accepted them and the client has received the * server Finished message. It cannot send early data to the server anymore. */ MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED, + } mbedtls_ssl_early_data_state; #endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */ From aa3593141b98d6634cfae408ad40504f11dccb85 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 11 Mar 2024 17:24:39 +0100 Subject: [PATCH 113/211] tls13: cli: Move definition of MBEDTLS_SSL_EARLY_DATA_STATE_xyz Move definition of MBEDTLS_SSL_EARLY_DATA_STATE_xyz from ssl.h(public) to ssl_misc.h(private) even if that means we cannot use the enum type for early_data_state in ssl.h. Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 53 +------------------------------------------ library/ssl_misc.h | 51 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 766ad791ae..7435448df8 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -747,57 +747,6 @@ typedef enum { MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED, MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED, } mbedtls_ssl_early_data_status; - -typedef enum { -/* - * The client has not sent the first ClientHello yet, the negotiation of early - * data has not started yet. - */ - MBEDTLS_SSL_EARLY_DATA_STATE_IDLE, - -/* - * In its ClientHello, the client has not included an early data indication - * extension. - */ - MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT, - -/* - * The client has sent an early data indication extension in its first - * ClientHello, it has not received the response (ServerHello or - * HelloRetryRequest) from the server yet. The transform to protect early data - * is not set either as for middlebox compatibility a dummy CCs may have to be - * sent in clear. Early data cannot be sent to the server yet. - */ - MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT, - -/* - * The client has sent an early data indication extension in its first - * ClientHello, it has not received the response (ServerHello or - * HelloRetryRequest) from the server yet. The transform to protect early data - * has been set and early data can be written now. - */ - MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE, - -/* - * The client has indicated the use of early data and the server has accepted - * it. - */ - MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED, - -/* - * The client has indicated the use of early data but the server has rejected - * it. - */ - MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED, - -/* - * The client has sent an early data indication extension in its first - * ClientHello, the server has accepted them and the client has received the - * server Finished message. It cannot send early data to the server anymore. - */ - MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED, - -} mbedtls_ssl_early_data_state; #endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */ /** @@ -1761,7 +1710,7 @@ struct mbedtls_ssl_context { * State of the negotiation and transfer of early data. Reset to * MBEDTLS_SSL_EARLY_DATA_STATE_IDLE when the context is reset. */ - mbedtls_ssl_early_data_state MBEDTLS_PRIVATE(early_data_state); + int MBEDTLS_PRIVATE(early_data_state); #endif unsigned MBEDTLS_PRIVATE(badmac_seen); /*!< records with a bad MAC received */ diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 883b98828d..05395537dd 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2153,6 +2153,57 @@ 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); + +typedef enum { +/* + * The client has not sent the first ClientHello yet, the negotiation of early + * data has not started yet. + */ + MBEDTLS_SSL_EARLY_DATA_STATE_IDLE, + +/* + * In its ClientHello, the client has not included an early data indication + * extension. + */ + MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT, + +/* + * The client has sent an early data indication extension in its first + * ClientHello, it has not received the response (ServerHello or + * HelloRetryRequest) from the server yet. The transform to protect early data + * is not set either as for middlebox compatibility a dummy CCs may have to be + * sent in clear. Early data cannot be sent to the server yet. + */ + MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT, + +/* + * The client has sent an early data indication extension in its first + * ClientHello, it has not received the response (ServerHello or + * HelloRetryRequest) from the server yet. The transform to protect early data + * has been set and early data can be written now. + */ + MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE, + +/* + * The client has indicated the use of early data and the server has accepted + * it. + */ + MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED, + +/* + * The client has indicated the use of early data but the server has rejected + * it. + */ + MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED, + +/* + * The client has sent an early data indication extension in its first + * ClientHello, the server has accepted them and the client has received the + * server Finished message. It cannot send early data to the server anymore. + */ + MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED, + +} mbedtls_ssl_early_data_state; #endif /* MBEDTLS_SSL_EARLY_DATA */ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ From fd4c0c8b3d218dbf3221552382e9da981d573ea1 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 11 Mar 2024 17:28:44 +0100 Subject: [PATCH 114/211] tls13: cli: Fix comment Signed-off-by: Ronald Cron --- library/ssl_misc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 05395537dd..2ec898b453 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2171,7 +2171,7 @@ typedef enum { * The client has sent an early data indication extension in its first * ClientHello, it has not received the response (ServerHello or * HelloRetryRequest) from the server yet. The transform to protect early data - * is not set either as for middlebox compatibility a dummy CCs may have to be + * is not set either as for middlebox compatibility a dummy CCS may have to be * sent in clear. Early data cannot be sent to the server yet. */ MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT, From 840de7ff2f2fb49aca9c001e840cfa9329a96656 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 11 Mar 2024 17:49:35 +0100 Subject: [PATCH 115/211] tls13: cli: Rename STATUS_NOT_SENT to STATUS_NOT_INDICATED Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 6 +++--- library/ssl_tls13_client.c | 2 +- tests/suites/test_suite_ssl.function | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 7435448df8..61b2359947 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -743,7 +743,7 @@ typedef enum { /* * See documentation of mbedtls_ssl_get_early_data_status(). */ - MBEDTLS_SSL_EARLY_DATA_STATUS_NO_IND_SENT, + MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_INDICATED, MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED, MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED, } mbedtls_ssl_early_data_status; @@ -5310,8 +5310,8 @@ int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl, * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if this function is called * prior to completion of the handshake. * - * \return #MBEDTLS_SSL_EARLY_DATA_STATUS_NO_IND_SENT if the client has - * not indicated the use of early data to the server. + * \return #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_INDICATED if the client + * has not indicated the use of early data to the server. * * \return #MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED if the client has * indicated the use of early data and the server has accepted diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 1ebbc7677d..bda77e4bf1 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -2327,7 +2327,7 @@ int mbedtls_ssl_get_early_data_status(mbedtls_ssl_context *ssl) switch (ssl->early_data_state) { case MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT: - return MBEDTLS_SSL_EARLY_DATA_STATUS_NO_IND_SENT; + return MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_INDICATED; break; case MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED: diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 6f022eb70a..bd5a7756e0 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -4125,7 +4125,7 @@ void tls13_cli_early_data_state(int scenario) break; case TEST_EARLY_DATA_NO_INDICATION_SENT: - TEST_EQUAL(ret, MBEDTLS_SSL_EARLY_DATA_STATUS_NO_IND_SENT); + TEST_EQUAL(ret, MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_INDICATED); break; case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */ From 0a271fde761d1692f250a56822a380b640326c30 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:34:02 +0000 Subject: [PATCH 116/211] Add key_destroyable parameter to mbedtls_test_psa_exercise_key This will allow us to use this smoke test to ensure that key slot content reads are only performed when we are registered to read a full slot. We will destroy the key on another thread while the key is being exercised, and fail the test if an unexpected error code is hit. Future commits will incrementally implement this new parameter. All current usages of this function have this parameter set to 0, in which case the new behaviour must be the same as the old behaviour Signed-off-by: Ryan Everett --- tests/include/test/psa_exercise_key.h | 18 ++++++++---- tests/src/psa_exercise_key.c | 29 +++++++++++-------- tests/suites/test_suite_pkparse.function | 2 +- tests/suites/test_suite_psa_crypto.function | 22 +++++++------- ...t_suite_psa_crypto_storage_format.function | 2 +- 5 files changed, 43 insertions(+), 30 deletions(-) diff --git a/tests/include/test/psa_exercise_key.h b/tests/include/test/psa_exercise_key.h index 44f5c08aa9..fa57d88727 100644 --- a/tests/include/test/psa_exercise_key.h +++ b/tests/include/test/psa_exercise_key.h @@ -209,18 +209,26 @@ int mbedtls_test_psa_exported_key_sanity_check( * ``` * if( ! exercise_key( ... ) ) goto exit; * ``` + * To use this function for multi-threaded tests where the key + * may be destroyed at any point: call this function with key_destroyable set + * to 1, while another thread calls psa_destroy_key on the same key; + * this will test whether destroying the key in use leads to any corruption. * - * \param key The key to exercise. It should be capable of performing - * \p alg. - * \param usage The usage flags to assume. - * \param alg The algorithm to exercise. + * \param key The key to exercise. It should be capable of performing + * \p alg. + * \param usage The usage flags to assume. + * \param alg The algorithm to exercise. + * \param key_destroyable If set to 1, a failure due to the key not existing + * or the key being destroyed mid-operation will only + * be reported if the error code is unexpected. * * \retval 0 The key failed the smoke tests. * \retval 1 The key passed the smoke tests. */ int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg); + psa_algorithm_t alg, + int key_destroyable); psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type, psa_algorithm_t alg); diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c index 7b81052c8c..e5cce79392 100644 --- a/tests/src/psa_exercise_key.c +++ b/tests/src/psa_exercise_key.c @@ -948,38 +948,43 @@ exit: int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg) + psa_algorithm_t alg, + int key_destroyable) { int ok = 0; - if (!check_key_attributes_sanity(key)) { + if (!check_key_attributes_sanity(key, key_destroyable)) { return 0; } if (alg == 0) { ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */ } else if (PSA_ALG_IS_MAC(alg)) { - ok = exercise_mac_key(key, usage, alg); + ok = exercise_mac_key(key, usage, alg, key_destroyable); } else if (PSA_ALG_IS_CIPHER(alg)) { - ok = exercise_cipher_key(key, usage, alg); + ok = exercise_cipher_key(key, usage, alg, key_destroyable); } else if (PSA_ALG_IS_AEAD(alg)) { - ok = exercise_aead_key(key, usage, alg); + ok = exercise_aead_key(key, usage, alg, key_destroyable); } else if (PSA_ALG_IS_SIGN(alg)) { - ok = exercise_signature_key(key, usage, alg); + ok = exercise_signature_key(key, usage, alg, key_destroyable); } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) { - ok = exercise_asymmetric_encryption_key(key, usage, alg); + ok = exercise_asymmetric_encryption_key(key, usage, alg, + key_destroyable); } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) { - ok = exercise_key_derivation_key(key, usage, alg); + ok = exercise_key_derivation_key(key, usage, alg, key_destroyable); } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) { - ok = exercise_raw_key_agreement_key(key, usage, alg); + ok = exercise_raw_key_agreement_key(key, usage, alg, key_destroyable); } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) { - ok = exercise_key_agreement_key(key, usage, alg); + ok = exercise_key_agreement_key(key, usage, alg, key_destroyable); } else { TEST_FAIL("No code to exercise this category of algorithm"); } - ok = ok && exercise_export_key(key, usage); - ok = ok && exercise_export_public_key(key); + ok = ok && exercise_export_key(key, + usage, + key_destroyable); + ok = ok && exercise_export_public_key(key, + key_destroyable); exit: return ok; diff --git a/tests/suites/test_suite_pkparse.function b/tests/suites/test_suite_pkparse.function index 7dc8413c85..a06fc30bc8 100644 --- a/tests/suites/test_suite_pkparse.function +++ b/tests/suites/test_suite_pkparse.function @@ -57,7 +57,7 @@ static int test_psa_bridge(const mbedtls_pk_context *ctx, if (mbedtls_test_can_exercise_psa_algorithm(exercise_alg)) { TEST_ASSERT(mbedtls_test_psa_exercise_key(psa_key, exercise_usage, - exercise_alg)); + exercise_alg, 0)); } mbedtls_test_set_step((unsigned long) -1); diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 114159799d..dfddbb94d8 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1379,7 +1379,7 @@ void *thread_generate_key(void *ctx) /* Do something with the key according * to its type and permitted usage. */ - if (!mbedtls_test_psa_exercise_key(key, gkc->usage, gkc->alg)) { + if (!mbedtls_test_psa_exercise_key(key, gkc->usage, gkc->alg, 0)) { psa_destroy_key(key); goto exit; } @@ -1715,7 +1715,7 @@ void import_export(data_t *data, * this doesn't directly validate the implementation, but it still helps * by cross-validating the test data with the sanity check code. */ if (!psa_key_lifetime_is_external(lifetime)) { - if (!mbedtls_test_psa_exercise_key(key, usage_arg, 0)) { + if (!mbedtls_test_psa_exercise_key(key, usage_arg, 0, 0)) { goto exit; } } @@ -1853,7 +1853,7 @@ void import_and_exercise_key(data_t *data, TEST_EQUAL(psa_get_key_bits(&got_attributes), bits); /* Do something with the key according to its type and permitted usage. */ - if (!mbedtls_test_psa_exercise_key(key, usage, alg)) { + if (!mbedtls_test_psa_exercise_key(key, usage, alg, 0)) { goto exit; } @@ -2529,10 +2529,10 @@ void key_policy_alg2(int key_type_arg, data_t *key_data, TEST_EQUAL(psa_get_key_algorithm(&got_attributes), alg); TEST_EQUAL(psa_get_key_enrollment_algorithm(&got_attributes), alg2); - if (!mbedtls_test_psa_exercise_key(key, usage, alg)) { + if (!mbedtls_test_psa_exercise_key(key, usage, alg, 0)) { goto exit; } - if (!mbedtls_test_psa_exercise_key(key, usage, alg2)) { + if (!mbedtls_test_psa_exercise_key(key, usage, alg2, 0)) { goto exit; } @@ -2663,10 +2663,10 @@ void copy_success(int source_usage_arg, } if (!psa_key_lifetime_is_external(target_lifetime)) { - if (!mbedtls_test_psa_exercise_key(target_key, expected_usage, expected_alg)) { + if (!mbedtls_test_psa_exercise_key(target_key, expected_usage, expected_alg, 0)) { goto exit; } - if (!mbedtls_test_psa_exercise_key(target_key, expected_usage, expected_alg2)) { + if (!mbedtls_test_psa_exercise_key(target_key, expected_usage, expected_alg2, 0)) { goto exit; } } @@ -9233,7 +9233,7 @@ void derive_key_exercise(int alg_arg, TEST_EQUAL(psa_get_key_bits(&got_attributes), derived_bits); /* Exercise the derived key. */ - if (!mbedtls_test_psa_exercise_key(derived_key, derived_usage, derived_alg)) { + if (!mbedtls_test_psa_exercise_key(derived_key, derived_usage, derived_alg, 0)) { goto exit; } @@ -9941,7 +9941,7 @@ void generate_key(int type_arg, TEST_EQUAL(psa_get_key_bits(&got_attributes), bits); /* Do something with the key according to its type and permitted usage. */ - if (!mbedtls_test_psa_exercise_key(key, usage, alg)) { + if (!mbedtls_test_psa_exercise_key(key, usage, alg, 0)) { goto exit; } @@ -10011,7 +10011,7 @@ void generate_key_ext(int type_arg, #endif /* Do something with the key according to its type and permitted usage. */ - if (!mbedtls_test_psa_exercise_key(key, usage, alg)) { + if (!mbedtls_test_psa_exercise_key(key, usage, alg, 0)) { goto exit; } @@ -10162,7 +10162,7 @@ void persistent_key_load_key_from_storage(data_t *data, } /* Do something with the key according to its type and permitted usage. */ - if (!mbedtls_test_psa_exercise_key(key, usage_flags, alg)) { + if (!mbedtls_test_psa_exercise_key(key, usage_flags, alg, 0)) { goto exit; } diff --git a/tests/suites/test_suite_psa_crypto_storage_format.function b/tests/suites/test_suite_psa_crypto_storage_format.function index bb1e2c68c3..efaaba58a3 100644 --- a/tests/suites/test_suite_psa_crypto_storage_format.function +++ b/tests/suites/test_suite_psa_crypto_storage_format.function @@ -187,7 +187,7 @@ static int test_read_key(const psa_key_attributes_t *expected_attributes, TEST_ASSERT(mbedtls_test_psa_exercise_key( key_id, psa_get_key_usage_flags(expected_attributes), - psa_get_key_algorithm(expected_attributes))); + psa_get_key_algorithm(expected_attributes), 0)); } From f08a93fbe599b85949940f9ac9366d842049197a Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:00:08 +0000 Subject: [PATCH 117/211] Add key_destroyable parameter to check_key_attributes_sanity This function is currently only used in the exercise_key smoke test. Signed-off-by: Ryan Everett --- tests/src/psa_exercise_key.c | 37 ++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c index e5cce79392..30f21da90e 100644 --- a/tests/src/psa_exercise_key.c +++ b/tests/src/psa_exercise_key.c @@ -38,7 +38,8 @@ static int lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime) } #endif -static int check_key_attributes_sanity(mbedtls_svc_key_id_t key) +static int check_key_attributes_sanity(mbedtls_svc_key_id_t key, + int key_destroyable) { int ok = 0; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; @@ -46,8 +47,13 @@ static int check_key_attributes_sanity(mbedtls_svc_key_id_t key) mbedtls_svc_key_id_t id; psa_key_type_t type; size_t bits; - - PSA_ASSERT(psa_get_key_attributes(key, &attributes)); + psa_status_t status = psa_get_key_attributes(key, &attributes); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + psa_reset_key_attributes(&attributes); + return 1; + } + PSA_ASSERT(status); lifetime = psa_get_key_lifetime(&attributes); id = psa_get_key_id(&attributes); type = psa_get_key_type(&attributes); @@ -66,17 +72,20 @@ static int check_key_attributes_sanity(mbedtls_svc_key_id_t key) (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <= PSA_KEY_ID_USER_MAX)); } #if defined(MBEDTLS_PSA_CRYPTO_SE_C) - /* randomly-generated 64-bit constant, should never appear in test data */ - psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21; - psa_status_t status = psa_get_key_slot_number(&attributes, &slot_number); - if (lifetime_is_dynamic_secure_element(lifetime)) { - /* Mbed TLS currently always exposes the slot number to - * applications. This is not mandated by the PSA specification - * and may change in future versions. */ - TEST_EQUAL(status, 0); - TEST_ASSERT(slot_number != 0xec94d4a5058a1a21); - } else { - TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT); + /* MBEDTLS_PSA_CRYPTO_SE_C does not support thread safety. */ + if (key_destroyable == 0) { + /* randomly-generated 64-bit constant, should never appear in test data */ + psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21; + status = psa_get_key_slot_number(&attributes, &slot_number); + if (lifetime_is_dynamic_secure_element(lifetime)) { + /* Mbed TLS currently always exposes the slot number to + * applications. This is not mandated by the PSA specification + * and may change in future versions. */ + TEST_EQUAL(status, 0); + TEST_ASSERT(slot_number != 0xec94d4a5058a1a21); + } else { + TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT); + } } #endif From 77635508845a57a73722409904d12d31b4f3da45 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:02:23 +0000 Subject: [PATCH 118/211] Add key_destroyable parameter to exercise_mac_key If the key has been destroyed (and the new parameter is 1) then we test that psa_mac_abort succeeds in this scenario. Signed-off-by: Ryan Everett --- tests/src/psa_exercise_key.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c index 30f21da90e..dc5b2bf007 100644 --- a/tests/src/psa_exercise_key.c +++ b/tests/src/psa_exercise_key.c @@ -119,20 +119,27 @@ exit: static int exercise_mac_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg) + psa_algorithm_t alg, + int key_destroyable) { psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; const unsigned char input[] = "foo"; unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 }; size_t mac_length = sizeof(mac); - + psa_status_t status = PSA_SUCCESS; /* Convert wildcard algorithm to exercisable algorithm */ if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) { alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg)); } if (usage & PSA_KEY_USAGE_SIGN_HASH) { - PSA_ASSERT(psa_mac_sign_setup(&operation, key, alg)); + status = psa_mac_sign_setup(&operation, key, alg); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + PSA_ASSERT(psa_mac_abort(&operation)); + return 1; + } + PSA_ASSERT(status); PSA_ASSERT(psa_mac_update(&operation, input, sizeof(input))); PSA_ASSERT(psa_mac_sign_finish(&operation, @@ -145,7 +152,13 @@ static int exercise_mac_key(mbedtls_svc_key_id_t key, (usage & PSA_KEY_USAGE_SIGN_HASH ? PSA_SUCCESS : PSA_ERROR_INVALID_SIGNATURE); - PSA_ASSERT(psa_mac_verify_setup(&operation, key, alg)); + status = psa_mac_verify_setup(&operation, key, alg); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + PSA_ASSERT(psa_mac_abort(&operation)); + return 1; + } + PSA_ASSERT(status); PSA_ASSERT(psa_mac_update(&operation, input, sizeof(input))); TEST_EQUAL(psa_mac_verify_finish(&operation, mac, mac_length), From 70691f3082a1bc6e96ca038439f15700cb389788 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:04:45 +0000 Subject: [PATCH 119/211] Add key_destroyable parameter to psa_exercise_cipher_key If the key has been destroyed (and the new parameter is 1), we test that psa_cipher_abort succeeds in this scenario. Signed-off-by: Ryan Everett --- tests/src/psa_exercise_key.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c index dc5b2bf007..ff0d1c0a63 100644 --- a/tests/src/psa_exercise_key.c +++ b/tests/src/psa_exercise_key.c @@ -174,7 +174,8 @@ exit: static int exercise_cipher_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg) + psa_algorithm_t alg, + int key_destroyable) { psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 }; @@ -186,13 +187,20 @@ static int exercise_cipher_key(mbedtls_svc_key_id_t key, size_t ciphertext_length = sizeof(ciphertext); unsigned char decrypted[sizeof(ciphertext)]; size_t part_length; + psa_status_t status = PSA_SUCCESS; PSA_ASSERT(psa_get_key_attributes(key, &attributes)); key_type = psa_get_key_type(&attributes); iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg); if (usage & PSA_KEY_USAGE_ENCRYPT) { - PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg)); + status = psa_cipher_encrypt_setup(&operation, key, alg); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + PSA_ASSERT(psa_cipher_abort(&operation)); + return 1; + } + PSA_ASSERT(status); if (iv_length != 0) { PSA_ASSERT(psa_cipher_generate_iv(&operation, iv, sizeof(iv), @@ -210,12 +218,17 @@ static int exercise_cipher_key(mbedtls_svc_key_id_t key, } if (usage & PSA_KEY_USAGE_DECRYPT) { - psa_status_t status; int maybe_invalid_padding = 0; if (!(usage & PSA_KEY_USAGE_ENCRYPT)) { maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg); } - PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg)); + status = psa_cipher_decrypt_setup(&operation, key, alg); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + PSA_ASSERT(psa_cipher_abort(&operation)); + return 1; + } + PSA_ASSERT(status); if (iv_length != 0) { PSA_ASSERT(psa_cipher_set_iv(&operation, iv, iv_length)); From fbe703de2a17e7e0a513f9074f55979794cb9fcd Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:09:25 +0000 Subject: [PATCH 120/211] Add key_destroyable parameter to exercise_aead_key Signed-off-by: Ryan Everett --- tests/src/psa_exercise_key.c | 39 +++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c index ff0d1c0a63..89434bfdcf 100644 --- a/tests/src/psa_exercise_key.c +++ b/tests/src/psa_exercise_key.c @@ -262,7 +262,8 @@ exit: static int exercise_aead_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg) + psa_algorithm_t alg, + int key_destroyable) { unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 }; size_t nonce_length; @@ -272,6 +273,7 @@ static int exercise_aead_key(mbedtls_svc_key_id_t key, unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)"; size_t ciphertext_length = sizeof(ciphertext); size_t plaintext_length = sizeof(ciphertext); + psa_status_t status = PSA_SUCCESS; /* Convert wildcard algorithm to exercisable algorithm */ if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) { @@ -283,12 +285,17 @@ static int exercise_aead_key(mbedtls_svc_key_id_t key, nonce_length = PSA_AEAD_NONCE_LENGTH(key_type, alg); if (usage & PSA_KEY_USAGE_ENCRYPT) { - PSA_ASSERT(psa_aead_encrypt(key, alg, - nonce, nonce_length, - NULL, 0, - plaintext, sizeof(plaintext), - ciphertext, sizeof(ciphertext), - &ciphertext_length)); + status = psa_aead_encrypt(key, alg, + nonce, nonce_length, + NULL, 0, + plaintext, sizeof(plaintext), + ciphertext, sizeof(ciphertext), + &ciphertext_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + PSA_ASSERT(status); } if (usage & PSA_KEY_USAGE_DECRYPT) { @@ -296,13 +303,17 @@ static int exercise_aead_key(mbedtls_svc_key_id_t key, (usage & PSA_KEY_USAGE_ENCRYPT ? PSA_SUCCESS : PSA_ERROR_INVALID_SIGNATURE); - TEST_EQUAL(psa_aead_decrypt(key, alg, - nonce, nonce_length, - NULL, 0, - ciphertext, ciphertext_length, - plaintext, sizeof(plaintext), - &plaintext_length), - verify_status); + status = psa_aead_decrypt(key, alg, + nonce, nonce_length, + NULL, 0, + ciphertext, ciphertext_length, + plaintext, sizeof(plaintext), + &plaintext_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + TEST_ASSERT(status == verify_status); } return 1; From 6edd40819e29b942885bc96eb63d6275738e1543 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:11:01 +0000 Subject: [PATCH 121/211] Add key_destroyable parameter to exercise_signature_key Signed-off-by: Ryan Everett --- tests/src/psa_exercise_key.c | 54 ++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c index 89434bfdcf..fde1187e70 100644 --- a/tests/src/psa_exercise_key.c +++ b/tests/src/psa_exercise_key.c @@ -337,7 +337,8 @@ static int can_sign_or_verify_message(psa_key_usage_t usage, static int exercise_signature_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg) + psa_algorithm_t alg, + int key_destroyable) { /* If the policy allows signing with any hash, just pick one. */ psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg); @@ -351,6 +352,7 @@ static int exercise_signature_key(mbedtls_svc_key_id_t key, TEST_FAIL("No hash algorithm for hash-and-sign testing"); #endif } + psa_status_t status = PSA_SUCCESS; if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) && PSA_ALG_IS_SIGN_HASH(alg)) { @@ -367,10 +369,15 @@ static int exercise_signature_key(mbedtls_svc_key_id_t key, } if (usage & PSA_KEY_USAGE_SIGN_HASH) { - PSA_ASSERT(psa_sign_hash(key, alg, - payload, payload_length, - signature, sizeof(signature), - &signature_length)); + status = psa_sign_hash(key, alg, + payload, payload_length, + signature, sizeof(signature), + &signature_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + PSA_ASSERT(status); } if (usage & PSA_KEY_USAGE_VERIFY_HASH) { @@ -378,10 +385,14 @@ static int exercise_signature_key(mbedtls_svc_key_id_t key, (usage & PSA_KEY_USAGE_SIGN_HASH ? PSA_SUCCESS : PSA_ERROR_INVALID_SIGNATURE); - TEST_EQUAL(psa_verify_hash(key, alg, - payload, payload_length, - signature, signature_length), - verify_status); + status = psa_verify_hash(key, alg, + payload, payload_length, + signature, signature_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + TEST_ASSERT(status == verify_status); } } @@ -392,10 +403,15 @@ static int exercise_signature_key(mbedtls_svc_key_id_t key, size_t signature_length = sizeof(signature); if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) { - PSA_ASSERT(psa_sign_message(key, alg, - message, message_length, - signature, sizeof(signature), - &signature_length)); + status = psa_sign_message(key, alg, + message, message_length, + signature, sizeof(signature), + &signature_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + PSA_ASSERT(status); } if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) { @@ -403,10 +419,14 @@ static int exercise_signature_key(mbedtls_svc_key_id_t key, (usage & PSA_KEY_USAGE_SIGN_MESSAGE ? PSA_SUCCESS : PSA_ERROR_INVALID_SIGNATURE); - TEST_EQUAL(psa_verify_message(key, alg, - message, message_length, - signature, signature_length), - verify_status); + status = psa_verify_message(key, alg, + message, message_length, + signature, signature_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + TEST_ASSERT(status == verify_status); } } From d48fc102d3d70094b52d1ab823859315b6befa3b Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:12:41 +0000 Subject: [PATCH 122/211] Add key_destroyable parameter to exercise_asymmetric_encryption_key Signed-off-by: Ryan Everett --- tests/src/psa_exercise_key.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c index fde1187e70..470073930c 100644 --- a/tests/src/psa_exercise_key.c +++ b/tests/src/psa_exercise_key.c @@ -438,7 +438,8 @@ exit: static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg) + psa_algorithm_t alg, + int key_destroyable) { unsigned char plaintext[PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE] = "Hello, world..."; @@ -446,22 +447,30 @@ static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key, "(wabblewebblewibblewobblewubble)"; size_t ciphertext_length = sizeof(ciphertext); size_t plaintext_length = 16; - + psa_status_t status = PSA_SUCCESS; if (usage & PSA_KEY_USAGE_ENCRYPT) { - PSA_ASSERT(psa_asymmetric_encrypt(key, alg, - plaintext, plaintext_length, - NULL, 0, - ciphertext, sizeof(ciphertext), - &ciphertext_length)); + status = psa_asymmetric_encrypt(key, alg, + plaintext, plaintext_length, + NULL, 0, + ciphertext, sizeof(ciphertext), + &ciphertext_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + PSA_ASSERT(status); } if (usage & PSA_KEY_USAGE_DECRYPT) { - psa_status_t status = - psa_asymmetric_decrypt(key, alg, - ciphertext, ciphertext_length, - NULL, 0, - plaintext, sizeof(plaintext), - &plaintext_length); + status = psa_asymmetric_decrypt(key, alg, + ciphertext, ciphertext_length, + NULL, 0, + plaintext, sizeof(plaintext), + &plaintext_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } TEST_ASSERT(status == PSA_SUCCESS || ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 && (status == PSA_ERROR_INVALID_ARGUMENT || From c1cc6686f084d647e42ec74304b7b1f8c82f06e1 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:17:43 +0000 Subject: [PATCH 123/211] Add key_destroyable parameter to key derivation smoke tests All current usages have this parameter set to 0 (in this case the behaviour of the test is unchanged) Signed-off-by: Ryan Everett --- tests/include/test/psa_exercise_key.h | 5 +- tests/src/psa_exercise_key.c | 77 +++++++++++++++------ tests/suites/test_suite_psa_crypto.function | 16 ++--- 3 files changed, 67 insertions(+), 31 deletions(-) diff --git a/tests/include/test/psa_exercise_key.h b/tests/include/test/psa_exercise_key.h index fa57d88727..713b093103 100644 --- a/tests/include/test/psa_exercise_key.h +++ b/tests/include/test/psa_exercise_key.h @@ -123,6 +123,9 @@ * \param input2 The first input to pass. * \param input2_length The length of \p input2 in bytes. * \param capacity The capacity to set. + * \param key_destroyable If set to 1, a failure due to the key not existing + * or the key being destroyed mid-operation will only + * be reported if the error code is unexpected. * * \return \c 1 on success, \c 0 on failure. */ @@ -132,7 +135,7 @@ int mbedtls_test_psa_setup_key_derivation_wrap( psa_algorithm_t alg, const unsigned char *input1, size_t input1_length, const unsigned char *input2, size_t input2_length, - size_t capacity); + size_t capacity, int key_destroyable); /** Perform a key agreement using the given key pair against its public key * using psa_raw_key_agreement(). diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c index 470073930c..7260f1a4d0 100644 --- a/tests/src/psa_exercise_key.c +++ b/tests/src/psa_exercise_key.c @@ -489,16 +489,22 @@ int mbedtls_test_psa_setup_key_derivation_wrap( psa_algorithm_t alg, const unsigned char *input1, size_t input1_length, const unsigned char *input2, size_t input2_length, - size_t capacity) + size_t capacity, int key_destroyable) { PSA_ASSERT(psa_key_derivation_setup(operation, alg)); + psa_status_t status = PSA_SUCCESS; if (PSA_ALG_IS_HKDF(alg)) { PSA_ASSERT(psa_key_derivation_input_bytes(operation, PSA_KEY_DERIVATION_INPUT_SALT, input1, input1_length)); - PSA_ASSERT(psa_key_derivation_input_key(operation, - PSA_KEY_DERIVATION_INPUT_SECRET, - key)); + status = psa_key_derivation_input_key(operation, + PSA_KEY_DERIVATION_INPUT_SECRET, + key); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + PSA_ASSERT(status); PSA_ASSERT(psa_key_derivation_input_bytes(operation, PSA_KEY_DERIVATION_INPUT_INFO, input2, @@ -507,13 +513,23 @@ int mbedtls_test_psa_setup_key_derivation_wrap( PSA_ASSERT(psa_key_derivation_input_bytes(operation, PSA_KEY_DERIVATION_INPUT_SALT, input1, input1_length)); - PSA_ASSERT(psa_key_derivation_input_key(operation, - PSA_KEY_DERIVATION_INPUT_SECRET, - key)); + status = psa_key_derivation_input_key(operation, + PSA_KEY_DERIVATION_INPUT_SECRET, + key); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + PSA_ASSERT(status); } else if (PSA_ALG_IS_HKDF_EXPAND(alg)) { - PSA_ASSERT(psa_key_derivation_input_key(operation, - PSA_KEY_DERIVATION_INPUT_SECRET, - key)); + status = psa_key_derivation_input_key(operation, + PSA_KEY_DERIVATION_INPUT_SECRET, + key); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + PSA_ASSERT(status); PSA_ASSERT(psa_key_derivation_input_bytes(operation, PSA_KEY_DERIVATION_INPUT_INFO, input2, @@ -523,9 +539,14 @@ int mbedtls_test_psa_setup_key_derivation_wrap( PSA_ASSERT(psa_key_derivation_input_bytes(operation, PSA_KEY_DERIVATION_INPUT_SEED, input1, input1_length)); - PSA_ASSERT(psa_key_derivation_input_key(operation, - PSA_KEY_DERIVATION_INPUT_SECRET, - key)); + status = psa_key_derivation_input_key(operation, + PSA_KEY_DERIVATION_INPUT_SECRET, + key); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + PSA_ASSERT(status); PSA_ASSERT(psa_key_derivation_input_bytes(operation, PSA_KEY_DERIVATION_INPUT_LABEL, input2, input2_length)); @@ -537,9 +558,14 @@ int mbedtls_test_psa_setup_key_derivation_wrap( PSA_KEY_DERIVATION_INPUT_SALT, input2, input2_length)); - PSA_ASSERT(psa_key_derivation_input_key(operation, - PSA_KEY_DERIVATION_INPUT_PASSWORD, - key)); + status = psa_key_derivation_input_key(operation, + PSA_KEY_DERIVATION_INPUT_PASSWORD, + key); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + return 1; + } + PSA_ASSERT(status); } else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) { PSA_ASSERT(psa_key_derivation_input_bytes(operation, PSA_KEY_DERIVATION_INPUT_SECRET, @@ -561,7 +587,8 @@ exit: static int exercise_key_derivation_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg) + psa_algorithm_t alg, + int key_destroyable) { psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT; unsigned char input1[] = "Input 1"; @@ -575,14 +602,20 @@ static int exercise_key_derivation_key(mbedtls_svc_key_id_t key, if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg, input1, input1_length, input2, input2_length, - capacity)) { + capacity, key_destroyable)) { goto exit; } - PSA_ASSERT(psa_key_derivation_output_bytes(&operation, - output, - capacity)); - PSA_ASSERT(psa_key_derivation_abort(&operation)); + psa_status_t status = psa_key_derivation_output_bytes(&operation, + output, + capacity); + if (key_destroyable && status == PSA_ERROR_BAD_STATE) { + /* The key has been destroyed. */ + PSA_ASSERT(psa_key_derivation_abort(&operation)); + } else { + PSA_ASSERT(status); + PSA_ASSERT(psa_key_derivation_abort(&operation)); + } } return 1; diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index dfddbb94d8..7ef8618ef0 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -8780,7 +8780,7 @@ void derive_over_capacity(int alg_arg) if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg, input1, input1_length, input2, input2_length, - capacity)) { + capacity, 0)) { goto exit; } @@ -9099,7 +9099,7 @@ void derive_full(int alg_arg, if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg, input1->x, input1->len, input2->x, input2->len, - requested_capacity)) { + requested_capacity, 0)) { goto exit; } @@ -9216,7 +9216,7 @@ void derive_key_exercise(int alg_arg, if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, base_key, alg, input1->x, input1->len, input2->x, input2->len, - capacity)) { + capacity, 0)) { goto exit; } @@ -9286,7 +9286,7 @@ void derive_key_export(int alg_arg, if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, base_key, alg, input1->x, input1->len, input2->x, input2->len, - capacity)) { + capacity, 0)) { goto exit; } @@ -9299,7 +9299,7 @@ void derive_key_export(int alg_arg, if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, base_key, alg, input1->x, input1->len, input2->x, input2->len, - capacity)) { + capacity, 0)) { goto exit; } @@ -9370,7 +9370,7 @@ void derive_key_type(int alg_arg, &operation, base_key, alg, input1->x, input1->len, input2->x, input2->len, - PSA_KEY_DERIVATION_UNLIMITED_CAPACITY) == 0) { + PSA_KEY_DERIVATION_UNLIMITED_CAPACITY, 0) == 0) { goto exit; } @@ -9435,7 +9435,7 @@ void derive_key_ext(int alg_arg, &operation, base_key, alg, input1->x, input1->len, input2->x, input2->len, - PSA_KEY_DERIVATION_UNLIMITED_CAPACITY) == 0) { + PSA_KEY_DERIVATION_UNLIMITED_CAPACITY, 0) == 0) { goto exit; } @@ -9499,7 +9499,7 @@ void derive_key(int alg_arg, if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, base_key, alg, input1->x, input1->len, input2->x, input2->len, - SIZE_MAX)) { + SIZE_MAX, 0)) { goto exit; } From 8163028fbdd59898cefaa4201c1e06972d91f9dc Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:21:12 +0000 Subject: [PATCH 124/211] Add key_destroyable parameter to raw key agreement smoke tests All current usages have this parameter set to 0 (meaning the behaviour of these tests hasn't changed). We also now return the actual error code, not GENERIC_ERROR Signed-off-by: Ryan Everett --- tests/include/test/psa_exercise_key.h | 5 ++- tests/src/psa_exercise_key.c | 38 +++++++++++++++------ tests/suites/test_suite_psa_crypto.function | 2 +- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/tests/include/test/psa_exercise_key.h b/tests/include/test/psa_exercise_key.h index 713b093103..23349166a7 100644 --- a/tests/include/test/psa_exercise_key.h +++ b/tests/include/test/psa_exercise_key.h @@ -146,12 +146,15 @@ int mbedtls_test_psa_setup_key_derivation_wrap( * * \param alg A key agreement algorithm compatible with \p key. * \param key A key that allows key agreement with \p alg. + * \param key_destroyable If set to 1, a failure due to the key not existing + * or the key being destroyed mid-operation will only + * be reported if the error code is unexpected. * * \return \c 1 on success, \c 0 on failure. */ psa_status_t mbedtls_test_psa_raw_key_agreement_with_self( psa_algorithm_t alg, - mbedtls_svc_key_id_t key); + mbedtls_svc_key_id_t key, int key_destroyable); /** Perform a key agreement using the given key pair against its public key * using psa_key_derivation_raw_key(). diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c index 7260f1a4d0..b62a34b5d7 100644 --- a/tests/src/psa_exercise_key.c +++ b/tests/src/psa_exercise_key.c @@ -668,7 +668,8 @@ exit: * private key against its own public key. */ psa_status_t mbedtls_test_psa_raw_key_agreement_with_self( psa_algorithm_t alg, - mbedtls_svc_key_id_t key) + mbedtls_svc_key_id_t key, + int key_destroyable) { psa_key_type_t private_key_type; psa_key_type_t public_key_type; @@ -677,25 +678,38 @@ psa_status_t mbedtls_test_psa_raw_key_agreement_with_self( size_t public_key_length; uint8_t output[1024]; size_t output_length; - /* Return GENERIC_ERROR if something other than the final call to - * psa_key_derivation_key_agreement fails. This isn't fully satisfactory, - * but it's good enough: callers will report it as a failed test anyway. */ - psa_status_t status = PSA_ERROR_GENERIC_ERROR; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - PSA_ASSERT(psa_get_key_attributes(key, &attributes)); + psa_status_t status = psa_get_key_attributes(key, &attributes); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + psa_reset_key_attributes(&attributes); + return PSA_SUCCESS; + } + PSA_ASSERT(status); + private_key_type = psa_get_key_type(&attributes); key_bits = psa_get_key_bits(&attributes); public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type); public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits); TEST_CALLOC(public_key, public_key_length); - PSA_ASSERT(psa_export_public_key(key, - public_key, public_key_length, - &public_key_length)); + status = psa_export_public_key(key, + public_key, public_key_length, + &public_key_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + status = PSA_SUCCESS; + goto exit; + } status = psa_raw_key_agreement(alg, key, public_key, public_key_length, output, sizeof(output), &output_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + status = PSA_SUCCESS; + goto exit; + } if (status == PSA_SUCCESS) { TEST_ASSERT(output_length <= PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type, @@ -717,14 +731,16 @@ exit: static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg) + psa_algorithm_t alg, + int key_destroyable) { int ok = 0; if (usage & PSA_KEY_USAGE_DERIVE) { /* We need two keys to exercise key agreement. Exercise the * private key against its own public key. */ - PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key)); + PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key, + key_destroyable)); } ok = 1; diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 7ef8618ef0..9390958378 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -2572,7 +2572,7 @@ void raw_agreement_key_policy(int policy_usage, PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, &key)); - status = mbedtls_test_psa_raw_key_agreement_with_self(exercise_alg, key); + status = mbedtls_test_psa_raw_key_agreement_with_self(exercise_alg, key, 0); TEST_EQUAL(status, expected_status); From e29b4b42b77f46788fbd89235dc19157da1f5266 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 13 Mar 2024 09:33:03 +0100 Subject: [PATCH 125/211] Fix copypasta Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 77d75b36f6..bbb7da2470 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -802,7 +802,7 @@ A future extension of the PSA API will support other import formats. Until those You can use the PK module as an intermediate step to create an RSA or ECC key for use with PSA. This is useful for use cases that the PSA API does not currently cover, such as: * Parsing a key in a format with metadata without knowing its type ahead of time. -* Parsing a key in a format that the PK module supports, but`psa_import_key` doesn't. +* Parsing a key in a format that the PK module supports, but `psa_import_key` doesn't. * Importing a key which you have in the form of a list of numbers, rather than the binary encoding required by `psa_import_key`. * Importing a key with less information than what the PSA API needs, for example an ECC public key in a compressed format, an RSA private key without the private exponent, or an RSA private key without the CRT parameters. @@ -909,7 +909,7 @@ A future extension of the PSA API will support other export formats. Until those This section discusses how to use a PSA key in a context that requires a PK object, such as PK formatting functions (`mbedtls_pk_write_key_der`, `mbedtls_pk_write_pubkey_der`, `mbedtls_pk_write_pubkey_pem`, `mbedtls_pk_write_key_pem` or `mbedtls_pk_write_pubkey`), Mbed TLS X.509 functions, Mbed TLS SSL functions, or another API that involves `mbedtls_pk_context` objects. The PSA key must be an RSA or ECC key since the PK module does not support DH keys. Three functions from `pk.h` help with that: * [`mbedtls_pk_copy_from_psa`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1ab8e88836fd9ee344ffe630c40447bd08) copies a PSA key into a PK object. The PSA key must be exportable. The PK object remains valid even if the PSA key is destroyed. -* [`mbedtls_pk_copy_public_from_psa`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a2a50247a528889c12ea0ddddb8b15a4e) copies a PSA key into a PK object. The PSA key must be exportable. The PK object remains valid even if the PSA key is destroyed. +* [`mbedtls_pk_copy_public_from_psa`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a2a50247a528889c12ea0ddddb8b15a4e) copies the public part of a PSA key into a PK object. The PK object remains valid even if the PSA key is destroyed. * [`mbedtls_pk_setup_opaque`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a4c04ac22ab9c1ae09cc29438c308bf05) sets up a PK object that wraps the PSA key. This functionality is only available when `MBEDTLS_USE_PSA_CRYPTO` is enabled. The PK object has the type `MBEDTLS_PK_OPAQUE` regardless of whether the key is an RSA or ECC key. The PK object can only be used as permitted by the PSA key's policy. The PK object contains a reference to the PSA key identifier, therefore PSA key must not be destroyed as long as the PK object remains alive. Here is some sample code illustrating how to use the PK module to format a PSA public key or the public key of a PSA key pair. From c4c1d3af3401c890a69a623b8e4749a501a886ad Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 12 Mar 2024 13:09:23 +0100 Subject: [PATCH 126/211] pk: use CRYPTO_CLIENT as guard for PK-PSA bridge functions instead of CRYPTO_C Signed-off-by: Valerio Setti --- include/mbedtls/pk.h | 146 ++++++++++++----------- library/pk.c | 272 ++++++++++++++++++++++--------------------- 2 files changed, 210 insertions(+), 208 deletions(-) diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h index d2e8674b21..fde302f872 100644 --- a/include/mbedtls/pk.h +++ b/include/mbedtls/pk.h @@ -390,77 +390,6 @@ int mbedtls_pk_setup_opaque(mbedtls_pk_context *ctx, const mbedtls_svc_key_id_t key); #endif /* MBEDTLS_USE_PSA_CRYPTO */ -#if defined(MBEDTLS_PSA_CRYPTO_C) -/** - * \brief Create a PK context starting from a key stored in PSA. - * This key: - * - must be exportable and - * - must be an RSA or EC key pair or public key (FFDH is not supported in PK). - * - * The resulting PK object will be a transparent type: - * - #MBEDTLS_PK_RSA for RSA keys or - * - #MBEDTLS_PK_ECKEY for EC keys. - * - * Once this functions returns the PK object will be completely - * independent from the original PSA key that it was generated - * from. - * Calling mbedtls_pk_sign(), mbedtls_pk_verify(), - * mbedtls_pk_encrypt(), mbedtls_pk_decrypt() on the resulting - * PK context will perform the corresponding algorithm for that - * PK context type. - * * For ECDSA, the choice of deterministic vs randomized will - * be based on the compile-time setting #MBEDTLS_ECDSA_DETERMINISTIC. - * * For an RSA key, the output PK context will allow both - * encrypt/decrypt and sign/verify regardless of the original - * key's policy. - * The original key's policy determines the output key's padding - * mode: PCKS1 v2.1 is set if the PSA key policy is OAEP or PSS, - * otherwise PKCS1 v1.5 is set. - * - * \param key_id The key identifier of the key stored in PSA. - * \param pk The PK context that will be filled. It must be initialized, - * but not set up. - * - * \return 0 on success. - * \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA in case the provided input - * parameters are not correct. - */ -int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk); - -/** - * \brief Create a PK context for the public key of a PSA key. - * - * The key must be an RSA or ECC key. It can be either a - * public key or a key pair, and only the public key is copied. - * The resulting PK object will be a transparent type: - * - #MBEDTLS_PK_RSA for RSA keys or - * - #MBEDTLS_PK_ECKEY for EC keys. - * - * Once this functions returns the PK object will be completely - * independent from the original PSA key that it was generated - * from. - * Calling mbedtls_pk_verify() or - * mbedtls_pk_encrypt() on the resulting - * PK context will perform the corresponding algorithm for that - * PK context type. - * - * For an RSA key, the output PK context will allow both - * encrypt and verify regardless of the original key's policy. - * The original key's policy determines the output key's padding - * mode: PCKS1 v2.1 is set if the PSA key policy is OAEP or PSS, - * otherwise PKCS1 v1.5 is set. - * - * \param key_id The key identifier of the key stored in PSA. - * \param pk The PK context that will be filled. It must be initialized, - * but not set up. - * - * \return 0 on success. - * \return MBEDTLS_ERR_PK_BAD_INPUT_DATA in case the provided input - * parameters are not correct. - */ -int mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk); -#endif /* MBEDTLS_PSA_CRYPTO_C */ - #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) /** * \brief Initialize an RSA-alt context @@ -529,7 +458,7 @@ int mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type); * PSA_ALG_RSA_PKCS1V15_CRYPT, * PSA_ALG_ECDSA(hash), * PSA_ALG_ECDH, where hash is a specific hash. - * \param usage PSA usage flag to check against, must be composed of: + * \param usage PSA usage flag to check against, must be composed of: * PSA_KEY_USAGE_SIGN_HASH * PSA_KEY_USAGE_DECRYPT * PSA_KEY_USAGE_DERIVE. @@ -550,7 +479,7 @@ int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg, psa_key_usage_t usage); #endif /* MBEDTLS_USE_PSA_CRYPTO */ -#if defined(MBEDTLS_PSA_CRYPTO_C) +#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) /** * \brief Determine valid PSA attributes that can be used to * import a key into PSA. @@ -710,7 +639,76 @@ int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk, int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk, const psa_key_attributes_t *attributes, mbedtls_svc_key_id_t *key_id); -#endif /* MBEDTLS_PSA_CRYPTO_C */ + +/** + * \brief Create a PK context starting from a key stored in PSA. + * This key: + * - must be exportable and + * - must be an RSA or EC key pair or public key (FFDH is not supported in PK). + * + * The resulting PK object will be a transparent type: + * - #MBEDTLS_PK_RSA for RSA keys or + * - #MBEDTLS_PK_ECKEY for EC keys. + * + * Once this functions returns the PK object will be completely + * independent from the original PSA key that it was generated + * from. + * Calling mbedtls_pk_sign(), mbedtls_pk_verify(), + * mbedtls_pk_encrypt(), mbedtls_pk_decrypt() on the resulting + * PK context will perform the corresponding algorithm for that + * PK context type. + * * For ECDSA, the choice of deterministic vs randomized will + * be based on the compile-time setting #MBEDTLS_ECDSA_DETERMINISTIC. + * * For an RSA key, the output PK context will allow both + * encrypt/decrypt and sign/verify regardless of the original + * key's policy. + * The original key's policy determines the output key's padding + * mode: PCKS1 v2.1 is set if the PSA key policy is OAEP or PSS, + * otherwise PKCS1 v1.5 is set. + * + * \param key_id The key identifier of the key stored in PSA. + * \param pk The PK context that will be filled. It must be initialized, + * but not set up. + * + * \return 0 on success. + * \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA in case the provided input + * parameters are not correct. + */ +int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk); + +/** + * \brief Create a PK context for the public key of a PSA key. + * + * The key must be an RSA or ECC key. It can be either a + * public key or a key pair, and only the public key is copied. + * The resulting PK object will be a transparent type: + * - #MBEDTLS_PK_RSA for RSA keys or + * - #MBEDTLS_PK_ECKEY for EC keys. + * + * Once this functions returns the PK object will be completely + * independent from the original PSA key that it was generated + * from. + * Calling mbedtls_pk_verify() or + * mbedtls_pk_encrypt() on the resulting + * PK context will perform the corresponding algorithm for that + * PK context type. + * + * For an RSA key, the output PK context will allow both + * encrypt and verify regardless of the original key's policy. + * The original key's policy determines the output key's padding + * mode: PCKS1 v2.1 is set if the PSA key policy is OAEP or PSS, + * otherwise PKCS1 v1.5 is set. + * + * \param key_id The key identifier of the key stored in PSA. + * \param pk The PK context that will be filled. It must be initialized, + * but not set up. + * + * \return 0 on success. + * \return MBEDTLS_ERR_PK_BAD_INPUT_DATA in case the provided input + * parameters are not correct. + */ +int mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_t key_id, mbedtls_pk_context *pk); +#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ /** * \brief Verify signature (including padding if relevant). diff --git a/library/pk.c b/library/pk.c index 1d85c9217f..ccc2eac6d0 100644 --- a/library/pk.c +++ b/library/pk.c @@ -380,7 +380,7 @@ int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg, } #endif /* MBEDTLS_USE_PSA_CRYPTO */ -#if defined(MBEDTLS_PSA_CRYPTO_C) +#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) #if defined(MBEDTLS_RSA_C) static psa_algorithm_t psa_algorithm_for_rsa(const mbedtls_rsa_context *rsa, int want_crypt) @@ -577,7 +577,14 @@ int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk, } psa_set_key_usage_flags(attributes, more_usage); + /* Key's enrollment is available only when an Mbed TLS implementation of PSA + * Crypto is being used, i.e. when MBEDTLS_PSA_CRYPTO_C is defined. + * Even though we don't officially support using other implementations of PSA + * Crypto with TLS and X.509 (yet), we try to keep vendor's customizations + * separated. */ +#if defined(MBEDTLS_PSA_CRYPTO_C) psa_set_key_enrollment_algorithm(attributes, PSA_ALG_NONE); +#endif return 0; } @@ -854,7 +861,136 @@ int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk, return import_pair_into_psa(pk, attributes, key_id); } } -#endif /* MBEDTLS_PSA_CRYPTO_C */ + +static int copy_from_psa(mbedtls_svc_key_id_t key_id, + mbedtls_pk_context *pk, + int public_only) +{ + psa_status_t status; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; + psa_key_type_t key_type; + psa_algorithm_t alg_type; + size_t key_bits; + /* Use a buffer size large enough to contain either a key pair or public key. */ + unsigned char exp_key[PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE]; + size_t exp_key_len; + int ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; + + if (pk == NULL) { + return MBEDTLS_ERR_PK_BAD_INPUT_DATA; + } + + status = psa_get_key_attributes(key_id, &key_attr); + if (status != PSA_SUCCESS) { + return MBEDTLS_ERR_PK_BAD_INPUT_DATA; + } + + if (public_only) { + status = psa_export_public_key(key_id, exp_key, sizeof(exp_key), &exp_key_len); + } else { + status = psa_export_key(key_id, exp_key, sizeof(exp_key), &exp_key_len); + } + if (status != PSA_SUCCESS) { + ret = PSA_PK_TO_MBEDTLS_ERR(status); + goto exit; + } + + key_type = psa_get_key_type(&key_attr); + if (public_only) { + key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type); + } + key_bits = psa_get_key_bits(&key_attr); + alg_type = psa_get_key_algorithm(&key_attr); + +#if defined(MBEDTLS_RSA_C) + if ((key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) || + (key_type == PSA_KEY_TYPE_RSA_PUBLIC_KEY)) { + + ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)); + if (ret != 0) { + goto exit; + } + + if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) { + ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), exp_key, exp_key_len); + } else { + ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*pk), exp_key, exp_key_len); + } + if (ret != 0) { + goto exit; + } + + mbedtls_md_type_t md_type = MBEDTLS_MD_NONE; + if (PSA_ALG_GET_HASH(alg_type) != PSA_ALG_ANY_HASH) { + md_type = mbedtls_md_type_from_psa_alg(alg_type); + } + + if (PSA_ALG_IS_RSA_OAEP(alg_type) || PSA_ALG_IS_RSA_PSS(alg_type)) { + ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V21, md_type); + } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg_type) || + alg_type == PSA_ALG_RSA_PKCS1V15_CRYPT) { + ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V15, md_type); + } + if (ret != 0) { + goto exit; + } + } else +#endif /* MBEDTLS_RSA_C */ +#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) + if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) || + PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type)) { + mbedtls_ecp_group_id grp_id; + + ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); + if (ret != 0) { + goto exit; + } + + grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(key_type), key_bits); + ret = mbedtls_pk_ecc_set_group(pk, grp_id); + if (ret != 0) { + goto exit; + } + + if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type)) { + ret = mbedtls_pk_ecc_set_key(pk, exp_key, exp_key_len); + if (ret != 0) { + goto exit; + } + ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, exp_key, exp_key_len, + mbedtls_psa_get_random, + MBEDTLS_PSA_RANDOM_STATE); + } else { + ret = mbedtls_pk_ecc_set_pubkey(pk, exp_key, exp_key_len); + } + if (ret != 0) { + goto exit; + } + } else +#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ + { + return MBEDTLS_ERR_PK_BAD_INPUT_DATA; + } + +exit: + psa_reset_key_attributes(&key_attr); + mbedtls_platform_zeroize(exp_key, sizeof(exp_key)); + + return ret; +} + +int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, + mbedtls_pk_context *pk) +{ + return copy_from_psa(key_id, pk, 0); +} + +int mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_t key_id, + mbedtls_pk_context *pk) +{ + return copy_from_psa(key_id, pk, 1); +} +#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ /* * Helper for mbedtls_pk_sign and mbedtls_pk_verify @@ -1378,136 +1514,4 @@ mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx) return ctx->pk_info->type; } -#if defined(MBEDTLS_PSA_CRYPTO_C) -static int copy_from_psa(mbedtls_svc_key_id_t key_id, - mbedtls_pk_context *pk, - int public_only) -{ - psa_status_t status; - psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; - psa_key_type_t key_type; - psa_algorithm_t alg_type; - size_t key_bits; - /* Use a buffer size large enough to contain either a key pair or public key. */ - unsigned char exp_key[PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE]; - size_t exp_key_len; - int ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA; - - if (pk == NULL) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - status = psa_get_key_attributes(key_id, &key_attr); - if (status != PSA_SUCCESS) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - - if (public_only) { - status = psa_export_public_key(key_id, exp_key, sizeof(exp_key), &exp_key_len); - } else { - status = psa_export_key(key_id, exp_key, sizeof(exp_key), &exp_key_len); - } - if (status != PSA_SUCCESS) { - ret = PSA_PK_TO_MBEDTLS_ERR(status); - goto exit; - } - - key_type = psa_get_key_type(&key_attr); - if (public_only) { - key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type); - } - key_bits = psa_get_key_bits(&key_attr); - alg_type = psa_get_key_algorithm(&key_attr); - -#if defined(MBEDTLS_RSA_C) - if ((key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) || - (key_type == PSA_KEY_TYPE_RSA_PUBLIC_KEY)) { - - ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)); - if (ret != 0) { - goto exit; - } - - if (key_type == PSA_KEY_TYPE_RSA_KEY_PAIR) { - ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), exp_key, exp_key_len); - } else { - ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*pk), exp_key, exp_key_len); - } - if (ret != 0) { - goto exit; - } - - mbedtls_md_type_t md_type = MBEDTLS_MD_NONE; - if (PSA_ALG_GET_HASH(alg_type) != PSA_ALG_ANY_HASH) { - md_type = mbedtls_md_type_from_psa_alg(alg_type); - } - - if (PSA_ALG_IS_RSA_OAEP(alg_type) || PSA_ALG_IS_RSA_PSS(alg_type)) { - ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V21, md_type); - } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg_type) || - alg_type == PSA_ALG_RSA_PKCS1V15_CRYPT) { - ret = mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk), MBEDTLS_RSA_PKCS_V15, md_type); - } - if (ret != 0) { - goto exit; - } - } else -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) || - PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type)) { - mbedtls_ecp_group_id grp_id; - - ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); - if (ret != 0) { - goto exit; - } - - grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(key_type), key_bits); - ret = mbedtls_pk_ecc_set_group(pk, grp_id); - if (ret != 0) { - goto exit; - } - - if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type)) { - ret = mbedtls_pk_ecc_set_key(pk, exp_key, exp_key_len); - if (ret != 0) { - goto exit; - } - ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, exp_key, exp_key_len, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE); - } else { - ret = mbedtls_pk_ecc_set_pubkey(pk, exp_key, exp_key_len); - } - if (ret != 0) { - goto exit; - } - } else -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - -exit: - psa_reset_key_attributes(&key_attr); - mbedtls_platform_zeroize(exp_key, sizeof(exp_key)); - - return ret; -} - - -int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, - mbedtls_pk_context *pk) -{ - return copy_from_psa(key_id, pk, 0); -} - -int mbedtls_pk_copy_public_from_psa(mbedtls_svc_key_id_t key_id, - mbedtls_pk_context *pk) -{ - return copy_from_psa(key_id, pk, 1); -} -#endif /* MBEDTLS_PSA_CRYPTO_C */ - #endif /* MBEDTLS_PK_C */ From 63097759f84ec831e7001b50303a5e4299b7893b Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 12 Mar 2024 13:18:13 +0100 Subject: [PATCH 127/211] all.sh: modify/add test components for CRYPTO_CLIENT The already existing component_test_psa_crypto_client() is renamed as component_test_default_psa_crypto_client_without_crypto_provider() while component_build_full_psa_crypto_client_without_crypto_provider() was added. - Both of them check that the missing symbols at link time (if any) belong to the psa_xxx() family. - The former builds with default config + CRYPTO_CLIENT - CRYPTO_C and then runs test suites. - The latter only perform the builds using the full config and then it checks that PK-PSA bridge functions are present. Signed-off-by: Valerio Setti --- tests/scripts/all.sh | 56 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 467ff8e7cf..b445ecf8cc 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -1285,19 +1285,67 @@ component_build_psa_crypto_spm () { check_renamed_symbols tests/include/spe/crypto_spe.h library/libmbedcrypto.a } -component_test_psa_crypto_client () { - msg "build: default config - PSA_CRYPTO_C + PSA_CRYPTO_CLIENT, make" +# Get a list of library-wise undefined symbols and ensure that they only +# belong to psa_xxx() functions and not to mbedtls_yyy() ones. +# This function is a common helper used by both: +# - component_test_default_psa_crypto_client_without_crypto_provider +# - component_build_full_psa_crypto_client_without_crypto_provider. +common_check_mbedtls_missing_symbols() { + nm library/libmbedcrypto.a | grep ' [TRrDC] ' | grep -Eo '(mbedtls_|psa_).*' | sort -u > sym_def.txt + nm library/libmbedcrypto.a | grep ' U ' | grep -Eo '(mbedtls_|psa_).*' | sort -u > sym_undef.txt + comm sym_def.txt sym_undef.txt -13 > linking_errors.txt + not grep mbedtls_ linking_errors.txt + + rm sym_def.txt sym_undef.txt linking_errors.txt +} + +component_test_default_psa_crypto_client_without_crypto_provider () { + msg "build: default config - PSA_CRYPTO_C + PSA_CRYPTO_CLIENT" + scripts/config.py unset MBEDTLS_PSA_CRYPTO_C scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C + scripts/config.py unset MBEDTLS_PSA_ITS_FILE_C scripts/config.py set MBEDTLS_PSA_CRYPTO_CLIENT scripts/config.py unset MBEDTLS_LMS_C - scripts/config.py unset MBEDTLS_LMS_PRIVATE + make - msg "test: default config - PSA_CRYPTO_C + PSA_CRYPTO_CLIENT, make" + msg "check missing symbols: default config - PSA_CRYPTO_C + PSA_CRYPTO_CLIENT" + common_check_mbedtls_missing_symbols + + msg "test: default config - PSA_CRYPTO_C + PSA_CRYPTO_CLIENT" make test } +component_build_full_psa_crypto_client_without_crypto_provider () { + msg "build: full config - PSA_CRYPTO_C" + + # Use full config which includes USE_PSA and CRYPTO_CLIENT. + scripts/config.py full + + scripts/config.py unset MBEDTLS_PSA_CRYPTO_C + scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C + # Dynamic secure element support is a deprecated feature and it is not + # available when CRYPTO_C and PSA_CRYPTO_STORAGE_C are disabled. + scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C + + # Since there is no crypto provider in this build it is not possible to + # build all the test executables and progrems due to missing PSA functions + # at link time. Therefore we will just build libraries and we'll check + # that symbols of interest are there. + make lib + + msg "check missing symbols: full config - PSA_CRYPTO_C" + + common_check_mbedtls_missing_symbols + + # Ensure that desired functions are included into the build (extend the + # following list as required). + grep mbedtls_pk_get_psa_attributes library/libmbedcrypto.a + grep mbedtls_pk_import_into_psa library/libmbedcrypto.a + grep mbedtls_pk_copy_from_psa library/libmbedcrypto.a +} + component_test_psa_crypto_rsa_no_genprime() { msg "build: default config minus MBEDTLS_GENPRIME" scripts/config.py unset MBEDTLS_GENPRIME From 13beaa2e606a00c9f8f463d5292ed3f444dd996b Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 12 Mar 2024 13:30:29 +0100 Subject: [PATCH 128/211] psa_crypto_stubs: extend stub functions for the CRYPTO_CLIENT tests Signed-off-by: Valerio Setti --- tests/src/psa_crypto_stubs.c | 50 ++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/tests/src/psa_crypto_stubs.c b/tests/src/psa_crypto_stubs.c index f3ca850747..81d7f4b328 100644 --- a/tests/src/psa_crypto_stubs.c +++ b/tests/src/psa_crypto_stubs.c @@ -22,4 +22,54 @@ psa_status_t psa_generate_random(uint8_t *output, return PSA_ERROR_COMMUNICATION_FAILURE; } +psa_status_t psa_export_key(mbedtls_svc_key_id_t key, + uint8_t *data, + size_t data_size, + size_t *data_length) +{ + (void) key; + (void) data; + (void) data_size; + (void) data_length; + return PSA_ERROR_COMMUNICATION_FAILURE; +} + +psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key, + uint8_t *data, + size_t data_size, + size_t *data_length) +{ + (void) key; + (void) data; + (void) data_size; + (void) data_length; + return PSA_ERROR_COMMUNICATION_FAILURE; +} + +psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key, + psa_key_attributes_t *attributes) +{ + (void) key; + (void) attributes; + return PSA_ERROR_COMMUNICATION_FAILURE; +} + +psa_status_t psa_hash_abort(psa_hash_operation_t *operation) +{ + (void) operation; + return PSA_ERROR_COMMUNICATION_FAILURE; +} + +psa_status_t psa_import_key(const psa_key_attributes_t *attributes, + const uint8_t *data, + size_t data_length, + mbedtls_svc_key_id_t *key) +{ + (void) attributes; + (void) data; + (void) data_length; + (void) key; + return PSA_ERROR_COMMUNICATION_FAILURE; +} + #endif /* MBEDTLS_PSA_CRYPTO_CLIENT && !MBEDTLS_PSA_CRYPTO_C */ From 864a50b7c8e14f857077128ca9d23f61158b83a0 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 12 Mar 2024 13:41:19 +0100 Subject: [PATCH 129/211] pk: uniformly guard set/get enrollment algorithm calls with CRYPTO_C Signed-off-by: Valerio Setti --- library/pk.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/library/pk.c b/library/pk.c index ccc2eac6d0..ec3741b13b 100644 --- a/library/pk.c +++ b/library/pk.c @@ -324,14 +324,14 @@ int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg, } psa_algorithm_t key_alg = psa_get_key_algorithm(&attributes); - /* Key's enrollment is available only when MBEDTLS_PSA_CRYPTO_CLIENT is - * defined, i.e. when the Mbed TLS implementation of PSA Crypto is being used. + /* Key's enrollment is available only when an Mbed TLS implementation of PSA + * Crypto is being used, i.e. when MBEDTLS_PSA_CRYPTO_C is defined. * Even though we don't officially support using other implementations of PSA - * Crypto with TLS and X.509 (yet), we're still trying to simplify the life of - * people who would like to try it before it's officially supported. */ -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) + * Crypto with TLS and X.509 (yet), we try to keep vendor's customizations + * separated. */ +#if defined(MBEDTLS_PSA_CRYPTO_C) psa_algorithm_t key_alg2 = psa_get_key_enrollment_algorithm(&attributes); -#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ +#endif /* MBEDTLS_PSA_CRYPTO_C */ key_usage = psa_get_key_usage_flags(&attributes); psa_reset_key_attributes(&attributes); @@ -349,11 +349,11 @@ int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg, if (alg == key_alg) { return 1; } -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) +#if defined(MBEDTLS_PSA_CRYPTO_C) if (alg == key_alg2) { return 1; } -#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ +#endif /* MBEDTLS_PSA_CRYPTO_C */ /* * If key_alg [or key_alg2] is a hash-and-sign with a wildcard for the hash, @@ -361,19 +361,18 @@ int mbedtls_pk_can_do_ext(const mbedtls_pk_context *ctx, psa_algorithm_t alg, * then alg is compliant with this key alg */ if (PSA_ALG_IS_SIGN_HASH(alg)) { - if (PSA_ALG_IS_SIGN_HASH(key_alg) && PSA_ALG_SIGN_GET_HASH(key_alg) == PSA_ALG_ANY_HASH && (alg & ~PSA_ALG_HASH_MASK) == (key_alg & ~PSA_ALG_HASH_MASK)) { return 1; } -#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) +#if defined(MBEDTLS_PSA_CRYPTO_C) if (PSA_ALG_IS_SIGN_HASH(key_alg2) && PSA_ALG_SIGN_GET_HASH(key_alg2) == PSA_ALG_ANY_HASH && (alg & ~PSA_ALG_HASH_MASK) == (key_alg2 & ~PSA_ALG_HASH_MASK)) { return 1; } -#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ +#endif /* MBEDTLS_PSA_CRYPTO_C */ } return 0; @@ -1323,7 +1322,10 @@ 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_algorithm_t psa_alg, sign_alg; +#if defined(MBEDTLS_PSA_CRYPTO_C) + psa_algorithm_t psa_enrollment_alg; +#endif /* MBEDTLS_PSA_CRYPTO_C */ psa_status_t status; status = psa_get_key_attributes(ctx->priv_id, &key_attr); @@ -1331,16 +1333,22 @@ int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type, return PSA_PK_RSA_TO_MBEDTLS_ERR(status); } psa_alg = psa_get_key_algorithm(&key_attr); +#if defined(MBEDTLS_PSA_CRYPTO_C) psa_enrollment_alg = psa_get_key_enrollment_algorithm(&key_attr); +#endif /* MBEDTLS_PSA_CRYPTO_C */ 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)) { + } +#if defined(MBEDTLS_PSA_CRYPTO_C) + else if (PSA_ALG_IS_RSA_PSS(psa_enrollment_alg)) { sign_alg = psa_enrollment_alg; - } else { + } +#endif /* MBEDTLS_PSA_CRYPTO_C */ + else { /* The opaque key has no RSA PSS algorithm associated. */ return MBEDTLS_ERR_PK_BAD_INPUT_DATA; } From 386c39f2d5b5dc9efffec04ad0b8a24176c6a9aa Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 13 Mar 2024 09:39:53 +0000 Subject: [PATCH 130/211] Check gcc version Signed-off-by: Dave Rodgman --- library/gcm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/gcm.c b/library/gcm.c index 976d6d76de..5dfac2349c 100644 --- a/library/gcm.c +++ b/library/gcm.c @@ -412,14 +412,14 @@ int mbedtls_gcm_starts(mbedtls_gcm_context *ctx, while (iv_len > 0) { use_len = (iv_len < 16) ? iv_len : 16; -#if defined(MBEDTLS_COMPILER_IS_GCC) +#if defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 70110) #pragma GCC diagnostic push #pragma GCC diagnostic warning "-Wstringop-overflow=0" #endif mbedtls_xor(ctx->y, ctx->y, p, use_len); -#if defined(MBEDTLS_COMPILER_IS_GCC) +#if defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 70110) #pragma GCC diagnostic pop #endif From fac1122b85a79574b0cdf920a636cb7710a2e07b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bence=20Sz=C3=A9pk=C3=BAti?= Date: Tue, 12 Mar 2024 16:38:23 +0100 Subject: [PATCH 131/211] Rename solution files to referece VS2017 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bence Szépkúti --- Makefile | 14 +++++++------- ...emplate.vcxproj => vs2017-app-template.vcxproj} | 0 ...mplate.vcxproj => vs2017-main-template.vcxproj} | 0 ...13-sln-template.sln => vs2017-sln-template.sln} | 0 scripts/generate_visualc_files.pl | 8 ++++---- scripts/windows_msbuild.bat | 2 +- tests/scripts/check-generated-files.sh | 2 +- visualc/{VS2013 => VS2017}/.gitignore | 0 8 files changed, 13 insertions(+), 13 deletions(-) rename scripts/data_files/{vs2013-app-template.vcxproj => vs2017-app-template.vcxproj} (100%) rename scripts/data_files/{vs2013-main-template.vcxproj => vs2017-main-template.vcxproj} (100%) rename scripts/data_files/{vs2013-sln-template.sln => vs2017-sln-template.sln} (100%) rename visualc/{VS2013 => VS2017}/.gitignore (100%) diff --git a/Makefile b/Makefile index 885948c112..0c404bffaa 100644 --- a/Makefile +++ b/Makefile @@ -60,7 +60,7 @@ gen_file_dep = | endif .PHONY: visualc_files -VISUALC_FILES = visualc/VS2013/mbedTLS.sln visualc/VS2013/mbedTLS.vcxproj +VISUALC_FILES = visualc/VS2017/mbedTLS.sln visualc/VS2017/mbedTLS.vcxproj # TODO: $(app).vcxproj for each $(app) in programs/ visualc_files: $(VISUALC_FILES) @@ -69,9 +69,9 @@ visualc_files: $(VISUALC_FILES) # they just need to be present. $(VISUALC_FILES): | library/generated_files $(VISUALC_FILES): $(gen_file_dep) scripts/generate_visualc_files.pl -$(VISUALC_FILES): $(gen_file_dep) scripts/data_files/vs2013-app-template.vcxproj -$(VISUALC_FILES): $(gen_file_dep) scripts/data_files/vs2013-main-template.vcxproj -$(VISUALC_FILES): $(gen_file_dep) scripts/data_files/vs2013-sln-template.sln +$(VISUALC_FILES): $(gen_file_dep) scripts/data_files/vs2017-app-template.vcxproj +$(VISUALC_FILES): $(gen_file_dep) scripts/data_files/vs2017-main-template.vcxproj +$(VISUALC_FILES): $(gen_file_dep) scripts/data_files/vs2017-sln-template.sln # TODO: also the list of .c and .h source files, but not their content $(VISUALC_FILES): echo " Gen $@ ..." @@ -147,10 +147,10 @@ neat: clean_more_on_top $(MAKE) -C programs neat $(MAKE) -C tests neat ifndef WINDOWS - rm -f visualc/VS2013/*.vcxproj visualc/VS2013/mbedTLS.sln + rm -f visualc/VS2017/*.vcxproj visualc/VS2017/mbedTLS.sln else - if exist visualc\VS2013\*.vcxproj del /Q /F visualc\VS2013\*.vcxproj - if exist visualc\VS2013\mbedTLS.sln del /Q /F visualc\VS2013\mbedTLS.sln + if exist visualc\VS2017\*.vcxproj del /Q /F visualc\VS2017\*.vcxproj + if exist visualc\VS2017\mbedTLS.sln del /Q /F visualc\VS2017\mbedTLS.sln endif check: lib tests diff --git a/scripts/data_files/vs2013-app-template.vcxproj b/scripts/data_files/vs2017-app-template.vcxproj similarity index 100% rename from scripts/data_files/vs2013-app-template.vcxproj rename to scripts/data_files/vs2017-app-template.vcxproj diff --git a/scripts/data_files/vs2013-main-template.vcxproj b/scripts/data_files/vs2017-main-template.vcxproj similarity index 100% rename from scripts/data_files/vs2013-main-template.vcxproj rename to scripts/data_files/vs2017-main-template.vcxproj diff --git a/scripts/data_files/vs2013-sln-template.sln b/scripts/data_files/vs2017-sln-template.sln similarity index 100% rename from scripts/data_files/vs2013-sln-template.sln rename to scripts/data_files/vs2017-sln-template.sln diff --git a/scripts/generate_visualc_files.pl b/scripts/generate_visualc_files.pl index 96ade2fa76..272337c22d 100755 --- a/scripts/generate_visualc_files.pl +++ b/scripts/generate_visualc_files.pl @@ -13,12 +13,12 @@ use warnings; use strict; use Digest::MD5 'md5_hex'; -my $vsx_dir = "visualc/VS2013"; +my $vsx_dir = "visualc/VS2017"; my $vsx_ext = "vcxproj"; -my $vsx_app_tpl_file = "scripts/data_files/vs2013-app-template.$vsx_ext"; -my $vsx_main_tpl_file = "scripts/data_files/vs2013-main-template.$vsx_ext"; +my $vsx_app_tpl_file = "scripts/data_files/vs2017-app-template.$vsx_ext"; +my $vsx_main_tpl_file = "scripts/data_files/vs2017-main-template.$vsx_ext"; my $vsx_main_file = "$vsx_dir/mbedTLS.$vsx_ext"; -my $vsx_sln_tpl_file = "scripts/data_files/vs2013-sln-template.sln"; +my $vsx_sln_tpl_file = "scripts/data_files/vs2017-sln-template.sln"; my $vsx_sln_file = "$vsx_dir/mbedTLS.sln"; my $programs_dir = 'programs'; diff --git a/scripts/windows_msbuild.bat b/scripts/windows_msbuild.bat index ff2b9f2d1c..2bc6a51ce8 100644 --- a/scripts/windows_msbuild.bat +++ b/scripts/windows_msbuild.bat @@ -14,7 +14,7 @@ if not "%~1"=="" set "retarget=,PlatformToolset=%1" @rem vcvarsall.bat will silently change the directory to that directory. @rem Setting the VSCMD_START_DIR environment variable causes it to change @rem to that directory instead. -set "VSCMD_START_DIR=%~dp0\..\visualc\VS2013" +set "VSCMD_START_DIR=%~dp0\..\visualc\VS2017" "%vcvarsall%" x64 && ^ msbuild /t:Rebuild /p:Configuration=%cfg%%retarget% /m mbedTLS.sln diff --git a/tests/scripts/check-generated-files.sh b/tests/scripts/check-generated-files.sh index 3fe4e8c63a..792885fdf3 100755 --- a/tests/scripts/check-generated-files.sh +++ b/tests/scripts/check-generated-files.sh @@ -142,5 +142,5 @@ if in_mbedtls_repo; then # generate_visualc_files enumerates source files (library/*.c). It doesn't # care about their content, but the files must exist. So it must run after # the step that creates or updates these files. - check scripts/generate_visualc_files.pl visualc/VS2013 + check scripts/generate_visualc_files.pl visualc/VS2017 fi diff --git a/visualc/VS2013/.gitignore b/visualc/VS2017/.gitignore similarity index 100% rename from visualc/VS2013/.gitignore rename to visualc/VS2017/.gitignore From 0719d7c3d8e134b3d95f5f075fa31fd75f95736c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bence=20Sz=C3=A9pk=C3=BAti?= Date: Tue, 12 Mar 2024 16:45:55 +0100 Subject: [PATCH 132/211] Update the MSBuild toolset versions to VS2017 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bence Szépkúti --- scripts/data_files/vs2017-app-template.vcxproj | 6 +++++- scripts/data_files/vs2017-main-template.vcxproj | 6 +++++- scripts/data_files/vs2017-sln-template.sln | 6 +++--- scripts/generate_visualc_files.pl | 2 +- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/scripts/data_files/vs2017-app-template.vcxproj b/scripts/data_files/vs2017-app-template.vcxproj index 2fe9cf33b5..36ca317052 100644 --- a/scripts/data_files/vs2017-app-template.vcxproj +++ b/scripts/data_files/vs2017-app-template.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -37,23 +37,27 @@ Application true Unicode + v141 Application true Unicode + v141 Application false true Unicode + v141 Application false true Unicode + v141 diff --git a/scripts/data_files/vs2017-main-template.vcxproj b/scripts/data_files/vs2017-main-template.vcxproj index 51861e16c5..448f9cd956 100644 --- a/scripts/data_files/vs2017-main-template.vcxproj +++ b/scripts/data_files/vs2017-main-template.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -28,23 +28,27 @@ StaticLibrary true Unicode + v141 StaticLibrary true Unicode + v141 StaticLibrary false true Unicode + v141 StaticLibrary false true Unicode + v141 diff --git a/scripts/data_files/vs2017-sln-template.sln b/scripts/data_files/vs2017-sln-template.sln index 615ce04234..80efb10832 100644 --- a/scripts/data_files/vs2017-sln-template.sln +++ b/scripts/data_files/vs2017-sln-template.sln @@ -1,8 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.31101.0 -MinimumVisualStudioVersion = 10.0.40219.1 +# Visual Studio 2017 +VisualStudioVersion = 15.0.26228.4 +MinimumVisualStudioVersion = 15.0.26228.4 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mbedTLS", "mbedTLS.vcxproj", "{46CF2D25-6A36-4189-B59C-E4815388E554}" EndProject APP_ENTRIES diff --git a/scripts/generate_visualc_files.pl b/scripts/generate_visualc_files.pl index 272337c22d..a0dfc57bff 100755 --- a/scripts/generate_visualc_files.pl +++ b/scripts/generate_visualc_files.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl # Generate main file, individual apps and solution files for -# MS Visual Studio 2013 +# MS Visual Studio 2017 # # Must be run from Mbed TLS root or scripts directory. # Takes no argument. From ae0d97ab8bedbfcc0bfd2f682287028e0fbdd443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bence=20Sz=C3=A9pk=C3=BAti?= Date: Tue, 12 Mar 2024 17:23:01 +0100 Subject: [PATCH 133/211] Update compilers list in docs and changelog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop support for MSVC 2013, 2015 and Arm Compiler 5 Signed-off-by: Bence Szépkúti --- ChangeLog.d/drop-msvc-2015-and-armcc-5.txt | 2 ++ README.md | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 ChangeLog.d/drop-msvc-2015-and-armcc-5.txt diff --git a/ChangeLog.d/drop-msvc-2015-and-armcc-5.txt b/ChangeLog.d/drop-msvc-2015-and-armcc-5.txt new file mode 100644 index 0000000000..de37c2781d --- /dev/null +++ b/ChangeLog.d/drop-msvc-2015-and-armcc-5.txt @@ -0,0 +1,2 @@ +Requirement changes + * Drop support for MSVC 2013, 2015 and Arm Compiler 5. diff --git a/README.md b/README.md index 2505d8fd9c..f22a45348a 100644 --- a/README.md +++ b/README.md @@ -47,11 +47,11 @@ The Make and CMake build systems create three libraries: libmbedcrypto, libmbedx You need the following tools to build the library with the provided makefiles: * GNU Make 3.82 or a build tool that CMake supports. -* A C99 toolchain (compiler, linker, archiver). We actively test with GCC 5.4, Clang 3.8, IAR 8 and Visual Studio 2013. More recent versions should work. Slightly older versions may work. +* A C99 toolchain (compiler, linker, archiver). We actively test with GCC 5.4, Clang 3.8, Arm Compiler 6, IAR 8 and Visual Studio 2017. More recent versions should work. Slightly older versions may work. * Python 3.8 to generate the test code. Python is also needed to integrate PSA drivers and to build the development branch (see next section). * Perl to run the tests, and to generate some source files in the development branch. * CMake 3.10.2 or later (if using CMake). -* Microsoft Visual Studio 2013 or later (if using Visual Studio). +* Microsoft Visual Studio 2017 or later (if using Visual Studio). * Doxygen 1.8.11 or later (if building the documentation; slightly older versions should work). ### Generated source files in the development branch @@ -221,7 +221,7 @@ subproject. ### Microsoft Visual Studio -The build files for Microsoft Visual Studio are generated for Visual Studio 2013. +The build files for Microsoft Visual Studio are generated for Visual Studio 2017. The solution file `mbedTLS.sln` contains all the basic projects needed to build the library and all the programs. The files in tests are not generated and compiled, as these need Python and perl environments as well. However, the selftest program in `programs/test/` is still available. From 93b282232fc777807f21cb7db8804759989bc2c7 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 13 Mar 2024 13:08:57 +0100 Subject: [PATCH 134/211] missing word Signed-off-by: Gilles Peskine --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7d3894e8b2..8bb0b60a40 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ You need the following tools to build the library with the provided makefiles: ### Git usage -The `development` branch and the `mbedtls-3.6` long-term support of Mbed TLS use a [Git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules#_cloning_submodules) ([framework](https://github.com/Mbed-TLS/mbedtls-framework)). This is not needed to merely compile the library at a release tag. This is not needed to consume a release archive (zip or tar). +The `development` branch and the `mbedtls-3.6` long-term support branch of Mbed TLS use a [Git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules#_cloning_submodules) ([framework](https://github.com/Mbed-TLS/mbedtls-framework)). This is not needed to merely compile the library at a release tag. This is not needed to consume a release archive (zip or tar). ### Generated source files in the development branch From bedd2519e64cd31fd43370ef28bb4b7ae96c5ae0 Mon Sep 17 00:00:00 2001 From: BensonLiou Date: Wed, 13 Mar 2024 20:21:26 +0800 Subject: [PATCH 135/211] fix code style Signed-off-by: BensonLiou --- tests/suites/test_suite_ssl.function | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 41f8bb7669..c2655de936 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -2419,7 +2419,7 @@ void ssl_session_serialize_version_check(int corrupt_major, * corrupt them bit-by-bit. */ for (cur_byte = 0; cur_byte < sizeof(should_corrupt_byte); cur_byte++) { int cur_bit; - unsigned char * const byte = &serialized_session[cur_byte]; + unsigned char *const byte = &serialized_session[cur_byte]; if (should_corrupt_byte[cur_byte] == 0) { continue; @@ -3932,11 +3932,16 @@ void tls13_cli_early_data_status(int scenario) if (client_ep.ssl.handshake->hello_retry_request_count == 0) { TEST_EQUAL(client_ep.ssl.early_data_status, MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE); - memcpy(client_random, client_ep.ssl.handshake->randbytes, MBEDTLS_CLIENT_HELLO_RANDOM_LEN); + memcpy(client_random, + client_ep.ssl.handshake->randbytes, + MBEDTLS_CLIENT_HELLO_RANDOM_LEN); } else { TEST_EQUAL(client_ep.ssl.early_data_status, MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED); - TEST_MEMORY_COMPARE(client_random, MBEDTLS_CLIENT_HELLO_RANDOM_LEN, client_ep.ssl.handshake->randbytes, MBEDTLS_CLIENT_HELLO_RANDOM_LEN); + TEST_MEMORY_COMPARE(client_random, + MBEDTLS_CLIENT_HELLO_RANDOM_LEN, + client_ep.ssl.handshake->randbytes, + MBEDTLS_CLIENT_HELLO_RANDOM_LEN); } break; } From 47cee8e2ee084645ab00d56db5ffea5d428af289 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Fri, 8 Mar 2024 21:38:02 +0000 Subject: [PATCH 136/211] Add mbedtls_psa_crypto_init_subsystem() Internal only for now, but can be made external with some more work. Break up psa_crypto_init into chunks to prevent deadlocks when initialising RNG, likewise break up mbedtls_crypto_free() to stop having to hold more than one mutex at a time. Signed-off-by: Paul Elliott --- library/psa_crypto.c | 266 +++++++++++++++++++++++++++++++++---------- 1 file changed, 207 insertions(+), 59 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 63fd05c59b..88842678f5 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -93,10 +93,25 @@ static int key_type_is_raw_bytes(psa_key_type_t type) #define RNG_INITIALIZED 1 #define RNG_SEEDED 2 +typedef enum { + PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS = 0, + PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS, + PSA_CRYPTO_SUBSYSTEM_RNG, + PSA_CRYPTO_SUBSYSTEM_TRANSACTION, +} mbedtls_psa_crypto_subsystem; + +#define PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED 0x01 +#define PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED 0x02 +#define PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED 0x04 + +#define PSA_CRYPTO_SUBSYSTEM_ALL_INITIALISED ( \ + PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED | \ + PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED | \ + PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED) + typedef struct { uint8_t initialized; uint8_t rng_state; - uint8_t drivers_initialized; mbedtls_psa_random_context_t rng; } psa_global_data_t; @@ -106,11 +121,22 @@ static uint8_t psa_get_initialized(void) { uint8_t initialized; +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + + initialized = global_data.rng_state == RNG_SEEDED; + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + #if defined(MBEDTLS_THREADING_C) mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex); #endif /* defined(MBEDTLS_THREADING_C) */ - initialized = global_data.initialized; + initialized = + (initialized && (global_data.initialized == PSA_CRYPTO_SUBSYSTEM_ALL_INITIALISED)); #if defined(MBEDTLS_THREADING_C) mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); @@ -127,7 +153,7 @@ static uint8_t psa_get_drivers_initialized(void) mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex); #endif /* defined(MBEDTLS_THREADING_C) */ - initialized = global_data.drivers_initialized; + initialized = (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED) != 0; #if defined(MBEDTLS_THREADING_C) mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); @@ -7490,29 +7516,53 @@ psa_status_t mbedtls_psa_crypto_configure_entropy_sources( void mbedtls_psa_crypto_free(void) { - /* Need to hold the mutex here to prevent this going ahead before - * psa_crypto_init() has completed, and to ensure integrity of - * global_data. */ + #if defined(MBEDTLS_THREADING_C) mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex); #endif /* defined(MBEDTLS_THREADING_C) */ - psa_wipe_all_key_slots(); - if (global_data.rng_state != RNG_NOT_INITIALIZED) { - mbedtls_psa_random_free(&global_data.rng); + /* Nothing to do to free transaction. */ + if (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED) { + global_data.initialized &= ~PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED; } - /* Wipe all remaining data, including configuration. - * In particular, this sets all state indicator to the value - * indicating "uninitialized". */ - mbedtls_platform_zeroize(&global_data, sizeof(global_data)); + if (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED) { + psa_wipe_all_key_slots(); + global_data.initialized &= ~PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED; + } #if defined(MBEDTLS_THREADING_C) mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); #endif /* defined(MBEDTLS_THREADING_C) */ +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + + if (global_data.rng_state != RNG_NOT_INITIALIZED) { + mbedtls_psa_random_free(&global_data.rng); + } + global_data.rng_state = RNG_NOT_INITIALIZED; + mbedtls_platform_zeroize(&global_data.rng, sizeof(global_data.rng)); + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_unlock(&mbedtls_threading_psa_rngdata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + /* Terminate drivers */ - psa_driver_wrapper_free(); + if (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED) { + psa_driver_wrapper_free(); + global_data.initialized &= ~PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED; + } + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + } #if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) @@ -7540,74 +7590,172 @@ static psa_status_t psa_crypto_recover_transaction( } #endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */ +static psa_status_t mbedtls_psa_crypto_init_subsystem(mbedtls_psa_crypto_subsystem subsystem) +{ + psa_status_t status = PSA_SUCCESS; + uint8_t driver_wrappers_initialized = 0; + + switch (subsystem) { + case PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS: + +#if defined(MBEDTLS_THREADING_C) + PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex)); +#endif /* defined(MBEDTLS_THREADING_C) */ + + if (!(global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED)) { + /* Init drivers */ + status = psa_driver_wrapper_init(); + + /* Drivers need shutdown regardless of startup errors. */ + global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED; + + + } +#if defined(MBEDTLS_THREADING_C) + PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock( + &mbedtls_threading_psa_globaldata_mutex)); +#endif /* defined(MBEDTLS_THREADING_C) */ + + break; + + case PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS: + +#if defined(MBEDTLS_THREADING_C) + PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex)); +#endif /* defined(MBEDTLS_THREADING_C) */ + + if (!(global_data.initialized & PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED)) { + status = psa_initialize_key_slots(); + + /* Need to wipe keys even if initialization fails. */ + global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED; + + } +#if defined(MBEDTLS_THREADING_C) + PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock( + &mbedtls_threading_psa_globaldata_mutex)); +#endif /* defined(MBEDTLS_THREADING_C) */ + + break; + + case PSA_CRYPTO_SUBSYSTEM_RNG: + +#if defined(MBEDTLS_THREADING_C) + PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex)); +#endif /* defined(MBEDTLS_THREADING_C) */ + + driver_wrappers_initialized = + (global_data.initialized & PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED); + +#if defined(MBEDTLS_THREADING_C) + PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock( + &mbedtls_threading_psa_globaldata_mutex)); +#endif /* defined(MBEDTLS_THREADING_C) */ + + /* Need to use separate mutex here, as initialisation can require + * testing of init flags, which requires locking the global data + * mutex. */ +#if defined(MBEDTLS_THREADING_C) + PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_rngdata_mutex)); +#endif /* defined(MBEDTLS_THREADING_C) */ + + /* Initialize and seed the random generator. */ + if (global_data.rng_state == RNG_NOT_INITIALIZED && driver_wrappers_initialized) { + mbedtls_psa_random_init(&global_data.rng); + global_data.rng_state = RNG_INITIALIZED; + + status = mbedtls_psa_random_seed(&global_data.rng); + if (status == PSA_SUCCESS) { + global_data.rng_state = RNG_SEEDED; + } + } + +#if defined(MBEDTLS_THREADING_C) + PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock( + &mbedtls_threading_psa_rngdata_mutex)); +#endif /* defined(MBEDTLS_THREADING_C) */ + + + break; + + case PSA_CRYPTO_SUBSYSTEM_TRANSACTION: + +#if defined(MBEDTLS_THREADING_C) + PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex)); +#endif /* defined(MBEDTLS_THREADING_C) */ + + if (!(global_data.initialized & PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED)) { +#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) + status = psa_crypto_load_transaction(); + if (status == PSA_SUCCESS) { + status = psa_crypto_recover_transaction(&psa_crypto_transaction); + if (status == PSA_SUCCESS) { + global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED; + } + status = psa_crypto_stop_transaction(); + } else if (status == PSA_ERROR_DOES_NOT_EXIST) { + /* There's no transaction to complete. It's all good. */ + global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED; + status = PSA_SUCCESS; + } +#else /* defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) */ + global_data.initialized |= PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED; + status = PSA_SUCCESS; +#endif /* defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) */ + } + +#if defined(MBEDTLS_THREADING_C) + PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_unlock( + &mbedtls_threading_psa_globaldata_mutex)); +#endif /* defined(MBEDTLS_THREADING_C) */ + + break; + + default: + status = PSA_ERROR_CORRUPTION_DETECTED; + } + + /* Exit label only required when using threading macros. */ +#if defined(MBEDTLS_THREADING_C) +exit: +#endif /* defined(MBEDTLS_THREADING_C) */ + + return status; +} + psa_status_t psa_crypto_init(void) { psa_status_t status; - /* Need to hold the mutex for the entire function to prevent incomplete - * initialisation before someone calls psa_crypto_free() or calls this - * function again before we set global_data.initialised to 1. */ - #if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - - /* We cannot use psa_get_initialized() here as we already hold the mutex. */ - if (global_data.initialized == 1) { -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - - /* Double initialization is explicitly allowed. */ + /* Double initialization is explicitly allowed. Early out if everything is + * done. */ + if (psa_get_initialized()) { return PSA_SUCCESS; } - /* Init drivers */ - status = psa_driver_wrapper_init(); - if (status != PSA_SUCCESS) { - goto exit; - } - global_data.drivers_initialized = 1; - - status = psa_initialize_key_slots(); + status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS); if (status != PSA_SUCCESS) { goto exit; } - /* Initialize and seed the random generator. */ - mbedtls_psa_random_init(&global_data.rng); - global_data.rng_state = RNG_INITIALIZED; - status = mbedtls_psa_random_seed(&global_data.rng); + status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS); if (status != PSA_SUCCESS) { goto exit; } - global_data.rng_state = RNG_SEEDED; -#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) - status = psa_crypto_load_transaction(); - if (status == PSA_SUCCESS) { - status = psa_crypto_recover_transaction(&psa_crypto_transaction); - if (status != PSA_SUCCESS) { - goto exit; - } - status = psa_crypto_stop_transaction(); - } else if (status == PSA_ERROR_DOES_NOT_EXIST) { - /* There's no transaction to complete. It's all good. */ - status = PSA_SUCCESS; + status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_RNG); + if (status != PSA_SUCCESS) { + goto exit; } -#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */ - /* All done. */ - global_data.initialized = 1; + status = mbedtls_psa_crypto_init_subsystem(PSA_CRYPTO_SUBSYSTEM_TRANSACTION); exit: -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); -#endif /* defined(MBEDTLS_THREADING_C) */ - if (status != PSA_SUCCESS) { mbedtls_psa_crypto_free(); } + return status; } From 838886da64e23f81ffbe82b987a347f467ecc9ad Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Tue, 12 Mar 2024 15:26:04 +0000 Subject: [PATCH 137/211] Protect the key slot management initialised flag Use the global data mutex, as the key slot mutex has to be held in some of the functions where we are testing the flag, and we already hold the global data mutex when calling the functions where the flag is set. Signed-off-by: Paul Elliott --- library/psa_crypto_slot_management.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 5dee32ffe3..6a51644027 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -34,6 +34,24 @@ typedef struct { static psa_global_data_t global_data; +static uint8_t psa_get_key_slots_initialized(void) +{ + + uint8_t initialized; + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_lock(&mbedtls_threading_psa_globaldata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + + initialized = global_data.key_slots_initialized; + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_unlock(&mbedtls_threading_psa_globaldata_mutex); +#endif /* defined(MBEDTLS_THREADING_C) */ + + return initialized; +} + int psa_is_valid_key_id(mbedtls_svc_key_id_t key, int vendor_ok) { psa_key_id_t key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key); @@ -136,7 +154,9 @@ psa_status_t psa_initialize_key_slots(void) { /* Nothing to do: program startup and psa_wipe_all_key_slots() both * guarantee that the key slots are initialized to all-zero, which - * means that all the key slots are in a valid, empty state. */ + * means that all the key slots are in a valid, empty state. The global + * data mutex is already held when calling this function, so no need to + * lock it here, to set the flag. */ global_data.key_slots_initialized = 1; return PSA_SUCCESS; } @@ -151,6 +171,7 @@ void psa_wipe_all_key_slots(void) slot->state = PSA_SLOT_PENDING_DELETION; (void) psa_wipe_key_slot(slot); } + /* The global data mutex is already held when calling this function. */ global_data.key_slots_initialized = 0; } @@ -161,7 +182,7 @@ psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id, size_t slot_idx; psa_key_slot_t *selected_slot, *unused_persistent_key_slot; - if (!global_data.key_slots_initialized) { + if (!psa_get_key_slots_initialized()) { status = PSA_ERROR_BAD_STATE; goto error; } @@ -344,7 +365,7 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key, psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; *p_slot = NULL; - if (!global_data.key_slots_initialized) { + if (!psa_get_key_slots_initialized()) { return PSA_ERROR_BAD_STATE; } From 0493ab56a424d886c2b63552dda5da21736ec939 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Wed, 6 Mar 2024 12:26:58 +0000 Subject: [PATCH 138/211] Add PSA threaded init tests Signed-off-by: Paul Elliott --- tests/suites/test_suite_psa_crypto_init.data | 3 + .../test_suite_psa_crypto_init.function | 115 ++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto_init.data b/tests/suites/test_suite_psa_crypto_init.data index 8c5b41d6cb..147d03fbed 100644 --- a/tests/suites/test_suite_psa_crypto_init.data +++ b/tests/suites/test_suite_psa_crypto_init.data @@ -10,6 +10,9 @@ deinit_without_init:0 PSA deinit twice deinit_without_init:1 +PSA threaded init checks +psa_threaded_init:100 + No random without init validate_module_init_generate_random:0 diff --git a/tests/suites/test_suite_psa_crypto_init.function b/tests/suites/test_suite_psa_crypto_init.function index 7a434322ae..9ff33a6d84 100644 --- a/tests/suites/test_suite_psa_crypto_init.function +++ b/tests/suites/test_suite_psa_crypto_init.function @@ -1,6 +1,7 @@ /* BEGIN_HEADER */ #include +#include "psa_crypto_core.h" /* Some tests in this module configure entropy sources. */ #include "psa_crypto_invasive.h" @@ -112,6 +113,59 @@ static void custom_entropy_init(mbedtls_entropy_context *ctx) #endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */ +#if defined MBEDTLS_THREADING_PTHREAD + +typedef struct { + int do_init; +} thread_psa_init_ctx_t; + +static void *thread_psa_init_function(void *ctx) +{ + thread_psa_init_ctx_t *init_context = (thread_psa_init_ctx_t *) ctx; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + uint8_t random[10] = { 0 }; + + if (init_context->do_init) { + PSA_ASSERT(psa_crypto_init()); + } + + /* If this is a test only thread, then we can assume PSA is being started + * up on another thread and thus we cannot know whether the following tests + * will be successful or not. These checks are still useful, however even + * without checking the return codes as they may show up race conditions on + * the flags they check under TSAN.*/ + + /* Test getting if drivers are initialised. */ + int can_do = psa_can_do_hash(PSA_ALG_NONE); + + if (init_context->do_init) { + TEST_ASSERT(can_do == 1); + } + +#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) + + /* Test getting global_data.rng_state. */ + status = mbedtls_psa_crypto_configure_entropy_sources(NULL, NULL); + + if (init_context->do_init) { + /* Bad state due to entropy sources already being setup in + * psa_crypto_init() */ + TEST_EQUAL(status, PSA_ERROR_BAD_STATE); + } +#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */ + + /* Test using the PSA RNG ony if we know PSA is up and running. */ + if (init_context->do_init) { + status = psa_generate_random(random, sizeof(random)); + + TEST_EQUAL(status, PSA_SUCCESS); + } + +exit: + return NULL; +} +#endif /* defined MBEDTLS_THREADING_PTHREAD */ + /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -154,6 +208,67 @@ void deinit_without_init(int count) } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_THREADING_PTHREAD */ +void psa_threaded_init(int arg_thread_count) +{ + thread_psa_init_ctx_t init_context; + thread_psa_init_ctx_t init_context_2; + + size_t thread_count = (size_t) arg_thread_count; + mbedtls_test_thread_t *threads = NULL; + + TEST_CALLOC(threads, sizeof(mbedtls_test_thread_t) * thread_count); + + init_context.do_init = 1; + + /* Test initialising PSA and testing certain protected globals on multiple + * threads. */ + for (size_t i = 0; i < thread_count; i++) { + TEST_EQUAL( + mbedtls_test_thread_create(&threads[i], + thread_psa_init_function, + (void *) &init_context), + 0); + } + + for (size_t i = 0; i < thread_count; i++) { + TEST_EQUAL(mbedtls_test_thread_join(&threads[i]), 0); + } + + PSA_DONE(); + + init_context_2.do_init = 0; + + /* Test initialising PSA whilst also testing flags on other threads. */ + for (size_t i = 0; i < thread_count; i++) { + + if (i & 1) { + + TEST_EQUAL( + mbedtls_test_thread_create(&threads[i], + thread_psa_init_function, + (void *) &init_context), + 0); + } else { + TEST_EQUAL( + mbedtls_test_thread_create(&threads[i], + thread_psa_init_function, + (void *) &init_context_2), + 0); + } + } + + for (size_t i = 0; i < thread_count; i++) { + TEST_EQUAL(mbedtls_test_thread_join(&threads[i]), 0); + } +exit: + + PSA_DONE(); + + mbedtls_free(threads); +} +/* END_CASE */ + /* BEGIN_CASE */ void validate_module_init_generate_random(int count) { From 73e4ea37f497bb43937b55e826cb955461e257b3 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:29:55 +0000 Subject: [PATCH 139/211] Add key_destroyable parameter to non-raw key agreement smoke tests All current usages have this parameter set to 0 (this means the tests are unchanged). Remove the GENERIC_ERROR return behaviour, in favour of returning the actual status. Signed-off-by: Ryan Everett --- tests/include/test/psa_exercise_key.h | 5 ++- tests/src/psa_exercise_key.c | 43 +++++++++++++++------ tests/suites/test_suite_psa_crypto.function | 4 +- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/tests/include/test/psa_exercise_key.h b/tests/include/test/psa_exercise_key.h index 23349166a7..f656b95f88 100644 --- a/tests/include/test/psa_exercise_key.h +++ b/tests/include/test/psa_exercise_key.h @@ -168,12 +168,15 @@ psa_status_t mbedtls_test_psa_raw_key_agreement_with_self( * \p key. * \param key A key pair object that is suitable for a key * agreement with \p operation. + * \param key_destroyable If set to 1, a failure due to the key not existing + * or the key being destroyed mid-operation will only + * be reported if the error code is unexpected. * * \return \c 1 on success, \c 0 on failure. */ psa_status_t mbedtls_test_psa_key_agreement_with_self( psa_key_derivation_operation_t *operation, - mbedtls_svc_key_id_t key); + mbedtls_svc_key_id_t key, int key_destroyable); /** Perform sanity checks on the given key representation. * diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c index b62a34b5d7..1cf45ac567 100644 --- a/tests/src/psa_exercise_key.c +++ b/tests/src/psa_exercise_key.c @@ -628,31 +628,45 @@ exit: * private key against its own public key. */ psa_status_t mbedtls_test_psa_key_agreement_with_self( psa_key_derivation_operation_t *operation, - mbedtls_svc_key_id_t key) + mbedtls_svc_key_id_t key, int key_destroyable) { psa_key_type_t private_key_type; psa_key_type_t public_key_type; size_t key_bits; uint8_t *public_key = NULL; size_t public_key_length; - /* Return GENERIC_ERROR if something other than the final call to - * psa_key_derivation_key_agreement fails. This isn't fully satisfactory, - * but it's good enough: callers will report it as a failed test anyway. */ - psa_status_t status = PSA_ERROR_GENERIC_ERROR; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - PSA_ASSERT(psa_get_key_attributes(key, &attributes)); + psa_status_t status = psa_get_key_attributes(key, &attributes); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + psa_reset_key_attributes(&attributes); + return PSA_SUCCESS; + } + PSA_ASSERT(status); + private_key_type = psa_get_key_type(&attributes); key_bits = psa_get_key_bits(&attributes); public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type); public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits); TEST_CALLOC(public_key, public_key_length); - PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length, - &public_key_length)); + status = psa_export_public_key(key, public_key, public_key_length, + &public_key_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + status = PSA_SUCCESS; + goto exit; + } + PSA_ASSERT(status); status = psa_key_derivation_key_agreement( operation, PSA_KEY_DERIVATION_INPUT_SECRET, key, public_key, public_key_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + status = PSA_SUCCESS; + goto exit; + } exit: /* * Key attributes may have been returned by psa_get_key_attributes() @@ -750,7 +764,8 @@ exit: static int exercise_key_agreement_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage, - psa_algorithm_t alg) + psa_algorithm_t alg, + int key_destroyable) { psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT; unsigned char input[1] = { 0 }; @@ -781,7 +796,12 @@ static int exercise_key_agreement_key(mbedtls_svc_key_id_t key, hash length. Otherwise test should fail with INVALID_ARGUMENT. */ if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - PSA_ASSERT(psa_get_key_attributes(key, &attributes)); + psa_status_t status = psa_get_key_attributes(key, &attributes); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + ok = 1; + } + PSA_ASSERT(status); size_t key_bits = psa_get_key_bits(&attributes); psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg); @@ -790,7 +810,8 @@ static int exercise_key_agreement_key(mbedtls_svc_key_id_t key, } } - TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key), + TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key, + key_destroyable), expected_key_agreement_status); if (expected_key_agreement_status != PSA_SUCCESS) { diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 9390958378..8fb7d44b31 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -2490,7 +2490,7 @@ void agreement_key_policy(int policy_usage, &key)); PSA_ASSERT(psa_key_derivation_setup(&operation, exercise_alg)); - status = mbedtls_test_psa_key_agreement_with_self(&operation, key); + status = mbedtls_test_psa_key_agreement_with_self(&operation, key, 0); TEST_EQUAL(status, expected_status); @@ -8681,7 +8681,7 @@ void derive_input(int alg_arg, // When taking a private key as secret input, use key agreement // to add the shared secret to the derivation TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self( - &operation, keys[i]), + &operation, keys[i], 0), expected_statuses[i]); } else { TEST_EQUAL(psa_key_derivation_input_key(&operation, steps[i], From fbf815d9cb178ac7bf3a883baf56fbaaa704257f Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:32:29 +0000 Subject: [PATCH 140/211] Add key_destroyable parameter to key export smoke tests These are only called from mbedtls_test_psa_exercise_key Signed-off-by: Ryan Everett --- tests/src/psa_exercise_key.c | 62 +++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c index 1cf45ac567..5aed683ebc 100644 --- a/tests/src/psa_exercise_key.c +++ b/tests/src/psa_exercise_key.c @@ -1002,7 +1002,8 @@ exit: } static int exercise_export_key(mbedtls_svc_key_id_t key, - psa_key_usage_t usage) + psa_key_usage_t usage, + int key_destroyable) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; uint8_t *exported = NULL; @@ -1010,25 +1011,31 @@ static int exercise_export_key(mbedtls_svc_key_id_t key, size_t exported_length = 0; int ok = 0; - PSA_ASSERT(psa_get_key_attributes(key, &attributes)); + psa_status_t status = psa_get_key_attributes(key, &attributes); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + psa_reset_key_attributes(&attributes); + return 1; + } + PSA_ASSERT(status); exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE( psa_get_key_type(&attributes), psa_get_key_bits(&attributes)); TEST_CALLOC(exported, exported_size); - if ((usage & PSA_KEY_USAGE_EXPORT) == 0 && - !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) { - TEST_EQUAL(psa_export_key(key, exported, - exported_size, &exported_length), - PSA_ERROR_NOT_PERMITTED); + status = psa_export_key(key, exported, exported_size, &exported_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + ok = 1; + goto exit; + } else if ((usage & PSA_KEY_USAGE_EXPORT) == 0 && + !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) { + TEST_EQUAL(status, PSA_ERROR_NOT_PERMITTED); ok = 1; goto exit; } - - PSA_ASSERT(psa_export_key(key, - exported, exported_size, - &exported_length)); + PSA_ASSERT(status); ok = mbedtls_test_psa_exported_key_sanity_check( psa_get_key_type(&attributes), psa_get_key_bits(&attributes), exported, exported_length); @@ -1044,7 +1051,8 @@ exit: return ok; } -static int exercise_export_public_key(mbedtls_svc_key_id_t key) +static int exercise_export_public_key(mbedtls_svc_key_id_t key, + int key_destroyable) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_key_type_t public_type; @@ -1053,16 +1061,27 @@ static int exercise_export_public_key(mbedtls_svc_key_id_t key) size_t exported_length = 0; int ok = 0; - PSA_ASSERT(psa_get_key_attributes(key, &attributes)); + psa_status_t status = psa_get_key_attributes(key, &attributes); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + psa_reset_key_attributes(&attributes); + return 1; + } + PSA_ASSERT(status); if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) { exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE( psa_get_key_type(&attributes), psa_get_key_bits(&attributes)); TEST_CALLOC(exported, exported_size); - TEST_EQUAL(psa_export_public_key(key, exported, - exported_size, &exported_length), - PSA_ERROR_INVALID_ARGUMENT); + status = psa_export_public_key(key, exported, + exported_size, &exported_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + ok = 1; + goto exit; + } + TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT); ok = 1; goto exit; } @@ -1073,9 +1092,14 @@ static int exercise_export_public_key(mbedtls_svc_key_id_t key) psa_get_key_bits(&attributes)); TEST_CALLOC(exported, exported_size); - PSA_ASSERT(psa_export_public_key(key, - exported, exported_size, - &exported_length)); + status = psa_export_public_key(key, exported, + exported_size, &exported_length); + if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) { + /* The key has been destroyed. */ + ok = 1; + goto exit; + } + PSA_ASSERT(status); ok = mbedtls_test_psa_exported_key_sanity_check( public_type, psa_get_key_bits(&attributes), exported, exported_length); From 50619991c8a49412536fc207bfefa69a15c76161 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 16:55:14 +0000 Subject: [PATCH 141/211] Add test function for concurrently using the same persistent key The thread functions can also be used in future tests for other key types and other test scenarios Signed-off-by: Ryan Everett --- tests/suites/test_suite_psa_crypto.function | 193 ++++++++++++++++++++ 1 file changed, 193 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 8fb7d44b31..6cb0744495 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1338,6 +1338,127 @@ exit: } #if defined(MBEDTLS_THREADING_PTHREAD) + +typedef struct same_key_context { + data_t *data; + mbedtls_svc_key_id_t key; + psa_key_attributes_t *attributes; + int type; + int bits; + /* The following two parameters are used to ensure that when multiple + * threads attempt to load/destroy the key, exactly one thread succeeds. */ + int key_loaded; + mbedtls_threading_mutex_t MBEDTLS_PRIVATE(key_loaded_mutex); +} +same_key_context; + +/* Attempt to import the key in ctx. This handles any valid error codes + * and reports an error for any invalid codes. This function also insures + * that once imported by some thread, all threads can use the key. */ +void *thread_import_key(void *ctx) +{ + mbedtls_svc_key_id_t returned_key_id; + same_key_context *skc = (struct same_key_context *) ctx; + psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT; + + /* Import the key, exactly one thread must succceed. */ + psa_status_t status = psa_import_key(skc->attributes, skc->data->x, + skc->data->len, &returned_key_id); + switch (status) { + case PSA_SUCCESS: + if (mbedtls_mutex_lock(&skc->key_loaded_mutex) == 0) { + if (skc->key_loaded) { + mbedtls_mutex_unlock(&skc->key_loaded_mutex); + /* More than one thread has succeeded, report a failure. */ + TEST_EQUAL(skc->key_loaded, 0); + } + skc->key_loaded = 1; + mbedtls_mutex_unlock(&skc->key_loaded_mutex); + } + break; + case PSA_ERROR_INSUFFICIENT_MEMORY: + /* If all of the key slots are reserved when a thread + * locks the mutex to reserve a new slot, it will return + * PSA_ERROR_INSUFFICIENT_MEMORY; this is correct behaviour. + * There is a chance for this to occur here when the number of + * threads running this function is larger than the number of + * free key slots. Each thread reserves an empty key slot, + * unlocks the mutex, then relocks it to finalize key creation. + * It is at that point where the thread sees that the key + * already exists, releases the reserved slot, + * and returns PSA_ERROR_ALREADY_EXISTS. + * There is no guarantee that the key is loaded upon this return + * code, so we can't test the key information. Just stop this + * thread from executing, note that this is not an error. */ + goto exit; + break; + case PSA_ERROR_ALREADY_EXISTS: + /* The key has been loaded by a different thread. */ + break; + default: + PSA_ASSERT(status); + } + /* At this point the key must exist, test the key information. */ + status = psa_get_key_attributes(skc->key, &got_attributes); + if (status == PSA_ERROR_INSUFFICIENT_MEMORY) { + /* This is not a test failure. The following sequence of events + * causes this to occur: + * 1: This thread successfuly imports a persistent key skc->key. + * 2: N threads reserve an empty key slot in psa_import_key, + * where N is equal to the number of free key slots. + * 3: A final thread attempts to reserve an empty key slot, kicking + * skc->key (which has no registered readers) out of its slot. + * 4: This thread calls psa_get_key_attributes(skc->key,...): + * it sees that skc->key is not in a slot, attempts to load it and + * finds that there are no free slots. + * This thread returns PSA_ERROR_INSUFFICIENT_MEMORY. + * + * The PSA spec allows this behaviour, it is an unavoidable consequence + * of allowing persistent keys to be kicked out of the key store while + * they are still valid. */ + goto exit; + } + PSA_ASSERT(status); + TEST_EQUAL(psa_get_key_type(&got_attributes), skc->type); + TEST_EQUAL(psa_get_key_bits(&got_attributes), skc->bits); + +exit: + /* Key attributes may have been returned by psa_get_key_attributes(), + * reset them as required. */ + psa_reset_key_attributes(&got_attributes); + return NULL; +} + +void *thread_use_and_destroy_key(void *ctx) +{ + same_key_context *skc = (struct same_key_context *) ctx; + + /* Do something with the key according + * to its type and permitted usage. */ + TEST_ASSERT(mbedtls_test_psa_exercise_key(skc->key, + skc->attributes->policy.usage, + skc->attributes->policy.alg, 1)); + + psa_status_t status = psa_destroy_key(skc->key); + if (status == PSA_SUCCESS) { + if (mbedtls_mutex_lock(&skc->key_loaded_mutex) == 0) { + /* Ensure that we are the only thread to succeed. */ + if (skc->key_loaded != 1) { + mbedtls_mutex_unlock(&skc->key_loaded_mutex); + //Will always fail + TEST_EQUAL(skc->key_loaded, 1); + } + skc->key_loaded = 0; + mbedtls_mutex_unlock(&skc->key_loaded_mutex); + } + } else { + TEST_EQUAL(status, PSA_ERROR_INVALID_HANDLE); + } + +exit: + return NULL; +} + typedef struct generate_key_context { psa_key_type_t type; psa_key_usage_t usage; @@ -1824,6 +1945,78 @@ exit: } /* END_CASE */ + +#if defined(MBEDTLS_THREADING_PTHREAD) +/* BEGIN_CASE depends_on:MBEDTLS_THREADING_PTHREAD:MBEDTLS_PSA_CRYPTO_STORAGE_C */ +void concurrently_use_same_persistent_key(data_t *data, + int type_arg, + int bits_arg, + int alg_arg, + int thread_count_arg) +{ + size_t thread_count = (size_t) thread_count_arg; + mbedtls_test_thread_t *threads = NULL; + mbedtls_svc_key_id_t key_id = mbedtls_svc_key_id_make(1, 1); + same_key_context skc; + skc.data = data; + skc.key = key_id; + skc.type = type_arg; + skc.bits = bits_arg; + skc.key_loaded = 0; + mbedtls_mutex_init(&skc.key_loaded_mutex); + psa_key_usage_t usage = mbedtls_test_psa_usage_to_exercise(skc.type, alg_arg); + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + PSA_ASSERT(psa_crypto_init()); + + psa_set_key_id(&attributes, key_id); + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_PERSISTENT); + psa_set_key_usage_flags(&attributes, usage); + psa_set_key_algorithm(&attributes, alg_arg); + psa_set_key_type(&attributes, type_arg); + psa_set_key_bits(&attributes, bits_arg); + skc.attributes = &attributes; + + TEST_CALLOC(threads, sizeof(mbedtls_test_thread_t) * thread_count); + + /* Test that when multiple threads import the same key, + * exactly one thread succeeds and the rest fail with valid errors. + * Also test that all threads can use the key as soon as it has been + * imported. */ + for (size_t i = 0; i < thread_count; i++) { + TEST_EQUAL( + mbedtls_test_thread_create(&threads[i], thread_import_key, + (void *) &skc), 0); + } + + /* Join threads. */ + for (size_t i = 0; i < thread_count; i++) { + TEST_EQUAL(mbedtls_test_thread_join(&threads[i]), 0); + } + + /* Test that when multiple threads use and destroy a key no corruption + * occurs, and exactly one thread succeeds when destroying the key. */ + for (size_t i = 0; i < thread_count; i++) { + TEST_EQUAL( + mbedtls_test_thread_create(&threads[i], thread_use_and_destroy_key, + (void *) &skc), 0); + } + + /* Join threads. */ + for (size_t i = 0; i < thread_count; i++) { + TEST_EQUAL(mbedtls_test_thread_join(&threads[i]), 0); + } + /* Ensure that one thread succeeded in destroying the key. */ + TEST_ASSERT(!skc.key_loaded); +exit: + psa_reset_key_attributes(&attributes); + mbedtls_mutex_free(&skc.key_loaded_mutex); + mbedtls_free(threads); + PSA_DONE(); +} +/* END_CASE */ +#endif + /* BEGIN_CASE */ void import_and_exercise_key(data_t *data, int type_arg, From f111f35478286a558a6e5690bd2cc731924b0f13 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 12 Mar 2024 17:00:40 +0000 Subject: [PATCH 142/211] Add test cases for concurrently_use_same_persistent_key There is a 1-1 correlation between these test cases and the test cases for import_and_exercise_key. Signed-off-by: Ryan Everett --- tests/suites/test_suite_psa_crypto.data | 44 +++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index b633c6f60f..a3a457da8a 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -4278,6 +4278,50 @@ PSA import/exercise: TLS 1.2 PRF SHA-256 depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF import_and_exercise_key:"c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0":PSA_KEY_TYPE_DERIVE:192:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256) +PSA concurrently import/exercise same key: RSA keypair, PKCS#1 v1.5 raw +depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT +concurrently_use_same_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:100 + +PSA concurrently import/exercise same key: RSA keypair, PSS-SHA-256 +depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT +concurrently_use_same_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):100 + +PSA concurrently import/exercise same key: RSA keypair, PSS-any-salt-SHA-256 +depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT +concurrently_use_same_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):100 + +PSA concurrently import/exercise same key: RSA public key, PKCS#1 v1.5 raw +depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY +concurrently_use_same_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:100 + +PSA concurrently import/exercise same key: RSA public key, PSS-SHA-256 +depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY +concurrently_use_same_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):100 + +PSA concurrently import/exercise same key: RSA public key, PSS-any-salt-SHA-256 +depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY +concurrently_use_same_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):100 + +PSA concurrently import/exercise same key: ECP SECP256R1 keypair, ECDSA +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256 +concurrently_use_same_persistent_key:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_ECDSA_ANY:100 + +PSA concurrently import/exercise same key: ECP SECP256R1 keypair, deterministic ECDSA +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256 +concurrently_use_same_persistent_key:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):100 + +PSA concurrently import/exercise same key: ECP SECP256R1 keypair, ECDH +depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256 +concurrently_use_same_persistent_key:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_ECDH:100 + +PSA concurrently import/exercise same key: HKDF SHA-256 +depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256 +concurrently_use_same_persistent_key:"c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0":PSA_KEY_TYPE_DERIVE:192:PSA_ALG_HKDF(PSA_ALG_SHA_256):100 + +PSA concurrently import/exercise same key: TLS 1.2 PRF SHA-256 +depends_on:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_TLS12_PRF +concurrently_use_same_persistent_key:"c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0":PSA_KEY_TYPE_DERIVE:192:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):100 + PSA sign hash: RSA PKCS#1 v1.5, raw depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT sign_hash_deterministic:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:"616263":"2c7744983f023ac7bb1c55529d83ed11a76a7898a1bb5ce191375a4aa7495a633d27879ff58eba5a57371c34feb1180e8b850d552476ebb5634df620261992f12ebee9097041dbbea85a42d45b344be5073ceb772ffc604954b9158ba81ec3dc4d9d65e3ab7aa318165f38c36f841f1c69cb1cfa494aa5cbb4d6c0efbafb043a" From 539d7d54aff3f1c2bf834253973714f1eb6fb884 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 13 Mar 2024 17:19:17 +0100 Subject: [PATCH 143/211] Work around a bug in ancient lcov lcov had a bug whereby it tries to create the output file relative to / if it has emitted a warning. We do CI runs on Ubuntu 16.04 which is too old to have the fix. As a quick fix for the CI, work around the bug. Signed-off-by: Gilles Peskine --- scripts/lcov.sh | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/scripts/lcov.sh b/scripts/lcov.sh index 0584a0aac7..9a0c58243f 100755 --- a/scripts/lcov.sh +++ b/scripts/lcov.sh @@ -39,13 +39,19 @@ in_mbedtls_build_dir () { lcov_library_report () { rm -rf Coverage mkdir Coverage Coverage/tmp - lcov --capture --initial --directory $library_dir -o Coverage/tmp/files.info - lcov --rc lcov_branch_coverage=1 --capture --directory $library_dir -o Coverage/tmp/tests.info - lcov --rc lcov_branch_coverage=1 --add-tracefile Coverage/tmp/files.info --add-tracefile Coverage/tmp/tests.info -o Coverage/tmp/all.info - lcov --rc lcov_branch_coverage=1 --remove Coverage/tmp/all.info -o Coverage/tmp/final.info '*.h' - gendesc tests/Descriptions.txt -o Coverage/tmp/descriptions - genhtml --title "$title" --description-file Coverage/tmp/descriptions --keep-descriptions --legend --branch-coverage -o Coverage Coverage/tmp/final.info - rm -f Coverage/tmp/*.info Coverage/tmp/descriptions + # Pass absolute paths as lcov output files. This works around a bug + # whereby lcov tries to create the output file in the root directory + # if it has emitted a warning. A fix was released in lcov 1.13 in 2016. + # Ubuntu 16.04 is affected, 18.04 and above are not. + # https://github.com/linux-test-project/lcov/commit/632c25a0d1f5e4d2f4fd5b28ce7c8b86d388c91f + COVTMP=$PWD/Coverage/tmp + lcov --capture --initial --directory $library_dir -o "$COVTMP/files.info" + lcov --rc lcov_branch_coverage=1 --capture --directory $library_dir -o "$COVTMP/tests.info" + lcov --rc lcov_branch_coverage=1 --add-tracefile "$COVTMP/files.info" --add-tracefile "$COVTMP/tests.info" -o "$COVTMP/all.info" + lcov --rc lcov_branch_coverage=1 --remove "$COVTMP/all.info" -o "$COVTMP/final.info" '*.h' + gendesc tests/Descriptions.txt -o "$COVTMP/descriptions" + genhtml --title "$title" --description-file "$COVTMP/descriptions" --keep-descriptions --legend --branch-coverage -o Coverage "$COVTMP/final.info" + rm -f "$COVTMP/"*.info "$COVTMP/descriptions" echo "Coverage report in: Coverage/index.html" } From 2824a209bcb7dc06c9ee61d15c998c8a4f4be21d Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Fri, 23 Feb 2024 17:51:47 +0000 Subject: [PATCH 144/211] Add ALPN information in session tickets Signed-off-by: Waleed Elmelegy --- include/mbedtls/ssl.h | 3 + library/ssl_tls.c | 82 ++++++++++++++++++++++++++-- library/ssl_tls13_server.c | 22 +++++++- tests/src/test_helpers/ssl_helpers.c | 9 ++- tests/suites/test_suite_ssl.function | 9 +++ 5 files changed, 118 insertions(+), 7 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 39bea79092..a6ee9a4487 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1312,6 +1312,9 @@ struct mbedtls_ssl_session { #if defined(MBEDTLS_SSL_EARLY_DATA) uint32_t MBEDTLS_PRIVATE(max_early_data_size); /*!< maximum amount of early data in tickets */ +#if defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C) + char *alpn; /*!< ALPN negotiated in the session */ +#endif #endif #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 681ccab441..d7d26ab063 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3735,7 +3735,25 @@ static int ssl_tls12_session_load(mbedtls_ssl_session *session, #if defined(MBEDTLS_SSL_PROTO_TLS1_3) /* Serialization of TLS 1.3 sessions: * - * For more detail, see the description of ssl_session_save(). + * 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 @@ -3750,9 +3768,16 @@ static int ssl_tls13_session_save(const mbedtls_ssl_session *session, size_t hostname_len = (session->hostname == NULL) ? 0 : strlen(session->hostname) + 1; #endif + +#if defined(MBEDTLS_SSL_SRV_C) && \ + defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) + const uint8_t alpn_len = (session->alpn == NULL) ? + 0 : (uint8_t) strlen(session->alpn) + 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) { @@ -3771,6 +3796,15 @@ static int ssl_tls13_session_save(const mbedtls_ssl_session *session, needed += 8; /* ticket_creation_time or ticket_reception_time */ #endif +#if defined(MBEDTLS_SSL_SRV_C) + if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { +#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) + needed += 1 /* alpn_len */ + + alpn_len; /* alpn */ +#endif + } +#endif /* MBEDTLS_SSL_SRV_C */ + #if defined(MBEDTLS_SSL_CLI_C) if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) { #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) @@ -3813,13 +3847,24 @@ static int ssl_tls13_session_save(const mbedtls_ssl_session *session, p += 2; #endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ -#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C) +#if defined(MBEDTLS_SSL_SRV_C) if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { +#if defined(MBEDTLS_HAVE_TIME) MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_creation_time, p, 0); p += 8; - } #endif /* MBEDTLS_HAVE_TIME */ +#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) + *p++ = alpn_len; + if (alpn_len > 0) { + /* save chosen alpn */ + memcpy(p, session->alpn, alpn_len); + p += alpn_len; + } +#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_ALPN */ + } +#endif /* MBEDTLS_SSL_SRV_C */ + #if defined(MBEDTLS_SSL_CLI_C) if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) { #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) @@ -3894,16 +3939,39 @@ static int ssl_tls13_session_load(mbedtls_ssl_session *session, p += 2; #endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ -#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C) +#if defined(MBEDTLS_SSL_SRV_C) if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { +#if defined(MBEDTLS_HAVE_TIME) 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_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) + uint8_t alpn_len; + + if (end - p < 1) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + alpn_len = *p++; + + if (end - p < alpn_len) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + if (alpn_len > 0) { + session->alpn = mbedtls_calloc(alpn_len, sizeof(char)); + if (session->alpn == NULL) { + return MBEDTLS_ERR_SSL_ALLOC_FAILED; + } + memcpy(session->alpn, p, alpn_len); + p += alpn_len; + } +#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_ALPN */ + } +#endif /* MBEDTLS_SSL_SRV_C */ + #if defined(MBEDTLS_SSL_CLI_C) if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) { #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) @@ -4848,6 +4916,10 @@ void mbedtls_ssl_session_free(mbedtls_ssl_session *session) #if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \ defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) mbedtls_free(session->hostname); +#endif +#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) && \ + defined(MBEDTLS_SSL_SRV_C) + mbedtls_free(session->alpn); #endif mbedtls_free(session->ticket); #endif diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 887c5c6c8f..291d64500d 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -467,7 +467,17 @@ static int ssl_tls13_session_copy_ticket(mbedtls_ssl_session *dst, #if defined(MBEDTLS_SSL_EARLY_DATA) dst->max_early_data_size = src->max_early_data_size; -#endif + +#if defined(MBEDTLS_SSL_ALPN) + if (src->alpn != NULL) { + dst->alpn = mbedtls_calloc(strlen(src->alpn) + 1, sizeof(char)); + if (dst->alpn == NULL) { + return MBEDTLS_ERR_SSL_ALLOC_FAILED; + } + memcpy(dst->alpn, src->alpn, strlen(src->alpn) + 1); + } +#endif /* MBEDTLS_SSL_ALPN */ +#endif /* MBEDTLS_SSL_EARLY_DATA*/ return 0; } @@ -3137,6 +3147,16 @@ static int ssl_tls13_prepare_new_session_ticket(mbedtls_ssl_context *ssl, MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags); +#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) + if (ssl->alpn_chosen != NULL) { + session->alpn = mbedtls_calloc(strlen(ssl->alpn_chosen) + 1, sizeof(char)); + if (session->alpn == NULL) { + return MBEDTLS_ERR_SSL_ALLOC_FAILED; + } + memcpy(session->alpn, ssl->alpn_chosen, strlen(ssl->alpn_chosen) + 1); + } +#endif + /* Generate ticket_age_add */ if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, (unsigned char *) &session->ticket_age_add, diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index 56e03f1090..89c1bbf522 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -1793,7 +1793,14 @@ int mbedtls_test_ssl_tls13_populate_session(mbedtls_ssl_session *session, #if defined(MBEDTLS_SSL_EARLY_DATA) session->max_early_data_size = 0x87654321; -#endif +#if defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C) + session->alpn = mbedtls_calloc(strlen("ALPNExample")+1, sizeof(char)); + if (session->alpn == NULL) { + return -1; + } + strcpy(session->alpn, "ALPNExample"); +#endif /* MBEDTLS_SSL_ALPN && MBEDTLS_SSL_SRV_C */ +#endif /* MBEDTLS_SSL_EARLY_DATA */ #if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C) if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 8cf2105a52..da07f2c62f 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -2104,6 +2104,15 @@ void ssl_serialize_session_save_load(int ticket_len, char *crt_file, #if defined(MBEDTLS_SSL_EARLY_DATA) TEST_ASSERT( original.max_early_data_size == restored.max_early_data_size); +#if defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C) + if (endpoint_type == MBEDTLS_SSL_IS_SERVER) { + TEST_ASSERT(original.alpn != NULL); + TEST_ASSERT(restored.alpn != NULL); + TEST_ASSERT(memcmp(original.alpn, + restored.alpn, + strlen(original.alpn)) == 0); + } +#endif #endif #if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) From 883f77cb08501c5fb618eb39fe5b575d7fd58374 Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Wed, 6 Mar 2024 19:09:41 +0000 Subject: [PATCH 145/211] Add mbedtls_ssl_session_set_alpn() function Signed-off-by: Waleed Elmelegy --- include/mbedtls/ssl.h | 7 ++-- library/ssl_misc.h | 7 ++++ library/ssl_tls.c | 56 +++++++++++++++++++++++----- library/ssl_tls13_server.c | 19 ++++------ tests/src/test_helpers/ssl_helpers.c | 6 +-- tests/suites/test_suite_ssl.function | 9 ++--- 6 files changed, 71 insertions(+), 33 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index a6ee9a4487..b05bfe1b72 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1304,6 +1304,10 @@ struct mbedtls_ssl_session { char *MBEDTLS_PRIVATE(hostname); /*!< host name binded with tickets */ #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION && MBEDTLS_SSL_CLI_C */ +#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C) + char *ticket_alpn; /*!< ALPN negotiated in the session */ +#endif + #if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_CLI_C) /*! Time in milliseconds when the last ticket was received. */ mbedtls_ms_time_t MBEDTLS_PRIVATE(ticket_reception_time); @@ -1312,9 +1316,6 @@ struct mbedtls_ssl_session { #if defined(MBEDTLS_SSL_EARLY_DATA) uint32_t MBEDTLS_PRIVATE(max_early_data_size); /*!< maximum amount of early data in tickets */ -#if defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C) - char *alpn; /*!< ALPN negotiated in the session */ -#endif #endif #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 2ec898b453..948c802299 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2852,6 +2852,13 @@ int mbedtls_ssl_session_set_hostname(mbedtls_ssl_session *session, const char *hostname); #endif +#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA) && \ + defined(MBEDTLS_SSL_ALPN) +MBEDTLS_CHECK_RETURN_CRITICAL +int mbedtls_ssl_session_set_alpn(mbedtls_ssl_session *session, + const char *alpn); +#endif + #if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS) #define MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME (604800) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index d7d26ab063..f78b97d444 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -2450,6 +2450,7 @@ mbedtls_ssl_mode_t mbedtls_ssl_get_mode_from_ciphersuite( #if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(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, @@ -3771,8 +3772,8 @@ static int ssl_tls13_session_save(const mbedtls_ssl_session *session, #if defined(MBEDTLS_SSL_SRV_C) && \ defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) - const uint8_t alpn_len = (session->alpn == NULL) ? - 0 : (uint8_t) strlen(session->alpn) + 1; + const uint8_t alpn_len = (session->ticket_alpn == NULL) ? + 0 : (uint8_t) strlen(session->ticket_alpn) + 1; #endif size_t needed = 4 /* ticket_age_add */ + 1 /* ticket_flags */ @@ -3858,7 +3859,7 @@ static int ssl_tls13_session_save(const mbedtls_ssl_session *session, *p++ = alpn_len; if (alpn_len > 0) { /* save chosen alpn */ - memcpy(p, session->alpn, alpn_len); + memcpy(p, session->ticket_alpn, alpn_len); p += alpn_len; } #endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_ALPN */ @@ -3951,6 +3952,7 @@ static int ssl_tls13_session_load(mbedtls_ssl_session *session, #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) uint8_t alpn_len; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; if (end - p < 1) { return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; @@ -3960,12 +3962,12 @@ static int ssl_tls13_session_load(mbedtls_ssl_session *session, if (end - p < alpn_len) { return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; } + if (alpn_len > 0) { - session->alpn = mbedtls_calloc(alpn_len, sizeof(char)); - if (session->alpn == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; + ret = mbedtls_ssl_session_set_alpn(session, (const char *) p); + if (ret != 0) { + return ret; } - memcpy(session->alpn, p, alpn_len); p += alpn_len; } #endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_ALPN */ @@ -4917,11 +4919,12 @@ void mbedtls_ssl_session_free(mbedtls_ssl_session *session) defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) mbedtls_free(session->hostname); #endif + mbedtls_free(session->ticket); +#endif + #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) && \ defined(MBEDTLS_SSL_SRV_C) - mbedtls_free(session->alpn); -#endif - mbedtls_free(session->ticket); + mbedtls_free(session->ticket_alpn); #endif mbedtls_platform_zeroize(session, sizeof(mbedtls_ssl_session)); @@ -9870,4 +9873,37 @@ int mbedtls_ssl_session_set_hostname(mbedtls_ssl_session *session, MBEDTLS_SSL_SERVER_NAME_INDICATION && MBEDTLS_SSL_CLI_C */ +#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA) && \ + defined(MBEDTLS_SSL_ALPN) +int mbedtls_ssl_session_set_alpn(mbedtls_ssl_session *session, + const char *alpn) +{ + size_t alpn_len = 0; + + if (alpn != NULL) { + alpn_len = strlen(alpn); + + if (alpn_len > MBEDTLS_SSL_MAX_ALPN_NAME_LEN) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + } + + if (session->ticket_alpn != NULL) { + mbedtls_zeroize_and_free(session->ticket_alpn, + strlen(session->ticket_alpn)); + } + + if (alpn == NULL) { + session->ticket_alpn = NULL; + } else { + session->ticket_alpn = mbedtls_calloc(strlen(alpn) + 1, sizeof(char)); + if (session->ticket_alpn == NULL) { + return MBEDTLS_ERR_SSL_ALLOC_FAILED; + } + memcpy(session->ticket_alpn, alpn, strlen(alpn) + 1); + } + + return 0; +} +#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_ALPN */ #endif /* MBEDTLS_SSL_TLS_C */ diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 291d64500d..9c73c7a1a5 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -469,12 +469,10 @@ static int ssl_tls13_session_copy_ticket(mbedtls_ssl_session *dst, dst->max_early_data_size = src->max_early_data_size; #if defined(MBEDTLS_SSL_ALPN) - if (src->alpn != NULL) { - dst->alpn = mbedtls_calloc(strlen(src->alpn) + 1, sizeof(char)); - if (dst->alpn == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - memcpy(dst->alpn, src->alpn, strlen(src->alpn) + 1); + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + ret = mbedtls_ssl_session_set_alpn(dst, src->ticket_alpn); + if (ret != 0) { + return ret; } #endif /* MBEDTLS_SSL_ALPN */ #endif /* MBEDTLS_SSL_EARLY_DATA*/ @@ -3148,12 +3146,9 @@ static int ssl_tls13_prepare_new_session_ticket(mbedtls_ssl_context *ssl, MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags); #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) - if (ssl->alpn_chosen != NULL) { - session->alpn = mbedtls_calloc(strlen(ssl->alpn_chosen) + 1, sizeof(char)); - if (session->alpn == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - memcpy(session->alpn, ssl->alpn_chosen, strlen(ssl->alpn_chosen) + 1); + ret = mbedtls_ssl_session_set_alpn(session, ssl->alpn_chosen); + if (ret != 0) { + return ret; } #endif diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index 89c1bbf522..9c1676fc63 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -1794,11 +1794,11 @@ int mbedtls_test_ssl_tls13_populate_session(mbedtls_ssl_session *session, #if defined(MBEDTLS_SSL_EARLY_DATA) session->max_early_data_size = 0x87654321; #if defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C) - session->alpn = mbedtls_calloc(strlen("ALPNExample")+1, sizeof(char)); - if (session->alpn == NULL) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + ret = mbedtls_ssl_session_set_alpn(session, "ALPNExample"); + if (ret != 0) { return -1; } - strcpy(session->alpn, "ALPNExample"); #endif /* MBEDTLS_SSL_ALPN && MBEDTLS_SSL_SRV_C */ #endif /* MBEDTLS_SSL_EARLY_DATA */ diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index da07f2c62f..e29667d0bc 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -2106,11 +2106,10 @@ void ssl_serialize_session_save_load(int ticket_len, char *crt_file, original.max_early_data_size == restored.max_early_data_size); #if defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C) if (endpoint_type == MBEDTLS_SSL_IS_SERVER) { - TEST_ASSERT(original.alpn != NULL); - TEST_ASSERT(restored.alpn != NULL); - TEST_ASSERT(memcmp(original.alpn, - restored.alpn, - strlen(original.alpn)) == 0); + TEST_ASSERT(original.ticket_alpn != NULL); + TEST_ASSERT(restored.ticket_alpn != NULL); + TEST_MEMORY_COMPARE(original.ticket_alpn, strlen(original.ticket_alpn), + restored.ticket_alpn, strlen(restored.ticket_alpn)); } #endif #endif From 11025636859e4cacf0259c0cd32c7191b74bf6b0 Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Thu, 7 Mar 2024 15:25:52 +0000 Subject: [PATCH 146/211] Add ALPN bit flag to session header Signed-off-by: Waleed Elmelegy --- library/ssl_tls.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index f78b97d444..e6023c03b8 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3736,6 +3736,7 @@ static int ssl_tls12_session_load(mbedtls_ssl_session *session, #if defined(MBEDTLS_SSL_PROTO_TLS1_3) /* Serialization of TLS 1.3 sessions: * + * For more detail, see the description of ssl_session_save(). * struct { * opaque hostname<0..2^16-1>; * uint64 ticket_reception_time; @@ -4130,6 +4131,12 @@ static int ssl_tls13_session_load(const mbedtls_ssl_session *session, #define SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE 0 #endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ +#if defined(MBEDTLS_SSL_ALPN) +#define SSL_SERIALIZED_SESSION_CONFIG_ALPN 1 +#else +#define SSL_SERIALIZED_SESSION_CONFIG_ALPN 0 +#endif /* MBEDTLS_SSL_ALPN */ + #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 @@ -4140,6 +4147,7 @@ static int ssl_tls13_session_load(const mbedtls_ssl_session *session, #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_ALPN_BIT 10 #define SSL_SERIALIZED_SESSION_CONFIG_BITFLAG \ ((uint16_t) ( \ @@ -4156,7 +4164,9 @@ static int ssl_tls13_session_load(const mbedtls_ssl_session *session, (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))) + SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE_BIT) | \ + (SSL_SERIALIZED_SESSION_CONFIG_ALPN << \ + SSL_SERIALIZED_SESSION_CONFIG_ALPN_BIT))) static const unsigned char ssl_serialized_session_header[] = { MBEDTLS_VERSION_MAJOR, From fe9ae085e384e95f0ee85cf8d6a6355ed43f73a6 Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Thu, 7 Mar 2024 15:47:31 +0000 Subject: [PATCH 147/211] Update serialized session description with ALPN information Signed-off-by: Waleed Elmelegy --- library/ssl_tls.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index e6023c03b8..ae42cf350c 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3737,25 +3737,6 @@ static int ssl_tls12_session_load(mbedtls_ssl_session *session, /* Serialization of TLS 1.3 sessions: * * For more detail, see the description of ssl_session_save(). - * 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 @@ -4244,6 +4225,10 @@ static const unsigned char ssl_serialized_session_header[] = { * #if defined(MBEDTLS_HAVE_TIME) * case server: uint64 ticket_creation_time; * #endif + * #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) + * uint8 alpn_len; + * opaque ticket_alpn<0..255>; + * #endif * }; * } serialized_session_tls13; * From 75e33fa12e24ee4e930b45c5b8d69c35aa152e39 Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Thu, 7 Mar 2024 16:57:58 +0000 Subject: [PATCH 148/211] Fix code style in ssl_tls.c Signed-off-by: Waleed Elmelegy --- library/ssl_tls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index ae42cf350c..de0057df90 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -4146,7 +4146,7 @@ static int ssl_tls13_session_load(const mbedtls_ssl_session *session, SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA_BIT) | \ (SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE << \ SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE_BIT) | \ - (SSL_SERIALIZED_SESSION_CONFIG_ALPN << \ + (SSL_SERIALIZED_SESSION_CONFIG_ALPN << \ SSL_SERIALIZED_SESSION_CONFIG_ALPN_BIT))) static const unsigned char ssl_serialized_session_header[] = { From 7dfba344752ba39b5c539d80964ccb0403133146 Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Tue, 12 Mar 2024 16:22:39 +0000 Subject: [PATCH 149/211] Fix possible overflow in ALPN length when saving session Signed-off-by: Waleed Elmelegy --- library/ssl_tls.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index de0057df90..3ee2538b65 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -2450,7 +2450,6 @@ mbedtls_ssl_mode_t mbedtls_ssl_get_mode_from_ciphersuite( #if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(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, @@ -3755,7 +3754,7 @@ static int ssl_tls13_session_save(const mbedtls_ssl_session *session, #if defined(MBEDTLS_SSL_SRV_C) && \ defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) const uint8_t alpn_len = (session->ticket_alpn == NULL) ? - 0 : (uint8_t) strlen(session->ticket_alpn) + 1; + 0 : (uint8_t) strlen(session->ticket_alpn); #endif size_t needed = 4 /* ticket_age_add */ + 1 /* ticket_flags */ @@ -3934,7 +3933,6 @@ static int ssl_tls13_session_load(mbedtls_ssl_session *session, #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) uint8_t alpn_len; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; if (end - p < 1) { return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; @@ -3945,11 +3943,20 @@ static int ssl_tls13_session_load(mbedtls_ssl_session *session, return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; } + if (alpn_len > MBEDTLS_SSL_MAX_ALPN_NAME_LEN) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + if (alpn_len > 0) { - ret = mbedtls_ssl_session_set_alpn(session, (const char *) p); - if (ret != 0) { - return ret; + if (session->ticket_alpn != NULL) { + mbedtls_zeroize_and_free(session->ticket_alpn, + strlen(session->ticket_alpn)); } + session->ticket_alpn = mbedtls_calloc(alpn_len + 1, sizeof(char)); + if (session->ticket_alpn == NULL) { + return MBEDTLS_ERR_SSL_ALLOC_FAILED; + } + memcpy(session->ticket_alpn, p, alpn_len); p += alpn_len; } #endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_ALPN */ @@ -4112,7 +4119,8 @@ static int ssl_tls13_session_load(const mbedtls_ssl_session *session, #define SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE 0 #endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */ -#if defined(MBEDTLS_SSL_ALPN) +#if defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C) && \ + defined(MBEDTLS_SSL_EARLY_DATA) #define SSL_SERIALIZED_SESSION_CONFIG_ALPN 1 #else #define SSL_SERIALIZED_SESSION_CONFIG_ALPN 0 @@ -4222,11 +4230,11 @@ static const unsigned char ssl_serialized_session_header[] = { * #endif * select ( endpoint ) { * case client: ClientOnlyData; + * case server: * #if defined(MBEDTLS_HAVE_TIME) - * case server: uint64 ticket_creation_time; + * uint64 ticket_creation_time; * #endif * #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) - * uint8 alpn_len; * opaque ticket_alpn<0..255>; * #endif * }; @@ -9870,8 +9878,8 @@ int mbedtls_ssl_session_set_hostname(mbedtls_ssl_session *session, #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA) && \ defined(MBEDTLS_SSL_ALPN) -int mbedtls_ssl_session_set_alpn(mbedtls_ssl_session *session, - const char *alpn) +int mbedtls_ssl_session_set_ticket_alpn(mbedtls_ssl_session *session, + const char *alpn) { size_t alpn_len = 0; @@ -9886,16 +9894,15 @@ int mbedtls_ssl_session_set_alpn(mbedtls_ssl_session *session, if (session->ticket_alpn != NULL) { mbedtls_zeroize_and_free(session->ticket_alpn, strlen(session->ticket_alpn)); + session->ticket_alpn = NULL; } - if (alpn == NULL) { - session->ticket_alpn = NULL; - } else { - session->ticket_alpn = mbedtls_calloc(strlen(alpn) + 1, sizeof(char)); + if (alpn != NULL) { + session->ticket_alpn = mbedtls_calloc(alpn_len + 1, 1); if (session->ticket_alpn == NULL) { return MBEDTLS_ERR_SSL_ALLOC_FAILED; } - memcpy(session->ticket_alpn, alpn, strlen(alpn) + 1); + memcpy(session->ticket_alpn, alpn, alpn_len); } return 0; From 5bc5263b2c501eadd9ae820a985a9c1b575a3fd4 Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Tue, 12 Mar 2024 16:25:08 +0000 Subject: [PATCH 150/211] Add code improvments and refactoring in dealing with ALPN Signed-off-by: Waleed Elmelegy --- include/mbedtls/ssl.h | 3 ++- library/ssl_misc.h | 4 ++-- library/ssl_tls13_server.c | 11 ++++++----- tests/src/test_helpers/ssl_helpers.c | 3 +-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index b05bfe1b72..57d7bc67eb 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1305,7 +1305,8 @@ struct mbedtls_ssl_session { #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION && MBEDTLS_SSL_CLI_C */ #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C) - char *ticket_alpn; /*!< ALPN negotiated in the session */ + char *ticket_alpn; /*!< ALPN negotiated in the session + during which the ticket was generated. */ #endif #if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_CLI_C) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 948c802299..a8807f67c6 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2855,8 +2855,8 @@ int mbedtls_ssl_session_set_hostname(mbedtls_ssl_session *session, #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA) && \ defined(MBEDTLS_SSL_ALPN) MBEDTLS_CHECK_RETURN_CRITICAL -int mbedtls_ssl_session_set_alpn(mbedtls_ssl_session *session, - const char *alpn); +int mbedtls_ssl_session_set_ticket_alpn(mbedtls_ssl_session *session, + const char *alpn); #endif #if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 9c73c7a1a5..9453c69392 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -469,8 +469,7 @@ static int ssl_tls13_session_copy_ticket(mbedtls_ssl_session *dst, dst->max_early_data_size = src->max_early_data_size; #if defined(MBEDTLS_SSL_ALPN) - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - ret = mbedtls_ssl_session_set_alpn(dst, src->ticket_alpn); + int ret = mbedtls_ssl_session_set_ticket_alpn(dst, src->ticket_alpn); if (ret != 0) { return ret; } @@ -3146,9 +3145,11 @@ static int ssl_tls13_prepare_new_session_ticket(mbedtls_ssl_context *ssl, MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags); #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) - ret = mbedtls_ssl_session_set_alpn(session, ssl->alpn_chosen); - if (ret != 0) { - return ret; + if (session->ticket_alpn == NULL) { + ret = mbedtls_ssl_session_set_ticket_alpn(session, ssl->alpn_chosen); + if (ret != 0) { + return ret; + } } #endif diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index 9c1676fc63..963938f1f8 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -1794,8 +1794,7 @@ int mbedtls_test_ssl_tls13_populate_session(mbedtls_ssl_session *session, #if defined(MBEDTLS_SSL_EARLY_DATA) session->max_early_data_size = 0x87654321; #if defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C) - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - ret = mbedtls_ssl_session_set_alpn(session, "ALPNExample"); + int ret = mbedtls_ssl_session_set_ticket_alpn(session, "ALPNExample"); if (ret != 0) { return -1; } From daa4da781ad32d1c44e72f5299504b21ecd37974 Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Wed, 13 Mar 2024 16:25:34 +0000 Subject: [PATCH 151/211] Increase ALPN length in saved session to 2 bytes Signed-off-by: Waleed Elmelegy --- library/ssl_tls.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 3ee2538b65..1e257e2099 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3753,8 +3753,8 @@ static int ssl_tls13_session_save(const mbedtls_ssl_session *session, #if defined(MBEDTLS_SSL_SRV_C) && \ defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) - const uint8_t alpn_len = (session->ticket_alpn == NULL) ? - 0 : (uint8_t) strlen(session->ticket_alpn); + const size_t alpn_len = (session->ticket_alpn == NULL) ? + 0 : strlen(session->ticket_alpn) + 1; #endif size_t needed = 4 /* ticket_age_add */ + 1 /* ticket_flags */ @@ -3781,7 +3781,7 @@ static int ssl_tls13_session_save(const mbedtls_ssl_session *session, #if defined(MBEDTLS_SSL_SRV_C) if (session->endpoint == MBEDTLS_SSL_IS_SERVER) { #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) - needed += 1 /* alpn_len */ + needed += 2 /* alpn_len */ + alpn_len; /* alpn */ #endif } @@ -3837,7 +3837,9 @@ static int ssl_tls13_session_save(const mbedtls_ssl_session *session, #endif /* MBEDTLS_HAVE_TIME */ #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) - *p++ = alpn_len; + MBEDTLS_PUT_UINT16_BE(alpn_len, p, 0); + p += 2; + if (alpn_len > 0) { /* save chosen alpn */ memcpy(p, session->ticket_alpn, alpn_len); @@ -3932,31 +3934,24 @@ static int ssl_tls13_session_load(mbedtls_ssl_session *session, #endif /* MBEDTLS_HAVE_TIME */ #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) - uint8_t alpn_len; + size_t alpn_len; - if (end - p < 1) { - return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; - } - alpn_len = *p++; - - if (end - p < alpn_len) { + if (end - p < 2) { return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; } - if (alpn_len > MBEDTLS_SSL_MAX_ALPN_NAME_LEN) { + alpn_len = MBEDTLS_GET_UINT16_BE(p, 0); + p += 2; + + if (end - p < (long int) alpn_len) { return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; } if (alpn_len > 0) { - if (session->ticket_alpn != NULL) { - mbedtls_zeroize_and_free(session->ticket_alpn, - strlen(session->ticket_alpn)); + int ret = mbedtls_ssl_session_set_ticket_alpn(session, (char *) p); + if (ret != 0) { + return ret; } - session->ticket_alpn = mbedtls_calloc(alpn_len + 1, sizeof(char)); - if (session->ticket_alpn == NULL) { - return MBEDTLS_ERR_SSL_ALLOC_FAILED; - } - memcpy(session->ticket_alpn, p, alpn_len); p += alpn_len; } #endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_ALPN */ @@ -4235,7 +4230,7 @@ static const unsigned char ssl_serialized_session_header[] = { * uint64 ticket_creation_time; * #endif * #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) - * opaque ticket_alpn<0..255>; + * opaque ticket_alpn<0..256>; * #endif * }; * } serialized_session_tls13; From b28ab0a45a40e80f974fe888c8aec21f222fbd9a Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Wed, 13 Mar 2024 16:48:28 +0000 Subject: [PATCH 152/211] Fix code style in ssl_tls.c Signed-off-by: Waleed Elmelegy --- library/ssl_tls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 1e257e2099..ac8e0ea437 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3754,7 +3754,7 @@ static int ssl_tls13_session_save(const mbedtls_ssl_session *session, #if defined(MBEDTLS_SSL_SRV_C) && \ defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) const size_t alpn_len = (session->ticket_alpn == NULL) ? - 0 : strlen(session->ticket_alpn) + 1; + 0 : strlen(session->ticket_alpn) + 1; #endif size_t needed = 4 /* ticket_age_add */ + 1 /* ticket_flags */ From 7b8b696790f0e6777e6c5b309dbc6d30a96f8d4d Mon Sep 17 00:00:00 2001 From: BensonLiou Date: Thu, 14 Mar 2024 18:11:09 +0800 Subject: [PATCH 153/211] Add change log Signed-off-by: BensonLiou --- ChangeLog.d/fix-new-rn-on-hrr.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 ChangeLog.d/fix-new-rn-on-hrr.txt diff --git a/ChangeLog.d/fix-new-rn-on-hrr.txt b/ChangeLog.d/fix-new-rn-on-hrr.txt new file mode 100644 index 0000000000..1b4f5e6a8c --- /dev/null +++ b/ChangeLog.d/fix-new-rn-on-hrr.txt @@ -0,0 +1,3 @@ +Bugfix + * In TLS 1.3 clients, fix an interoperability problem due to the client + generating a new random after a HelloRetryRequest. Fixes #8669. From c9515600fd22ae12b9bb42d562ba55d0195fae76 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 14 Mar 2024 13:20:36 +0000 Subject: [PATCH 154/211] Fix state transition diagram This now represents the implemented model Signed-off-by: Ryan Everett --- .../key-slot-state-transitions.png | Bin 70492 -> 71568 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/architecture/psa-thread-safety/key-slot-state-transitions.png b/docs/architecture/psa-thread-safety/key-slot-state-transitions.png index 34cc79b3596d12a8e4e98ffbbb5620d0c7c8221c..1b50e7395d78051d20524568475128ea82228aa7 100644 GIT binary patch delta 48599 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 G^#1^VphQss literal 70492 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 Date: Thu, 14 Mar 2024 15:05:09 +0100 Subject: [PATCH 155/211] tls13: Use a flag not a counter for CCS and HRR handling Reconcile with 5fbd27055d15c8ac234a229389ff4e31977487a0 on another branch Signed-off-by: Gilles Peskine --- library/ssl_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ssl_client.c b/library/ssl_client.c index 371c06c974..345e608938 100644 --- a/library/ssl_client.c +++ b/library/ssl_client.c @@ -793,7 +793,7 @@ static int ssl_prepare_client_hello(mbedtls_ssl_context *ssl) #endif { #if defined(MBEDTLS_SSL_PROTO_TLS1_3) - if (ssl->handshake->hello_retry_request_count == 0) + if (!ssl->handshake->hello_retry_request_flag) #endif { ret = ssl_generate_random(ssl); From d4d6a7a20d3feeef8f64e59d083713eba70ea391 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 14 Mar 2024 13:21:34 +0000 Subject: [PATCH 156/211] Rework and update psa-thread-safety.md I have restructured this file, and updated it to reflect changes in design/designs now being implemented. Signed-off-by: Ryan Everett --- .../psa-thread-safety/psa-thread-safety.md | 721 ++++++++---------- 1 file changed, 314 insertions(+), 407 deletions(-) diff --git a/docs/architecture/psa-thread-safety/psa-thread-safety.md b/docs/architecture/psa-thread-safety/psa-thread-safety.md index dc5d7e1894..06b317f490 100644 --- a/docs/architecture/psa-thread-safety/psa-thread-safety.md +++ b/docs/architecture/psa-thread-safety/psa-thread-safety.md @@ -1,450 +1,357 @@ -# Thread safety of the PSA subsystem +# Thread-safety of the PSA subsystem -Currently PSA Crypto API calls in Mbed TLS releases are not thread-safe. In Mbed TLS 3.6 we are planning to add a minimal support for thread-safety of the PSA Crypto API (see section [Strategy for 3.6](#strategy-for-36)). +Currently, PSA Crypto API calls in Mbed TLS releases are not thread-safe. -In the [Design analysis](#design-analysis) section we analyse design choices. This discussion is not constrained to what is planned for 3.6 and considers future developments. It also leaves some questions open and discusses options that have been (or probably will be) rejected. +As of Mbed TLS 3.6, an MVP for making the [PSA Crypto key management API](https://arm-software.github.io/psa-api/crypto/1.1/api/keys/management.html) and [`psa_crypto_init`](https://arm-software.github.io/psa-api/crypto/1.1/api/library/library.html#c.psa_crypto_init) thread-safe has been implemented. Implementations which only ever call PSA functions from a single thread are not affected by this new feature. -## Design analysis +Summary of recent work: -This section explores possible designs and does not reflect what is currently implemented. +- Key Store: + - Slot states are described in the [Key slot states](#key-slot-states) section. They guarantee safe concurrent access to slot contents. + - Key slots are protected by a global mutex, as described in [Key store consistency and abstraction function](#key-store-consistency-and-abstraction-function). + - Key destruction strategy abiding by [Key destruction guarantees](#key-destruction-guarantees), with an implementation discussed in [Key destruction implementation](#key-destruction-implementation). +- The main `global_data` (the one in `psa_crypto.c`) is protected by its own mutex as described in the [Global data](#global-data) section. +- The testing system has now been made thread-safe. Tests can now spin up multiple threads, see [Thread-safe testing](#thread-safe-testing) for details. +- Some multithreaded testing of the key management API has been added, this is outlined in [Testing-and-analysis](#testing-and-analysis). +- The solution uses the pre-existing `MBEDTLS_THREADING_C` threading abstraction. +- The core makes no additional guarantees for drivers. See [Driver policy](#driver-policy) for details. -### Requirements +The usage of keys within other PSA Crypto APIs is planned to be made thread-safe in future, but currently we are not testing this. -#### Backward compatibility requirement +## Overview of the document -Code that is currently working must keep working. There can be an exception for code that uses features that are advertised as experimental; for example, it would be annoying but ok to add extra requirements for drivers. +* The [Guarantees](#guarantees) section describes the properties that are followed when PSA functions are invoked by multiple threads. +* The [Usage guide](#usage-guide) section gives guidance on initializing, using and freeing PSA when using multiple threads. +* The [Current strategy](#current-strategy) section describes how thread-safety of key management and `global_data` is achieved. +* The [Testing and analysis](#testing-and-analysis) section discusses the state of our testing, as well as how this testing will be extended in future. +* The [Future work](#future-work) section outlines our long-term goals for thread-safety; it also analyses how we might go about achieving these goals. -(In this section, “currently” means Mbed TLS releases without proper concurrency management: 3.0.0, 3.1.0, and any other subsequent 3.x version.) +## Definitions -In particular, if you either protect all PSA calls with a mutex, or only ever call PSA functions from a single thread, your application currently works and must keep working. If your application currently builds and works with `MBEDTLS_PSA_CRYPTO_C` and `MBEDTLS_THREADING_C` enabled, it must keep building and working. +*Concurrent calls* -As a consequence, we must not add a new platform requirement beyond mutexes for the base case. It would be ok to add new platform requirements if they're only needed for PSA drivers, or if they're only performance improvements. +The PSA specification defines concurrent calls as: "In some environments, an application can make calls to the Crypto API in separate threads. In such an environment, concurrent calls are two or more calls to the API whose execution can overlap in time." (https://arm-software.github.io/psa-api/crypto/1.1/overview/conventions.html#concurrent-calls). -Tempting platform requirements that we cannot add to the default `MBEDTLS_THREADING_C` include: +*Thread-safety* -* Releasing a mutex from a different thread than the one that acquired it. This isn't even guaranteed to work with pthreads. -* New primitives such as semaphores or condition variables. +In general, a system is thread-safe if any valid set of concurrent calls is handled as if the effect and return code of every call is equivalent to some sequential ordering. We implement a weaker notion of thread-safety, we only guarantee thread-safety in the circumstances described in the [PSA Concurrent calling conventions](#psa-concurrent-calling-conventions) section. -#### Correctness out of the box +## Guarantees -If you build with `MBEDTLS_PSA_CRYPTO_C` and `MBEDTLS_THREADING_C`, the code must be functionally correct: no race conditions, deadlocks or livelocks. +### Correctness out of the box -The [PSA Crypto API specification](https://armmbed.github.io/mbed-crypto/html/overview/conventions.html#concurrent-calls) defines minimum expectations for concurrent calls. They must work as if they had been executed one at a time (excluding resource-management errors), except that the following cases have undefined behavior: +Building with `MBEDTLS_PSA_CRYPTO_C` and `MBEDTLS_THREADING_C` gives code which is correct; there are no race-conditions, deadlocks or livelocks when concurrently calling any set of PSA key management functions once `psa_crypto_init` has been called (see the [Initialization](#initialization) section for details on how to correctly initialize the PSA subsystem when using multiple threads). -* Destroying a key while it's in use. -* Concurrent calls using the same operation object. (An operation object may not be used by more than one thread at a time. But it can move from one thread to another between calls.) -* Overlap of an output buffer with an input or output of a concurrent call. -* Modification of an input buffer during a call. +We do not test or support calling other PSA API functions concurrently. -Note that while the specification does not define the behavior in such cases, Mbed TLS can be used as a crypto service. It's acceptable if an application can mess itself up, but it is not acceptable if an application can mess up the crypto service. As a consequence, destroying a key while it's in use may violate the security property that all key material is erased as soon as `psa_destroy_key` returns, but it may not cause data corruption or read-after-free inside the key store. +There is no busy-waiting in our implementation, every API call completes in a finite number of steps regardless of the locking policy of the underlying mutexes. -#### No spinning +When only considering key management functions: Mbed TLS 3.6 abides by the minimum expectation for concurrent calls set by the PSA specification (see [PSA Concurrent calling conventions](#psa-concurrent-calling-conventions)). -The code must not spin on a potentially non-blocking task. For example, this is proscribed: -``` -lock(m); -while (!its_my_turn) { - unlock(m); - lock(m); -} -``` +#### PSA Concurrent calling conventions -Rationale: this can cause battery drain, and can even be a livelock (spinning forever), e.g. if the thread that might unblock this one has a lower priority. +These are the conventions which are planned to be added to the PSA 1.2 specification, Mbed TLS 3.6 abides by these when only considering [key management functions](https://arm-software.github.io/psa-api/crypto/1.1/api/keys/management.html): -#### Driver requirements +> The result of two or more concurrent calls must be consistent with the same set of calls being executed sequentially in some order, provided that the calls obey the following constraints: +> +> * There is no overlap between an output parameter of one call and an input or output parameter of another call. Overlap between input parameters is permitted. +> +> * A call to :code:`psa_destroy_key()` must not overlap with a concurrent call to any of the following functions: +> - Any call where the same key identifier is a parameter to the call. +> - Any call in a multi-part operation, where the same key identifier was used as a parameter to a previous step in the multi-part operation. +> +> * Concurrent calls must not use the same operation object. +> +> If any of these constraints are violated, the behaviour is undefined. +> +> The consistency requirement does not apply to errors that arise from resource failures or limitations. For example, errors resulting from resource exhaustion can arise in concurrent execution that do not arise in sequential execution. +> +> As an example of this rule: suppose two calls are executed concurrently which both attempt to create a new key with the same key identifier that is not already in the key store. Then: +> * If one call returns :code:`PSA_ERROR_ALREADY_EXISTS`, then the other call must succeed. +> * If one of the calls succeeds, then the other must fail: either with :code:`PSA_ERROR_ALREADY_EXISTS` or some other error status. +> * Both calls can fail with error codes that are not :code:`PSA_ERROR_ALREADY_EXISTS`. +> +> If the application concurrently modifies an input parameter while a function call is in progress, the behaviour is undefined. -At the time of writing, the driver interface specification does not consider multithreaded environments. +### Backwards compatibility -We need to define clear policies so that driver implementers know what to expect. Here are two possible policies at two ends of the spectrum; what is desirable is probably somewhere in between. +Code which was working prior to Mbed TLS 3.6 will still work. Implementations which only ever call PSA functions from a single thread, or which protect all PSA calls using a mutex, are not affected by this new feature. If an application previously worked with a 3.X version, it will still work on version 3.6. -* **Policy 1:** Driver entry points may be called concurrently from multiple threads, even if they're using the same key, and even including destroying a key while an operation is in progress on it. -* **Policy 2:** At most one driver entry point is active at any given time. +### Supported threading implementations -Combining the two we arrive at **Policy 3**: +Currently, the only threading library with support shipped in the code base is pthread (enabled by `MBEDTLS_THREADING_PTHREAD`). The only concurrency primitives we use are mutexes, see [Condition variables](#condition-variables) for discussion about implementing new primitives in future major releases. + +Users can add support to any platform which has mutexes using the Mbed TLS platform abstraction layer (see `include/mbedtls/threading.h` for details). + +We intend to ship support for other platforms including Windows in future releases. + +### Key destruction guarantees + +Much like all other API calls, `psa_destroy_key` does not block indefinitely, and when `psa_destroy_key` returns: + +1. The key identifier does not exist. This is a functional requirement for persistent keys: any thread can immediately create a new key with the same identifier. +2. The resources from the key have been freed. This allows threads to create similar keys immediately after destruction, regardless of resources. + +When `psa_destroy_key` is called on a key that is in use, guarantee 2 may be violated. This is consistent with the PSA specification requirements, as destruction of a key in use is undefined. + +In future versions we aim to enforce stronger requirements for key destruction, see [Long term key destruction requirements](#long-term-key-destruction-requirements) for details. + +### Driver policy + +The core makes no additional guarantees for drivers. Driver entry points may be called concurrently from multiple threads. Threads can concurrently call entry points using the same key, there is also no protection from destroying a key which is in use. + +### Random number generators + +The PSA RNG can be accessed both from various PSA functions, and from application code via `mbedtls_psa_get_random`. + +When using the built-in RNG implementations, i.e. when `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is disabled, querying the RNG is thread-safe (`init` and `seed` are only thread-safe when called as part of `psa_crypto_init`, but not when called directly. `free` is not thread-safe). + +When `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is enabled, thread-safety depends on the implementation. + +## Usage guide + +### Initialization + +The PSA subsystem is initialized via a call to [`psa_crypto_init`](https://arm-software.github.io/psa-api/crypto/1.1/api/library/library.html#c.psa_crypto_init). This is a thread-safe function, and multiple calls to `psa_crypto_init` are explicitly allowed. It is valid to have multiple threads each calling `psa_crypto_init` followed by a call to any PSA key management function (if the init succeeds). + +### General usage + +Once initialized, threads can use any PSA function if there is no overlap between their calls. All threads share the same set of keys, as soon as one thread returns from creating/loading a key via a key management API call the key can be used by any thread. If multiple threads attempt to load the same persistent key, with the same key identifier, only one thread can succeed - the others will return `PSA_ERROR_ALREADY_EXISTS`. + +Applications may need careful handling of resource management errors. As explained in ([PSA Concurrent calling conventions](#psa-concurrent-calling-conventions)) operations in progress can have memory related side effects, it is possible for a lack of resources to cause errors which do not arise in sequential execution. For example, multiple threads attempting to load the same persistent key can lead to some threads returning `PSA_ERROR_INSUFFICIENT_MEMORY` if the key is not currently in the key store - while trying to load a persistent key into the key store a thread temporarily reserves a free key slot. + +If a mutex operation fails, which only happens if the mutex implementation fails, the error code `PSA_ERROR_SERVICE_FAILURE` will be returned. If this code is returned, execution of the PSA subsystem must be stopped. All functions which have internal mutex locks and unlocks (except for when the lock/unlock occurs in a function that has no return value) will return with this error code in this situation. + +### Freeing + +There is no thread-safe way to free all PSA resources. This is because any such operation would need to wait for all other threads to complete their tasks before wiping resources. + +`mbedtls_psa_crypto_free` must only be called by a single thread once all threads have completed their operations. + +## Current strategy + +This section describes how we have implemented thread-safety. There is discussion of: techniques, internal properties for enforcing thread-safe access, how the system stays consistent and our abstraction model. + +### Protected resources + +#### Global data + +We have added a mutex `mbedtls_threading_psa_globaldata_mutex` defined in `include/mbedtls/threading.h`, which is used to make `psa_crypto_init` thread-safe. + +There are two `psa_global_data_t` structs, each with a single instance `global_data`: + +* The struct in `library/psa_crypto.c` is protected by `mbedtls_threading_psa_globaldata_mutex`. The RNG fields within this struct are not protected by this mutex, and are not always thread-safe (see [Random number generators](#random-number-generators)). +* The struct in `library/psa_crypto_slot_management.c` has two fields: `key_slots` is protected as described in [Key slots](#key-slots), `key_slots_initialized` is protected by the global data mutex. + +#### Key slots + +Keys are stored internally in a global array of key slots known as the "key store", defined in `library/psa_slot_management.c`. + +##### Key slot states + +Each key slot has a state variable and a `registered_readers` counter. These two variables dictate whether an operation can access a slot, and in what way the slot can be used. + +There are four possible states for a key slot: + +* `PSA_SLOT_EMPTY`: no thread is currently accessing the slot, and no information is stored in the slot. Any thread is able to change the slot's state to `PSA_SLOT_FILLING` and begin to load data into the slot. +* `PSA_SLOT_FILLING`: one thread is currently loading or creating material to fill the slot, this thread is responsible for the next state transition. Other threads cannot read the contents of a slot which is in this state. +* `PSA_SLOT_FULL`: the slot contains a key, and any thread is able to use the key after registering as a reader, increasing `registered_readers` by 1. +* `PSA_SLOT_PENDING_DELETION`: the key within the slot has been destroyed or marked for destruction, but at least one thread is still registered as a reader (`registered_readers > 0`). No thread can register to read this slot. The slot must not be wiped until the last reader unregisters. It is during the last unregister that the contents of the slot are wiped, and the slot's state is set to `PSA_SLOT_EMPTY`. + +###### Key slot state transition diagram +![](key-slot-state-transitions.png) + +In the state transition diagram above, an arrow between two states `q1` and `q2` with label `f` indicates that if the state of a slot is `q1` immediately before `f`'s linearization point, it may be `q2` immediately after `f`'s linearization point. The `PSA_SLOT_PENDING_DELETION -> PSA_SLOT_EMPTY` transition can be done by any function which calls `psa_unregister_read`. + +The state transition diagram can be generated in https://app.diagrams.net/ via this [url](https://viewer.diagrams.net/?tags=%7B%7D&highlight=0000ff&edit=_blank&layers=1&nav=1#R3VxLd5s4FP4ts%2FAyOUjiuazrJJPW7aQn7UzTjQ8F2VaLgQP4lV8%2FwjyMBMaCgEOaRQ8S0gV0rz599%2BGO0PvV7i4w%2FeUnz8bOCEr2boQmIwh1JNF%2F44590iFrKOlYBMROusCx45E847QznbdYExuHzMDI85yI%2BGyn5bkutiKmzwwCb8sOm3sO%2B1TfXOBSx6NlOuXe%2F4gdLdPPgtqx%2F29MFsvsyUA1kjsrMxucfkm4NG1vW%2BhCNyP0PvC8KLla7d5jJ167bF2Sebcn7uYvFmA3EpnwAzxP5%2F%2Fef9h%2BMVx3PH765f%2F6eJUqY2M66%2FSDR1B1qLyxTTb0chFf3n6bTrNuKr9wp2Lw0gxnATZtHITZ3Z8BP56XclifaJ8tOn1xql%2FaGG%2BXJMKPvmnFd7bUwuInRCuHtgC9NEM%2FUfqc7LCdiyouSrpOGxxEeFfoShfpDnsrHAV7OiS9K%2BupwlKLVaW0vS3oP%2B1aFlSf9ZmpxS1yyUel0ItULw10BECFkvgVc%2B13sbXTluWYYUgsdqECb%2B3a8QpNJNqiixPsv6e3Do2nYmOyK46b7LPWjkT5JHr9VOg%2FTokb2YyT2gi9dWDh83YZmcECRzXj5GQctpldXNZtQXdKhe6yvgA7ZkQ27N6vUmj6hAeP0C87aTqKytlE8t3prOJe5QVpxrVR%2BNMZsTLixCbLVBJ7sLZ8EV5ggLBkgH5oztZugBckjHBw2PBlm6RKmZo%2F6XnA7lmHLNzYTqlR4IB2xFuTUMR9l95YEduOZYwDHJJn8%2BdBXmxOfvyBh09WxiNlUmlg9TuIB4H83EifwkBzFThI11DSDEYbV%2FBltpOJAdwUbz4PcT%2F6FAH9m08PX5%2FeJoIPDsCNzgE8hWKpAMWgFopzyJeKkC%2Bdgfz2AA4FARwMC8BZyykBrTB%2BnzkHegbsjHJygD03iTP7jfczi%2BJ1RDx3yJCd7ZkhQnYqGTJC%2Bfn94Xf5OL69n07vP98NGoaR%2BsowLIsce418nb%2F%2BOGfn1ZWkiCjp4ebz5GDugnqa3Exvvt7%2F8%2Flt6mhwfEbri86Ie5btPNj2dCYLPZ2jM3BQdAZK9PDTZagB6lHKisqegoqsXmtA0aCuKbSBOPGiXAeoHGmSL0t2dBHEiOkP5SY42ODZPMD4QINCx4uEMSSWENJPiTgG1RZRBsO0st08RKKVi5Evxa1AFUvoHtyulTbeWjLrVf21YQXcYoCTpAzgVIpFLBSBOIyWIRzSJa0dxMkSB3HU1hFnkn3H4IRhbk5cEi4rUerNYFK%2BC18MSlfUQGRDY1EJdWN8eqXUC2BUFUnmdGmt6VFn55zoctkB8ZBUe7ASzQ6gQYGVrCmMwahay%2BiSonKCeKZ%2FAouoDZj7wrB0e55%2BYYOFPU2S6t8LcuPBmfGyXiefXiRv3HbzTMayBcid5TvPeH1PHpV3DzsxBzOhi0xyowFNpGs%2FM1175njW75xozr43kmE5XnhgqY1m%2BWuq%2BOKsN8xLc5Tr4gwASGdtrZsIIMt2oXKpEwBV5e07YalF%2BBZ0wQu0tN%2BcgiwI%2B8PKKUANMlaiKC1hH5yKA12IgqIq16gShmwcRoG3fzl8dQOVg4W4fBt34HvLuso6P9k2eKH5XrFcw%2BgB4irP6e6DjJW09hxaNcfF%2FvFtWEFGxLE%2BpW3SFGmcly1Ia7uyuLKHXRM1HAKm1O6bTliTwYWMO4IUkPn3fbrOlatzkUoM4egei0Q9RvdEHWZl0MiigrbIwtVjqP0V0FVaXfbeHLQwNGmwgNJZIUYMKNnUjjkKG9%2FroxCjWq8Xqsw9Dw1tYKg9nCiCcDIwR%2BxEeKoxnECOqKj9lXdVmx2sMLtK16hUotvArdoSv5wmfRvxpPrN2kWiE%2BisW9QRkAH0SkBWlV3iNNl5RqF1oGgoeMKFx1vH85GsXUNdV2QoG7IBkY54uUySEwqBTdNgP%2F2a4lOAwb6EJqFrDUr5H6r%2FImDUCgOgiTCl%2FZv1k0OoKOge7A8i6vd7B1goKTpL6jridH2UfDyQ9W46hzNdX3zZ%2FLj9aLmuX%2FlziG5IHFO90ernVb1RONGCtmHVeyCuEEPhQ0TCkKucCVp1R%2BEqbU6YwZGV7yU1Zw1TkC4OzKhFMN3zm8ftY5Zo44BsDtUmM28d%2Bevo7aUha9GhA6RUZFDpqL44nMYIvVipHHz9VHpzu%2FrDfmYlmjIQrYQ5ppOy3NSFamMMNiJcKiIWLtXjBIkmSY%2BCOt04H57k79uncPzNDvFXcm9f3c30HghHZqc5XWhiqWz6XqyGnjOkfjkIGhLl0Fp7eRzl0KCYZTZ15PiouSZ3W1VVadJlPlOL3q912guf4qxBn97FNQgKDLWb4x1xOTjO%2F2%2BDU7R5%2FI9HkuHH%2F70F3fwP), which encodes the graph. +##### Key slot access primitives + +The state of a key slot is updated via the internal function `psa_key_slot_state_transition`. To change the state of `slot` from `expected_state` to `new_state`, when `new_state` is not `PSA_SLOT_EMPTY`, one must call `psa_key_slot_state_transition(slot, expected_state, new_state)`; if the state was not `expected_state` then `PSA_ERROR_CORRUPTION_DETECTED` is returned, this must not be a possibility in our code. The sole reason for having an expected state parameter here is to guarantee that our functions work as expected. + +Changing a slot's state to `PSA_SLOT_EMPTY` is done via `psa_wipe_key_slot`, this function wipes the entirety of the key slot. + +The reader count of a slot is incremented via `psa_register_read`, and decremented via `psa_unregister_read`. Library functions register to read a slot via the `psa_get_and_lock_key_slot_X` functions, read from the slot, then call `psa_unregister_read` to make known that they have finished reading the slot's contents. + +##### Key store consistency and abstraction function + +The key store is protected by a single global mutex `mbedtls_threading_key_slot_mutex`. + +We maintain the consistency of the key store by ensuring that all reads and writes to `slot->state` and `slot->registered_readers` are performed under `mbedtls_threading_key_slot_mutex`. All the access primitives described above must be called while the mutex is held; there is a convenience function `psa_unregister_read_under_mutex` which wraps a call to `psa_unregister_read` in a mutex lock/unlock pair. + +A thread can only traverse the key store while holding `mbedtls_threading_key_slot_mutex`, the set of keys within the key store which the thread holding the mutex can access is equivalent to the set: + + {mbedtls_svc_key_id_t k : (\exists slot := &global_data.key_slots[i]) [ + (slot->state == PSA_SLOT_FULL) && + (slot->attr.id == k)]} + +The union of this set and the set of persistent keys not currently loaded into slots is our abstraction function for the key store, any key not in this union does not currently exist (even if the key is in a slot which has a `PSA_SLOT_FILLING` or `PSA_SLOT_PENDING_DELETION` state). Attempting to start using any key which is not a member of the union will result in a `PSA_ERROR_INVALID_HANDLE` error code. + +##### Locking and unlocking the mutex + +If a lock or unlock operation fails and this is the first failure within a function, the function will return `PSA_ERROR_SERVICE_FAILURE`. If a lock or unlock operation fails after a different failure has been identified, the status code is not overwritten. + +We have defined a set of macros in `library/psa_crypto_core.h` to capture the common pattern of (un)locking the mutex and returning or jumping to an exit label upon failure. + +##### Key creation and loading + +To load a new key into a slot, the following internal utility functions are used: + +* `psa_reserve_free_key_slot` - This function, which must be called under `mbedtls_threading_key_slot_mutex`, iterates through the key store to find a slot whose state is `PSA_SLOT_EMPTY`. If found, it reserves the slot by setting its state to `PSA_SLOT_FILLING`. If not found, it will see if there are any persistent keys loaded which do not have any readers, if there are it will kick one such key out of the key store. +* `psa_start_key_creation` - This function wraps around `psa_reserve_free_key_slot`, if a slot has been found then the slot id is set. This second step is not done under the mutex, at this point the calling thread has exclusive access to the slot. +* `psa_finish_key_creation` - After the contents of the key have been loaded (again this loading is not done under the mutex), the thread calls `psa_finish_key_creation`. This function takes the mutex, checks that the key does not exist in the key store (this check cannot be done before this stage), sets the slot's state to `PSA_SLOT_FULL` and releases the mutex. Upon success, any thread is immediately able to use the new key. +* `psa_fail_key_creation` - If there is a failure at any point in the key creation stage, this clean-up function takes the mutex, wipes the slot, and releases the mutex. Immediately after this unlock, any thread can start to use the slot for another key load. + +##### Re-loading persistent keys + +As described above, persistent keys can be kicked out of the key slot array provided they are not currently being used (`registered_readers == 0`). When attempting to use a persistent key that has been kicked out of a slot, the call to `psa_get_and_lock_key_slot` will see that the key is not in a slot, call `psa_reserve_free_key_slot` and load the key back into the reserved slot. This entire sequence is done during a single mutex lock, which is necessary for thread-safety (see documentation of `psa_get_and_lock_key_slot`). + +If `psa_reserve_free_key_slot` cannot find a suitable slot, the key cannot be loaded back in. This will lead to a `PSA_ERROR_INSUFFICIENT_MEMORY` error. + +##### Using existing keys + +One-shot operations follow a standard pattern when using an existing key: + +* They call some `psa_get_and_lock_key_slot_X` function, which finds the key and registers the thread as a reader. +* They operate on the key slot, usually copying the key into a separate buffer to be used by the operation. This step is not done under the mutex. +* Once finished, they call `psa_unregister_read_under_mutex`. + +Multi-part and restartable operations each have a "setup" function where the key is inputted. This function follows the above pattern. The key is copied into the `operation` object, and the thread unregisters. They do not access the key slots again. The copy of the key will not be destroyed during a call to `psa_destroy_key`, the thread running the operation is responsible for deleting this copy in the clean-up. This may need to change to enforce the long term key requirements ([Long term key destruction requirements](#long-term-key-destruction-requirements)). + +##### Key destruction implementation + +The locking strategy here is explained in `library/psa_crypto.c`. The destroying thread (the thread calling `psa_destroy_key`) does not always wipe the key slot. The destroying thread registers to read the key, sets the slot's state to `PSA_SLOT_PENDING_DELETION`, wipes the slot from memory if the key is persistent, and then unregisters from reading the slot. + +`psa_unregister_read` internally calls `psa_wipe_key_slot` iff the slot's state is `PSA_SLOT_PENDING_DELETION` and the slot's registered reader counter is equal to 1. This implements a "last one out closes the door" approach, where the final thread to unregister from reading a destroyed key will automatically wipe the contents of the slot; this ensure that there is no corruption. + +### Linearisability of the system + +To satisfy the requirements in [Correctness out of the box](#correctness-out-of-the-box), we require our functions to be "linearisable" (under certain constraints). This means that any (constraint satisfying) set of concurrent calls are performed as if they were executed in some sequential order. + +The standard way of reasoning that this is the case is to identify a "linearization point" for each call, this is a single execution step where the function takes effect (this is usually a step in which the effects of the call become visible to other threads). If every call has a linearization point, the set of calls is equivalent to sequentially performing the calls in order of when their linearization point occurred. + +We only require linearisability to hold in the case where a resource-management error is not returned. In a set of concurrent calls, it is permitted for a call c to fail with a `PSA_ERROR_INSUFFICIENT_MEMORY` return code even if there does not exist a sequential ordering of the calls in which c returns this error. Even if such an error occurs, all calls are still required to be functionally correct. + +To help justify that our system is linearisable, here are the linearization points/planned linearization points of each PSA call : + +* Key creation functions (including `psa_copy_key`) - The linearization point for a successful call is the mutex unlock within `psa_finish_key_creation`; it is at this point that the key becomes visible to other threads. The linearization point for a failed call is the closest mutex unlock after the failure is first identified. +* `psa_destroy_key` - The linearization point for a successful destruction is the mutex unlock, the slot is now in the state `PSA_SLOT_PENDING_DELETION` meaning that the key has been destroyed. For failures, the linearization point is the same. +* `psa_purge_key`, `psa_close_key` - The linearization point is the mutex unlock after wiping the slot for a success, or unregistering for a failure. +* One shot operations - The linearization point is the final unlock of the mutex within `psa_get_and_lock_key_slot`, as that is the point in which it is decided whether the key exists. +* Multi-part operations - The linearization point of the key input function is the final unlock of the mutex within `psa_get_and_lock_key_slot`. All other steps have no non resource-related side effects (except for key derivation, covered in the key creation functions). + +Please note that one shot operations and multi-part operations are not yet considered thread-safe, as we do not test whether they rely on unprotected global resources. + +## Testing and analysis + +### Thread-safe testing + +It is now possible for individual tests to spin up multiple threads. This work has made the global variables used in tests thread-safe. If multiple threads fail a test assert, the first failure will be reported with correct line numbers. + +The `step` feature used in some tests is not thread-safe, it cannot be made thread-safe unless we introduce thread-local variables. + +### Current state of testing + +Our testing is a work in progress. It is not feasible to run our traditional, single-threaded, tests in such a way that tests concurrency. Therefore, we must write a new suite of testing. + +Our tests currently only run on pthread. + +We run tests using [ThreadSanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html) to detect data races. We test the key store, and test that our key slot state system is enforced. + +Currently, not every API call is tested, we also cannot feasibly test every combination of concurrent API calls. API calls can in general be split into a few categories, each category calling the same internal functions in the same order - it is the internal functions that are in charge of locking mutexes and interacting with the key store; we have tests which cover every category. + +Since we do not run every cryptographic operation concurrently, we do not test that operations are free of unexpected global variables, cryptographic operations are not considered thread-safe. + +### Expanding testing + +Through future work on testing, it would be good to: + +* For every API call, have a test which runs multiple copies of the call simultaneously. +* After implementing other threading platforms, expand the tests to these platforms. +* Have increased testing for kicking persistent keys out of slots. +* Explicitly test that there all global variables are protected, for this we need to cover every operation in a concurrent scenario while running ThreadSanitizer. + +### Performance + +Key loading does somewhat run in parallel, deriving the key and copying it key into the slot is not done under any mutex. + +Key destruction is entirely sequential, this is required for persistent keys to stop issues with re-loading keys which cannot otherwise be avoided without changing our approach to thread-safety. + + +## Future work + +### Long term requirements + +As explained previously, we eventually aim to make the entirety of the PSA API thread-safe. This will build on the work that we have already completed. This requires a full suite of testing, see [Expanding testing](#expanding-testing) for details. + +### Long term performance requirements + +Our plan for cryptographic operations is that they are not performed under any global mutex. One-shot operations and multi-part operations will each only hold the global mutex for finding the relevant key in the key slot, and unregistering as a reader after the operation. + +### Long term key destruction requirements + +The [PSA Crypto Key destruction specification](https://arm-software.github.io/psa-api/crypto/1.1/api/keys/management.html#key-destruction) mandates that implementations make a best effort to ensure that the key material cannot be recovered. In the long term, it would be good to guarantee that `psa_destroy_key` wipes all copies of the key material. + +Here are our long term key destruction goals: + +`psa_destroy_key` does not block indefinitely, and when `psa_destroy_key` returns: + +1. The key identifier does not exist. This is a functional requirement for persistent keys: any thread can immediately create a new key with the same identifier. +2. The resources from the key have been freed. This allows threads to create similar keys immediately after destruction, regardless of resources. +4. No copy of the key material exists. Rationale: this is a security requirement. We do not have this requirement yet, but we need to document this as a security weakness, and we would like to satisfy this security requirement in the future. + +#### Condition variables + +It would be ideal to add these to a future major version; we cannot add these as requirements to the default `MBEDTLS_THREADING_C` for backwards compatibility reasons. + +Condition variables would enable us to fulfil the final requirement in [Long term key destruction requirements](#long-term-key-destruction-requirements). Destruction would then work as follows: + + * When a thread calls `psa_destroy_key`, they continue as normal until the `psa_unregister_read` call. + * Instead of calling `psa_unregister_read`, the thread waits until the condition `slot->registered_readers == 1` is true (the destroying thread is the final reader). + * At this point, the destroying thread directly calls `psa_wipe_key_slot`. + +A few changes are needed for this to follow our destruction requirements: + + * Multi-part operations will need to remain registered as readers of their key slot until their copy of the key is destroyed, i.e. at the end of the finish/abort call. + * The functionality where `psa_unregister_read` can wipe the key slot will need to be removed, slot wiping is now only done by the destroying/wiping thread. + +### Protecting operation contexts + +Currently, we rely on the crypto service to ensure that the same operation is not invoked concurrently. This abides by the PSA Crypto API Specification ([PSA Concurrent calling conventions](#psa-concurrent-calling-conventions)). + +Concurrent access to the same operation object can compromise the crypto service. For example, if the operation context has a pointer (depending on the compiler and the platform, the pointer assignment may or may not be atomic). This violates the functional correctness requirement of the crypto service. + +If, in future, we want to protect against this within the library then operations will require a status field protected by a global mutex. On entry, API calls would check the state and return an error if the state is ACTIVE. If the state is INACTIVE, then the call will set the state to ACTIVE, do the operation section and then restore the state to INACTIVE before returning. + +### Future driver work + +A future policy we may wish to enforce for drivers is: * By default, each driver only has at most one entry point active at any given time. In other words, each driver has its own exclusive lock. * Drivers have an optional `"thread_safe"` boolean property. If true, it allows concurrent calls to this driver. * Even with a thread-safe driver, the core never starts the destruction of a key while there are operations in progress on it, and never performs concurrent calls on the same multipart operation. -#### Long-term performance requirements - -In the short term, correctness is the important thing. We can start with a global lock. - -In the medium to long term, performing a slow or blocking operation (for example, a driver call, or an RSA decryption) should not block other threads, even if they're calling the same driver or using the same key object. - -We may want to go directly to a more sophisticated approach because when a system works with a global lock, it's typically hard to get rid of it to get more fine-grained concurrency. - -#### Key destruction short-term requirements - -##### Summary of guarantees in the short term - -When `psa_destroy_key` returns: - -1. The key identifier doesn't exist. Rationale: this is a functional requirement for persistent keys: the caller can immediately create a new key with the same identifier. -2. The resources from the key have been freed. Rationale: in a low-resource condition, this may be necessary for the caller to re-create a similar key, which should be possible. -3. The call must not block indefinitely, and in particular cannot wait for an event that is triggered by application code such as calling an abort function. Rationale: this may not strictly be a functional requirement, but it is an expectation `psa_destroy_key` does not block forever due to another thread, which could potentially be another process on a multi-process system. In particular, it is only acceptable for `psa_destroy_key` to block, when waiting for another thread to complete a PSA Cryptography API call that it had already started. - -When `psa_destroy_key` is called on a key that is in use, guarantee 2. might be violated. (This is consistent with the requirement [“Correctness out of the box”](#correctness-out-of-the-box), as destroying a key while it's in use is undefined behavior.) - -#### Key destruction long-term requirements - -The [PSA Crypto API specification](https://armmbed.github.io/mbed-crypto/html/api/keys/management.html#key-destruction) mandates that implementations make a best effort to ensure that the key material cannot be recovered. In the long term, it would be good to guarantee that `psa_destroy_key` wipes all copies of the key material. - -##### Summary of guarantees in the long term - -When `psa_destroy_key` returns: - -1. The key identifier doesn't exist. Rationale: this is a functional requirement for persistent keys: the caller can immediately create a new key with the same identifier. -2. The resources from the key have been freed. Rationale: in a low-resource condition, this may be necessary for the caller to re-create a similar key, which should be possible. -3. The call must not block indefinitely, and in particular cannot wait for an event that is triggered by application code such as calling an abort function. Rationale: this may not strictly be a functional requirement, but it is an expectation `psa_destroy_key` does not block forever due to another thread, which could potentially be another process on a multi-process system. In particular, it is only acceptable for `psa_destroy_key` to block, when waiting for another thread to complete a PSA Cryptography API call that it had already started. -4. No copy of the key material exists. Rationale: this is a security requirement. We do not have this requirement yet, but we need to document this as a security weakness, and we would like to satisfy this security requirement in the future. - -As opposed to the short term requirements, all the above guarantees hold even if `psa_destroy_key` is called on a key that is in use. - -### Resources to protect - -Analysis of the behavior of the PSA key store as of Mbed TLS 9202ba37b19d3ea25c8451fd8597fce69eaa6867. - -#### Global variables - -* `psa_crypto_slot_management::global_data.key_slots[i]`: see [“Key slots”](#key-slots). - -* `psa_crypto_slot_management::global_data.key_slots_initialized`: - * `psa_initialize_key_slots`: modification. - * `psa_wipe_all_key_slots`: modification. - * `psa_get_empty_key_slot`: read. - * `psa_get_and_lock_key_slot`: read. - -* `psa_crypto::global_data.rng`: depends on the RNG implementation. See [“Random generator”](#random-generator). - * `psa_generate_random`: query. - * `mbedtls_psa_crypto_configure_entropy_sources` (only if `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is enabled): setup. Only called from `psa_crypto_init` via `mbedtls_psa_random_init`, or from test code. - * `mbedtls_psa_crypto_free`: deinit. - * `psa_crypto_init`: seed (via `mbedtls_psa_random_seed`); setup via `mbedtls_psa_crypto_configure_entropy_sources. - -* `psa_crypto::global_data.{initialized,rng_state}`: these are bit-fields and cannot be modified independently so they must be protected by the same mutex. The following functions access these fields: - * `mbedtls_psa_crypto_configure_entropy_sources` [`rng_state`] (only if `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is enabled): read. Only called from `psa_crypto_init` via `mbedtls_psa_random_init`, or from test code. - * `mbedtls_psa_crypto_free`: modification. - * `psa_crypto_init`: modification. - * Many functions via `GUARD_MODULE_INITIALIZED`: read. - -#### Key slots - -##### Key slot array traversal - -“Occupied key slot” is determined by `psa_is_key_slot_occupied` based on `slot->attr.type`. - -The following functions traverse the key slot array: - -* `psa_get_and_lock_key_slot_in_memory`: reads `slot->attr.id`. -* `psa_get_and_lock_key_slot_in_memory`: calls `psa_lock_key_slot` on one occupied slot. -* `psa_get_empty_key_slot`: calls `psa_is_key_slot_occupied`. -* `psa_get_empty_key_slot`: calls `psa_wipe_key_slot` and more modifications on one occupied slot with no active user. -* `psa_get_empty_key_slot`: calls `psa_lock_key_slot` and more modification on one unoccupied slot. -* `psa_wipe_all_key_slots`: writes to all slots. -* `mbedtls_psa_get_stats`: reads from all slots. - -##### Key slot state - -The following functions modify a slot's usage state: - -* `psa_lock_key_slot`: writes to `slot->lock_count`. -* `psa_unlock_key_slot`: writes to `slot->lock_count`. -* `psa_wipe_key_slot`: writes to `slot->lock_count`. -* `psa_destroy_key`: reads `slot->lock_count`, calls `psa_lock_key_slot`. -* `psa_wipe_all_key_slots`: writes to all slots. -* `psa_get_empty_key_slot`: writes to `slot->lock_count` and calls `psa_wipe_key_slot` and `psa_lock_key_slot` on one occupied slot with no active user; calls `psa_lock_key_slot` on one unoccupied slot. -* `psa_close_key`: reads `slot->lock_count`; calls `psa_get_and_lock_key_slot_in_memory`, `psa_wipe_key_slot` and `psa_unlock_key_slot`. -* `psa_purge_key`: reads `slot->lock_count`; calls `psa_get_and_lock_key_slot_in_memory`, `psa_wipe_key_slot` and `psa_unlock_key_slot`. - -**slot->attr access:** -`psa_crypto_core.h`: -* `psa_key_slot_set_flags` - writes to attr.flags -* `psa_key_slot_set_bits_in_flags` - writes to attr.flags -* `psa_key_slot_clear_bits` - writes to attr.flags -* `psa_is_key_slot_occupied` - reads attr.type (but see “[Determining whether a key slot is occupied](#determining-whether-a-key-slot-is-occupied)”) -* `psa_key_slot_get_flags` - reads attr.flags - -`psa_crypto_slot_management.c`: -* `psa_get_and_lock_key_slot_in_memory` - reads attr.id -* `psa_get_empty_key_slot` - reads attr.lifetime -* `psa_load_persistent_key_into_slot` - passes attr pointer to psa_load_persistent_key -* `psa_load_persistent_key` - reads attr.id and passes pointer to psa_parse_key_data_from_storage -* `psa_parse_key_data_from_storage` - writes to many attributes -* `psa_get_and_lock_key_slot` - writes to attr.id, attr.lifetime, and attr.policy.usage -* `psa_purge_key` - reads attr.lifetime, calls psa_wipe_key_slot -* `mbedtls_psa_get_stats` - reads attr.lifetime, attr.id - -`psa_crypto.c`: -* `psa_get_and_lock_key_slot_with_policy` - reads attr.type, attr.policy. -* `psa_get_and_lock_transparent_key_slot_with_policy` - reads attr.lifetime -* `psa_destroy_key` - reads attr.lifetime, attr.id -* `psa_get_key_attributes` - copies all publicly available attributes of a key -* `psa_export_key` - copies attributes -* `psa_export_public_key` - reads attr.type, copies attributes -* `psa_start_key_creation` - writes to the whole attr structure -* `psa_validate_optional_attributes` - reads attr.type, attr.bits -* `psa_import_key` - reads attr.bits -* `psa_copy_key` - reads attr.bits, attr.type, attr.lifetime, attr.policy -* `psa_mac_setup` - copies whole attr structure -* `psa_mac_compute_internal` - copies whole attr structure -* `psa_verify_internal` - copies whole attr structure -* `psa_sign_internal` - copies whole attr structure, reads attr.type -* `psa_assymmetric_encrypt` - reads attr.type -* `psa_assymetric_decrypt` - reads attr.type -* `psa_cipher_setup` - copies whole attr structure, reads attr.type -* `psa_cipher_encrypt` - copies whole attr structure, reads attr.type -* `psa_cipher_decrypt` - copies whole attr structure, reads attr.type -* `psa_aead_encrypt` - copies whole attr structure -* `psa_aead_decrypt` - copies whole attr structure -* `psa_aead_setup` - copies whole attr structure -* `psa_generate_derived_key_internal` - reads attr.type, writes to and reads from attr.bits, copies whole attr structure -* `psa_key_derivation_input_key` - reads attr.type -* `psa_key_agreement_raw_internal` - reads attr.type and attr.bits - -##### Determining whether a key slot is occupied - -`psa_is_key_slot_occupied` currently uses the `attr.type` field to determine whether a key slot is occupied. This works because we maintain the invariant that an occupied slot contains key material. With concurrency, it is desirable to allow a key slot to be reserved, but not yet contain key material or even metadata. When creating a key, determining the key type can be costly, for example when loading a persistent key from storage or (not yet implemented) when importing or unwrapping a key using an interface that determines the key type from the data that it parses. So we should not need to hold the global key store lock while the key type is undetermined. - -Instead, `psa_is_key_slot_occupied` should use the key identifier to decide whether a slot is occupied. The key identifier is always readily available: when allocating a slot for a persistent key, it's an input of the function that allocates the key slot; when allocating a slot for a volatile key, the identifier is calculated from the choice of slot. - -Alternatively, we could use a dedicated indicator that the slot is occupied. The advantage of this is that no field of the `attr` structure would be needed to determine the slot state. This would be a clean separation between key attributes and slot state and `attr` could be treated exactly like key slot content. This would save code size and maintenance effort. The cost of it would be that each slot would need an extra field to indicate whether it is occupied. - -##### Key slot content - -Other than what is used to determine the [“key slot state”](#key-slot-state), the contents of a key slot are only accessed as follows: - -* Modification during key creation (between `psa_start_key_creation` and `psa_finish_key_creation` or `psa_fail_key_creation`). -* Destruction in `psa_wipe_key_slot`. -* Read in many functions, between calls to `psa_lock_key_slot` and `psa_unlock_key_slot`. - -**slot->key access:** -* `psa_allocate_buffer_to_slot` - allocates key.data, sets key.bytes; -* `psa_copy_key_material_into_slot` - writes to key.data -* `psa_remove_key_data_from_memory` - writes and reads to/from key data -* `psa_get_key_attributes` - reads from key data -* `psa_export_key` - passes key data to psa_driver_wrapper_export_key -* `psa_export_public_key` - passes key data to psa_driver_wrapper_export_public_key -* `psa_finish_key_creation` - passes key data to psa_save_persistent_key -* `psa_validate_optional_attributes` - passes key data and bytes to mbedtls_psa_rsa_load_representation -* `psa_import_key` - passes key data to psa_driver_wrapper_import_key -* `psa_copy_key` - passes key data to psa_driver_wrapper_copy_key, psa_copy_key_material_into_slot -* `psa_mac_setup` - passes key data to psa_driver_wrapper_mac_sign_setup, psa_driver_wrapper_mac_verify_setup -* `psa_mac_compute_internal` - passes key data to psa_driver_wrapper_mac_compute -* `psa_sign_internal` - passes key data to psa_driver_wrapper_sign_message, psa_driver_wrapper_sign_hash -* `psa_verify_internal` - passes key data to psa_driver_wrapper_verify_message, psa_driver_wrapper_verify_hash -* `psa_asymmetric_encrypt` - passes key data to mbedtls_psa_rsa_load_representation -* `psa_asymmetric_decrypt` - passes key data to mbedtls_psa_rsa_load_representation -* `psa_cipher_setup ` - passes key data to psa_driver_wrapper_cipher_encrypt_setup and psa_driver_wrapper_cipher_decrypt_setup -* `psa_cipher_encrypt` - passes key data to psa_driver_wrapper_cipher_encrypt -* `psa_cipher_decrypt` - passes key data to psa_driver_wrapper_cipher_decrypt -* `psa_aead_encrypt` - passes key data to psa_driver_wrapper_aead_encrypt -* `psa_aead_decrypt` - passes key data to psa_driver_wrapper_aead_decrypt -* `psa_aead_setup` - passes key data to psa_driver_wrapper_aead_encrypt_setup and psa_driver_wrapper_aead_decrypt_setup -* `psa_generate_derived_key_internal` - passes key data to psa_driver_wrapper_import_key -* `psa_key_derivation_input_key` - passes key data to psa_key_derivation_input_internal -* `psa_key_agreement_raw_internal` - passes key data to mbedtls_psa_ecp_load_representation -* `psa_generate_key` - passes key data to psa_driver_wrapper_generate_key - -#### Random generator - -The PSA RNG can be accessed both from various PSA functions, and from application code via `mbedtls_psa_get_random`. - -With the built-in RNG implementations using `mbedtls_ctr_drbg_context` or `mbedtls_hmac_drbg_context`, querying the RNG with `mbedtls_xxx_drbg_random()` is thread-safe (protected by a mutex inside the RNG implementation), but other operations (init, free, seed) are not. - -When `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is enabled, thread safety depends on the implementation. - -#### Driver resources - -Depends on the driver. The PSA driver interface specification does not discuss whether drivers must support concurrent calls. - -### Simple global lock strategy - -Have a single mutex protecting all accesses to the key store and other global variables. In practice, this means every PSA API function needs to take the lock on entry and release on exit, except for: - -* Hash function. -* Accessors for key attributes and other local structures. - -Note that operation functions do need to take the lock, since they need to prevent the destruction of the key. - -Note that this does not protect access to the RNG via `mbedtls_psa_get_random`, which is guaranteed to be thread-safe when `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is disabled. - -This approach is conceptually simple, but requires extra instrumentation to every function and has bad performance in a multithreaded environment since a slow operation in one thread blocks unrelated operations on other threads. - -### Global lock excluding slot content - -Have a single mutex protecting all accesses to the key store and other global variables, except that it's ok to access the content of a key slot without taking the lock if one of the following conditions holds: - -* The key slot is in a state that guarantees that the thread has exclusive access. -* The key slot is in a state that guarantees that no other thread can modify the slot content, and the accessing thread is only reading the slot. - -Note that a thread must hold the global mutex when it reads or changes a slot's state. - -#### Slot states - -For concurrency purposes, a slot can be in one of four states: - -* EMPTY: no thread is currently accessing the slot, and no information is stored in the slot. Any thread is able to change the slot's state to FILLING and begin loading data. -* FILLING: one thread is currently loading or creating material to fill the slot, this thread is responsible for the next state transition. Other threads cannot read the contents of a slot which is in FILLING. -* FULL: the slot contains a key, and any thread is able to use the key after registering as a reader. -* PENDING_DELETION: the key within the slot has been destroyed or marked for destruction, but at least one thread is still registered as a reader. No thread can register to read this slot. The slot must not be wiped until the last reader de-registers, wiping the slot by calling `psa_wipe_key_slot`. - -To change `slot` to state `new_state`, a function must call `psa_slot_state_transition(slot, new_state)`. - -A counter field within each slot keeps track of how many readers have registered. Library functions must call `psa_register_read` before reading the key data within a slot, and `psa_unregister_read` after they have finished operating. - -Any call to `psa_slot_state_transition`, `psa_register_read` or `psa_unregister_read` must be performed by a thread which holds the global mutex. - -##### Linearizability of the system - -To satisfy the requirements in [Correctness out of the box](#correctness-out-of-the-box), we require our functions to be "linearizable" (under certain constraints). This means that any (constraint satisfying) set of concurrent calls are performed as if they were executed in some sequential order. - -The standard way of reasoning that this is the case is to identify a "linearization point" for each call, this is a single execution step where the function takes effect (this is usually a step in which the effects of the call become visible to other threads). If every call has a linearization point, the set of calls is equivalent to sequentially performing the calls in order of when their linearization point occurred. - -We only require linearizability to hold in the case where a resource-management error is not returned. In a set of concurrent calls, it is permitted for a call c to fail with a PSA_ERROR_INSUFFICIENT_MEMORY return code even if there does not exist a sequential ordering of the calls in which c returns this error. Even if such an error occurs, all calls are still required to be functionally correct. - -We only access and modify a slot's state and reader count while we hold the global lock. This ensures the memory in which these fields are stored is correctly synchronized. It also ensures that the key data within the slot is synchronised where needed (the writer unlocks the mutex after filling the data, and any reader must lock the mutex before reading the data). - -To help justify that our system is linearizable, here is a list of key slot state changing functions and their linearization points (for the sake of brevity not all failure cases are covered, but those cases are not complex): -* `psa_wipe_key_slot, psa_register_read, psa_unregister_read, psa_slot_state_transition,` - These functions are all always performed under the global mutex, so they have no effects visible to other threads (this implies that they are linearizable). -* `psa_get_empty_key_slot, psa_get_and_lock_key_slot_in_memory, psa_load_X_key_into_slot, psa_fail_key_creation` - These functions hold the mutex for all non-setup/finalizing code, their linearization points are the release of the mutex. -* `psa_get_and_lock_key_slot` - If the key is already in a slot, the linearization point is the linearization point of the call to `psa_get_and_lock_key_slot_in_memory`. If the key is not in a slot and is loaded into one, the linearization point is the linearization point of the call to `psa_load_X_key_into_slot`. -* `psa_start_key_creation` - From the perspective of other threads, the only effect of a successful call to this function is that the amount of usable resources decreases (a key slot which was usable is now unusable). Since we do not consider resource management as linearizable behaviour, when arguing for linearizability of the system we consider this function to have no visible effect to other threads. -* `psa_finish_key_creation` - On a successful load, we lock the mutex and set the state of the slot to FULL, the linearization point is then the following unlock. On an unsuccessful load, the linearization point is when we return - no action we have performed has been made visible to another thread as the slot is still in a FILLING state. -* `psa_destroy_key, psa_close_key, psa_purge_key` - As per the requirements, we need only argue for the case where the key is not in use here. The linearization point is the unlock after wiping the data and setting the slot state to EMPTY. -* `psa_import_key, psa_copy_key, psa_generate_key, mbedtls_psa_register_se_key` - These functions call both `psa_start_key_creation` and `psa_finish_key_creation`, the linearization point of a successful call is the linearization point of the call to `psa_finish_key_creation`. The linearization point of an unsuccessful call is the linearization point of the call to `psa_fail_key_creation`. -* `psa_key_derivation_output_key` - Same as above. If the operation object is in use by multiple threads, the behaviour need not be linearizable. - -Library functions which operate on a slot will return `PSA_ERROR_BAD_STATE` if the slot is in an inappropriate state for the function at the linearization point. - -##### Key slot state transition diagram - -![](key-slot-state-transitions.png) - -In the state transition diagram above, an arrow between two states `q1` and `q2` with label `f` indicates that if the state of a slot is `q1` immediately before `f`'s linearization point, it may be `q2` immediately after `f`'s linearization point. - -##### Generating the key slot state transition diagram from source - -To generate the state transition diagram in https://app.diagrams.net/, open the following url: - -https://viewer.diagrams.net/?tags=%7B%7D&highlight=FFFFFF&edit=_blank&layers=1&nav=1&title=key-slot-state-transitions#R5Vxbd5s4EP4t%2B%2BDH5iAJcXms4ySbrdtNT7qX9MWHgGyrxcABHNv59SsM2EhgDBhs3PVL0CANoBl9fDMaMkC3i%2FWDb3jzz65F7AGUrPUAjQYQAqBh9ieSbGKJIqFYMPOplXTaC57pO0mEUiJdUosEXMfQde2QerzQdB2HmCEnM3zfXfHdpq7NX9UzZiQneDYNOy%2F9h1rhPJZqUN3Lfyd0Nk%2BvDBQ9PrMw0s7JkwRzw3JXGRG6G6Bb33XD%2BGixviV2NHnpvMTj7g%2Bc3d2YT5ywyoDv4H08%2Ffvxj9VX3XGGw5cf3o9PHxJjvBn2MnngAVRspm9o0Td2OIsO7%2F8aj1Mx0585U9B5bgQTnxgW8YP07Ksv9he1bOcn3KSTzm6c2Zc1hqs5DcmzZ5jRmRVzsegK4cJmLcAOjcCLjT6la2LtVGUnJZmnN%2BKHZJ0RJZP0QNwFCf0N65KclbXEYDuPTdqrjP0T0Txj%2BlRmJB4322neG4UdJHapYSMACowkzphjfYy8nbVM2wgCavIT5btLx4pmaCSxFpscf%2FNvcmrbeMk2Rutsv9Emba1puBvEjl8y8v2QqJGOOGiNwF36Jjnul6Hhz0hY0k%2BO%2BxGLW8V522Zshwtsl8p8YhshfePXfpFBkys8uZQ92UHXwYrgE%2FFzJ6Oya1VUpOo3euancWplJKiNpymnduttu0k4wQFhzgGXjk9mNAiJv13seX9kBhkbr%2BxlwK9Xm86cyEeZQxCfCaJlSRnafkxOLKhlRTqGPgnou%2FG61Re5khc93PZx8XCAR4XOVb56RADYvTOSq3CwXAQM0g2UVJ2zxAd4mt%2BkaoAwxJ1OA9KNLasA%2Ft3np28v14nevQNvvXXwTmBYysAwKIXhHdxLWbiXjsB9c%2FCGFcEb9Au8ec%2FJgWxl7D7yDugYrFO6mXE4LzAmU4Pak59kMzEZXofUdfoM2ema6SNkJ5ohp1Qc3x1%2B51%2FF94%2Fj8eOXh17DMFIuDMNyldderTjnt18u0Lm4kXAVIz3dfRlt3b2inUZ347tvj39%2BuU4b9Y7PqF3RmepRZbPotTmdSdNOx%2BgM7BWdgRJ7%2BWkyVAGLJmWs8G9BLCs3KsAq1FTMGkhQX5XrAEUgTfJ5yY5WyHXYFSdk4YWbLeEJbDfsMdlJF1Qfuc5OjXwuegOKXtTt48sNbhIwxaMuGjL1K98VYYwkpRijMDjg0QBEWawUZJAmqc1QRpYElGG%2BjgSX7DoFVow0U%2BrQYH41cVW6uE7Gmg%2FM7rKu8mCDWvEpRSvUegboKaKfgi3Npf%2B2RZaYbZwv51492dMcg6rm3FGvMEhWMecwitowb4MVQZHIoQ9ADPMBY5PplizPwzes82imSlL5fUGhPzjSX9bK9LOD%2BI6bLp7RUDYBfTA9%2B50sH%2Bkz%2Fvi0rha6CVsGFQO4lNEZjjWxXfNnhtTV0GDabkCiobVGeUtm8uyo%2BtFjf9A%2FtVEb6A%2BQxntZO1k1nr5CfC7sR0X74K3QzixwVwxrMzyz2zy9XBHw%2B5WnhyrkvATjhoAPDuVWzsQpUVGsUwhDFglC392cDl%2FtQGVvIW63jFsIpmVN4aOZdBmc6L47HN5wkNc9xsmX4LfHwKs%2BTB6Eu57AE6N3mcwa0gBnbaSCorO1uaqsZpJ7CtDrXKQjHouQVn7P4l2iIzwWl%2BrvhsfmyyOup9JFbo3gsegeC47bEvh1kUgsNGT7%2BxSXxrfW6BzsFV4iIbzFTesukCpkCSvG72153HXtRZQumlYiRF3YcmqLPqVZzC4ThIWzc5ZKrspbEzwMdbg1UTUtiHsNKwpoCitCPZfSXfFtMSMprufiQsLeAkprhVwRoECekbQVj%2FG7GF0UchXb9UxV%2FcehoQkMNYcTXBFO%2BhXVwQNJ%2BNpwAgWWonRXHlrsdrDA7XJpoFzQUyN9tKIeyeXoryNvXr5Q26jQ2H0P1y6IAXQhEMuT3pwlz55TOohNfcESIXHSeMcSbbNAGpahrMs6RBoS9XLVGbAS0NRNA7GnyV4F6PxNqBK6UaG0%2B6HyJwJ6qTIA6ijDze%2Bso%2BxSPoToZXqpfK3%2Fz9JLT3S5Hk%2FhRNNmX9%2B%2B338yHccr%2FIyqHfLGlZw1%2BiSzM%2BpWtRC2X0VqSKgew2JeqDLc4iOZqvaoW6HPVWJuEQOzXcOaeMQPIlxxwi0ZY%2Ffk1q%2Ba2Gp6XVI7pM4JakrLN66DGpaiQAuIiGVQGIie6Pxnq6CAl6wAqu9Cv9gXl1VT%2F1VL9%2Fa74OmW%2Brk2T%2Fnkbu57gsolw4KiqrUde0WnLBnW3P9fj7j7%2Fr%2BjoLv%2FAA%3D%3D - -#### Destruction of a key in use - -Problem: In [Key destruction long-term requirements](#key-destruction-long-term-requirements) we require that the key slot is destroyed (by `psa_wipe_key_slot`) even while it's in use (FILLING or with at least one reader). - -How do we ensure that? This needs something more sophisticated than mutexes (concurrency number >2)! Even a per-slot mutex isn't enough (we'd need a reader-writer lock). - -Solution: after some team discussion, we've decided to rely on a new threading abstraction which mimics C11 (i.e. `mbedtls_fff` where `fff` is the C11 function name, having the same parameters and return type, with default implementations for C11, pthreads and Windows). We'll likely use condition variables in addition to mutexes. - -##### Mutex only - -When calling `psa_wipe_key_slot` it is the callers responsibility to set the slot state to PENDING_DELETION first. For most functions this is a clean {FULL, !has_readers} -> PENDING_DELETION transition: psa_get_empty_key_slot, psa_get_and_lock_key_slot, psa_close_key, psa_purge_key. - -`psa_wipe_all_key_slots` is only called from `mbedtls_psa_crypto_free`, here we will need to return an error as we won't be able to free the key store if a key is in use without compromising the state of the secure side. This is acceptable as an untrusted application cannot call `mbedtls_psa_crypto_free` in a crypto service. In a service integration, `mbedtls_psa_crypto_free` on the client cuts the communication with the crypto service. Also, this is the current behaviour. - -`psa_destroy_key` registers as a reader, marks the slot as deleted, deletes persistent keys and opaque keys and unregisters before returning. This will free the key ID, but the slot might be still in use. This only works if drivers are protected by a mutex (and the persistent storage as well if needed). `psa_destroy_key` transfers to PENDING_DELETION as an intermediate state. The last reading operation will wipe the key slot upon unregistering. In case of volatile keys freeing up the ID while the slot is still in use does not provide any benefit and we don't need to do it. - -These are serious limitations, but this can be implemented with mutexes only and arguably satisfies the [Key destruction short-term requirements](#key-destruction-short-term-requirements). - -Variations: - -1. As a first step the multipart operations would lock the keys for reading on setup and release on free -2. In a later stage this would be improved by locking the keys on entry into multi-part API calls and released before exiting. - -The second variant can't be implemented as a backward compatible improvement on the first as multipart operations that were successfully completed in the first case, would fail in the second. If we want to implement these incrementally, multipart operations in a multithreaded environment must be left unsupported in the first variant. This makes the first variant impractical (multipart operations returning an error in builds with multithreading enabled is not a behaviour that would be very useful to release). - -We can't reuse the `lock_count` field to mark key slots deleted, as we still need to keep track the lock count while the slot is marked for deletion. This means that we will need to add a new field to key slots. This new field can be reused to indicate whether the slot is occupied (see section [Determining whether a key slot is occupied](#determining-whether-a-key-slot-is-occupied)). (There would be three states: deleted, occupied, empty.) - -#### Condition variables - -Clean UNUSED -> PENDING_DELETION transition works as before. - -`psa_wipe_all_key_slots` and `psa_destroy_key` mark the slot as deleted and go to sleep until the slot has no registered readers. When waking up, they wipe the slot, and return. - -If the slot is already marked as deleted the threads calling `psa_wipe_all_key_slots` and `psa_destroy_key` go to sleep until the deletion completes. To satisfy [Key destruction long-term requirements](#key-destruction-long-term-requirements) none of the threads may return from the call until the slot is deleted completely. This can be achieved by signalling them when the slot has already been wiped and ready for use, that is not marked for deletion anymore. To handle spurious wake-ups, these threads need to be able to tell whether the slot was already deleted. This is not trivial, because by the time the thread wakes up, theoretically the slot might be in any state. It might have been reused and maybe even marked for deletion again. - -To resolve this, we can either: - -1. Depend on the deletion marker. If the slot has been reused and is marked for deletion again, the threads keep waiting until the second deletion completes. -2. Introduce a uuid (eg a global counter plus a slot ID), which is recorded by the thread waiting for deletion and checks whether it matches. If it doesn't, the function can return as the slot was already reallocated. If it does match, it can check whether it is still marked for deletion, if it is, the thread goes back to sleep, if it isn't, the function can return. - -##### Platform abstraction - -Introducing condition variables to the platform abstraction layer would be best done in a major version. If we can't wait until that, we will need to introduce a new compile time flag. Considering that this only will be needed on the PSA Crypto side and the upcoming split, it makes sense to make this flag responsible for the entire PSA Crypto threading support. Therefore if we want to keep the option open for implementing this in a backward compatible manner, we need to introduce and use this new flag already when implementing [Mutex only](#mutex-only). (If we keep the abstraction layer for mutexes the same, this shouldn't mean increase in code size and would mean only minimal effort on the porting side.) - -#### Operation contexts - -Concurrent access to the same operation context can compromise the crypto service for example if the operation context has a pointer (depending on the compiler and the platform, the pointer assignment may or may not be atomic). This violates the functional correctness requirement of the crypto service. (Concurrent calls to operations is undefined behaviour, but still should not compromise the CIA of the crypto service.) - -If we want to protect against this in the library, operations will need a status field protected by a global mutex similarly to key slots. On entry, API calls would check the state and return an error if it is already ACTIVE. Otherwise they set it to ACTIVE and restore it to INACTIVE before returning. - -Alternatively, protecting operation contexts can be left as the responsibility of the crypto service. The [PSA Crypto API Specification](https://arm-software.github.io/psa-api/crypto/1.1/overview/conventions.html#concurrent-calls) does not require the library to provide any protection in this case. A crypto service can easily add its own mutex in its operation structure wrapper (the same structure where it keeps track of which client connection owns that operation object). - -#### Drivers - -Each driver that hasn’t got the "thread_safe” property set has a dedicated mutex. - -Implementing "thread_safe” drivers depends on the condition variable protection in the key store, as we must guarantee that the core never starts the destruction of a key while there are operations in progress on it. - -Start with implementing threading for drivers without the "thread_safe” property (all drivers behave like the property wasn't set). Add "thread_safe" drivers at some point after the [Condition variables](#condition-variables) approach is implemented in the core. - -##### Reentrancy - -It is natural sometimes to want to perform cryptographic operations from a driver, for example calculating a hash as part of various other crypto primitives, or using a block cipher in a driver for a mode, etc. Also encrypting/authenticating communication with a secure element. - -**Non-thread-safe drivers:** - -A driver is non-thread-safe if the `thread-safe` property (see [Driver requirements](#driver-requirements)) is set to false. - In the non-thread-safe case we have these natural assumptions/requirements: -1. Drivers don't call the core for any operation for which they provide an entry point -2. The core doesn't hold the driver mutex between calls to entry points -With these, the only way of a deadlock is when we have several drivers and they have circular dependencies. That is, Driver A makes a call that is despatched to Driver B and upon executing that Driver B makes a call that is despatched to Driver A. For example Driver A does CCM calls Driver B to do CBC-MAC, which in turn calls Driver A to do AES. This example is pretty contrived and it is hard to find a more practical example. +1. Drivers don't call the core for any operation for which they provide an entry point. +2. The core doesn't hold the driver mutex between calls to entry points. + +With these, the only way of a deadlock is when there are several drivers with circular dependencies. That is, Driver A makes a call that is dispatched to Driver B; upon executing this call Driver B makes a call that is dispatched to Driver A. For example Driver A does CCM, which calls driver B to do CBC-MAC, which in turn calls Driver A to perform AES. Potential ways for resolving this: -1. Non-thread-safe drivers must not call the core -2. Provide a new public API that drivers can safely call -3. Make the dispatch layer public for drivers to call + +1. Non-thread-safe drivers must not call the core. +2. Provide a new public API that drivers can safely call. +3. Make the dispatch layer public for drivers to call. 4. There is a whitelist of core APIs that drivers can call. Drivers providing entry points to these must not make a call to the core when handling these calls. (Drivers are still allowed to call any core API that can't have a driver entry point.) The first is too restrictive, the second and the third would require making it a stable API, and would likely increase the code size for a relatively rare feature. We are choosing the fourth as that is the most viable option. **Thread-safe drivers:** -A driver is non-thread-safe if the `thread-safe` property (see [Driver requirements](#driver-requirements)) is set to true. +A driver would be non-thread-safe if the `thread-safe` property is set to true. -To make reentrancy in non-thread-safe drivers work, thread-safe drivers must not make a call to the core when handling a call that is on the non-thread-safe driver core API whitelist. +To make re-entrancy in non-thread-safe drivers work, thread-safe drivers must not make a call to the core when handling a call that is on the non-thread-safe driver core API whitelist. -Thread-safe drivers have less guarantees from the core and need to implement more complex logic and we can reasonably expect them to be more flexible in terms of reentrancy as well. At this point it is hard to see what further guarantees would be useful and feasible. Therefore, we don't provide any further guarantees for now. +Thread-safe drivers have fewer guarantees from the core and need to implement more complex logic. We can reasonably expect them to be more flexible in terms of re-entrancy as well. At this point it is hard to see what further guarantees would be useful and feasible. Therefore, we don't provide any further guarantees for now. -Thread-safe drivers must not make any assumption about the operation of the core beyond what is discussed in the [Reentrancy](#reentrancy) and [Driver requirements](#driver-requirements) sections. - -#### Global data - -PSA Crypto makes use of a `global_data` variable that will be accessible from multiple threads and needs to be protected. Any function accessing this variable (or its members) must take the corresponding lock first. Since `global_data` holds the RNG state, these will involve relatively expensive operations and therefore ideally `global_data` should be protected by its own, dedicated lock (different from the one protecting the key store). - -Note that this does not protect access to the RNG via `mbedtls_psa_get_random`, which is guaranteed to be thread-safe when `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is disabled. Still, doing so is conceptually simpler and we probably will want to remove the lower level mutex in the long run, since the corresponding interface will be removed from the public API. The two mutexes are different and are always taken in the same order, there is no risk of deadlock. - -The purpose of `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is very similar to the driver interface (and might even be added to it in the long run), therefore it makes sense to handle it the same way. In particular, we can use the `global_data` mutex to protect it as a default and when we implement the "thread_safe” property for drivers, we implement it for `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` as well. - -#### Implementation notes - -Since we only have simple mutexes, locking the same mutex from the same thread is a deadlock. Therefore functions taking the global mutex must not be called while holding the same mutex. Functions taking the mutex will document this fact and the implications. - -Releasing the mutex before a function call might introduce race conditions. Therefore might not be practical to take the mutex in low level access functions. If functions like that don't take the mutex, they need to rely on the caller to take it for them. These functions will document that the caller is required to hold the mutex. - -To avoid performance degradation, functions must hold mutexes for as short time as possible. In particular, they must not start expensive operations (eg. doing cryptography) while holding the mutex. - -## Strategy for 3.6 - -The goal is to provide viable threading support without extending the platform abstraction. (Condition variables should be added in 4.0.) This means that we will be relying on mutexes only. - -- Key Store - - Slot states are described in the [Slot states](#slot-states) section. They guarantee safe concurrent access to slot contents. - - Slot states will be protected by a global mutex as described in the introduction of the [Global lock excluding slot content](#global-lock-excluding-slot-content) section. - - Simple key destruction strategy as described in the [Mutex only](#mutex-only) section (variant 2). - - The slot state and key attributes will be separated as described in the last paragraph of the [Determining whether a key slot is occupied](#determining-whether-a-key-slot-is-occupied) section. -- The main `global_data` (the one in `psa_crypto.c`) shall be protected by its own mutex as described in the [Global data](#global-data) section. -- The solution shall use the pre-existing `MBEDTLS_THREADING_C` threading abstraction. That is, the flag proposed in the [Platform abstraction](#platform-abstraction) section won't be implemented. -- The core makes no additional guarantees for drivers. That is, Policy 1 in section [Driver requirements](#driver-requirements) applies. +Thread-safe drivers must not make any assumption about the operation of the core beyond what is discussed here. From f6f973c235dd179fa418324578e736496fe8b47f Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 14 Mar 2024 15:54:07 +0000 Subject: [PATCH 157/211] Document security weakness in concurrent execution of psa_destroy_key Signed-off-by: Ryan Everett --- include/psa/crypto.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/psa/crypto.h b/include/psa/crypto.h index 73889e0ddc..7083bd911b 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -527,6 +527,11 @@ psa_status_t psa_copy_key(mbedtls_svc_key_id_t source_key, * If a key is currently in use in a multipart operation, then destroying the * key will cause the multipart operation to fail. * + * \warning We can only guarantee that the the key material will + * eventually be wiped from memory. With threading enabled + * and during concurrent execution, copies of the key material may + * still exist until all threads have finished using the key. + * * \param key Identifier of the key to erase. If this is \c 0, do nothing and * return #PSA_SUCCESS. * From 6c488709d6bea8d2e2d23f72a6080d1c5abb3680 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 14 Mar 2024 17:49:44 +0000 Subject: [PATCH 158/211] Fix typo in thread_import_key Signed-off-by: Ryan Everett --- tests/suites/test_suite_psa_crypto.function | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 6cb0744495..30d34264aa 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1361,7 +1361,7 @@ void *thread_import_key(void *ctx) same_key_context *skc = (struct same_key_context *) ctx; psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT; - /* Import the key, exactly one thread must succceed. */ + /* Import the key, exactly one thread must succeed. */ psa_status_t status = psa_import_key(skc->attributes, skc->data->x, skc->data->len, &returned_key_id); switch (status) { From 3de040f62d470dc44af1085b04c2a0c4ee0fe718 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 14 Mar 2024 17:50:06 +0000 Subject: [PATCH 159/211] Use TEST_FAIL in threaded tests Signed-off-by: Ryan Everett --- tests/suites/test_suite_psa_crypto.function | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 30d34264aa..7a242fd73d 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1370,7 +1370,7 @@ void *thread_import_key(void *ctx) if (skc->key_loaded) { mbedtls_mutex_unlock(&skc->key_loaded_mutex); /* More than one thread has succeeded, report a failure. */ - TEST_EQUAL(skc->key_loaded, 0); + TEST_FAIL("The same key has been loaded into the key store multiple times."); } skc->key_loaded = 1; mbedtls_mutex_unlock(&skc->key_loaded_mutex); @@ -1445,8 +1445,7 @@ void *thread_use_and_destroy_key(void *ctx) /* Ensure that we are the only thread to succeed. */ if (skc->key_loaded != 1) { mbedtls_mutex_unlock(&skc->key_loaded_mutex); - //Will always fail - TEST_EQUAL(skc->key_loaded, 1); + TEST_FAIL("The same key has been destroyed multiple times."); } skc->key_loaded = 0; mbedtls_mutex_unlock(&skc->key_loaded_mutex); From 6de38ac91c2b626e4c0ac1094f0b92dadcffed05 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 14 Mar 2024 17:50:39 +0000 Subject: [PATCH 160/211] Add missing PSA_ASSERT in mbedtls_test_psa_raw_key_agreement_with_self Signed-off-by: Ryan Everett --- tests/src/psa_exercise_key.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c index 5aed683ebc..937bd45d22 100644 --- a/tests/src/psa_exercise_key.c +++ b/tests/src/psa_exercise_key.c @@ -715,6 +715,7 @@ psa_status_t mbedtls_test_psa_raw_key_agreement_with_self( status = PSA_SUCCESS; goto exit; } + PSA_ASSERT(status); status = psa_raw_key_agreement(alg, key, public_key, public_key_length, From e1b50f38e40faffa12b9f0315e9fa2f581cc2ee0 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 14 Mar 2024 17:51:09 +0000 Subject: [PATCH 161/211] Document unsupported concurrency scenario in psa_exercise_key Signed-off-by: Ryan Everett --- tests/include/test/psa_exercise_key.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/include/test/psa_exercise_key.h b/tests/include/test/psa_exercise_key.h index f656b95f88..f6be3073ac 100644 --- a/tests/include/test/psa_exercise_key.h +++ b/tests/include/test/psa_exercise_key.h @@ -223,6 +223,14 @@ int mbedtls_test_psa_exported_key_sanity_check( * to 1, while another thread calls psa_destroy_key on the same key; * this will test whether destroying the key in use leads to any corruption. * + * There cannot be a set of concurrent calls: + * `mbedtls_test_psa_exercise_key(ki,...)` such that each ki is a unique + * persistent key not loaded into any key slot, and i is greater than the + * number of free key slots. + * This is because such scenarios can lead to unsupported + * `PSA_ERROR_INSUFFICIENT_MEMORY` return codes. + * + * * \param key The key to exercise. It should be capable of performing * \p alg. * \param usage The usage flags to assume. From 74191a56e84cb0a2bb70e6c481c22ffa233931a5 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Sat, 9 Mar 2024 17:38:16 +0100 Subject: [PATCH 162/211] ssl_server2: Split early data enablement from max_early_data_size setting Signed-off-by: Ronald Cron --- programs/ssl/ssl_server2.c | 44 +++++++++++++++++++------------ tests/opt-testcases/tls13-misc.sh | 4 +-- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index f00a111fd1..a5d2ed1020 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -122,7 +122,8 @@ int main(void) #define DFL_SNI NULL #define DFL_ALPN_STRING NULL #define DFL_GROUPS NULL -#define DFL_MAX_EARLY_DATA_SIZE 0 +#define DFL_EARLY_DATA -1 +#define DFL_MAX_EARLY_DATA_SIZE ((uint32_t) -1) #define DFL_SIG_ALGS NULL #define DFL_DHM_FILE NULL #define DFL_TRANSPORT MBEDTLS_SSL_TRANSPORT_STREAM @@ -429,9 +430,10 @@ int main(void) #if defined(MBEDTLS_SSL_EARLY_DATA) #define USAGE_EARLY_DATA \ - " max_early_data_size=%%d default: -1 (disabled)\n" \ - " options: -1 (disabled), " \ - " >= 0 (enabled, max amount of early data )\n" + " early_data=%%d default: library default\n" \ + " options: 0 (disabled), 1 (enabled)\n" \ + " max_early_data_size=%%d default: library default\n" \ + " options: max amount of early data\n" #else #define USAGE_EARLY_DATA "" #endif /* MBEDTLS_SSL_EARLY_DATA */ @@ -694,7 +696,10 @@ struct options { const char *cid_val_renego; /* the CID to use for incoming messages * after renegotiation */ int reproducible; /* make communication reproducible */ +#if defined(MBEDTLS_SSL_EARLY_DATA) + int early_data; /* early data enablement flag */ uint32_t max_early_data_size; /* max amount of early data */ +#endif int query_config_mode; /* whether to read config */ int use_srtp; /* Support SRTP */ int force_srtp_profile; /* SRTP protection profile to use or all */ @@ -1609,10 +1614,6 @@ int main(int argc, char *argv[]) }; #endif /* MBEDTLS_SSL_DTLS_SRTP */ -#if defined(MBEDTLS_SSL_EARLY_DATA) - int tls13_early_data_enabled = MBEDTLS_SSL_EARLY_DATA_DISABLED; -#endif - #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) mbedtls_memory_buffer_alloc_init(alloc_buf, sizeof(alloc_buf)); #if defined(MBEDTLS_MEMORY_DEBUG) @@ -1747,7 +1748,10 @@ int main(int argc, char *argv[]) opt.sni = DFL_SNI; opt.alpn_string = DFL_ALPN_STRING; opt.groups = DFL_GROUPS; +#if defined(MBEDTLS_SSL_EARLY_DATA) + opt.early_data = DFL_EARLY_DATA; opt.max_early_data_size = DFL_MAX_EARLY_DATA_SIZE; +#endif opt.sig_algs = DFL_SIG_ALGS; opt.dhm_file = DFL_DHM_FILE; opt.transport = DFL_TRANSPORT; @@ -1980,14 +1984,18 @@ usage: } #endif #if defined(MBEDTLS_SSL_EARLY_DATA) - else if (strcmp(p, "max_early_data_size") == 0) { - long long value = atoll(q); - tls13_early_data_enabled = - value >= 0 ? MBEDTLS_SSL_EARLY_DATA_ENABLED : - MBEDTLS_SSL_EARLY_DATA_DISABLED; - if (tls13_early_data_enabled) { - opt.max_early_data_size = atoi(q); + else if (strcmp(p, "early_data") == 0) { + switch (atoi(q)) { + case 0: + opt.early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED; + break; + case 1: + opt.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED; + break; + default: goto usage; } + } else if (strcmp(p, "max_early_data_size") == 0) { + opt.max_early_data_size = (uint32_t) atoll(q); } #endif /* MBEDTLS_SSL_EARLY_DATA */ else if (strcmp(p, "renegotiation") == 0) { @@ -2805,8 +2813,10 @@ usage: } #if defined(MBEDTLS_SSL_EARLY_DATA) - mbedtls_ssl_conf_early_data(&conf, tls13_early_data_enabled); - if (tls13_early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED) { + if (opt.early_data != DFL_EARLY_DATA) { + mbedtls_ssl_conf_early_data(&conf, opt.early_data); + } + if (opt.max_early_data_size != DFL_MAX_EARLY_DATA_SIZE) { mbedtls_ssl_conf_max_early_data_size( &conf, opt.max_early_data_size); } diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh index 066fa3fae0..0c8d2ae8ff 100755 --- a/tests/opt-testcases/tls13-misc.sh +++ b/tests/opt-testcases/tls13-misc.sh @@ -523,7 +523,7 @@ requires_all_configs_enabled MBEDTLS_SSL_EARLY_DATA MBEDTLS_SSL_SESSION_TICKETS requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED run_test "TLS 1.3 G->m: EarlyData: feature is enabled, good." \ - "$P_SRV force_version=tls13 debug_level=4 max_early_data_size=$EARLY_DATA_INPUT_LEN" \ + "$P_SRV force_version=tls13 debug_level=4 early_data=1 max_early_data_size=$EARLY_DATA_INPUT_LEN" \ "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+GROUP-ALL:+KX-ALL \ -d 10 -r --earlydata $EARLY_DATA_INPUT " \ 0 \ @@ -542,7 +542,7 @@ requires_all_configs_enabled MBEDTLS_SSL_EARLY_DATA MBEDTLS_SSL_SESSION_TICKETS 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_SRV force_version=tls13 debug_level=4 early_data=1 max_early_data_size=1024" \ "$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" \ From f1ad73f6ca54c0ede5fa46e3ad45398d2c8d6178 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 5 Mar 2024 08:38:49 +0100 Subject: [PATCH 163/211] ssl-opt.sh: Group TLS 1.3 resumption and early data compat tests Signed-off-by: Ronald Cron --- tests/opt-testcases/tls13-misc.sh | 267 +++++++++++++++++++++++++++--- tests/ssl-opt.sh | 219 ------------------------ 2 files changed, 243 insertions(+), 243 deletions(-) diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh index 0c8d2ae8ff..87fea095b6 100755 --- a/tests/opt-testcases/tls13-misc.sh +++ b/tests/opt-testcases/tls13-misc.sh @@ -252,6 +252,225 @@ run_test "TLS 1.3: G->m: PSK: configured ephemeral only, good." \ 0 \ -s "key exchange mode: ephemeral$" +requires_openssl_tls1_3_with_compatible_ephemeral +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3: NewSessionTicket: Basic check, m->O" \ + "$O_NEXT_SRV -msg -tls1_3 -no_resume_ephemeral -no_cache --num_tickets 4" \ + "$P_CLI debug_level=1 reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "got new session ticket." \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -c "HTTP/1.0 200 ok" + +requires_gnutls_tls1_3 +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3: NewSessionTicket: Basic check, m->G" \ + "$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --disable-client-cert" \ + "$P_CLI debug_level=1 reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "got new session ticket." \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -c "HTTP/1.0 200 OK" \ + -s "This is a resumed session" + +requires_openssl_tls1_3_with_compatible_ephemeral +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_enabled MBEDTLS_DEBUG_C +requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +# https://github.com/openssl/openssl/issues/10714 +# Until now, OpenSSL client does not support reconnect. +skip_next_test +run_test "TLS 1.3: NewSessionTicket: Basic check, O->m" \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4" \ + "$O_NEXT_CLI -msg -debug -tls1_3 -reconnect" \ + 0 \ + -s "=> write NewSessionTicket msg" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" + +requires_gnutls_tls1_3 +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_enabled MBEDTLS_DEBUG_C +requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3: NewSessionTicket: Basic check, G->m" \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4" \ + "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -r" \ + 0 \ + -c "Connecting again- trying to resume previous session" \ + -c "NEW SESSION TICKET (4) was received" \ + -s "=> write NewSessionTicket msg" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \ + -s "key exchange mode: ephemeral" \ + -s "key exchange mode: psk_ephemeral" \ + -s "found pre_shared_key extension" + +requires_gnutls_tls1_3 +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_enabled MBEDTLS_DEBUG_C +requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +# Test the session resumption when the cipher suite for the original session is +# TLS1-3-AES-256-GCM-SHA384. In that case, the PSK is 384 bits long and not +# 256 bits long as with all the other TLS 1.3 cipher suites. +requires_ciphersuite_enabled TLS1-3-AES-256-GCM-SHA384 +run_test "TLS 1.3: NewSessionTicket: Basic check with AES-256-GCM only, G->m" \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=4" \ + "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-256-GCM -V -r" \ + 0 \ + -c "Connecting again- trying to resume previous session" \ + -c "NEW SESSION TICKET (4) was received" \ + -s "Ciphersuite is TLS1-3-AES-256-GCM-SHA384" \ + -s "=> write NewSessionTicket msg" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \ + -s "key exchange mode: ephemeral" \ + -s "key exchange mode: psk_ephemeral" \ + -s "found pre_shared_key extension" + +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_config_enabled MBEDTLS_DEBUG_C +requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3: NewSessionTicket: Basic check, m->m" \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4" \ + "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "got new session ticket ( 3 )" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -c "HTTP/1.0 200 OK" \ + -s "=> write NewSessionTicket msg" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \ + -s "key exchange mode: ephemeral" \ + -s "key exchange mode: psk_ephemeral" \ + -s "found pre_shared_key extension" + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: NewSessionTicket: Ticket lifetime max value (7d)" \ + "$P_SRV debug_level=1 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=604800 tickets=1" \ + "$P_CLI reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "HTTP/1.0 200 OK" \ + -c "got new session ticket" \ + -c "Reconnecting with saved session... ok" \ + -s "Protocol is TLSv1.3" \ + -S "Ticket lifetime (604800) is greater than 7 days." + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: NewSessionTicket: Ticket lifetime too long (7d + 1s)" \ + "$P_SRV debug_level=1 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=604801 tickets=1" \ + "$P_CLI reco_mode=1 reconnect=1" \ + 1 \ + -c "Protocol is TLSv1.3" \ + -C "HTTP/1.0 200 OK" \ + -C "got new session ticket" \ + -C "Reconnecting with saved session... ok" \ + -S "Protocol is TLSv1.3" \ + -s "Ticket lifetime (604801) is greater than 7 days." + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: NewSessionTicket: ticket lifetime=0" \ + "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=0 tickets=1" \ + "$P_CLI debug_level=2 reco_mode=1 reconnect=1" \ + 1 \ + -c "Protocol is TLSv1.3" \ + -c "HTTP/1.0 200 OK" \ + -c "Discard new session ticket" \ + -C "got new session ticket" \ + -c "Reconnecting with saved session... failed" \ + -s "Protocol is TLSv1.3" \ + -s "<= write new session ticket" + +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_config_enabled MBEDTLS_DEBUG_C +requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3: NewSessionTicket: servername check, m->m" \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4 \ + sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \ + "$P_CLI debug_level=4 server_name=localhost reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "got new session ticket." \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -c "HTTP/1.0 200 OK" \ + -s "=> write NewSessionTicket msg" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \ + -s "key exchange mode: ephemeral" \ + -s "key exchange mode: psk_ephemeral" \ + -s "found pre_shared_key extension" + +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_config_enabled MBEDTLS_DEBUG_C +requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3: NewSessionTicket: servername negative check, m->m" \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4 \ + sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \ + "$P_CLI debug_level=4 server_name=localhost reco_server_name=remote reco_mode=1 reconnect=1" \ + 1 \ + -c "Protocol is TLSv1.3" \ + -c "got new session ticket." \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -c "Hostname mismatch the session ticket, disable session resumption." \ + -s "=> write NewSessionTicket msg" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" + requires_gnutls_tls1_3 requires_config_enabled MBEDTLS_DEBUG_C requires_config_enabled MBEDTLS_SSL_CLI_C @@ -340,6 +559,30 @@ run_test "TLS 1.3, ext PSK, early data" \ -c "EncryptedExtensions: early_data(42) extension received." \ -c "EncryptedExtensions: early_data(42) extension ( ignored )." +EARLY_DATA_INPUT_LEN_BLOCKS=$(( ( $( cat $EARLY_DATA_INPUT | wc -c ) + 31 ) / 32 )) +EARLY_DATA_INPUT_LEN=$(( $EARLY_DATA_INPUT_LEN_BLOCKS * 32 )) + +requires_gnutls_next +requires_all_configs_enabled MBEDTLS_SSL_EARLY_DATA MBEDTLS_SSL_SESSION_TICKETS \ + MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 G->m: EarlyData: feature is enabled, good." \ + "$P_SRV force_version=tls13 debug_level=4 early_data=1 max_early_data_size=$EARLY_DATA_INPUT_LEN" \ + "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+GROUP-ALL:+KX-ALL \ + -d 10 -r --earlydata $EARLY_DATA_INPUT " \ + 0 \ + -s "Sent max_early_data_size=$EARLY_DATA_INPUT_LEN" \ + -s "NewSessionTicket: early_data(42) extension exists." \ + -s "ClientHello: early_data(42) extension exists." \ + -s "EncryptedExtensions: early_data(42) extension exists." \ + -s "$( head -1 $EARLY_DATA_INPUT )" \ + -s "$( tail -1 $EARLY_DATA_INPUT )" \ + -s "200 early data bytes read" \ + -s "106 early data bytes read" + requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ @@ -512,30 +755,6 @@ run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk_all." \ -s "found matched identity" \ -s "key exchange mode: psk_ephemeral" -EARLY_DATA_INPUT_LEN_BLOCKS=$(( ( $( cat $EARLY_DATA_INPUT | wc -c ) + 31 ) / 32 )) -EARLY_DATA_INPUT_LEN=$(( $EARLY_DATA_INPUT_LEN_BLOCKS * 32 )) - -requires_gnutls_next -requires_all_configs_enabled MBEDTLS_SSL_EARLY_DATA MBEDTLS_SSL_SESSION_TICKETS \ - MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE -requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 G->m: EarlyData: feature is enabled, good." \ - "$P_SRV force_version=tls13 debug_level=4 early_data=1 max_early_data_size=$EARLY_DATA_INPUT_LEN" \ - "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+GROUP-ALL:+KX-ALL \ - -d 10 -r --earlydata $EARLY_DATA_INPUT " \ - 0 \ - -s "Sent max_early_data_size=$EARLY_DATA_INPUT_LEN" \ - -s "NewSessionTicket: early_data(42) extension exists." \ - -s "ClientHello: early_data(42) extension exists." \ - -s "EncryptedExtensions: early_data(42) extension exists." \ - -s "$( head -1 $EARLY_DATA_INPUT )" \ - -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 \ diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 0e86368681..5243ceb138 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -13413,180 +13413,6 @@ run_test "TLS 1.3: Check client no signature algorithm, m->m" \ 1 \ -c "no suitable signature algorithm" -requires_openssl_tls1_3_with_compatible_ephemeral -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3: NewSessionTicket: Basic check, m->O" \ - "$O_NEXT_SRV -msg -tls1_3 -no_resume_ephemeral -no_cache --num_tickets 4" \ - "$P_CLI debug_level=1 reco_mode=1 reconnect=1" \ - 0 \ - -c "Protocol is TLSv1.3" \ - -c "got new session ticket." \ - -c "Saving session for reuse... ok" \ - -c "Reconnecting with saved session" \ - -c "HTTP/1.0 200 ok" - -requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3: NewSessionTicket: Basic check, m->G" \ - "$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --disable-client-cert" \ - "$P_CLI debug_level=1 reco_mode=1 reconnect=1" \ - 0 \ - -c "Protocol is TLSv1.3" \ - -c "got new session ticket." \ - -c "Saving session for reuse... ok" \ - -c "Reconnecting with saved session" \ - -c "HTTP/1.0 200 OK" \ - -s "This is a resumed session" - -requires_openssl_tls1_3_with_compatible_ephemeral -requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_DEBUG_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -# https://github.com/openssl/openssl/issues/10714 -# Until now, OpenSSL client does not support reconnect. -skip_next_test -run_test "TLS 1.3: NewSessionTicket: Basic check, O->m" \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4" \ - "$O_NEXT_CLI -msg -debug -tls1_3 -reconnect" \ - 0 \ - -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" - -requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_DEBUG_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3: NewSessionTicket: Basic check, G->m" \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4" \ - "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -r" \ - 0 \ - -c "Connecting again- trying to resume previous session" \ - -c "NEW SESSION TICKET (4) was received" \ - -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \ - -s "key exchange mode: ephemeral" \ - -s "key exchange mode: psk_ephemeral" \ - -s "found pre_shared_key extension" - -requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_DEBUG_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -# Test the session resumption when the cipher suite for the original session is -# TLS1-3-AES-256-GCM-SHA384. In that case, the PSK is 384 bits long and not -# 256 bits long as with all the other TLS 1.3 cipher suites. -requires_ciphersuite_enabled TLS1-3-AES-256-GCM-SHA384 -run_test "TLS 1.3: NewSessionTicket: Basic check with AES-256-GCM only, G->m" \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=4" \ - "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-256-GCM -V -r" \ - 0 \ - -c "Connecting again- trying to resume previous session" \ - -c "NEW SESSION TICKET (4) was received" \ - -s "Ciphersuite is TLS1-3-AES-256-GCM-SHA384" \ - -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \ - -s "key exchange mode: ephemeral" \ - -s "key exchange mode: psk_ephemeral" \ - -s "found pre_shared_key extension" - -requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_config_enabled MBEDTLS_DEBUG_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3: NewSessionTicket: Basic check, m->m" \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4" \ - "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \ - 0 \ - -c "Protocol is TLSv1.3" \ - -c "got new session ticket ( 3 )" \ - -c "Saving session for reuse... ok" \ - -c "Reconnecting with saved session" \ - -c "HTTP/1.0 200 OK" \ - -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \ - -s "key exchange mode: ephemeral" \ - -s "key exchange mode: psk_ephemeral" \ - -s "found pre_shared_key extension" - -requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ - MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ - MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ - MBEDTLS_DEBUG_C \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED -requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: NewSessionTicket: Ticket lifetime max value (7d)" \ - "$P_SRV debug_level=1 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=604800 tickets=1" \ - "$P_CLI reco_mode=1 reconnect=1" \ - 0 \ - -c "Protocol is TLSv1.3" \ - -c "HTTP/1.0 200 OK" \ - -c "got new session ticket" \ - -c "Reconnecting with saved session... ok" \ - -s "Protocol is TLSv1.3" \ - -S "Ticket lifetime (604800) is greater than 7 days." - -requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ - MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ - MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ - MBEDTLS_DEBUG_C \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED -requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: NewSessionTicket: Ticket lifetime too long (7d + 1s)" \ - "$P_SRV debug_level=1 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=604801 tickets=1" \ - "$P_CLI reco_mode=1 reconnect=1" \ - 1 \ - -c "Protocol is TLSv1.3" \ - -C "HTTP/1.0 200 OK" \ - -C "got new session ticket" \ - -C "Reconnecting with saved session... ok" \ - -S "Protocol is TLSv1.3" \ - -s "Ticket lifetime (604801) is greater than 7 days." - -requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ - MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ - MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ - MBEDTLS_DEBUG_C \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED -requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: NewSessionTicket: ticket lifetime=0" \ - "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=0 tickets=1" \ - "$P_CLI debug_level=2 reco_mode=1 reconnect=1" \ - 1 \ - -c "Protocol is TLSv1.3" \ - -c "HTTP/1.0 200 OK" \ - -c "Discard new session ticket" \ - -C "got new session ticket" \ - -c "Reconnecting with saved session... failed" \ - -s "Protocol is TLSv1.3" \ - -s "<= write new session ticket" - requires_openssl_tls1_3_with_compatible_ephemeral requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 requires_config_enabled MBEDTLS_DEBUG_C @@ -13618,51 +13444,6 @@ run_test "TLS 1.2: Check rsa_pss_rsae compatibility issue, m->G" \ -c "Protocol is TLSv1.2" \ -c "HTTP/1.0 200 [Oo][Kk]" -requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_config_enabled MBEDTLS_DEBUG_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3: NewSessionTicket: servername check, m->m" \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4 \ - sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \ - "$P_CLI debug_level=4 server_name=localhost reco_mode=1 reconnect=1" \ - 0 \ - -c "Protocol is TLSv1.3" \ - -c "got new session ticket." \ - -c "Saving session for reuse... ok" \ - -c "Reconnecting with saved session" \ - -c "HTTP/1.0 200 OK" \ - -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \ - -s "key exchange mode: ephemeral" \ - -s "key exchange mode: psk_ephemeral" \ - -s "found pre_shared_key extension" - -requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_config_enabled MBEDTLS_DEBUG_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3: NewSessionTicket: servername negative check, m->m" \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4 \ - sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \ - "$P_CLI debug_level=4 server_name=localhost reco_server_name=remote reco_mode=1 reconnect=1" \ - 1 \ - -c "Protocol is TLSv1.3" \ - -c "got new session ticket." \ - -c "Saving session for reuse... ok" \ - -c "Reconnecting with saved session" \ - -c "Hostname mismatch the session ticket, disable session resumption." \ - -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" - requires_config_enabled MBEDTLS_SSL_SRV_C requires_config_enabled MBEDTLS_DEBUG_C requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED From c8d604d0a13b2a7a522c3d174fb41c32eabe63ce Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 5 Mar 2024 15:05:47 +0100 Subject: [PATCH 164/211] ssl-opt.sh: Group TLS 1.3 resumption and early data m->G tests Signed-off-by: Ronald Cron --- tests/opt-testcases/tls13-misc.sh | 136 +++++++++++++++--------------- 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh index 87fea095b6..848592d1ab 100755 --- a/tests/opt-testcases/tls13-misc.sh +++ b/tests/opt-testcases/tls13-misc.sh @@ -285,6 +285,74 @@ run_test "TLS 1.3: NewSessionTicket: Basic check, m->G" \ -c "HTTP/1.0 200 OK" \ -s "This is a resumed session" +requires_gnutls_tls1_3 +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_EARLY_DATA +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED +run_test "TLS 1.3 m->G: EarlyData: basic check, good" \ + "$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:+ECDHE-PSK:+PSK \ + --earlydata --maxearlydata 16384 --disable-client-cert" \ + "$P_CLI debug_level=4 early_data=1 reco_mode=1 reconnect=1 reco_delay=900" \ + 0 \ + -c "received max_early_data_size: 16384" \ + -c "Reconnecting with saved session" \ + -c "NewSessionTicket: early_data(42) extension received." \ + -c "ClientHello: early_data(42) extension exists." \ + -c "EncryptedExtensions: early_data(42) extension received." \ + -c "EncryptedExtensions: early_data(42) extension exists." \ + -c "<= write EndOfEarlyData" \ + -s "Parsing extension 'Early Data/42' (0 bytes)" \ + -s "Sending extension Early Data/42 (0 bytes)" \ + -s "END OF EARLY DATA (5) was received." \ + -s "early data accepted" + +requires_gnutls_tls1_3 +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_EARLY_DATA +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED +run_test "TLS 1.3 m->G: EarlyData: write early data, good" \ + "$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:+ECDHE-PSK:+PSK --earlydata --disable-client-cert" \ + "$P_CLI debug_level=4 early_data=1 reco_mode=1 reconnect=1 reco_delay=900" \ + 0 \ + -c "Reconnecting with saved session" \ + -c "NewSessionTicket: early_data(42) extension received." \ + -c "ClientHello: early_data(42) extension exists." \ + -c "EncryptedExtensions: early_data(42) extension received." \ + -c "EncryptedExtensions: early_data(42) extension exists." \ + -c "<= write early_data" \ + -c "<= write EndOfEarlyData" \ + -s "Parsing extension 'Early Data/42' (0 bytes)" \ + -s "Sending extension Early Data/42 (0 bytes)" \ + -s "END OF EARLY DATA (5) was received." \ + -s "early data accepted" \ + -s "decrypted early data with length" + +requires_gnutls_tls1_3 +requires_config_enabled MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_EARLY_DATA +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED +run_test "TLS 1.3 m->G: EarlyData: no early_data in NewSessionTicket, good" \ + "$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:+ECDHE-PSK:+PSK --disable-client-cert" \ + "$P_CLI debug_level=4 early_data=1 reco_mode=1 reconnect=1" \ + 0 \ + -c "Reconnecting with saved session" \ + -C "NewSessionTicket: early_data(42) extension received." \ + -c "ClientHello: early_data(42) extension does not exist." \ + -C "EncryptedExtensions: early_data(42) extension received." \ + -C "EncryptedExtensions: early_data(42) extension exists." + requires_openssl_tls1_3_with_compatible_ephemeral requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS requires_config_enabled MBEDTLS_SSL_SRV_C @@ -471,74 +539,6 @@ run_test "TLS 1.3: NewSessionTicket: servername negative check, m->m" \ -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" -requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_EARLY_DATA -requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED -run_test "TLS 1.3 m->G: EarlyData: basic check, good" \ - "$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:+ECDHE-PSK:+PSK \ - --earlydata --maxearlydata 16384 --disable-client-cert" \ - "$P_CLI debug_level=4 early_data=1 reco_mode=1 reconnect=1 reco_delay=900" \ - 0 \ - -c "received max_early_data_size: 16384" \ - -c "Reconnecting with saved session" \ - -c "NewSessionTicket: early_data(42) extension received." \ - -c "ClientHello: early_data(42) extension exists." \ - -c "EncryptedExtensions: early_data(42) extension received." \ - -c "EncryptedExtensions: early_data(42) extension exists." \ - -c "<= write EndOfEarlyData" \ - -s "Parsing extension 'Early Data/42' (0 bytes)" \ - -s "Sending extension Early Data/42 (0 bytes)" \ - -s "END OF EARLY DATA (5) was received." \ - -s "early data accepted" - -requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_EARLY_DATA -requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED -run_test "TLS 1.3 m->G: EarlyData: write early data, good" \ - "$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:+ECDHE-PSK:+PSK --earlydata --disable-client-cert" \ - "$P_CLI debug_level=4 early_data=1 reco_mode=1 reconnect=1 reco_delay=900" \ - 0 \ - -c "Reconnecting with saved session" \ - -c "NewSessionTicket: early_data(42) extension received." \ - -c "ClientHello: early_data(42) extension exists." \ - -c "EncryptedExtensions: early_data(42) extension received." \ - -c "EncryptedExtensions: early_data(42) extension exists." \ - -c "<= write early_data" \ - -c "<= write EndOfEarlyData" \ - -s "Parsing extension 'Early Data/42' (0 bytes)" \ - -s "Sending extension Early Data/42 (0 bytes)" \ - -s "END OF EARLY DATA (5) was received." \ - -s "early data accepted" \ - -s "decrypted early data with length" - -requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_EARLY_DATA -requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED -run_test "TLS 1.3 m->G: EarlyData: no early_data in NewSessionTicket, good" \ - "$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:+ECDHE-PSK:+PSK --disable-client-cert" \ - "$P_CLI debug_level=4 early_data=1 reco_mode=1 reconnect=1" \ - 0 \ - -c "Reconnecting with saved session" \ - -C "NewSessionTicket: early_data(42) extension received." \ - -c "ClientHello: early_data(42) extension does not exist." \ - -C "EncryptedExtensions: early_data(42) extension received." \ - -C "EncryptedExtensions: early_data(42) extension exists." - #TODO: OpenSSL tests don't work now. It might be openssl options issue, cause GnuTLS has worked. skip_next_test requires_openssl_tls1_3 From c893779bb558d282aeccea434ffe4d68ddfd8b9b Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 5 Mar 2024 15:17:01 +0100 Subject: [PATCH 165/211] ssl-opt.sh: Remove redundant early data test Signed-off-by: Ronald Cron --- tests/opt-testcases/tls13-misc.sh | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh index 848592d1ab..370a4793cf 100755 --- a/tests/opt-testcases/tls13-misc.sh +++ b/tests/opt-testcases/tls13-misc.sh @@ -310,31 +310,6 @@ run_test "TLS 1.3 m->G: EarlyData: basic check, good" \ -s "END OF EARLY DATA (5) was received." \ -s "early data accepted" -requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_EARLY_DATA -requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED -run_test "TLS 1.3 m->G: EarlyData: write early data, good" \ - "$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:+ECDHE-PSK:+PSK --earlydata --disable-client-cert" \ - "$P_CLI debug_level=4 early_data=1 reco_mode=1 reconnect=1 reco_delay=900" \ - 0 \ - -c "Reconnecting with saved session" \ - -c "NewSessionTicket: early_data(42) extension received." \ - -c "ClientHello: early_data(42) extension exists." \ - -c "EncryptedExtensions: early_data(42) extension received." \ - -c "EncryptedExtensions: early_data(42) extension exists." \ - -c "<= write early_data" \ - -c "<= write EndOfEarlyData" \ - -s "Parsing extension 'Early Data/42' (0 bytes)" \ - -s "Sending extension Early Data/42 (0 bytes)" \ - -s "END OF EARLY DATA (5) was received." \ - -s "early data accepted" \ - -s "decrypted early data with length" - requires_gnutls_tls1_3 requires_config_enabled MBEDTLS_DEBUG_C requires_config_enabled MBEDTLS_SSL_CLI_C From 05210086c04d9f75a8db880eae4706a223594c3a Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 5 Mar 2024 16:34:51 +0100 Subject: [PATCH 166/211] ssl-opt.sh: Expand m->G resumption and early data tests Signed-off-by: Ronald Cron --- tests/opt-testcases/tls13-misc.sh | 162 ++++++++++++++++++++++-------- 1 file changed, 120 insertions(+), 42 deletions(-) diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh index 370a4793cf..a134fb880f 100755 --- a/tests/opt-testcases/tls13-misc.sh +++ b/tests/opt-testcases/tls13-misc.sh @@ -269,64 +269,142 @@ run_test "TLS 1.3: NewSessionTicket: Basic check, m->O" \ -c "HTTP/1.0 200 ok" requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3: NewSessionTicket: Basic check, m->G" \ - "$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --disable-client-cert" \ - "$P_CLI debug_level=1 reco_mode=1 reconnect=1" \ +requires_all_configs_enabled MBEDTLS_SSL_CLI_C \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED +run_test "TLS 1.3 m->G: resumption" \ + "$G_NEXT_SRV -d 5 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --disable-client-cert" \ + "$P_CLI reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session... ok" \ + -c "HTTP/1.0 200 OK" + +requires_gnutls_tls1_3 +requires_all_configs_enabled MBEDTLS_SSL_CLI_C \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED +requires_ciphersuite_enabled TLS1-3-AES-256-GCM-SHA384 +run_test "TLS 1.3 m->G: resumption with AES-256-GCM-SHA384 only" \ + "$G_NEXT_SRV -d 5 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --disable-client-cert" \ + "$P_CLI force_ciphersuite=TLS1-3-AES-256-GCM-SHA384 reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "Ciphersuite is TLS1-3-AES-256-GCM-SHA384" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session... ok" \ + -c "HTTP/1.0 200 OK" + +requires_gnutls_tls1_3 +requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_EARLY_DATA \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED +run_test "TLS 1.3 m->G: resumption with early data" \ + "$G_NEXT_SRV -d 5 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --disable-client-cert \ + --earlydata --maxearlydata 16384" \ + "$P_CLI debug_level=3 early_data=1 reco_mode=1 reconnect=1" \ 0 \ -c "Protocol is TLSv1.3" \ - -c "got new session ticket." \ -c "Saving session for reuse... ok" \ -c "Reconnecting with saved session" \ -c "HTTP/1.0 200 OK" \ - -s "This is a resumed session" - -requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_EARLY_DATA -requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED -run_test "TLS 1.3 m->G: EarlyData: basic check, good" \ - "$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:+ECDHE-PSK:+PSK \ - --earlydata --maxearlydata 16384 --disable-client-cert" \ - "$P_CLI debug_level=4 early_data=1 reco_mode=1 reconnect=1 reco_delay=900" \ - 0 \ -c "received max_early_data_size: 16384" \ - -c "Reconnecting with saved session" \ -c "NewSessionTicket: early_data(42) extension received." \ -c "ClientHello: early_data(42) extension exists." \ -c "EncryptedExtensions: early_data(42) extension received." \ - -c "EncryptedExtensions: early_data(42) extension exists." \ - -c "<= write EndOfEarlyData" \ - -s "Parsing extension 'Early Data/42' (0 bytes)" \ - -s "Sending extension Early Data/42 (0 bytes)" \ - -s "END OF EARLY DATA (5) was received." \ - -s "early data accepted" + -c "bytes of early data written" \ + -s "decrypted early data with length:" requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_EARLY_DATA +requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_EARLY_DATA \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED -run_test "TLS 1.3 m->G: EarlyData: no early_data in NewSessionTicket, good" \ - "$G_NEXT_SRV -d 10 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:+ECDHE-PSK:+PSK --disable-client-cert" \ - "$P_CLI debug_level=4 early_data=1 reco_mode=1 reconnect=1" \ +requires_ciphersuite_enabled TLS1-3-AES-256-GCM-SHA384 +run_test "TLS 1.3 m->G: resumption with early data, AES-256-GCM-SHA384 only" \ + "$G_NEXT_SRV -d 5 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --disable-client-cert \ + --earlydata --maxearlydata 16384" \ + "$P_CLI debug_level=3 force_ciphersuite=TLS1-3-AES-256-GCM-SHA384 early_data=1 reco_mode=1 reconnect=1" \ 0 \ + -c "Protocol is TLSv1.3" \ + -c "Ciphersuite is TLS1-3-AES-256-GCM-SHA384" \ + -c "Saving session for reuse... ok" \ -c "Reconnecting with saved session" \ + -c "HTTP/1.0 200 OK" \ + -c "received max_early_data_size: 16384" \ + -c "NewSessionTicket: early_data(42) extension received." \ + -c "ClientHello: early_data(42) extension exists." \ + -c "EncryptedExtensions: early_data(42) extension received." \ + -c "bytes of early data written" \ + -s "decrypted early data with length:" + +requires_gnutls_tls1_3 +requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_EARLY_DATA \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED +run_test "TLS 1.3 m->G: resumption, early data cli-enabled/srv-disabled" \ + "$G_NEXT_SRV -d 5 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:+ECDHE-PSK:+PSK --disable-client-cert" \ + "$P_CLI debug_level=3 early_data=1 reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -c "HTTP/1.0 200 OK" \ + -C "received max_early_data_size: 16384" \ -C "NewSessionTicket: early_data(42) extension received." \ - -c "ClientHello: early_data(42) extension does not exist." \ - -C "EncryptedExtensions: early_data(42) extension received." \ - -C "EncryptedExtensions: early_data(42) extension exists." + +requires_gnutls_tls1_3 +requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_EARLY_DATA \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED +run_test "TLS 1.3 m->G: resumption, early data cli-default/srv-enabled" \ + "$G_NEXT_SRV -d 5 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --disable-client-cert \ + --earlydata --maxearlydata 16384" \ + "$P_CLI debug_level=3 reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -c "HTTP/1.0 200 OK" \ + -c "received max_early_data_size: 16384" \ + -c "NewSessionTicket: early_data(42) extension received." \ + -C "ClientHello: early_data(42) extension exists." \ + +requires_gnutls_tls1_3 +requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_EARLY_DATA \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED +run_test "TLS 1.3 m->G: resumption, early data cli-disabled/srv-enabled" \ + "$G_NEXT_SRV -d 5 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --disable-client-cert \ + --earlydata --maxearlydata 16384" \ + "$P_CLI debug_level=3 early_data=0 reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -c "HTTP/1.0 200 OK" \ + -c "received max_early_data_size: 16384" \ + -c "NewSessionTicket: early_data(42) extension received." \ + -C "ClientHello: early_data(42) extension exists." \ requires_openssl_tls1_3_with_compatible_ephemeral requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS From 47d4a524831b1c80ccdbe8fd719be684ae018fe0 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 5 Mar 2024 17:03:05 +0100 Subject: [PATCH 167/211] ssl-opt.sh: Remove m->O early data test based on external PSK Eventually we do not support early data with external PSK thus no point to do a positive test on that basis. Signed-off-by: Ronald Cron --- tests/opt-testcases/tls13-misc.sh | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh index a134fb880f..7ce0ca5d20 100755 --- a/tests/opt-testcases/tls13-misc.sh +++ b/tests/opt-testcases/tls13-misc.sh @@ -592,26 +592,6 @@ run_test "TLS 1.3: NewSessionTicket: servername negative check, m->m" \ -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" -#TODO: OpenSSL tests don't work now. It might be openssl options issue, cause GnuTLS has worked. -skip_next_test -requires_openssl_tls1_3 -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_EARLY_DATA -requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED -run_test "TLS 1.3, ext PSK, early data" \ - "$O_NEXT_SRV_EARLY_DATA -msg -debug -tls1_3 -psk_identity 0a0b0c -psk 010203 -allow_no_dhe_kex -nocert" \ - "$P_CLI debug_level=5 tls13_kex_modes=psk early_data=1 psk=010203 psk_identity=0a0b0c" \ - 1 \ - -c "Reconnecting with saved session" \ - -c "NewSessionTicket: early_data(42) extension received." \ - -c "ClientHello: early_data(42) extension exists." \ - -c "EncryptedExtensions: early_data(42) extension received." \ - -c "EncryptedExtensions: early_data(42) extension ( ignored )." - EARLY_DATA_INPUT_LEN_BLOCKS=$(( ( $( cat $EARLY_DATA_INPUT | wc -c ) + 31 ) / 32 )) EARLY_DATA_INPUT_LEN=$(( $EARLY_DATA_INPUT_LEN_BLOCKS * 32 )) From 00fa13bf78d36529e9c3c550a619f43dc6e621df Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 5 Mar 2024 17:45:44 +0100 Subject: [PATCH 168/211] ssl-opt.sh: Rework m->O resumption and early data tests Signed-off-by: Ronald Cron --- tests/opt-testcases/tls13-misc.sh | 49 ++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh index 7ce0ca5d20..5f386a325d 100755 --- a/tests/opt-testcases/tls13-misc.sh +++ b/tests/opt-testcases/tls13-misc.sh @@ -253,20 +253,49 @@ run_test "TLS 1.3: G->m: PSK: configured ephemeral only, good." \ -s "key exchange mode: ephemeral$" requires_openssl_tls1_3_with_compatible_ephemeral -requires_config_enabled MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3: NewSessionTicket: Basic check, m->O" \ - "$O_NEXT_SRV -msg -tls1_3 -no_resume_ephemeral -no_cache --num_tickets 4" \ - "$P_CLI debug_level=1 reco_mode=1 reconnect=1" \ +requires_all_configs_enabled MBEDTLS_SSL_CLI_C \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED +run_test "TLS 1.3 m->O: resumption" \ + "$O_NEXT_SRV -msg -tls1_3 -no_resume_ephemeral -no_cache --num_tickets 1" \ + "$P_CLI reco_mode=1 reconnect=1" \ 0 \ -c "Protocol is TLSv1.3" \ - -c "got new session ticket." \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session... ok" \ + -c "HTTP/1.0 200 ok" + +# No early data m->O tests for the time being. The option -early_data is needed +# to enable early data on OpenSSL server and it is not compatible with the +# -www option we usually use for testing with OpenSSL server (see +# O_NEXT_SRV_EARLY_DATA definition). In this configuration when running the +# ephemeral then ticket based scenario we use for early data testing the first +# handshake fails. The following skipped test is here to illustrate the kind +# of testing we would like to do. +skip_next_test +requires_openssl_tls1_3_with_compatible_ephemeral +requires_all_configs_enabled MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_EARLY_DATA \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED +run_test "TLS 1.3 m->O: resumption with early data" \ + "$O_NEXT_SRV_EARLY_DATA -msg -tls1_3 -no_resume_ephemeral -no_cache --num_tickets 1" \ + "$P_CLI debug_level=3 early_data=1 reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ -c "Saving session for reuse... ok" \ -c "Reconnecting with saved session" \ - -c "HTTP/1.0 200 ok" + -c "HTTP/1.0 200 OK" \ + -c "received max_early_data_size: 16384" \ + -c "NewSessionTicket: early_data(42) extension received." \ + -c "ClientHello: early_data(42) extension exists." \ + -c "EncryptedExtensions: early_data(42) extension received." \ + -c "bytes of early data written" \ + -s "decrypted early data with length:" requires_gnutls_tls1_3 requires_all_configs_enabled MBEDTLS_SSL_CLI_C \ From 854df135abab21d46dc2660ef9afa5a429eeec4a Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 5 Mar 2024 17:50:50 +0100 Subject: [PATCH 169/211] ssl-opt.sh: Group TLS 1.3 resumption and early data G->m tests Signed-off-by: Ronald Cron --- tests/opt-testcases/tls13-misc.sh | 48 +++++++++++++++---------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh index 5f386a325d..1201b6e0b0 100755 --- a/tests/opt-testcases/tls13-misc.sh +++ b/tests/opt-testcases/tls13-misc.sh @@ -473,6 +473,30 @@ run_test "TLS 1.3: NewSessionTicket: Basic check, G->m" \ -s "key exchange mode: psk_ephemeral" \ -s "found pre_shared_key extension" +EARLY_DATA_INPUT_LEN_BLOCKS=$(( ( $( cat $EARLY_DATA_INPUT | wc -c ) + 31 ) / 32 )) +EARLY_DATA_INPUT_LEN=$(( $EARLY_DATA_INPUT_LEN_BLOCKS * 32 )) + +requires_gnutls_next +requires_all_configs_enabled MBEDTLS_SSL_EARLY_DATA MBEDTLS_SSL_SESSION_TICKETS \ + MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 G->m: EarlyData: feature is enabled, good." \ + "$P_SRV force_version=tls13 debug_level=4 early_data=1 max_early_data_size=$EARLY_DATA_INPUT_LEN" \ + "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+GROUP-ALL:+KX-ALL \ + -d 10 -r --earlydata $EARLY_DATA_INPUT " \ + 0 \ + -s "Sent max_early_data_size=$EARLY_DATA_INPUT_LEN" \ + -s "NewSessionTicket: early_data(42) extension exists." \ + -s "ClientHello: early_data(42) extension exists." \ + -s "EncryptedExtensions: early_data(42) extension exists." \ + -s "$( head -1 $EARLY_DATA_INPUT )" \ + -s "$( tail -1 $EARLY_DATA_INPUT )" \ + -s "200 early data bytes read" \ + -s "106 early data bytes read" + requires_gnutls_tls1_3 requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS requires_config_enabled MBEDTLS_SSL_SRV_C @@ -621,30 +645,6 @@ run_test "TLS 1.3: NewSessionTicket: servername negative check, m->m" \ -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" -EARLY_DATA_INPUT_LEN_BLOCKS=$(( ( $( cat $EARLY_DATA_INPUT | wc -c ) + 31 ) / 32 )) -EARLY_DATA_INPUT_LEN=$(( $EARLY_DATA_INPUT_LEN_BLOCKS * 32 )) - -requires_gnutls_next -requires_all_configs_enabled MBEDTLS_SSL_EARLY_DATA MBEDTLS_SSL_SESSION_TICKETS \ - MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE -requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 G->m: EarlyData: feature is enabled, good." \ - "$P_SRV force_version=tls13 debug_level=4 early_data=1 max_early_data_size=$EARLY_DATA_INPUT_LEN" \ - "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+GROUP-ALL:+KX-ALL \ - -d 10 -r --earlydata $EARLY_DATA_INPUT " \ - 0 \ - -s "Sent max_early_data_size=$EARLY_DATA_INPUT_LEN" \ - -s "NewSessionTicket: early_data(42) extension exists." \ - -s "ClientHello: early_data(42) extension exists." \ - -s "EncryptedExtensions: early_data(42) extension exists." \ - -s "$( head -1 $EARLY_DATA_INPUT )" \ - -s "$( tail -1 $EARLY_DATA_INPUT )" \ - -s "200 early data bytes read" \ - -s "106 early data bytes read" - requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ From 1ccd7a72c839a2aec7e1c8857eefe493c0dc14b8 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 5 Mar 2024 23:31:07 +0100 Subject: [PATCH 170/211] ssp-opt.sh: Expand G->m resumption and early data tests Signed-off-by: Ronald Cron --- tests/opt-testcases/tls13-misc.sh | 198 ++++++++++++++++++++++-------- 1 file changed, 146 insertions(+), 52 deletions(-) diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh index 1201b6e0b0..77a7f79e8a 100755 --- a/tests/opt-testcases/tls13-misc.sh +++ b/tests/opt-testcases/tls13-misc.sh @@ -454,73 +454,167 @@ run_test "TLS 1.3: NewSessionTicket: Basic check, O->m" \ -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_DEBUG_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ +requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3: NewSessionTicket: Basic check, G->m" \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4" \ +run_test "TLS 1.3 G->m: resumption" \ + "$P_SRV debug_level=2 tickets=1" \ "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -r" \ 0 \ - -c "Connecting again- trying to resume previous session" \ - -c "NEW SESSION TICKET (4) was received" \ - -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \ - -s "key exchange mode: ephemeral" \ - -s "key exchange mode: psk_ephemeral" \ - -s "found pre_shared_key extension" + -s "Protocol is TLSv1.3" \ + -s "key exchange mode: psk" \ + -s "Select PSK ciphersuite" + +requires_gnutls_tls1_3 +requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +requires_ciphersuite_enabled TLS1-3-AES-256-GCM-SHA384 +# Test the session resumption when the cipher suite for the original session is +# TLS1-3-AES-256-GCM-SHA384. In that case, the PSK is 384 bits long and not +# 256 bits long as with all the other TLS 1.3 cipher suites. +run_test "TLS 1.3 G->m: resumption with AES-256-GCM-SHA384 only" \ + "$P_SRV debug_level=2 tickets=1" \ + "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-256-GCM -V -r" \ + 0 \ + -s "Protocol is TLSv1.3" \ + -s "key exchange mode: psk" \ + -s "Select PSK ciphersuite: 1302 - TLS1-3-AES-256-GCM-SHA384" EARLY_DATA_INPUT_LEN_BLOCKS=$(( ( $( cat $EARLY_DATA_INPUT | wc -c ) + 31 ) / 32 )) EARLY_DATA_INPUT_LEN=$(( $EARLY_DATA_INPUT_LEN_BLOCKS * 32 )) -requires_gnutls_next -requires_all_configs_enabled MBEDTLS_SSL_EARLY_DATA MBEDTLS_SSL_SESSION_TICKETS \ - MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +requires_gnutls_tls1_3 +requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_SSL_SRV_C MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 G->m: EarlyData: feature is enabled, good." \ - "$P_SRV force_version=tls13 debug_level=4 early_data=1 max_early_data_size=$EARLY_DATA_INPUT_LEN" \ - "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+GROUP-ALL:+KX-ALL \ - -d 10 -r --earlydata $EARLY_DATA_INPUT " \ +run_test "TLS 1.3 G->m: resumption with early data" \ + "$P_SRV debug_level=4 tickets=1 early_data=1 max_early_data_size=$EARLY_DATA_INPUT_LEN" \ + "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -r \ + --earlydata $EARLY_DATA_INPUT" \ 0 \ - -s "Sent max_early_data_size=$EARLY_DATA_INPUT_LEN" \ - -s "NewSessionTicket: early_data(42) extension exists." \ - -s "ClientHello: early_data(42) extension exists." \ - -s "EncryptedExtensions: early_data(42) extension exists." \ - -s "$( head -1 $EARLY_DATA_INPUT )" \ - -s "$( tail -1 $EARLY_DATA_INPUT )" \ - -s "200 early data bytes read" \ + -s "Protocol is TLSv1.3" \ + -s "key exchange mode: psk" \ + -s "Select PSK ciphersuite" \ + -s "Sent max_early_data_size=$EARLY_DATA_INPUT_LEN" \ + -s "NewSessionTicket: early_data(42) extension exists." \ + -s "ClientHello: early_data(42) extension exists." \ + -s "EncryptedExtensions: early_data(42) extension exists." \ + -s "$( head -1 $EARLY_DATA_INPUT )" \ + -s "$( tail -1 $EARLY_DATA_INPUT )" \ + -s "200 early data bytes read" \ -s "106 early data bytes read" requires_gnutls_tls1_3 -requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_DEBUG_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ +requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_SSL_SRV_C MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -# Test the session resumption when the cipher suite for the original session is -# TLS1-3-AES-256-GCM-SHA384. In that case, the PSK is 384 bits long and not -# 256 bits long as with all the other TLS 1.3 cipher suites. requires_ciphersuite_enabled TLS1-3-AES-256-GCM-SHA384 -run_test "TLS 1.3: NewSessionTicket: Basic check with AES-256-GCM only, G->m" \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key force_version=tls13 tickets=4" \ - "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-256-GCM -V -r" \ - 0 \ - -c "Connecting again- trying to resume previous session" \ - -c "NEW SESSION TICKET (4) was received" \ - -s "Ciphersuite is TLS1-3-AES-256-GCM-SHA384" \ - -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \ - -s "key exchange mode: ephemeral" \ - -s "key exchange mode: psk_ephemeral" \ - -s "found pre_shared_key extension" +run_test "TLS 1.3 G->m: resumption with early data, AES-256-GCM-SHA384 only" \ + "$P_SRV debug_level=4 tickets=1 early_data=1 max_early_data_size=$EARLY_DATA_INPUT_LEN" \ + "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-256-GCM -V -r \ + --earlydata $EARLY_DATA_INPUT" \ + 0 \ + -s "Protocol is TLSv1.3" \ + -s "key exchange mode: psk" \ + -s "Select PSK ciphersuite: 1302 - TLS1-3-AES-256-GCM-SHA384" \ + -s "Sent max_early_data_size=$EARLY_DATA_INPUT_LEN" \ + -s "NewSessionTicket: early_data(42) extension exists." \ + -s "ClientHello: early_data(42) extension exists." \ + -s "EncryptedExtensions: early_data(42) extension exists." \ + -s "$( head -1 $EARLY_DATA_INPUT )" \ + -s "$( tail -1 $EARLY_DATA_INPUT )" \ + -s "200 early data bytes read" \ + -s "106 early data bytes read" + +# The Mbed TLS server does not allow early data for the ticket it sends but +# the GnuTLS indicates early data anyway when resuming with the ticket and +# sends early data. The Mbed TLS server does not expect early data in +# association with the ticket thus it eventually fails the resumption +# handshake. The GnuTLS client behavior is not compliant here with the TLS 1.3 +# specification and thus its behavior may change in following versions. +requires_gnutls_tls1_3 +requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_SSL_SRV_C MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 G->m: resumption, early data cli-enabled/srv-default" \ + "$P_SRV debug_level=4 tickets=1" \ + "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -r \ + --earlydata $EARLY_DATA_INPUT" \ + 1 \ + -s "Protocol is TLSv1.3" \ + -s "key exchange mode: psk" \ + -s "Select PSK ciphersuite" \ + -S "Sent max_early_data_size" \ + -S "NewSessionTicket: early_data(42) extension exists." \ + -s "ClientHello: early_data(42) extension exists." \ + -s "EarlyData: rejected, feature disabled in server configuration." \ + -S "EncryptedExtensions: early_data(42) extension exists." \ + -s "EarlyData: deprotect and discard app data records" \ + -s "EarlyData: Too much early data received" + +# The Mbed TLS server does not allow early data for the ticket it sends but +# the GnuTLS indicates early data anyway when resuming with the ticket and +# sends early data. The Mbed TLS server does not expect early data in +# association with the ticket thus it eventually fails the resumption +# handshake. The GnuTLS client behavior is not compliant here with the TLS 1.3 +# specification and thus its behavior may change in following versions. +requires_gnutls_tls1_3 +requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_SSL_SRV_C MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 G->m: resumption, early data cli-enabled/srv-disabled" \ + "$P_SRV debug_level=4 tickets=1 early_data=0" \ + "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -r \ + --earlydata $EARLY_DATA_INPUT" \ + 1 \ + -s "Protocol is TLSv1.3" \ + -s "key exchange mode: psk" \ + -s "Select PSK ciphersuite" \ + -S "Sent max_early_data_size" \ + -S "NewSessionTicket: early_data(42) extension exists." \ + -s "ClientHello: early_data(42) extension exists." \ + -s "EarlyData: rejected, feature disabled in server configuration." \ + -S "EncryptedExtensions: early_data(42) extension exists." \ + -s "EarlyData: deprotect and discard app data records" \ + -s "EarlyData: Too much early data received" + +requires_gnutls_tls1_3 +requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_SSL_SRV_C MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 G->m: resumption, early data cli-disabled/srv-enabled" \ + "$P_SRV debug_level=4 tickets=1 early_data=1" \ + "$G_NEXT_CLI localhost -d 4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V -r" \ + 0 \ + -s "Protocol is TLSv1.3" \ + -s "key exchange mode: psk" \ + -s "Select PSK ciphersuite" \ + -s "Sent max_early_data_size" \ + -s "NewSessionTicket: early_data(42) extension exists." \ + -S "ClientHello: early_data(42) extension exists." \ + -S "EncryptedExtensions: early_data(42) extension exists." requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS requires_config_enabled MBEDTLS_SSL_SRV_C From 820199a2ef1ced857798c33110d3ea01f9b2006d Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Sun, 10 Mar 2024 10:39:26 +0100 Subject: [PATCH 171/211] ssl-opt.sh: Rework O->m placeholder test Signed-off-by: Ronald Cron --- tests/opt-testcases/tls13-misc.sh | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh index 77a7f79e8a..ab4805f777 100755 --- a/tests/opt-testcases/tls13-misc.sh +++ b/tests/opt-testcases/tls13-misc.sh @@ -436,22 +436,21 @@ run_test "TLS 1.3 m->G: resumption, early data cli-disabled/srv-enabled" \ -C "ClientHello: early_data(42) extension exists." \ requires_openssl_tls1_3_with_compatible_ephemeral -requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_DEBUG_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ +requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED # https://github.com/openssl/openssl/issues/10714 # Until now, OpenSSL client does not support reconnect. skip_next_test -run_test "TLS 1.3: NewSessionTicket: Basic check, O->m" \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4" \ +run_test "TLS 1.3 O->m: resumption" \ + "$P_SRV debug_level=2 tickets=1" \ "$O_NEXT_CLI -msg -debug -tls1_3 -reconnect" \ 0 \ - -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" + -s "Protocol is TLSv1.3" \ + -s "key exchange mode: psk" \ + -s "Select PSK ciphersuite" requires_gnutls_tls1_3 requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ From 3cf41457eee7d27b16002297b445211cf92c008a Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Sun, 10 Mar 2024 10:44:14 +0100 Subject: [PATCH 172/211] ssl-opt.sh: Move m->m resumption tests Move m->m resumption tests just before resumption and early data tests against GnuTLS and OpenSSL. Signed-off-by: Ronald Cron --- tests/opt-testcases/tls13-misc.sh | 714 +++++++++++++++--------------- 1 file changed, 357 insertions(+), 357 deletions(-) diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh index ab4805f777..7fc3af9644 100755 --- a/tests/opt-testcases/tls13-misc.sh +++ b/tests/opt-testcases/tls13-misc.sh @@ -71,6 +71,196 @@ run_test "TLS 1.3 m->m: Multiple PSKs: invalid ticket, reconnect with PSK" \ -S "key exchange mode: ephemeral$" \ -s "ticket is not authentic" +requires_gnutls_tls1_3 +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C +requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED +run_test "TLS 1.3: G->m: ephemeral_all/psk, fail, no common kex mode" \ + "$P_SRV tls13_kex_modes=psk debug_level=5 $(get_srv_psk_list)" \ + "$G_NEXT_CLI -d 10 --priority NORMAL:-VERS-ALL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:-PSK:+VERS-TLS1.3 \ + --pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70 \ + localhost" \ + 1 \ + -s "found psk key exchange modes extension" \ + -s "found pre_shared_key extension" \ + -s "Found PSK_EPHEMERAL KEX MODE" \ + -S "Found PSK KEX MODE" \ + -S "key exchange mode: psk$" \ + -S "key exchange mode: psk_ephemeral" \ + -S "key exchange mode: ephemeral" + +requires_gnutls_tls1_3 +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED +requires_all_configs_disabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +run_test "TLS 1.3: G->m: PSK: configured psk only, good." \ + "$P_SRV tls13_kex_modes=all debug_level=5 $(get_srv_psk_list)" \ + "$G_NEXT_CLI -d 10 --priority NORMAL:-VERS-ALL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK:+VERS-TLS1.3:+GROUP-ALL \ + --pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70 \ + localhost" \ + 0 \ + -s "found psk key exchange modes extension" \ + -s "found pre_shared_key extension" \ + -s "Found PSK_EPHEMERAL KEX MODE" \ + -s "Found PSK KEX MODE" \ + -s "key exchange mode: psk$" + +requires_gnutls_tls1_3 +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +requires_all_configs_disabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +run_test "TLS 1.3: G->m: PSK: configured psk_ephemeral only, good." \ + "$P_SRV tls13_kex_modes=all debug_level=5 $(get_srv_psk_list)" \ + "$G_NEXT_CLI -d 10 --priority NORMAL:-VERS-ALL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK:+VERS-TLS1.3:+GROUP-ALL \ + --pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70 \ + localhost" \ + 0 \ + -s "found psk key exchange modes extension" \ + -s "found pre_shared_key extension" \ + -s "Found PSK_EPHEMERAL KEX MODE" \ + -s "Found PSK KEX MODE" \ + -s "key exchange mode: psk_ephemeral$" + +requires_gnutls_tls1_3 +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_all_configs_disabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3: G->m: PSK: configured ephemeral only, good." \ + "$P_SRV tls13_kex_modes=all debug_level=5 $(get_srv_psk_list)" \ + "$G_NEXT_CLI -d 10 --priority NORMAL:-VERS-ALL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK:+VERS-TLS1.3:+GROUP-ALL \ + --pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70 \ + localhost" \ + 0 \ + -s "key exchange mode: ephemeral$" + +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_config_enabled MBEDTLS_DEBUG_C +requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3: NewSessionTicket: Basic check, m->m" \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4" \ + "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "got new session ticket ( 3 )" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -c "HTTP/1.0 200 OK" \ + -s "=> write NewSessionTicket msg" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \ + -s "key exchange mode: ephemeral" \ + -s "key exchange mode: psk_ephemeral" \ + -s "found pre_shared_key extension" + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: NewSessionTicket: Ticket lifetime max value (7d)" \ + "$P_SRV debug_level=1 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=604800 tickets=1" \ + "$P_CLI reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "HTTP/1.0 200 OK" \ + -c "got new session ticket" \ + -c "Reconnecting with saved session... ok" \ + -s "Protocol is TLSv1.3" \ + -S "Ticket lifetime (604800) is greater than 7 days." + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: NewSessionTicket: Ticket lifetime too long (7d + 1s)" \ + "$P_SRV debug_level=1 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=604801 tickets=1" \ + "$P_CLI reco_mode=1 reconnect=1" \ + 1 \ + -c "Protocol is TLSv1.3" \ + -C "HTTP/1.0 200 OK" \ + -C "got new session ticket" \ + -C "Reconnecting with saved session... ok" \ + -S "Protocol is TLSv1.3" \ + -s "Ticket lifetime (604801) is greater than 7 days." + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: NewSessionTicket: ticket lifetime=0" \ + "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=0 tickets=1" \ + "$P_CLI debug_level=2 reco_mode=1 reconnect=1" \ + 1 \ + -c "Protocol is TLSv1.3" \ + -c "HTTP/1.0 200 OK" \ + -c "Discard new session ticket" \ + -C "got new session ticket" \ + -c "Reconnecting with saved session... failed" \ + -s "Protocol is TLSv1.3" \ + -s "<= write new session ticket" + +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_config_enabled MBEDTLS_DEBUG_C +requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3: NewSessionTicket: servername check, m->m" \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4 \ + sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \ + "$P_CLI debug_level=4 server_name=localhost reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "got new session ticket." \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -c "HTTP/1.0 200 OK" \ + -s "=> write NewSessionTicket msg" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \ + -s "key exchange mode: ephemeral" \ + -s "key exchange mode: psk_ephemeral" \ + -s "found pre_shared_key extension" + +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_config_enabled MBEDTLS_DEBUG_C +requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3: NewSessionTicket: servername negative check, m->m" \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4 \ + sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \ + "$P_CLI debug_level=4 server_name=localhost reco_server_name=remote reco_mode=1 reconnect=1" \ + 1 \ + -c "Protocol is TLSv1.3" \ + -c "got new session ticket." \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -c "Hostname mismatch the session ticket, disable session resumption." \ + -s "=> write NewSessionTicket msg" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ + -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" + requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \ MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ @@ -185,72 +375,177 @@ run_test "TLS 1.3 m->m: Session resumption failure, age outside tolerance window -S "Ticket age exceeds limitation" \ -s "Ticket age outside tolerance window" -requires_gnutls_tls1_3 -requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C -requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED -run_test "TLS 1.3: G->m: ephemeral_all/psk, fail, no common kex mode" \ - "$P_SRV tls13_kex_modes=psk debug_level=5 $(get_srv_psk_list)" \ - "$G_NEXT_CLI -d 10 --priority NORMAL:-VERS-ALL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:-PSK:+VERS-TLS1.3 \ - --pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70 \ - localhost" \ - 1 \ - -s "found psk key exchange modes extension" \ - -s "found pre_shared_key extension" \ - -s "Found PSK_EPHEMERAL KEX MODE" \ - -S "Found PSK KEX MODE" \ - -S "key exchange mode: psk$" \ - -S "key exchange mode: psk_ephemeral" \ - -S "key exchange mode: ephemeral" - -requires_gnutls_tls1_3 -requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C \ - MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ +requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ + MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED -requires_all_configs_disabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED -run_test "TLS 1.3: G->m: PSK: configured psk only, good." \ - "$P_SRV tls13_kex_modes=all debug_level=5 $(get_srv_psk_list)" \ - "$G_NEXT_CLI -d 10 --priority NORMAL:-VERS-ALL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK:+VERS-TLS1.3:+GROUP-ALL \ - --pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70 \ - localhost" \ - 0 \ - -s "found psk key exchange modes extension" \ - -s "found pre_shared_key extension" \ - -s "Found PSK_EPHEMERAL KEX MODE" \ - -s "Found PSK KEX MODE" \ - -s "key exchange mode: psk$" +run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/none." \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=7" \ + "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \ + 0 \ + -c "Pre-configured PSK number = 1" \ + -S "sent selected_identity:" \ + -s "key exchange mode: ephemeral" \ + -S "key exchange mode: psk_ephemeral" \ + -S "key exchange mode: psk$" \ + -s "No suitable PSK key exchange mode" \ + -s "No usable PSK or ticket" -requires_gnutls_tls1_3 -requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C \ - MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ +requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ + MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED +run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk." \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=8" \ + "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \ + 0 \ + -c "Pre-configured PSK number = 1" \ + -S "No suitable PSK key exchange mode" \ + -s "found matched identity" + +requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ + MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED +run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk_ephemeral." \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=9" \ + "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \ + 0 \ + -c "Pre-configured PSK number = 1" \ + -S "sent selected_identity:" \ + -s "key exchange mode: ephemeral" \ + -S "key exchange mode: psk_ephemeral" \ + -S "key exchange mode: psk$" \ + -s "No suitable 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 \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED +run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk_all." \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=10" \ + "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \ + 0 \ + -c "Pre-configured PSK number = 1" \ + -S "No suitable PSK key exchange mode" \ + -s "found matched identity" + +requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ + MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -requires_all_configs_disabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED -run_test "TLS 1.3: G->m: PSK: configured psk_ephemeral only, good." \ - "$P_SRV tls13_kex_modes=all debug_level=5 $(get_srv_psk_list)" \ - "$G_NEXT_CLI -d 10 --priority NORMAL:-VERS-ALL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK:+VERS-TLS1.3:+GROUP-ALL \ - --pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70 \ - localhost" \ - 0 \ - -s "found psk key exchange modes extension" \ - -s "found pre_shared_key extension" \ - -s "Found PSK_EPHEMERAL KEX MODE" \ - -s "Found PSK KEX MODE" \ - -s "key exchange mode: psk_ephemeral$" +run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/none." \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=7" \ + "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \ + 0 \ + -c "Pre-configured PSK number = 1" \ + -S "sent selected_identity:" \ + -s "key exchange mode: ephemeral" \ + -S "key exchange mode: psk_ephemeral" \ + -S "key exchange mode: psk$" \ + -s "No suitable PSK key exchange mode" \ + -s "No usable PSK or ticket" -requires_gnutls_tls1_3 -requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SRV_C MBEDTLS_DEBUG_C \ - MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED -requires_all_configs_disabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3: G->m: PSK: configured ephemeral only, good." \ - "$P_SRV tls13_kex_modes=all debug_level=5 $(get_srv_psk_list)" \ - "$G_NEXT_CLI -d 10 --priority NORMAL:-VERS-ALL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK:+VERS-TLS1.3:+GROUP-ALL \ - --pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70 \ - localhost" \ - 0 \ - -s "key exchange mode: ephemeral$" +requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ + MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk." \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=8" \ + "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \ + 0 \ + -c "Pre-configured PSK number = 1" \ + -S "sent selected_identity:" \ + -s "key exchange mode: ephemeral" \ + -S "key exchange mode: psk_ephemeral" \ + -S "key exchange mode: psk$" \ + -s "No suitable 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 \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk_ephemeral." \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=9" \ + "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \ + 0 \ + -c "Pre-configured PSK number = 1" \ + -S "No suitable PSK key exchange mode" \ + -s "found matched identity" \ + -s "key exchange mode: psk_ephemeral" + +requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ + MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk_all." \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=10" \ + "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \ + 0 \ + -c "Pre-configured PSK number = 1" \ + -S "No suitable PSK key exchange mode" \ + -s "found matched identity" \ + -s "key exchange mode: psk_ephemeral" + +requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ + MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/none." \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=7" \ + "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \ + 0 \ + -c "Pre-configured PSK number = 1" \ + -S "sent selected_identity:" \ + -s "key exchange mode: ephemeral" \ + -S "key exchange mode: psk_ephemeral" \ + -S "key exchange mode: psk$" \ + -s "No suitable 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 \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk." \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=8" \ + "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \ + 0 \ + -c "Pre-configured PSK number = 1" \ + -S "No suitable PSK key exchange mode" \ + -s "found matched identity" + +requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ + MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk_ephemeral." \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=9" \ + "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \ + 0 \ + -c "Pre-configured PSK number = 1" \ + -S "No suitable PSK key exchange mode" \ + -s "found matched identity" \ + -s "key exchange mode: psk_ephemeral" + +requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ + MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk_all." \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=10" \ + "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \ + 0 \ + -c "Pre-configured PSK number = 1" \ + -S "No suitable PSK key exchange mode" \ + -s "found matched identity" \ + -s "key exchange mode: psk_ephemeral" requires_openssl_tls1_3_with_compatible_ephemeral requires_all_configs_enabled MBEDTLS_SSL_CLI_C \ @@ -615,301 +910,6 @@ run_test "TLS 1.3 G->m: resumption, early data cli-disabled/srv-enabled" \ -S "ClientHello: early_data(42) extension exists." \ -S "EncryptedExtensions: early_data(42) extension exists." -requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_config_enabled MBEDTLS_DEBUG_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3: NewSessionTicket: Basic check, m->m" \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4" \ - "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \ - 0 \ - -c "Protocol is TLSv1.3" \ - -c "got new session ticket ( 3 )" \ - -c "Saving session for reuse... ok" \ - -c "Reconnecting with saved session" \ - -c "HTTP/1.0 200 OK" \ - -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \ - -s "key exchange mode: ephemeral" \ - -s "key exchange mode: psk_ephemeral" \ - -s "found pre_shared_key extension" - -requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ - MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ - MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ - MBEDTLS_DEBUG_C \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED -requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: NewSessionTicket: Ticket lifetime max value (7d)" \ - "$P_SRV debug_level=1 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=604800 tickets=1" \ - "$P_CLI reco_mode=1 reconnect=1" \ - 0 \ - -c "Protocol is TLSv1.3" \ - -c "HTTP/1.0 200 OK" \ - -c "got new session ticket" \ - -c "Reconnecting with saved session... ok" \ - -s "Protocol is TLSv1.3" \ - -S "Ticket lifetime (604800) is greater than 7 days." - -requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ - MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ - MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ - MBEDTLS_DEBUG_C \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED -requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: NewSessionTicket: Ticket lifetime too long (7d + 1s)" \ - "$P_SRV debug_level=1 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=604801 tickets=1" \ - "$P_CLI reco_mode=1 reconnect=1" \ - 1 \ - -c "Protocol is TLSv1.3" \ - -C "HTTP/1.0 200 OK" \ - -C "got new session ticket" \ - -C "Reconnecting with saved session... ok" \ - -S "Protocol is TLSv1.3" \ - -s "Ticket lifetime (604801) is greater than 7 days." - -requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ - MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ - MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ - MBEDTLS_DEBUG_C \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED -requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: NewSessionTicket: ticket lifetime=0" \ - "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=0 tickets=1" \ - "$P_CLI debug_level=2 reco_mode=1 reconnect=1" \ - 1 \ - -c "Protocol is TLSv1.3" \ - -c "HTTP/1.0 200 OK" \ - -c "Discard new session ticket" \ - -C "got new session ticket" \ - -c "Reconnecting with saved session... failed" \ - -s "Protocol is TLSv1.3" \ - -s "<= write new session ticket" - -requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_config_enabled MBEDTLS_DEBUG_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3: NewSessionTicket: servername check, m->m" \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4 \ - sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \ - "$P_CLI debug_level=4 server_name=localhost reco_mode=1 reconnect=1" \ - 0 \ - -c "Protocol is TLSv1.3" \ - -c "got new session ticket." \ - -c "Saving session for reuse... ok" \ - -c "Reconnecting with saved session" \ - -c "HTTP/1.0 200 OK" \ - -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \ - -s "key exchange mode: ephemeral" \ - -s "key exchange mode: psk_ephemeral" \ - -s "found pre_shared_key extension" - -requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_config_enabled MBEDTLS_DEBUG_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3: NewSessionTicket: servername negative check, m->m" \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4 \ - sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \ - "$P_CLI debug_level=4 server_name=localhost reco_server_name=remote reco_mode=1 reconnect=1" \ - 1 \ - -c "Protocol is TLSv1.3" \ - -c "got new session ticket." \ - -c "Saving session for reuse... ok" \ - -c "Reconnecting with saved session" \ - -c "Hostname mismatch the session ticket, disable session resumption." \ - -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" - -requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ - MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/none." \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=7" \ - "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \ - 0 \ - -c "Pre-configured PSK number = 1" \ - -S "sent selected_identity:" \ - -s "key exchange mode: ephemeral" \ - -S "key exchange mode: psk_ephemeral" \ - -S "key exchange mode: psk$" \ - -s "No suitable 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 \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk." \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=8" \ - "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \ - 0 \ - -c "Pre-configured PSK number = 1" \ - -S "No suitable PSK key exchange mode" \ - -s "found matched identity" - -requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ - MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk_ephemeral." \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=9" \ - "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \ - 0 \ - -c "Pre-configured PSK number = 1" \ - -S "sent selected_identity:" \ - -s "key exchange mode: ephemeral" \ - -S "key exchange mode: psk_ephemeral" \ - -S "key exchange mode: psk$" \ - -s "No suitable 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 \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk_all." \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=10" \ - "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \ - 0 \ - -c "Pre-configured PSK number = 1" \ - -S "No suitable PSK key exchange mode" \ - -s "found matched identity" - -requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ - MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/none." \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=7" \ - "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \ - 0 \ - -c "Pre-configured PSK number = 1" \ - -S "sent selected_identity:" \ - -s "key exchange mode: ephemeral" \ - -S "key exchange mode: psk_ephemeral" \ - -S "key exchange mode: psk$" \ - -s "No suitable 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 \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk." \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=8" \ - "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \ - 0 \ - -c "Pre-configured PSK number = 1" \ - -S "sent selected_identity:" \ - -s "key exchange mode: ephemeral" \ - -S "key exchange mode: psk_ephemeral" \ - -S "key exchange mode: psk$" \ - -s "No suitable 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 \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk_ephemeral." \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=9" \ - "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \ - 0 \ - -c "Pre-configured PSK number = 1" \ - -S "No suitable PSK key exchange mode" \ - -s "found matched identity" \ - -s "key exchange mode: psk_ephemeral" - -requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ - MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk_all." \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=10" \ - "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \ - 0 \ - -c "Pre-configured PSK number = 1" \ - -S "No suitable PSK key exchange mode" \ - -s "found matched identity" \ - -s "key exchange mode: psk_ephemeral" - -requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ - MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/none." \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=7" \ - "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \ - 0 \ - -c "Pre-configured PSK number = 1" \ - -S "sent selected_identity:" \ - -s "key exchange mode: ephemeral" \ - -S "key exchange mode: psk_ephemeral" \ - -S "key exchange mode: psk$" \ - -s "No suitable 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 \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk." \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=8" \ - "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \ - 0 \ - -c "Pre-configured PSK number = 1" \ - -S "No suitable PSK key exchange mode" \ - -s "found matched identity" - -requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ - MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk_ephemeral." \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=9" \ - "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \ - 0 \ - -c "Pre-configured PSK number = 1" \ - -S "No suitable PSK key exchange mode" \ - -s "found matched identity" \ - -s "key exchange mode: psk_ephemeral" - -requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ - MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk_all." \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=10" \ - "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \ - 0 \ - -c "Pre-configured PSK number = 1" \ - -S "No suitable PSK key exchange mode" \ - -s "found matched identity" \ - -s "key exchange mode: psk_ephemeral" - 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 \ From e739892cf8a5a083caa3e390d64a9d251c5a6a3f Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Sun, 10 Mar 2024 12:11:02 +0100 Subject: [PATCH 173/211] ssl-opt.sh: Rework m->m resumption tests Signed-off-by: Ronald Cron --- tests/opt-testcases/tls13-misc.sh | 539 +++++++++++++++++------------- 1 file changed, 302 insertions(+), 237 deletions(-) diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh index 7fc3af9644..534ebb9630 100755 --- a/tests/opt-testcases/tls13-misc.sh +++ b/tests/opt-testcases/tls13-misc.sh @@ -138,29 +138,6 @@ run_test "TLS 1.3: G->m: PSK: configured ephemeral only, good." \ 0 \ -s "key exchange mode: ephemeral$" -requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_config_enabled MBEDTLS_DEBUG_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3: NewSessionTicket: Basic check, m->m" \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4" \ - "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \ - 0 \ - -c "Protocol is TLSv1.3" \ - -c "got new session ticket ( 3 )" \ - -c "Saving session for reuse... ok" \ - -c "Reconnecting with saved session" \ - -c "HTTP/1.0 200 OK" \ - -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \ - -s "key exchange mode: ephemeral" \ - -s "key exchange mode: psk_ephemeral" \ - -s "found pre_shared_key extension" - requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ @@ -168,333 +145,405 @@ requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: NewSessionTicket: Ticket lifetime max value (7d)" \ - "$P_SRV debug_level=1 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=604800 tickets=1" \ - "$P_CLI reco_mode=1 reconnect=1" \ - 0 \ - -c "Protocol is TLSv1.3" \ - -c "HTTP/1.0 200 OK" \ - -c "got new session ticket" \ - -c "Reconnecting with saved session... ok" \ - -s "Protocol is TLSv1.3" \ - -S "Ticket lifetime (604800) is greater than 7 days." - -requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ - MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ - MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ - MBEDTLS_DEBUG_C \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED -requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: NewSessionTicket: Ticket lifetime too long (7d + 1s)" \ - "$P_SRV debug_level=1 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=604801 tickets=1" \ - "$P_CLI reco_mode=1 reconnect=1" \ - 1 \ - -c "Protocol is TLSv1.3" \ - -C "HTTP/1.0 200 OK" \ - -C "got new session ticket" \ - -C "Reconnecting with saved session... ok" \ - -S "Protocol is TLSv1.3" \ - -s "Ticket lifetime (604801) is greater than 7 days." - -requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ - MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ - MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ - MBEDTLS_DEBUG_C \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED -requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: NewSessionTicket: ticket lifetime=0" \ - "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=0 tickets=1" \ - "$P_CLI debug_level=2 reco_mode=1 reconnect=1" \ - 1 \ - -c "Protocol is TLSv1.3" \ - -c "HTTP/1.0 200 OK" \ - -c "Discard new session ticket" \ - -C "got new session ticket" \ - -c "Reconnecting with saved session... failed" \ - -s "Protocol is TLSv1.3" \ - -s "<= write new session ticket" - -requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_config_enabled MBEDTLS_DEBUG_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3: NewSessionTicket: servername check, m->m" \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4 \ - sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \ - "$P_CLI debug_level=4 server_name=localhost reco_mode=1 reconnect=1" \ - 0 \ - -c "Protocol is TLSv1.3" \ - -c "got new session ticket." \ - -c "Saving session for reuse... ok" \ - -c "Reconnecting with saved session" \ - -c "HTTP/1.0 200 OK" \ - -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" \ - -s "key exchange mode: ephemeral" \ - -s "key exchange mode: psk_ephemeral" \ - -s "found pre_shared_key extension" - -requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS -requires_config_enabled MBEDTLS_SSL_SRV_C -requires_config_enabled MBEDTLS_SSL_CLI_C -requires_config_enabled MBEDTLS_DEBUG_C -requires_all_configs_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3: NewSessionTicket: servername negative check, m->m" \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=4 \ - sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \ - "$P_CLI debug_level=4 server_name=localhost reco_server_name=remote reco_mode=1 reconnect=1" \ - 1 \ - -c "Protocol is TLSv1.3" \ - -c "got new session ticket." \ - -c "Saving session for reuse... ok" \ - -c "Reconnecting with saved session" \ - -c "Hostname mismatch the session ticket, disable session resumption." \ - -s "=> write NewSessionTicket msg" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET" \ - -s "server state: MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET_FLUSH" - -requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \ - MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Session resumption failure, ticket authentication failed." \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=8 dummy_ticket=1" \ - "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \ +run_test "TLS 1.3 m->m: resumption" \ + "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key" \ + "$P_CLI reco_mode=1 reconnect=1" \ 0 \ - -c "Pre-configured PSK number = 1" \ - -S "sent selected_identity:" \ + -c "Protocol is TLSv1.3" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session... ok" \ + -c "HTTP/1.0 200 OK" \ + -s "Protocol is TLSv1.3" \ + -s "key exchange mode: psk" \ + -s "Select PSK ciphersuite" + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: resumption with servername" \ + "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key \ + sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \ + "$P_CLI server_name=localhost reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session... ok" \ + -c "HTTP/1.0 200 OK" \ + -s "Protocol is TLSv1.3" \ + -s "key exchange mode: psk" \ + -s "Select PSK ciphersuite" + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: resumption with ticket max lifetime (7d)" \ + "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=604800 tickets=1" \ + "$P_CLI reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session... ok" \ + -c "HTTP/1.0 200 OK" \ + -s "Protocol is TLSv1.3" \ + -s "key exchange mode: psk" \ + -s "Select PSK ciphersuite" + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: resumption fails, ticket lifetime too long (7d + 1s)" \ + "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=604801 tickets=1" \ + "$P_CLI reco_mode=1 reconnect=1" \ + 1 \ + -c "Protocol is TLSv1.3" \ + -C "Saving session for reuse... ok" \ + -c "Reconnecting with saved session... failed" \ + -S "Protocol is TLSv1.3" \ + -S "key exchange mode: psk" \ + -S "Select PSK ciphersuite" \ + -s "Ticket lifetime (604801) is greater than 7 days." + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: resumption fails, ticket lifetime=0" \ + "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key ticket_timeout=0 tickets=1" \ + "$P_CLI debug_level=2 reco_mode=1 reconnect=1" \ + 1 \ + -c "Protocol is TLSv1.3" \ + -C "Saving session for reuse... ok" \ + -c "Discard new session ticket" \ + -c "Reconnecting with saved session... failed" \ + -s "Protocol is TLSv1.3" \ + -S "key exchange mode: psk" \ + -S "Select PSK ciphersuite" + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: resumption fails, servername check failed" \ + "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key \ + sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \ + "$P_CLI debug_level=4 server_name=localhost reco_server_name=remote reco_mode=1 reconnect=1" \ + 1 \ + -c "Protocol is TLSv1.3" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -c "Hostname mismatch the session ticket, disable session resumption." \ + -s "Protocol is TLSv1.3" \ + -S "key exchange mode: psk" \ + -S "Select PSK ciphersuite" + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: resumption fails, ticket auth failed." \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=8 dummy_ticket=1" \ + "$P_CLI reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ -s "key exchange mode: ephemeral" \ - -S "key exchange mode: psk_ephemeral" \ - -S "key exchange mode: psk$" \ + -s "Protocol is TLSv1.3" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -S "key exchange mode: psk" \ -s "ticket is not authentic" \ -S "ticket is expired" \ -S "Invalid ticket creation time" \ -S "Ticket age exceeds limitation" \ -S "Ticket age outside tolerance window" -requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \ - MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Session resumption failure, ticket expired." \ +run_test "TLS 1.3 m->m: resumption fails, ticket expired." \ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=8 dummy_ticket=2" \ - "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \ + "$P_CLI reco_mode=1 reconnect=1" \ 0 \ - -c "Pre-configured PSK number = 1" \ - -S "sent selected_identity:" \ + -c "Protocol is TLSv1.3" \ -s "key exchange mode: ephemeral" \ - -S "key exchange mode: psk_ephemeral" \ - -S "key exchange mode: psk$" \ + -s "Protocol is TLSv1.3" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -S "key exchange mode: psk" \ -S "ticket is not authentic" \ -s "ticket is expired" \ -S "Invalid ticket creation time" \ -S "Ticket age exceeds limitation" \ -S "Ticket age outside tolerance window" -requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \ - MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Session resumption failure, invalid start time." \ +run_test "TLS 1.3 m->m: resumption fails, invalid creation time." \ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=8 dummy_ticket=3" \ "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \ 0 \ - -c "Pre-configured PSK number = 1" \ - -S "sent selected_identity:" \ + -c "Protocol is TLSv1.3" \ -s "key exchange mode: ephemeral" \ - -S "key exchange mode: psk_ephemeral" \ - -S "key exchange mode: psk$" \ + -s "Protocol is TLSv1.3" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -S "key exchange mode: psk" \ -S "ticket is not authentic" \ -S "ticket is expired" \ -s "Invalid ticket creation time" \ -S "Ticket age exceeds limitation" \ -S "Ticket age outside tolerance window" -requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \ - MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Session resumption failure, ticket expired. too old" \ +run_test "TLS 1.3 m->m: resumption fails, ticket expired, too old" \ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=8 dummy_ticket=4" \ "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \ 0 \ - -c "Pre-configured PSK number = 1" \ - -S "sent selected_identity:" \ + -c "Protocol is TLSv1.3" \ -s "key exchange mode: ephemeral" \ - -S "key exchange mode: psk_ephemeral" \ - -S "key exchange mode: psk$" \ + -s "Protocol is TLSv1.3" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -S "key exchange mode: psk" \ -S "ticket is not authentic" \ -S "ticket is expired" \ -S "Invalid ticket creation time" \ -s "Ticket age exceeds limitation" \ -S "Ticket age outside tolerance window" -requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \ - MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Session resumption failure, age outside tolerance window, too young." \ +run_test "TLS 1.3 m->m: resumption fails, age outside tolerance window, too young" \ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=8 dummy_ticket=5" \ "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \ 0 \ - -c "Pre-configured PSK number = 1" \ - -S "sent selected_identity:" \ + -c "Protocol is TLSv1.3" \ -s "key exchange mode: ephemeral" \ - -S "key exchange mode: psk_ephemeral" \ - -S "key exchange mode: psk$" \ + -s "Protocol is TLSv1.3" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -S "key exchange mode: psk" \ -S "ticket is not authentic" \ -S "ticket is expired" \ -S "Invalid ticket creation time" \ -S "Ticket age exceeds limitation" \ -s "Ticket age outside tolerance window" -requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_SSL_SRV_C \ - MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Session resumption failure, age outside tolerance window, too old." \ +run_test "TLS 1.3 m->m: resumption fails, age outside tolerance window, too old" \ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key tickets=8 dummy_ticket=6" \ "$P_CLI debug_level=4 reco_mode=1 reconnect=1" \ 0 \ - -c "Pre-configured PSK number = 1" \ - -S "sent selected_identity:" \ + -c "Protocol is TLSv1.3" \ -s "key exchange mode: ephemeral" \ - -S "key exchange mode: psk_ephemeral" \ - -S "key exchange mode: psk$" \ + -s "Protocol is TLSv1.3" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -S "key exchange mode: psk" \ -S "ticket is not authentic" \ -S "ticket is expired" \ -S "Invalid ticket creation time" \ -S "Ticket age exceeds limitation" \ -s "Ticket age outside tolerance window" -requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ - MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/none." \ +run_test "TLS 1.3 m->m: resumption fails, cli/tkt kex modes psk/none" \ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=7" \ "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \ 0 \ - -c "Pre-configured PSK number = 1" \ - -S "sent selected_identity:" \ + -c "Protocol is TLSv1.3" \ -s "key exchange mode: ephemeral" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: psk$" \ + -s "found matched identity" \ -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 \ +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk." \ +run_test "TLS 1.3 m->m: ephemeral over psk resumption, cli/tkt kex modes psk/psk" \ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=8" \ "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \ 0 \ - -c "Pre-configured PSK number = 1" \ - -S "No suitable PSK key exchange mode" \ - -s "found matched identity" - -requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \ - MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ - MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk_ephemeral." \ - "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=9" \ - "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \ - 0 \ - -c "Pre-configured PSK number = 1" \ - -S "sent selected_identity:" \ + -c "Protocol is TLSv1.3" \ -s "key exchange mode: ephemeral" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: psk$" \ + -s "found matched identity" \ + -S "No suitable PSK key exchange mode" \ + -S "No usable PSK or ticket" + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED +run_test "TLS 1.3 m->m: resumption fails, cli/tkt kex modes psk/psk_ephemeral" \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=9" \ + "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -s "key exchange mode: ephemeral" \ + -S "key exchange mode: psk_ephemeral" \ + -S "key exchange mode: psk$" \ + -s "found matched identity" \ -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 \ +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk/psk_all." \ +run_test "TLS 1.3 m->m: ephemeral over psk resumption, cli/tkt kex modes psk/psk_all" \ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=10" \ "$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \ 0 \ - -c "Pre-configured PSK number = 1" \ + -c "Protocol is TLSv1.3" \ + -s "key exchange mode: ephemeral" \ + -S "key exchange mode: psk_ephemeral" \ + -S "key exchange mode: psk$" \ + -s "found matched identity" \ -S "No suitable PSK key exchange mode" \ - -s "found matched identity" + -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 \ +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/none." \ +run_test "TLS 1.3 m->m: resumption fails, cli/tkt kex modes psk_ephemeral/none" \ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=7" \ "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \ 0 \ - -c "Pre-configured PSK number = 1" \ - -S "sent selected_identity:" \ + -c "Protocol is TLSv1.3" \ -s "key exchange mode: ephemeral" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: psk$" \ + -s "found matched identity" \ -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 \ +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk." \ +run_test "TLS 1.3 m->m: resumption fails, cli/tkt kex modes psk_ephemeral/psk" \ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=8" \ "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \ 0 \ - -c "Pre-configured PSK number = 1" \ - -S "sent selected_identity:" \ + -c "Protocol is TLSv1.3" \ -s "key exchange mode: ephemeral" \ -S "key exchange mode: psk_ephemeral" \ -S "key exchange mode: psk$" \ + -s "found matched identity" \ -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 \ +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk_ephemeral." \ +run_test "TLS 1.3 m->m: resumption, cli/tkt kex modes psk_ephemeral/psk_ephemeral" \ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=9" \ "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \ 0 \ - -c "Pre-configured PSK number = 1" \ - -S "No suitable PSK key exchange mode" \ + -c "Protocol is TLSv1.3" \ + -s "key exchange mode: ephemeral" \ + -s "key exchange mode: psk_ephemeral" \ + -S "key exchange mode: psk$" \ -s "found matched identity" \ - -s "key exchange mode: psk_ephemeral" + -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 \ +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_ephemeral/psk_all." \ +run_test "TLS 1.3 m->m: resumption, cli/tkt kex modes psk_ephemeral/psk_all" \ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=10" \ "$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \ 0 \ - -c "Pre-configured PSK number = 1" \ - -S "No suitable PSK key exchange mode" \ + -c "Protocol is TLSv1.3" \ + -s "key exchange mode: ephemeral" \ + -s "key exchange mode: psk_ephemeral" \ + -S "key exchange mode: psk$" \ -s "found matched identity" \ - -s "key exchange mode: psk_ephemeral" + -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 \ +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/none." \ +run_test "TLS 1.3 m->m: resumption fails, cli/tkt kex modes psk_all/none" \ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=7" \ "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \ 0 \ @@ -506,46 +555,62 @@ run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/none." \ -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 \ +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk." \ +run_test "TLS 1.3 m->m: ephemeral over psk resumption, cli/tkt kex modes psk_all/psk" \ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=8" \ "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \ 0 \ - -c "Pre-configured PSK number = 1" \ + -c "Protocol is TLSv1.3" \ + -s "key exchange mode: ephemeral" \ + -S "key exchange mode: psk_ephemeral" \ + -S "key exchange mode: psk$" \ + -s "found matched identity" \ -S "No suitable PSK key exchange mode" \ - -s "found matched identity" + -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 \ +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk_ephemeral." \ +run_test "TLS 1.3 m->m: resumption, cli/tkt kex modes psk_all/psk_ephemeral" \ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=9" \ "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \ 0 \ - -c "Pre-configured PSK number = 1" \ - -S "No suitable PSK key exchange mode" \ + -c "Protocol is TLSv1.3" \ + -s "key exchange mode: ephemeral" \ + -s "key exchange mode: psk_ephemeral" \ + -S "key exchange mode: psk$" \ -s "found matched identity" \ - -s "key exchange mode: psk_ephemeral" + -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 \ +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED -run_test "TLS 1.3 m->m: Resumption with ticket flags, psk_all/psk_all." \ +run_test "TLS 1.3 m->m: resumption, cli/tkt kex modes psk_all/psk_all" \ "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key dummy_ticket=10" \ "$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \ 0 \ - -c "Pre-configured PSK number = 1" \ - -S "No suitable PSK key exchange mode" \ + -c "Protocol is TLSv1.3" \ + -s "key exchange mode: ephemeral" \ + -s "key exchange mode: psk_ephemeral" \ + -S "key exchange mode: psk$" \ -s "found matched identity" \ - -s "key exchange mode: psk_ephemeral" + -S "No suitable PSK key exchange mode" \ + -S "No usable PSK or ticket" requires_openssl_tls1_3_with_compatible_ephemeral requires_all_configs_enabled MBEDTLS_SSL_CLI_C \ From dd2dc1578a2707d24ff516ca133def42f06bcaf4 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 15 Mar 2024 10:08:32 +0100 Subject: [PATCH 174/211] ssl-opt.sh: Add m->m resumption and early data tests Signed-off-by: Ronald Cron --- tests/opt-testcases/tls13-misc.sh | 199 ++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh index 534ebb9630..5e43921710 100755 --- a/tests/opt-testcases/tls13-misc.sh +++ b/tests/opt-testcases/tls13-misc.sh @@ -196,6 +196,205 @@ run_test "TLS 1.3 m->m: resumption with ticket max lifetime (7d)" \ -s "key exchange mode: psk" \ -s "Select PSK ciphersuite" +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +requires_ciphersuite_enabled TLS1-3-AES-256-GCM-SHA384 +run_test "TLS 1.3 m->m: resumption with AES-256-GCM-SHA384 only" \ + "$P_SRV debug_level=2 crt_file=data_files/server5.crt key_file=data_files/server5.key" \ + "$P_CLI force_ciphersuite=TLS1-3-AES-256-GCM-SHA384 reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "Ciphersuite is TLS1-3-AES-256-GCM-SHA384" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session... ok" \ + -c "HTTP/1.0 200 OK" \ + -s "Protocol is TLSv1.3" \ + -s "key exchange mode: psk" \ + -s "Select PSK ciphersuite: 1302 - TLS1-3-AES-256-GCM-SHA384" + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: resumption with early data" \ + "$P_SRV debug_level=4 early_data=1 crt_file=data_files/server5.crt key_file=data_files/server5.key" \ + "$P_CLI debug_level=3 early_data=1 reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -c "HTTP/1.0 200 OK" \ + -c "received max_early_data_size" \ + -c "NewSessionTicket: early_data(42) extension received." \ + -c "ClientHello: early_data(42) extension exists." \ + -c "EncryptedExtensions: early_data(42) extension received." \ + -c "bytes of early data written" \ + -C "0 bytes of early data written" \ + -s "Protocol is TLSv1.3" \ + -s "key exchange mode: psk" \ + -s "Select PSK ciphersuite" \ + -s "Sent max_early_data_size" \ + -s "NewSessionTicket: early_data(42) extension exists." \ + -s "ClientHello: early_data(42) extension exists." \ + -s "EncryptedExtensions: early_data(42) extension exists." \ + -s "early data bytes read" + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +requires_ciphersuite_enabled TLS1-3-AES-256-GCM-SHA384 +run_test "TLS 1.3 m->m: resumption with early data, AES-256-GCM-SHA384 only" \ + "$P_SRV debug_level=4 early_data=1 crt_file=data_files/server5.crt key_file=data_files/server5.key" \ + "$P_CLI debug_level=3 force_ciphersuite=TLS1-3-AES-256-GCM-SHA384 early_data=1 reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "Ciphersuite is TLS1-3-AES-256-GCM-SHA384" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -c "HTTP/1.0 200 OK" \ + -c "received max_early_data_size" \ + -c "NewSessionTicket: early_data(42) extension received." \ + -c "ClientHello: early_data(42) extension exists." \ + -c "EncryptedExtensions: early_data(42) extension received." \ + -c "bytes of early data written" \ + -C "0 bytes of early data written" \ + -s "Protocol is TLSv1.3" \ + -s "key exchange mode: psk" \ + -s "Select PSK ciphersuite: 1302 - TLS1-3-AES-256-GCM-SHA384" \ + -s "Sent max_early_data_size" \ + -s "NewSessionTicket: early_data(42) extension exists." \ + -s "ClientHello: early_data(42) extension exists." \ + -s "EncryptedExtensions: early_data(42) extension exists." \ + -s "early data bytes read" + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: resumption, early data cli-enabled/srv-default" \ + "$P_SRV debug_level=4 crt_file=data_files/server5.crt key_file=data_files/server5.key" \ + "$P_CLI debug_level=3 early_data=1 reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -c "HTTP/1.0 200 OK" \ + -C "received max_early_data_size" \ + -C "NewSessionTicket: early_data(42) extension received." \ + -C "ClientHello: early_data(42) extension exists." \ + -C "EncryptedExtensions: early_data(42) extension received." \ + -c "0 bytes of early data written" \ + -s "Protocol is TLSv1.3" \ + -s "key exchange mode: psk" \ + -s "Select PSK ciphersuite" \ + -S "Sent max_early_data_size" \ + -S "NewSessionTicket: early_data(42) extension exists." \ + -S "ClientHello: early_data(42) extension exists." \ + -S "EncryptedExtensions: early_data(42) extension exists." \ + -S "early data bytes read" + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: resumption, early data cli-enabled/srv-disabled" \ + "$P_SRV debug_level=4 early_data=0 crt_file=data_files/server5.crt key_file=data_files/server5.key" \ + "$P_CLI debug_level=3 early_data=1 reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -c "HTTP/1.0 200 OK" \ + -C "received max_early_data_size" \ + -C "NewSessionTicket: early_data(42) extension received." \ + -C "ClientHello: early_data(42) extension exists." \ + -C "EncryptedExtensions: early_data(42) extension received." \ + -c "0 bytes of early data written" \ + -s "Protocol is TLSv1.3" \ + -s "key exchange mode: psk" \ + -s "Select PSK ciphersuite" \ + -S "Sent max_early_data_size" \ + -S "NewSessionTicket: early_data(42) extension exists." \ + -S "ClientHello: early_data(42) extension exists." \ + -S "EncryptedExtensions: early_data(42) extension exists." \ + -S "early data bytes read" + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: resumption, early data cli-default/srv-enabled" \ + "$P_SRV debug_level=4 early_data=1 crt_file=data_files/server5.crt key_file=data_files/server5.key" \ + "$P_CLI debug_level=3 reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -c "HTTP/1.0 200 OK" \ + -c "received max_early_data_size" \ + -c "NewSessionTicket: early_data(42) extension received." \ + -C "ClientHello: early_data(42) extension exists." \ + -C "EncryptedExtensions: early_data(42) extension received." \ + -C "bytes of early data written" \ + -s "Protocol is TLSv1.3" \ + -s "key exchange mode: psk" \ + -s "Select PSK ciphersuite" \ + -s "Sent max_early_data_size" \ + -s "NewSessionTicket: early_data(42) extension exists." \ + -S "ClientHello: early_data(42) extension exists." \ + -S "EncryptedExtensions: early_data(42) extension exists." \ + -S "early data bytes read" + +requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ + MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ + MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ + MBEDTLS_SSL_EARLY_DATA MBEDTLS_DEBUG_C \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +requires_any_configs_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \ + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +run_test "TLS 1.3 m->m: resumption, early data cli-disabled/srv-enabled" \ + "$P_SRV debug_level=4 early_data=1 crt_file=data_files/server5.crt key_file=data_files/server5.key" \ + "$P_CLI debug_level=3 early_data=0 reco_mode=1 reconnect=1" \ + 0 \ + -c "Protocol is TLSv1.3" \ + -c "Saving session for reuse... ok" \ + -c "Reconnecting with saved session" \ + -c "HTTP/1.0 200 OK" \ + -c "received max_early_data_size" \ + -c "NewSessionTicket: early_data(42) extension received." \ + -C "ClientHello: early_data(42) extension exists." \ + -C "EncryptedExtensions: early_data(42) extension received." \ + -C "bytes of early data written" \ + -s "Protocol is TLSv1.3" \ + -s "key exchange mode: psk" \ + -s "Select PSK ciphersuite" \ + -s "Sent max_early_data_size" \ + -s "NewSessionTicket: early_data(42) extension exists." \ + -S "ClientHello: early_data(42) extension exists." \ + -S "EncryptedExtensions: early_data(42) extension exists." \ + -S "early data bytes read" + requires_all_configs_enabled MBEDTLS_SSL_PROTO_TLS1_3 \ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \ MBEDTLS_SSL_SESSION_TICKETS MBEDTLS_HAVE_TIME \ From e40e42cf21a3af4732babdaa5ed732733ff640e8 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 13 Mar 2024 10:31:50 +0100 Subject: [PATCH 175/211] Add change log for early data feature Signed-off-by: Ronald Cron --- ChangeLog.d/early-data.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ChangeLog.d/early-data.txt diff --git a/ChangeLog.d/early-data.txt b/ChangeLog.d/early-data.txt new file mode 100644 index 0000000000..bb4eb45d29 --- /dev/null +++ b/ChangeLog.d/early-data.txt @@ -0,0 +1,4 @@ +Features + * Mbed TLS now supports the writing and reading of TLS 1.3 early data. + Early data is supported when the configuration option + MBEDTLS_SSL_EARLY_DATA is enabled (disabled by default). From 124ed8a775970a8df882f2b9e6eef7200d353ce9 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 13 Mar 2024 10:41:37 +0100 Subject: [PATCH 176/211] tls13-support.md: Some fixes Signed-off-by: Ronald Cron --- docs/architecture/tls13-support.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/architecture/tls13-support.md b/docs/architecture/tls13-support.md index 6db0e54c39..33fe76d1a3 100644 --- a/docs/architecture/tls13-support.md +++ b/docs/architecture/tls13-support.md @@ -26,7 +26,7 @@ Support description - Mbed TLS supports ECDHE key establishment. - - Mbed TLS does not support DHE key establishment. + - Mbed TLS supports DHE key establishment. - Mbed TLS supports pre-shared keys for key establishment, pre-shared keys provisioned externally as well as provisioned via the ticket mechanism. @@ -51,7 +51,7 @@ Support description | signature_algorithms | YES | | use_srtp | no | | heartbeat | no | - | apln | YES | + | alpn | YES | | signed_certificate_timestamp | no | | client_certificate_type | no | | server_certificate_type | no | @@ -71,7 +71,8 @@ Support description Potentially all ECDHE groups: secp256r1, x25519, secp384r1, x448 and secp521r1. - Finite field groups (DHE) are not supported. + Potentially all DHE groups: + ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144 and ffdhe8192. - Supported signature algorithms (both for certificates and CertificateVerify): depends on the library configuration. @@ -105,7 +106,7 @@ Support description | Mbed TLS configuration option | Support | | ---------------------------------------- | ------- | - | MBEDTLS_SSL_ALL_ALERT_MESSAGES | no | + | MBEDTLS_SSL_ALL_ALERT_MESSAGES | yes | | MBEDTLS_SSL_ASYNC_PRIVATE | no | | MBEDTLS_SSL_CONTEXT_SERIALIZATION | no | | MBEDTLS_SSL_DEBUG_ALL | no | From 1b606d883575053e80809f7bb7d500afe365c024 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 13 Mar 2024 10:46:21 +0100 Subject: [PATCH 177/211] tls13-support.md: Early data supported now Signed-off-by: Ronald Cron --- docs/architecture/tls13-support.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/architecture/tls13-support.md b/docs/architecture/tls13-support.md index 33fe76d1a3..39c676cb1b 100644 --- a/docs/architecture/tls13-support.md +++ b/docs/architecture/tls13-support.md @@ -33,7 +33,7 @@ Support description - Mbed TLS supports session resumption via the ticket mechanism. - - Mbed TLS does not support sending or receiving early data (0-RTT data). + - Mbed TLS supports sending and receiving early data (0-RTT data). - Supported cipher suites: depends on the library configuration. Potentially all of them: @@ -59,7 +59,7 @@ Support description | key_share | YES | | pre_shared_key | YES | | psk_key_exchange_modes | YES | - | early_data | no | + | early_data | YES | | cookie | no | | supported_versions | YES | | certificate_authorities | no | @@ -173,8 +173,6 @@ Prototype upstreaming status The following parts of the TLS 1.3 prototype remain to be upstreamed: -- Sending (client) and receiving (server) early data (0-RTT data). - - New TLS Message Processing Stack (MPS) The TLS 1.3 prototype is developed alongside a rewrite of the TLS messaging layer, From d76a2d8b98836e82bd4d510b09dca586865e107b Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 13 Mar 2024 10:49:48 +0100 Subject: [PATCH 178/211] tls13-support.md: Stop referring to the prototype Signed-off-by: Ronald Cron --- docs/architecture/tls13-support.md | 42 ++---------------------------- 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/docs/architecture/tls13-support.md b/docs/architecture/tls13-support.md index 39c676cb1b..95a0ba79a4 100644 --- a/docs/architecture/tls13-support.md +++ b/docs/architecture/tls13-support.md @@ -4,17 +4,8 @@ TLS 1.3 support Overview -------- -Mbed TLS provides a partial implementation of the TLS 1.3 protocol defined in -the "Support description" section below. The TLS 1.3 support enablement -is controlled by the MBEDTLS_SSL_PROTO_TLS1_3 configuration option. - -The development of the TLS 1.3 protocol is based on the TLS 1.3 prototype -located at https://github.com/hannestschofenig/mbedtls. The prototype is -itself based on a version of the development branch that we aim to keep as -recent as possible (ideally the head) by merging regularly commits of the -development branch into the prototype. The section "Prototype upstreaming -status" below describes what remains to be upstreamed. - +Mbed TLS provides an implementation of the TLS 1.3. The TLS 1.3 support +enablement is controlled by the MBEDTLS_SSL_PROTO_TLS1_3 configuration option. Support description ------------------- @@ -168,31 +159,6 @@ Support description TLS 1.3 specification. -Prototype upstreaming status ----------------------------- - -The following parts of the TLS 1.3 prototype remain to be upstreamed: - -- New TLS Message Processing Stack (MPS) - - The TLS 1.3 prototype is developed alongside a rewrite of the TLS messaging layer, - encompassing low-level details such as record parsing, handshake reassembly, and - DTLS retransmission state machine. - - MPS has the following components: - - Layer 1 (Datagram handling) - - Layer 2 (Record handling) - - Layer 3 (Message handling) - - Layer 4 (Retransmission State Machine) - - Reader (Abstracted pointer arithmetic and reassembly logic for incoming data) - - Writer (Abstracted pointer arithmetic and fragmentation logic for outgoing data) - - Of those components, the following have been upstreamed - as part of `MBEDTLS_SSL_PROTO_TLS1_3`: - - - Reader ([`library/mps_reader.h`](../../library/mps_reader.h)) - - Coding rules checklist for TLS 1.3 ---------------------------------- @@ -265,10 +231,6 @@ TLS 1.3 specific coding rules: - the macro to check for data when reading from an input buffer `MBEDTLS_SSL_CHK_BUF_READ_PTR`. - These macros were introduced after the prototype was written thus are - likely not to be used in prototype where we now would use them in - development. - The three first types, MBEDTLS_BYTE_{0-8}, MBEDTLS_PUT_UINT{8|16|32|64}_BE and MBEDTLS_GET_UINT{8|16|32|64}_BE improve the readability of the code and reduce the risk of writing or reading bytes in the wrong order. From b372b2e5bb2949a9e96f7f152a69f9db63862894 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 13 Mar 2024 14:10:58 +0100 Subject: [PATCH 179/211] docs: Move TLS 1.3 early data doc to a dedicated file Signed-off-by: Ronald Cron --- docs/architecture/tls13-support.md | 172 ----------------------------- docs/tls13-early-data.md | 171 ++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+), 172 deletions(-) create mode 100644 docs/tls13-early-data.md diff --git a/docs/architecture/tls13-support.md b/docs/architecture/tls13-support.md index 95a0ba79a4..2ac3950295 100644 --- a/docs/architecture/tls13-support.md +++ b/docs/architecture/tls13-support.md @@ -433,175 +433,3 @@ outbound message on server side as well. * state change: the state change is done in the main state handler to ease the navigation of the state machine transitions. - - -Writing and reading early or 0-RTT data ---------------------------------------- - -An application function to write and send a buffer of data to a server through -TLS may plausibly look like: - -``` -int write_data( mbedtls_ssl_context *ssl, - const unsigned char *data_to_write, - size_t data_to_write_len, - size_t *data_written ) -{ - *data_written = 0; - - while( *data_written < data_to_write_len ) - { - ret = mbedtls_ssl_write( ssl, data_to_write + *data_written, - data_to_write_len - *data_written ); - - if( ret < 0 && - ret != MBEDTLS_ERR_SSL_WANT_READ && - ret != MBEDTLS_ERR_SSL_WANT_WRITE ) - { - return( ret ); - } - - *data_written += ret; - } - - return( 0 ); -} -``` -where ssl is the SSL context to use, data_to_write the address of the data -buffer and data_to_write_len the number of data bytes. The handshake may -not be completed, not even started for the SSL context ssl when the function is -called and in that case the mbedtls_ssl_write() API takes care transparently of -completing the handshake before to write and send data to the server. The -mbedtls_ssl_write() may not been able to write and send all data in one go thus -the need for a loop calling it as long as there are still data to write and -send. - -An application function to write and send early data and only early data, -data sent during the first flight of client messages while the handshake is in -its initial phase, would look completely similar but the call to -mbedtls_ssl_write_early_data() instead of mbedtls_ssl_write(). -``` -int write_early_data( mbedtls_ssl_context *ssl, - const unsigned char *data_to_write, - size_t data_to_write_len, - size_t *data_written ) -{ - *data_written = 0; - - while( *data_written < data_to_write_len ) - { - ret = mbedtls_ssl_write_early_data( ssl, data_to_write + *data_written, - data_to_write_len - *data_written ); - - if( ret < 0 && - ret != MBEDTLS_ERR_SSL_WANT_READ && - ret != MBEDTLS_ERR_SSL_WANT_WRITE ) - { - return( ret ); - } - - *data_written += ret; - } - - return( 0 ); -} -``` -Note that compared to write_data(), write_early_data() can also return -MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA and that should be handled -specifically by the user of write_early_data(). A fresh SSL context (typically -just after a call to mbedtls_ssl_setup() or mbedtls_ssl_session_reset()) would -be expected when calling `write_early_data`. - -All together, code to write and send a buffer of data as long as possible as -early data and then as standard post-handshake application data could -plausibly look like: - -``` -ret = write_early_data( ssl, data_to_write, data_to_write_len, - &early_data_written ); -if( ret < 0 && - ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA ) -{ - goto error; -} - -ret = write_data( ssl, data_to_write + early_data_written, - data_to_write_len - early_data_written, &data_written ); -if( ret < 0 ) - goto error; - -data_written += early_data_written; -``` - -Finally, taking into account that the server may reject early data, application -code to write and send a buffer of data could plausibly look like: -``` -ret = write_early_data( ssl, data_to_write, data_to_write_len, - &early_data_written ); -if( ret < 0 && - ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA ) -{ - goto error; -} - -/* - * Make sure the handshake is completed as it is a requisite to - * mbedtls_ssl_get_early_data_status(). - */ -while( !mbedtls_ssl_is_handshake_over( ssl ) ) -{ - ret = mbedtls_ssl_handshake( ssl ); - if( ret < 0 && - ret != MBEDTLS_ERR_SSL_WANT_READ && - ret != MBEDTLS_ERR_SSL_WANT_WRITE ) - { - goto error; - } -} - -ret = mbedtls_ssl_get_early_data_status( ssl ); -if( ret < 0 ) - goto error; - -if( ret == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED ) - early_data_written = 0; - -ret = write_data( ssl, data_to_write + early_data_written, - data_to_write_len - early_data_written, &data_written ); -if( ret < 0 ) - goto error; - -data_written += early_data_written; -``` - -Basically, the same holds for reading early data on the server side without the -complication of possible rejection. An application function to read early data -into a given buffer could plausibly look like: -``` -int read_early_data( mbedtls_ssl_context *ssl, - unsigned char *buffer, - size_t buffer_size, - size_t *data_len ) -{ - *data_len = 0; - - while( *data_len < buffer_size ) - { - ret = mbedtls_ssl_read_early_data( ssl, buffer + *data_len, - buffer_size - *data_len ); - - if( ret < 0 && - ret != MBEDTLS_ERR_SSL_WANT_READ && - ret != MBEDTLS_ERR_SSL_WANT_WRITE ) - { - return( ret ); - } - - *data_len += ret; - } - - return( 0 ); -} -``` -with again calls to read_early_data() expected to be done with a fresh SSL -context. diff --git a/docs/tls13-early-data.md b/docs/tls13-early-data.md new file mode 100644 index 0000000000..be05743556 --- /dev/null +++ b/docs/tls13-early-data.md @@ -0,0 +1,171 @@ + +Writing and reading early or 0-RTT data +--------------------------------------- + +An application function to write and send a buffer of data to a server through +TLS may plausibly look like: + +``` +int write_data( mbedtls_ssl_context *ssl, + const unsigned char *data_to_write, + size_t data_to_write_len, + size_t *data_written ) +{ + *data_written = 0; + + while( *data_written < data_to_write_len ) + { + ret = mbedtls_ssl_write( ssl, data_to_write + *data_written, + data_to_write_len - *data_written ); + + if( ret < 0 && + ret != MBEDTLS_ERR_SSL_WANT_READ && + ret != MBEDTLS_ERR_SSL_WANT_WRITE ) + { + return( ret ); + } + + *data_written += ret; + } + + return( 0 ); +} +``` +where ssl is the SSL context to use, data_to_write the address of the data +buffer and data_to_write_len the number of data bytes. The handshake may +not be completed, not even started for the SSL context ssl when the function is +called and in that case the mbedtls_ssl_write() API takes care transparently of +completing the handshake before to write and send data to the server. The +mbedtls_ssl_write() may not been able to write and send all data in one go thus +the need for a loop calling it as long as there are still data to write and +send. + +An application function to write and send early data and only early data, +data sent during the first flight of client messages while the handshake is in +its initial phase, would look completely similar but the call to +mbedtls_ssl_write_early_data() instead of mbedtls_ssl_write(). +``` +int write_early_data( mbedtls_ssl_context *ssl, + const unsigned char *data_to_write, + size_t data_to_write_len, + size_t *data_written ) +{ + *data_written = 0; + + while( *data_written < data_to_write_len ) + { + ret = mbedtls_ssl_write_early_data( ssl, data_to_write + *data_written, + data_to_write_len - *data_written ); + + if( ret < 0 && + ret != MBEDTLS_ERR_SSL_WANT_READ && + ret != MBEDTLS_ERR_SSL_WANT_WRITE ) + { + return( ret ); + } + + *data_written += ret; + } + + return( 0 ); +} +``` +Note that compared to write_data(), write_early_data() can also return +MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA and that should be handled +specifically by the user of write_early_data(). A fresh SSL context (typically +just after a call to mbedtls_ssl_setup() or mbedtls_ssl_session_reset()) would +be expected when calling `write_early_data`. + +All together, code to write and send a buffer of data as long as possible as +early data and then as standard post-handshake application data could +plausibly look like: + +``` +ret = write_early_data( ssl, data_to_write, data_to_write_len, + &early_data_written ); +if( ret < 0 && + ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA ) +{ + goto error; +} + +ret = write_data( ssl, data_to_write + early_data_written, + data_to_write_len - early_data_written, &data_written ); +if( ret < 0 ) + goto error; + +data_written += early_data_written; +``` + +Finally, taking into account that the server may reject early data, application +code to write and send a buffer of data could plausibly look like: +``` +ret = write_early_data( ssl, data_to_write, data_to_write_len, + &early_data_written ); +if( ret < 0 && + ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA ) +{ + goto error; +} + +/* + * Make sure the handshake is completed as it is a requisite to + * mbedtls_ssl_get_early_data_status(). + */ +while( !mbedtls_ssl_is_handshake_over( ssl ) ) +{ + ret = mbedtls_ssl_handshake( ssl ); + if( ret < 0 && + ret != MBEDTLS_ERR_SSL_WANT_READ && + ret != MBEDTLS_ERR_SSL_WANT_WRITE ) + { + goto error; + } +} + +ret = mbedtls_ssl_get_early_data_status( ssl ); +if( ret < 0 ) + goto error; + +if( ret == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED ) + early_data_written = 0; + +ret = write_data( ssl, data_to_write + early_data_written, + data_to_write_len - early_data_written, &data_written ); +if( ret < 0 ) + goto error; + +data_written += early_data_written; +``` + +Basically, the same holds for reading early data on the server side without the +complication of possible rejection. An application function to read early data +into a given buffer could plausibly look like: +``` +int read_early_data( mbedtls_ssl_context *ssl, + unsigned char *buffer, + size_t buffer_size, + size_t *data_len ) +{ + *data_len = 0; + + while( *data_len < buffer_size ) + { + ret = mbedtls_ssl_read_early_data( ssl, buffer + *data_len, + buffer_size - *data_len ); + + if( ret < 0 && + ret != MBEDTLS_ERR_SSL_WANT_READ && + ret != MBEDTLS_ERR_SSL_WANT_WRITE ) + { + return( ret ); + } + + *data_len += ret; + } + + return( 0 ); +} +``` +with again calls to read_early_data() expected to be done with a fresh SSL +context. From 0fce958f17db2d450d23ea49dcb938c75a187f32 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 13 Mar 2024 14:22:19 +0100 Subject: [PATCH 180/211] tls13-early-data.md: Adapt code examples to new coding style Signed-off-by: Ronald Cron --- docs/tls13-early-data.md | 112 +++++++++++++++++++++------------------ 1 file changed, 59 insertions(+), 53 deletions(-) diff --git a/docs/tls13-early-data.md b/docs/tls13-early-data.md index be05743556..28a8cc6c18 100644 --- a/docs/tls13-early-data.md +++ b/docs/tls13-early-data.md @@ -6,29 +6,28 @@ An application function to write and send a buffer of data to a server through TLS may plausibly look like: ``` -int write_data( mbedtls_ssl_context *ssl, - const unsigned char *data_to_write, - size_t data_to_write_len, - size_t *data_written ) +int write_data(mbedtls_ssl_context *ssl, + const unsigned char *data_to_write, + size_t data_to_write_len, + size_t *data_written) { + int ret; *data_written = 0; - while( *data_written < data_to_write_len ) - { - ret = mbedtls_ssl_write( ssl, data_to_write + *data_written, - data_to_write_len - *data_written ); + while (*data_written < data_to_write_len) { + ret = mbedtls_ssl_write(ssl, data_to_write + *data_written, + data_to_write_len - *data_written); - if( ret < 0 && + if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && - ret != MBEDTLS_ERR_SSL_WANT_WRITE ) - { - return( ret ); + ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + return ret; } *data_written += ret; } - return( 0 ); + return 0; } ``` where ssl is the SSL context to use, data_to_write the address of the data @@ -36,7 +35,7 @@ buffer and data_to_write_len the number of data bytes. The handshake may not be completed, not even started for the SSL context ssl when the function is called and in that case the mbedtls_ssl_write() API takes care transparently of completing the handshake before to write and send data to the server. The -mbedtls_ssl_write() may not been able to write and send all data in one go thus +mbedtls_ssl_write() may not be able to write and send all data in one go thus the need for a loop calling it as long as there are still data to write and send. @@ -45,29 +44,28 @@ data sent during the first flight of client messages while the handshake is in its initial phase, would look completely similar but the call to mbedtls_ssl_write_early_data() instead of mbedtls_ssl_write(). ``` -int write_early_data( mbedtls_ssl_context *ssl, - const unsigned char *data_to_write, - size_t data_to_write_len, - size_t *data_written ) +int write_early_data(mbedtls_ssl_context *ssl, + const unsigned char *data_to_write, + size_t data_to_write_len, + size_t *data_written) { + int ret; *data_written = 0; - while( *data_written < data_to_write_len ) - { - ret = mbedtls_ssl_write_early_data( ssl, data_to_write + *data_written, - data_to_write_len - *data_written ); + while (*data_written < data_to_write_len) { + ret = mbedtls_ssl_write_early_data(ssl, data_to_write + *data_written, + data_to_write_len - *data_written); - if( ret < 0 && + if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && - ret != MBEDTLS_ERR_SSL_WANT_WRITE ) - { - return( ret ); + ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + return ret; } *data_written += ret; } - return( 0 ); + return 0; } ``` Note that compared to write_data(), write_early_data() can also return @@ -81,18 +79,22 @@ early data and then as standard post-handshake application data could plausibly look like: ``` -ret = write_early_data( ssl, data_to_write, data_to_write_len, - &early_data_written ); -if( ret < 0 && - ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA ) -{ +ret = write_early_data(ssl, + data_to_write, + data_to_write_len, + &early_data_written); +if (ret < 0 && + ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA) { goto error; } -ret = write_data( ssl, data_to_write + early_data_written, - data_to_write_len - early_data_written, &data_written ); -if( ret < 0 ) +ret = write_data(ssl, + data_to_write + early_data_written, + data_to_write_len - early_data_written, + &data_written); +if (ret < 0) { goto error; +} data_written += early_data_written; ``` @@ -100,40 +102,44 @@ data_written += early_data_written; Finally, taking into account that the server may reject early data, application code to write and send a buffer of data could plausibly look like: ``` -ret = write_early_data( ssl, data_to_write, data_to_write_len, - &early_data_written ); -if( ret < 0 && - ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA ) -{ +ret = write_early_data(ssl, + data_to_write, + data_to_write_len, + &early_data_written); +if (ret < 0 && + ret != MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA) { goto error; } /* - * Make sure the handshake is completed as it is a requisite to + * Make sure the handshake is completed as it is a requisite of * mbedtls_ssl_get_early_data_status(). */ -while( !mbedtls_ssl_is_handshake_over( ssl ) ) -{ - ret = mbedtls_ssl_handshake( ssl ); - if( ret < 0 && +while (!mbedtls_ssl_is_handshake_over(ssl)) { + ret = mbedtls_ssl_handshake(ssl); + if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && - ret != MBEDTLS_ERR_SSL_WANT_WRITE ) - { + ret != MBEDTLS_ERR_SSL_WANT_WRITE) { goto error; } } -ret = mbedtls_ssl_get_early_data_status( ssl ); -if( ret < 0 ) +ret = mbedtls_ssl_get_early_data_status(ssl); +if (ret < 0) { goto error; +} -if( ret == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED ) +if (ret == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) { early_data_written = 0; +} -ret = write_data( ssl, data_to_write + early_data_written, - data_to_write_len - early_data_written, &data_written ); -if( ret < 0 ) +ret = write_data(ssl, + data_to_write + early_data_written, + data_to_write_len - early_data_written, + &data_written); +if (ret < 0) { goto error; +} data_written += early_data_written; ``` From d514d9c7988c39e04b3a802cd0b1ee4051b6b1c2 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 13 Mar 2024 15:19:38 +0100 Subject: [PATCH 181/211] tls13-early-data.md: Fix reading early data documentation Signed-off-by: Ronald Cron --- docs/tls13-early-data.md | 71 ++++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/docs/tls13-early-data.md b/docs/tls13-early-data.md index 28a8cc6c18..4b6f5d305c 100644 --- a/docs/tls13-early-data.md +++ b/docs/tls13-early-data.md @@ -1,6 +1,6 @@ -Writing and reading early or 0-RTT data ---------------------------------------- +Writing early data +------------------ An application function to write and send a buffer of data to a server through TLS may plausibly look like: @@ -144,34 +144,49 @@ if (ret < 0) { data_written += early_data_written; ``` -Basically, the same holds for reading early data on the server side without the -complication of possible rejection. An application function to read early data -into a given buffer could plausibly look like: +Reading early data +------------------ +Mbed TLS provides the mbedtls_ssl_read_early_data() API to read the early data +that a TLS 1.3 server might receive during the TLS 1.3 handshake. + +While establishing a TLS 1.3 connection with a client using a combination +of the mbedtls_ssl_handshake(), mbedtls_ssl_read() and mbedtls_ssl_write() APIs, +the reception of early data is signaled by an API returning the +MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA error code. Early data can then be read +with the mbedtls_ssl_read_early_data() API. + +For example, a typical code to establish a TLS connection, where ssl is the SSL +context to use: ``` -int read_early_data( mbedtls_ssl_context *ssl, - unsigned char *buffer, - size_t buffer_size, - size_t *data_len ) -{ - *data_len = 0; +while ((int ret = mbedtls_ssl_handshake(&ssl)) != 0) { - while( *data_len < buffer_size ) - { - ret = mbedtls_ssl_read_early_data( ssl, buffer + *data_len, - buffer_size - *data_len ); - - if( ret < 0 && - ret != MBEDTLS_ERR_SSL_WANT_READ && - ret != MBEDTLS_ERR_SSL_WANT_WRITE ) - { - return( ret ); - } - - *data_len += ret; + if (ret < 0 && + ret != MBEDTLS_ERR_SSL_WANT_READ && + ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + break; + } +} +``` +could be adapted to handle early data in the following way: +``` +size_t data_read_len = 0; +while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) { + + if (ret == MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA) { + ret = mbedtls_ssl_read_early_data(&ssl, + buffer + data_read_len, + sizeof(buffer) - data_read_len); + if (ret < 0) { + break; + } + data_read_len += ret; + continue; + } + + if (ret < 0 && + ret != MBEDTLS_ERR_SSL_WANT_READ && + ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + break; } - - return( 0 ); } ``` -with again calls to read_early_data() expected to be done with a fresh SSL -context. From 1987a7c0681f9c307daa4239fdea01963bbd6c28 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 14 Mar 2024 19:05:26 +0100 Subject: [PATCH 182/211] Document that we do not implement the anti-replay defenses Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 39bea79092..3a0800b36d 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -5224,6 +5224,11 @@ int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl); * same warnings apply to any use of the * early_exporter_master_secret. * + * Mbed TLS does not implement one of the anti-replay defenses + * defined in section 8 of the TLS 1.3 specification: + * single-ticket use or ClientHello recording within a given + * time window. + * * \note This function is used in conjunction with * mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(), * mbedtls_ssl_read() and mbedtls_ssl_write() to read early From a32546c96e5c12b8b4b28d22e5ec3f1c9e819368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bence=20Sz=C3=A9pk=C3=BAti?= Date: Fri, 15 Mar 2024 12:14:39 +0100 Subject: [PATCH 183/211] Update changelog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Expand MSVC to Visual Studio and announce the moving of the solution files. Signed-off-by: Bence Szépkúti --- ChangeLog.d/drop-msvc-2015-and-armcc-5.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog.d/drop-msvc-2015-and-armcc-5.txt b/ChangeLog.d/drop-msvc-2015-and-armcc-5.txt index de37c2781d..435cc98492 100644 --- a/ChangeLog.d/drop-msvc-2015-and-armcc-5.txt +++ b/ChangeLog.d/drop-msvc-2015-and-armcc-5.txt @@ -1,2 +1,5 @@ Requirement changes - * Drop support for MSVC 2013, 2015 and Arm Compiler 5. + * Drop support for Visual Studio 2013 and 2015, and Arm Compiler 5. +Changes + * Rename directory containing Visual Studio files from visualc/VS2013 to + visualc/VS2017. From e05b54229f8fdffd7adab806790dd8a0b3486bbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bence=20Sz=C3=A9pk=C3=BAti?= Date: Fri, 15 Mar 2024 12:18:04 +0100 Subject: [PATCH 184/211] Drop reference to Visual Studio 2013 from config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All supported versions of Visual Studio support AESNI, so drop the version number. Signed-off-by: Bence Szépkúti --- include/mbedtls/mbedtls_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h index 7cf4153b11..df9745a081 100644 --- a/include/mbedtls/mbedtls_config.h +++ b/include/mbedtls/mbedtls_config.h @@ -2211,7 +2211,7 @@ * Enable AES-NI support on x86-64 or x86-32. * * \note AESNI is only supported with certain compilers and target options: - * - Visual Studio 2013: supported. + * - Visual Studio: supported * - GCC, x86-64, target not explicitly supporting AESNI: * requires MBEDTLS_HAVE_ASM. * - GCC, x86-32, target not explicitly supporting AESNI: From 131b2ffd8962dae3264d98064886b83a660b6668 Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Thu, 14 Mar 2024 01:39:39 +0000 Subject: [PATCH 185/211] Fix bug in ALPN negotiating Signed-off-by: Waleed Elmelegy --- ChangeLog.d/fix-alpn-negotiating-bug.txt | 3 +++ library/ssl_tls.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 ChangeLog.d/fix-alpn-negotiating-bug.txt diff --git a/ChangeLog.d/fix-alpn-negotiating-bug.txt b/ChangeLog.d/fix-alpn-negotiating-bug.txt new file mode 100644 index 0000000000..3bceb37f38 --- /dev/null +++ b/ChangeLog.d/fix-alpn-negotiating-bug.txt @@ -0,0 +1,3 @@ +Bugfix + * Fix the restoration of the ALPN when loading serialized connection with + * the mbedtls_ssl_context_load() API. diff --git a/library/ssl_tls.c b/library/ssl_tls.c index ac8e0ea437..ffca53ed60 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -5423,7 +5423,7 @@ static int ssl_context_load(mbedtls_ssl_context *ssl, /* alpn_chosen should point to an item in the configured list */ for (cur = ssl->conf->alpn_list; *cur != NULL; cur++) { if (strlen(*cur) == alpn_len && - memcmp(p, cur, alpn_len) == 0) { + memcmp(p, *cur, alpn_len) == 0) { ssl->alpn_chosen = *cur; break; } From 4dfb0e7c90ff6079c323bba13f15297d8a157b6c Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Thu, 14 Mar 2024 01:48:40 +0000 Subject: [PATCH 186/211] Add ALPN checking when accepting early data Signed-off-by: Waleed Elmelegy --- library/ssl_tls.c | 15 ++++++++ library/ssl_tls13_server.c | 23 +++++++++++- tests/include/test/ssl_helpers.h | 7 ++++ tests/src/test_helpers/ssl_helpers.c | 6 ++++ tests/suites/test_suite_ssl.data | 16 +++++++++ tests/suites/test_suite_ssl.function | 52 ++++++++++++++++++++++++++++ 6 files changed, 118 insertions(+), 1 deletion(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index ffca53ed60..ac53853a5b 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -238,6 +238,11 @@ int mbedtls_ssl_session_copy(mbedtls_ssl_session *dst, #endif #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ +#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_ALPN) && \ + defined(MBEDTLS_SSL_EARLY_DATA) + dst->ticket_alpn = NULL; +#endif + #if defined(MBEDTLS_X509_CRT_PARSE_C) #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) @@ -275,6 +280,16 @@ int mbedtls_ssl_session_copy(mbedtls_ssl_session *dst, #endif /* MBEDTLS_X509_CRT_PARSE_C */ +#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_ALPN) && \ + defined(MBEDTLS_SSL_EARLY_DATA) + { + int ret = mbedtls_ssl_session_set_ticket_alpn(dst, src->ticket_alpn); + if (ret != 0) { + return ret; + } + } +#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_ALPN && MBEDTLS_SSL_EARLY_DATA */ + #if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) if (src->ticket != NULL) { dst->ticket = mbedtls_calloc(1, src->ticket_len); diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 2c30da8918..e8afe4509b 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -1819,7 +1819,6 @@ static int ssl_tls13_check_early_data_requirements(mbedtls_ssl_context *ssl) * NOTE: * - The TLS version number is checked in * ssl_tls13_offered_psks_check_identity_match_ticket(). - * - ALPN is not checked for the time being (TODO). */ if (handshake->selected_identity != 0) { @@ -1846,6 +1845,28 @@ static int ssl_tls13_check_early_data_requirements(mbedtls_ssl_context *ssl) return -1; } +#if defined(MBEDTLS_SSL_ALPN) + const char *alpn = mbedtls_ssl_get_alpn_protocol(ssl); + size_t alpn_len; + + if (alpn == NULL && ssl->session_negotiate->ticket_alpn == NULL) { + return 0; + } + + if (alpn != NULL) { + alpn_len = strlen(alpn); + } + + if (alpn == NULL || + ssl->session_negotiate->ticket_alpn == NULL || + alpn_len != strlen(ssl->session_negotiate->ticket_alpn) || + (memcmp(alpn, ssl->session_negotiate->ticket_alpn, alpn_len) != 0)) { + MBEDTLS_SSL_DEBUG_MSG(1, ("EarlyData: rejected, the selected ALPN is different " + "from the one associated with the pre-shared key.")); + return -1; + } +#endif + return 0; } #endif /* MBEDTLS_SSL_EARLY_DATA */ diff --git a/tests/include/test/ssl_helpers.h b/tests/include/test/ssl_helpers.h index 335386be1c..77f85c4966 100644 --- a/tests/include/test/ssl_helpers.h +++ b/tests/include/test/ssl_helpers.h @@ -78,6 +78,10 @@ enum { #undef MBEDTLS_SSL_TLS1_3_LABEL }; +#if defined(MBEDTLS_SSL_ALPN) +#define MBEDTLS_TEST_MAX_ALPN_LIST_SIZE 10 +#endif + typedef struct mbedtls_test_ssl_log_pattern { const char *pattern; size_t counter; @@ -118,6 +122,9 @@ typedef struct mbedtls_test_handshake_test_options { #if defined(MBEDTLS_SSL_CACHE_C) mbedtls_ssl_cache_context *cache; #endif +#if defined(MBEDTLS_SSL_ALPN) + const char *alpn_list[MBEDTLS_TEST_MAX_ALPN_LIST_SIZE]; +#endif } mbedtls_test_handshake_test_options; /* diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index 963938f1f8..55201c0b78 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -833,6 +833,12 @@ int mbedtls_test_ssl_endpoint_init( options->max_early_data_size); } #endif +#if defined(MBEDTLS_SSL_ALPN) + /* check that alpn_list contains at least one valid entry */ + if (options->alpn_list[0] != NULL) { + mbedtls_ssl_conf_alpn_protocols(&(ep->conf), options->alpn_list); + } +#endif #endif #if defined(MBEDTLS_SSL_CACHE_C) && defined(MBEDTLS_SSL_SRV_C) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 0ecf65c031..734b945148 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3294,6 +3294,22 @@ tls13_read_early_data:TEST_EARLY_DATA_SERVER_REJECTS TLS 1.3 read early data, discard after HRR tls13_read_early_data:TEST_EARLY_DATA_HRR +TLS 1.3 cli, early data, same ALPN +depends_on:MBEDTLS_SSL_ALPN +tls13_read_early_data:TEST_EARLY_DATA_SAME_ALPN + +TLS 1.3 cli, early data, different ALPN +depends_on:MBEDTLS_SSL_ALPN +tls13_read_early_data:TEST_EARLY_DATA_DIFF_ALPN + +TLS 1.3 cli, early data, no initial ALPN +depends_on:MBEDTLS_SSL_ALPN +tls13_read_early_data:TEST_EARLY_DATA_NO_INITIAL_ALPN + +TLS 1.3 cli, early data, no later ALPN +depends_on:MBEDTLS_SSL_ALPN +tls13_read_early_data:TEST_EARLY_DATA_NO_LATER_ALPN + TLS 1.3 cli, early data state, early data accepted tls13_cli_early_data_state:TEST_EARLY_DATA_ACCEPTED diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 2fe49979d5..67d97e47ce 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -17,6 +17,10 @@ #define TEST_EARLY_DATA_NO_INDICATION_SENT 1 #define TEST_EARLY_DATA_SERVER_REJECTS 2 #define TEST_EARLY_DATA_HRR 3 +#define TEST_EARLY_DATA_SAME_ALPN 4 +#define TEST_EARLY_DATA_DIFF_ALPN 5 +#define TEST_EARLY_DATA_NO_INITIAL_ALPN 6 +#define TEST_EARLY_DATA_NO_LATER_ALPN 7 #if (!defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \ defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) && \ @@ -3728,6 +3732,19 @@ void tls13_read_early_data(int scenario) server_options.group_list = group_list; server_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED; +#if defined(MBEDTLS_SSL_ALPN) + switch (scenario) { + case TEST_EARLY_DATA_SAME_ALPN: + case TEST_EARLY_DATA_DIFF_ALPN: + case TEST_EARLY_DATA_NO_LATER_ALPN: + client_options.alpn_list[0] = "ALPNExample"; + client_options.alpn_list[1] = NULL; + server_options.alpn_list[0] = "ALPNExample"; + server_options.alpn_list[1] = NULL; + break; + } +#endif + ret = mbedtls_test_get_tls13_ticket(&client_options, &server_options, &saved_session); TEST_EQUAL(ret, 0); @@ -3756,6 +3773,33 @@ void tls13_read_early_data(int scenario) "EarlyData: Ignore application message before 2nd ClientHello"; server_options.group_list = group_list + 1; break; +#if defined(MBEDTLS_SSL_ALPN) + case TEST_EARLY_DATA_SAME_ALPN: + client_options.alpn_list[0] = "ALPNExample"; + client_options.alpn_list[1] = NULL; + server_options.alpn_list[0] = "ALPNExample"; + server_options.alpn_list[1] = NULL; + break; + case TEST_EARLY_DATA_DIFF_ALPN: + case TEST_EARLY_DATA_NO_INITIAL_ALPN: + client_options.alpn_list[0] = "ALPNExample2"; + client_options.alpn_list[1] = NULL; + server_options.alpn_list[0] = "ALPNExample2"; + server_options.alpn_list[1] = NULL; + mbedtls_debug_set_threshold(3); + server_pattern.pattern = + "EarlyData: rejected, the selected ALPN is different " + "from the one associated with the pre-shared key."; + break; + case TEST_EARLY_DATA_NO_LATER_ALPN: + client_options.alpn_list[0] = NULL; + server_options.alpn_list[0] = NULL; + mbedtls_debug_set_threshold(3); + server_pattern.pattern = + "EarlyData: rejected, the selected ALPN is different " + "from the one associated with the pre-shared key."; + break; +#endif default: TEST_FAIL("Unknown scenario."); @@ -3807,6 +3851,9 @@ void tls13_read_early_data(int scenario) switch (scenario) { case TEST_EARLY_DATA_ACCEPTED: +#if defined(MBEDTLS_SSL_ALPN) + case TEST_EARLY_DATA_SAME_ALPN: +#endif TEST_EQUAL(ret, MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA); TEST_EQUAL(server_ep.ssl.handshake->early_data_accepted, 1); TEST_EQUAL(mbedtls_ssl_read_early_data(&(server_ep.ssl), @@ -3821,6 +3868,11 @@ void tls13_read_early_data(int scenario) case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */ case TEST_EARLY_DATA_HRR: +#if defined(MBEDTLS_SSL_ALPN) + case TEST_EARLY_DATA_DIFF_ALPN: + case TEST_EARLY_DATA_NO_INITIAL_ALPN: + case TEST_EARLY_DATA_NO_LATER_ALPN: +#endif TEST_EQUAL(ret, 0); TEST_EQUAL(server_ep.ssl.handshake->early_data_accepted, 0); TEST_EQUAL(server_pattern.counter, 1); From a69572b437695823f085e7f73b7a2b90cb826667 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 12 Mar 2024 15:24:34 +0100 Subject: [PATCH 187/211] pk_import_into_psa: test persistent keys Test the behavior of mbedtls_pk_get_psa_attributes() and mbedtls_pk_import_into_psa() with respect to lifetime. In particular, test that they work with persistent keys as documented. Test cases generated by the following script: ``` for old in [('transparent', '0:0:1'), ('opaque volatile [export]', '1:0:1'), ('opaque volatile [copy]', '1:0:0'), ('opaque persistent [export]', '1:1:1'), ('opaque persistent [copy]', '1:1:0')]: for to_public in [('pair', '0'), ('public', '1')]: for to_persistent in [('volatile', '0'), ('persistent', '1')]: depends = ('\ndepends_on:MBEDTLS_USE_PSA_CRYPTO' if old[0].startswith('opaque') else '') print(f"""\ PSA import into PSA: {old[0]} -> {to_persistent[0]} {to_public[0]}{depends} pk_import_into_psa_lifetime:{old[1]}:{to_public[1]}:{to_persistent[1]} """) ``` Signed-off-by: Gilles Peskine --- tests/suites/test_suite_pk.data | 76 +++++++++++++++++++++++++ tests/suites/test_suite_pk.function | 87 ++++++++++++++++++++++++++++- 2 files changed, 162 insertions(+), 1 deletion(-) diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data index 989235dec7..b88bd08906 100644 --- a/tests/suites/test_suite_pk.data +++ b/tests/suites/test_suite_pk.data @@ -1306,6 +1306,82 @@ PSA import into PSA: ECDSA public to pair (bad) depends_on:MBEDTLS_PK_HAVE_ECC_KEYS:MBEDTLS_TEST_PSA_ECC_AT_LEAST_ONE_CURVE:MBEDTLS_PK_CAN_ECDSA_SOME pk_import_into_psa_fail:MBEDTLS_PK_ECDSA:FROM_PUBLIC:PSA_KEY_TYPE_ECC_KEY_PAIR(MBEDTLS_TEST_PSA_ECC_ONE_FAMILY):0:MBEDTLS_ERR_PK_TYPE_MISMATCH +PSA import into PSA: transparent -> volatile pair +pk_import_into_psa_lifetime:0:0:1:0:0 + +PSA import into PSA: transparent -> persistent pair +pk_import_into_psa_lifetime:0:0:1:0:1 + +PSA import into PSA: transparent -> volatile public +pk_import_into_psa_lifetime:0:0:1:1:0 + +PSA import into PSA: transparent -> persistent public +pk_import_into_psa_lifetime:0:0:1:1:1 + +PSA import into PSA: opaque volatile [export] -> volatile pair +depends_on:MBEDTLS_USE_PSA_CRYPTO +pk_import_into_psa_lifetime:1:0:1:0:0 + +PSA import into PSA: opaque volatile [export] -> persistent pair +depends_on:MBEDTLS_USE_PSA_CRYPTO +pk_import_into_psa_lifetime:1:0:1:0:1 + +PSA import into PSA: opaque volatile [export] -> volatile public +depends_on:MBEDTLS_USE_PSA_CRYPTO +pk_import_into_psa_lifetime:1:0:1:1:0 + +PSA import into PSA: opaque volatile [export] -> persistent public +depends_on:MBEDTLS_USE_PSA_CRYPTO +pk_import_into_psa_lifetime:1:0:1:1:1 + +PSA import into PSA: opaque volatile [copy] -> volatile pair +depends_on:MBEDTLS_USE_PSA_CRYPTO +pk_import_into_psa_lifetime:1:0:0:0:0 + +PSA import into PSA: opaque volatile [copy] -> persistent pair +depends_on:MBEDTLS_USE_PSA_CRYPTO +pk_import_into_psa_lifetime:1:0:0:0:1 + +PSA import into PSA: opaque volatile [copy] -> volatile public +depends_on:MBEDTLS_USE_PSA_CRYPTO +pk_import_into_psa_lifetime:1:0:0:1:0 + +PSA import into PSA: opaque volatile [copy] -> persistent public +depends_on:MBEDTLS_USE_PSA_CRYPTO +pk_import_into_psa_lifetime:1:0:0:1:1 + +PSA import into PSA: opaque persistent [export] -> volatile pair +depends_on:MBEDTLS_USE_PSA_CRYPTO +pk_import_into_psa_lifetime:1:1:1:0:0 + +PSA import into PSA: opaque persistent [export] -> persistent pair +depends_on:MBEDTLS_USE_PSA_CRYPTO +pk_import_into_psa_lifetime:1:1:1:0:1 + +PSA import into PSA: opaque persistent [export] -> volatile public +depends_on:MBEDTLS_USE_PSA_CRYPTO +pk_import_into_psa_lifetime:1:1:1:1:0 + +PSA import into PSA: opaque persistent [export] -> persistent public +depends_on:MBEDTLS_USE_PSA_CRYPTO +pk_import_into_psa_lifetime:1:1:1:1:1 + +PSA import into PSA: opaque persistent [copy] -> volatile pair +depends_on:MBEDTLS_USE_PSA_CRYPTO +pk_import_into_psa_lifetime:1:1:0:0:0 + +PSA import into PSA: opaque persistent [copy] -> persistent pair +depends_on:MBEDTLS_USE_PSA_CRYPTO +pk_import_into_psa_lifetime:1:1:0:0:1 + +PSA import into PSA: opaque persistent [copy] -> volatile public +depends_on:MBEDTLS_USE_PSA_CRYPTO +pk_import_into_psa_lifetime:1:1:0:1:0 + +PSA import into PSA: opaque persistent [copy] -> persistent public +depends_on:MBEDTLS_USE_PSA_CRYPTO +pk_import_into_psa_lifetime:1:1:0:1:1 + PSA import into PSA: opaque RSA, COPY (ok) depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_SIGN pk_import_into_psa_opaque:PSA_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_RSA_GEN_KEY_MIN_BITS:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_RSA_GEN_KEY_MIN_BITS:PSA_KEY_USAGE_COPY | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_SIGN_MESSAGE:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:0 diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 180cf76394..5ebe1469d4 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -2030,6 +2030,92 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:MBEDTLS_TEST_PSA_ECC_AT_LEAST_ONE_CURVE:MBEDTLS_PSA_CRYPTO_STORAGE_C */ +void pk_import_into_psa_lifetime(int from_opaque, + int from_persistent, /* when from opaque */ + int from_exportable, /* when from opaque */ + int to_public, + int to_persistent) +{ + mbedtls_pk_context pk; + mbedtls_pk_init(&pk); + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + mbedtls_svc_key_id_t old_key_id = MBEDTLS_SVC_KEY_ID_INIT; + mbedtls_svc_key_id_t new_key_id = MBEDTLS_SVC_KEY_ID_INIT; + mbedtls_svc_key_id_t expected_key_id = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_lifetime_t expected_lifetime = PSA_KEY_LIFETIME_VOLATILE; + + PSA_INIT(); + + if (from_opaque) { +#if defined(MBEDTLS_USE_PSA_CRYPTO) + psa_key_type_t from_psa_type = + PSA_KEY_TYPE_ECC_KEY_PAIR(MBEDTLS_TEST_PSA_ECC_ONE_FAMILY); + psa_set_key_type(&attributes, from_psa_type); + psa_set_key_bits(&attributes, MBEDTLS_TEST_PSA_ECC_ONE_CURVE_BITS); + psa_set_key_usage_flags( + &attributes, + (from_exportable ? PSA_KEY_USAGE_EXPORT : PSA_KEY_USAGE_COPY) | + PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&attributes, PSA_ALG_ECDH); + if (from_persistent) { + psa_set_key_id(&attributes, mbedtls_svc_key_id_make(0, 1)); + } + PSA_ASSERT(psa_generate_key(&attributes, &old_key_id)); + TEST_EQUAL(mbedtls_pk_setup_opaque(&pk, old_key_id), 0); + psa_reset_key_attributes(&attributes); +#else + (void) from_persistent; + (void) from_exportable; + TEST_FAIL("Attempted to test opaque key without opaque key support"); +#endif + } else { + psa_key_type_t psa_type_according_to_setup; + TEST_EQUAL(pk_setup_for_type(MBEDTLS_PK_ECKEY, 1, + &pk, &psa_type_according_to_setup), 0); + } + + if (to_persistent) { + expected_key_id = mbedtls_svc_key_id_make(42, 2); + psa_set_key_id(&attributes, expected_key_id); + /* psa_set_key_id() sets the lifetime to PERSISTENT */ + expected_lifetime = PSA_KEY_LIFETIME_PERSISTENT; + } + + psa_key_usage_t to_usage = + to_public ? PSA_KEY_USAGE_VERIFY_HASH : PSA_KEY_USAGE_SIGN_HASH; + TEST_EQUAL(mbedtls_pk_get_psa_attributes(&pk, to_usage, + &attributes), 0); + /* mbedtls_pk_get_psa_attributes() is specified to not modify + * the persistence attributes. */ + TEST_EQUAL(psa_get_key_lifetime(&attributes), expected_lifetime); + TEST_EQUAL(MBEDTLS_SVC_KEY_ID_GET_KEY_ID(psa_get_key_id(&attributes)), + MBEDTLS_SVC_KEY_ID_GET_KEY_ID(expected_key_id)); + + TEST_EQUAL(mbedtls_pk_import_into_psa(&pk, &attributes, &new_key_id), 0); + if (!mbedtls_test_key_consistency_psa_pk(new_key_id, &pk)) { + goto exit; + } + + PSA_ASSERT(psa_get_key_attributes(new_key_id, &attributes)); + TEST_EQUAL(psa_get_key_lifetime(&attributes), expected_lifetime); + /* Here expected_key_id=0 for a volatile key, but we expect + * attributes to contain a dynamically assigned key id which we + * can't predict. */ + if (to_persistent) { + TEST_ASSERT(mbedtls_svc_key_id_equal(psa_get_key_id(&attributes), + expected_key_id)); + } + +exit: + mbedtls_pk_free(&pk); + psa_reset_key_attributes(&attributes); + psa_destroy_key(old_key_id); + psa_destroy_key(new_key_id); + PSA_DONE(); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_USE_PSA_CRYPTO */ void pk_get_psa_attributes_opaque(int from_type_arg, int from_bits_arg, int from_usage_arg, int from_alg_arg, @@ -2056,7 +2142,6 @@ void pk_get_psa_attributes_opaque(int from_type_arg, int from_bits_arg, psa_set_key_usage_flags(&attributes, from_usage); psa_set_key_algorithm(&attributes, alg); psa_set_key_enrollment_algorithm(&attributes, 42); - //TODO: test with persistent key PSA_ASSERT(psa_generate_key(&attributes, &old_key_id)); TEST_EQUAL(mbedtls_pk_setup_opaque(&pk, old_key_id), 0); From 78279962d6e1025d0e1883269b10e271a8de73c9 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Fri, 15 Mar 2024 13:34:01 +0000 Subject: [PATCH 188/211] Fix minor style issues Signed-off-by: Paul Elliott --- library/psa_crypto.c | 1 - library/psa_crypto_slot_management.c | 1 - 2 files changed, 2 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 88842678f5..dd638de92c 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -7675,7 +7675,6 @@ static psa_status_t mbedtls_psa_crypto_init_subsystem(mbedtls_psa_crypto_subsyst &mbedtls_threading_psa_rngdata_mutex)); #endif /* defined(MBEDTLS_THREADING_C) */ - break; case PSA_CRYPTO_SUBSYSTEM_TRANSACTION: diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 6a51644027..b184ed08c9 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -36,7 +36,6 @@ static psa_global_data_t global_data; static uint8_t psa_get_key_slots_initialized(void) { - uint8_t initialized; #if defined(MBEDTLS_THREADING_C) From 933aec86fdbc4e1e6bec6de0f5f9463415b91ff2 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 15 Mar 2024 10:43:56 +0100 Subject: [PATCH 189/211] Remove experimental warnings related to early data Signed-off-by: Ronald Cron --- include/mbedtls/mbedtls_config.h | 7 ------- include/mbedtls/ssl.h | 6 ------ 2 files changed, 13 deletions(-) diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h index feb2054902..60f24105da 100644 --- a/include/mbedtls/mbedtls_config.h +++ b/include/mbedtls/mbedtls_config.h @@ -1854,9 +1854,6 @@ * Comment this to disable support for early data. If MBEDTLS_SSL_PROTO_TLS1_3 * is not enabled, this option does not have any effect on the build. * - * This feature is experimental, not completed and thus not ready for - * production. - * * \note The maximum amount of early data can be set with * MBEDTLS_SSL_MAX_EARLY_DATA_SIZE. * @@ -4145,10 +4142,6 @@ * * If MBEDTLS_SSL_EARLY_DATA is not defined, this default value does not * have any impact on the build. - * - * This feature is experimental, not completed and thus not ready for - * production. - * */ //#define MBEDTLS_SSL_MAX_EARLY_DATA_SIZE 1024 diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 3a0800b36d..46a624e864 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -2097,9 +2097,6 @@ void mbedtls_ssl_conf_authmode(mbedtls_ssl_config *conf, int authmode); * MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA indicating that some early data have * been received. To read the early data, call mbedtls_ssl_read_early_data() * before calling the original function again. - * - * \warning This interface is experimental and may change without notice. - * */ void mbedtls_ssl_conf_early_data(mbedtls_ssl_config *conf, int early_data_enabled); @@ -2125,12 +2122,9 @@ void mbedtls_ssl_conf_early_data(mbedtls_ssl_config *conf, * \param[in] conf The SSL configuration to use. * \param[in] max_early_data_size The maximum amount of 0-RTT data. * - * \warning This interface is experimental and may change without notice. - * * \warning This interface DOES NOT influence/limit the amount of early data * that can be received through previously created and issued tickets, * which clients may have stored. - * */ void mbedtls_ssl_conf_max_early_data_size( mbedtls_ssl_config *conf, uint32_t max_early_data_size); From 582865fbfb970bd043a62caa60ce9d94f43acb71 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 15 Mar 2024 14:48:34 +0100 Subject: [PATCH 190/211] Improve the change log Signed-off-by: Ronald Cron --- ChangeLog.d/early-data.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ChangeLog.d/early-data.txt b/ChangeLog.d/early-data.txt index bb4eb45d29..3c3826c954 100644 --- a/ChangeLog.d/early-data.txt +++ b/ChangeLog.d/early-data.txt @@ -1,4 +1,5 @@ Features - * Mbed TLS now supports the writing and reading of TLS 1.3 early data. - Early data is supported when the configuration option - MBEDTLS_SSL_EARLY_DATA is enabled (disabled by default). + * Mbed TLS now supports the writing and reading of TLS 1.3 early data (see + docs/tls13-early-data.md). The support enablement is controlled at build + time by the MBEDTLS_SSL_EARLY_DATA configuration option and at runtime by + the mbedtls_ssl_conf_early_data() API (by default disabled in both cases). From 3996ebc037f8d5bdc7d2c35aea65b3d86faee87b Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 15 Mar 2024 14:57:05 +0100 Subject: [PATCH 191/211] Fix documentation about anti-replay defenses Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 46a624e864..429127893e 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -5218,10 +5218,10 @@ int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl); * same warnings apply to any use of the * early_exporter_master_secret. * - * Mbed TLS does not implement one of the anti-replay defenses + * \warning Mbed TLS does not implement any of the anti-replay defenses * defined in section 8 of the TLS 1.3 specification: - * single-ticket use or ClientHello recording within a given - * time window. + * single-use of tickets or ClientHello recording within a + * given time window. * * \note This function is used in conjunction with * mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(), From a9bdc8fbb8b26112115b9fd735bd2c1226d52db5 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 15 Mar 2024 15:52:04 +0100 Subject: [PATCH 192/211] Improve tls13-support.md Signed-off-by: Ronald Cron --- docs/architecture/tls13-support.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/architecture/tls13-support.md b/docs/architecture/tls13-support.md index 2ac3950295..d6fc19e4a3 100644 --- a/docs/architecture/tls13-support.md +++ b/docs/architecture/tls13-support.md @@ -4,8 +4,8 @@ TLS 1.3 support Overview -------- -Mbed TLS provides an implementation of the TLS 1.3. The TLS 1.3 support -enablement is controlled by the MBEDTLS_SSL_PROTO_TLS1_3 configuration option. +Mbed TLS provides an implementation of the TLS 1.3 protocol. The TLS 1.3 support +may be enabled using the MBEDTLS_SSL_PROTO_TLS1_3 configuration option. Support description ------------------- From 0db6a9033aed3bd10975c898b850ebf8343b1690 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Fri, 15 Mar 2024 13:48:20 +0000 Subject: [PATCH 193/211] Start subsystem IDs at 1 instead of 0 Catch potential invalid calls to init. Signed-off-by: Paul Elliott --- library/psa_crypto.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index dd638de92c..c28937df14 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -93,8 +93,10 @@ static int key_type_is_raw_bytes(psa_key_type_t type) #define RNG_INITIALIZED 1 #define RNG_SEEDED 2 +/* IDs for PSA crypto subsystems. Starts at 1 to catch potential uninitialized + * variables as arguments. */ typedef enum { - PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS = 0, + PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS = 1, PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS, PSA_CRYPTO_SUBSYSTEM_RNG, PSA_CRYPTO_SUBSYSTEM_TRANSACTION, From d35dce6e235dd0c7818949d0954b1bdcaadfea52 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Fri, 15 Mar 2024 13:57:16 +0000 Subject: [PATCH 194/211] Add comments about RNG mutex requirements Signed-off-by: Paul Elliott --- library/psa_crypto.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index c28937df14..373918a885 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -7145,6 +7145,9 @@ exit: #endif /** Initialize the PSA random generator. + * + * Note: the mbedtls_threading_psa_rngdata_mutex should be held when calling + * this function if mutexes are enabled. */ static void mbedtls_psa_random_init(mbedtls_psa_random_context_t *rng) { @@ -7177,6 +7180,9 @@ static void mbedtls_psa_random_init(mbedtls_psa_random_context_t *rng) } /** Deinitialize the PSA random generator. + * + * Note: the mbedtls_threading_psa_rngdata_mutex should be held when calling + * this function if mutexes are enabled. */ static void mbedtls_psa_random_free(mbedtls_psa_random_context_t *rng) { From b24e36d07b16e2e4c7f6341f5e033ed7f4ac773f Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Fri, 15 Mar 2024 16:25:48 +0000 Subject: [PATCH 195/211] Add explanatory comment for init flags Signed-off-by: Paul Elliott --- library/psa_crypto.c | 1 + 1 file changed, 1 insertion(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 373918a885..a0a002a088 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -102,6 +102,7 @@ typedef enum { PSA_CRYPTO_SUBSYSTEM_TRANSACTION, } mbedtls_psa_crypto_subsystem; +/* Initialization flags for global_data::initialized */ #define PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED 0x01 #define PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED 0x02 #define PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED 0x04 From c408ef463ca37f3cc0c9af7b79142997841ef683 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Fri, 15 Mar 2024 17:29:46 +0000 Subject: [PATCH 196/211] Update slot transition diagram Adds missing transition and italicises internal functions Signed-off-by: Ryan Everett --- .../key-slot-state-transitions.png | Bin 71568 -> 50367 bytes .../psa-thread-safety/psa-thread-safety.md | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/architecture/psa-thread-safety/key-slot-state-transitions.png b/docs/architecture/psa-thread-safety/key-slot-state-transitions.png index 1b50e7395d78051d20524568475128ea82228aa7..08e4cc080e8e14e4f27d661f47ca368d4eea6664 100644 GIT binary patch literal 50367 zcmYhjcRZEvA3uH{hajt4mkom;w3%~qyJY98qgNo^>4c}Xe1IHw%+y#LBn z#qr^8lSRY$ePy0A}PCTl%rjgygzdNX-ncbA?SX^74m;3%k z66P71((%u;rnA!{&QtG`oso*Bvy=6uL+OQNG2^E{f-8Q%H5N1uIQU(0B{x}AoQ>ri z)pNvcxM?A-lp|$kQj4hT`0i5R(ZozSgYHvy-N?_-o}|m&a_99=$E995!N`iYh3syDGE(>2EnHhoA6K z>e)f6Q_`cVrNv{B2miYbr3SbSBDdP}B!2-*3BmATQqxb#(0=Q_Gmi1j%Pf02NzSUv z2OF(413ovXKKwDVGNJ$9;yf6Qu#h8`gDml>}A%Jg9Ci%^BB=NNZ(K&t=l*p-PqvkPhhnA)(dG22vY%QwWjDG9%=S=n}4#wb3p~$2Kt0vMe%C zZD*YDEl+!1i>y68T&}oQJt=zhTPQH`WR9tc@Av8TowIqVCKV;CAw7d4ZyKoQ7Aae- z!>Auvy=(O|{3V}6do@qD;+w1}u6?}kx!KNSi)Zw_=Wy_xP9uTs2_80fW4SO!c5l*c z?Ce1PjFS<(#5uc3z5R!vJMpV}mthphaLfB2RC=`3!=R{rRL=byY> zn*lX3b)u@%8AHqPxZ%9xm=i`z#l#us{GutAzuB zd48s{ESd3MNLewSIn*b*Gfe);XaE$F7V$&$yQjH&GH_N6YQ1_oFNmL;4{x$P7@Jh{3g z&L!SQ!LrDG^!?h=m6Iph()E4^Y!j}D6BC5KIexsu&Khe2>LPdjAHqK2E_;aFD4 zBhkX#2}Euswe#=DguDJ6u6Z>j<)ww;Fu(3HTgSS~%6^AcA@0L!x-?`~WBnIoW>gA^ zY$%Y;-54({%hpQ8H=bSFI6eKm8r`3+Wf1j%I;RRkn`&fi76GF1;BzKPOn5Sk|P9? zcJ^B%%;0RlQ(hF!2UcVioZ+MIkB&z5(1@uB*UmQOk~N-NdzLoHM?JxTSSX}Jo;cz9 zW*eQc=S0{I%g5pH+@X^A5G}bx%Hf~wi5gUkoGNHp0hvY2kvXxyJ$GU}l;pFIgOZPvXAPSMyi3c-X^jh>g4 z<^f3mLYmTTu(h(A_IeWdn>tk;+m)Ztk@@}ZPqfQ;N$X1_ZeT>pbU)J#dO1w<(fq|) z*BAL zb5){`Ca$n!eso|=L=a{~9pMG9lN44+FnAJ@wkJ~<#2Pp|ZKwx7_kTt_bdjNl|B~yT zVw~ih7efrUz6VvN;j{HNcv{>W7Q^wQKSn`?Pj~a$SBdv z$F;xTeq@xbsPV`0Qc`mYGG@KQC}Urwo*ggP3ohq4b~N_iC@lFdjlJVYa=GoV3Fz%F zz0(6%Xl&X{L^p(aP1GZ9ZYlRmc;>&GeEKt-VUHqc=lfj_>-zOZ-&d_JLhhZF!FjZq z65nqA&Dv#|!`;3OpUQ{LTzS(NCj#Y9|$QmZkO2>u(bD^Gl?{S!Va;8%{O`$p8xS7mU9F(-+N@KQ5d_> z`5x0!Y9FI^FvfKlSo1jc!hCw!p z=t6IsclJ5AXo9uy0^3ZERi_!}3{vPGa5qo>x>ed+7;j9yu_%;4!!dNz&O1%Itv9qc z$|a5z7O(gXK4nbU;ZrP6_IIewIm$jZCYj5R7wzo6d1!=c9V*-IznAO7Ze2t-urmD0 z9N!Izt$u(6;4fu3x&DE$SW`H)E)u!s>Z~hK+!FBdTY&qP_myjr7yS4_KgK<{k)rEY zFt1&$NcnugTls&8%TEVBw~9qdd}s?iS-dMxezf^m!sGP`A9v(;{5|Lwh0v$_@2cRd zhc#Uo?d{bT3Lz)^4(FtHoA|qY-BgO~xyCui(PmXNL5R zi#DiGGCSqnlTpQmUseD6#6=IPMH~;c(mXdpDLludB_QnB-96}pk1bM5M6%b3_^+BM3Lt}cg+RNA*aPLm*q1@ye|?Mw7oCX5j{Um`>AUrrH}~?ROEZHIwv%Zx|Jl>@ zpM7Ysi1)3iLaEwXKD?r8<2z@h-V!i4{aJJ(q90;jawBi}{FN-P7&d0o-R-4wur#{< z?~*h{~B|$y?(}Z(hbruDG&F`HcsGqan+=>C3m=Z3j_O_gB%O8MiDufBg#`R$>C{3d^Pto&u#;`KG{ zJ)hYXnVAEPs&8^fR*oeNyUHVr`bE!92nfh2<0X&7uPRdiN6f2tuV5*Eg=?6&e&!}^ zkZ#ykh~xJHjd=w}%D$LA@y3@5Otnr8zL4yuK_mhwlMRswo#suKRjCfcr$`tYzrzW=>$$##ZkBz=f?PJHR(4f(J`rn|HvpoxXXImOQj{ zu?G7>IF=<+Bq;a+21i00`kk`+!BXtW2YSwm)v5`b++pg5VDYH`+lXUdfH(l-o^Xh8D9)Typf(yAhsAhC$m2rWGrW&yK?s$sx<(n zD;jaw?NCtk_D@D$hgnu3x1&JP37>eReYU7$c4xYEiJQ7=l<#8t zi^k2CRnWng&e#AD$U7|M^T_i8EOa*1(e!8g?NnMS_Pr^unU!Wz4mHITMq{V4ZP5{9 z4)e6?MjfF|^m1qu&A+YeFOi1HT~ABX7Eqg6w<-`HQauvsd*=X46lyvaO?upTP`(~` zb~N@zW-Xx?^oud>c#~-I!!qs_&F|Q-qiZpQan}BPBU9e6JI;TAOo}t2c^CFUAD&2H zG{#m@iv8mRy7uw75#0el4&pdQkyMfumWO;1YP#7lIC%?zZrh6LxS$t<}Hv-<()@?<-h)_!w|IfcoUVFdEsV zZx?;L_X-jvv~Nk!yuuS4V$>y7tnUs+F%vj{M?O1$enBt=ngCa^+VNq?jevk-X(H_W%QJsPq5UNFqA*t zj1Y4n0t=yGYP2n9uHiLi9bZ@c__w0Q_qFT`%{*}LH8+&0xTy13al3eEQ1cDTO9V#p zcCrOfzjxIBVm-nNIfae7tBu&4xZO-{3c)dybvZ{cLX<#1clVmkWWPK1supe6c-Fjy z5(#_}7yqO6MXrw3nvs$J&JZ2`DL^eslZ^6t%b`qDOBD~arVM<28%HD8MzBWrY*YO` z>$El>EH1wmYP|k4b0LW-UiimzI-5W45Y3`9@2|TY{^C01Q%6-DERMRmgCh?EQ;zq; zIyD2fV(z>=0|Zo)*TVUJPpZNTk?im9lA^ST(E8+-)cb0HMltgsP_DgK3ksvB0Oov| zxLI$sX+E4Yd8{VZ8~fi6Q+bs0YTa`2J&tN)=i2NsV~t$YPv0?xx`*&xR>;Os_F)+B&vg6u zdtFDwJ)vySIpjE?;&Le#Fxs`tO6l*mJtCg+iqKPjvZXwyr8Ld5e^5OWaOBjmGkg!L z+G?=8u}66-P|*_&QDzG1KZBhOl?23f6vWjM;X^rp=1Wj>$O&8C+$5z&_>4g8@4aUg zwUl}9ZQ8Lu`l!`zJkYK1M6N-4>L}$XjRqg~ng|ceB0h$Tk1|pYUATKOs#tz!P-h?= z)}=#Al0Y;L(f2yLnTC>W`a=DqPpnf0Qt{4*40M=FR0s}x-I zc{nCcFMLBy`Pdi%TvxW65%GZM=mL6vMpH+InVF^_e*B74cAUN{hbl)|JJZ9P{`eHs z5&7`^j~5)y%#r2^$({;z#&9H^Qp5!Jpyk7V0 zw6Av{Ewj8K`ko7zXFD*BE>O4=6X=y_9VtuAP1Pqt$t|ndMixHjY#6sjy;5Fj{R+MR&y;b?Ho!cmHOx*Nmr>N^{iq%sFnKKK??0% zzi6;NFu5GLd^!COwj57m3l`lI)rpu%ilw6}pG94vlQ7(7%3fSP`cqI69c8Ol7C@Xf z>o7N61IUc16Gy8bP@H&k&MO36!Xr-)N18NH#0ompI;cj_oouI{+-OW$-gAI zv2-I*-Y}k&R{+@jC3g2a?}q7}jrl|@%hU&Sskg{D)n_7Gtl3oasez}&>@^sx#}GO3 zhb@|%PFW%qZ1~LgTN2G#PhP8w^@=mg60r=g$+o@ywP!8pL;-ud$a?((eBsFA;`+y+ zpo1NXmQmqz9Th^SO}?mZK}dPh0D0B7bfbmB7CQ*q%lpZv*0g(nCguY~0#eRHhCPgt zDjh&k{78yTe{5ITM=U6`CbL}WWfE7UT)NmMyO+}HyYQg7xXP&8N}im`%80peh%YiP zc5NR1hJBqQZCT-M=jJaDt1V>W@sHagV#Lysn`bF=$5IXxqZ<8ujzVKEdEbw2yS>!5 zO&Cwf8QH#ViOrFiWwt7GV~U`>Ab4T+c|r7-m$>aHTRSYWj2lUTMc=P8WK>h-hWQ~~ z*3MHtTTo3GQVWT=g1USPS7_NUsr!>}Z{{L1df7#~qw|ia;OHfehigJjt-7wwn5$P` zGIArCi!aZfv&7-b1F$%ln<3O=5)%af%U7p=uW(8Rlu9Njyr8>2ROJ#S+etq&I>fv^ z;X_bMcJ?Vf#9MH$hX#B5t|2QbSa7j70sR});Mn2EX3LC@L0WjO>%aJt@Dip77xZ7X zmzplZ1tcuS-tx7^WJla`uZ|*5bKm>?5m&!uXiYAxYm!?XXuUgDc5x6d%H`R!+(r z#n#-#wNIL(BWDO)dW;}CcQB?#cLtFOAl@YppO{{&1>iR39!2OD>kHaqN&GW&9z#Z- zU)n7gbKB(SOB6|Py!5Xp6=S4LOtb5ybC9I~=I+Y*CvBrdiM#OYZQVrZHgjb)I{ox6 zBD}dcB)G)|*F*N2$N9q-8Y<1!^Y(@U>*a(T%Uh{sxNORrVm}Aavvj$ar)lv%#B22GHjmU39FUz*q zvAIo5d)(&mm~-^M#`3UjXf)#d1qE)j=_h(d_Ig`NOCnaHrn1nN{p$0zF4k-GP8JE2mjZ1KD zKiS0ZyBoL~4gQ!9iE^(iQ|wAxa;Es*S`kN2S_5|K?{8^P#_yiB<1*z8HB)Oq~i-YKh~ z`K`lAhoKHSDPFU#JsjqIEvCI}tm)I1-O7C&fftT}atzV)8=kLcH#yn=P`^q^$uG^ycBHx{E2kF5rS5juR6d)~HD=<)7>x>VO-zJ^f8~#RT)L8z;7W zK9wYE9{sh(x`HE^RMaozK-b&Cnn;-X_w0LJyUz zNE}_#SA0_KRO^6N!WPy<6A_;Hlm|!Ad_LVuQ)_r;sM_T+R zH%KMt%Ge0ll|(-pCI;_Q0D9#>ag zf@o22zhBK=^E<3~#Uj30GE9NwdzT|o(Yfzfo-)ydluvni0!1d>HuB^&R{MW$if0rk z{29TbMS>eHJ7)x>w8y36%tjz7a;azw?4-@K}Rktn)d_)G?0-d1- zPO6 zBv9{_(?vc$`Hvlc$cA}nl?sy=!9@Hk4C-#Vnai_Gv;$Q@8)6>1MIv#u{h`aQ}@D2#~Mqt{{=tJHC1Z z_2~epPuei%i8Pwv4}bW!CASpvHew0|!+U^c3}hXwE~fcY!a0=E!I4>fDMwr?wj8Kc zFy>}u0xbJu$GY{9O5kJP?L6Nn#0s4{7g!b_Q7wMx33ms-=9T23_CNDyZvi5l)PEwJ zQ;;0fVZchw&o>Px?T0h<2BOAd73QrW!E%I8V;{zo@g_&2!!UsYJs&dPjJJ+|@LM*Q zR~o)2H5#E!#2iPeXh2~Cp!av5L&Xzddg_!=jhSd2)Z}sm*Br19V;^6JG85Psl?;AG zcC(y2+I-mH{!g7Oqq^boM*ehPc4q29MJbKkK1v3#$GLh2Ab4#jAb{x+12mJb(hFP& z8!+;95h}_x&(?tByN{mAiSkFx#!e zURjjC4@ghSq<*;0Q=SQ%drTpLgHU@9YgmDA~;dc&s7N zL$IRJJ%Az6j@w58ANr$ml)`m21Bm(1?S?n7SS!8=);paW8avG!0fwPd)tJo}YCs}( zH5tVSyHp_`M=+h+nb2)_A1Gq+xeF@iC4P%)8k z;#|#PN@8^iEU+A=ht9{q1D=u)5wozUnsoi*l#^)FJq>20#`c_W9MWVYo^-N#aWUFF zBjZsP2+J?H)N7AEVho-k2wB7?7tiG;+Pu4vXa+>8hYreWGt{k9cJd!>_mBU6s~FIf zZ;-ZT+!!$>wMw>#T{vPmkQv^>BUKTxkD_>^)oE2XX4Y$^Xf&{sT-JvJzz zQECoTHRU<6R$F_ik#4G~8Ys6bC4nc7L|5Iz<320)Tu2+}-TfKD>fA*zz=}U|0QXn? z9$omGcF3;V$X4mSJoM9j}=5Q>I+MTq7HWM8Txw4i__50JrfN8ILF?5oN#c zL4-{VW-_}@kcm_WzG5AnfM5KX-EX70t!2@u-~>-8))T4W2t+mKtwg|_)`|iLEZYc+ zYRNJyIj`gc1QJ^817KarNP3lMeC%ZRwK7qE77wfRnG?n+0QkYyKw`wGCOp9m7HIbL03ZCA3Prb@dE(oj&s@je z_3ITaYB^}Lo4+KB?*4b92}`5G{{kP&6HvJjYs`#hsc4Z8iA8cB+ExO!)+=+m`Z!Rg z;V(7!rPTqb`X&_Q^22QGNh?*%S8D+_kZ^fs4fV#bG|Ifm^X|4~OJJN2$g!6F6wZ|zSu<<~0NLRqAM8YRDh0#2*6LTsf2js- z&=-5c#J*m)V3yx+rlE~I09w~fcXqoW!9rjaN3kNXiGEw3=_teip{_Q6i!3ie5DIr} z(N!Mpi`otS=OW3Dv`X}4+)Tg06HR&vu_jtP5@edXJ)>ny!5Oy(#K}++_yIN`5Mr$$ zvqi{PY0B>C=JfRgE$Z!*&vMa~BfD^kVP(h$^hjsBPsekRXppw?F`sy!7S$)fo?hBF zY<2U~{ben*KN^ad>S*Efd=VT~G#*Nc028*m)4EzOiB%(+BD#bng|_+>Xt>e0L7t@8 z3B*1$JWRF%j{}>n4&*KL``!{mTcWT#SglOVhyE(kNc)*D=Q&>>jM8CoI=BRN$uTY* z5_fQEbqMlGp%jK}K=gxU(5e?oY@`c0LB<{?9cn>|H-;8|5Z^y0`}l!!Nt0+W46MhJ zCWd6zp2Us}rL!>KW}S{BvV%DB;atd6R(ntg1o8QGzGNT`Woco4kp-8~=)AAA{z(s= z)Bg!zo~iJTVj9#yLSxABABxJO}NIVO%g5 z;V=hfUx_p<8Q#N#ta=lik5mDD*dR7fcMj)sr z!2$jpEP6sLicqlwl{j~Q4E_B;hAP6GtpwTR7NSaX2z)&Q->!Wwj z#C1O?QSxdvn*!KzFZ3;Y`tX6`_yh|Kp$oL(3HU4h9ktzT`4_=^0zKsXg^{AsJnx^* zQTN=~qK8@CDBgOjjzs5J=dbjj!MB+U3E6w%X>w$YAtLQ99}8}Ht=m@}ve9tJ-Gm`2 zk&H@0b?MQNs6zI^`~nqf;1jjXjoVP-n|v9bWf;|Bc1W-mD}sV9<+n`55)hi#qxqNq zC4YcD%vpB8=7KPV>I^#+){e`v` zz>{TO25T|Yo})$QoU0eEkpNdGPlv1+z^p>lc0^p5?6KeHl%g*L1%G!J&N^X%OdzE| zu)W@|rk3KE!EQ(^d}a!k6vHao=L$YCD}DdyAJXruL4e;DS7aPt#;R#~W_?Y~bj;OoUVrq%BJicvqBb4JBe4N4uo=*hc_azcQE_SQ)zpG? zG0=={LH5zD3fM2U1gRNHtaAADH^}SX;XAO+%VVzJx#gsKW%Fkr{=5SQm`I;HI0BDX zGy@NH2+YEokP*6?1=eoe8d$LRJZJp(tbxhx?TLqxTJaaxSa=RUu(c+j!(Ct!+X8>e zHw2bw@#;$cbhGFeftVCv28{tH=>01ARpPWJL23~D>yQ(wf{!!-oox(w{gIChz2lY8F+Xf%6O-K$$UA1Kwga8VRgz#3*GaQJ{^a7>LdKhA;SQ2l{*vGC&}B;( zNZ9uf#)r z{bOwfy(P5je>NK-p*sQl zDsDXwTtYWOA4*K`_xt-7K`6^?Y?rWVcZb+wf)R*82nDA+20&b6#6lTMK1;0NGUYL1 zZD8V}D7ppEp_#?inn2_!pnujnnz9~K==o62H(i2F$6LVV0Pt0Xt@enB8M`!O@KAkZ z-wmkpnuT2=ofl&!9}*k4k#wwDuO_4r#E}!z2DFm(G$A?r+1h;;N6J&0Q;K2dqAVpt zFiu!HDQ+y@dYFA#6-vCkrt0rV4s3(>OukHVXP4jh_q$60>!AD+YZIJ>oY8lL?6EO8PdYT* znEA9IYSonrK!7Sj&2@4F z-YnyuRGqv(=laod9~cPbicF^BGC);SB0k!+wklPcGcCPdTc3BPzo*``YrH9sWtCz+ zuLv=r!)xU62!+A5m4arux1bCb)TW=A8o(0M4QvYu`R+vtDvVXYb|#1Q%+d5-$nh}A zt`S8@mhxpe(lnVrA2MHkEQ}fkvnw?gn{5Fl_(Mhw;WDHHmEZo47s1yWhsjZ#42OWZ zorJuzK3Y6)TJn*$>!X7@A>Kwv$!8Y|t`%m0$CPh&Mm!b818KHqud18RyP#_VLdfE4vsz)4N3sRboSTMTpplp|B$^t->U~g66B#4AH zJBA^(7F8}?)e{Aq{fq8J@{}uS8pGJM3PNJQAIW@Iw-Qw;F>IKb{}#j=W^!*(faHwd zRTFNEW(O|%2LbexhvZS3YdK>@DSSyl>mG&I{br z6+q*^7K5;ATh=*x6X2!mG>|-?Ay>a5z+JRi-E{Kk>N7o+!MIV7?C3wVqU6*5-82*y zsiI}i*5UG~!R-V6RZL{6aoXIsfZd8%vM8qNt+OngQLY-*19AuJ^Ec?+4U6l@LZCOoBivtR)W?pTB z4~}E$I{tQcteKDbY?$fEkQObH)<=Iot&2{$RpLi$7l`S?l)*7k4Ji=25fho z+Qx6v!btRl`011NC&5UA-)hdt(^ViO@Mg<_g!19*hsT$T>_IWnAgMt5IFaHn z9l@@b3x*M+a;BfV44e6`<~x#vVaXuXcFhnrD8Gt2aHi{`CFT0=a`hY4r|x(6u2t$v`t5H}COuPxi6gx;hFgI~k_feflNxKt5>ow+@czb25BxSH zG0K3#VN``l=HK2X6aEm9c1pw{fp`{WU>bwL4Tj@~p{o#6RPl!`9{pQBmxbpz-%P116d5S}FxsIXh|jgz=&86J>m&x>8?hIkm#! zKjKP5E&llUq|Xt5gbi+1^9gu;b?BYKjjX4`dSg3}nhjlBCC4vnKaq(qg+rxZi&ka- z`ZsS|NDaLZX;iI+IMM>ay8zjbLmh=hkS zid6XaRG#=A8g27C&OqbEP1!Vv(|*L{V2;vbNT006u9qt)>dK!asf{{S3ajJ}7^5>~ z*trhu5zb|xIgSuv=3L+;`xjx>P1?@*{H(9CD*8IJE5~nVinR-Wnc>S(1`EGLeOAgk z`(Ho)Uv@b#kure=Qq5L#3cDUN+1t|Iit%mUk-wz+Hq#6D{|haXmJ!dFuYtUkDD#o( za%m$->CzT4gr5JFxz8{kd|D=-aKY_LNU$_+pTqlCRF>n4u0&My1N$Zz=J{4Od9nG-4=Zn5z`=Vl?e`t<)38=;SLWXuBvCZG?+YYe5I2_QAu;W%$iVd* zIh9fKk@(;}w$LAlJt`tAh`J|tZ}6493b+@O@a~8r4@#t?L31L>|&8ftquO?!aF-=OATb*?e5dvRGJh7u(< zDrLDCXaLf*|1!|-s(athpC?y-s)7X(XgNNOdm5}jEO_iQrq@lsJQw`?avoR0#aj*D zjFAIxT~f@F>x9`f?waWq;_#*-Y~?SKos+L0%V1mgU%ht8*vg=o?+wOz*3lLw@A1Kq zHRV{gHL*QC{>p*Qm(5-e4Y?}0#9cV!hJTz%iISp28E&1$C{RmtEx{m{x|SS>&QOrU zeNLD37fi3RO{Kg)0QQCw?)47s;3j$=ik98H)Se^qOmTHebi2e$!~lB%I>ecyE>dVA z@`f+=Um|+?gaeC%)7WQ8XYE0=osEYfd9*9{b9kfIUtX`BR1bduBf^qEJYGevDq55vWu=>;r2AA^~jp+Iz>H3to&b34On_TNh*F?CA zq5}^zI*0DDmhU`4m+yDA7mpdjYCUlUVQWTo9^V$w-Exa-_3gchYZ26*hn(yl-j!%f~@lB`DObe^B7uGQjy_ZNTEKO>k*Vtg0 zF}-Jxv!uC{M(R6Osm|qPwpO;uHm=nz^XwW5uva02w5hrvuDEwn7XEIip!WF;lE}6m za}ALWX&rFx3njg-q2OIGm0d$hYDpbF-K3?B`4TlYDBXJH4tP>(- zz11DfUX$`SZSCJN(Fv(8-C_a5=q}hY^tMZr636~-ZQ-NBFV1IEbo=ZTE#~PiPnTUs zQkDrEUVItUY~xu$pGVjjTXOa=tL}QQvaLS!B?**Uh?XZUDTWyD8T1jLUWYb53L4AH zSf;<1JF-I68S5+mUDKHT|E~EVj`Ag?XiecV&Q8iw?!8p6QleNJ4~Z&{z3dpdfX;DA z8QP)P(b=!sk=k@jaCxec^gHsBuK>Yq<~JbkEQ0hDl3ai9RfRhq9HbhrEMT(bGv}JqCqh5G#&B*?hTHt%g!EuZdh6L?`<4 z4b^kPto{t?ZWb^5pjz?y?s>O!PL+^E9j3R6RZRi+e*{O9A&a*X2b+=ztnq0@Juvy(B0z1nqk>^A@o<43W<)FyS*E7A zuoa&O<4L{#kuT*vGa?fqWQeYbszlyk?Sl!}&l&Kd&XTPWVt?O~Gj^g0ytrBpFr@9B zc!!bgGxh8Pt00K?ot`NBXtWVq@l@(jHT96Vi1g4Mep0l8NP!6r^xPZq2NLAT=$CcH z{q})Ev0Uw?+o>>2=reO8WxhCP!R8D+^9f&qqV1*jKI~-&C~WuQ?!^hlEp@7o^|e_} z!v4`0sR{YuL1{D3m_vz1GHOi_hE}{0<}HLf@B6}D&t;^3Vf~`qr@e;(2i6uJ{4+25 zTvegA>K>&mpSJzTgiQ4D(5hOldmr`Vl@|7jRA0B1uYIlLp;wVo6vfw_OIx`6dINbn zc^gLkO>SZcg%Vy==VSk;!XPcNtkv@HVaBI>m1Q2;y@5K91W}ad>p-ro;$R_F-am_Y zK!5pT_{op*AKFC7t4eE2>+?Nf zb0I!g%%Axs`-kGxr`nd6l1;1Pi^G;17BgPchW=nDwkWl}6erQQHXof}EgO?utViQn z>VkJc&C>EZ>|Lj~qt07MY)w$OL+$*JM}ow0ry|6pKz;w^5lb|#J^SZL5N0)bd_f*vq;W2xCW*1fpuGT@J>#6~0z|EMVlbB<^ z^scamK5*;XQqSl4H(9#=WwcFNp>|^VoZRc-?Dy)c4yYhzmm@;*i*iWWgHEH@?!bvvv?a24D>9UvI ze3Ipa^{iGaM>OgNcBHKAz+6ScCSz)G7vIIjIu3hE#&1twe-67mttV(H;y21LLsiJ! z9DOL~Ema$N{AQmn>C4nwS~H(C=INe8dq!L>vsHtprW7pEM^w$5^>FO~{UF;=?uEs! zEh^78z;e*nwCLdCpL&)q;kh{l4dAQewx>M;g^tM2K`k||Ag8e70Bw+%)Nq#yZypa8 z)Sj7)e4USuCc4<>H&9xJ)aig?uDV^QU)pG2yiWgQq0WqwWuB3b;l5Cf*=004Z&$nV zJ&qAw11l^AFH&&ZyJ ztt6kcZJ2Lt9sGM)V`6cg+p%VNTvKNC<94zsh?ifX&o~>6Hh%76*lHD{{&wlNp321z z(j>Ciu}^{USPodA^b%r%?^8wrj?y5Q>h0W3!zHVQd3}%C;Y&M6c&eh zxM>GP%!q`}Isbu)T04Q`MlDHXC2VfuO?wG@vx%XE%Z#=U^8p8iA>$i@vXMMWCZEX; zI}Bf&7jog>^celTkOl=2VMfJfNzUywz5#kPS(-(|sziv{7>%{uO69>thcV*9*OBMY z&wcydnk5ZM9~19hL{9^Iu75w;ss`oF7t0-03QN#qN#dt_{pRMAbNM_8_-30HpWXtL<#=$)fPrt5aiGu!4ABO$Z$dmsAYYkIkmS})XZuACbuP28+L!) z8(}@uG~_)#bETor;fl6cm(P091(ZT+7#|yLvE10(xl=4$?L`~)8RnL-{p4N?6Qt_G zhE}Z9W~IH+lfK93@}blKpSwZ)`8@ILtON0F;Y$|jVPu1$>D{j*EQGMEKh6z{fD}pY z47>^}(m|@MRsH2%nID$EtBz2;GAOuo1zHp{q9Vu<#)6e5X?zcJ2N{M&5=Vky4> ztHw!V(Lm$%y?A-}2BbLPR#MpcIf_-~6A5F-U7jpyDu9NbsO!=SW-5)p*M*BxLe;SY z5^%M;N^o-O$3jmcqq=vZ;Z&3__b(K4klGbqAD#oRJF6A*s4+4k#Gc)X3dNBX@FY-; zxG}*P3@@NQvwxQR{Rp-DX8GUbM-$fWwR|=toYmXeZOH=OUUKOjtZl234!YKhE+aa~qyfzW}v@rNOH)=5Oq1Tkh z(iE-u`dNV{k28Wl!%Xx2=zV*=Nttq87z#ImrbXj`8Dy2%ZP@yutCR#)Q?i9wC;aai zxbx^2WeXwVZ=N$P&*$N{FlM!!e+#t*S@AEDX#1k}VU#knkXbpFKRn#Lxg(SzU$0Nk zPhTvt6lwYQNveu_*&4=5b>D_G^2(1K2B*&!SFuPA7{_?Bjo_%LrF1&(jYHZ66er@& z_ghZqgkc{rR@!X-?kB)CN(-0IdrLz|gmIe|2GmMv*aZ&~MCnl=5)XsS9$bbQc|vdgu#$ z-*t36bs+ zkdjimqz94G0fv+iMClSFBm|^HN~MwRE~P`@TQ|@9>~Fuv{pM-T3*QmW#$@sMZ008YoUbZ{vc>iwf^Bxaw^LUhHv5>VOMB)obIWHVy*-! zM_zq{oVwo=Y)GUUjMi|acvV5Plpvj@l!DZ%lI!XI#&y~%d|mARdtrs$HUqAiu#{dU zZ5#EHB$_=wB@@=_Pv2SYJef;odY;q}FHBo&Rx7r%|GQNA2k(%L7VAs12q`Yh`}%+r z@nAil3b3oteCVc#Zx@HNIc43Ktic(*EGJFJAhFgE!GC4GMeRnrf9%B2f6-QXG#gj~WEqoq+dV`0o zn+_PRFSuzf`Abnuo3UQkQeAl5I0@t5SJ`}P8C?G}ZAq`|b#);!5pJhz?=AmX+>`ie75u*47_30Kc>9jgCU=Rw=+3M%8c(O-sjaAx+e3xF$nj>YmDI z5;SR90j@RrqrbF}1&?S&f`S22M}E3CKf9bW&V9U^{?b$IE7ixSl2dOogR~7cPYpDa z{eX5MSkrDl1q(N8KU(mEX}Ec@i{895lHhZx(v*~YD==$CKYmOy9I~T zlSc)BMDS`Bq)tIf&Z!-3hq+@hYxkUK=HtVZ!!kb*+R@1|Q6)?2@e7Ik`xE8|0@6FT zStlkyge0$;?G%KY*mMFcZZ1`PZ+Z(>7u@7w6 zBLe6NI|R;6$YD5|&8F8SwACo?kE}fdHX>a8mbd-dMUgnxXi|2yGMuH}8bOMaAHk$9 z2s@YC7P^DXAd0y&X9r{S3cI6*XUHeQ+YMBnTA*hdBsP_7D!3Sb-|AH{b~Y($>kB^Hf+UG1bU2{RD?0Ah@QN(ZYHooeHt_jwSffwgSry zjL)YaZJ*OEHk%%QuoOSs2YEQ<(xBfjCwsc<#$d}!O7|+pv+C!nqnYA^u+m}76^YK* z&$$nB?%sJ5<XAa;uv=-Ah7MEk-fiH98Fy=4{mkn`b3wy&MRn4o2< zB2FI+X;VRkIF`V!Q1pc({8ig{#5)`tn#k6l&tqW206XzXd?W)Rvq?pj4G0kDEDh`y zs)GSwFkVFYZSaOy0qCH+!ya+}+Gti6=qFA1O@FUqLa_-U(2UiKYcx_R3@a?`(rZm@ z{jCy0>(X^}1+Np6bJ&e)D9CO!rqc{z>wVMCJlqJP$hq{?c;5wxgnAs{4CbUq@Ub$n zWR`o?b5ClNVDP8Z{5M#vK^*j#*tGxd6+xj11xr@}x!>;^n;WBG49$&(q(jERu#?4% zuI41ac1|M8cG}u)e`yn&p;RLrYG@TjY~m$d&4>(frP;>uhbtszJD*e?z>_6W2KDs4 z@^|Te=bifzZs1|Lmkn;9RXYzrT%uE~n5;W7F>6B-7SgqS)n0)jOMk5p6Lsa0&&3an zUQx;u;d!x>@kT#G=W8j7%Uu2YlMb>t9W<-lMOL>bPmsf|>(W6)ZxG^f^!Uj3hgEN~ zK`1jF{Q1zzCndjBTXj9-corES??uIt2~w>62n)Eu9(1qW13-viL&5YG7`EP|)~#I+ z41k3_W)1jN()(IF+XmB+f1y9+ekIKae0-7I+p8ERls@D=Pyy&5{6EZy{8 zj~MVvA%$s-oqxQATN`J6kB$OyPOHMLBYEwRPXhhg!O6||+Ft&%rXp-GqPBdeBEHu= zpV%7S2g8IGCzoMD9OGZ0A7xTWMHz&&ilTbW^~#0e9{LD}GME6x-9IQxi$N^W>TPg2 z+}nX*(lR;)p4Dg=S=j{8cZoyMRVqXlql3~i$VlL$%rd`*Wav)==cF?gKmlIRhRe6K zsNAH%rzTc}!usxhDA8&$zQ|Qva{&uL;TL}M^3oF=*R)5Xdo=AEk9`mwBBia-(O|&M zT5~$K?&?GcNd2+2*ooV^{f-O2xB&hGxrq?h=GS`={ry87w0U;83UvqnIna8ANx(CD zjlTlE?Jqsd5YV1V?&z$pj#?rL!#BwG9)5Xd%ODomdB6v?w2kTRpM2C9!@qpCOO`3XU1WN|FBsV?@7^1O1pQ1^KB1S#2D+|+qtk8zZ=?Cpc+i^tcH8kgf?nw_BbqE{z56;Z&*z9hXPVEATBi?ud_$Flgw?0glJOe)ae*iZm-S6tKzmV?r9F z#*YwC%4L^QIRT(s4DxS@^kTu~ie!JhZ_13y)f^Z6V+rEy#aZg6egrWF>Y%q z1_)?+s?^eIRxo7R`Xu11G6V)~X7II_et`S^8J|8EtBno(H_sZLaUT&f46gfLkyA$yJ<6t|I`b1Ac;8eX zmo%P0e3GRFd~zKwZ~#Y-nun12ny|Z`mO!^%-@bfz9v8b>|1&LB z5Ur}S#xxiM*^PjF1D~V~0~`k-j5h-Z-{J%6|1GX11Wn;uTC%1N*#7gizI?x^FDD{& zs9bj@F91$+!q}^f1-1dMHC5Ybm3xKpIp~S0(S0t|Xd{cztM~6*+VRk;z>fC`j_B}E z9V$ryh|<$N!>0)#e18|7Jbkw19T^M>1jc0Tdo;BWfQf#FBY0p1;4HG+q4;CDpda}E z(uNm(KS6q_waC}QhHZcK4?)XO*AM6#>`NcbaKSh7`6N(mP|DX>kk=j(k;CGUD98uI%`|r3c8^KqIsW zV^}-0H=$#+GX{rF)t|+ZQG%zgD_awZ=pa>h{#!KXFaz9j$|ZOo8&B47%^@0Yj!#T~ zxa#utFS&d-*71?-OedFjLI4~6vFxd{;MMAjhPf+h0n#} z#;h5Lh#mF8`%%<<5_AE;nVT>xez4h~ZBIc!hANUI0k+W#U(%|t6Et+>Is63aq}^V7ZAS1R3o<{}3C`Mvs8pZOL)a+m%DeN?PE_Y6YNk?xX=~P)A1w z|LttjETV&p7Eo@xPYg^w^~8V@L~pPg((C}@%xx5GPrM~{N+zxvb7^ z3XQ`ON)}B6`>6gZNFhn1vs>}*jMr2rYL$DGeK=_mLeRKN(#_yM!2|4r9-!SF?F(P9 zN-izBZ!)S50Pv5sro+k58?L?H~3v64V&(a-qlwjoWE!o{^MKGYIWK`5b# zgb~cHu|qt?_#H7Cx8`pcGGe_g^4YFBHt=J-+dJAghvIHiZf*F95QxaHa{12?$IpGuFl-Q z%YLv6{8p;Jh-?5t2((UMMz*sxX!huGu6QT72be43OhmJyr5tdGn!ZCah{9qVB#LaL z2fQe0XOM8vEa+^XX8gL>;`?wGWmtZy3%{TpwW`29w^l;T)eS$;>}?=+my!CBTb}~m z6VL;Cee?M?6cGyd#r=1HCsh9UGnlU|q|Vv2;4C_ogBi;mLEfbTumOakN3J&0XDC1Y z2k0-V-FcP|FVBNS{W>|`+@P!gsSP)2ZGdBmXY>(m_ol+-VE6HIGFe645%I7&!6SYF zjq8#M5-}e6K5b%3vP0(P<;2rI7igkI`v4Oo81VqLOI$x@Xl!Tx{~jz2bdl`iN?l$Y zv0@DXzx6a3z=?aJ;wriL3}eXZRHj@G&X=P-pQV}E-WDn6P>_>UxO~$zAd1Etsko7l z`~kGvQK;QMyK^wTj}J|6t4KNs9n!(;t&$sMxTX0N#Yqoiw;?9Uq6N7snHXpUX*WIn zm3oO)kKtJ>=Y|d$>UV;3ol|d*Q$_r2s~jt}pRm=jF3E7*eY(Kq``Dp`kxW zzNvQV<-7K>{egtUb zD5RmJG@&SXFv1ZRWIP8A;tJK-s!T3^ID#Cjux@a!hF3daoRH1a!2}}xZ(_gItX1L8 zW73>EsCugU(e8bWz*_3je6@=t>o7ae;J}+KUtMwVyCiRJ=akzE?lrsFi5H z8(hM7@I!EPZ9L>VEDqiue#F0zDLN=#C(CnuHRYf{RU&(tTL^5mxBJVb8k4}v-oVG5 z+KafuP6LLK2o;_>;W~Ea7tX}-UrEVMhc$o9cPZ-2dj1M@=y{yjK2^=*pbsh8OVMa8 zQAKDH`!FEB_`9(>m{tx71w+#idzs0^0GFNimr`b@0;``*$vRg0L;&xdx4wrrSI6jF z{}+O)y>JolOXFVzrCJYYt-XwaHcho?ZJyWjqhLA=+$ zg0Fp0pWfyVIU*zXp(H7=y-j>kQdmUXXy*Ir>d?!lL;#42Sc-*V+%5uwd!W3$bJmeK zGYu0%YY>f8=cTNs634zVy!RPQ;G_cD-WC(iWW5$M*Cy$(<9k?IXI5I)LR{cY^Tv2f zxmk5(Iy=?5A-z)Nz>ot*+_dugWoVx*4@kD*A$xB7seqi9oW2o0wGQk^VxQiTtAP2t zsc&h{uKTj@Gz3n1nEy4+A2JODuxb~SoYt1<`=GWu;2pFZ+%~hOt059B8h%{aJ5%01 zcH$>J;Qt*;Yux~oCiQ8C#4l&nQ;txm)(gm>^q9x*eZQxwW6E1`?veQNi@vbQ;kRq0 z?@Rsy2VT+aZT;WUM;X!p8%$wwPqrONeSF3lu6(wIzD4R#sseg&X?Qx0kcrBiA-xwL zyDJy^6~(=CEx55iO-&??e1%xh_rwskg5m1U2dduoQ7kvXz_@pBSF5=anjEew5Tpv+ zGE6&1wVNa(i{X?n&G5?FRw9;bz<8unPg+f1-3RvMjIVYq7^%ph>FJtC(K|7xe*|gb zTSJGHZf*)m>mO+N5s6yV^nr$4GKfCJNBy)KuW>m9Ih!;ixhX~7W^_Jb<98?$V5}G! z_6+g(#j%nbYyfO2&mqJQ|);J1z zn(67LS?3vS!P-O3Y42{}$Fbk&@a;H86);b6*V~7yqGEimCDp72-$CLbfYA9}ZdfgO z+@1oRp*i2}@Q1#L&&)rQfR@k0xk=;y-ZRpAI#cFuC~4zGfL5uxG?afK2BwW1GuNHk zRW>y8=vk>&dkh&+Ss-Buyy2#=ntSai4M9*hp6W=T(U9(5>k^=$c6VI7Uja9ZTrNpBt%cr4-qN91rz8jy#2D6iXchp@ZN(B8^F;$fu~J=BLbR zG6j9`5Tp6Tz7(~9M*Z$dyw6v9H$K{6;C=(%8i`N&^es@TM?g?b7_{Usbb1F;t;HAu z9ul@6G`KzQWY9x?+lIsEmws589zrabGp=UYu<_Fz=V-Y^&*ShSqK@zAh^!*9&l2}l zi8b|A{2vz&u~Fu`YT~34qBy2BN`+h_CiXoR{8rH`eruVrw&W+$iuPcy!f8J#(W(9; zj!@3PIg)mQ8`+vOj~FEXYq|5#$`_w~MR)5RBp3|XfD)D$ZaP(0R>XUK8JY6_=RF-D zo~{qqcDjLo1H4pxWajiWZr0RP8@b-euCzrj$nX?vH0WIjhVpKmDl7k->bl(K)b(f6=>arb+R z04*3`YC?pj9v9a>XEetOGNLP5(Fj6BbmF&0b9XoizR@aPPYAsfDL?JY*@I$zYSmZU za8!$F)a>HtINX`-nlw1sCvkvD`khOkP7%!9XU^p0x3cH4{;yVFo0a_}Dm z?Vq(OPRr#PVOnMo-0<-#c(t^`fs2hu}m1~=GE;`JrT}QSv{hyE(rR@(DNV` zIYh5Hga6?tI+Jvh!6tmgmiIYvN9q=C)?!puSv7@loWC4CaypANZOckjFw3?@a|I}` z3%9&&-sb^lviS>4-#m zi*m>#j~np2n2PcE%v^ivu1mfO*O*aPlYia6pY%qPJ;=JC;?Y&z^1JiO%RV@B822BKUv@5u#yBhbm zUP!Z<+{>fnOU3@`Ltvhu1c?<(lHzXFT}vl=A~*Z5=66VAfhXq0jHsuM+t-44d5#8& z+k{Hjz%s4^;%bL@I=B0bOJd2zL0Ywk_Rq&c@Z@3cJK@tK+`(Y;YP4c{AK~*RU7&&W zh0kmKo}zVeq?5o<0@cejgLM{+GVVf`dhw0M9G}U2V=EP8(@(BnGvmL^7CiIuD{_^; zYTI8NL{UYyIXxD|Dwc}K?<>&x#FK?D3_H~x{M7*d@bA! z;a^CEy`!aq9J+>3tE`S|TN8b^0mhQ#+aGP=zzr zn|^MZAmwo758{R9yW!X`qjlFh%*m`D^gX%r&AlZi`tzn@tio&nB6^pRaq{^)SB-B# zv{A@2LGA_~v6nr#97U>DY@R1~Wh)x!^6oC~EF(kwBFxos?^*D-HJaPg?>bmM3pQzz zubRdoK?Q%XZhDc*G4%5EVILb@i&S>H0L>e;)DwEaf19od&J{sardXv_NCXRc(v`J- zZ2w6+KxciT6i3}ZRbKw?Fz#Hbmop@A+;R3T2xdqT+ZwUwkX3_m4Sy$FY(rOF|1D_F z8)HC(97r{I|0o#KN(d`m!l!Kg#R4%RU?OjX$oe;~8FYK`_3W>+(BE+0R}l`)^4Dt^ zd@#XBpehb)2+y!c49={2=?c zFl7Bn>Uz&)jOZ6yRP4ceMj_E!pW(#amqih5P4x=}ptuA|U#8UZ&&RNSz|r8%rt^3M}7#Dd6+E?Za(f z4On!oe9_OkhoQl559q&gNYI-sECgeAvAugQ2qzalq#SiCSl+LN%y#|eG&*H<>ibN#HBLHQqCeSHROP|RK3*t*2JaMmU&DT5)JRtS*O=|Dp2b8 zfdHvEnW%ioS)z_BC7$e>bKcqE_7448^)~EPaMDnsty67~)*n>*>5rUvRIc{ClAsLw zZHqRF(W|TCzHUrpNG5ZZP~m zcIRNN^K`1iszE+MhGh7Yxn1hdhBU6Yb2bZIcNV+sZT|$U;Pn=g^UQoU4!1yZXgC)g zJj#2hP}f6n*JVJL+B`Td6z)lUxUD|0v+)h5qhXoHokC^>Ly^V#yxN#nSBCCSmPE3W z-;4^9FZaE(!!-jc_SXfLh79DvCPQ0fS@VZ4hIHTNkodOh6P|x#G5612FuEny(Lkw~ z;)>T3hSQlh#c|5&0UG;m|CA)5 zR*_<{mZ;4yf^V{x<##X8F?3g-hPkr;mPb)p=~jlt4wJR@Mm}o+dkV24y-m-)z7fwDk}ZiNw8z?AC#kyP8e?c5UT4g==dVgy8lumV)Z1YaQu{gMRC`=?-bWJAv&I%!b8`=B(gw|R&%lS1xHb$%{17Hnutd^&J)MsmDMD}@SeiEUiAy~ z3qLb8@yS@%&%=J+F^c*GGAm}L#I^X@wmGr<^Mj{F*?39xw|KY_BpXdLMy=R8Rkzy1 zqDnau>r}cu_RS9Xqh=erz9=7hzB^?7YJAgfL)yGaf#PKcYOsh*?w1NkY2rC0m+){M zH=qiW^uE|tudyY#6)rGKf~lJR;{B|_Ic*!sALcioh@}a!Ncwi`N=}?h;KRlUb% zq|>#^>2;yJBHCiv{pVyJk2e}OG^gDUxwAf}9+6x53$ETLS}9O!7*#wLuR7m1e_e5P zU34>Q$b$-M*pY>M{VwBN*M4Fht~7~q9T^LVRcFy7|MFLzh`u+h^{#Pg^FHd`Cp*C7 zLX#qiy65F?$rWqQD~}xYE*aSm-%R_M3UCG=3Jz8_R_B|Xhw}>~gsb`-co_aXBQcFjF-vG|z0fx%F)}H? zKPPuM0$8rUm&QR%x$tBqa#uyUuzA!&`z{xic zYm@Jy#WRmUgd{7G3XkYy;63F3&3j@wmTz>9roISw^5 zR_#CsI(H6}FXh;37K^n zQwed?{$`CR-pJ=dsL)wDB3LBCOvrauC`I8sA4I8q5Al$yV01SekTGCazmcJqFv)9{=8BTZ9_ z=TJ7dwiJw|I!|Kz%D7(LSn`n6JwNd>g((W7gx^$X9N}3R1|wv!3elgATaAbB2>$%N zgH+S3fLWr{d%u2-H%CXcXm)}sFlx>oT%24QIrwg{5Qh}4iMt;Oq-wHENbL012Pc(A zvC5~m@4$oFc(woKP5m>4$7e3@Yxz+(ZOvC0VR${T)DJ*K^I=0ieckRVHufA7{p0Cx z-Pe_+?nbUgBqB2j1Z_th@FXzm>D$AEuhZfv*@w$}uMRs@jdz7r>ff1W22jiw(TTag zX?Q}~)NuMhjXdm1$JiVhW1EX53`WmzV?s$i0Q!3e6r1`MDML`mRbHi>Vvc(s=Vb5) zOzWsQ1RYAg=<#|Ob%%M}zX%DKVmtf(u-Fvi-}!f{h{hz`Z?1naR3=bWchCDs%-2f_9uLDLx=a*mR(b~#Uh-PufPujtiP$R>9t3T>&#Er^|iyIp_wt9@=Ck;$az-2xR8YAyjEg?OWn%=!@Xk;}@ZQ1RT~YqGez|J5SLKrW)&uC2g>= z1P5?~BFmBo1^qlAUSYj00-INiYblzjA#PxkD-8zaD>!RoJzDTAb5k7(-#^y9)G62* zg2)4-zL7;BI4gliS^;dJRDmvzAV4;3A@x_DdUmRG7->3wg8#B&-D+-{wpudS`gUHS zr51)!Es^tc>MnFIy2%MwZ9@H&x)P5%1+6bCfG}w&sH!gp zKpAZ<8^F&V$#FReuT!}Uy1av16PJ5Kr4fa&+g~pNc^q!uDu@GY$3|G>LmYG9&@XOl zaoN7KVov5=25|>qLU_NwfUwa`_qp#)5kUnUz++Tx@tf`xrwQoz$kWp#Y@jMBQXj#` zK@gyu6G*0n^u%O(0Vt4an9KnrwZX~YW;!+91Gg>zLoR;}P=Ww28K_8@Yd+p(5h3vAu$pB5$-zig%K7~<8r=JdRpsNpL{{3mC2FZ7D^nqyrK|#wzMdkdXi_$w0RG z6o}B`XCLbHuPoOp9|)$1DTY|w(itWtnqFW zwEGzK4;UPT1qGm*Wp3<_p#GuS58#R7-jCXwr&gC>3#LDX{6dvZGxXfx>bTOO9>l3z zkyiq(`uc$U`IU9xMS5)wr~vn{bdZ{Nsd{W{!2mmn+Al!-+F!K+0(uu50ie*-b7LQ^ z0NtKlX7%Mue+sl%3VwNAMPb2~)*V0%^hOPYT_Qt`KxLRmA}X}EiBku&Z7z+0ZtR;N zF0U3%D+^T*`M;4n<1%k(D_IP{6_=Je!0m;K%*j)$CENya)=u+4Ap3D>=DlFJPM^|T zppBuTwE;RyV8{Z{)ZLokIfKhv4RtF%)uL$Cc)vqH1z1BBE3-|6I8^8s0mVJMv+k(K<}pXf5^Wjn2_hzB(NmK3O)K) z5QR=r#_9$-qh8??iap(0wUb;O%L1rp3+TFx*cb)c?9I&HRL&ZDgyg`JSGfaUZ z8_3OhOcxP%L9v273b*r^3yR)_i+a%BiT+^!SCvsuWv6f7zdT}X(+}(g@{B57>ZRBR zEDw1}(?cuO5ek8_#@=rPwM*?Y^-#GT+YhS8VqiiSr=KBzVmCzW(5&x30NVfG(xZo& zK#qBWBv)p*8t4Ho28cR=Ag>EDV(XKQ@6IPIo~;~55#x~>BY-lmyq*=1r*(`STwY>8 zU@`1p2H61twxvne1d5iB8K*uO^xlC=lYVnZ)-Z`WW^`2iT|zOJ`BmoPv=y*eyzpeu z`~+%aVZGQTQO(bXS;u#xulVXA&Vp5c$L!oC%E1>x1<$B$g+R)tZdUnkKLSDRNLxs1 ziGNp@3SQ&zC7;a_0~vy{zIcH!;}b}8bO7G^+*e-#SfFOQOMpGjP2HG>Hu^FUr!4*T z_+2M~B0^vJW+9vsDc z{>aWJD5X!=$Lrfw1J!+7MNoz(c4@^E=?;F+1_=ni zQ9ar5>SH_7D>?8ln`bLI4X^ziqacN>VvL-mvH>iGS#KF-14^)}joycxdTZ`C$QAb| z`xKcRxjan|C+NdL>6ibhjLKfC>U*`L9^g2Up|et8p0Pv(?oIh_-R7B{I{V*svq4bf zb!XcbeCv5JshACr4gG-PFdn`a-}nQyy3!%JmkvI;Kvq7}sshp-yw*1RwS4e&IQ&7@FDuB7oe(@?=*8X`uYlW3QZFuWGg5 zrotHu#u{*~X=rif{{x^xr6{$xpJ>ruT#SFAu367551LWwOc1PiHFsN?TjwZTSt(Za zy-+wlQA5Hf%^O`4HyB>^Bye$LKPTaS7%Rw=AQ(rwdJ*`>TQ+_9w{86|$-~jp#*e?2 zk0&M$r$DY@-N8x8QyT54QqP1K*I8FgmN9e0ZkF--(A}{y7y~tR)r}YSNk%rE#ux}k z9V^-m$^w_RzPsrIit{S(9)~dhH^Yl?RAa3_lOT{U*rD$EgrNZ7u{>@tu#IC{B%ul2y-Xs{$zS?s>na@6|5J~k?Utb2(c(YO=f#c!4e9_?H>43Df9m!R zCjm!zi3NLr(seP?tkDv45u}#7g;O9}-yT@6$70^`y`so~<2ZjOuxRYJoXi>rYa*`D z{SGnEukD4){(CR_PP-R+2^&XqttQKfO<~3#u4D=WW+Jy!X;Sq4ZBp=Yz?^*_xmH3t1UE zT9QZzl*)?<*sywNQJQ(-G6PztD)3}K|41&K()JkCRbj(1w@g?3!pO$D_>YC|n10hK zVk#9pW-X25d>X7Iuok*2j)R)mH*QqEL^ubmKN8g;@E+%1I<`t3b-m_bAFsODC@%{m#ylfftk?rz<@i{9lI%!x#9 zw|`5i`r;^fk|$B|5Z4Rfb`({+kI&W&80z!Ieqt&?mq1?i)vjI|`nz$qthkshMQV+x zSKy2$UF!;Ww1|-I;N7=z?+1Rt$w>#*zj?Gq*0CE8_6iLe9Jt;}KnM|0=U0&2?86lx zpEc&jyYll&lp!Q@A zaBr`VK07|!4w40s_E!}kwj8f~V7HjeI3zp&XVc3d;in;(y;WQcKakmp{r7MB{GeI{ zAc=XPK}diWZo=R}GDK&pi?s#*kH$Sv!F}VPp>9hMKg@|R5dsySjh6b z=Y*^Pne#OzgG-Ai8cgZjckX@Ywdy@`$uu~IS-*T=$DB#P@*EkkB>b-P+!po%*G=}M zFQy;Z6%C{wqLzT4T?ukZPEp{AA{f-Cm2qL$%kLoWLwMp;+7ncJxY;|XHgjHZx*~En z&s#+7 z6UZLj8v{^k`MVdk6K{bibLrX6?k98F%ogd>jf(Lp%&{o_8}Fc<_;)uLskdQN+X35t zyJQ#OihiA6?eF^13<%0ONgaXBPNQQR#ozjJD!y_?e&gM^ zn{E%5ls}_$-<|K}Ra~?}gz~jF*F4Artp=tcT69@y{eB26VgiV2kFnM)g3%zOfy=dq zdVgtVNCw&b{RMaEa3>pKa$?mPNGw<=yMVr^w(I$=6Og3v7M>iKVoQ^Yzz6%c~V<;r_XWx?*!<;p!>Mz zIq*Mi*X6+dQF?yq1KG5SuI(~11f2Z9X$A7Lev_aBejR%PF5wVDnn0o^xLP=3OxBoE z(pth~3ds47k?tz^Jg@AMmjWf@ad3Mm?4V2vRW4QX@M~U%!zd)$3Y6RJM!pmaNl{5# zVkgcOpzbq+i94CLTa+S==@k_0f$kxf%F1R3o(-kA6q9BC=<|Xnca3>v4!ok*x#Qc) zG=+r|-=@-(Ti2xN%9ggAYn_KOu^0>)zKo|L#-pN23DBYFd-XW4q_kvr1eK6h{>;oJ zU%bXslAxppe__W(cB|X)6fjslmV6ZwMy`o(F8{Fa=PVQDBdoMT%#j~ID%aq6rIP&b z;ok)mxJSQK$KVXhbSRFU{8)dDMFr{~;_6x|?S`Vq^iPq(q&A<4~x&8SQ!2a=3sg4Ud$^Z#3BT$%ue|V_oW>C#_(itJ4zZ+J2aS;&An*Sm z_=I+La>PV{@V7%8E=mOIls8RJ0I$o{BkkH%!eLtw2NT3OZL*K zW=~|;{l?@VkZN~~_C~%wn%$ngnDm#l#xV(`Ae4M&rvMcjTy1ep`@U^%c^!skUPHx& zFqa`LG1Pyuv_9d(aCfhwUf8`xQ|`8ug7KNZ_S#dM34h;W>YKWa(g1_>5|b1dHDrH^ zSP@Ww6;^Vg=^P&$jf?PB3PJ}RU*dLE8qWj3V(F2~EXB-AZ;1GIzkzPe@FLR8YA$#7 z`fU+DL9v^%j2Ukx#a3knE@m+y5lE3c`iQ!AgQJe$r+9rV@KD`;JS-c3=u&j#55LWw z4iOxNO`N+ZC%E;$HuiwNwm+Tk7hB}a>qa*EHy5lvl+$f%$Pk<)#sn%(t(v$7?>FRd zctvK_R(YG+0guaPMtAXt;!O!WF{JNW+TEMIQ?{oB3Y2$%^{AcTb%?Dv&w&$N~*P*nqcCY%;a79lWU7#Dy5#Qrm?qlob+O7&V{m=yYo*O!~8M6sCK-ni#nZB6BQ( z|1DOAE0WA)_SSYt`2fP}gqQr`beGy$gH69l{X0`XVw+3{i8hhkuFvjndZz{FgC5+mVXV9#!5x$>Yvm z?y3qMKY%fh_r2&-F3+soCAZ!U$(}tOdEpy$_~e!NMy; zSTTCfzt7G*rT(~THKxG#I?ayYl`ZL~W4C|CL{^FXtNzZ|L8%}8Qsf4Bq#{CSOw9e+ zcW{gg*NuNAB0?qYBjg>=!zEwdPGJ3(8R;BJLAZ;@dZm%=pYo9sGP6kHrG1)zTfota z!scL$jt8PPGRazT6jyYc#BJSK9m};iSsV70#yfAUe)%T9c3u9oGrQw3np>|6PEZ3% zQ4q`WHR@HO+O-w0<4TIY?sD%X@gYdcM$HT?e_0f2=l!VhhCg?DDKP3&FUa-#H)xj_ z^~3vx5n0(E86Bb9H_)m#K41XND7rP^f+n!i8YNzlY=ZZTnB9NZ(I8#3u&oqW@u#*RxO8HY&^Arw`3kCX1gAM0OC zc~$79=PDKC==Uh*>lbbIY~osxO$! zUVFiv!!w!cp^PGa!oe+R{G7kql$j28ta za<{Z^%{Xd}h3GS4Ena*+7ZE`GCq~vHtqR zLm5m|*i-CBlJtX#%yXwwI->goLpJVrEQ}c`ZNq1a@j7T4Z%4ISQ-6L>5=DxXTk%Iv zK9k4ll64#%z3#Cm9dHl1b^lFD+{ECkHb;cthhHE|c z1i?3EkMIobO%aZ@y?%Gpj_RTYst4+;!(dTK(!zeYJ(dtXYb(G2F4Z ztNOrSPX7AN&G(Lf)GXR@Xzav}Ucek-;fRU%T@UaKDWe}LX0Q$1_e@E$i#Q%t%4&K? zL6PhXV>+WJaMyGH+UR{^DMV05jLg#Tw^660pDEijUC`aYv6epiAs| zD>CAro;cIV5cHPy>CD#kMcw)|dD=@>D33>-#w4?Ulpi6c@sVD9Kq&56FZ}jg3Ei5W z3}dirpN5r!!?|uenKkoUK1!!QQ4AkUIqk$SZ%T;-7O*x{a|6Q^ScW8jP+4&*+2Q}R z_0>^PMQy(`4Bbe>DBYqkbO-~IGJr^gh?z6z>~r?>JikIB(L|et8YIRtFro?hmzj<8xk;?O0{!oCoUn=L zjC2@Rx)`g}v)Y^h&BxIh6OKlgG_F+F1s+ar0_7soA`Y#^pL`O%G=OP9hh@gT{ifm; zJ8+TnE?)v1=Y*?bq%oXgv&K6G4ix5=-A&kr6JSobk~)!(T^kbzMHIxc0*(!InN1pX zW5P!pyaME|R)wzjWn^K`=A!Ob-dweLbTj*|cIJo^`s#(}j`)<3 z3g$VdSn?;&>&Ti>UkBq?0_lfBzwNKHh&ksWWgX_*>|K5_U*8wyazK~W^2+EBU=i%k zYH6G6s(Mb%G#H3bv}D7IP72NY_(X65<(<~P^vpYc`6U-~Ufh7NF~;Y^OVKNGkxXlKrRs|VlnrcdAtCti^{Yjc z(sr{FUI?$3M|O%Yk!vpNZ%P|E$fQCzFU*$IF|Vw2jzoVA&$#^6?lUf+>VP(C$ms=s zeetJOHM-1){1u)0?DeUy+LmD+TuO3WT$i}i1MEbJtm)kpR{=R74Y_GYQ) z+xBBQ<2k@U9D?eNg1hq ztnDf}t%LfU0dM|N+vxWq+5h15pofX#a$oBPgK^dkVeHtS;71A6dlUlT&be28aD71*#cYrF%wnK4%B zqVI*verc_y&GV^0)XN@KrhP3>o8&d|#u|1GXP7DFB58|%Y=jKW)X(d0G+nsoE92yW zySV?z<(C;5wN0uixlh{>Hyr2oWPrkC$7Dn0zS|v>UTOO7i0bS{k-TM16?{Qrt*pwl z!!kK`h}1)KmA_!pgeuW)?blE^q4B zaXH_aui~APMs<91mRQ$>mAuW-o*RI(x9Cj!@OT;7;qMWv?Z5olScC}}h6(c=91&wP z_?$cBzw^NcUL(lwL#JkgSBOr(VgE2~^bV0W#(7X0bI8{7g6#>n6dtwKY4;oZN+A-p zW>W8FOCrJcK<2)jA{X(BK1Cn$$VK7p@*B;O>lQ(;BkMfL*%yR(T1kHDETyR(+)Si{ z-)xGfADOow!{c8$ad5G|zTk4Jpy#~j%TfjGv9Lidl|Ebm6vXr{K#0VqUonpA05{dh!e2$?^2e zZVcgHl!1jktnm6nDVYO80}(Nft)3oTboq54e!31n?dGMzUF4r(w$|Qrr@%q^{tNmc zNz*)TIc_VixdmioRs79(*#&0LFDns#iSb(8#%AEe6s2Xb1XOKt&3xWf5XmZ^dH$_4 z=QBB$G7xnos%x2)K&`HFWLfk0ZUfRuh-)1ed!qe?=jjXK$ZJZN)ekwO9(qN>dWwVk zMxV5)OJ;1Mzlun<9NY}s_n+R6~WA@7fqVh z*JgXZ-{Q&9ifIkaPK_i(f2fYOO1F$zBn2>T_jPNggKl#7V> zix;f6?q0j&mg|pI)~@f#acTxpGS8|E%6+|sjf&IZ>}>-P-{2E83GAW%yY)6(Lrw}K z1}b14153@@Zlf^5<8Ru5Sr>{w+M(opq9-CCj_TnzK2OY%lWOUF^;x{24OZ zjrTNLAuO}J3jgX6j+ZOV;8e_kxdYAZ?~I=e=LnXn35bdkHQOcr2_9EtHA5*T+bUS zkJ!b&lzXT=nhbQlg}?nr@tK-wrK4z(BB`T)tW&&|KuZzHPdzD1rtMMAB{J~Bdu)b= zf&h&2n+s%KC_abQD%0h8e$4$;(HrL*u3HwlxP08>ozIr;@_7#REby^B-Us^KU4SyZ zzA(4kHxJM=_pdeoAQg*nUUtUb=LH{;Ke$EwQzM>?Ow58G``kOfJ$gQWW#0sREoNnU zSV5h@fbTIr2DUgr|8Q;4s5y zh}kAJ<9G=2`=mT?ztX2M7YlG%F|Jf1RGJ$8vCSl-?yi}(XWD_T$tMW;QZ%@{I3WN| zNk2RD_UHmB{?H!4t|{^TaP}dc8;Q@m&+T&2>bwwCmd`0H-+uu%RNJ$J_)2ls?lthb zB3!8mRNC$4y^kOE+_CmF*A$wYpE`~WlaYW|ESmv`!NV8_0o3{aCg%tQ;9GBXlHNo4 z*4XIQWJY3#t+Y8-B`;d($6IgO!vi`)brp5Ne_*NVVFiCeEj2!F2skz{;(y;FV=&j* zfKt{JfuZiIL~ceW4#3u17x}KLkTw*$e8dp6o9Bz`{*w{r?mx#l4o$K@8epFyO7ogs@L0$pKc7h(Ilb<#~(z z5vyrJoqP&9`IM6N1oKJ>EM^D~H7;8O7i%vOLhFB)D@sY*9Ym7UyI8BC2sn!_SB5jbLM#GF zi$JY=dq2SfZ2VL&i|#?)2kB+YV36!{1Yj#mr9o=_fwY@$nGgqXt&I&3FjB!0HG5sm z%fE&Mn3he#>cL^lNBw%+KRd-{=(3T4TOez8nRDhq%hliUpzD6)q?t3|c~I&Pm>kv7 z-hSbh$HR5i?!L68FYQG@;8SqY$jemBGRQ?e7j^ zCW|vQghsoNe!mK58I6^;I0r+axFrw>B~}Vdz{cNpzU%LWAS_w{{EkY<_*I@Kg9exW zBl*DXsZm*V2;?6sw*svA$~qvMG+MP<5wVMPaptlh3MyUl0CNJy_Btfe0H69b?g8q! z68J8)G^JDGv;D!0@{FL1Vm5$CP}==7zp5@EGXS*~WH}x5N(1Qg>K znVg5%wSc-GcljoDRle`N@F|7FI!^VaC)NzZCm^A6=GFn?2o5#+3t59MuI)5K^b#>%uS$ zyrz^}(wpW5eEp4JUR7!3V_Q7R24sHP<0XxV3F9*$AN(+9V z<&ZFoHO}cx6u!>C3K)GkLk1E<8Bd)Y_Q8OA&CiG|3xzJTxcH07j^2h$g8X$h<{d~{ z*nS+^%RUU;nN%}7qgw6}f+63K005xs0;-=?@06*L3hoTbPYn3;ekND8)x7m+av8$( zdk=dM?QrA)NF>aJ;sSR8?eevQ&gA@6n}3mtz##OS!oyx*5s@21oxKDYq1geBD`;a{ z0#i)SeFXXd)&dYoP6Zq{J>WmO?1#YZGFqQLMRfkaIg!xL1wPUy1EggtZVWZ@5SR)X-4%0iX_^bG?1fK9gL_3P%4Q|4 z$65tM%e;X6oEDd1`_fW@ALGiD6GT`hdgtPrRAh&Snp9zBgf`j70uQN5C4sG6e4H%?Wcs z&JNR#*{*dtUh`*NLMn-AfUQXFNdII1nNL&kj7aYj<5&c(|K5?!(OCMv@{Z%71+YZ} zRuF?JW;b0Mk#A}{D8+Us7A1!06w(feCM7@JfLQ$wjPMIELJdgqrq&rr(z}$|+`I(H z49;hP07ssmG1i5G%5`tNfN--zUzpCX*L31`6Jl&D&P%Fqk3M!n+jBvw7dPm zkcH0QxB~_9B1tG$bsVIertlTP*hbZHalb4_HNcZ=kuV>^*$Frf#(F;CAgcOv?b(+e zC4 zgm4GmgyaLHACXa-TFk^3JspIP%}GaX%VjexeE_cSKl*|b=p{O$p?u1recys`=YCRA z+#s+Qln=d7-1h_hgw`W;!Rhy1>tzC8{J>Ba6hLoX&bGtBOZFXbXO`^Z0e7Zq!zM*u z_)^0VOa;}Din;ccnch}+siPuyBppy2`H}CR&ER0D0QafiHpd@qPf_1`7NrmqFu9s1 z-&Wt<`kyE8t~D{y}rgQ(T3UmE!Yi;3PGh`emBTNOMXlf{I@8QT-3`u*;0E|#xMUOvCLS7B-FuCRXlj^$C}6}}cYMVD zZwrP#fH#q*h*TB@O!zAaj@6(k>^)k^I4*^3KrcEgIx>rz-u@D=M*sp=sR-@`Ny|wI zwYWa@i3e=>@6j*q`D(=00n<`pBROBKJ=jKJ6QUJ^BUHZIp&8ak?!l001!J9N6)bj( za*y5ROx8W_$!KO0c)amFXK_;wpr7?&MA;0^Ra`(@tX3 zS`yCU*}Byajl2xz=XEW_R7u$z|5Z_&AhhvLR%;A@dEBxjpnbf_$+Z>^ves#sAmzND zps)9^6oz89osv*9^@nTAAJYMU!?!)3K)ImYVWT}h3DsHN52XdqbLtO|et6@JKFrY4 zwzf(KpGo0-JG6sB-a<%GYt|dHS$y@;-=No%u>!9*=_DB;!OVqf`vdBCHucryFZ{g& zbpAgO%Mgueo|fN_i;9*BoSpl-J#sCcS*?0P$%%y5MT89tjN{Xg#~*HfPb#j>7+ARm z$GW_$yZscu++kp6g^G>tzb;he1`#WlklauN__s2ao#iA1MvKJbHp&Hq`K0Ik3|KSD zYPW8^#w(6q6luQx=~%M+2qaJ+8LWF9-+sE1WF!*=GGzXI^QpRo`Y*_0D4U|O?&@o&S%JEPK6s|xMU&rS={2Z$Q_O3p@HLVZS3)Shb z{k?8K&3YPh8f2W-at2P})g!=#v=9@l;JeCM4<5`DE;f>x%LG{o3tkOv=qZK3hw2*1f2ABDc zo=m@#)eY#9-eE)*N85rsuo{2w#Bnl?@7+PIfZYq}jX8q2(e+zqsS_9G=AT>K|0V*G zoz36$9)?liwZly}J;U_q0OzSHyarKO&2Lrtdu2zl%2du<7^4+771>v@>5~cm&u)o< zI7pfNfBHcjVG=|&-QQlZQ2xN>7A26TbB*7`^SBuWBr-L~Z1v#?3VdEnz?iO3DO7K0 zOH2lvB&PdWW3OG8QD}pfFY02lk<44h;@@3BA(Si66f}$^XEbS+CCWdi0!y|=I2PRk zVd}=?(Aszaan~Cv9|v_I?ap1?elMLB>ts7mOi4-m-~;&UZ(gE#+0PJQLF|VYw9}^= z?eQidl@%mDbz{udttSI_2V~-+mK{M`;e2`tJj@((%WV|p8skk|(mmhDY8W;z%GBtB zEb#%0Ek{u5=>RiN2inyOtRVUJl957EVNB zr2}h{5oc!Ukm}4c77~lf!k7W!Ofn#!Ij+cuLeh`sA0(GE_H({oI`)7}&BlC6nGV1T zA2scZbL$;h_g)t)W+Fh=QsE0u-x3oA=z#Pp;@*~l9xZrh#q2rAg7Ju;t&*e>b`caA zlk5j)&vwDasOR;jSXsdbjJ3ROb_}Ld@1&m4kLVM-PZK5Iazm)|AXe#@_}fH^jF0<(3DxXXeHQX6jz>w^!Yg)m$Nc|_|;JCD{Et4^%o=Kl45=EMz(s2=+Zs-v$% zy`UA_1-CtLuEZhe+d@CIp90y5VFNqpfehXOwq4!V^Ppj|oFj5_GE@R4xwd{Fe|cO; zWh;vMl2zlnJN^L`W6;zGn~z?MFklB3*!N6ytL=OOWcgYK{9<`2CT#${3)Q-*{+3Qq zoWbyb^nUYZ*kw%4%a|PfwG@flT zRVOd`ACGJf-XHW~O+t0zL;47_FIq;R>TiIXxmvSvv`3zhX#r8pt7`wH(6)j~c^7g$ zU8+pHw+t$NL&z0fuRdNuY1bOoP_2@TjfKo%e$(k}sc;v314@s}XWzXWqF~h5UjhQ= zU5~5A_P0(YWjyVA=W-uSS2}#T#3L<&wp6;|)@}i~~$1LQeCb5V?!Qvh(tzv2Rhn=z< zq-8l^E0R^c^jcO4AV6zM?O*LC_WY^lq zz%mnS6%}22gC*3uPswRxS;;7qjc&_&Rj@S1_FU;F1Y?SM3eQV1(&Qn&-g2^q`Z(%~ zNCLiNT=`bu;lh+*7)w|C$=l(87Yk2EN+dqO_>XZJika1*EqGPsaC?YI`rtcT#0)~u z-|e6c#)>S|Jl!;xRI!($tt2-2MOp%jt9u1yggd%Y&*Ym8b&%49vI$8sp-2<2`@6vu z0>)Di4wyUBKZmdKfzsG~VQYMmEksy!=O+StIhGOBHRY3$wOHsW)WSInG^;~g>Re+e zj!y~3T#rQmK#A3R);VXnnO9$r&S=hKjLx;eEtr2w@oIc79LTY6g|lH)0&NdQVA2iL z$Bs^y<(spmUaIkJH7#AKdC-p|*MC;k`3r}jCFruliB1Ll%@fAhFFAvt#9O42$6ijF zP!>6L9e>$86=YpJ-_oeYr|!)s8ktsJsj4SYTKJ0P# z2v9qi&u0Tk2DYpdRJ0dAf;;CJu+_7{mIT3v?ln9mZg$c%-%t7s1CyLE2Mm!V z1uc*C7`NJbarHkyx0ZTU_Pl?C(8Q1Lo}G-%v*FrTtXaH{Dh&ffXAX9?t7niz_trEC zl}_}D7Y1FG=(QNUR_MP1?)Z+yw`Vm#o3KWumTUX)j+OI+iN<|UqrAzEeK*_OK$PQ= z8G9r^`?gLiogu;;R?1lEt)YZ?12}ENyj4#UcEKfeJWE5}d4=!vd(>G2c2WFszadA1ML=+p?IWl!8dt`LOB{U7!(+-Tr6Zlt;w2M>< zrCWto>H2Rj62Br>5QiCCeu0g>ylQZG-lOY5h}L%0k5px(DKAu;YieABgS)Y#$*43n zw)W9aV4ZA$jBYhgLOhgEYoy|FrJcgM{OlanBNrJAU&@R*cz-<|p^GCG(xQ!u^yV$s z)onxmzD6_>OVH%$VIQM~_QK^l z{I+D{u<`-VGOc6=SZ9fm{K`*f(1^W20{`7lsd2vgb7)ij>(%Nyns(9=_oK_U{(`HL z>4WVh!F`@m5F%odzKo_8>MqX@RQ%iMQ9yhrqXu@a#DIE-u3+xvQbu)dUBWo9xD~H% z-k)9ud)A;}_98tmfV>&yWl#VvhCu~j zWpBrHd$>=shfhCc0oKMEYyCMMXttUk(e zr5c6iP$s8trD|P0r4|&(!kZy&>d6~}1dsK#ynts|^S z3m5ohAF%nq78hhs3>e>t7$IPqHyj4u(9y;|r@+Toc8S?{fYKclk{Pj-LFp3g4`1s% ze71J)-{BGw9tiPlnRpbCkoEKtGsl>SL)FaD`zqkOJ`R1tiN97KW$Fy?^gZh4=c@xr zaT{aj+=q ztLGB~I+uXJ53KIg)M(F-(NOWe=q0PTf+q(L-O#>@tX1~n7i45W*l&N{o`rc4ol(%^ zv-KMcT$hin%`9$*fl?kS*$-%ywOEiD>flC^3S&_!Q#^%^Z@$LpHmWE9l7y7&VL;E` zXPeKa=24Id{0{CI5|j00fH&kA{0S5PZ-YaTJnD3y+HV6yW9|Z}?GcqmNhd8+Hx7LF8jFI!{_7XVfYFi*p4;k2XFyY5J!sA|4ozfo$PKoPUhl{I&+|dkqK&vlr1^V5xfRY(?+Hm!NJ&AnV^7KhsR^bb@g>xmGyp;HUGV{EB&)IN0gP13HCZf6 z8mP$XS3cT;x#<|x$u8Z`fyQEEP>{sm-Iljh>*Zla{9`RLucvemp(wAqqK~RqI$H+{fyjQ%9y(xDdtw{q2EmlCz882nR9;3Z7%5S@60%; z4$}Z?mS4q;uz|SZ)E*gX8O*pWkdz>i&DxL8VQqSlarR4FwZC8iG%Uk%kKf)tmfI}6 zQeX#F&10vR-~B3Lmu52;10%}QRJtuN@x3Jec0TEC);mvm+{uGCfwNS$1XtnjjH6Oh)?v7+!7<#7A846BcirxUme{ zSDl^`t^zMekW_akw_m4r=-+v4^4*HD%~8W^B<4mso5LqTPs|%KW5xtR=!NDs+JmD# z?L@N+{!@OpF`Ztzjp8`bdNhLIr!~@ef*xbKb2^1gY3m|h5YfyqiHQ_Kv zOe^Rqqw=-I{JO<#5<%IUum7BODF5jqjR*V|G(JBT)u*7rrs`vPBXwN^T!9TC_roG>$w$Gf)l*;@6Y!J9$;W66_#!t@Z4* zG`Zj*9G4M9PeWcm1ZflfSO55w^uG!51GXjEvMh5hnn&Z|SJSn6>T?V-lVCJitQvf3 zH@(2KY!UHkCsH;_A$+ksHV-K4s0Cqo2!YCu$mmRXl;I0Gj8o6EfSO_#Je=kgIAWGE z9%y_V?Qie~#$mw{1<}Ab%ubXj&nXr#lDMi|_Q}qR<;k-u3Z8D?>dY`Jc4BSH=q-75C>>TX4HrHG_^6D^zZ($fq zf0;lT6B!TM5TX8rh`WL44I1G}6-PEsmLNbBMf$XrhQ?^NzO(BAkm{7w_%Db}vG%-y zJ1^4zfLDm}wQvn6V(v%_3`icR+ZWMgv2X~S$PWZFHz6*iwAlICXTg8Ue|m))g~dsu zFq%2>!JUw}*>djbpU0%~qolrz&=m24l4=28ymH;bbbrNw(L3K0rv$~p7++f3gXIR^ zra#o^KFeu=u;s+G7pd&PU`yL5mh35FZyueBxlUWuqaI7!(J>R&uj+Ix|Ko=z+WQx_ z46gVL7zV8+&$fAcc;9&V*~?FSK*Vj&UkP`vt;4&T0H>aqrpvqg;%Fp7B_+VXNfxkeygU&r~6#@I;f^BH}-v_tdK9yyKZkk7gRkZQ}D*qPDoku(^SG~?oO0?E0I6j*#m z)#O*QA9Gi@ycBQXEX`Dfl$DyJtqh|UKmE4A27-j z*nzPIA`*{-U?N?XR<^jL*2dzxy?TS(MG_N^*0&y6Zh~c+J46pCX{c=w1vqxJu@)TL zV|Z$>(H@-WZHLsq9@a;Q8wg@;>(;-5(c+uoz2c)I)xp|Ps6c&AebCu7B@Xc*ghrMy zREyD3Yxag!6fWGRtl}U^sGN@OejI{m2lXC_{7W#ra_|n{oDYm*DY@tpl`Pgu7japi zJfDfSyFn?JTv!E+F!i{KyW!6SudVmE4uli{VXbt8UOEG#*r1kNS5Ty2xLFh(J%?a? z_~;{8rkj~!9tABixHRp-dGg%Tp$g^Jk39@&dj4T=me_Lr zjxE~zf!455}2@#K0?KHF9OC zTxLgml^5+FX1(`txjkDH5w2UuP8G-EDq|{)8!)k4&RA+wpkMyDN`P+DbI0e{Ia_$!&;nZNVg#noLsDR zhT zoDmMNhVt)8$CBGage~>@i23?NxFwOIOmxa4daK{fyvAPaI~+2oY2%Tkjhz0`MIOGF zDwED*>GxYsIs0acdXk$h1t__VODCgipD~m1o*a3n^NrQeshk{HxE^s(lO`ml7}5w? zNy0ioyJ%`{iBgnFoglvP(2_xSDgw^lH&ybROe2L_xVUH+hay@*igb|^e$gcuMUK8t z>Y&&owTPxBw21U{+!xP}3B)lhu!N>dIZ&pOxF;a%WfeJfiqzbNaUSN zkw0&oAt>sW@lzUeJT;VdA<77*iuU=}3$rIA zQqC_v4^Q#!cijOqP08U6V8~zdRg^5D@@rBzt~VI0nv*Gf#~{=4C$jv&0ObCY+#VQV zBuN+(d0Y~8y)?TgOpBC|pl|?;Wcr6;h#QN~ImAs{tTd`|vDhaKa(FvF9Ng|s9Z&%N zIsD86a|S5OuuK~6f)(R5Cy7idlihElp#m6BgUmVDtFf#R!oeS~e@dp`h55r+Tt_y! zvy81cIQZtIS%%r{ne_qzY?BYhXIIbGqhq zZj!Qy!AP0m$IH7WD}ewU+9@1X?rM$c>1sEOG1h93^S?fE^G3Z+xHVdH!FioX5Oed$ z#Q53?_g*TF7X1^eXp7f^_ z$(MB6)^$Q7%BlNOAfIc=i)`Scs7=sj2p0yhO5FD^8(mB~qr#0w%YQ;`NX#~^T5t3l zbjA&}z(^9{{G;0*7aX;245IXpUg&grXlmL8e4rPo&HrjEMKX)jYkJr zJ8A#>Jo>I6LC)Q&{Tq~IUd~H^N%6PN(kVl_;xx1UJ0Ls=yv@hs#3x1vpTa2y347ce4p{?5=onP5!yvKK`o96!18GuU5Qy8*LmWXq(=h~6H6v!l`Y9BVDGYyyE}RXOlyVO=;!?A24T zBK|4P?*^J?q{Lq>Rm=|D@EP1a9{)XK1*)_Scz>Fl6w|zqRO`_k8qvC<;+tT01iXas zmSPmR3GH`)p)?NAgYk2O0r0+WzbAGit;mTq;gyN9TwhIj1(AWYxf}cFh5IEp_8(nL)~l8g$nTKYlN#es4PM_Y1ERzEh0JdPuiM((S`*)wNdYazjlkYCE8 zdg8#f0W>&n3ts>zVUv@1Ts~57r_zrFN&wWWG0vht>iuVok@yiO1TB5 zVWPHhB^;)kSTdXwEMaJgo_H1jF#x)>YFk<=ardMR#@&%}_3Ab#IyvX==FwVLRU!7(Ldv z#&|edf#{c5SSHk9MU`D;C$>s}W*6-K754`}g^f#S-~3U;PEZE2e`wB*0Y*1^r(dAP zS4LQe#C7N`Slk-2rVwl;{&oi0*i{}L4kaEA4}AdcdpAGsk0Adwg1Mq#*>W38s>RNd z{&(31A=xzA36HKIP>`QQowtYTZk)S6Uv>~kb*To_H@VX4SJR>po$f?>a$L!@1_vaB zF`dI1TQ|LbhmF|4o8QGxcTaVkk8@j~71>Hh&kd2Cex literal 71568 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 Km8ulY0{;) PSA_SLOT_EMPTY` transition can be done by any function which calls `psa_unregister_read`. +In the state transition diagram above, an arrow between two states `q1` and `q2` with label `f` indicates that if the state of a slot is `q1` immediately before `f`'s linearization point, it may be `q2` immediately after `f`'s linearization point. Internal functions have italicized labels. The `PSA_SLOT_PENDING_DELETION -> PSA_SLOT_EMPTY` transition can be done by any function which calls `psa_unregister_read`. -The state transition diagram can be generated in https://app.diagrams.net/ via this [url](https://viewer.diagrams.net/?tags=%7B%7D&highlight=0000ff&edit=_blank&layers=1&nav=1#R3VxLd5s4FP4ts%2FAyOUjiuazrJJPW7aQn7UzTjQ8F2VaLgQP4lV8%2FwjyMBMaCgEOaRQ8S0gV0rz599%2BGO0PvV7i4w%2FeUnz8bOCEr2boQmIwh1JNF%2F44590iFrKOlYBMROusCx45E847QznbdYExuHzMDI85yI%2BGyn5bkutiKmzwwCb8sOm3sO%2B1TfXOBSx6NlOuXe%2F4gdLdPPgtqx%2F29MFsvsyUA1kjsrMxucfkm4NG1vW%2BhCNyP0PvC8KLla7d5jJ167bF2Sebcn7uYvFmA3EpnwAzxP5%2F%2Fef9h%2BMVx3PH765f%2F6eJUqY2M66%2FSDR1B1qLyxTTb0chFf3n6bTrNuKr9wp2Lw0gxnATZtHITZ3Z8BP56XclifaJ8tOn1xql%2FaGG%2BXJMKPvmnFd7bUwuInRCuHtgC9NEM%2FUfqc7LCdiyouSrpOGxxEeFfoShfpDnsrHAV7OiS9K%2BupwlKLVaW0vS3oP%2B1aFlSf9ZmpxS1yyUel0ItULw10BECFkvgVc%2B13sbXTluWYYUgsdqECb%2B3a8QpNJNqiixPsv6e3Do2nYmOyK46b7LPWjkT5JHr9VOg%2FTokb2YyT2gi9dWDh83YZmcECRzXj5GQctpldXNZtQXdKhe6yvgA7ZkQ27N6vUmj6hAeP0C87aTqKytlE8t3prOJe5QVpxrVR%2BNMZsTLixCbLVBJ7sLZ8EV5ggLBkgH5oztZugBckjHBw2PBlm6RKmZo%2F6XnA7lmHLNzYTqlR4IB2xFuTUMR9l95YEduOZYwDHJJn8%2BdBXmxOfvyBh09WxiNlUmlg9TuIB4H83EifwkBzFThI11DSDEYbV%2FBltpOJAdwUbz4PcT%2F6FAH9m08PX5%2FeJoIPDsCNzgE8hWKpAMWgFopzyJeKkC%2Bdgfz2AA4FARwMC8BZyykBrTB%2BnzkHegbsjHJygD03iTP7jfczi%2BJ1RDx3yJCd7ZkhQnYqGTJC%2Bfn94Xf5OL69n07vP98NGoaR%2BsowLIsce418nb%2F%2BOGfn1ZWkiCjp4ebz5GDugnqa3Exvvt7%2F8%2Flt6mhwfEbri86Ie5btPNj2dCYLPZ2jM3BQdAZK9PDTZagB6lHKisqegoqsXmtA0aCuKbSBOPGiXAeoHGmSL0t2dBHEiOkP5SY42ODZPMD4QINCx4uEMSSWENJPiTgG1RZRBsO0st08RKKVi5Evxa1AFUvoHtyulTbeWjLrVf21YQXcYoCTpAzgVIpFLBSBOIyWIRzSJa0dxMkSB3HU1hFnkn3H4IRhbk5cEi4rUerNYFK%2BC18MSlfUQGRDY1EJdWN8eqXUC2BUFUnmdGmt6VFn55zoctkB8ZBUe7ASzQ6gQYGVrCmMwahay%2BiSonKCeKZ%2FAouoDZj7wrB0e55%2BYYOFPU2S6t8LcuPBmfGyXiefXiRv3HbzTMayBcid5TvPeH1PHpV3DzsxBzOhi0xyowFNpGs%2FM1175njW75xozr43kmE5XnhgqY1m%2BWuq%2BOKsN8xLc5Tr4gwASGdtrZsIIMt2oXKpEwBV5e07YalF%2BBZ0wQu0tN%2BcgiwI%2B8PKKUANMlaiKC1hH5yKA12IgqIq16gShmwcRoG3fzl8dQOVg4W4fBt34HvLuso6P9k2eKH5XrFcw%2BgB4irP6e6DjJW09hxaNcfF%2FvFtWEFGxLE%2BpW3SFGmcly1Ia7uyuLKHXRM1HAKm1O6bTliTwYWMO4IUkPn3fbrOlatzkUoM4egei0Q9RvdEHWZl0MiigrbIwtVjqP0V0FVaXfbeHLQwNGmwgNJZIUYMKNnUjjkKG9%2FroxCjWq8Xqsw9Dw1tYKg9nCiCcDIwR%2BxEeKoxnECOqKj9lXdVmx2sMLtK16hUotvArdoSv5wmfRvxpPrN2kWiE%2BisW9QRkAH0SkBWlV3iNNl5RqF1oGgoeMKFx1vH85GsXUNdV2QoG7IBkY54uUySEwqBTdNgP%2F2a4lOAwb6EJqFrDUr5H6r%2FImDUCgOgiTCl%2FZv1k0OoKOge7A8i6vd7B1goKTpL6jridH2UfDyQ9W46hzNdX3zZ%2FLj9aLmuX%2FlziG5IHFO90ernVb1RONGCtmHVeyCuEEPhQ0TCkKucCVp1R%2BEqbU6YwZGV7yU1Zw1TkC4OzKhFMN3zm8ftY5Zo44BsDtUmM28d%2Bevo7aUha9GhA6RUZFDpqL44nMYIvVipHHz9VHpzu%2FrDfmYlmjIQrYQ5ppOy3NSFamMMNiJcKiIWLtXjBIkmSY%2BCOt04H57k79uncPzNDvFXcm9f3c30HghHZqc5XWhiqWz6XqyGnjOkfjkIGhLl0Fp7eRzl0KCYZTZ15PiouSZ3W1VVadJlPlOL3q912guf4qxBn97FNQgKDLWb4x1xOTjO%2F2%2BDU7R5%2FI9HkuHH%2F70F3fwP), which encodes the graph. +The state transition diagram can be generated in https://app.diagrams.net/ via this [url](https://viewer.diagrams.net/?tags=%7B%7D&highlight=0000ff&edit=_blank&layers=1&nav=1#R3Vxbd5s4EP4t%2B%2BDH5CBxf6zrJJvW7aYn7W7dFx9qZFstBg7gW379CnMxkoUtY%2BGQ%2BiVISCPQjD59mhnSU98vNg%2BRE84%2FBS7yelBxNz110IMQAEsnf9KabVZjmHnFLMJu3mhf8YxfUF6p5LVL7KKYapgEgZfgkK6cBL6PJglV50RRsKabTQOPHjV0Zuig4nnieIe1%2F2E3mWe1FjT39X8jPJsXIwPDzu4snKJx%2Fibx3HGDdaVKveup76MgSLKrxeY98tLJK%2BYl63dfc7d8sAj5iUiHH%2BBlOP338cP6i%2B37%2Ff7oV%2Fjr442aSVk53jJ%2F4R40PCKv7%2BIVuZyll%2FffhsOimsiv3OE0njvxOEKOi6K4uPszYtuzUnbzk2yLSScPTvRLCv31HCfoOXQm6Z01MbF0hGThkRIgl04cZkqf4g1yS1HVScnnaYWiBG0qVfkkPaBggZJoS5rkdzUrV1hhsUpeXlf0n1fNK6ov6pzc4mal5L1SyEWulzN0BABHSeyM%2Be671NpJaeI5cYwn9ERFwdJ30xkaKKREJifafs9v7QqjamGwqbYbbIvSBidlJ3I9qtTvu6SFoketNuJgGU3QabtMnGiGkiPttKwdcqlVfKjbiu50ju6Kugh5ToJX9NrnKTQf4SnA5M1qTUc3GJvI3jvvVV2rrCDTvrUrP4sSq6mM2GyaDsTurK2chAsMENaiBC7WcBg746UfoRmOExTtEKCy2HH9UieaGzo%2Fya5BL2wPz%2FzUmInloIhUpOsXE1h%2Bl99YYNdNZfQjFOMX5%2BdOXmpzYToLu3nR%2Bz19wLXC48uMRYpyc8lHofCbhyDKLVRMm1LZDbzMwAoxgOkSTKcxakfpIjvD3aenr6O3CfOdQ3lbOsrneK1U8BocxetyXygLo2qhZl9ojvJQEOVBt1CetpwDNBYG%2BRObRcuoXvDSU6g%2BdbA3%2Fo224wkB9QQH%2FlvD9WJhdRHXc8mQEsr2bw%2FkDzf2%2B8fh8PHzQ6exWjVeGas1kb3xrFPTX3%2FcsenVlaSLKOnp7vNgZ%2B6CehrcDe%2B%2BPv7z%2BW3qqHOkx2yL84ifUZudhZtznsKJdYrzwE5xHqiQzc%2FSoAnI2VTTDXoX1DXj1gS6CS1TJwWVES9KiIDBMCvtuozIEkEMLkciZAVFKzSeRgjtuFLsBQmfJwkCDXeYmExAwuViXBw6OWpnOVuBC12kbKUY7VosDfD4hnyYvNWbHA6zXq96POyWEzCFSkUpoNIgqEaDGkhdewVWqpZiNgNLTWHAkti6yphk237B5oA5xT6O5wLHyjcGXOVSvRi5bogVabZJQ5cqx0ItrtQrABmPkzO6nCzJRuqWFOx6YQ1xN1lzRBMNa6idQjStiNmWMdyGHi%2FdYASxB4sawCI24GwrzfLlWf%2FANo2NpqIcfy7ItAcn2mvWMfnkInvipotn0NcmAD9MQu8FLR%2Fxs%2F7uaSN2nq1hpyejMpew0pqwTzNKKjYkMZKx47tjL5j8Lvn2%2BPtFA6VyJ14Q7wj8Wb3CJbHaaq%2BDwf8wel7iuIxdDqgWvZou5Oe5ZJr0Q%2F1ae5zKS6mQQtarG5SgT6PCztuN5GiCG1u3IjnQhJSV6HrDjQ3UOdauxMRV3gmRi1UuipMo2F6OcXLwtLMQVy5jCS4IzTLoM2CxDC403xuaTdktQByXicj32nKJ%2Bym0Oh8X28e3bnltVYbX6k1D1arJOBsEibssi6t3NDR1w3YBeI4uLinUymYc9ZJwBxRujjY9CNzZuUqSjLAnlIarFj2hon4DvdPwY4Cm8MOkyhjtJUByra547orZHXCpzgKKtPSXFFCKrpKJDO3mbCP9ha%2FXK2VWn4aGJjDUHE50QTjp2Gmtxkt3NpxAhs0Y7WXe8c0O1tKZhr42eZ61NQ4PqdPbdV8dX%2FYywsvlF05yIRGorwSJPKrNaFJ6iKaxX6oryMTEGxoHSFTNvIWWpWtQszUbqpbKyqVCy1AIts6NnpC3qY4CbPohTEW9NaFS%2FtTjbwTso8IAOEeY3vzJ2gnKcLP23%2FKnMcdBQQJgKrpFc0hJFLKNbJwnvNwMp3BsWbMvqx%2F3Hye%2BH3I%2FjJHDGanEmkZf47XGGEWzFruViqMyOTI667YSxmX9hCNNHmPk2pwQYUxxBi%2FCIEsRPMtPP0M%2BipykgYM%2FCM%2BPJaT00kURXu3yfsbBMgmX1DOfn1X9GlB5FB0kIKWuAe65%2BGLvHSX0almMsLMJDCeyCeScfv6wT%2FdEAyKimUz7YFkRebtSbpNNu7IPcs6F8zEZQaIh4L0gqUvww0j7vh7F%2FW9ujL7iR%2FfmYWy1QF0KOy2JxzmWSicnvP4nF93KumPJi9n4UMmQFxOKWea550bW3W9qcrPiuCZdz4yaJ4x1gVwcXb8SyAWwDTlsQmUijIxPogmYkeL%2B3%2BJkzff%2FXEi9%2Bx8%3D). ##### Key slot access primitives The state of a key slot is updated via the internal function `psa_key_slot_state_transition`. To change the state of `slot` from `expected_state` to `new_state`, when `new_state` is not `PSA_SLOT_EMPTY`, one must call `psa_key_slot_state_transition(slot, expected_state, new_state)`; if the state was not `expected_state` then `PSA_ERROR_CORRUPTION_DETECTED` is returned, this must not be a possibility in our code. The sole reason for having an expected state parameter here is to guarantee that our functions work as expected. From f266b51e3feebd8d88584eab54b82ebc7df5d1f3 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Fri, 15 Mar 2024 17:30:31 +0000 Subject: [PATCH 197/211] Respond to feedback on psa-thread-safety.md A few typo fixes, extrapolations and extra details. Signed-off-by: Ryan Everett --- .../psa-thread-safety/psa-thread-safety.md | 68 +++++++++++-------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/docs/architecture/psa-thread-safety/psa-thread-safety.md b/docs/architecture/psa-thread-safety/psa-thread-safety.md index 58051fda12..d33e0a6c47 100644 --- a/docs/architecture/psa-thread-safety/psa-thread-safety.md +++ b/docs/architecture/psa-thread-safety/psa-thread-safety.md @@ -10,13 +10,13 @@ Summary of recent work: - Slot states are described in the [Key slot states](#key-slot-states) section. They guarantee safe concurrent access to slot contents. - Key slots are protected by a global mutex, as described in [Key store consistency and abstraction function](#key-store-consistency-and-abstraction-function). - Key destruction strategy abiding by [Key destruction guarantees](#key-destruction-guarantees), with an implementation discussed in [Key destruction implementation](#key-destruction-implementation). -- The main `global_data` (the one in `psa_crypto.c`) is protected by its own mutex as described in the [Global data](#global-data) section. +- `global_data` variables in `psa_crypto.c` and `psa_crypto_slot_management.c` are now protected by mutexes, as described in the [Global data](#global-data) section. - The testing system has now been made thread-safe. Tests can now spin up multiple threads, see [Thread-safe testing](#thread-safe-testing) for details. - Some multithreaded testing of the key management API has been added, this is outlined in [Testing-and-analysis](#testing-and-analysis). - The solution uses the pre-existing `MBEDTLS_THREADING_C` threading abstraction. - The core makes no additional guarantees for drivers. See [Driver policy](#driver-policy) for details. -The usage of keys within other PSA Crypto APIs is planned to be made thread-safe in future, but currently we are not testing this. +The other functions in the PSA Crypto API are planned to be made thread-safe in future, but currently we are not testing this. ## Overview of the document @@ -30,7 +30,7 @@ The usage of keys within other PSA Crypto APIs is planned to be made thread-safe *Concurrent calls* -The PSA specification defines concurrent calls as: "In some environments, an application can make calls to the Crypto API in separate threads. In such an environment, concurrent calls are two or more calls to the API whose execution can overlap in time." (https://arm-software.github.io/psa-api/crypto/1.1/overview/conventions.html#concurrent-calls). +The PSA specification defines concurrent calls as: "In some environments, an application can make calls to the Crypto API in separate threads. In such an environment, concurrent calls are two or more calls to the API whose execution can overlap in time." (See PSA documentation [here](https://arm-software.github.io/psa-api/crypto/1.1/overview/conventions.html#concurrent-calls).) *Thread-safety* @@ -56,7 +56,7 @@ These are the conventions which are planned to be added to the PSA 1.2 specifica > > * There is no overlap between an output parameter of one call and an input or output parameter of another call. Overlap between input parameters is permitted. > -> * A call to :code:`psa_destroy_key()` must not overlap with a concurrent call to any of the following functions: +> * A call to `psa_destroy_key()` must not overlap with a concurrent call to any of the following functions: > - Any call where the same key identifier is a parameter to the call. > - Any call in a multi-part operation, where the same key identifier was used as a parameter to a previous step in the multi-part operation. > @@ -67,9 +67,9 @@ These are the conventions which are planned to be added to the PSA 1.2 specifica > The consistency requirement does not apply to errors that arise from resource failures or limitations. For example, errors resulting from resource exhaustion can arise in concurrent execution that do not arise in sequential execution. > > As an example of this rule: suppose two calls are executed concurrently which both attempt to create a new key with the same key identifier that is not already in the key store. Then: -> * If one call returns :code:`PSA_ERROR_ALREADY_EXISTS`, then the other call must succeed. -> * If one of the calls succeeds, then the other must fail: either with :code:`PSA_ERROR_ALREADY_EXISTS` or some other error status. -> * Both calls can fail with error codes that are not :code:`PSA_ERROR_ALREADY_EXISTS`. +> * If one call returns `PSA_ERROR_ALREADY_EXISTS`, then the other call must succeed. +> * If one of the calls succeeds, then the other must fail: either with `PSA_ERROR_ALREADY_EXISTS` or some other error status. +> * Both calls can fail with error codes that are not `PSA_ERROR_ALREADY_EXISTS`. > > If the application concurrently modifies an input parameter while a function call is in progress, the behaviour is undefined. @@ -104,9 +104,9 @@ The core makes no additional guarantees for drivers. Driver entry points may be The PSA RNG can be accessed both from various PSA functions, and from application code via `mbedtls_psa_get_random`. -When using the built-in RNG implementations, i.e. when `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is disabled, querying the RNG is thread-safe (`init` and `seed` are only thread-safe when called as part of `psa_crypto_init`, but not when called directly. `free` is not thread-safe). +When using the built-in RNG implementations, i.e. when `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is disabled, querying the RNG is thread-safe (`mbedtls_psa_random_init` and `mbedtls_psa_random_seed` are only thread-safe when called while holding `mbedtls_threading_psa_rngdata_mutex`. `mbedtls_psa_random_free` is not thread-safe). -When `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is enabled, thread-safety depends on the implementation. +When `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is enabled, it is down to the external implementation to ensure thread-safety, should threading be enabled. ## Usage guide @@ -118,7 +118,7 @@ The PSA subsystem is initialized via a call to [`psa_crypto_init`](https://arm-s Once initialized, threads can use any PSA function if there is no overlap between their calls. All threads share the same set of keys, as soon as one thread returns from creating/loading a key via a key management API call the key can be used by any thread. If multiple threads attempt to load the same persistent key, with the same key identifier, only one thread can succeed - the others will return `PSA_ERROR_ALREADY_EXISTS`. -Applications may need careful handling of resource management errors. As explained in ([PSA Concurrent calling conventions](#psa-concurrent-calling-conventions)) operations in progress can have memory related side effects, it is possible for a lack of resources to cause errors which do not arise in sequential execution. For example, multiple threads attempting to load the same persistent key can lead to some threads returning `PSA_ERROR_INSUFFICIENT_MEMORY` if the key is not currently in the key store - while trying to load a persistent key into the key store a thread temporarily reserves a free key slot. +Applications may need careful handling of resource management errors. As explained in ([PSA Concurrent calling conventions](#psa-concurrent-calling-conventions)), operations in progress can have memory related side effects. It is possible for a lack of resources to cause errors which do not arise in sequential execution. For example, multiple threads attempting to load the same persistent key can lead to some threads returning `PSA_ERROR_INSUFFICIENT_MEMORY` if the key is not currently in the key store - while trying to load a persistent key into the key store a thread temporarily reserves a free key slot. If a mutex operation fails, which only happens if the mutex implementation fails, the error code `PSA_ERROR_SERVICE_FAILURE` will be returned. If this code is returned, execution of the PSA subsystem must be stopped. All functions which have internal mutex locks and unlocks (except for when the lock/unlock occurs in a function that has no return value) will return with this error code in this situation. @@ -143,8 +143,13 @@ There are two `psa_global_data_t` structs, each with a single instance `global_d * The struct in `library/psa_crypto.c` is protected by `mbedtls_threading_psa_globaldata_mutex`. The RNG fields within this struct are not protected by this mutex, and are not always thread-safe (see [Random number generators](#random-number-generators)). * The struct in `library/psa_crypto_slot_management.c` has two fields: `key_slots` is protected as described in [Key slots](#key-slots), `key_slots_initialized` is protected by the global data mutex. +#### Mutex usage + +A deadlock would occur if a thread attempts to lock a mutex while already holding it. Functions which need to be called while holding the global mutex have documentation to say this. + #### Key slots + Keys are stored internally in a global array of key slots known as the "key store", defined in `library/psa_slot_management.c`. ##### Key slot states @@ -166,7 +171,7 @@ In the state transition diagram above, an arrow between two states `q1` and `q2` The state transition diagram can be generated in https://app.diagrams.net/ via this [url](https://viewer.diagrams.net/?tags=%7B%7D&highlight=0000ff&edit=_blank&layers=1&nav=1#R3Vxbd5s4EP4t%2B%2BDH5CBxf6zrJJvW7aYn7W7dFx9qZFstBg7gW379CnMxkoUtY%2BGQ%2BiVISCPQjD59mhnSU98vNg%2BRE84%2FBS7yelBxNz110IMQAEsnf9KabVZjmHnFLMJu3mhf8YxfUF6p5LVL7KKYapgEgZfgkK6cBL6PJglV50RRsKabTQOPHjV0Zuig4nnieIe1%2F2E3mWe1FjT39X8jPJsXIwPDzu4snKJx%2Fibx3HGDdaVKveup76MgSLKrxeY98tLJK%2BYl63dfc7d8sAj5iUiHH%2BBlOP338cP6i%2B37%2Ff7oV%2Fjr442aSVk53jJ%2F4R40PCKv7%2BIVuZyll%2FffhsOimsiv3OE0njvxOEKOi6K4uPszYtuzUnbzk2yLSScPTvRLCv31HCfoOXQm6Z01MbF0hGThkRIgl04cZkqf4g1yS1HVScnnaYWiBG0qVfkkPaBggZJoS5rkdzUrV1hhsUpeXlf0n1fNK6ov6pzc4mal5L1SyEWulzN0BABHSeyM%2Be671NpJaeI5cYwn9ERFwdJ30xkaKKREJifafs9v7QqjamGwqbYbbIvSBidlJ3I9qtTvu6SFoketNuJgGU3QabtMnGiGkiPttKwdcqlVfKjbiu50ju6Kugh5ToJX9NrnKTQf4SnA5M1qTUc3GJvI3jvvVV2rrCDTvrUrP4sSq6mM2GyaDsTurK2chAsMENaiBC7WcBg746UfoRmOExTtEKCy2HH9UieaGzo%2Fya5BL2wPz%2FzUmInloIhUpOsXE1h%2Bl99YYNdNZfQjFOMX5%2BdOXmpzYToLu3nR%2Bz19wLXC48uMRYpyc8lHofCbhyDKLVRMm1LZDbzMwAoxgOkSTKcxakfpIjvD3aenr6O3CfOdQ3lbOsrneK1U8BocxetyXygLo2qhZl9ojvJQEOVBt1CetpwDNBYG%2BRObRcuoXvDSU6g%2BdbA3%2Fo224wkB9QQH%2FlvD9WJhdRHXc8mQEsr2bw%2FkDzf2%2B8fh8PHzQ6exWjVeGas1kb3xrFPTX3%2FcsenVlaSLKOnp7vNgZ%2B6CehrcDe%2B%2BPv7z%2BW3qqHOkx2yL84ifUZudhZtznsKJdYrzwE5xHqiQzc%2FSoAnI2VTTDXoX1DXj1gS6CS1TJwWVES9KiIDBMCvtuozIEkEMLkciZAVFKzSeRgjtuFLsBQmfJwkCDXeYmExAwuViXBw6OWpnOVuBC12kbKUY7VosDfD4hnyYvNWbHA6zXq96POyWEzCFSkUpoNIgqEaDGkhdewVWqpZiNgNLTWHAkti6yphk237B5oA5xT6O5wLHyjcGXOVSvRi5bogVabZJQ5cqx0ItrtQrABmPkzO6nCzJRuqWFOx6YQ1xN1lzRBMNa6idQjStiNmWMdyGHi%2FdYASxB4sawCI24GwrzfLlWf%2FANo2NpqIcfy7ItAcn2mvWMfnkInvipotn0NcmAD9MQu8FLR%2Fxs%2F7uaSN2nq1hpyejMpew0pqwTzNKKjYkMZKx47tjL5j8Lvn2%2BPtFA6VyJ14Q7wj8Wb3CJbHaaq%2BDwf8wel7iuIxdDqgWvZou5Oe5ZJr0Q%2F1ae5zKS6mQQtarG5SgT6PCztuN5GiCG1u3IjnQhJSV6HrDjQ3UOdauxMRV3gmRi1UuipMo2F6OcXLwtLMQVy5jCS4IzTLoM2CxDC403xuaTdktQByXicj32nKJ%2Bym0Oh8X28e3bnltVYbX6k1D1arJOBsEibssi6t3NDR1w3YBeI4uLinUymYc9ZJwBxRujjY9CNzZuUqSjLAnlIarFj2hon4DvdPwY4Cm8MOkyhjtJUByra547orZHXCpzgKKtPSXFFCKrpKJDO3mbCP9ha%2FXK2VWn4aGJjDUHE50QTjp2Gmtxkt3NpxAhs0Y7WXe8c0O1tKZhr42eZ61NQ4PqdPbdV8dX%2FYywsvlF05yIRGorwSJPKrNaFJ6iKaxX6oryMTEGxoHSFTNvIWWpWtQszUbqpbKyqVCy1AIts6NnpC3qY4CbPohTEW9NaFS%2FtTjbwTso8IAOEeY3vzJ2gnKcLP23%2FKnMcdBQQJgKrpFc0hJFLKNbJwnvNwMp3BsWbMvqx%2F3Hye%2BH3I%2FjJHDGanEmkZf47XGGEWzFruViqMyOTI667YSxmX9hCNNHmPk2pwQYUxxBi%2FCIEsRPMtPP0M%2BipykgYM%2FCM%2BPJaT00kURXu3yfsbBMgmX1DOfn1X9GlB5FB0kIKWuAe65%2BGLvHSX0almMsLMJDCeyCeScfv6wT%2FdEAyKimUz7YFkRebtSbpNNu7IPcs6F8zEZQaIh4L0gqUvww0j7vh7F%2FW9ujL7iR%2FfmYWy1QF0KOy2JxzmWSicnvP4nF93KumPJi9n4UMmQFxOKWea550bW3W9qcrPiuCZdz4yaJ4x1gVwcXb8SyAWwDTlsQmUijIxPogmYkeL%2B3%2BJkzff%2FXEi9%2Bx8%3D). ##### Key slot access primitives -The state of a key slot is updated via the internal function `psa_key_slot_state_transition`. To change the state of `slot` from `expected_state` to `new_state`, when `new_state` is not `PSA_SLOT_EMPTY`, one must call `psa_key_slot_state_transition(slot, expected_state, new_state)`; if the state was not `expected_state` then `PSA_ERROR_CORRUPTION_DETECTED` is returned, this must not be a possibility in our code. The sole reason for having an expected state parameter here is to guarantee that our functions work as expected. +The state of a key slot is updated via the internal function `psa_key_slot_state_transition`. To change the state of `slot` from `expected_state` to `new_state`, when `new_state` is not `PSA_SLOT_EMPTY`, one must call `psa_key_slot_state_transition(slot, expected_state, new_state)`; if the state was not `expected_state` then `PSA_ERROR_CORRUPTION_DETECTED` is returned. The sole reason for having an expected state parameter here is to help guarantee that our functions work as expected, this error code cannot occur without an internal coding error. Changing a slot's state to `PSA_SLOT_EMPTY` is done via `psa_wipe_key_slot`, this function wipes the entirety of the key slot. @@ -184,7 +189,7 @@ A thread can only traverse the key store while holding `mbedtls_threading_key_sl (slot->state == PSA_SLOT_FULL) && (slot->attr.id == k)]} -The union of this set and the set of persistent keys not currently loaded into slots is our abstraction function for the key store, any key not in this union does not currently exist (even if the key is in a slot which has a `PSA_SLOT_FILLING` or `PSA_SLOT_PENDING_DELETION` state). Attempting to start using any key which is not a member of the union will result in a `PSA_ERROR_INVALID_HANDLE` error code. +The union of this set and the set of persistent keys not currently loaded into slots is our abstraction function for the key store, any key not in this union does not currently exist as far as the code is concerned (even if the key is in a slot which has a `PSA_SLOT_FILLING` or `PSA_SLOT_PENDING_DELETION` state). Attempting to start using any key which is not a member of the union will result in a `PSA_ERROR_INVALID_HANDLE` error code. ##### Locking and unlocking the mutex @@ -211,35 +216,35 @@ If `psa_reserve_free_key_slot` cannot find a suitable slot, the key cannot be lo One-shot operations follow a standard pattern when using an existing key: -* They call some `psa_get_and_lock_key_slot_X` function, which finds the key and registers the thread as a reader. -* They operate on the key slot, usually copying the key into a separate buffer to be used by the operation. This step is not done under the mutex. +* They call one of the `psa_get_and_lock_key_slot_X` functions, which then finds the key and registers the thread as a reader. +* They operate on the key slot, usually copying the key into a separate buffer to be used by the operation. This step is not performed under the key slot mutex. * Once finished, they call `psa_unregister_read_under_mutex`. -Multi-part and restartable operations each have a "setup" function where the key is inputted. This function follows the above pattern. The key is copied into the `operation` object, and the thread unregisters. They do not access the key slots again. The copy of the key will not be destroyed during a call to `psa_destroy_key`, the thread running the operation is responsible for deleting this copy in the clean-up. This may need to change to enforce the long term key requirements ([Long term key destruction requirements](#long-term-key-destruction-requirements)). +Multi-part and restartable operations each have a "setup" function where the key is passed in, these functions follow the above pattern. The key is copied into the `operation` object, and the thread unregisters from reading the key (the operations do not access the key slots again). The copy of the key will not be destroyed during a call to `psa_destroy_key`, the thread running the operation is responsible for deleting its copy in the clean-up. This may need to change to enforce the long term key requirements ([Long term key destruction requirements](#long-term-key-destruction-requirements)). ##### Key destruction implementation The locking strategy here is explained in `library/psa_crypto.c`. The destroying thread (the thread calling `psa_destroy_key`) does not always wipe the key slot. The destroying thread registers to read the key, sets the slot's state to `PSA_SLOT_PENDING_DELETION`, wipes the slot from memory if the key is persistent, and then unregisters from reading the slot. -`psa_unregister_read` internally calls `psa_wipe_key_slot` iff the slot's state is `PSA_SLOT_PENDING_DELETION` and the slot's registered reader counter is equal to 1. This implements a "last one out closes the door" approach, where the final thread to unregister from reading a destroyed key will automatically wipe the contents of the slot; this ensure that there is no corruption. +`psa_unregister_read` internally calls `psa_wipe_key_slot` if and only if the slot's state is `PSA_SLOT_PENDING_DELETION` and the slot's registered reader counter is equal to 1. This implements a "last one out closes the door" approach. The final thread to unregister from reading a destroyed key will automatically wipe the contents of the slot; no readers remain to reference the slot post deletion, so there cannot be corruption. -### Linearisability of the system +### linearizability of the system -To satisfy the requirements in [Correctness out of the box](#correctness-out-of-the-box), we require our functions to be "linearisable" (under certain constraints). This means that any (constraint satisfying) set of concurrent calls are performed as if they were executed in some sequential order. +To satisfy the requirements in [Correctness out of the box](#correctness-out-of-the-box), we require our functions to be "linearizable" (under certain constraints). This means that any (constraint satisfying) set of concurrent calls are performed as if they were executed in some sequential order. The standard way of reasoning that this is the case is to identify a "linearization point" for each call, this is a single execution step where the function takes effect (this is usually a step in which the effects of the call become visible to other threads). If every call has a linearization point, the set of calls is equivalent to sequentially performing the calls in order of when their linearization point occurred. -We only require linearisability to hold in the case where a resource-management error is not returned. In a set of concurrent calls, it is permitted for a call c to fail with a `PSA_ERROR_INSUFFICIENT_MEMORY` return code even if there does not exist a sequential ordering of the calls in which c returns this error. Even if such an error occurs, all calls are still required to be functionally correct. +We only require linearizability to hold in the case where a resource-management error is not returned. In a set of concurrent calls, it is permitted for a call c to fail with a `PSA_ERROR_INSUFFICIENT_MEMORY` return code even if there does not exist a sequential ordering of the calls in which c returns this error. Even if such an error occurs, all calls are still required to be functionally correct. -To help justify that our system is linearisable, here are the linearization points/planned linearization points of each PSA call : +To help justify that our system is linearizable, here are the linearization points/planned linearization points of each PSA call : * Key creation functions (including `psa_copy_key`) - The linearization point for a successful call is the mutex unlock within `psa_finish_key_creation`; it is at this point that the key becomes visible to other threads. The linearization point for a failed call is the closest mutex unlock after the failure is first identified. * `psa_destroy_key` - The linearization point for a successful destruction is the mutex unlock, the slot is now in the state `PSA_SLOT_PENDING_DELETION` meaning that the key has been destroyed. For failures, the linearization point is the same. * `psa_purge_key`, `psa_close_key` - The linearization point is the mutex unlock after wiping the slot for a success, or unregistering for a failure. -* One shot operations - The linearization point is the final unlock of the mutex within `psa_get_and_lock_key_slot`, as that is the point in which it is decided whether the key exists. +* One shot operations - The linearization point is the final unlock of the mutex within `psa_get_and_lock_key_slot`, as that is the point in which it is decided whether or not the key exists. * Multi-part operations - The linearization point of the key input function is the final unlock of the mutex within `psa_get_and_lock_key_slot`. All other steps have no non resource-related side effects (except for key derivation, covered in the key creation functions). -Please note that one shot operations and multi-part operations are not yet considered thread-safe, as we do not test whether they rely on unprotected global resources. +Please note that one shot operations and multi-part operations are not yet considered thread-safe, as we have not yet tested whether they rely on unprotected global resources. The key slot access in these operations is thread-safe. ## Testing and analysis @@ -247,19 +252,19 @@ Please note that one shot operations and multi-part operations are not yet consi It is now possible for individual tests to spin up multiple threads. This work has made the global variables used in tests thread-safe. If multiple threads fail a test assert, the first failure will be reported with correct line numbers. -The `step` feature used in some tests is not thread-safe, it cannot be made thread-safe unless we introduce thread-local variables. +Although the `step` feature used in some tests is thread-safe, it may produce unexpected results for multi-threaded tests. `mbedtls_test_set_step` or `mbedtls_test_increment_step` calls within threads can happen in any order, thus may not produce the desired result when precise ordering is required. ### Current state of testing -Our testing is a work in progress. It is not feasible to run our traditional, single-threaded, tests in such a way that tests concurrency. Therefore, we must write a new suite of testing. +Our testing is a work in progress. It is not feasible to run our traditional, single-threaded, tests in such a way that tests concurrency. We need to write new test suites for concurrency testing. -Our tests currently only run on pthread. +Our tests currently only run on pthread, we hope to expand this in the future (our API already allows this). -We run tests using [ThreadSanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html) to detect data races. We test the key store, and test that our key slot state system is enforced. +We run tests using [ThreadSanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html) to detect data races. We test the key store, and test that our key slot state system is enforced. We also test the thread-safety of `psa_crypto_init`. -Currently, not every API call is tested, we also cannot feasibly test every combination of concurrent API calls. API calls can in general be split into a few categories, each category calling the same internal functions in the same order - it is the internal functions that are in charge of locking mutexes and interacting with the key store; we have tests which cover every category. +Currently, not every API call is tested, we also cannot feasibly test every combination of concurrent API calls. API calls can in general be split into a few categories, each category calling the same internal key management functions in the same order - it is the internal functions that are in charge of locking mutexes and interacting with the key store; we test the thread-safety of these functions. -Since we do not run every cryptographic operation concurrently, we do not test that operations are free of unexpected global variables, cryptographic operations are not considered thread-safe. +Since we do not run every cryptographic operation concurrently, we do not test that operations are free of unexpected global variables. ### Expanding testing @@ -268,7 +273,8 @@ Through future work on testing, it would be good to: * For every API call, have a test which runs multiple copies of the call simultaneously. * After implementing other threading platforms, expand the tests to these platforms. * Have increased testing for kicking persistent keys out of slots. -* Explicitly test that there all global variables are protected, for this we need to cover every operation in a concurrent scenario while running ThreadSanitizer. +* Explicitly test that all global variables are protected, for this we would need to cover every operation in a concurrent scenario while running ThreadSanitizer. +* Run tests on more threading implementations, once these implementations are supported. ### Performance @@ -285,7 +291,9 @@ As explained previously, we eventually aim to make the entirety of the PSA API t ### Long term performance requirements -Our plan for cryptographic operations is that they are not performed under any global mutex. One-shot operations and multi-part operations will each only hold the global mutex for finding the relevant key in the key slot, and unregistering as a reader after the operation. +Our plan for cryptographic operations is that they are not performed under any global mutex. One-shot operations and multi-part operations will each only hold the global mutex for finding the relevant key in the key slot, and unregistering as a reader after the operation, using their own operation-specific mutexes to guard any shared data that they use. + +We aim to eventually replace some/all of the mutexes with RWLocks, if possible. ### Long term key destruction requirements From 7d8fd3fafe3d32de6760a7421ecde0fdc1761e78 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Fri, 15 Mar 2024 17:50:45 +0000 Subject: [PATCH 198/211] Add changelog entry for threading MVP Signed-off-by: Paul Elliott --- ChangeLog.d/add_threading_changelog.txt | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ChangeLog.d/add_threading_changelog.txt diff --git a/ChangeLog.d/add_threading_changelog.txt b/ChangeLog.d/add_threading_changelog.txt new file mode 100644 index 0000000000..b6c79f03f9 --- /dev/null +++ b/ChangeLog.d/add_threading_changelog.txt @@ -0,0 +1,6 @@ +Features + * Add protection for multithreaded access to the PSA keystore and protection + for multithreaded access to the the PSA global state, including + concurrently calling psa_crypto_init() when MBEDTLS_THREADING_C and + MBEDTLS_THREADING_PTHREAD are defined. See + docs/architecture/psa-thread-safety/psa-thread-safety.md for more details. From 765b75f2f8622a7f33021d3696d31104e4387333 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Mon, 18 Mar 2024 10:20:43 +0000 Subject: [PATCH 199/211] Update docs/architecture/psa-thread-safety/psa-thread-safety.md Co-authored-by: Paul Elliott <62069445+paul-elliott-arm@users.noreply.github.com> Signed-off-by: Ryan Everett --- docs/architecture/psa-thread-safety/psa-thread-safety.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/architecture/psa-thread-safety/psa-thread-safety.md b/docs/architecture/psa-thread-safety/psa-thread-safety.md index d33e0a6c47..edb94c56ba 100644 --- a/docs/architecture/psa-thread-safety/psa-thread-safety.md +++ b/docs/architecture/psa-thread-safety/psa-thread-safety.md @@ -147,6 +147,8 @@ There are two `psa_global_data_t` structs, each with a single instance `global_d A deadlock would occur if a thread attempts to lock a mutex while already holding it. Functions which need to be called while holding the global mutex have documentation to say this. +To avoid performance degradation, functions must hold mutexes for as short a time as possible. In particular, they must not start expensive operations (eg. doing cryptography) while holding the mutex. + #### Key slots From 2a9eb221073b2c1a93049d1edc52899f7ef7abbb Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 18 Mar 2024 11:15:06 +0000 Subject: [PATCH 200/211] Check file content to see if it looks auto-generated Signed-off-by: Dave Rodgman --- scripts/code_style.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/code_style.py b/scripts/code_style.py index 08ec4af423..71e3edf035 100755 --- a/scripts/code_style.py +++ b/scripts/code_style.py @@ -51,6 +51,12 @@ def list_generated_files() -> FrozenSet[str]: checks = re.findall(CHECK_CALL_RE, content) return frozenset(word for s in checks for word in s.split()) +# Check for comment string indicating an auto-generated file +AUTOGEN_RE = re.compile(r"Warning[ :-]+This file is (now )?auto[ -]generated", re.ASCII | re.IGNORECASE) +def is_file_autogenerated(filename): + content = open(filename, encoding="utf-8").read() + return AUTOGEN_RE.search(content) is not None + def get_src_files(since: Optional[str]) -> List[str]: """ Use git to get a list of the source files. @@ -85,7 +91,8 @@ def get_src_files(since: Optional[str]) -> List[str]: # generated files (we're correcting the templates instead). src_files = [filename for filename in src_files if not (filename.startswith("3rdparty/") or - filename in generated_files)] + filename in generated_files or + is_file_autogenerated(filename))] return src_files def get_uncrustify_version() -> str: From 4e4540d8e08fe83f4b9f8c06d981ece769a617e3 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 18 Mar 2024 11:55:39 +0000 Subject: [PATCH 201/211] line length fix Signed-off-by: Dave Rodgman --- scripts/code_style.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/code_style.py b/scripts/code_style.py index 71e3edf035..b12198d38f 100755 --- a/scripts/code_style.py +++ b/scripts/code_style.py @@ -52,7 +52,8 @@ def list_generated_files() -> FrozenSet[str]: return frozenset(word for s in checks for word in s.split()) # Check for comment string indicating an auto-generated file -AUTOGEN_RE = re.compile(r"Warning[ :-]+This file is (now )?auto[ -]generated", re.ASCII | re.IGNORECASE) +AUTOGEN_RE = re.compile(r"Warning[ :-]+This file is (now )?auto[ -]generated", + re.ASCII | re.IGNORECASE) def is_file_autogenerated(filename): content = open(filename, encoding="utf-8").read() return AUTOGEN_RE.search(content) is not None From 27eb68d29588937741ed89fd4f395a37c20b2ac6 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 15 Mar 2024 16:13:37 +0100 Subject: [PATCH 202/211] Enable TLS 1.3 by default Signed-off-by: Ronald Cron --- ChangeLog.d/enable-tls13-by-default.txt | 2 ++ include/mbedtls/mbedtls_config.h | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 ChangeLog.d/enable-tls13-by-default.txt diff --git a/ChangeLog.d/enable-tls13-by-default.txt b/ChangeLog.d/enable-tls13-by-default.txt new file mode 100644 index 0000000000..636078c7c1 --- /dev/null +++ b/ChangeLog.d/enable-tls13-by-default.txt @@ -0,0 +1,2 @@ +Changes + * The TLS 1.3 protocol is now enabled in the default configuration. diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h index cf6d406cb3..b9790b9c19 100644 --- a/include/mbedtls/mbedtls_config.h +++ b/include/mbedtls/mbedtls_config.h @@ -1774,7 +1774,7 @@ * * Uncomment this macro to enable the support for TLS 1.3. */ -//#define MBEDTLS_SSL_PROTO_TLS1_3 +#define MBEDTLS_SSL_PROTO_TLS1_3 /** * \def MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE @@ -1796,7 +1796,7 @@ * effect on the build. * */ -//#define MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +#define MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE /** * \def MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED From a3f385d1a8a0b30d3e4b3516e4f65d7aa9053076 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 18 Mar 2024 10:25:37 +0100 Subject: [PATCH 203/211] all.sh: Disable TLS 1.3 when pre-requisites are not meet Signed-off-by: Ronald Cron --- tests/scripts/all.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index acfcf5cb3b..bf248c8c8e 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -1305,6 +1305,7 @@ component_test_default_psa_crypto_client_without_crypto_provider () { scripts/config.py unset MBEDTLS_PSA_CRYPTO_C scripts/config.py unset MBEDTLS_PSA_CRYPTO_STORAGE_C scripts/config.py unset MBEDTLS_PSA_ITS_FILE_C + scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3 scripts/config.py set MBEDTLS_PSA_CRYPTO_CLIENT scripts/config.py unset MBEDTLS_LMS_C @@ -1843,6 +1844,8 @@ component_test_tls1_2_default_stream_cipher_only () { scripts/config.py unset MBEDTLS_GCM_C scripts/config.py unset MBEDTLS_CCM_C scripts/config.py unset MBEDTLS_CHACHAPOLY_C + #Disable TLS 1.3 (as no AEAD) + scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3 # Disable CBC-legacy (controlled by MBEDTLS_CIPHER_MODE_CBC plus at least one block cipher (AES, ARIA, Camellia, DES)) scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC # Disable CBC-EtM (controlled by the same as CBC-legacy plus MBEDTLS_SSL_ENCRYPT_THEN_MAC) @@ -1869,6 +1872,8 @@ component_test_tls1_2_default_stream_cipher_only_use_psa () { scripts/config.py unset MBEDTLS_GCM_C scripts/config.py unset MBEDTLS_CCM_C scripts/config.py unset MBEDTLS_CHACHAPOLY_C + #Disable TLS 1.3 (as no AEAD) + scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3 # Disable CBC-legacy (controlled by MBEDTLS_CIPHER_MODE_CBC plus at least one block cipher (AES, ARIA, Camellia, DES)) scripts/config.py unset MBEDTLS_CIPHER_MODE_CBC # Disable CBC-EtM (controlled by the same as CBC-legacy plus MBEDTLS_SSL_ENCRYPT_THEN_MAC) @@ -1894,6 +1899,8 @@ component_test_tls1_2_default_cbc_legacy_cipher_only () { scripts/config.py unset MBEDTLS_GCM_C scripts/config.py unset MBEDTLS_CCM_C scripts/config.py unset MBEDTLS_CHACHAPOLY_C + #Disable TLS 1.3 (as no AEAD) + scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3 # Enable CBC-legacy (controlled by MBEDTLS_CIPHER_MODE_CBC plus at least one block cipher (AES, ARIA, Camellia, DES)) scripts/config.py set MBEDTLS_CIPHER_MODE_CBC # Disable CBC-EtM (controlled by the same as CBC-legacy plus MBEDTLS_SSL_ENCRYPT_THEN_MAC) @@ -1921,6 +1928,8 @@ component_test_tls1_2_deafult_cbc_legacy_cipher_only_use_psa () { scripts/config.py unset MBEDTLS_GCM_C scripts/config.py unset MBEDTLS_CCM_C scripts/config.py unset MBEDTLS_CHACHAPOLY_C + #Disable TLS 1.3 (as no AEAD) + scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3 # Enable CBC-legacy (controlled by MBEDTLS_CIPHER_MODE_CBC plus at least one block cipher (AES, ARIA, Camellia, DES)) scripts/config.py set MBEDTLS_CIPHER_MODE_CBC # Disable CBC-EtM (controlled by the same as CBC-legacy plus MBEDTLS_SSL_ENCRYPT_THEN_MAC) @@ -1947,6 +1956,8 @@ component_test_tls1_2_default_cbc_legacy_cbc_etm_cipher_only () { scripts/config.py unset MBEDTLS_GCM_C scripts/config.py unset MBEDTLS_CCM_C scripts/config.py unset MBEDTLS_CHACHAPOLY_C + #Disable TLS 1.3 (as no AEAD) + scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3 # Enable CBC-legacy (controlled by MBEDTLS_CIPHER_MODE_CBC plus at least one block cipher (AES, ARIA, Camellia, DES)) scripts/config.py set MBEDTLS_CIPHER_MODE_CBC # Enable CBC-EtM (controlled by the same as CBC-legacy plus MBEDTLS_SSL_ENCRYPT_THEN_MAC) @@ -1974,6 +1985,8 @@ component_test_tls1_2_default_cbc_legacy_cbc_etm_cipher_only_use_psa () { scripts/config.py unset MBEDTLS_GCM_C scripts/config.py unset MBEDTLS_CCM_C scripts/config.py unset MBEDTLS_CHACHAPOLY_C + #Disable TLS 1.3 (as no AEAD) + scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3 # Enable CBC-legacy (controlled by MBEDTLS_CIPHER_MODE_CBC plus at least one block cipher (AES, ARIA, Camellia, DES)) scripts/config.py set MBEDTLS_CIPHER_MODE_CBC # Enable CBC-EtM (controlled by the same as CBC-legacy plus MBEDTLS_SSL_ENCRYPT_THEN_MAC) @@ -4645,6 +4658,7 @@ component_test_no_max_fragment_length () { component_test_asan_remove_peer_certificate () { msg "build: default config with MBEDTLS_SSL_KEEP_PEER_CERTIFICATE disabled (ASan build)" scripts/config.py unset MBEDTLS_SSL_KEEP_PEER_CERTIFICATE + scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3 CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan . make From 46ac0658cf155a3fb1eda983790093ad4e4cc205 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 18 Mar 2024 12:39:04 +0100 Subject: [PATCH 204/211] all.sh: Adapt/Fix some components Signed-off-by: Ronald Cron --- tests/scripts/all.sh | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index bf248c8c8e..f0bf7f6119 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -2622,7 +2622,6 @@ component_test_psa_crypto_config_accel_ecdsa () { # Start from default config (no USE_PSA) + TLS 1.3 helper_libtestdriver1_adjust_config "default" - scripts/config.py set MBEDTLS_SSL_PROTO_TLS1_3 # Disable the module that's accelerated scripts/config.py unset MBEDTLS_ECDSA_C @@ -2663,7 +2662,7 @@ component_test_psa_crypto_config_accel_ecdh () { # Configure # --------- - # Start from default config (no TLS 1.3, no USE_PSA) + # Start from default config (no USE_PSA) helper_libtestdriver1_adjust_config "default" # Disable the module that's accelerated @@ -3656,7 +3655,7 @@ component_test_psa_crypto_config_accel_hash () { # Configure # --------- - # Start from default config (no TLS 1.3, no USE_PSA) + # Start from default config (no USE_PSA) helper_libtestdriver1_adjust_config "default" # Disable the things that are being accelerated @@ -3700,7 +3699,7 @@ component_test_psa_crypto_config_accel_hash_keep_builtins () { ALG_SHA_224 ALG_SHA_256 ALG_SHA_384 ALG_SHA_512 \ ALG_SHA3_224 ALG_SHA3_256 ALG_SHA3_384 ALG_SHA3_512" - # Start from default config (no TLS 1.3, no USE_PSA) + # Start from default config (no USE_PSA) helper_libtestdriver1_adjust_config "default" helper_libtestdriver1_make_drivers "$loc_accel_list" @@ -4195,7 +4194,6 @@ component_build_psa_accel_alg_hkdf() { msg "build: full - MBEDTLS_USE_PSA_CRYPTO + PSA_WANT_ALG_HKDF without MBEDTLS_HKDF_C" scripts/config.py full scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO - scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3 scripts/config.py unset MBEDTLS_HKDF_C # Make sure to unset TLS1_3 since it requires HKDF_C and will not build properly without it. scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3 @@ -5875,7 +5873,7 @@ support_build_armcc () { } component_test_tls13_only () { - msg "build: default config with MBEDTLS_SSL_PROTO_TLS1_3, without MBEDTLS_SSL_PROTO_TLS1_2" + msg "build: default config without MBEDTLS_SSL_PROTO_TLS1_2" scripts/config.py set MBEDTLS_SSL_EARLY_DATA scripts/config.py set MBEDTLS_SSL_RECORD_SIZE_LIMIT make CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/tls13-only.h\"'" @@ -6012,29 +6010,25 @@ component_test_tls13_only_ephemeral_all () { tests/ssl-opt.sh } -component_test_tls13 () { - msg "build: default config with MBEDTLS_SSL_PROTO_TLS1_3 enabled, without padding" - scripts/config.py set MBEDTLS_SSL_PROTO_TLS1_3 - scripts/config.py set MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +component_test_tls13_no_padding () { + msg "build: default config plus early data minus padding" scripts/config.py set MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY 1 scripts/config.py set MBEDTLS_SSL_EARLY_DATA CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan . make - msg "test: default config with MBEDTLS_SSL_PROTO_TLS1_3 enabled, without padding" + msg "test: default config plus early data minus padding" make test - msg "ssl-opt.sh (TLS 1.3)" + msg "ssl-opt.sh (TLS 1.3 no padding)" tests/ssl-opt.sh } component_test_tls13_no_compatibility_mode () { - msg "build: default config with MBEDTLS_SSL_PROTO_TLS1_3 enabled, without padding" - scripts/config.py set MBEDTLS_SSL_PROTO_TLS1_3 + msg "build: default config plus early data minus middlebox compatibility mode" scripts/config.py unset MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE - scripts/config.py set MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY 1 scripts/config.py set MBEDTLS_SSL_EARLY_DATA CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan . make - msg "test: default config with MBEDTLS_SSL_PROTO_TLS1_3 enabled, without padding" + msg "test: default config plus early data minus middlebox compatibility mode" make test msg "ssl-opt.sh (TLS 1.3 no compatibility mode)" tests/ssl-opt.sh From d2cb7f42688643fd7439c4a733168dccb6fe6e58 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 18 Mar 2024 12:49:18 +0100 Subject: [PATCH 205/211] all.sh: Add TLS 1.2 only component Signed-off-by: Ronald Cron --- tests/scripts/all.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index f0bf7f6119..e17d5ac9b9 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -5872,6 +5872,22 @@ support_build_armcc () { (check_tools "$armc5_cc" "$armc6_cc" > /dev/null 2>&1) } +component_test_tls12_only () { + msg "build: default config without MBEDTLS_SSL_PROTO_TLS1_3, cmake, gcc, ASan" + scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3 + CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . + make + + msg "test: main suites (inc. selftests) (ASan build)" + make test + + msg "test: ssl-opt.sh (ASan build)" + tests/ssl-opt.sh + + msg "test: compat.sh (ASan build)" + tests/compat.sh +} + component_test_tls13_only () { msg "build: default config without MBEDTLS_SSL_PROTO_TLS1_2" scripts/config.py set MBEDTLS_SSL_EARLY_DATA From 1bd787a3e009edab2f426815eb96a85f424b06dd Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 18 Mar 2024 12:32:49 +0000 Subject: [PATCH 206/211] Minor relaxation to auto-gen regex Signed-off-by: Dave Rodgman --- scripts/code_style.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/code_style.py b/scripts/code_style.py index b12198d38f..07952b6cb5 100755 --- a/scripts/code_style.py +++ b/scripts/code_style.py @@ -52,7 +52,7 @@ def list_generated_files() -> FrozenSet[str]: return frozenset(word for s in checks for word in s.split()) # Check for comment string indicating an auto-generated file -AUTOGEN_RE = re.compile(r"Warning[ :-]+This file is (now )?auto[ -]generated", +AUTOGEN_RE = re.compile(r"Warning[ :-]+This file is (now )?auto[ -]?generated", re.ASCII | re.IGNORECASE) def is_file_autogenerated(filename): content = open(filename, encoding="utf-8").read() From f5f48549e2e0cca7ce64ba86325f34c1375482ff Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Mon, 18 Mar 2024 13:39:50 +0000 Subject: [PATCH 207/211] Add issues fixed to changelog entry Signed-off-by: Paul Elliott --- ChangeLog.d/add_threading_changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog.d/add_threading_changelog.txt b/ChangeLog.d/add_threading_changelog.txt index b6c79f03f9..e9f6cc7ed7 100644 --- a/ChangeLog.d/add_threading_changelog.txt +++ b/ChangeLog.d/add_threading_changelog.txt @@ -4,3 +4,4 @@ Features concurrently calling psa_crypto_init() when MBEDTLS_THREADING_C and MBEDTLS_THREADING_PTHREAD are defined. See docs/architecture/psa-thread-safety/psa-thread-safety.md for more details. + Resolves issues #3263 and #7945. From d59caf4e515b5ba52f42146f60d2ddf8020e3aea Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 18 Mar 2024 16:20:14 +0100 Subject: [PATCH 208/211] test_suite_pk: extend pk_psa_wrap_sign_ext() Try to perform verify_ext() using the opaque context when the key type is MBEDTLS_PK_RSASSA_PSS. This currently leads to a crash while running the test suite and this will be fixed by the next commit. Signed-off-by: Valerio Setti --- tests/suites/test_suite_pk.function | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 089202bb4d..ce590de524 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -2060,6 +2060,18 @@ void pk_psa_wrap_sign_ext(int pk_type, int key_bits, int key_pk_type, int md_alg sig, sizeof(sig), &sig_len, mbedtls_test_rnd_std_rand, NULL), 0); + /* Trying to perform a verify_ext() using the opaque context is not supported + * so here we verify that this does not crash. */ + if (key_pk_type == MBEDTLS_PK_RSASSA_PSS) { + mbedtls_pk_rsassa_pss_options pss_opts = { + .mgf1_hash_id = md_alg, + .expected_salt_len = MBEDTLS_RSA_SALT_LEN_ANY, + }; + TEST_EQUAL(mbedtls_pk_verify_ext(key_pk_type, &pss_opts, &pk, md_alg, + hash, hash_len, sig, sig_len), + MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE); + } + mbedtls_pk_free(&pk); TEST_EQUAL(PSA_SUCCESS, psa_destroy_key(key_id)); From 07500fd874fd8688d008e28d349a948a5dd00835 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 18 Mar 2024 16:22:33 +0100 Subject: [PATCH 209/211] pk: check PK context type in mbedtls_pk_verify_ext() before trying RSA PSS Signed-off-by: Valerio Setti --- library/pk.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/library/pk.c b/library/pk.c index ec3741b13b..097777f2c0 100644 --- a/library/pk.c +++ b/library/pk.c @@ -1126,6 +1126,12 @@ int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options, return mbedtls_pk_verify(ctx, md_alg, hash, hash_len, sig, sig_len); } + /* Ensure the PK context is of the right type otherwise mbedtls_pk_rsa() + * below would return a NULL pointer. */ + if (mbedtls_pk_get_type(ctx) != MBEDTLS_PK_RSA) { + return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; + } + #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; const mbedtls_pk_rsassa_pss_options *pss_opts; From 8ad5be0e5d8b15626f6cbe43ecbb3b7af79b96fa Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 18 Mar 2024 17:22:52 +0100 Subject: [PATCH 210/211] add changelog Signed-off-by: Valerio Setti --- ChangeLog.d/fix-null-dereference-verify-ext.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 ChangeLog.d/fix-null-dereference-verify-ext.txt diff --git a/ChangeLog.d/fix-null-dereference-verify-ext.txt b/ChangeLog.d/fix-null-dereference-verify-ext.txt new file mode 100644 index 0000000000..4654178726 --- /dev/null +++ b/ChangeLog.d/fix-null-dereference-verify-ext.txt @@ -0,0 +1,3 @@ +Bugfix + * Fix NULL pointer dereference in mbedtls_pk_verify_ext() when called using + an opaque RSA context and specifying MBEDTLS_PK_RSASSA_PSS as key type. From da47518554b5e56e3c5d08fdad304fb282baaba4 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 19 Mar 2024 09:54:46 +0100 Subject: [PATCH 211/211] test_suite_pk: always test verify_ext with opaque keys in pk_psa_wrap_sign_ext() Signed-off-by: Valerio Setti --- tests/suites/test_suite_pk.function | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index ce590de524..808abcff39 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -2060,8 +2060,7 @@ void pk_psa_wrap_sign_ext(int pk_type, int key_bits, int key_pk_type, int md_alg sig, sizeof(sig), &sig_len, mbedtls_test_rnd_std_rand, NULL), 0); - /* Trying to perform a verify_ext() using the opaque context is not supported - * so here we verify that this does not crash. */ + /* verify_ext() is not supported when using an opaque context. */ if (key_pk_type == MBEDTLS_PK_RSASSA_PSS) { mbedtls_pk_rsassa_pss_options pss_opts = { .mgf1_hash_id = md_alg, @@ -2070,6 +2069,10 @@ void pk_psa_wrap_sign_ext(int pk_type, int key_bits, int key_pk_type, int md_alg TEST_EQUAL(mbedtls_pk_verify_ext(key_pk_type, &pss_opts, &pk, md_alg, hash, hash_len, sig, sig_len), MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE); + } else { + TEST_EQUAL(mbedtls_pk_verify_ext(key_pk_type, NULL, &pk, md_alg, + hash, hash_len, sig, sig_len), + MBEDTLS_ERR_PK_TYPE_MISMATCH); } mbedtls_pk_free(&pk);