Skip to content

Commit 7eabf6c

Browse files
Allow drivers to choose key slots
Add a function that allows the driver to allocate a key slot, and a callback function implemented in the core that allows the driver to search the table of occupied slots.
1 parent 47b726b commit 7eabf6c

File tree

4 files changed

+120
-10
lines changed

4 files changed

+120
-10
lines changed

include/psa/crypto_se_driver.h

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,49 @@ typedef struct {
677677
} psa_drv_se_aead_t;
678678
/**@}*/
679679

680+
/** \defgroup se_slot_usage Secure element slot usage mask
681+
*/
682+
/**@{*/
683+
684+
/** The type of slot usage data for a driver.
685+
*
686+
* A driver can use this data to keep track of which slot numbers are in use
687+
* and which are available for new keys. The core stores this data to
688+
* internal persistent storage.
689+
*
690+
* The representation of this type is opaque. To access it,
691+
* the driver can call psa_drv_cb_find_free_slot().
692+
*/
693+
typedef struct psa_drv_se_slot_usage_s psa_drv_se_slot_usage_t;
694+
695+
/** Callback function to find a free slot within a range.
696+
*
697+
* The PSA Crypto core provides this function to access the opaque
698+
* data type that represents the slot usage.
699+
*
700+
* \param[in] slot_usage The opaque data structure containing the
701+
* driver's slot usage table.
702+
* \param from The start of the range.
703+
* It is included in the search.
704+
* \param before The end of the range.
705+
* It is not included in the search.
706+
* \param[out] found On success, a free slot number such that
707+
* `from <= found < before`.
708+
*
709+
* \retval #PSA_SUCCESS
710+
* Success. \c *found contains a slot number which is between
711+
* \p from and \p before-1 inclusive and which is currently free.
712+
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
713+
* All slots in the indicated range are occupied.
714+
*/
715+
psa_status_t psa_drv_cb_find_free_slot(
716+
const psa_drv_se_slot_usage_t *slot_usage,
717+
psa_key_slot_number_t from,
718+
psa_key_slot_number_t before,
719+
psa_key_slot_number_t *found);
720+
721+
/**@}*/
722+
680723
/** \defgroup se_key_management Secure Element Key Management
681724
* Currently, key management is limited to importing keys in the clear,
682725
* destroying keys, and exporting keys in the clear.
@@ -685,6 +728,32 @@ typedef struct {
685728
*/
686729
/**@{*/
687730

731+
/* This type is documented in crypto.h. As far as drivers are concerned,
732+
* this is an opaque type. */
733+
typedef struct psa_key_attributes_s psa_key_attributes_t;
734+
735+
/** \brief A function that allocates a slot number for a key.
736+
*
737+
* This function is typically implemented as one or more calls to
738+
* psa_drv_cb_find_free_slot(), with bounds determined by the key
739+
* attributes and the secure element configuration.
740+
*
741+
* \param[in] attributes Attributes of the key.
742+
* \param[in] slot_usage Slot usage data of the driver.
743+
* \param[out] key_slot Slot where the key will be stored.
744+
* This must be a valid slot for a key of the
745+
* chosen type. It must be unoccupied.
746+
*
747+
* \retval #PSA_SUCCESS
748+
* Success.
749+
* \retval #PSA_ERROR_NOT_SUPPORTED
750+
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
751+
*/
752+
typedef psa_status_t (*psa_drv_se_allocate_key_t)(
753+
const psa_key_attributes_t *attributes,
754+
const psa_drv_se_slot_usage_t *slot_usage,
755+
psa_key_slot_number_t *key_slot);
756+
688757
/** \brief A function that imports a key into a secure element in binary format
689758
*
690759
* This function can support any output from psa_export_key(). Refer to the
@@ -815,6 +884,13 @@ typedef struct {
815884
* slots numbered 0 through `slot_count - 1`.
816885
*/
817886
psa_key_slot_number_t slot_count;
887+
/** Function that allocates a slot number.
888+
*
889+
* If the secure element has no constraints regarding which keys
890+
* can go into which slots, this should be \c NULL. In this case
891+
* the core will pick any free slot when creating a key.
892+
*/
893+
psa_drv_se_allocate_key_t p_allocate;
818894
/** Function that performs a key import operation */
819895
psa_drv_se_import_key_t p_import;
820896
/** Function that performs a generation */

library/psa_crypto_se.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@
4848
/* Driver lookup */
4949
/****************************************************************/
5050

