Update import_key and generate_key SE methods to the current API

The methods to import and generate a key in a secure element drivers
were written for an earlier version of the application-side interface.
Now that there is a psa_key_attributes_t structure that combines all
key metadata including its lifetime (location), type, size, policy and
extra type-specific data (domain parameters), pass that to drivers
instead of separate arguments for each piece of metadata. This makes
the interface less cluttered.

Update parameter names and descriptions to follow general conventions.

Document the public-key output on key generation more precisely.
Explain that it is optional in a driver, and when a driver would
implement it. Declare that it is optional in the core, too (which
means that a crypto core might not support drivers for secure elements
that do need this feature).

Update the implementation and the tests accordingly.
This commit is contained in:
Gilles Peskine 2019-08-06 17:32:04 +02:00
parent 5a2d15256d
commit f3801fff77
3 changed files with 72 additions and 72 deletions

View file

@ -956,15 +956,21 @@ typedef psa_status_t (*psa_drv_se_validate_slot_number_t)(
* documentation of psa_export_key() for the format for each key type. * documentation of psa_export_key() for the format for each key type.
* *
* \param[in,out] drv_context The driver context structure. * \param[in,out] drv_context The driver context structure.
* \param[in] key_slot Slot where the key will be stored * \param key_slot Slot where the key will be stored.
* This must be a valid slot for a key of the * This must be a valid slot for a key of the
* chosen type. It must be unoccupied. * chosen type. It must be unoccupied.
* \param[in] lifetime The required lifetime of the key storage * \param[in] attributes The key attributes, including the lifetime,
* \param[in] type Key type (a \c PSA_KEY_TYPE_XXX value) * the key type and the usage policy.
* \param[in] algorithm Key algorithm (a \c PSA_ALG_XXX value) * Drivers should not access the key size stored
* \param[in] usage The allowed uses of the key * in the attributes: it may not match the
* \param[in] p_data Buffer containing the key data * data passed in \p data.
* \param[in] data_length Size of the `data` buffer in bytes * Drivers can call psa_get_key_lifetime(),
* psa_get_key_type(),
* psa_get_key_usage_flags() and
* psa_get_key_algorithm() to access this
* information.
* \param[in] data Buffer containing the key data.
* \param[in] data_length Size of the \p data buffer in bytes.
* \param[out] bits On success, the key size in bits. The driver * \param[out] bits On success, the key size in bits. The driver
* must determine this value after parsing the * must determine this value after parsing the
* key according to the key type. * key according to the key type.
@ -973,15 +979,13 @@ typedef psa_status_t (*psa_drv_se_validate_slot_number_t)(
* \retval #PSA_SUCCESS * \retval #PSA_SUCCESS
* Success. * Success.
*/ */
typedef psa_status_t (*psa_drv_se_import_key_t)(psa_drv_se_context_t *drv_context, typedef psa_status_t (*psa_drv_se_import_key_t)(
psa_key_slot_number_t key_slot, psa_drv_se_context_t *drv_context,
psa_key_lifetime_t lifetime, psa_key_slot_number_t key_slot,
psa_key_type_t type, const psa_key_attributes_t *attributes,
psa_algorithm_t algorithm, const uint8_t *data,
psa_key_usage_t usage, size_t data_length,
const uint8_t *p_data, size_t *bits);
size_t data_length,
size_t *bits);
/** /**
* \brief A function that destroys a secure element key and restore the slot to * \brief A function that destroys a secure element key and restore the slot to
@ -1048,41 +1052,51 @@ typedef psa_status_t (*psa_drv_se_export_key_t)(psa_drv_se_context_t *drv_contex
* element * element
* *
* If \p type is asymmetric (#PSA_KEY_TYPE_IS_ASYMMETRIC(\p type) = 1), * If \p type is asymmetric (#PSA_KEY_TYPE_IS_ASYMMETRIC(\p type) = 1),
* the public component of the generated key will be placed in `p_pubkey_out`. * the driver may export the public key at the time of generation,
* The format of the public key information will match the format specified for * in the format documented for psa_export_public_key() by writing it
* the psa_export_key() function for the key type. * to the \p pubkey buffer.
* This is optional, intended for secure elements that output the
* public key at generation time and that cannot export the public key
* later. Drivers that do not need this feature should leave
* \p *pubkey_length set to 0 and should
* implement the psa_drv_key_management_t::p_export_public function.
* Some implementations do not support this feature, in which case
* \p pubkey is \c NULL and \p pubkey_size is 0.
* *
* \param[in,out] drv_context The driver context structure. * \param[in,out] drv_context The driver context structure.
* \param[in] key_slot Slot where the generated key will be placed * \param key_slot Slot where the key will be stored.
* \param[in] type The type of the key to be generated * This must be a valid slot for a key of the
* \param[in] usage The prescribed usage of the generated key * chosen type. It must be unoccupied.
* Note: Not all Secure Elements support the same * \param[in] attributes The key attributes, including the lifetime,
* restrictions that PSA Crypto does (and vice * the key type and size, and the usage policy.
* versa). * Drivers can call psa_get_key_lifetime(),
* Driver developers should endeavor to match the * psa_get_key_type(), psa_get_key_bits(),
* usages as close as possible. * psa_get_key_usage_flags() and
* \param[in] bits The size in bits of the key to be generated. * psa_get_key_algorithm() to access this
* \param[in] extra Extra parameters for key generation. The * information.
* interpretation of this parameter should match * \param[out] pubkey A buffer where the driver can write the
* the interpretation in the `extra` parameter is * public key, when generating an asymmetric
* the `psa_generate_key` function * key pair.
* \param[in] extra_size The size in bytes of the \p extra buffer * This is \c NULL when generating a symmetric
* \param[out] p_pubkey_out The buffer where the public key information will * key or if the core does not support
* be placed * exporting the public key at generation time.
* \param[in] pubkey_out_size The size in bytes of the `p_pubkey_out` buffer * \param pubkey_size The size of the `pubkey` buffer in bytes.
* \param[out] p_pubkey_length Upon successful completion, will contain the * This is 0 when generating a symmetric
* size of the data placed in `p_pubkey_out`. * key or if the core does not support
* exporting the public key at generation time.
* \param[out] pubkey_length On entry, this is always 0.
* On success, the number of bytes written to
* \p pubkey. If this is 0 or unchanged on return,
* the core will not read the \p pubkey buffer,
* and will instead call the driver's
* psa_drv_key_management_t::p_export_public
* function to export the public key when needed.
*/ */
typedef psa_status_t (*psa_drv_se_generate_key_t)(psa_drv_se_context_t *drv_context, typedef psa_status_t (*psa_drv_se_generate_key_t)(
psa_key_slot_number_t key_slot, psa_drv_se_context_t *drv_context,
psa_key_type_t type, psa_key_slot_number_t key_slot,
psa_key_usage_t usage, const psa_key_attributes_t *attributes,
size_t bits, uint8_t *pubkey, size_t pubkey_size, size_t *pubkey_length);
const void *extra,
size_t extra_size,
uint8_t *p_pubkey_out,
size_t pubkey_out_size,
size_t *p_pubkey_length);
/** /**
* \brief A struct containing all of the function pointers needed to for secure * \brief A struct containing all of the function pointers needed to for secure

View file

@ -1827,10 +1827,7 @@ psa_status_t psa_import_key( const psa_key_attributes_t *attributes,
} }
status = drv->key_management->p_import( status = drv->key_management->p_import(
psa_get_se_driver_context( driver ), psa_get_se_driver_context( driver ),
slot->data.se.slot_number, slot->data.se.slot_number, attributes, data, data_length,
slot->attr.lifetime, slot->attr.type,
slot->attr.policy.alg, slot->attr.policy.usage,
data, data_length,
&bits ); &bits );
if( status != PSA_SUCCESS ) if( status != PSA_SUCCESS )
goto exit; goto exit;

View file

@ -81,21 +81,15 @@ static psa_status_t counter_allocate( psa_drv_se_context_t *context,
/* Null import: do nothing, but pretend it worked. */ /* Null import: do nothing, but pretend it worked. */
static psa_status_t null_import( psa_drv_se_context_t *context, static psa_status_t null_import( psa_drv_se_context_t *context,
psa_key_slot_number_t slot_number, psa_key_slot_number_t slot_number,
psa_key_lifetime_t lifetime, const psa_key_attributes_t *attributes,
psa_key_type_t type, const uint8_t *data,
psa_algorithm_t algorithm,
psa_key_usage_t usage,
const uint8_t *p_data,
size_t data_length, size_t data_length,
size_t *bits ) size_t *bits )
{ {
(void) context; (void) context;
(void) slot_number; (void) slot_number;
(void) lifetime; (void) attributes;
(void) type; (void) data;
(void) algorithm;
(void) usage;
(void) p_data;
/* We're supposed to return a key size. Return one that's correct for /* We're supposed to return a key size. Return one that's correct for
* plain data keys. */ * plain data keys. */
*bits = PSA_BYTES_TO_BITS( data_length ); *bits = PSA_BYTES_TO_BITS( data_length );
@ -132,11 +126,8 @@ static void ram_slots_reset( void )
static psa_status_t ram_import( psa_drv_se_context_t *context, static psa_status_t ram_import( psa_drv_se_context_t *context,
psa_key_slot_number_t slot_number, psa_key_slot_number_t slot_number,
psa_key_lifetime_t lifetime, const psa_key_attributes_t *attributes,
psa_key_type_t type, const uint8_t *data,
psa_algorithm_t algorithm,
psa_key_usage_t usage,
const uint8_t *p_data,
size_t data_length, size_t data_length,
size_t *bits ) size_t *bits )
{ {
@ -144,13 +135,11 @@ static psa_status_t ram_import( psa_drv_se_context_t *context,
DRIVER_ASSERT( slot_number < ARRAY_LENGTH( ram_slots ) ); DRIVER_ASSERT( slot_number < ARRAY_LENGTH( ram_slots ) );
if( data_length > sizeof( ram_slots[slot_number].content ) ) if( data_length > sizeof( ram_slots[slot_number].content ) )
return( PSA_ERROR_INSUFFICIENT_STORAGE ); return( PSA_ERROR_INSUFFICIENT_STORAGE );
ram_slots[slot_number].lifetime = lifetime; ram_slots[slot_number].lifetime = psa_get_key_lifetime( attributes );
ram_slots[slot_number].type = type; ram_slots[slot_number].type = psa_get_key_type( attributes );
ram_slots[slot_number].bits = PSA_BYTES_TO_BITS( data_length ); ram_slots[slot_number].bits = PSA_BYTES_TO_BITS( data_length );
*bits = PSA_BYTES_TO_BITS( data_length ); *bits = PSA_BYTES_TO_BITS( data_length );
(void) algorithm; memcpy( ram_slots[slot_number].content, data, data_length );
(void) usage;
memcpy( ram_slots[slot_number].content, p_data, data_length );
return( PSA_SUCCESS ); return( PSA_SUCCESS );
} }