Skip to content

Commit c88b896

Browse files
Pass the key creation method to drivers
Pass the key creation method (import/generate/derive/copy) to the driver methods to allocate or validate a slot number. This allows drivers to enforce policies such as "this key slot can only be used for keys generated inside the secure element".
1 parent f8ec001 commit c88b896

File tree

5 files changed

+51
-21
lines changed

5 files changed

+51
-21
lines changed

include/psa/crypto_se_driver.h

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -810,12 +810,23 @@ typedef struct {
810810
*/
811811
/**@{*/
812812

813+
/** An enumeration indicating how a key is created.
814+
*/
815+
typedef enum
816+
{
817+
PSA_KEY_CREATION_IMPORT, /**< During psa_import_key() */
818+
PSA_KEY_CREATION_GENERATE, /**< During psa_generate_key() */
819+
PSA_KEY_CREATION_DERIVE, /**< During psa_key_derivation_output_key() */
820+
PSA_KEY_CREATION_COPY, /**< During psa_copy_key() */
821+
} psa_key_creation_method_t;
822+
813823
/** \brief A function that allocates a slot for a key.
814824
*
815825
* \param[in,out] drv_context The driver context structure.
816826
* \param[in,out] persistent_data A pointer to the persistent data
817827
* that allows writing.
818828
* \param[in] attributes Attributes of the key.
829+
* \param method The way in which the key is being created.
819830
* \param[out] key_slot Slot where the key will be stored.
820831
* This must be a valid slot for a key of the
821832
* chosen type. It must be unoccupied.
@@ -831,14 +842,16 @@ typedef psa_status_t (*psa_drv_se_allocate_key_t)(
831842
psa_drv_se_context_t *drv_context,
832843
void *persistent_data,
833844
const psa_key_attributes_t *attributes,
845+
psa_key_creation_method_t method,
834846
psa_key_slot_number_t *key_slot);
835847

836848
/** \brief A function that determines whether a slot number is valid
837849
* for a key.
838850
*
839-
* \param[in,out] drv_context The driver context structure.
840-
* \param[in] attributes Attributes of the key.
841-
* \param[in] key_slot Slot where the key is to be stored.
851+
* \param[in,out] drv_context The driver context structure.
852+
* \param[in] attributes Attributes of the key.
853+
* \param method The way in which the key is being created.
854+
* \param[in] key_slot Slot where the key is to be stored.
842855
*
843856
* \retval #PSA_SUCCESS
844857
* The given slot number is valid for a key with the given
@@ -855,6 +868,7 @@ typedef psa_status_t (*psa_drv_se_allocate_key_t)(
855868
typedef psa_status_t (*psa_drv_se_validate_slot_number_t)(
856869
psa_drv_se_context_t *drv_context,
857870
const psa_key_attributes_t *attributes,
871+
psa_key_creation_method_t method,
858872
psa_key_slot_number_t key_slot);
859873

860874
/** \brief A function that imports a key into a secure element in binary format
@@ -1004,9 +1018,12 @@ typedef struct {
10041018
/** Function that allocates a slot for a key.
10051019
*
10061020
* The core calls this function to determine a slot number, then
1007-
* calls the actual creation function (such as
1008-
* psa_drv_se_key_management_t::p_import or
1009-
* psa_drv_se_key_management_t::p_generate).
1021+
* calls the actual creation function. The `method` parameter passed
1022+
* to this function indicates which creation function is called next:
1023+
* - #PSA_KEY_CREATION_IMPORT is followed by psa_drv_se_key_management_t::p_import
1024+
* - #PSA_KEY_CREATION_GENERATE is followed by psa_drv_se_key_management_t::p_generate
1025+
* - #PSA_KEY_CREATION_DERIVE is followed by psa_drv_se_key_derivation_t::p_derive
1026+
* - #PSA_KEY_CREATION_COPY is followed by psa_drv_se_key_management_t::p_export
10101027
*
10111028
* If this function succeeds, the next call that the core makes to the
10121029
* driver is either the creation function or
@@ -1022,9 +1039,7 @@ typedef struct {
10221039
* The core calls this function instead of
10231040
* psa_drv_se_key_management_t::p_allocate to create
10241041
* a key in a specific slot. It then calls the actual creation function
1025-
* (such as psa_drv_se_key_management_t::p_import or
1026-
* psa_drv_se_key_management_t::p_generate) or
1027-
* psa_drv_se_key_management_t::p_destroy.
1042+
* as for `p_allocate`.
10281043
*/
10291044
psa_drv_se_validate_slot_number_t p_validate_slot_number;
10301045
/** Function that performs a key import operation */

library/psa_crypto.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,16 +1505,22 @@ static psa_status_t psa_validate_key_attributes(
15051505
return( PSA_SUCCESS );
15061506
}
15071507

1508-
/** An enumeration indicating how a key is created.
1508+
#if !defined(MBEDTLS_PSA_CRYPTO_SE_C)
1509+
/* Key creation methods only make a difference in this module when
1510+
* secure element support is enabled. To avoid cluttering the code
1511+
* with too many #ifdef, we do use the type, and since crypto_se_driver.h
1512+
* is not #include'd, we need to define it. The type does not need to
1513+
* be compatible with the definition in crypto_se_driver.h, it just
1514+
* needs to be sufficient to get the code to build. So do something
1515+
* that gives compilers a chance of optimizing the variables of this type
1516+
* away: give all constants the same value.
15091517
*/
1510-
typedef enum
1511-
{
1512-
PSA_KEY_CREATION_IMPORT,
1513-
PSA_KEY_CREATION_GENERATE,
1514-
PSA_KEY_CREATION_DERIVE,
1515-
PSA_KEY_CREATION_COPY,
1516-
PSA_KEY_CREATION_REGISTER,
1517-
} psa_key_creation_method_t;
1518+
#define PSA_KEY_CREATION_IMPORT 0
1519+
#define PSA_KEY_CREATION_GENERATE 0
1520+
#define PSA_KEY_CREATION_DERIVE 0
1521+
#define PSA_KEY_CREATION_COPY 0
1522+
typedef int psa_key_creation_method_t;
1523+
#endif /* !MBEDTLS_PSA_CRYPTO_SE_C */
15181524

15191525
/** Prepare a key slot to receive key material.
15201526
*
@@ -1592,7 +1598,7 @@ static psa_status_t psa_start_key_creation(
15921598
* we can roll back to a state where the key doesn't exist. */
15931599
if( *p_drv != NULL && method != PSA_KEY_CREATION_REGISTER )
15941600
{
1595-
status = psa_find_se_slot_for_key( attributes, *p_drv,
1601+
status = psa_find_se_slot_for_key( attributes, method, *p_drv,
15961602
&slot->data.se.slot_number );
15971603
if( status != PSA_SUCCESS )
15981604
return( status );

library/psa_crypto_se.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ psa_status_t psa_destroy_se_persistent_data( psa_key_lifetime_t lifetime )
191191

192192
psa_status_t psa_find_se_slot_for_key(
193193
const psa_key_attributes_t *attributes,
194+
psa_key_creation_method_t method,
194195
psa_se_drv_table_entry_t *driver,
195196
psa_key_slot_number_t *slot_number )
196197
{
@@ -214,7 +215,8 @@ psa_status_t psa_find_se_slot_for_key(
214215
driver->methods->key_management->p_validate_slot_number;
215216
if( p_validate_slot_number == NULL )
216217
return( PSA_ERROR_NOT_SUPPORTED );
217-
status = p_validate_slot_number( &driver->context, attributes,
218+
status = p_validate_slot_number( &driver->context,
219+
attributes, method,
218220
*slot_number );
219221
}
220222
else
@@ -227,7 +229,7 @@ psa_status_t psa_find_se_slot_for_key(
227229
return( PSA_ERROR_NOT_SUPPORTED );
228230
status = p_allocate( &driver->context,
229231
driver->internal.persistent_data,
230-
attributes,
232+
attributes, method,
231233
slot_number );
232234
}
233235
return( status );

library/psa_crypto_se.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ psa_drv_se_context_t *psa_get_se_driver_context(
135135
*/
136136
psa_status_t psa_find_se_slot_for_key(
137137
const psa_key_attributes_t *attributes,
138+
psa_key_creation_method_t method,
138139
psa_se_drv_table_entry_t *driver,
139140
psa_key_slot_number_t *slot_number );
140141

tests/suites/test_suite_psa_crypto_se_driver_hal.function

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@
4141
static psa_status_t counter_allocate( psa_drv_se_context_t *context,
4242
void *persistent_data,
4343
const psa_key_attributes_t *attributes,
44+
psa_key_creation_method_t method,
4445
psa_key_slot_number_t *slot_number )
4546
{
4647
psa_key_slot_number_t *p_counter = persistent_data;
4748
(void) attributes;
49+
(void) method;
4850
if( context->persistent_data_size != sizeof( psa_key_slot_number_t ) )
4951
return( PSA_ERROR_DETECTED_BY_DRIVER );
5052
++*p_counter;
@@ -162,10 +164,12 @@ static psa_status_t ram_destroy( psa_drv_se_context_t *context,
162164
static psa_status_t ram_allocate( psa_drv_se_context_t *context,
163165
void *persistent_data,
164166
const psa_key_attributes_t *attributes,
167+
psa_key_creation_method_t method,
165168
psa_key_slot_number_t *slot_number )
166169
{
167170
ram_slot_usage_t *slot_usage = persistent_data;
168171
(void) attributes;
172+
(void) method;
169173
DRIVER_ASSERT( context->persistent_data_size == sizeof( ram_slot_usage_t ) );
170174
for( *slot_number = ram_min_slot;
171175
*slot_number < ARRAY_LENGTH( ram_slots );
@@ -180,10 +184,12 @@ static psa_status_t ram_allocate( psa_drv_se_context_t *context,
180184
static psa_status_t ram_validate_slot_number(
181185
psa_drv_se_context_t *context,
182186
const psa_key_attributes_t *attributes,
187+
psa_key_creation_method_t method,
183188
psa_key_slot_number_t slot_number )
184189
{
185190
(void) context;
186191
(void) attributes;
192+
(void) method;
187193
if( slot_number >= ARRAY_LENGTH( ram_slots ) )
188194
return( PSA_ERROR_INVALID_ARGUMENT );
189195
return( PSA_SUCCESS );

0 commit comments

Comments
 (0)