Merge pull request #3996 from stevew817/feature/allow_reading_external_keys
Allow loading external wrapped keys
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index acb4f8e..39144a3 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -2358,6 +2358,15 @@
}
else
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
+ if( psa_key_lifetime_is_external( psa_get_key_lifetime( attributes ) ) )
+ {
+ /* Importing a key with external lifetime through the driver wrapper
+ * interface is not yet supported. Return as if this was an invalid
+ * lifetime. */
+ status = PSA_ERROR_INVALID_ARGUMENT;
+ goto exit;
+ }
+ else
{
status = psa_import_key_into_slot( slot, data, data_length );
if( status != PSA_SUCCESS )
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index 4c4ad03..39d6dbb 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -248,7 +248,11 @@
goto exit;
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
- if( psa_key_lifetime_is_external( slot->attr.lifetime ) )
+ /* Special handling is required for loading keys associated with a
+ * dynamically registered SE interface. */
+ const psa_drv_se_t *drv;
+ psa_drv_se_context_t *drv_context;
+ if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) )
{
psa_se_key_data_storage_t *data;
if( key_data_length != sizeof( *data ) )
@@ -259,14 +263,13 @@
data = (psa_se_key_data_storage_t *) key_data;
memcpy( &slot->data.se.slot_number, &data->slot_number,
sizeof( slot->data.se.slot_number ) );
+
+ status = PSA_SUCCESS;
+ goto exit;
}
- else
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
- {
- status = psa_copy_key_material_into_slot( slot, key_data, key_data_length );
- if( status != PSA_SUCCESS )
- goto exit;
- }
+
+ status = psa_copy_key_material_into_slot( slot, key_data, key_data_length );
exit:
psa_free_persistent_key_data( key_data, key_data_length );
@@ -343,19 +346,26 @@
if ( psa_key_lifetime_is_external( lifetime ) )
{
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+ /* Check whether a driver is registered against this lifetime */
psa_se_drv_table_entry_t *driver = psa_get_se_driver_entry( lifetime );
- if( driver == NULL )
- return( PSA_ERROR_INVALID_ARGUMENT );
- else
+ if( driver != NULL )
{
if (p_drv != NULL)
*p_drv = driver;
return( PSA_SUCCESS );
}
-#else
+#else /* MBEDTLS_PSA_CRYPTO_SE_C */
(void) p_drv;
- return( PSA_ERROR_INVALID_ARGUMENT );
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
+
+#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS)
+ /* Key location for external keys gets checked by the wrapper */
+ return( PSA_SUCCESS );
+#else /* MBEDTLS_PSA_CRYPTO_DRIVERS */
+ /* No support for external lifetimes at all, or dynamic interface
+ * did not find driver for requested lifetime. */
+ return( PSA_ERROR_INVALID_ARGUMENT );
+#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS */
}
else
/* Local/internal keys are always valid */
diff --git a/library/psa_crypto_storage.c b/library/psa_crypto_storage.c
index 1ebd20e..10a1ad3 100644
--- a/library/psa_crypto_storage.c
+++ b/library/psa_crypto_storage.c
@@ -374,8 +374,12 @@
uint8_t *storage_data;
psa_status_t status;
+ /* All keys saved to persistent storage always have a key context */
+ if( data == NULL || data_length == 0 )
+ return( PSA_ERROR_INVALID_ARGUMENT );
+
if( data_length > PSA_CRYPTO_MAX_STORAGE_SIZE )
- return PSA_ERROR_INSUFFICIENT_STORAGE;
+ return( PSA_ERROR_INSUFFICIENT_STORAGE );
storage_data_length = data_length + sizeof( psa_persistent_key_storage_format );
storage_data = mbedtls_calloc( 1, storage_data_length );
@@ -426,6 +430,11 @@
status = psa_parse_key_data_from_storage( loaded_data, storage_data_length,
data, data_length, attr );
+ /* All keys saved to persistent storage always have a key context */
+ if( status == PSA_SUCCESS &&
+ ( *data == NULL || *data_length == 0 ) )
+ status = PSA_ERROR_STORAGE_FAILURE;
+
exit:
mbedtls_free( loaded_data );
return( status );
diff --git a/library/psa_crypto_storage.h b/library/psa_crypto_storage.h
index fbc94fc..1d597c0 100644
--- a/library/psa_crypto_storage.h
+++ b/library/psa_crypto_storage.h
@@ -86,6 +86,9 @@
* already occupied non-persistent key, as well as ensuring the key data is
* validated.
*
+ * Note: This function will only succeed for key buffers which are not
+ * empty. If passed a NULL pointer or zero-length, the function will fail
+ * with #PSA_ERROR_INVALID_ARGUMENT.
*
* \param[in] attr The attributes of the key to save.
* The key identifier field in the attributes
@@ -94,6 +97,7 @@
* \param data_length The number of bytes that make up the key data.
*
* \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
* \retval #PSA_ERROR_STORAGE_FAILURE
@@ -111,9 +115,10 @@
* metadata and writes them to the appropriate output parameters.
*
* Note: This function allocates a buffer and returns a pointer to it through
- * the data parameter. psa_free_persistent_key_data() must be called after
- * this function to zeroize and free this buffer, regardless of whether this
- * function succeeds or fails.
+ * the data parameter. On successful return, the pointer is guaranteed to be
+ * valid and the buffer contains at least one byte of data.
+ * psa_free_persistent_key_data() must be called on the data buffer
+ * afterwards to zeroize and free this buffer.
*
* \param[in,out] attr On input, the key identifier field identifies
* the key to load. Other fields are ignored.
diff --git a/tests/suites/test_suite_psa_crypto_slot_management.data b/tests/suites/test_suite_psa_crypto_slot_management.data
index 396cdfb..ece8f14 100644
--- a/tests/suites/test_suite_psa_crypto_slot_management.data
+++ b/tests/suites/test_suite_psa_crypto_slot_management.data
@@ -107,10 +107,15 @@
depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
open_fail:1:PSA_ERROR_DOES_NOT_EXIST
-Create failure: invalid lifetime
-create_fail:0x7fffffff:0:PSA_ERROR_INVALID_ARGUMENT
+Create failure: invalid lifetime for a persistent key
+depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
+create_fail:0x7fffffff:1:PSA_ERROR_INVALID_ARGUMENT
-Create failure: invalid key id (0)
+Create failure: invalid lifetime for a volatile key
+depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
+create_fail:0x7fffff00:0:PSA_ERROR_INVALID_ARGUMENT
+
+Create failure: invalid key id (0) for a persistent key
depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
create_fail:PSA_KEY_LIFETIME_PERSISTENT:0:PSA_ERROR_INVALID_HANDLE