Skip to content

Individual setters for persistent key attributes #109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 43 additions & 14 deletions include/psa/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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(),
* psa_generate_derived_key() or psa_copy_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 overwrites any identifier and lifetime values
* previously set in \p attributes.
* 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 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.
*
Expand Down
16 changes: 12 additions & 4 deletions include/psa/crypto_struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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)
{
Expand Down
6 changes: 2 additions & 4 deletions include/psa/crypto_values.h
Original file line number Diff line number Diff line change
Expand Up @@ -663,10 +663,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
Expand Down
15 changes: 15 additions & 0 deletions tests/suites/test_suite_psa_crypto.data
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
30 changes: 27 additions & 3 deletions tests/suites/test_suite_psa_crypto.function
Original file line number Diff line number Diff line change
Expand Up @@ -1096,7 +1096,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 );
Expand Down Expand Up @@ -1179,7 +1179,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 );
Expand All @@ -1203,6 +1204,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,
Expand Down Expand Up @@ -4883,7 +4907,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 );
Expand Down
10 changes: 5 additions & 5 deletions tests/suites/test_suite_psa_crypto_persistent_key.function
Original file line number Diff line number Diff line change
Expand Up @@ -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, &handle,
Expand All @@ -123,7 +123,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, &handle,
Expand Down Expand Up @@ -153,7 +153,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, &handle,
second_data->x, second_data->len ) );
Expand All @@ -175,7 +175,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, &handle, data->x, data->len ),
expected_status );
Expand Down Expand Up @@ -228,7 +228,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 );

Expand Down
33 changes: 22 additions & 11 deletions tests/suites/test_suite_psa_crypto_slot_management.function
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,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 );
Expand Down Expand Up @@ -205,7 +206,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 );
Expand Down Expand Up @@ -283,7 +285,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, &handle,
material, sizeof( material ) ),
Expand Down Expand Up @@ -330,8 +333,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 );
Expand All @@ -342,8 +347,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 );

Expand Down Expand Up @@ -434,8 +441,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 );
Expand All @@ -449,7 +458,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 );
Expand All @@ -459,7 +469,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 );
Expand Down