Skip to content
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

Openless PSA crypto APIs implementation #3547

Merged
merged 55 commits into from
Nov 20, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
d2ed481
Split persistence and key id validation
ronald-cron-arm Jul 17, 2020
2a99315
Add volatile key identifiers
ronald-cron-arm Jul 17, 2020
98a54dd
psa: slot mgmt: Don't use handles to loop through slot array
ronald-cron-arm Jul 24, 2020
91e9515
Introduce PSA_KEY_HANDLE_INIT macro
ronald-cron-arm Jul 30, 2020
c26f8d4
Introduce psa_key_handle_is_null inline function
ronald-cron-arm Sep 1, 2020
47a8561
Introduce psa_key_handle_equal inline function
ronald-cron-arm Sep 1, 2020
c4d1b51
Define handles as key identifiers
ronald-cron-arm Jul 31, 2020
2d52eb2
tests: Fix invalid key identifier error code
ronald-cron-arm Sep 17, 2020
432e19c
tests: Fix error codes when using "invalid" handles
ronald-cron-arm Sep 17, 2020
4184107
tests: Fix checks of volatile key identifier
ronald-cron-arm Sep 17, 2020
e4f6d5c
tests: Fix persistent slot lifecycle tests
ronald-cron-arm Nov 9, 2020
cf56a0a
psa: Move from key handle to key identifier
ronald-cron-arm Aug 4, 2020
277a85f
Add psa_purge_key API
ronald-cron-arm Aug 4, 2020
c3623db
State PSA_CRYPTO_KEY_ID_ENCODES_OWNER and USE_PSA_CRYPTO incompatibility
ronald-cron-arm Oct 29, 2020
adc2ff2
Adapt programs to PSA openless APIs
ronald-cron-arm Sep 16, 2020
5425a21
tests: Adapt PSA tests to openless APIs
ronald-cron-arm Aug 4, 2020
3930997
tests: slot mgmt: Add purge checks in volatile key lifecycle test
ronald-cron-arm Oct 20, 2020
e7e86cf
tests: slot mgmt: Rename ways of invalidating keys
ronald-cron-arm Oct 20, 2020
994b805
tests: slot mgmt: Fix test data
ronald-cron-arm Oct 20, 2020
f67aefe
tests: slot mgmt: Add psa_purge_key testing
ronald-cron-arm Oct 20, 2020
fc9c556
Forbid volatile key identifiers for non volatile keys
ronald-cron-arm Oct 15, 2020
97c8ad5
Merge search of loaded volatile and persistent keys
ronald-cron-arm Oct 15, 2020
5134519
Fix close/purge of a key
ronald-cron-arm Oct 16, 2020
3c76a42
Improve psa_key_start_creation description
ronald-cron-arm Oct 16, 2020
6b5ff53
Add mbedtls_set_key_owner_id API
ronald-cron-arm Oct 16, 2020
390f607
Add tests checking owner of volatile keys
ronald-cron-arm Oct 16, 2020
f1ff9a8
tests: psa: Use PSA_KEY_LIFETIME_IS_VOLATILE where it should
ronald-cron-arm Oct 19, 2020
9678355
psa: Fix references to macros in comments
ronald-cron-arm Oct 19, 2020
4067d1c
psa: Improve key creation documentation
ronald-cron-arm Oct 19, 2020
d98059d
psa: Fix tests/handling of lifetime incompatible with location
ronald-cron-arm Oct 23, 2020
65f38a3
Add key id check when creating a volatile key
ronald-cron-arm Oct 23, 2020
54b9008
psa: Forbid creation/registration of keys in vendor range
ronald-cron-arm Oct 29, 2020
f95a2b1
psa: mgmt: Add key slot access counter
ronald-cron-arm Oct 22, 2020
0c3752a
psa: slot mgmt: Add unaccessed slots counter in stats
ronald-cron-arm Oct 30, 2020
ddd3d05
psa: Add access counter check in slot wipe
ronald-cron-arm Oct 30, 2020
f291111
psa: Do not reset a key slot under access
ronald-cron-arm Oct 29, 2020
a5b894f
psa: mgmt: Add key slot reuse
ronald-cron-arm Oct 21, 2020
77c89f5
Fix several typos
ronald-cron-arm Nov 10, 2020
19daca9
Prefer persistent over permanent
ronald-cron-arm Nov 10, 2020
7587ae4
Miscellaneous documentation improvements
ronald-cron-arm Nov 11, 2020
7d54f66
Miscellaneous coding style fixes
ronald-cron-arm Nov 11, 2020
f473d8b
psa: slot mgmt: Improve psa_search_key_in_slots implementation
ronald-cron-arm Nov 12, 2020
cbd7bea
psa: slot mgmt: Simplify psa_validate_key_id
ronald-cron-arm Nov 11, 2020
9e12f8f
tests: psa crypto: Fix lifetime_is_secure_element()
ronald-cron-arm Nov 13, 2020
c985114
programs: ssl: Fix printf parameter type cast
ronald-cron-arm Nov 13, 2020
4640c15
psa: Remove error message output
ronald-cron-arm Nov 13, 2020
cbf6a1d
psa: slot mgmt: Add access counter overflow check
ronald-cron-arm Nov 13, 2020
5097294
psa: Decrement slot access count when finalizing key creation
ronald-cron-arm Nov 14, 2020
81709fc
psa: Move key identifier return to psa_finish_key_creation()
ronald-cron-arm Nov 14, 2020
ab79bd2
tests: slot mgmt: Improve key_slot_eviction_to_import_new_key test
ronald-cron-arm Nov 14, 2020
5c52292
psa: Rename functions to get a key slot
ronald-cron-arm Nov 14, 2020
1ad1eee
psa stats: Count locked slots instead of unlocked ones
ronald-cron-arm Nov 15, 2020
a3d9dac
Add change log
ronald-cron-arm Nov 15, 2020
1d12d87
Improve/fix documentation
ronald-cron-arm Nov 18, 2020
3a4f0e3
tests: psa: Reset key attributes where needed
ronald-cron-arm Nov 19, 2020
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
55 changes: 45 additions & 10 deletions library/psa_crypto_slot_management.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
{
status = PSA_ERROR_BAD_STATE;
goto error;
}

