Secure Element Key Management

## Data Structures

struct | psa_drv_se_key_management_t
| A struct containing all of the function pointers needed to for secure element key management. More...

## Typedefs

typedef psa_status_t(* | psa_drv_se_allocate_key_t) (psa_drv_se_context_t *drv_context, void *persistent_data, const psa_key_attributes_t *attributes, psa_key_creation_method_t method, psa_key_slot_number_t *key_slot)
| A function that allocates a slot for a key. More...
typedef psa_status_t(* | psa_drv_se_validate_slot_number_t) (psa_drv_se_context_t *drv_context, void *persistent_data, const psa_key_attributes_t *attributes, psa_key_creation_method_t method, psa_key_slot_number_t key_slot)
| A function that determines whether a slot number is valid for a key. More...
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)
| A function that imports a key into a secure element in binary format. More...
typedef psa_status_t(* | psa_drv_se_destroy_key_t) (psa_drv_se_context_t *drv_context, void *persistent_data, psa_key_slot_number_t key_slot)
| A function that destroys a secure element key and restore the slot to its default state. More...
typedef psa_status_t(* | psa_drv_se_export_key_t) (psa_drv_se_context_t *drv_context, psa_key_slot_number_t key, uint8_t *p_data, size_t data_size, size_t *p_data_length)
| A function that exports a secure element key in binary format. More...
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)
| A function that generates a symmetric or asymmetric key on a secure element. More...

## Enumerations

enum | psa_key_creation_method_t { PSA_KEY_CREATION_IMPORT , PSA_KEY_CREATION_GENERATE , PSA_KEY_CREATION_DERIVE , PSA_KEY_CREATION_COPY , PSA_KEY_CREATION_REGISTER }

## Detailed Description

Currently, key management is limited to importing keys in the clear, destroying keys, and exporting keys in the clear. Whether a key may be exported is determined by the key policies in place on the key slot.

## Typedef Documentation

## psa_drv_se_allocate_key_t

typedef psa_status_t(* psa_drv_se_allocate_key_t) (psa_drv_se_context_t *drv_context, void *persistent_data, const psa_key_attributes_t *attributes, psa_key_creation_method_t method, psa_key_slot_number_t *key_slot)

A function that allocates a slot for a key.

To create a key in a specific slot in a secure element, the core first calls this function to determine a valid slot number, then calls a function to create the key material in that slot. In nominal conditions (that is, if no error occurs), the effect of a call to a key creation function in the PSA Cryptography API with a lifetime that places the key in a secure element is the following:

1. The core calls psa_drv_se_key_management_t::p_allocate (or in some implementations psa_drv_se_key_management_t::p_validate_slot_number). The driver selects (or validates) a suitable slot number given the key attributes and the state of the secure element.
2. The core calls a key creation function in the driver.

The key creation functions in the PSA Cryptography API are:

- psa_import_key(), which causes a call to `p_allocate` with `method` = PSA_KEY_CREATION_IMPORT then a call to psa_drv_se_key_management_t::p_import.
- psa_generate_key(), which causes a call to `p_allocate` with `method` = PSA_KEY_CREATION_GENERATE then a call to psa_drv_se_key_management_t::p_import.
- psa_key_derivation_output_key(), which causes a call to `p_allocate` with `method` = PSA_KEY_CREATION_DERIVE then a call to psa_drv_se_key_derivation_t::p_derive.
- psa_copy_key(), which causes a call to `p_allocate` with `method` = PSA_KEY_CREATION_COPY then a call to psa_drv_se_key_management_t::p_export.

In case of errors, other behaviors are possible.

- If the PSA Cryptography subsystem dies after the first step, for example because the device has lost power abruptly, the second step may never happen, or may happen after a reset and re-initialization. Alternatively, after a reset and re-initialization, the core may call psa_drv_se_key_management_t::p_destroy on the slot number that was allocated (or validated) instead of calling a key creation function.
- If an error occurs, the core may call psa_drv_se_key_management_t::p_destroy on the slot number that was allocated (or validated) instead of calling a key creation function.

Errors and system resets also have an impact on the driver's persistent data. If a reset happens before the overall key creation process is completed (before or after the second step above), it is unspecified whether the persistent data after the reset is identical to what it was before or after the call to `p_allocate` (or `p_validate_slot_number`).

Parameters

  [in,out] | drv_context | The driver context structure.
  [in,out] | persistent_data | A pointer to the persistent data that allows writing.
  [in] | attributes | Attributes of the key.
  | method | The way in which the key is being created.
  [out] | 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.

Return values

  PSA_SUCCESS | Success. The core will record `*key_slot` as the key slot where the key is stored and will update the persistent data in storage.
  PSA_ERROR_NOT_SUPPORTED |
  PSA_ERROR_INSUFFICIENT_STORAGE |

Definition at line 910 of file crypto_se_driver.h.

## psa_drv_se_destroy_key_t

typedef psa_status_t(* psa_drv_se_destroy_key_t) (psa_drv_se_context_t *drv_context, void *persistent_data, psa_key_slot_number_t key_slot)

A function that destroys a secure element key and restore the slot to its default state.

This function destroys the content of the key from a secure element. Implementations shall make a best effort to ensure that any previous content of the slot is unrecoverable.

This function returns the specified slot to its default state.

Parameters

  [in,out] | drv_context | The driver context structure.
  [in,out] | persistent_data | A pointer to the persistent data that allows writing.
  | key_slot | The key slot to erase.

Return values

  PSA_SUCCESS | The slot's content, if any, has been erased.

Definition at line 1018 of file crypto_se_driver.h.

## psa_drv_se_export_key_t

