mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2025-02-02 06:11:08 +00:00
psa: mgmt: Add key slot reuse
When looking for an empty key slot to store the description of a key, if all key slots are in use, reuse the first encountered and unaccessed key slot containing the description of a permanent key. Signed-off-by: Ronald Cron <ronald.cron@arm.com>
This commit is contained in:
parent
f291111007
commit
a5b894f7e2
|
@ -173,27 +173,62 @@ void psa_wipe_all_key_slots( void )
|
|||
psa_status_t psa_get_empty_key_slot( psa_key_id_t *volatile_key_id,
|
||||
psa_key_slot_t **p_slot )
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t slot_idx;
|
||||
psa_key_slot_t *selected_slot, *unaccessed_permanent_key_slot;
|
||||
|
||||
if( ! global_data.key_slots_initialized )
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
|
||||
for( slot_idx = PSA_KEY_SLOT_COUNT; slot_idx > 0; slot_idx-- )
|
||||
{
|
||||
*p_slot = &global_data.key_slots[ slot_idx - 1 ];
|
||||
if( ! psa_is_key_slot_occupied( *p_slot ) )
|
||||
{
|
||||
*volatile_key_id = PSA_KEY_ID_VOLATILE_MIN +
|
||||
( (psa_key_id_t)slot_idx ) - 1;
|
||||
|
||||
psa_increment_key_slot_access_count( *p_slot );
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
status = PSA_ERROR_BAD_STATE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
selected_slot = unaccessed_permanent_key_slot = NULL;
|
||||
for( slot_idx = 0; slot_idx < PSA_KEY_SLOT_COUNT; slot_idx++ )
|
||||
{
|
||||
psa_key_slot_t *slot = &global_data.key_slots[ slot_idx ];
|
||||
if( ! psa_is_key_slot_occupied( slot ) )
|
||||
{
|
||||
selected_slot = slot;
|
||||
break;
|
||||
}
|
||||
|
||||
if( ( unaccessed_permanent_key_slot == NULL ) &&
|
||||
( ! PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) ) &&
|
||||
( ! psa_is_key_slot_accessed( slot ) ) )
|
||||
unaccessed_permanent_key_slot = slot;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is no unused key slot and there is at least one unaccessed key
|
||||
* slot containing the description of a permament key, recycle the first
|
||||
* such key slot we encountered. If we need later on to operate on the
|
||||
* permanent key we evict now, we will reload its description from storage.
|
||||
*/
|
||||
if( ( selected_slot == NULL ) &&
|
||||
( unaccessed_permanent_key_slot != NULL ) )
|
||||
{
|
||||
selected_slot = unaccessed_permanent_key_slot;
|
||||
selected_slot->access_count = 1;
|
||||
psa_wipe_key_slot( selected_slot );
|
||||
}
|
||||
|
||||
if( selected_slot != NULL )
|
||||
{
|
||||
*volatile_key_id = PSA_KEY_ID_VOLATILE_MIN +
|
||||
( (psa_key_id_t)( selected_slot - global_data.key_slots ) );
|
||||
*p_slot = selected_slot;
|
||||
psa_increment_key_slot_access_count( selected_slot );
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
|
||||
error:
|
||||
*p_slot = NULL;
|
||||
return( PSA_ERROR_INSUFFICIENT_MEMORY );
|
||||
*volatile_key_id = 0;
|
||||
|
||||
return( status );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||
|
|
|
@ -186,3 +186,23 @@ invalid_handle:INVALID_HANDLE_HUGE:PSA_ERROR_INVALID_HANDLE:PSA_ERROR_INVALID_HA
|
|||
|
||||
Open many transient keys
|
||||
many_transient_keys:42
|
||||
|
||||
# Eviction from a key slot to be able to import a new permanent key.
|
||||
Key slot eviction to import a new permanent key
|
||||
key_slot_eviction_to_import_new_key:PSA_KEY_LIFETIME_PERSISTENT
|
||||
|
||||
# Eviction from a key slot to be able to import a new volatile key.
|
||||
Key slot eviction to import a new volatile key
|
||||
key_slot_eviction_to_import_new_key:PSA_KEY_LIFETIME_VOLATILE
|
||||
|
||||
# Check that non reusable key slots are not deleted/overwritten in case of key
|
||||
# slot starvation:
|
||||
# . An attempt to access a permanent key while all RAM key slots are occupied
|
||||
# by volatile keys fails and does not lead to volatile key data to be
|
||||
# spoiled.
|
||||
# . With all key slot in use with one containing a permanent key, an attempt
|
||||
# to copy the permanent key fails (the permanent key slot cannot be reclaimed
|
||||
# as it is accessed by the copy process) without the permament key data and
|
||||
# volatile key data being spoiled.
|
||||
Non reusable key slots integrity in case of key slot starvation
|
||||
non_reusable_key_slots_integrity_in_case_of_key_slot_starvation
|
||||
|
|
|
@ -877,3 +877,189 @@ exit:
|
|||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
|
||||
void key_slot_eviction_to_import_new_key( int lifetime_arg )
|
||||
{
|
||||
psa_key_lifetime_t lifetime = (psa_key_lifetime_t)lifetime_arg;
|
||||
size_t i;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
uint8_t exported[sizeof( size_t )];
|
||||
size_t exported_length;
|
||||
mbedtls_svc_key_id_t key, returned_key_id;
|
||||
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
|
||||
psa_set_key_algorithm( &attributes, 0 );
|
||||
psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );
|
||||
|
||||
/*
|
||||
* Create PSA_KEY_SLOT_COUNT persistent keys.
|
||||
*/
|
||||
for( i = 0; i < PSA_KEY_SLOT_COUNT; i++ )
|
||||
{
|
||||
key = mbedtls_svc_key_id_make( i, i + 1 );
|
||||
psa_set_key_id( &attributes, key );
|
||||
PSA_ASSERT( psa_import_key( &attributes,
|
||||
(uint8_t *) &i, sizeof( i ),
|
||||
&returned_key_id ) );
|
||||
TEST_ASSERT( mbedtls_svc_key_id_equal( returned_key_id, key ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new persistent or volatile key. When creating the key,
|
||||
* one of the description of the previously created persistent key
|
||||
* is removed from the RAM key slots. This makes room to store its
|
||||
* description in RAM.
|
||||
*/
|
||||
i = PSA_KEY_SLOT_COUNT;
|
||||
key = mbedtls_svc_key_id_make( i, i + 1 );
|
||||
psa_set_key_id( &attributes, key );
|
||||
|
||||
if( lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
||||
psa_set_key_lifetime( &attributes, PSA_KEY_LIFETIME_VOLATILE );
|
||||
|
||||
PSA_ASSERT( psa_import_key( &attributes,
|
||||
(uint8_t *) &i, sizeof( i ),
|
||||
&returned_key_id ) );
|
||||
if( lifetime != PSA_KEY_LIFETIME_VOLATILE )
|
||||
TEST_ASSERT( mbedtls_svc_key_id_equal( returned_key_id, key ) );
|
||||
|
||||
/*
|
||||
* Check that we can export all ( PSA_KEY_SLOT_COUNT + 1 ) keys,
|
||||
* that they have the expected value and destroy them. In that process,
|
||||
* the description of the persistent key that was evicted from the RAM
|
||||
* slots when creating the last key is restored in a RAM slot to export
|
||||
* its value.
|
||||
*/
|
||||
for( i = 0; i <= PSA_KEY_SLOT_COUNT; i++ )
|
||||
{
|
||||
if( i < PSA_KEY_SLOT_COUNT )
|
||||
key = mbedtls_svc_key_id_make( i, i + 1 );
|
||||
else
|
||||
key = returned_key_id;
|
||||
|
||||
PSA_ASSERT( psa_export_key( key,
|
||||
exported, sizeof( exported ),
|
||||
&exported_length ) );
|
||||
ASSERT_COMPARE( exported, exported_length,
|
||||
(uint8_t *) &i, sizeof( i ) );
|
||||
PSA_ASSERT( psa_destroy_key( key ) );
|
||||
}
|
||||
|
||||
exit:
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
|
||||
void non_reusable_key_slots_integrity_in_case_of_key_slot_starvation( )
|
||||
{
|
||||
psa_status_t status;
|
||||
size_t i;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
uint8_t exported[sizeof( size_t )];
|
||||
size_t exported_length;
|
||||
mbedtls_svc_key_id_t permanent_key = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
mbedtls_svc_key_id_t permanent_key2 = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
mbedtls_svc_key_id_t returned_key_id = MBEDTLS_SVC_KEY_ID_INIT;
|
||||
mbedtls_svc_key_id_t *keys = NULL;
|
||||
|
||||
TEST_ASSERT( PSA_KEY_SLOT_COUNT >= 1 );
|
||||
|
||||
ASSERT_ALLOC( keys, PSA_KEY_SLOT_COUNT );
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
psa_set_key_usage_flags( &attributes,
|
||||
PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY );
|
||||
psa_set_key_algorithm( &attributes, 0 );
|
||||
psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );
|
||||
|
||||
/*
|
||||
* Create a permanent key
|
||||
*/
|
||||
permanent_key = mbedtls_svc_key_id_make( 0x100, 0x205 );
|
||||
psa_set_key_id( &attributes, permanent_key );
|
||||
PSA_ASSERT( psa_import_key( &attributes,
|
||||
(uint8_t *) &permanent_key,
|
||||
sizeof( permanent_key ),
|
||||
&returned_key_id ) );
|
||||
TEST_ASSERT( mbedtls_svc_key_id_equal( returned_key_id, permanent_key ) );
|
||||
|
||||
/*
|
||||
* Create PSA_KEY_SLOT_COUNT volatile keys
|
||||
*/
|
||||
psa_set_key_lifetime( &attributes, PSA_KEY_LIFETIME_VOLATILE );
|
||||
for( i = 0; i < PSA_KEY_SLOT_COUNT; i++ )
|
||||
{
|
||||
PSA_ASSERT( psa_import_key( &attributes,
|
||||
(uint8_t *) &i, sizeof( i ),
|
||||
&keys[i]) );
|
||||
}
|
||||
psa_reset_key_attributes( &attributes );
|
||||
|
||||
/*
|
||||
* Check that we cannot access the persistent key as all slots are
|
||||
* occupied by volatile keys and the implementation needs to load the
|
||||
* persistent key description in a slot to be able to access it.
|
||||
*/
|
||||
status = psa_get_key_attributes( permanent_key, &attributes );
|
||||
TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_MEMORY );
|
||||
|
||||
/*
|
||||
* Check we can export the volatile key created last and that it has the
|
||||
* expected value. Then, destroy it.
|
||||
*/
|
||||
PSA_ASSERT( psa_export_key( keys[PSA_KEY_SLOT_COUNT - 1],
|
||||
exported, sizeof( exported ),
|
||||
&exported_length ) );
|
||||
i = PSA_KEY_SLOT_COUNT - 1;
|
||||
ASSERT_COMPARE( exported, exported_length, (uint8_t *) &i, sizeof( i ) );
|
||||
PSA_ASSERT( psa_destroy_key( keys[PSA_KEY_SLOT_COUNT - 1] ) );
|
||||
|
||||
/*
|
||||
* Check that we can now access the persistent key again.
|
||||
*/
|
||||
PSA_ASSERT( psa_get_key_attributes( permanent_key, &attributes ) );
|
||||
TEST_ASSERT( mbedtls_svc_key_id_equal( attributes.core.id,
|
||||
permanent_key ) );
|
||||
|
||||
/*
|
||||
* Check that we cannot copy the persistent key as all slots are occupied
|
||||
* by the permanent key and the volatile keys and the slot containing the
|
||||
* permanent key cannot be reclaimed as it contains the key to copy.
|
||||
*/
|
||||
permanent_key2 = mbedtls_svc_key_id_make( 0x100, 0x204 );
|
||||
psa_set_key_id( &attributes, permanent_key2 );
|
||||
status = psa_copy_key( permanent_key, &attributes, &returned_key_id );
|
||||
TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_MEMORY );
|
||||
|
||||
/*
|
||||
* Check we can export the remaining volatile keys and that they have the
|
||||
* expected values.
|
||||
*/
|
||||
for( i = 0; i < ( PSA_KEY_SLOT_COUNT - 1 ); i++ )
|
||||
{
|
||||
PSA_ASSERT( psa_export_key( keys[i],
|
||||
exported, sizeof( exported ),
|
||||
&exported_length ) );
|
||||
ASSERT_COMPARE( exported, exported_length,
|
||||
(uint8_t *) &i, sizeof( i ) );
|
||||
PSA_ASSERT( psa_destroy_key( keys[i] ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Check we can export the persistent key and that it have the expected
|
||||
* value.
|
||||
*/
|
||||
|
||||
PSA_ASSERT( psa_export_key( permanent_key, exported, sizeof( exported ),
|
||||
&exported_length ) );
|
||||
ASSERT_COMPARE( exported, exported_length,
|
||||
(uint8_t *) &permanent_key, sizeof( permanent_key ) );
|
||||
exit:
|
||||
psa_destroy_key( permanent_key );
|
||||
PSA_DONE( );
|
||||
mbedtls_free( keys );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
|
Loading…
Reference in a new issue