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/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index f0e4782..99bb063 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -186,6 +186,9 @@
  * \retval #PSA_ERROR_ALREADY_EXISTS
  *         There is already a key with the identifier specified in
  *         \p attributes.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         The secure element driver for the specified lifetime does not
+ *         support registering a key.
  * \retval #PSA_ERROR_INVALID_ARGUMENT
  *         \p attributes specifies a lifetime which is not located
  *         in a secure element.
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
diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal.data b/tests/suites/test_suite_psa_crypto_se_driver_hal.data
index 53e3fc5..1b0ef04 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal.data
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.data
@@ -121,23 +121,23 @@
 generate_key_smoke:PSA_KEY_TYPE_HMAC:256:PSA_ALG_HMAC( PSA_ALG_SHA_256 )
 
 Key registration: smoke test
-register_key_smoke_test:MIN_DRIVER_LIFETIME:-1:PSA_SUCCESS
-
-Key registration: invalid lifetime (volatile)
-register_key_smoke_test:PSA_KEY_LIFETIME_VOLATILE:-1:PSA_ERROR_INVALID_ARGUMENT
-
-Key registration: invalid lifetime (internal storage)
-register_key_smoke_test:PSA_KEY_LIFETIME_PERSISTENT:-1:PSA_ERROR_INVALID_ARGUMENT
-
-Key registration: invalid lifetime (no registered driver)
-register_key_smoke_test:MIN_DRIVER_LIFETIME + 1:-1:PSA_ERROR_INVALID_ARGUMENT
-
-Key registration: with driver validation (accepted)
 register_key_smoke_test:MIN_DRIVER_LIFETIME:1:PSA_SUCCESS
 
-Key registration: with driver validation (rejected)
+Key registration: invalid lifetime (volatile)
+register_key_smoke_test:PSA_KEY_LIFETIME_VOLATILE:1:PSA_ERROR_INVALID_ARGUMENT
+
+Key registration: invalid lifetime (internal storage)
+register_key_smoke_test:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_ERROR_INVALID_ARGUMENT
+
+Key registration: invalid lifetime (no registered driver)
+register_key_smoke_test:MIN_DRIVER_LIFETIME + 1:1:PSA_ERROR_INVALID_ARGUMENT
+
+Key registration: rejected
 register_key_smoke_test:MIN_DRIVER_LIFETIME:0:PSA_ERROR_NOT_PERMITTED
 
+Key registration: not supported
+register_key_smoke_test:MIN_DRIVER_LIFETIME:-1:PSA_ERROR_NOT_SUPPORTED
+
 Import-sign-verify: sign in driver, ECDSA
 depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
 sign_verify:SIGN_IN_DRIVER_AND_PARALLEL_CREATION:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP256R1 ):PSA_ALG_ECDSA_ANY:0:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":"54686973206973206e6f74206120686173682e"