typedef psa_status_t(* psa_drv_se_export_key_t) (psa_drv_se_context_t *drv_context, psa_key_slot_number_t key, uint8_t *p_data, size_t data_size, size_t *p_data_length)

A function that exports a secure element key in binary format.

The output of this function can be passed to psa_import_key() to create an equivalent object.

If a key is created with `psa_import_key()` and then exported with this function, it is not guaranteed that the resulting data is identical: the implementation may choose a different representation of the same key if the format permits it.

This function should generate output in the same format that `psa_export_key()` does. Refer to the documentation of `psa_export_key()` for the format for each key type.

Parameters

  [in,out] | drv_context | The driver context structure.
  [in] | key | Slot whose content is to be exported. This must be an occupied key slot.
  [out] | p_data | Buffer where the key data is to be written.
  [in] | data_size | Size of the `p_data` buffer in bytes.
  [out] | p_data_length | On success, the number of bytes that make up the key data.

Return values

  PSA_SUCCESS |
  PSA_ERROR_DOES_NOT_EXIST |
  PSA_ERROR_NOT_PERMITTED |
  PSA_ERROR_NOT_SUPPORTED |
  PSA_ERROR_COMMUNICATION_FAILURE |
  PSA_ERROR_HARDWARE_FAILURE |
  PSA_ERROR_CORRUPTION_DETECTED |

Definition at line 1054 of file crypto_se_driver.h.

## psa_drv_se_generate_key_t

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)

A function that generates a symmetric or asymmetric key on a secure element.

If the key type `type` recorded in `attributes` is asymmetric (PSA_KEY_TYPE_IS_ASYMMETRIC(`type`) = 1), 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 `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 `*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 `pubkey` is `NULL` and `pubkey_size` is 0.

Parameters

  [in,out] | drv_context | The driver context structure.
  | 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.
  [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.
  [out] | pubkey | A buffer where the driver can write the public key, when generating an asymmetric key pair. This is `NULL` when generating a symmetric key or if the core does not support exporting the public key at generation time.
  | 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.
  [out] | pubkey_length | On entry, this is always 0. On success, the number of bytes written to `pubkey`. If this is 0 or unchanged on return, the core will not read the `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.

Definition at line 1106 of file crypto_se_driver.h.

## psa_drv_se_import_key_t

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)

A function that imports a key into a secure element in binary format.

This function can support any output from psa_export_key(). Refer to the documentation of psa_export_key() for the format for each key type.

Parameters

  [in,out] | drv_context | The driver context structure.
  | 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.
  [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 `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.
  [in] | data | Buffer containing the key data.
  [in] | data_length | Size of the `data` buffer in bytes.
  [out] | bits | On success, the key size in bits. The driver must determine this value after parsing the key according to the key type. This value is not used if the function fails.

Return values

  PSA_SUCCESS | Success.

Definition at line 992 of file crypto_se_driver.h.

## psa_drv_se_validate_slot_number_t

typedef psa_status_t(* psa_drv_se_validate_slot_number_t) (psa_drv_se_context_t *drv_context, void *persistent_data, const psa_key_attributes_t *attributes, psa_key_creation_method_t method, psa_key_slot_number_t key_slot)

A function that determines whether a slot number is valid for a key.

To create a key in a specific slot in a secure element, the core first calls this function to validate the choice of slot number, then calls a function to create the key material in that slot. See the documentation of psa_drv_se_allocate_key_t for more details.

As of the PSA Cryptography API specification version 1.0, there is no way for applications to trigger a call to this function. However some implementations offer the capability to create or declare a key in a specific slot via implementation-specific means, generally for the sake of initial device provisioning or onboarding. Such a mechanism may be added to a future version of the PSA Cryptography API specification.

This function may update the driver's persistent data through `persistent_data`. The core will save the updated persistent data at the end of the key creation process. See the description of psa_drv_se_allocate_key_t for more information.

Parameters

  [in,out] | drv_context | The driver context structure.
  [in,out] | persistent_data | A pointer to the persistent data that allows writing.
  [in] | attributes | Attributes of the key.
  | method | The way in which the key is being created.
  [in] | key_slot | Slot where the key is to be stored.

Return values

  PSA_SUCCESS | The given slot number is valid for a key with the given attributes.
  PSA_ERROR_INVALID_ARGUMENT | The given slot number is not valid for a key with the given attributes. This includes the case where the slot number is not valid at all.
  PSA_ERROR_ALREADY_EXISTS | There is already a key with the specified slot number. Drivers may choose to return this error from the key creation function instead.

Definition at line 956 of file crypto_se_driver.h.

## Enumeration Type Documentation

## psa_key_creation_method_t

enum psa_key_creation_method_t

An enumeration indicating how a key is created.

Enumerator
PSA_KEY_CREATION_IMPORT | During psa_import_key()
PSA_KEY_CREATION_GENERATE | During psa_generate_key()
PSA_KEY_CREATION_DERIVE | During psa_key_derivation_output_key()
PSA_KEY_CREATION_COPY | During psa_copy_key()

PSA_KEY_CREATION_REGISTER

A key is being registered with mbedtls_psa_register_se_key().

The core only passes this value to psa_drv_se_key_management_t::p_validate_slot_number, not to psa_drv_se_key_management_t::p_allocate. The call to `p_validate_slot_number` is not followed by any other call to the driver: the key is considered successfully registered if the call to `p_validate_slot_number` succeeds, or if `p_validate_slot_number` is null.

With this creation method, the driver must return PSA_SUCCESS if the given attributes are compatible with the existing key in the slot, and PSA_ERROR_DOES_NOT_EXIST if the driver can determine that there is no key with the specified slot number.

This is an Mbed Crypto extension.

Definition at line 817 of file crypto_se_driver.h.