From 1b93588d93e9161b1c085441372828b8e8078055 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 27 Oct 2025 11:12:07 +0100 Subject: [PATCH 1/8] psa_crypto_slot_management: check key ID range when loading a persistent key Do not try to load a persistent key whose key ID is in the volatile range. Signed-off-by: Valerio Setti --- library/psa_crypto_slot_management.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index f1a651f0d9..d514d1af04 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -684,6 +684,12 @@ static psa_status_t psa_load_persistent_key_into_slot(psa_key_slot_t *slot) psa_status_t status = PSA_SUCCESS; uint8_t *key_data = NULL; size_t key_data_length = 0; + psa_key_id_t key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(slot->attr.id); + + /* Do not try to load a persistent key whose ID is in the volatile range. */ + if ((key_id >= PSA_KEY_ID_VOLATILE_MIN) && (key_id <= PSA_KEY_ID_VOLATILE_MAX)) { + return PSA_ERROR_DOES_NOT_EXIST; + } status = psa_load_persistent_key(&slot->attr, &key_data, &key_data_length); From 2a9a272bdb233b366705a2a83c89ac3ee9305333 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 27 Oct 2025 11:16:36 +0100 Subject: [PATCH 2/8] changelog: prevent loading peristent keys if the key ID is in the volatile range Signed-off-by: Valerio Setti --- ChangeLog.d/issue488.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 ChangeLog.d/issue488.txt diff --git a/ChangeLog.d/issue488.txt b/ChangeLog.d/issue488.txt new file mode 100644 index 0000000000..77cbe2d5e3 --- /dev/null +++ b/ChangeLog.d/issue488.txt @@ -0,0 +1,3 @@ +Bugfix + * Prevent loading of peristent keys whose key ID belong to the volatile + range. From 3e5d0c12025f965952af4c002e267ce7b33258c5 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 23 Oct 2025 12:29:48 +0200 Subject: [PATCH 3/8] Test key identifier ranges Add some assertions on the various ranges of key identifiers to ensure that they're disjoint and they comply with documented guarantees. Signed-off-by: Gilles Peskine --- .../test_suite_psa_crypto_persistent_key.data | 3 ++ ...t_suite_psa_crypto_persistent_key.function | 36 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.data b/tests/suites/test_suite_psa_crypto_persistent_key.data index 133e726aec..7f4f27df90 100644 --- a/tests/suites/test_suite_psa_crypto_persistent_key.data +++ b/tests/suites/test_suite_psa_crypto_persistent_key.data @@ -33,6 +33,9 @@ parse_storage_data_check:"505341004b45590000000000010000000170000001000000000000 Parse storage: truncated key parse_storage_data_check:"505341004b455900000000000100000001700000010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b":"":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_DATA_INVALID +Key identifier ranges +key_id_ranges: + # Not specific to files, but only run this test in an environment where the maximum size could be reached. Save maximum-size persistent raw key depends_on:MBEDTLS_PSA_ITS_FILE_C diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function index ea8cb6bc8f..f767db9fcd 100644 --- a/tests/suites/test_suite_psa_crypto_persistent_key.function +++ b/tests/suites/test_suite_psa_crypto_persistent_key.function @@ -117,6 +117,42 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void key_id_ranges() +{ + /* PSA Crypto API specification */ + TEST_EQUAL(PSA_KEY_ID_NULL, 0x00000000); + TEST_EQUAL(PSA_KEY_ID_USER_MIN, 0x00000001); + TEST_EQUAL(PSA_KEY_ID_USER_MAX, 0x3fffffff); + TEST_EQUAL(PSA_KEY_ID_VENDOR_MIN, 0x40000000); + TEST_EQUAL(PSA_KEY_ID_VENDOR_MAX, 0x7fffffff); + + /* Volatile key IDs */ + TEST_LE_U(PSA_KEY_ID_VENDOR_MIN, PSA_KEY_ID_VOLATILE_MIN); + TEST_LE_U(PSA_KEY_ID_VOLATILE_MAX, PSA_KEY_ID_VENDOR_MAX); + TEST_LE_U(PSA_KEY_ID_VOLATILE_MIN, PSA_KEY_ID_VOLATILE_MAX); + + /* Built-in key IDs */ + /* Mbed TLS 2.27 reserved 0x7fff0000..0x7fffefff for built-in keys. + * Integrators may have hard-coded built-in key IDs in this range, + * so if this range starts conflicting with something else, it's + * an incompatible change. */ +#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) + TEST_LE_U(MBEDTLS_PSA_KEY_ID_BUILTIN_MIN, 0x7fff0000); + TEST_LE_U(MBEDTLS_PSA_KEY_ID_BUILTIN_MAX, 0x7fffefff); + TEST_LE_U(PSA_KEY_ID_VENDOR_MIN, MBEDTLS_PSA_KEY_ID_BUILTIN_MIN); + TEST_LE_U(MBEDTLS_PSA_KEY_ID_BUILTIN_MAX, PSA_KEY_ID_VENDOR_MAX); +#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ + /* To avoid confusion, make sure we avoid the built-in key ID range + * even in builds without built-in keys.. */ + if (PSA_KEY_ID_VOLATILE_MIN <= 0x7fff0000) { + TEST_LE_U(PSA_KEY_ID_VOLATILE_MAX + 1, 0x7fff0000); + } else { + TEST_LE_U(0x7fffefff + 1, PSA_KEY_ID_VOLATILE_MIN); + } +} +/* END_CASE */ + /* BEGIN_CASE */ void save_large_persistent_key(int data_length_arg, int expected_status) { From 32dbf968c807bbcadd099d81ccc1a6144fb14417 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 23 Oct 2025 13:15:50 +0200 Subject: [PATCH 4/8] Test with bad data in storage: key IDs Test what happens when the application tries to access a key and the storage contains something invalid: either a corrupted file, or a key ID that's outside the standard range for persistent keys. Coverage of APIs in this commit: * `psa_get_key_attributes()` (generally as a proxy for any key access); * `psa_export_key()` (minor, but does provide some coverage of what happens if only the key material is corrupted); * `psa_destroy_key()`, which hopefully should work even for a corrupted file. Coverage of key IDs in this commit: * Key IDs in various ranges: user (i.e. the normal range for persistent keys), builtin, volatile, reserved file ID, none of the above. * Includes coverage for nonzero owner ID. No coverage of corrupted files in this commit. Assert the behavior that I think is the right thing. Subsequent commits will reconcile the library behavior with the code as needed. Signed-off-by: Gilles Peskine --- .../test_suite_psa_crypto_persistent_key.data | 147 +++++++++++++++++ ...t_suite_psa_crypto_persistent_key.function | 153 ++++++++++++++++++ 2 files changed, 300 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.data b/tests/suites/test_suite_psa_crypto_persistent_key.data index 7f4f27df90..bead47902b 100644 --- a/tests/suites/test_suite_psa_crypto_persistent_key.data +++ b/tests/suites/test_suite_psa_crypto_persistent_key.data @@ -136,3 +136,150 @@ destroy_nonexistent:1:PSA_ERROR_INVALID_HANDLE Destroy invalid id: 0xffffffff destroy_nonexistent:0xffffffff:PSA_ERROR_INVALID_HANDLE + +Load key: owner=0 id=1, good, 1 byte +load_primed_storage:0:1:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS + +Load key: owner=0 id=2, good +load_primed_storage:0:2:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS + +Load key: owner=0 id=PSA_KEY_USER_MIN, good +load_primed_storage:0:PSA_KEY_ID_USER_MIN:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS + +Load key: owner=0 id=PSA_KEY_USER_MAX, good +load_primed_storage:0:PSA_KEY_ID_USER_MIN:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS + +Load key: owner=0 id=0 (bad id) +load_primed_storage:0:0:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_SUCCESS + +Load key: owner=0 id=PSA_KEY_ID_VOLATILE_MIN (bad id) +load_primed_storage:0:PSA_KEY_ID_VOLATILE_MIN:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=0 id=PSA_KEY_ID_VOLATILE_MAX (bad id) +load_primed_storage:0:PSA_KEY_ID_VOLATILE_MAX:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +# We use the numerical ID in the test data because the numerical range +# of built-in keys is part of the interface contract between the library +# and third-party code that provide built-in keys. We can extend this +# range, but shrinking it would be an incompatible change. +Load key: owner=0 id=MBEDTLS_PSA_KEY_ID_BUILTIN_MIN (bad id) +load_primed_storage:0:0x7fff0000:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=0 id=MBEDTLS_PSA_KEY_ID_BUILTIN_MAX (bad id) +load_primed_storage:0:0x7fffefff:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=0 id=0x7fffffff (bad id: not in any range) +load_primed_storage:0:KEY_ID_OUTSIDE_DEFINED_RANGES:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=0 id=0xffff0000 (bad id: reserved file UID, not in use) +load_primed_storage:0:0xffff0000:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=0 id=entropy file seed +load_primed_storage:0:PSA_CRYPTO_ITS_RANDOM_SEED_UID:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=0 id=0xffffffff (bad id: reserved file UID, not in use) +load_primed_storage:0:0xffffffff:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=42 id=2, good +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:42:2:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS + +Load key: owner=42 id=PSA_KEY_USER_MIN, good +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:42:PSA_KEY_ID_USER_MIN:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS + +Load key: owner=42 id=PSA_KEY_USER_MAX, good +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:42:PSA_KEY_ID_USER_MIN:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS + +Load key: owner=42 id=0 (bad id) +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:42:0:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_SUCCESS + +Load key: owner=42 id=PSA_KEY_ID_VOLATILE_MIN (bad id) +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:42:PSA_KEY_ID_VOLATILE_MIN:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=42 id=PSA_KEY_ID_VOLATILE_MAX (bad id) +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:42:PSA_KEY_ID_VOLATILE_MAX:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +# We use the numerical ID in the test data because the numerical range +# of built-in keys is part of the interface contract between the library +# and third-party code that provide built-in keys. We can extend this +# range, but shrinking it would be an incompatible change. +Load key: owner=42 id=MBEDTLS_PSA_KEY_ID_BUILTIN_MIN (bad id) +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:42:0x7fff0000:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=42 id=MBEDTLS_PSA_KEY_ID_BUILTIN_MAX (bad id) +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:42:0x7fffefff:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=42 id=0x7fffffff (bad id: not in any range) +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:42:KEY_ID_OUTSIDE_DEFINED_RANGES:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=42 id=0xffff0000 (bad id: reserved file UID, not in use) +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:42:0xffff0000:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=42 id=(entropy file seed & 0xffffffff) +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:42:PSA_CRYPTO_ITS_RANDOM_SEED_UID:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=42 id=0xffffffff (bad id: reserved file UID, not in use) +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:42:0xffffffff:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=-0x80000000 id=2, good +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:-0x80000000:2:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS + +Load key: owner=-0x80000000 id=PSA_KEY_USER_MIN, good +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:-0x80000000:PSA_KEY_ID_USER_MIN:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS + +Load key: owner=-0x80000000 id=PSA_KEY_USER_MAX, good +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:-0x80000000:PSA_KEY_ID_USER_MIN:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS + +Load key: owner=-0x80000000 id=0 (bad id) +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:-0x80000000:0:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_SUCCESS + +Load key: owner=-0x80000000 id=PSA_KEY_ID_VOLATILE_MIN (bad id) +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:-0x80000000:PSA_KEY_ID_VOLATILE_MIN:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=-0x80000000 id=PSA_KEY_ID_VOLATILE_MAX (bad id) +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:-0x80000000:PSA_KEY_ID_VOLATILE_MAX:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +# We use the numerical ID in the test data because the numerical range +# of built-in keys is part of the interface contract between the library +# and third-party code that provide built-in keys. We can extend this +# range, but shrinking it would be an incompatible change. +Load key: owner=-0x80000000 id=MBEDTLS_PSA_KEY_ID_BUILTIN_MIN (bad id) +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:-0x80000000:0x7fff0000:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=-0x80000000 id=MBEDTLS_PSA_KEY_ID_BUILTIN_MAX (bad id) +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:-0x80000000:0x7fffefff:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=-0x80000000 id=0x7fffffff (bad id: not in any range) +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:-0x80000000:KEY_ID_OUTSIDE_DEFINED_RANGES:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=-0x80000000 id=0xffff0000 (bad id: reserved file UID, not in use) +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:-0x80000000:0xffff0000:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=-0x80000000 id=(entropy file seed & 0xffffffff) +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:-0x80000000:PSA_CRYPTO_ITS_RANDOM_SEED_UID:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE + +Load key: owner=-0x80000000 id=0xffffffff (bad id: reserved file UID, not in use) +depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +load_primed_storage:-0x80000000:0xffffffff:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function index f767db9fcd..b8321f90e2 100644 --- a/tests/suites/test_suite_psa_crypto_persistent_key.function +++ b/tests/suites/test_suite_psa_crypto_persistent_key.function @@ -14,9 +14,32 @@ #include +#include "mbedtls/ctr_drbg.h" +#include "psa_crypto_its.h" #include "psa_crypto_slot_management.h" #include "psa_crypto_storage.h" +#define KEY_ID_IN_USER_RANGE(id) \ + (PSA_KEY_ID_USER_MIN <= (id) && (id) <= PSA_KEY_ID_USER_MAX) + +#define KEY_ID_IN_VOLATILE_RANGE(id) \ + (PSA_KEY_ID_VOLATILE_MIN <= (id) && (id) <= PSA_KEY_ID_VOLATILE_MAX) + +#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) +#define KEY_ID_IN_BUILTIN_RANGE(id) \ + (MBEDTLS_PSA_KEY_ID_BUILTIN_MIN <= (id) && (id) <= MBEDTLS_PSA_KEY_ID_BUILTIN_MAX) +#else +#define KEY_ID_IN_BUILTIN_RANGE(id) 0 +#endif + +/* Range of file UIDs reserved for uses other than storing a key. + * Defined by the TF-PSA-Crypto storage specification + * docs/architecture/mbed-crypto-storage-specification.md */ +#define KEY_ID_IN_RESERVED_FILE_ID_RANGE(id) (0xffff0000 <= ((id) & 0xffffffff)) + +/* Define a key ID that is in none of the recognized ranges and not 0 */ +#define KEY_ID_OUTSIDE_DEFINED_RANGES 0x7fffffffu + #define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY" #define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH (sizeof(PSA_KEY_STORAGE_MAGIC_HEADER)) @@ -150,6 +173,12 @@ void key_id_ranges() } else { TEST_LE_U(0x7fffefff + 1, PSA_KEY_ID_VOLATILE_MIN); } + + /* Sanity check on test data */ + TEST_ASSERT(!KEY_ID_IN_USER_RANGE(KEY_ID_OUTSIDE_DEFINED_RANGES)); + TEST_ASSERT(!KEY_ID_IN_VOLATILE_RANGE(KEY_ID_OUTSIDE_DEFINED_RANGES)); + TEST_ASSERT(!KEY_ID_IN_BUILTIN_RANGE(KEY_ID_OUTSIDE_DEFINED_RANGES)); + TEST_ASSERT(!KEY_ID_IN_RESERVED_FILE_ID_RANGE(KEY_ID_OUTSIDE_DEFINED_RANGES)); } /* END_CASE */ @@ -374,3 +403,127 @@ exit: PSA_DONE(); } /* END_CASE */ + +/* BEGIN_CASE */ +/* Write content to the file that corresponds to the given key ID, + * then attempt to use a key with this ID. + * Depending on the validity of the key ID and storage content, + * this may or may not work. + */ +void load_primed_storage(int32_t owner_id, + int64_t key_id_arg, /* 0..2^32-1 */ + data_t *content, + int expected_attributes_status_arg, + int expected_export_status_arg, + int expected_destroy_status_arg) +{ + mbedtls_svc_key_id_t key_id = mbedtls_svc_key_id_make(owner_id, key_id_arg); + /* Storage UID (file name) for the given key ID, following the storage + * specification. */ + psa_storage_uid_t uid = (uint64_t) owner_id << 32 | key_id_arg; + psa_status_t expected_attributes_status = expected_attributes_status_arg; + psa_status_t expected_export_status = expected_export_status_arg; + psa_status_t expected_destroy_status = expected_destroy_status_arg; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + uint8_t *key_data = NULL; + struct psa_storage_info_t info; + + /* Sanity checks on the test data */ + /* The test framework doesn't support unsigned types, so check that + * the key ID is in the actual valid range here. */ + TEST_LE_U(0, key_id_arg); + TEST_LE_U(key_id_arg, 0xffffffff); +#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) + TEST_EQUAL(owner_id, 0); +#endif + + PSA_INIT(); + +#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) && \ + defined(MBEDTLS_CTR_DRBG_C) && \ + defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) + /* Skip this test if we happened to pick the volatile key used by the + * PSA RNG, if there is one. */ + if (owner_id == 0 && psa_key_id_is_volatile(key_id)) { + if (psa_get_key_attributes(key_id, &attributes) == PSA_SUCCESS) { + mbedtls_test_skip("Volatile key already in use", + __LINE__, __FILE__); + goto exit; + } + } +#endif + + /* Prime the storage. */ + psa_status_t file_status = psa_its_get_info(uid, &info); + if (uid == 0) { + /* 0 is not a valid file ID, according to the PSA secure storage + * API specification. */ + if (file_status == PSA_ERROR_DOES_NOT_EXIST) { + /* Our own partial storage implementation (psa_its_file.c) + * is not compliant, it returns the wrong error code here. + * That's not a problem, just let it go. */ + } else { + TEST_EQUAL(file_status, PSA_ERROR_INVALID_ARGUMENT); + } + } else if (KEY_ID_IN_RESERVED_FILE_ID_RANGE(key_id_arg) && + file_status == PSA_SUCCESS) { + /* The key ID corresponds to a reserved file (e.g. transaction + * log or entropy seed). Don't corrupt that file. */ + } else { + TEST_EQUAL(file_status, PSA_ERROR_DOES_NOT_EXIST); + TEST_EQUAL(psa_its_set(uid, content->len, content->x, 0), PSA_SUCCESS); + } + + /* Reading attributes should work for any valid key. */ + TEST_EQUAL(psa_get_key_attributes(key_id, &attributes), + expected_attributes_status); + if (expected_attributes_status == PSA_SUCCESS) { + /* It's not our job here to validate the attributes, but do + * sanity-check the attributes related to persistence. */ + TEST_ASSERT(mbedtls_svc_key_id_equal(key_id, + psa_get_key_id(&attributes))); + TEST_EQUAL(psa_get_key_lifetime(&attributes), + PSA_KEY_LIFETIME_PERSISTENT); + } + + /* Exporting should work for a valid key that has export permission. */ + /* Allocate enough memory for the key data (assuming the key + * representation in storage is not compressed compared to the + * export format). */ + size_t key_data_size = content->len; + size_t key_data_length = SIZE_MAX; + TEST_CALLOC(key_data, key_data_size); + TEST_EQUAL(psa_export_key(key_id, + key_data, key_data_size, &key_data_length), + expected_export_status); + if (expected_export_status == PSA_SUCCESS) { + TEST_ASSERT(key_data_length != 0); + } + /* Assert that the data length is sensible even if export failed. + * This reduces the risk of memory corruption if an application + * doesn't check the return status of export(). */ + TEST_LE_U(key_data_length, key_data_size); + + /* Destroying the key should work even for malformed content. + * But it should not work for reserved file IDs. */ + TEST_EQUAL(psa_destroy_key(key_id), expected_destroy_status); + if (uid == 0) { + /* Invalid file UID. No point in asserting anything about the file. */ + } else if (expected_destroy_status == PSA_SUCCESS) { + file_status = psa_its_get_info(uid, &info); + if (key_id_arg == 0) { + /* psa_destroy_key(0) is defined as a no-op, so it should not + * affect the file. */ + TEST_EQUAL(file_status, PSA_SUCCESS); + } else { + TEST_EQUAL(file_status, PSA_ERROR_DOES_NOT_EXIST); + } + } + +exit: + psa_reset_key_attributes(&attributes); + PSA_DONE(); + psa_its_remove(uid); + mbedtls_free(key_data); +} +/* END_CASE */ From e2b0e94592d9b517fbb0e193f591181de50d6594 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 27 Oct 2025 14:27:29 +0100 Subject: [PATCH 5/8] tests: suite_psa_crypto_persistent: fix formatting Signed-off-by: Valerio Setti --- tests/suites/test_suite_psa_crypto_persistent_key.function | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function index b8321f90e2..d8c58fea68 100644 --- a/tests/suites/test_suite_psa_crypto_persistent_key.function +++ b/tests/suites/test_suite_psa_crypto_persistent_key.function @@ -466,7 +466,7 @@ void load_primed_storage(int32_t owner_id, TEST_EQUAL(file_status, PSA_ERROR_INVALID_ARGUMENT); } } else if (KEY_ID_IN_RESERVED_FILE_ID_RANGE(key_id_arg) && - file_status == PSA_SUCCESS) { + file_status == PSA_SUCCESS) { /* The key ID corresponds to a reserved file (e.g. transaction * log or entropy seed). Don't corrupt that file. */ } else { From 0e595793581324133c00365b476343dee9ef5770 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 28 Oct 2025 13:07:49 +0100 Subject: [PATCH 6/8] Test with bad data in storage: support existing built-in or volatile key When testing what happens with when accessing a key ID in the built-in or volatile range and a file exists in storage, we were skipping the test case when the key existed. When the volatile or built-in key exists, the expectations on the test case are wrong, but the test case is still useful: we should ensure that the existence of the file doesn't somehow prevent access to the built-in or volatile key. So, instead of skipping, change the test assertions on the fly to ensure that we are accessing the existing key. Signed-off-by: Gilles Peskine --- ...t_suite_psa_crypto_persistent_key.function | 99 ++++++++++++++----- 1 file changed, 72 insertions(+), 27 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function index d8c58fea68..f0fcd5f7fc 100644 --- a/tests/suites/test_suite_psa_crypto_persistent_key.function +++ b/tests/suites/test_suite_psa_crypto_persistent_key.function @@ -57,6 +57,9 @@ typedef struct { uint8_t key_data[]; } psa_persistent_key_storage_format; +const size_t persistent_key_payload_offset = + offsetof(psa_persistent_key_storage_format, key_data); + /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -439,19 +442,29 @@ void load_primed_storage(int32_t owner_id, PSA_INIT(); -#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) && \ - defined(MBEDTLS_CTR_DRBG_C) && \ - defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO) - /* Skip this test if we happened to pick the volatile key used by the - * PSA RNG, if there is one. */ - if (owner_id == 0 && psa_key_id_is_volatile(key_id)) { - if (psa_get_key_attributes(key_id, &attributes) == PSA_SUCCESS) { - mbedtls_test_skip("Volatile key already in use", - __LINE__, __FILE__); - goto exit; - } + /* This is the start of the test case, so normally, no key exists. + * The test data is based on the assumption that the key doesn't exist. + * However, there are some cases where a key does exist: + * - A volatile key used by the PSA RNG. + * - A built-in key provided by the platform (in our test code: + * mbedtls_psa_platform_get_builtin_key() in platform_builtin_keys.c). + * In such cases, we'll have different expectations. + */ + int key_already_existed = + psa_get_key_attributes(key_id, &attributes) == PSA_SUCCESS; + if (key_already_existed) { + expected_attributes_status = PSA_SUCCESS; + expected_export_status = + (psa_get_key_usage_flags(&attributes) & PSA_KEY_USAGE_EXPORT ? + PSA_SUCCESS : + PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes)) ? + PSA_SUCCESS : + PSA_ERROR_NOT_PERMITTED); } -#endif + /* In case this is a built-in key, psa_get_key_attributes() + * loads it into the cache. Purge the cache to make sure the loading + * code gets triggered. */ + psa_purge_key(key_id); /* Prime the storage. */ psa_status_t file_status = psa_its_get_info(uid, &info); @@ -477,7 +490,7 @@ void load_primed_storage(int32_t owner_id, /* Reading attributes should work for any valid key. */ TEST_EQUAL(psa_get_key_attributes(key_id, &attributes), expected_attributes_status); - if (expected_attributes_status == PSA_SUCCESS) { + if (expected_attributes_status == PSA_SUCCESS && !key_already_existed) { /* It's not our job here to validate the attributes, but do * sanity-check the attributes related to persistence. */ TEST_ASSERT(mbedtls_svc_key_id_equal(key_id, @@ -486,6 +499,19 @@ void load_primed_storage(int32_t owner_id, PSA_KEY_LIFETIME_PERSISTENT); } + /* Extract the key material from the file. + * We assume that the file uses the standard key representation in + * storage, which is always the case at the time of writing. + * If the file is truncated, there is no key material, and we just + * declare an empty buffer here. + */ + const uint8_t *payload = NULL; + size_t payload_length = 0; + if (content->len >= persistent_key_payload_offset) { + payload = content->x + persistent_key_payload_offset; + payload_length = content->len - persistent_key_payload_offset; + } + /* Exporting should work for a valid key that has export permission. */ /* Allocate enough memory for the key data (assuming the key * representation in storage is not compressed compared to the @@ -497,26 +523,45 @@ void load_primed_storage(int32_t owner_id, key_data, key_data_size, &key_data_length), expected_export_status); if (expected_export_status == PSA_SUCCESS) { - TEST_ASSERT(key_data_length != 0); + if (key_already_existed) { + /* The key already existed. We don't know what it is, + * but check that it is not what we put in storage. */ + TEST_ASSERT(key_data_length != payload_length || + memcmp(key_data, payload, payload_length)); + } else { + TEST_MEMORY_COMPARE(key_data, key_data_length, + payload, payload_length); + } } /* Assert that the data length is sensible even if export failed. * This reduces the risk of memory corruption if an application * doesn't check the return status of export(). */ TEST_LE_U(key_data_length, key_data_size); - /* Destroying the key should work even for malformed content. - * But it should not work for reserved file IDs. */ - TEST_EQUAL(psa_destroy_key(key_id), expected_destroy_status); - if (uid == 0) { - /* Invalid file UID. No point in asserting anything about the file. */ - } else if (expected_destroy_status == PSA_SUCCESS) { - file_status = psa_its_get_info(uid, &info); - if (key_id_arg == 0) { - /* psa_destroy_key(0) is defined as a no-op, so it should not - * affect the file. */ - TEST_EQUAL(file_status, PSA_SUCCESS); - } else { - TEST_EQUAL(file_status, PSA_ERROR_DOES_NOT_EXIST); + if (key_already_existed) { + /* There was a key with the key ID under test, for example a key + * used by the PSA RNG. Don't disrupt whatever is using that key. + * Pure the key cache: this is necessary if the key was a built-in + * key which got loaded into the cache by the get_attributes and + * export calls above, otherwise PSA_DONE() would legitimately + * complain about a non-empty cache. + */ + psa_purge_key(key_id); + } else { + /* Destroying the key should work even for malformed content. + * But it should not work for reserved file IDs. */ + TEST_EQUAL(psa_destroy_key(key_id), expected_destroy_status); + if (uid == 0) { + /* Invalid file UID. No point in asserting anything about the file. */ + } else if (expected_destroy_status == PSA_SUCCESS) { + file_status = psa_its_get_info(uid, &info); + if (key_id_arg == 0) { + /* psa_destroy_key(0) is defined as a no-op, so it should not + * affect the file. */ + TEST_EQUAL(file_status, PSA_SUCCESS); + } else { + TEST_EQUAL(file_status, PSA_ERROR_DOES_NOT_EXIST); + } } } From cbc6bc56b1828ef9188ac398332c625d0eef78c5 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 31 Oct 2025 11:30:18 +0100 Subject: [PATCH 7/8] tests: suite_psa_crypto_persistent_key: fix test data for 3.6 branch Previous tests were backported from tf-psa-crypto and they work fine there. However the library implementation is not the same between 3.6 and tf-psa-crypto: in 3.6 we only prevent loading of persistent keys if their ID is within the volatile range, but the built-in one is still allowed. Therefore this commit fix expected return values for the 3.6 branch when built-in keys are accessed. Signed-off-by: Valerio Setti --- .../test_suite_psa_crypto_persistent_key.data | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.data b/tests/suites/test_suite_psa_crypto_persistent_key.data index bead47902b..4755ad6e29 100644 --- a/tests/suites/test_suite_psa_crypto_persistent_key.data +++ b/tests/suites/test_suite_psa_crypto_persistent_key.data @@ -163,13 +163,13 @@ load_primed_storage:0:PSA_KEY_ID_VOLATILE_MAX:"505341004b45590000000000010000000 # and third-party code that provide built-in keys. We can extend this # range, but shrinking it would be an incompatible change. Load key: owner=0 id=MBEDTLS_PSA_KEY_ID_BUILTIN_MIN (bad id) -load_primed_storage:0:0x7fff0000:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE +load_primed_storage:0:0x7fff0000:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS Load key: owner=0 id=MBEDTLS_PSA_KEY_ID_BUILTIN_MAX (bad id) -load_primed_storage:0:0x7fffefff:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE +load_primed_storage:0:0x7fffefff:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS Load key: owner=0 id=0x7fffffff (bad id: not in any range) -load_primed_storage:0:KEY_ID_OUTSIDE_DEFINED_RANGES:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE +load_primed_storage:0:KEY_ID_OUTSIDE_DEFINED_RANGES:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS Load key: owner=0 id=0xffff0000 (bad id: reserved file UID, not in use) load_primed_storage:0:0xffff0000:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE @@ -210,15 +210,15 @@ load_primed_storage:42:PSA_KEY_ID_VOLATILE_MAX:"505341004b4559000000000001000000 # range, but shrinking it would be an incompatible change. Load key: owner=42 id=MBEDTLS_PSA_KEY_ID_BUILTIN_MIN (bad id) depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER -load_primed_storage:42:0x7fff0000:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE +load_primed_storage:42:0x7fff0000:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS Load key: owner=42 id=MBEDTLS_PSA_KEY_ID_BUILTIN_MAX (bad id) depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER -load_primed_storage:42:0x7fffefff:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE +load_primed_storage:42:0x7fffefff:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS Load key: owner=42 id=0x7fffffff (bad id: not in any range) depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER -load_primed_storage:42:KEY_ID_OUTSIDE_DEFINED_RANGES:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE +load_primed_storage:42:KEY_ID_OUTSIDE_DEFINED_RANGES:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS Load key: owner=42 id=0xffff0000 (bad id: reserved file UID, not in use) depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER @@ -262,15 +262,15 @@ load_primed_storage:-0x80000000:PSA_KEY_ID_VOLATILE_MAX:"505341004b4559000000000 # range, but shrinking it would be an incompatible change. Load key: owner=-0x80000000 id=MBEDTLS_PSA_KEY_ID_BUILTIN_MIN (bad id) depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER -load_primed_storage:-0x80000000:0x7fff0000:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE +load_primed_storage:-0x80000000:0x7fff0000:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS Load key: owner=-0x80000000 id=MBEDTLS_PSA_KEY_ID_BUILTIN_MAX (bad id) depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER -load_primed_storage:-0x80000000:0x7fffefff:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE +load_primed_storage:-0x80000000:0x7fffefff:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS Load key: owner=-0x80000000 id=0x7fffffff (bad id: not in any range) depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER -load_primed_storage:-0x80000000:KEY_ID_OUTSIDE_DEFINED_RANGES:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HANDLE +load_primed_storage:-0x80000000:KEY_ID_OUTSIDE_DEFINED_RANGES:"505341004b455900000000000100000001100800010000000000000000000000010000004c":PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS Load key: owner=-0x80000000 id=0xffff0000 (bad id: reserved file UID, not in use) depends_on:MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER From 8102fe3b0fb16a78bfb8cd213d5d111ed270af29 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 3 Nov 2025 11:07:04 +0100 Subject: [PATCH 8/8] tests: suite_psa_crypto_persistent_key: fix load_primed_storage Do not remove keys that belong to the reserved range. Signed-off-by: Valerio Setti --- tests/suites/test_suite_psa_crypto_persistent_key.function | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function index f0fcd5f7fc..acf57e2acf 100644 --- a/tests/suites/test_suite_psa_crypto_persistent_key.function +++ b/tests/suites/test_suite_psa_crypto_persistent_key.function @@ -568,7 +568,11 @@ void load_primed_storage(int32_t owner_id, exit: psa_reset_key_attributes(&attributes); PSA_DONE(); - psa_its_remove(uid); + if (!KEY_ID_IN_RESERVED_FILE_ID_RANGE(key_id_arg)) { + /* The key ID corresponds to a reserved file (e.g. transaction + * log or entropy seed). Don't corrupt that file. */ + psa_its_remove(uid); + } mbedtls_free(key_data); } /* END_CASE */