SE support: Use a transaction when registering a key
When registering a key in a secure element, go through the transaction
mechanism. This makes the code simpler, at the expense of a few extra
storage operations. Given that registering a key is typically very
rare over the lifetime of a device, this is an acceptable loss.
Drivers must now have a p_validate_slot_number method, otherwise
registering a key is not possible. This reduces the risk that due to a
mistake during the integration of a device, an application might claim
a slot in a way that is not supported by the driver.
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index b9ea00f..90158f8 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -1579,7 +1579,7 @@
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
/* For a key in a secure element, we need to do three things
- * when creating a key (but not when registering an existing key):
+ * when creating or registering a key:
* create the key file in internal storage, create the
* key inside the secure element, and update the driver's
* persistent data. Start a transaction that will encompass these
@@ -1592,7 +1592,7 @@
* secure element driver updates its persistent state, but we do not yet
* save the driver's persistent state, so that if the power fails,
* we can roll back to a state where the key doesn't exist. */
- if( *p_drv != NULL && method != PSA_KEY_CREATION_REGISTER )
+ if( *p_drv != NULL )
{
status = psa_find_se_slot_for_key( attributes, method, *p_drv,
&slot->data.se.slot_number );
@@ -1609,6 +1609,12 @@
return( status );
}
}
+
+ if( *p_drv == NULL && method == PSA_KEY_CREATION_REGISTER )
+ {
+ /* Key registration only makes sense with a secure element. */
+ return( PSA_ERROR_INVALID_ARGUMENT );
+ }
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
return( status );
@@ -1883,7 +1889,6 @@
psa_status_t status;
psa_key_slot_t *slot = NULL;
psa_se_drv_table_entry_t *driver = NULL;
- const psa_drv_se_t *drv;
psa_key_handle_t handle = 0;
/* Leaving attributes unspecified is not currently supported.
@@ -1900,37 +1905,6 @@
if( status != PSA_SUCCESS )
goto exit;
- if( driver == NULL )
- {
- status = PSA_ERROR_INVALID_ARGUMENT;
- goto exit;
- }
- drv = psa_get_se_driver_methods( driver );
-
- if ( psa_get_key_slot_number( attributes,
- &slot->data.se.slot_number ) != PSA_SUCCESS )
- {
- /* The application didn't specify a slot number. This doesn't
- * make sense when registering a slot. */
- status = PSA_ERROR_INVALID_ARGUMENT;
- goto exit;
- }
-
- /* If the driver has a slot number validation method, call it.
- * If it doesn't, it means the secure element is unable to validate
- * anything and so we have to trust the application. */
- if( drv->key_management != NULL &&
- drv->key_management->p_validate_slot_number != NULL )
- {
- status = drv->key_management->p_validate_slot_number(
- psa_get_se_driver_context( driver ),
- attributes,
- PSA_KEY_CREATION_REGISTER,
- slot->data.se.slot_number );
- if( status != PSA_SUCCESS )
- goto exit;
- }
-
status = psa_finish_key_creation( slot, driver );
exit:
diff --git a/library/psa_crypto_se.c b/library/psa_crypto_se.c
index 523c621..2cda4cc 100644
--- a/library/psa_crypto_se.c
+++ b/library/psa_crypto_se.c
@@ -225,6 +225,12 @@
attributes, method,
*slot_number );
}
+ else if( method == PSA_KEY_CREATION_REGISTER )
+ {
+ /* The application didn't specify a slot number. This doesn't
+ * make sense when registering a slot. */
+ return( PSA_ERROR_INVALID_ARGUMENT );
+ }
else
{
/* The application didn't tell us which slot to use. Let the driver