51-
typedef struct psa_drv_se_slot_usage_s psa_drv_se_slot_usage_t;
52-
5351
typedef struct psa_se_drv_table_entry_s
5452
{
5553
psa_key_lifetime_t lifetime;
@@ -177,6 +175,8 @@ psa_status_t psa_find_se_slot_for_key(
177175
const psa_se_drv_table_entry_t *drv,
178176
psa_key_slot_number_t *slot_number )
179177
{
178+
psa_status_t status;
179+
180180
/* The maximum possible value of the type is never a valid slot number
181181
* because it's too large. (0 is valid.) */
182182
*slot_number = -1;
@@ -188,10 +188,20 @@ psa_status_t psa_find_se_slot_for_key(
188188
if( drv->methods->key_management == NULL )
189189
return( PSA_ERROR_NOT_SUPPORTED );
190190

191-
return( psa_drv_cb_find_free_slot(
192-
drv->slot_usage,
193-
0, drv->methods->key_management->slot_count,
194-
slot_number ) );
191+
if( drv->methods->key_management->p_allocate == NULL )
192+
{
193+
status = psa_drv_cb_find_free_slot(
194+
drv->slot_usage,
195+
0, drv->methods->key_management->slot_count,
196+
slot_number );
197+
}
198+
else
199+
{
200+
status = drv->methods->key_management->p_allocate( attributes,
201+
drv->slot_usage,
202+
slot_number );
203+
}
204+
return( status );
195205
}
196206

197207
psa_status_t psa_update_se_slot_usage(

tests/suites/test_suite_psa_crypto_se_driver_hal.data

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,11 @@ register_twice:3
2727
Register SE driver: maximum number of drivers
2828
register_max:
2929

30-
Key creation smoke test
31-
key_creation_import_export:
30+
Key creation smoke test (no p_allocate)
31+
key_creation_import_export:-1
32+
33+
Key creation smoke test (p_allocate allows all slots)
34+
key_creation_import_export:0
35+
36+
Key creation smoke test (p_allocate allows 1 slot)
37+
key_creation_import_export:ARRAY_LENGTH( ram_slots ) - 1

tests/suites/test_suite_psa_crypto_se_driver_hal.function

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@ typedef struct
2121
} ram_slot_t;
2222
static ram_slot_t ram_slots[16];
2323

24+
static uint8_t ram_min_slot = 0;
25+
2426
static void ram_slots_reset( void )
2527
{
2628
memset( ram_slots, 0, sizeof( ram_slots ) );
29+
ram_min_slot = 0;
2730
}
2831

2932
static psa_status_t ram_import( psa_key_slot_number_t slot_number,
@@ -71,6 +74,16 @@ psa_status_t ram_destroy( psa_key_slot_number_t slot_number )
7174
return( PSA_SUCCESS );
7275
}
7376

77+
psa_status_t ram_allocate( const psa_key_attributes_t *attributes,
78+
const psa_drv_se_slot_usage_t *slot_usage,
79+
psa_key_slot_number_t *slot_number )
80+
{
81+
(void) attributes;
82+
return( psa_drv_cb_find_free_slot( slot_usage,
83+
ram_min_slot, -1,
84+
slot_number ) );
85+
}
86+
7487
/* END_HEADER */
7588

7689
/* BEGIN_DEPENDENCIES
@@ -144,7 +157,7 @@ exit:
144157
/* END_CASE */
145158

146159
/* BEGIN_CASE */
147-
void key_creation_import_export( )
160+
void key_creation_import_export( int min_slot )
148161
{
149162
psa_drv_se_t driver;
150163
psa_drv_se_key_management_t key_management;
@@ -155,7 +168,7 @@ void key_creation_import_export( )
155168
const uint8_t key_material[3] = {0xfa, 0xca, 0xde};
156169
uint8_t exported[sizeof( key_material )];
157170
size_t exported_length;
158-
psa_key_slot_number_t expected_slot = 0;
171+
psa_key_slot_number_t expected_slot = ( min_slot >= 0 ? min_slot : 0 );
159172

160173
memset( &driver, 0, sizeof( driver ) );
161174
memset( &key_management, 0, sizeof( key_management ) );
@@ -165,6 +178,11 @@ void key_creation_import_export( )
165178
key_management.p_import = ram_import;
166179
key_management.p_export = ram_export;
167180
key_management.p_destroy = ram_destroy;
181+
if( min_slot >= 0 )
182+
{
183+
key_management.p_allocate = ram_allocate;
184+
ram_min_slot = min_slot;
185+
}
168186

169187
PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
170188
PSA_ASSERT( psa_crypto_init( ) );

0 commit comments

Comments
 (0)