mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-11-23 00:02:39 +03:00
Merge pull request #10473 from valeriosetti/issue488-3.6
[3.6] psa_load_builtin_key_into_slot: prevent accessing the PSA storage if key ID is in volatile range
This commit is contained in:
3
ChangeLog.d/issue488.txt
Normal file
3
ChangeLog.d/issue488.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Bugfix
|
||||||
|
* Prevent loading of peristent keys whose key ID belong to the volatile
|
||||||
|
range.
|
||||||
@@ -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;
|
psa_status_t status = PSA_SUCCESS;
|
||||||
uint8_t *key_data = NULL;
|
uint8_t *key_data = NULL;
|
||||||
size_t key_data_length = 0;
|
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,
|
status = psa_load_persistent_key(&slot->attr,
|
||||||
&key_data, &key_data_length);
|
&key_data, &key_data_length);
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ parse_storage_data_check:"505341004b45590000000000010000000170000001000000000000
|
|||||||
Parse storage: truncated key
|
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
|
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.
|
# 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
|
Save maximum-size persistent raw key
|
||||||
depends_on:MBEDTLS_PSA_ITS_FILE_C
|
depends_on:MBEDTLS_PSA_ITS_FILE_C
|
||||||
@@ -133,3 +136,150 @@ destroy_nonexistent:1:PSA_ERROR_INVALID_HANDLE
|
|||||||
|
|
||||||
Destroy invalid id: 0xffffffff
|
Destroy invalid id: 0xffffffff
|
||||||
destroy_nonexistent:0xffffffff:PSA_ERROR_INVALID_HANDLE
|
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_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_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_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
|
||||||
|
|
||||||
|
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_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_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_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
|
||||||
|
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_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_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_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
|
||||||
|
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
|
||||||
|
|||||||
@@ -14,9 +14,32 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "mbedtls/ctr_drbg.h"
|
||||||
|
#include "psa_crypto_its.h"
|
||||||
#include "psa_crypto_slot_management.h"
|
#include "psa_crypto_slot_management.h"
|
||||||
#include "psa_crypto_storage.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 "PSA\0KEY"
|
||||||
#define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH (sizeof(PSA_KEY_STORAGE_MAGIC_HEADER))
|
#define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH (sizeof(PSA_KEY_STORAGE_MAGIC_HEADER))
|
||||||
|
|
||||||
@@ -34,6 +57,9 @@ typedef struct {
|
|||||||
uint8_t key_data[];
|
uint8_t key_data[];
|
||||||
} psa_persistent_key_storage_format;
|
} psa_persistent_key_storage_format;
|
||||||
|
|
||||||
|
const size_t persistent_key_payload_offset =
|
||||||
|
offsetof(psa_persistent_key_storage_format, key_data);
|
||||||
|
|
||||||
/* END_HEADER */
|
/* END_HEADER */
|
||||||
|
|
||||||
/* BEGIN_DEPENDENCIES
|
/* BEGIN_DEPENDENCIES
|
||||||
@@ -117,6 +143,48 @@ exit:
|
|||||||
}
|
}
|
||||||
/* END_CASE */
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
|
||||||
/* BEGIN_CASE */
|
/* BEGIN_CASE */
|
||||||
void save_large_persistent_key(int data_length_arg, int expected_status)
|
void save_large_persistent_key(int data_length_arg, int expected_status)
|
||||||
{
|
{
|
||||||
@@ -338,3 +406,173 @@ exit:
|
|||||||
PSA_DONE();
|
PSA_DONE();
|
||||||
}
|
}
|
||||||
/* END_CASE */
|
/* 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();
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
/* 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);
|
||||||
|
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 && !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,
|
||||||
|
psa_get_key_id(&attributes)));
|
||||||
|
TEST_EQUAL(psa_get_key_lifetime(&attributes),
|
||||||
|
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
|
||||||
|
* 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) {
|
||||||
|
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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
psa_reset_key_attributes(&attributes);
|
||||||
|
PSA_DONE();
|
||||||
|
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 */
|
||||||
|
|||||||
Reference in New Issue
Block a user