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.
*
* \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
* chosen type. It must be unoccupied.
* \param[in] lifetime The required lifetime of the key storage
* \param[in] type Key type (a \c PSA_KEY_TYPE_XXX value)
* \param[in] algorithm Key algorithm (a \c PSA_ALG_XXX value)
* \param[in] usage The allowed uses of the key
* \param[in] p_data Buffer containing the key data
* \param[in] data_length Size of the `data` buffer in bytes
* \param[in] attributes The key attributes, including the lifetime,
* the key type and the usage policy.
* Drivers should not access the key size stored
* in the attributes: it may not match the
* data passed in \p data.
* 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
* must determine this value after parsing the
* key according to the key type.
@ -973,15 +979,13 @@ typedef psa_status_t (*psa_drv_se_validate_slot_number_t)(
* \retval #PSA_SUCCESS
* Success.
*/
typedef psa_status_t (*psa_drv_se_import_key_t)(psa_drv_se_context_t *drv_context,
psa_key_slot_number_t key_slot,
psa_key_lifetime_t lifetime,
psa_key_type_t type,
psa_algorithm_t algorithm,
psa_key_usage_t usage,
const uint8_t *p_data,
size_t data_length,
size_t *bits);
typedef psa_status_t (*psa_drv_se_import_key_t)(
psa_drv_se_context_t *drv_context,
psa_key_slot_number_t key_slot,
const psa_key_attributes_t *attributes,
const uint8_t *data,
size_t data_length,
size_t *bits);
/**
* \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
*
* 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 format of the public key information will match the format specified for
* the psa_export_key() function for the key type.
* the driver may export the public key at the time of generation,
* in the format documented for psa_export_public_key() by writing it
* 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] key_slot Slot where the generated key will be placed
* \param[in] type The type of the key to be generated
* \param[in] usage The prescribed usage of the generated key
* Note: Not all Secure Elements support the same
* restrictions that PSA Crypto does (and vice
* versa).
* Driver developers should endeavor to match the
* usages as close as possible.
* \param[in] bits The size in bits of the key to be generated.
* \param[in] extra Extra parameters for key generation. The
* interpretation of this parameter should match
* the interpretation in the `extra` parameter is
* the `psa_generate_key` function
* \param[in] extra_size The size in bytes of the \p extra buffer
* \param[out] p_pubkey_out The buffer where the public key information will
* be placed
* \param[in] pubkey_out_size The size in bytes of the `p_pubkey_out` buffer
* \param[out] p_pubkey_length Upon successful completion, will contain the
* size of the data placed in `p_pubkey_out`.
* \param key_slot Slot where the key will be stored.
* This must be a valid slot for a key of the
* chosen type. It must be unoccupied.
* \param[in] attributes The key attributes, including the lifetime,
* the key type and size, and the usage policy.
* Drivers can call psa_get_key_lifetime(),
* psa_get_key_type(), psa_get_key_bits(),
* psa_get_key_usage_flags() and
* psa_get_key_algorithm() to access this
* information.
* \param[out] pubkey A buffer where the driver can write the
* public key, when generating an asymmetric
* key pair.
* This is \c NULL when generating a symmetric
* key or if the core does not support
* exporting the public key at generation time.
* \param pubkey_size The size of the `pubkey` buffer in bytes.
* This is 0 when generating a symmetric
* 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,
psa_key_slot_number_t key_slot,
psa_key_type_t type,
psa_key_usage_t usage,
size_t bits,
const void *extra,
size_t extra_size,
uint8_t *p_pubkey_out,
size_t pubkey_out_size,
size_t *p_pubkey_length);
typedef psa_status_t (*psa_drv_se_generate_key_t)(
psa_drv_se_context_t *drv_context,
psa_key_slot_number_t key_slot,
const psa_key_attributes_t *attributes,
uint8_t *pubkey, size_t pubkey_size, size_t *pubkey_length);
/**
* \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(
psa_get_se_driver_context( driver ),
slot->data.se.slot_number,
slot->attr.lifetime, slot->attr.type,
slot->attr.policy.alg, slot->attr.policy.usage,
data, data_length,
slot->data.se.slot_number, attributes, data, data_length,
&bits );
if( status != PSA_SUCCESS )
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. */
static psa_status_t null_import( psa_drv_se_context_t *context,
psa_key_slot_number_t slot_number,
psa_key_lifetime_t lifetime,
psa_key_type_t type,
psa_algorithm_t algorithm,
psa_key_usage_t usage,
const uint8_t *p_data,
const psa_key_attributes_t *attributes,
const uint8_t *data,
size_t data_length,
size_t *bits )
{
(void) context;
(void) slot_number;
(void) lifetime;
(void) type;
(void) algorithm;
(void) usage;
(void) p_data;
(void) attributes;
(void) data;
/* We're supposed to return a key size. Return one that's correct for
* plain data keys. */
*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,
psa_key_slot_number_t slot_number,
psa_key_lifetime_t lifetime,
psa_key_type_t type,
psa_algorithm_t algorithm,
psa_key_usage_t usage,
const uint8_t *p_data,
const psa_key_attributes_t *attributes,
const uint8_t *data,
size_t data_length,
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 ) );
if( data_length > sizeof( ram_slots[slot_number].content ) )
return( PSA_ERROR_INSUFFICIENT_STORAGE );
ram_slots[slot_number].lifetime = lifetime;
ram_slots[slot_number].type = type;
ram_slots[slot_number].lifetime = psa_get_key_lifetime( attributes );
ram_slots[slot_number].type = psa_get_key_type( attributes );
ram_slots[slot_number].bits = PSA_BYTES_TO_BITS( data_length );
*bits = PSA_BYTES_TO_BITS( data_length );
(void) algorithm;
(void) usage;
memcpy( ram_slots[slot_number].content, p_data, data_length );
memcpy( ram_slots[slot_number].content, data, data_length );
return( PSA_SUCCESS );
}