Skip to content

Commit 7a054e6

Browse files
Support slot_number attribute when creating a key
Allow the application to choose the slot number in a secure element, rather than always letting the driver choose. With this commit, any application may request any slot. In an implementation with isolation, it's up to the service to filter key creation requests and apply policies to limit which applications can request which slot.
1 parent d59da21 commit 7a054e6

File tree

4 files changed

+105
-15
lines changed

4 files changed

+105
-15
lines changed

library/psa_crypto.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,10 +1578,6 @@ static psa_status_t psa_start_key_creation(
15781578
* we can roll back to a state where the key doesn't exist. */
15791579
if( *p_drv != NULL )
15801580
{
1581-
/* Choosing a slot number is not supported yet. */
1582-
if( attributes->core.flags & MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER )
1583-
return( PSA_ERROR_NOT_SUPPORTED );
1584-
15851581
status = psa_find_se_slot_for_key( attributes, *p_drv,
15861582
&slot->data.se.slot_number );
15871583
if( status != PSA_SUCCESS )

library/psa_crypto_se.c

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,6 @@ psa_status_t psa_find_se_slot_for_key(
195195
psa_key_slot_number_t *slot_number )
196196
{
197197
psa_status_t status;
198-
psa_drv_se_allocate_key_t p_allocate = NULL;
199198

200199
/* If the lifetime is wrong, it's a bug in the library. */
201200
if( driver->lifetime != psa_get_key_lifetime( attributes ) )
@@ -204,17 +203,33 @@ psa_status_t psa_find_se_slot_for_key(
204203
/* If the driver doesn't support key creation in any way, give up now. */
205204
if( driver->methods->key_management == NULL )
206205
return( PSA_ERROR_NOT_SUPPORTED );
207-
p_allocate = driver->methods->key_management->p_allocate;
208206

209-
/* If the driver doesn't tell us how to allocate a slot, that's
210-
* not supported for the time being. */
211-
if( p_allocate == NULL )
212-
return( PSA_ERROR_NOT_SUPPORTED );
213-
214-
status = p_allocate( &driver->context,
215-
driver->internal.persistent_data,
216-
attributes,
217-
slot_number );
207+
if( psa_get_key_slot_number( attributes, slot_number ) == PSA_SUCCESS )
208+
{
209+
/* The application wants to use a specific slot. Allow it if
210+
* the driver supports it. On a system with isolation,
211+
* the crypto service must check that the application is
212+
* permitted to request this slot. */
213+
psa_drv_se_validate_slot_number_t p_validate_slot_number =
214+
driver->methods->key_management->p_validate_slot_number;
215+
if( p_validate_slot_number == NULL )
216+
return( PSA_ERROR_NOT_SUPPORTED );
217+
status = p_validate_slot_number( &driver->context, attributes,
218+
*slot_number );
219+
}
220+
else
221+
{
222+
/* The application didn't tell us which slot to use. Let the driver
223+
* choose. This is the normal case. */
224+
psa_drv_se_allocate_key_t p_allocate =
225+
driver->methods->key_management->p_allocate;
226+
if( p_allocate == NULL )
227+
return( PSA_ERROR_NOT_SUPPORTED );
228+
status = p_allocate( &driver->context,
229+
driver->internal.persistent_data,
230+
attributes,
231+
slot_number );
232+
}
218233
return( status );
219234
}
220235

tests/suites/test_suite_psa_crypto_se_driver_hal.data

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ key_creation_import_export:0:1
3939
SE key import-export, check after restart (slot 3)
4040
key_creation_import_export:3:1
4141

42+
Key creation in a specific slot (0)
43+
key_creation_in_chosen_slot:0:PSA_SUCCESS
44+
45+
Key creation in a specific slot (max)
46+
key_creation_in_chosen_slot:ARRAY_LENGTH( ram_slots ) - 1:PSA_SUCCESS
47+
48+
Key creation in a specific slot (too large)
49+
key_creation_in_chosen_slot:ARRAY_LENGTH( ram_slots ):PSA_ERROR_INVALID_ARGUMENT
50+
4251
Key creation smoke test: AES-CTR
4352
key_creation_smoke:PSA_KEY_TYPE_AES:PSA_ALG_CTR:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
4453

tests/suites/test_suite_psa_crypto_se_driver_hal.function

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,18 @@ static psa_status_t ram_allocate( psa_drv_se_context_t *context,
177177
return( PSA_ERROR_INSUFFICIENT_STORAGE );
178178
}
179179

180+
static psa_status_t ram_validate_slot_number(
181+
psa_drv_se_context_t *context,
182+
const psa_key_attributes_t *attributes,
183+
psa_key_slot_number_t slot_number )
184+
{
185+
(void) context;
186+
(void) attributes;
187+
if( slot_number >= ARRAY_LENGTH( ram_slots ) )
188+
return( PSA_ERROR_INVALID_ARGUMENT );
189+
return( PSA_SUCCESS );
190+
}
191+
180192

181193

182194
/****************************************************************/
@@ -536,6 +548,64 @@ exit:
536548
}
537549
/* END_CASE */
538550

551+
/* BEGIN_CASE */
552+
void key_creation_in_chosen_slot( int slot_arg,
553+
int expected_status_arg )
554+
{
555+
psa_key_slot_number_t wanted_slot = slot_arg;
556+
psa_status_t expected_status = expected_status_arg;
557+
psa_status_t status;
558+
psa_drv_se_t driver;
559+
psa_drv_se_key_management_t key_management;
560+
psa_key_lifetime_t lifetime = 2;
561+
psa_key_id_t id = 1;
562+
psa_key_handle_t handle = 0;
563+
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
564+
const uint8_t key_material[3] = {0xfa, 0xca, 0xde};
565+
566+
memset( &driver, 0, sizeof( driver ) );
567+
memset( &key_management, 0, sizeof( key_management ) );
568+
driver.hal_version = PSA_DRV_SE_HAL_VERSION;
569+
driver.key_management = &key_management;
570+
driver.persistent_data_size = sizeof( ram_slot_usage_t );
571+
key_management.p_validate_slot_number = ram_validate_slot_number;
572+
key_management.p_import = ram_import;
573+
key_management.p_destroy = ram_destroy;
574+
key_management.p_export = ram_export;
575+
576+
PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
577+
PSA_ASSERT( psa_crypto_init( ) );
578+
579+
/* Create a key. */
580+
psa_set_key_id( &attributes, id );
581+
psa_set_key_lifetime( &attributes, lifetime );
582+
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
583+
psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );
584+
psa_set_key_slot_number( &attributes, wanted_slot );
585+
status = psa_import_key( &attributes,
586+
key_material, sizeof( key_material ),
587+
&handle );
588+
TEST_EQUAL( status, expected_status );
589+
590+
if( status == PSA_SUCCESS )
591+
{
592+
/* Test that the key was created in the expected slot. */
593+
TEST_EQUAL( ram_slots[wanted_slot].type, PSA_KEY_TYPE_RAW_DATA );
594+
595+
/* Test that the key is reported with the correct attributes,
596+
* including the expected slot. */
597+
PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
598+
599+
PSA_ASSERT( psa_destroy_key( handle ) );
600+
}
601+
602+
exit:
603+
PSA_DONE( );
604+
ram_slots_reset( );
605+
psa_purge_storage( );
606+
}
607+
/* END_CASE */
608+
539609
/* BEGIN_CASE */
540610
void key_creation_smoke( int type_arg, int alg_arg,
541611
data_t *key_material )

0 commit comments

Comments
 (0)