diff --git a/include/psa/crypto.h b/include/psa/crypto.h index 043db3288e..8c42e932e7 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -132,7 +132,8 @@ psa_status_t psa_crypto_init(void); * psa_reset_key_attributes() on an attribute structure is optional if * the structure has only been modified by the following functions * since it was initialized or last reset with psa_reset_key_attributes(): - * - psa_make_key_persistent() + * - psa_set_key_id() + * - psa_set_key_lifetime() * - psa_set_key_type() * - psa_set_key_bits() * - psa_set_key_usage_flags() @@ -173,7 +174,9 @@ psa_status_t psa_crypto_init(void); * * A typical sequence to create a key is as follows: * -# Create and initialize an attribute structure. - * -# If the key is persistent, call psa_make_key_persistent(). + * -# If the key is persistent, call psa_set_key_id(). + * Also call psa_set_key_lifetime() to place the key in a non-default + * location. * -# Set the key policy with psa_set_key_usage_flags() and * psa_set_key_algorithm(). * -# Set the key type with psa_set_key_type(). If the key type requires @@ -203,30 +206,56 @@ psa_status_t psa_crypto_init(void); */ typedef struct psa_key_attributes_s psa_key_attributes_t; -/** Declare a key as persistent. +/** Declare a key as persistent and set its key identifier. * - * This function does not access storage, it merely fills the attribute - * structure with given values. The persistent key will be written to - * storage when the attribute structure is passed to a key creation - * function such as psa_import_key(), psa_generate_random_key(), + * If the attribute structure currently declares the key as volatile (which + * is the default content of an attribute structure), this function sets + * the lifetime attribute to #PSA_KEY_LIFETIME_PERSISTENT. + * + * This function does not access storage, it merely stores the given + * value in the structure. + * The persistent key will be written to storage when the attribute + * structure is passed to a key creation function such as + * psa_import_key(), psa_generate_random_key(), * psa_generate_derived_key() or psa_copy_key(). * - * This function overwrites any identifier and lifetime values - * previously set in \p attributes. - * * This function may be declared as `static` (i.e. without external * linkage). This function may be provided as a function-like macro, * but in this case it must evaluate each of its arguments exactly once. * * \param[out] attributes The attribute structure to write to. * \param id The persistent identifier for the key. + */ +static void psa_set_key_id(psa_key_attributes_t *attributes, + psa_key_id_t id); + +/** Set the location of a persistent key. + * + * To make a key persistent, you must give it a persistent key identifier + * with psa_set_key_id(). By default, a key that has a persistent identifier + * is stored in the default storage area identifier by + * #PSA_KEY_LIFETIME_PERSISTENT. Call this function to choose a storage + * area, or to explicitly declare the key as volatile. + * + * This function does not access storage, it merely stores the given + * value in the structure. + * The persistent key will be written to storage when the attribute + * structure is passed to a key creation function such as + * psa_import_key(), psa_generate_random_key(), + * psa_generate_derived_key() or psa_copy_key(). + * + * This function may be declared as `static` (i.e. without external + * linkage). This function may be provided as a function-like macro, + * but in this case it must evaluate each of its arguments exactly once. + * + * \param[out] attributes The attribute structure to write to. * \param lifetime The lifetime for the key. * If this is #PSA_KEY_LIFETIME_VOLATILE, the - * key will be volatile, and \p id is ignored. + * key will be volatile, and the key identifier + * attribute is reset to 0. */ -static void psa_make_key_persistent(psa_key_attributes_t *attributes, - psa_key_id_t id, - psa_key_lifetime_t lifetime); +static void psa_set_key_lifetime(psa_key_attributes_t *attributes, + psa_key_lifetime_t lifetime); /** Retrieve the key identifier from key attributes. * diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index f6bec2cf5f..df765711cb 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -279,12 +279,12 @@ static inline struct psa_key_attributes_s psa_key_attributes_init( void ) return( v ); } -static inline void psa_make_key_persistent(psa_key_attributes_t *attributes, - psa_key_id_t id, - psa_key_lifetime_t lifetime) +static inline void psa_set_key_id(psa_key_attributes_t *attributes, + psa_key_id_t id) { attributes->id = id; - attributes->lifetime = lifetime; + if( attributes->lifetime == PSA_KEY_LIFETIME_VOLATILE ) + attributes->lifetime = PSA_KEY_LIFETIME_PERSISTENT; } static inline psa_key_id_t psa_get_key_id( @@ -293,6 +293,14 @@ static inline psa_key_id_t psa_get_key_id( return( attributes->id ); } +static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes, + psa_key_lifetime_t lifetime) +{ + attributes->lifetime = lifetime; + if( lifetime == PSA_KEY_LIFETIME_VOLATILE ) + attributes->id = 0; +} + static inline psa_key_lifetime_t psa_get_key_lifetime( const psa_key_attributes_t *attributes) { diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h index d30af41410..e67fc60988 100644 --- a/include/psa/crypto_values.h +++ b/include/psa/crypto_values.h @@ -672,10 +672,8 @@ * Then you may create and use a key as follows: * - Set the key usage field using #PSA_ALG_ANY_HASH, for example: * ``` - * psa_key_policy_set_usage(&policy, - * PSA_KEY_USAGE_SIGN, //or PSA_KEY_USAGE_VERIFY - * PSA_xxx_SIGNATURE(PSA_ALG_ANY_HASH)); - * psa_set_key_policy(handle, &policy); + * psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN); // or VERIFY + * psa_set_key_algorithm(&attributes, PSA_xxx_SIGNATURE(PSA_ALG_ANY_HASH)); * ``` * - Import or generate key material. * - Call psa_asymmetric_sign() or psa_asymmetric_verify(), passing diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 752132a3df..991d91a3ee 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -4,6 +4,21 @@ static_checks: PSA key attributes structure attributes_set_get:0x6963:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CCM:PSA_KEY_TYPE_AES:128 +PSA key attributes: id only +persistence_attributes:0x1234:-1:-1:0x1234:PSA_KEY_LIFETIME_PERSISTENT + +PSA key attributes: lifetime=3 only +persistence_attributes:-1:3:-1:0:3 + +PSA key attributes: id then back to volatile +persistence_attributes:0x1234:PSA_KEY_LIFETIME_VOLATILE:-1:0:PSA_KEY_LIFETIME_VOLATILE + +PSA key attributes: id then lifetime +persistence_attributes:0x1234:3:-1:0x1234:3 + +PSA key attributes: lifetime then id +persistence_attributes:0x1234:3:0x1235:0x1235:3 + PSA import/export raw: 0 bytes import_export:"":PSA_KEY_TYPE_RAW_DATA:0:PSA_KEY_USAGE_EXPORT:0:0:PSA_SUCCESS:1 diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 75b303ba4a..8b5773733b 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1098,7 +1098,7 @@ static int test_operations_on_invalid_handle( psa_key_handle_t handle ) size_t length; int ok = 0; - psa_make_key_persistent( &attributes, 0x6964, PSA_KEY_LIFETIME_PERSISTENT ); + psa_set_key_id( &attributes, 0x6964 ); psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT ); psa_set_key_algorithm( &attributes, PSA_ALG_CTR ); psa_set_key_type( &attributes, PSA_KEY_TYPE_AES ); @@ -1181,7 +1181,8 @@ void attributes_set_get( int id_arg, int lifetime_arg, TEST_EQUAL( psa_get_key_type( &attributes ), 0 ); TEST_EQUAL( psa_get_key_bits( &attributes ), 0 ); - psa_make_key_persistent( &attributes, id, lifetime ); + psa_set_key_id( &attributes, id ); + psa_set_key_lifetime( &attributes, lifetime ); psa_set_key_usage_flags( &attributes, usage_flags ); psa_set_key_algorithm( &attributes, alg ); psa_set_key_type( &attributes, type ); @@ -1205,6 +1206,29 @@ void attributes_set_get( int id_arg, int lifetime_arg, } /* END_CASE */ +/* BEGIN_CASE */ +void persistence_attributes( int id1_arg, int lifetime_arg, int id2_arg, + int expected_id_arg, int expected_lifetime_arg ) +{ + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t id1 = id1_arg; + psa_key_lifetime_t lifetime = lifetime_arg; + psa_key_id_t id2 = id2_arg; + psa_key_id_t expected_id = expected_id_arg; + psa_key_lifetime_t expected_lifetime = expected_lifetime_arg; + + if( id1_arg != -1 ) + psa_set_key_id( &attributes, id1 ); + if( lifetime_arg != -1 ) + psa_set_key_lifetime( &attributes, lifetime ); + if( id2_arg != -1 ) + psa_set_key_id( &attributes, id2 ); + + TEST_EQUAL( psa_get_key_id( &attributes ), expected_id ); + TEST_EQUAL( psa_get_key_lifetime( &attributes ), expected_lifetime ); +} +/* END_CASE */ + /* BEGIN_CASE */ void import( data_t *data, int type_arg, int attr_bits_arg, @@ -4877,7 +4901,7 @@ void persistent_key_load_key_from_storage( data_t *data, PSA_ASSERT( psa_crypto_init() ); - psa_make_key_persistent( &attributes, key_id, PSA_KEY_LIFETIME_PERSISTENT ); + psa_set_key_id( &attributes, key_id ); psa_set_key_usage_flags( &attributes, usage_flags ); psa_set_key_algorithm( &attributes, alg ); psa_set_key_type( &attributes, type ); diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function index 1ebab9c063..636f2603bd 100644 --- a/tests/suites/test_suite_psa_crypto_persistent_key.function +++ b/tests/suites/test_suite_psa_crypto_persistent_key.function @@ -96,7 +96,7 @@ void save_large_persistent_key( int data_too_large, int expected_status ) PSA_ASSERT( psa_crypto_init() ); - psa_make_key_persistent( &attributes, key_id, PSA_KEY_LIFETIME_PERSISTENT ); + psa_set_key_id( &attributes, key_id ); psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA ); TEST_EQUAL( psa_import_key( &attributes, data, data_length, &handle ), @@ -122,7 +122,7 @@ void persistent_key_destroy( int key_id_arg, int restart, PSA_ASSERT( psa_crypto_init() ); - psa_make_key_persistent( &attributes, key_id, PSA_KEY_LIFETIME_PERSISTENT ); + psa_set_key_id( &attributes, key_id ); psa_set_key_type( &attributes, first_type ); PSA_ASSERT( psa_import_key( &attributes, first_data->x, first_data->len, @@ -150,7 +150,7 @@ void persistent_key_destroy( int key_id_arg, int restart, PSA_ASSERT( psa_crypto_init() ); /* Create another key in the same slot */ - psa_make_key_persistent( &attributes, key_id, PSA_KEY_LIFETIME_PERSISTENT ); + psa_set_key_id( &attributes, key_id ); psa_set_key_type( &attributes, second_type ); PSA_ASSERT( psa_import_key( &attributes, second_data->x, second_data->len, &handle ) ); @@ -172,7 +172,7 @@ void persistent_key_import( int key_id_arg, int type_arg, data_t *data, PSA_ASSERT( psa_crypto_init() ); - psa_make_key_persistent( &attributes, key_id, PSA_KEY_LIFETIME_PERSISTENT ); + psa_set_key_id( &attributes, key_id ); psa_set_key_type( &attributes, type ); TEST_EQUAL( psa_import_key( &attributes, data->x, data->len, &handle ), expected_status ); @@ -224,7 +224,7 @@ void import_export_persistent_key( data_t *data, int type_arg, PSA_ASSERT( psa_crypto_init( ) ); - psa_make_key_persistent( &attributes, key_id, PSA_KEY_LIFETIME_PERSISTENT ); + psa_set_key_id( &attributes, key_id ); psa_set_key_type( &attributes, type ); psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT ); diff --git a/tests/suites/test_suite_psa_crypto_slot_management.function b/tests/suites/test_suite_psa_crypto_slot_management.function index 3e4f0cc404..5e594c27b3 100644 --- a/tests/suites/test_suite_psa_crypto_slot_management.function +++ b/tests/suites/test_suite_psa_crypto_slot_management.function @@ -143,7 +143,8 @@ void persistent_slot_lifecycle( int lifetime_arg, int id_arg, PSA_ASSERT( psa_crypto_init( ) ); /* Get a handle and import a key. */ - psa_make_key_persistent( &attributes, id, lifetime ); + psa_set_key_id( &attributes, id ); + psa_set_key_lifetime( &attributes, lifetime ); psa_set_key_type( &attributes, type ); psa_set_key_usage_flags( &attributes, usage_flags ); psa_set_key_algorithm( &attributes, alg ); @@ -221,7 +222,8 @@ void create_existent( int lifetime_arg, int id_arg, PSA_ASSERT( psa_crypto_init( ) ); /* Create a key. */ - psa_make_key_persistent( &attributes, id, lifetime ); + psa_set_key_id( &attributes, id ); + psa_set_key_lifetime( &attributes, lifetime ); psa_set_key_type( &attributes, type1 ); psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT ); psa_set_key_algorithm( &attributes, 0 ); @@ -298,7 +300,8 @@ void create_fail( int lifetime_arg, int id_arg, PSA_ASSERT( psa_crypto_init( ) ); - psa_make_key_persistent( &attributes, id, lifetime ); + psa_set_key_id( &attributes, id ); + psa_set_key_lifetime( &attributes, lifetime ); psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA ); TEST_EQUAL( psa_import_key( &attributes, material, sizeof( material ), &handle ), @@ -345,8 +348,10 @@ void copy_across_lifetimes( int source_lifetime_arg, int source_id_arg, /* Populate the source slot. */ if( source_lifetime != PSA_KEY_LIFETIME_VOLATILE ) - psa_make_key_persistent( &source_attributes, - source_id, source_lifetime ); + { + psa_set_key_id( &source_attributes, source_id ); + psa_set_key_lifetime( &source_attributes, source_lifetime ); + } psa_set_key_type( &source_attributes, source_type ); psa_set_key_usage_flags( &source_attributes, source_usage ); psa_set_key_algorithm( &source_attributes, source_alg ); @@ -358,8 +363,10 @@ void copy_across_lifetimes( int source_lifetime_arg, int source_id_arg, /* Prepare the target slot. */ if( target_lifetime != PSA_KEY_LIFETIME_VOLATILE ) - psa_make_key_persistent( &target_attributes, - target_id, target_lifetime ); + { + psa_set_key_id( &target_attributes, target_id ); + psa_set_key_lifetime( &target_attributes, target_lifetime ); + } psa_set_key_usage_flags( &target_attributes, target_usage ); psa_set_key_algorithm( &target_attributes, target_alg ); @@ -449,8 +456,10 @@ void copy_to_occupied( int source_lifetime_arg, int source_id_arg, /* Populate the source slot. */ if( source_lifetime != PSA_KEY_LIFETIME_VOLATILE ) - psa_make_key_persistent( &attributes, - source_id, source_lifetime ); + { + psa_set_key_id( &attributes, source_id ); + psa_set_key_lifetime( &attributes, source_lifetime ); + } psa_set_key_type( &attributes, source_type ); psa_set_key_usage_flags( &attributes, source_usage ); psa_set_key_algorithm( &attributes, source_alg ); @@ -465,7 +474,8 @@ void copy_to_occupied( int source_lifetime_arg, int source_id_arg, } else { - psa_make_key_persistent( &attributes1, target_id, target_lifetime ); + psa_set_key_id( &attributes1, target_id ); + psa_set_key_lifetime( &attributes1, target_lifetime ); psa_set_key_type( &attributes1, target_type ); psa_set_key_usage_flags( &attributes1, target_usage ); psa_set_key_algorithm( &attributes1, target_alg ); @@ -476,7 +486,8 @@ void copy_to_occupied( int source_lifetime_arg, int source_id_arg, PSA_ASSERT( psa_get_key_attributes( target_handle, &attributes1 ) ); /* Make a copy attempt. */ - psa_make_key_persistent( &attributes, target_id, target_lifetime ); + psa_set_key_id( &attributes, target_id ); + psa_set_key_lifetime( &attributes, target_lifetime ); TEST_EQUAL( psa_copy_key( source_handle, &attributes, &new_handle ), PSA_ERROR_ALREADY_EXISTS );