From d49a499d033def28cbd5132d17974e462c628bda Mon Sep 17 00:00:00 2001 From: Darryl Green Date: Mon, 18 Jun 2018 17:27:26 +0100 Subject: [PATCH] psa: Implement persistent keys Allow use of persistent keys, including configuring them, importing and exporting them, and destroying them. When getting a slot using psa_get_key_slot, there are 3 scenarios that can occur if the keys lifetime is persistent: 1. Key type is PSA_KEY_TYPE_NONE, no persistent storage entry: - The key slot is treated as a standard empty key slot 2. Key type is PSA_KEY_TYPE_NONE, persistent storage entry exists: - Attempt to load the key from persistent storage 3. Key type is not PSA_KEY_TYPE_NONE: - As checking persistent storage on every use of the key could be expensive, the persistent key is assumed to be saved in persistent storage, the in-memory key is continued to be used. --- crypto/tests/Makefile | 3 + include/psa/crypto.h | 11 + library/psa_crypto.c | 83 ++++- scripts/mbed_crypto.make | 2 + tests/CMakeLists.txt | 1 + tests/suites/test_suite_psa_crypto.data | 4 + tests/suites/test_suite_psa_crypto.function | 81 +++++ .../test_suite_psa_crypto_persistent_key.data | 78 ++++ ...t_suite_psa_crypto_persistent_key.function | 341 ++++++++++++++++++ 9 files changed, 599 insertions(+), 5 deletions(-) create mode 100644 tests/suites/test_suite_psa_crypto_persistent_key.data create mode 100644 tests/suites/test_suite_psa_crypto_persistent_key.function diff --git a/crypto/tests/Makefile b/crypto/tests/Makefile index 2f68e8677..cc4355bed 100644 --- a/crypto/tests/Makefile +++ b/crypto/tests/Makefile @@ -16,12 +16,14 @@ PYTHON ?= python APPS := \ test_suite_psa_crypto \ test_suite_psa_crypto_metadata \ + test_suite_psa_crypto_persistent_key \ test_suite_psa_crypto_storage_file \ # Don't delete this line. # Look up for associated function files func.test_suite_psa_crypto := test_suite_psa_crypto func.test_suite_psa_crypto_metadata := test_suite_psa_crypto_metadata +func.test_suite_psa_crypto_persistent_key := test_suite_psa_crypto_persistent_key func.test_suite_psa_crypto_storage_file := test_suite_psa_crypto_storage_file .SILENT: @@ -58,6 +60,7 @@ clean: test: $(APPS) ./test_suite_psa_crypto_metadata ./test_suite_psa_crypto + ./test_suite_psa_crypto_persistent_key ./test_suite_psa_crypto_storage_file # Create separate targets for generating embedded tests. diff --git a/include/psa/crypto.h b/include/psa/crypto.h index d1a3f0f3b..1ca64922e 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -1441,6 +1441,7 @@ typedef uint32_t psa_algorithm_t; * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * \retval #PSA_ERROR_INSUFFICIENT_STORAGE * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_STORAGE_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED * \retval #PSA_ERROR_BAD_STATE @@ -1922,6 +1923,16 @@ psa_status_t psa_get_key_lifetime(psa_key_slot_t key, * whether the lifetime of an occupied key slot can be changed, is * implementation-dependent. * + * When creating a persistent key, you must call this function before creating + * the key material with psa_import_key(), psa_generate_key() or + * psa_generator_import_key(). To open an existing persistent key, you must + * call this function with the correct lifetime value before using the slot + * for a cryptographic operation. Once a slot's lifetime has been set, + * the lifetime remains associated with the slot until a subsequent call to + * psa_set_key_lifetime(), until the key is wiped with psa_destroy_key or + * until the application terminates (or disconnects from the cryptography + * service, if the implementation offers such a possibility). + * * \param key Slot whose lifetime is to be changed. * \param lifetime The lifetime value to set for the given key slot. * diff --git a/library/psa_crypto.c b/library/psa_crypto.c index c205e12f6..6b089831e 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -43,6 +43,10 @@ #include "psa/crypto.h" +/* Include internal declarations that are useful for implementing persistently + * stored keys. */ +#include "psa_crypto_storage.h" + #include #include #if defined(MBEDTLS_PLATFORM_C) @@ -702,6 +706,27 @@ static psa_status_t psa_import_key_into_slot( key_slot_t *slot, return( PSA_SUCCESS ); } +#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) +static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t key, + key_slot_t *p_slot ) +{ + psa_status_t status = PSA_SUCCESS; + uint8_t *key_data = NULL; + size_t key_data_length = 0; + + status = psa_load_persistent_key( key, &( p_slot )->type, + &( p_slot )->policy, &key_data, + &key_data_length ); + if( status != PSA_SUCCESS ) + goto exit; + status = psa_import_key_into_slot( p_slot, + key_data, key_data_length ); +exit: + psa_free_persistent_key_data( key_data, key_data_length ); + return( status ); +} +#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ + /* Retrieve a key slot, occupied or not. */ static psa_status_t psa_get_key_slot( psa_key_slot_t key, key_slot_t **p_slot ) @@ -715,6 +740,23 @@ static psa_status_t psa_get_key_slot( psa_key_slot_t key, return( PSA_ERROR_INVALID_ARGUMENT ); *p_slot = &global_data.key_slots[key - 1]; + +#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) + if( ( *p_slot )->lifetime == PSA_KEY_LIFETIME_PERSISTENT ) + { + /* There are two circumstances this can occur: the key material has + * not yet been created, or the key exists in storage but has not yet + * been loaded into memory. */ + if( ( *p_slot )->type == PSA_KEY_TYPE_NONE ) + { + psa_status_t status = PSA_SUCCESS; + status = psa_load_persistent_key_into_slot( key, *p_slot ); + if( status != PSA_ERROR_EMPTY_SLOT ) + return( status ); + } + } +#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ + return( PSA_SUCCESS ); } @@ -830,18 +872,44 @@ psa_status_t psa_import_key( psa_key_slot_t key, return( status ); } - return( PSA_SUCCESS ); +#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) + if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT ) + { + /* Store in file location */ + status = psa_save_persistent_key( key, slot->type, &slot->policy, data, + data_length ); + if( status != PSA_SUCCESS ) + { + (void) psa_remove_key_data_from_memory( slot ); + slot->type = PSA_KEY_TYPE_NONE; + } + } +#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ + + return( status ); } psa_status_t psa_destroy_key( psa_key_slot_t key ) { key_slot_t *slot; - psa_status_t status; + psa_status_t status = PSA_SUCCESS; + psa_status_t storage_status = PSA_SUCCESS; status = psa_get_key_slot( key, &slot ); if( status != PSA_SUCCESS ) return( status ); - return( psa_remove_key_from_memory( slot ) ); +#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) + if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT ) + { + storage_status = psa_destroy_persistent_key( key ); + } +#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ + status = psa_remove_key_data_from_memory( slot ); + /* Zeroize the slot to wipe metadata such as policies. */ + mbedtls_zeroize( slot, sizeof( *slot ) ); + if( status != PSA_SUCCESS ) + return( status ); + return( storage_status ); } /* Return the size of the key in the given slot, in bits. */ @@ -2974,16 +3042,21 @@ psa_status_t psa_set_key_lifetime( psa_key_slot_t key, if( lifetime != PSA_KEY_LIFETIME_VOLATILE && lifetime != PSA_KEY_LIFETIME_PERSISTENT && - lifetime != PSA_KEY_LIFETIME_WRITE_ONCE) + lifetime != PSA_KEY_LIFETIME_WRITE_ONCE ) return( PSA_ERROR_INVALID_ARGUMENT ); status = psa_get_empty_key_slot( key, &slot ); if( status != PSA_SUCCESS ) return( status ); - if( lifetime != PSA_KEY_LIFETIME_VOLATILE ) + if( lifetime == PSA_KEY_LIFETIME_WRITE_ONCE ) return( PSA_ERROR_NOT_SUPPORTED ); +#if !defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) + if( lifetime == PSA_KEY_LIFETIME_PERSISTENT ) + return( PSA_ERROR_NOT_SUPPORTED ); +#endif + slot->lifetime = lifetime; return( PSA_SUCCESS ); diff --git a/scripts/mbed_crypto.make b/scripts/mbed_crypto.make index ab54d555f..f51f5f8f3 100644 --- a/scripts/mbed_crypto.make +++ b/scripts/mbed_crypto.make @@ -158,6 +158,8 @@ TEST_FILES := \ tests/suites/test_suite_psa_crypto_hash.function \ tests/suites/test_suite_psa_crypto_metadata.data \ tests/suites/test_suite_psa_crypto_metadata.function \ + tests/suites/test_suite_psa_crypto_persistent_key.data \ + tests/suites/test_suite_psa_crypto_persistent_key.function \ tests/suites/test_suite_psa_crypto_storage_file.data \ tests/suites/test_suite_psa_crypto_storage_file.function \ # Don't delete this line. diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7af7fcf18..34658c8e1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -113,6 +113,7 @@ add_test_suite(poly1305) add_test_suite(psa_crypto) add_test_suite(psa_crypto_hash) add_test_suite(psa_crypto_metadata) +add_test_suite(psa_crypto_persistent_key) add_test_suite(psa_crypto_storage_file) add_test_suite(shax) add_test_suite(ssl) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index ea214d25a..7e70de38a 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -1834,3 +1834,7 @@ validate_module_init_generate_random: PSA validate module initialization: key based validate_module_init_key_based: + +persistent key can be accessed after in-memory deletion: AES, 128 bits, CTR +depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PSA_CRYPTO_STORAGE_C +persistent_key_load_key_from_storage:"2b7e151628aed2a6abf7158809cf4f3c":PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 674a6e9fe..4692dbe84 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -4030,3 +4030,84 @@ void validate_module_init_key_based( ) TEST_ASSERT( status == PSA_ERROR_BAD_STATE ); } /* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */ +void persistent_key_load_key_from_storage( data_t *data, int type_arg, + int bits, int usage_arg, + int alg_arg ) +{ + psa_key_slot_t slot = 1; + psa_key_type_t type = (psa_key_type_t) type_arg; + psa_key_type_t type_get; + size_t bits_get; + psa_key_policy_t policy_set; + psa_key_policy_t policy_get; + psa_key_usage_t policy_usage = (psa_key_usage_t) usage_arg; + psa_algorithm_t policy_alg = (psa_algorithm_t) alg_arg; + unsigned char *first_export = NULL; + unsigned char *second_export = NULL; + size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits ); + size_t first_exported_length; + size_t second_exported_length; + + ASSERT_ALLOC( first_export, export_size ); + ASSERT_ALLOC( second_export, export_size ); + + TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); + + TEST_ASSERT( psa_set_key_lifetime( + slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); + + psa_key_policy_init( &policy_set ); + + psa_key_policy_set_usage( &policy_set, policy_usage, + policy_alg ); + + TEST_ASSERT( psa_set_key_policy( slot, &policy_set ) == PSA_SUCCESS ); + + /* Import the key */ + TEST_ASSERT( psa_import_key( slot, type, + data->x, data->len ) == PSA_SUCCESS ); + + /* Export the key */ + TEST_ASSERT( psa_export_key( slot, first_export, export_size, + &first_exported_length ) == PSA_SUCCESS ); + + /* Shutdown and restart */ + mbedtls_psa_crypto_free(); + + TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); + + /* Mark slot as persistent again */ + TEST_ASSERT( psa_set_key_lifetime( + slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); + + /* Check key slot still contains key data */ + TEST_ASSERT( psa_get_key_information( + slot, &type_get, &bits_get ) == PSA_SUCCESS ); + TEST_ASSERT( type_get == type ); + TEST_ASSERT( bits_get == (size_t) bits ); + + TEST_ASSERT( psa_get_key_policy( slot, &policy_get ) == PSA_SUCCESS ); + TEST_ASSERT( psa_key_policy_get_usage( + &policy_get ) == policy_usage ); + TEST_ASSERT( psa_key_policy_get_algorithm( + &policy_get ) == policy_alg ); + + /* Export the key again */ + TEST_ASSERT( psa_export_key( slot, second_export, export_size, + &second_exported_length ) == PSA_SUCCESS ); + + ASSERT_COMPARE( first_export, first_exported_length, + second_export, second_exported_length ); + + ASSERT_COMPARE( data->x, data->len, + first_export, first_exported_length ); + +exit: + mbedtls_free( first_export ); + mbedtls_free( second_export ); + psa_destroy_key( slot ); + mbedtls_psa_crypto_free(); +} +/* END_CASE */ diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.data b/tests/suites/test_suite_psa_crypto_persistent_key.data new file mode 100644 index 000000000..46e547c93 --- /dev/null +++ b/tests/suites/test_suite_psa_crypto_persistent_key.data @@ -0,0 +1,78 @@ +PSA Storage format data for storage +format_storage_data_check:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"505341004b45590000000000000001700100000000000012620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION + +PSA Storage parse stored data +parse_storage_data_check:"505341004b45590000000000000001700100000000000012620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_SUCCESS + +PSA Storage parse stored data wrong version, should fail +parse_storage_data_check:"505341004b455900ffffffff000001700100000000000012620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ERROR_STORAGE_FAILURE + +PSA Storage parse too big data, should fail +parse_storage_data_check:"505341004b45590000000000000001700100000000000012ffffffff3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ERROR_STORAGE_FAILURE + +PSA Storage parse bad magic, should fail +parse_storage_data_check:"645341004b45590000000000000001700100000000000012620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ERROR_STORAGE_FAILURE + +PSA Storage parse not enough magic, should fail +parse_storage_data_check:"505341004b4559":"":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ERROR_STORAGE_FAILURE + +# 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_CRYPTO_STORAGE_FILE_C +save_large_persistent_key:0:PSA_SUCCESS + +Save larger than maximum size persistent raw key, should fail +save_large_persistent_key:1:PSA_ERROR_INSUFFICIENT_STORAGE + +Persistent key is configurable +depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C +persistent_key_is_configurable:1:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24" + +Persistent key destroy +depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C +persistent_key_destroy:1:1:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RAW_DATA:"deadbeef" + +Persistent key destroy missing key +depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C +persistent_key_destroy:1:0:PSA_KEY_TYPE_RSA_KEYPAIR:"":PSA_KEY_TYPE_RAW_DATA:"deadbeef" + +Key lifetime defaults to volatile +depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C +default_volatile_lifetime:1:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24" + +Persistent key import +depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C +persistent_key_import:1:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_SUCCESS + +Persistent key import garbage data, should fail +depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C +persistent_key_import:1:PSA_KEY_TYPE_RSA_KEYPAIR:"11111111":PSA_ERROR_INVALID_ARGUMENT + +import/export persistent raw key: 0 byte +import_export_persistent_key:"":PSA_KEY_TYPE_RAW_DATA:0:0 + +import/export persistent raw key: 1 byte +import_export_persistent_key:"2a":PSA_KEY_TYPE_RAW_DATA:8:0 + +import/export persistent key RSA public key: good, 1024-bit +depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C +import_export_persistent_key:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:0 + +import/export persistent key RSA keypair: good, 1024-bit +depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C +import_export_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:1024:0 + +import/export persistent raw key file not exist: 1 byte +import_export_persistent_key:"2a":PSA_KEY_TYPE_RAW_DATA:8:1 + +import/export persistent key RSA public key file not exist: 1024-bit +depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C +import_export_persistent_key:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:1 + +import/export persistent key RSA keypair file not exist: 1024-bit +depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C +import_export_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:1024:1 + +PSA import/export-persistent symmetric key: 16 bytes +depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C +import_export_persistent_key:"2b7e151628aed2a6abf7158809cf4f3c":PSA_KEY_TYPE_AES:128:0 diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function new file mode 100644 index 000000000..505f1f9e1 --- /dev/null +++ b/tests/suites/test_suite_psa_crypto_persistent_key.function @@ -0,0 +1,341 @@ +/* BEGIN_HEADER */ +#include +#include "psa/crypto.h" +#include "psa_crypto_storage.h" +#include "psa_crypto_storage_backend.h" +#include "mbedtls/md.h" + +#define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY" +#define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH ( sizeof( PSA_KEY_STORAGE_MAGIC_HEADER ) ) + +typedef struct { + uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH]; + uint8_t version[4]; + uint8_t type[sizeof( psa_key_type_t )]; + uint8_t policy[sizeof( psa_key_policy_t )]; + uint8_t data_len[4]; + uint8_t key_data[]; +} psa_persistent_key_storage_format; +/* END_HEADER */ + +/* BEGIN_DEPENDENCIES + * depends_on:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_PSA_CRYPTO_STORAGE_C + * END_DEPENDENCIES + */ + +/* BEGIN_CASE */ +void format_storage_data_check( data_t *key_data, + data_t *expected_file_data, + int key_type, int key_usage, int key_alg ) +{ + uint8_t *file_data; + size_t file_data_length; + psa_key_policy_t key_policy; + + key_policy.usage = (psa_key_usage_t) key_usage; + key_policy.alg = (psa_algorithm_t) key_alg; + + file_data_length = key_data->len + sizeof( psa_persistent_key_storage_format ); + file_data = mbedtls_calloc( 1, file_data_length ); + psa_format_key_data_for_storage( key_data->x, key_data->len, + (psa_key_type_t) key_type, &key_policy, + file_data ); + + ASSERT_COMPARE( expected_file_data->x, expected_file_data->len, + file_data, file_data_length ); + mbedtls_free( file_data ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void parse_storage_data_check( data_t *file_data, + data_t *expected_key_data, + int expected_key_type, + int expected_key_usage, + int expected_key_alg, + int expected_status ) +{ + uint8_t *key_data = NULL; + size_t key_data_length = 0; + psa_key_type_t key_type = 0; + psa_key_policy_t key_policy; + psa_status_t status; + + status = psa_parse_key_data_from_storage( file_data->x, file_data->len, + &key_data, &key_data_length, + &key_type, &key_policy ); + + TEST_ASSERT( status == expected_status ); + if( status != PSA_SUCCESS ) + goto exit; + + TEST_ASSERT( key_type == (psa_key_type_t) expected_key_type ); + TEST_ASSERT( key_policy.usage == (uint32_t) expected_key_usage ); + TEST_ASSERT( key_policy.alg == (uint32_t) expected_key_alg ); + ASSERT_COMPARE( expected_key_data->x, expected_key_data->len, + key_data, key_data_length ); + +exit: + mbedtls_free( key_data ); +} +/* END_CASE */ + + +/* BEGIN_CASE */ +void save_large_persistent_key( int data_too_large, int expected_status ) +{ + psa_key_slot_t slot = 1; + uint8_t *data = NULL; + size_t data_length = PSA_CRYPTO_MAX_STORAGE_SIZE; + + if( data_too_large ) + data_length += 1; + + ASSERT_ALLOC( data, data_length ); + + TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); + + TEST_ASSERT( psa_set_key_lifetime( + slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); + + TEST_ASSERT( psa_import_key( slot, PSA_KEY_TYPE_RAW_DATA, + data, data_length ) == expected_status ); + +exit: + mbedtls_free( data ); + psa_destroy_persistent_key( slot ); + mbedtls_psa_crypto_free(); +} +/* END_CASE */ + + +/* BEGIN_CASE */ +void persistent_key_is_configurable( int slot_arg, int type_arg, + data_t *data ) +{ + psa_key_policy_t policy; + psa_key_lifetime_t lifetime; + psa_key_slot_t slot = (psa_key_slot_t) slot_arg; + psa_key_type_t type = (psa_key_type_t) type_arg; + + TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); + + TEST_ASSERT( psa_set_key_lifetime( + slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); + + psa_key_policy_init( &policy ); + + TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + + TEST_ASSERT( psa_import_key( slot, type, + data->x, data->len ) == PSA_SUCCESS ); + + TEST_ASSERT( psa_get_key_lifetime( slot, &lifetime ) == PSA_SUCCESS ); + + TEST_ASSERT( lifetime == PSA_KEY_LIFETIME_PERSISTENT ); + +exit: + psa_destroy_persistent_key( slot ); + mbedtls_psa_crypto_free(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void persistent_key_destroy( int slot_arg, int should_store, + int first_type_arg, data_t *first_data, + int second_type_arg, data_t *second_data ) +{ + psa_key_policy_t policy; + psa_key_slot_t slot = (psa_key_slot_t) slot_arg; + psa_key_type_t first_type = (psa_key_type_t) first_type_arg; + psa_key_type_t second_type = (psa_key_type_t) second_type_arg; + + TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); + + TEST_ASSERT( psa_set_key_lifetime( + slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); + + psa_key_policy_init( &policy ); + + if( should_store == 1 ) + { + TEST_ASSERT( psa_import_key( + slot, first_type, + first_data->x, first_data->len ) == PSA_SUCCESS ); + } + + /* Destroy the key */ + TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS ); + + TEST_ASSERT( psa_get_key_information( + slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT ); + + /* Check key slot storage is removed */ + TEST_ASSERT( psa_is_key_present_in_storage( slot ) == 0 ); + + /* Check destroying the key again doesn't report failure */ + TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS ); + TEST_ASSERT( psa_get_key_information( + slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT ); + + /* Shutdown and restart */ + mbedtls_psa_crypto_free(); + + TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); + + /* Mark slot as persistent again */ + TEST_ASSERT( psa_set_key_lifetime( + slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); + + /* Check key slot is empty */ + TEST_ASSERT( psa_get_key_information( + slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT ); + + /* Import different key data to ensure slot really was empty */ + psa_key_policy_init( &policy ); + + psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, + PSA_ALG_VENDOR_FLAG ); + + TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + + TEST_ASSERT( psa_import_key( + slot, second_type, + second_data->x, second_data->len ) == PSA_SUCCESS ); + +exit: + psa_destroy_persistent_key( slot ); + mbedtls_psa_crypto_free(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void default_volatile_lifetime( int slot_arg, int type_arg, data_t *data ) +{ + psa_key_policy_t policy; + psa_key_slot_t slot = (psa_key_slot_t) slot_arg; + psa_key_type_t type = (psa_key_type_t) type_arg; + + TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); + + psa_key_policy_init( &policy ); + + TEST_ASSERT( psa_import_key( slot, type, + data->x, data->len ) == PSA_SUCCESS ); + + /* Shutdown and restart */ + mbedtls_psa_crypto_free(); + + TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); + + /* Check key slot is empty */ + TEST_ASSERT( psa_get_key_information( + slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT ); + +exit: + psa_destroy_persistent_key( slot ); + mbedtls_psa_crypto_free(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void persistent_key_import( int slot_arg, int type_arg, data_t *data, + int expected_status ) +{ + psa_key_policy_t policy; + psa_key_lifetime_t lifetime; + psa_key_slot_t slot = (psa_key_slot_t) slot_arg; + psa_key_type_t type = (psa_key_type_t) type_arg; + + TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); + + TEST_ASSERT( psa_set_key_lifetime( + slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); + + psa_key_policy_init( &policy ); + + TEST_ASSERT( psa_import_key( slot, type, + data->x, data->len ) == expected_status ); + + if( expected_status != PSA_SUCCESS ) + { + TEST_ASSERT( psa_is_key_present_in_storage( slot ) == 0 ); + goto exit; + } + + TEST_ASSERT( psa_get_key_lifetime( slot, &lifetime ) == PSA_SUCCESS ); + + TEST_ASSERT( lifetime == PSA_KEY_LIFETIME_PERSISTENT ); + +exit: + psa_destroy_persistent_key( slot ); + mbedtls_psa_crypto_free(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void import_export_persistent_key( data_t *data, int type_arg, + int expected_bits, int key_not_exist ) +{ + psa_key_slot_t slot = 1; + psa_key_type_t type = (psa_key_type_t) type_arg; + unsigned char *exported = NULL; + size_t export_size = data->len; + size_t exported_length; + psa_key_type_t got_type; + size_t got_bits; + psa_key_policy_t policy; + psa_key_lifetime_t lifetime_get; + + ASSERT_ALLOC( exported, export_size ); + + TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + + TEST_ASSERT( psa_set_key_lifetime( + slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); + + psa_key_policy_init( &policy ); + + psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, + PSA_ALG_VENDOR_FLAG ); + + TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + + /* Import the key */ + TEST_ASSERT( psa_import_key( slot, type, + data->x, data->len ) == PSA_SUCCESS ); + + TEST_ASSERT( psa_get_key_lifetime( + slot, &lifetime_get ) == PSA_SUCCESS ); + TEST_ASSERT( lifetime_get == PSA_KEY_LIFETIME_PERSISTENT ); + + /* Test the key information */ + TEST_ASSERT( psa_get_key_information( + slot, &got_type, &got_bits ) == PSA_SUCCESS ); + TEST_ASSERT( got_type == type ); + TEST_ASSERT( got_bits == (size_t) expected_bits ); + + TEST_ASSERT( psa_is_key_present_in_storage( slot ) == 1 ); + + if( key_not_exist ) + { + psa_destroy_persistent_key( slot ); + } + /* Export the key */ + TEST_ASSERT( psa_export_key( slot, exported, export_size, + &exported_length ) == PSA_SUCCESS ); + + ASSERT_COMPARE( data->x, data->len, exported, exported_length ); + + /* Destroy the key */ + TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS ); + TEST_ASSERT( psa_get_key_information( + slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT ); + TEST_ASSERT( psa_is_key_present_in_storage( slot ) == 0 ); + +exit: + mbedtls_free( exported ); + psa_destroy_persistent_key( slot ); + mbedtls_psa_crypto_free( ); +} +/* END_CASE */