Update SE support to pass a location when registering a driver

Now that lifetimes have structures and secure element drivers handle
all the lifetimes with a certain location, update driver registration
to take a location as argument rather than a lifetime.

This commit updates the Mbed TLS implementation.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
Gilles Peskine 2020-05-10 00:44:04 +02:00
parent 52ac958d6b
commit 2b04f4683b
2 changed files with 40 additions and 41 deletions

View file

@ -66,7 +66,7 @@ typedef struct
struct psa_se_drv_table_entry_s struct psa_se_drv_table_entry_s
{ {
psa_key_lifetime_t lifetime; psa_key_location_t location;
const psa_drv_se_t *methods; const psa_drv_se_t *methods;
union union
{ {
@ -81,15 +81,16 @@ psa_se_drv_table_entry_t *psa_get_se_driver_entry(
psa_key_lifetime_t lifetime ) psa_key_lifetime_t lifetime )
{ {
size_t i; size_t i;
/* In the driver table, lifetime=0 means an entry that isn't used. psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( lifetime );
* No driver has a lifetime of 0 because it's a reserved value /* In the driver table, location=0 means an entry that isn't used.
* (which designates volatile keys). Make sure we never return * No driver has a location of 0 because it's a reserved value
* a driver entry for lifetime 0. */ * (which designates transparent keys). Make sure we never return
if( lifetime == 0 ) * a driver entry for location 0. */
if( location == 0 )
return( NULL ); return( NULL );
for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ ) for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
{ {
if( driver_table[i].lifetime == lifetime ) if( driver_table[i].location == location )
return( &driver_table[i] ); return( &driver_table[i] );
} }
return( NULL ); return( NULL );
@ -129,7 +130,7 @@ static psa_status_t psa_get_se_driver_its_file_uid(
const psa_se_drv_table_entry_t *driver, const psa_se_drv_table_entry_t *driver,
psa_storage_uid_t *uid ) psa_storage_uid_t *uid )
{ {
if( driver->lifetime > PSA_MAX_SE_LIFETIME ) if( driver->location > PSA_MAX_SE_LOCATION )
return( PSA_ERROR_NOT_SUPPORTED ); return( PSA_ERROR_NOT_SUPPORTED );
#if SIZE_MAX > UINT32_MAX #if SIZE_MAX > UINT32_MAX
@ -139,7 +140,7 @@ static psa_status_t psa_get_se_driver_its_file_uid(
#endif #endif
/* See the documentation of PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE. */ /* See the documentation of PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE. */
*uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + driver->lifetime; *uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + driver->location;
return( PSA_SUCCESS ); return( PSA_SUCCESS );
} }
@ -186,12 +187,12 @@ psa_status_t psa_save_se_persistent_data(
0 ) ); 0 ) );
} }
psa_status_t psa_destroy_se_persistent_data( psa_key_lifetime_t lifetime ) psa_status_t psa_destroy_se_persistent_data( psa_key_location_t location )
{ {
psa_storage_uid_t uid; psa_storage_uid_t uid;
if( lifetime > PSA_MAX_SE_LIFETIME ) if( location > PSA_MAX_SE_LOCATION )
return( PSA_ERROR_NOT_SUPPORTED ); return( PSA_ERROR_NOT_SUPPORTED );
uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + lifetime; uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + location;
return( psa_its_remove( uid ) ); return( psa_its_remove( uid ) );
} }
@ -202,9 +203,11 @@ psa_status_t psa_find_se_slot_for_key(
psa_key_slot_number_t *slot_number ) psa_key_slot_number_t *slot_number )
{ {
psa_status_t status; psa_status_t status;
psa_key_location_t key_location =
PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime( attributes ) );
/* If the lifetime is wrong, it's a bug in the library. */ /* If the location is wrong, it's a bug in the library. */
if( driver->lifetime != psa_get_key_lifetime( attributes ) ) if( driver->location != key_location )
return( PSA_ERROR_CORRUPTION_DETECTED ); return( PSA_ERROR_CORRUPTION_DETECTED );
/* If the driver doesn't support key creation in any way, give up now. */ /* If the driver doesn't support key creation in any way, give up now. */
@ -278,7 +281,7 @@ psa_status_t psa_init_all_se_drivers( void )
for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ ) for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
{ {
psa_se_drv_table_entry_t *driver = &driver_table[i]; psa_se_drv_table_entry_t *driver = &driver_table[i];
if( driver->lifetime == 0 ) if( driver->location == 0 )
continue; /* skipping unused entry */ continue; /* skipping unused entry */
const psa_drv_se_t *methods = psa_get_se_driver_methods( driver ); const psa_drv_se_t *methods = psa_get_se_driver_methods( driver );
if( methods->p_init != NULL ) if( methods->p_init != NULL )
@ -286,7 +289,7 @@ psa_status_t psa_init_all_se_drivers( void )
psa_status_t status = methods->p_init( psa_status_t status = methods->p_init(
&driver->u.context, &driver->u.context,
driver->u.internal.persistent_data, driver->u.internal.persistent_data,
driver->lifetime ); driver->location );
if( status != PSA_SUCCESS ) if( status != PSA_SUCCESS )
return( status ); return( status );
status = psa_save_se_persistent_data( driver ); status = psa_save_se_persistent_data( driver );
@ -304,7 +307,7 @@ psa_status_t psa_init_all_se_drivers( void )
/****************************************************************/ /****************************************************************/
psa_status_t psa_register_se_driver( psa_status_t psa_register_se_driver(
psa_key_lifetime_t lifetime, psa_key_location_t location,
const psa_drv_se_t *methods) const psa_drv_se_t *methods)
{ {
size_t i; size_t i;
@ -313,33 +316,30 @@ psa_status_t psa_register_se_driver(
if( methods->hal_version != PSA_DRV_SE_HAL_VERSION ) if( methods->hal_version != PSA_DRV_SE_HAL_VERSION )
return( PSA_ERROR_NOT_SUPPORTED ); return( PSA_ERROR_NOT_SUPPORTED );
/* Driver table entries are 0-initialized. 0 is not a valid driver /* Driver table entries are 0-initialized. 0 is not a valid driver
* lifetime because it means a volatile key. */ * location because it means a transparent key. */
#if defined(static_assert) #if defined(static_assert)
static_assert( PSA_KEY_LIFETIME_VOLATILE == 0, static_assert( PSA_KEY_LOCATION_LOCAL_STORAGE == 0,
"Secure element support requires 0 to mean a volatile key" ); "Secure element support requires 0 to mean a local key" );
#endif #endif
if( lifetime == PSA_KEY_LIFETIME_VOLATILE || if( location == PSA_KEY_LOCATION_LOCAL_STORAGE )
lifetime == PSA_KEY_LIFETIME_PERSISTENT )
{
return( PSA_ERROR_INVALID_ARGUMENT ); return( PSA_ERROR_INVALID_ARGUMENT );
} if( location > PSA_MAX_SE_LOCATION )
if( lifetime > PSA_MAX_SE_LIFETIME )
return( PSA_ERROR_NOT_SUPPORTED ); return( PSA_ERROR_NOT_SUPPORTED );
for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ ) for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
{ {
if( driver_table[i].lifetime == 0 ) if( driver_table[i].location == 0 )
break; break;
/* Check that lifetime isn't already in use up to the first free /* Check that location isn't already in use up to the first free
* entry. Since entries are created in order and never deleted, * entry. Since entries are created in order and never deleted,
* there can't be a used entry after the first free entry. */ * there can't be a used entry after the first free entry. */
if( driver_table[i].lifetime == lifetime ) if( driver_table[i].location == location )
return( PSA_ERROR_ALREADY_EXISTS ); return( PSA_ERROR_ALREADY_EXISTS );
} }
if( i == PSA_MAX_SE_DRIVERS ) if( i == PSA_MAX_SE_DRIVERS )
return( PSA_ERROR_INSUFFICIENT_MEMORY ); return( PSA_ERROR_INSUFFICIENT_MEMORY );
driver_table[i].lifetime = lifetime; driver_table[i].location = location;
driver_table[i].methods = methods; driver_table[i].methods = methods;
driver_table[i].u.internal.persistent_data_size = driver_table[i].u.internal.persistent_data_size =
methods->persistent_data_size; methods->persistent_data_size;

View file

@ -31,31 +31,30 @@
#include "psa/crypto.h" #include "psa/crypto.h"
#include "psa/crypto_se_driver.h" #include "psa/crypto_se_driver.h"
/** The maximum lifetime value that this implementation supports /** The maximum location value that this implementation supports
* for a secure element. * for a secure element.
* *
* This is not a characteristic that each PSA implementation has, but a * This is not a characteristic that each PSA implementation has, but a
* limitation of the current implementation due to the constraints imposed * limitation of the current implementation due to the constraints imposed
* by storage. See #PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE. * by storage. See #PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE.
* *
* The minimum lifetime value for a secure element is 2, like on any * The minimum location value for a secure element is 1, like on any
* PSA implementation (0=volatile and 1=internal-storage are taken). * PSA implementation (0 means a transparent key).
*/ */
#define PSA_MAX_SE_LIFETIME 255 #define PSA_MAX_SE_LOCATION 255
/** The base of the range of ITS file identifiers for secure element /** The base of the range of ITS file identifiers for secure element
* driver persistent data. * driver persistent data.
* *
* We use a slice of the implemenation reserved range 0xffff0000..0xffffffff, * We use a slice of the implemenation reserved range 0xffff0000..0xffffffff,
* specifically the range 0xfffffe00..0xfffffeff. The length of this range * specifically the range 0xfffffe00..0xfffffeff. The length of this range
* drives the value of #PSA_MAX_SE_LIFETIME. * drives the value of #PSA_MAX_SE_LOCATION. The identifier 0xfffffe00 is
* The identifiers 0xfffffe00 and 0xfffffe01 are actually not used since * actually not used since it corresponds to #PSA_KEY_LOCATION_LOCAL_STORAGE
* they correspond to #PSA_KEY_LIFETIME_VOLATILE and * which doesn't have a driver.
* #PSA_KEY_LIFETIME_PERSISTENT which don't have a driver.
*/ */
#define PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE ( (psa_key_id_t) 0xfffffe00 ) #define PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE ( (psa_key_id_t) 0xfffffe00 )
/** The maximum number of registered secure element driver lifetimes. */ /** The maximum number of registered secure element driver locations. */
#define PSA_MAX_SE_DRIVERS 4 #define PSA_MAX_SE_DRIVERS 4
/** Unregister all secure element drivers. /** Unregister all secure element drivers.
@ -173,10 +172,10 @@ psa_status_t psa_save_se_persistent_data(
* *
* This is currently only used for testing. * This is currently only used for testing.
* *
* \param[in] lifetime The driver lifetime whose persistent data should * \param[in] location The location identifier for the driver whose
* be erased. * persistent data is to be erased.
*/ */
psa_status_t psa_destroy_se_persistent_data( psa_key_lifetime_t lifetime ); psa_status_t psa_destroy_se_persistent_data( psa_key_location_t location );
/** The storage representation of a key whose data is in a secure element. /** The storage representation of a key whose data is in a secure element.