for( slot_idx = PSA_KEY_SLOT_COUNT; slot_idx > 0; slot_idx-- )
selected_slot = unaccessed_permanent_key_slot = NULL;
for( slot_idx = 0; slot_idx < PSA_KEY_SLOT_COUNT; slot_idx++ )
{
*p_slot = &global_data.key_slots[ slot_idx - 1 ];
if( ! psa_is_key_slot_occupied( *p_slot ) )
psa_key_slot_t *slot = &global_data.key_slots[ slot_idx ];
if( ! psa_is_key_slot_occupied( slot ) )
{
*volatile_key_id = PSA_KEY_ID_VOLATILE_MIN +
( (psa_key_id_t)slot_idx ) - 1;
selected_slot = slot;
break;
}
gilles-peskine-arm marked this conversation as resolved.
Show resolved Hide resolved

psa_increment_key_slot_access_count( *p_slot );
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;
}

return( PSA_SUCCESS );
}
/*
* 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
gilles-peskine-arm marked this conversation as resolved.
Show resolved Hide resolved
* such key slot we encountered. If we need later on to operate on the
gilles-peskine-arm marked this conversation as resolved.
Show resolved Hide resolved
* 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)
Expand Down
20 changes: 20 additions & 0 deletions tests/suites/test_suite_psa_crypto_slot_management.data
Original file line number Diff line number Diff line change
Expand Up @@ -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
186 changes: 186 additions & 0 deletions tests/suites/test_suite_psa_crypto_slot_management.function
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* one of the description of the previously created persistent key
* one of the descriptions of the previously created persistent keys

* 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 );
gilles-peskine-arm marked this conversation as resolved.
Show resolved Hide resolved

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 ) );
gilles-peskine-arm marked this conversation as resolved.
Show resolved Hide resolved

/*
* 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 */