Draft specification for key derivation
Pass all the initial inputs in a single structure. It's impossible to pass the inputs as soon as the application makes them available because the core cannot know which driver to call until it receives the SECRET input. Do support hiding the key material inside a secure element if the relevant driver has all the requisite entry points. Do cooked key derivation (i.e. derivation of non-raw keys) and key agreement separately. Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
parent
f954853e00
commit
a2b41598d6
1 changed files with 250 additions and 17 deletions
|
@ -297,25 +297,251 @@ TODO
|
|||
|
||||
TODO
|
||||
|
||||
#### Operation family `"key_derivation"`
|
||||
### Driver entry points for key derivation
|
||||
|
||||
This family requires the following type and entry points:
|
||||
Key derivation is more complex than other multipart operations due to the multiplicity of inputs and outputs, to the fact that multiple drivers can be involved (key agreement and subsequent key derivation accelerator, opaque driver for the secret key and for derived keys), and because the involvement of an opaque driver cannot be determined as soon as the operation is set up (since `psa_key_derivation_setup()` does not determine the key input).
|
||||
|
||||
* Type `"key_derivation_operation_t"`: the type of a key derivation operation context.
|
||||
* `"key_derivation_setup"`: called by `psa_key_derivation_setup()`.
|
||||
* `"key_derivation_set_capacity"`: called by `psa_key_derivation_set_capacity()`. The core will always enforce the capacity, therefore this function does not need to do anything for algorithms where the output stream only depends on the effective generated length and not on the capacity.
|
||||
* `"key_derivation_input_bytes"`: called by `psa_key_derivation_input_bytes()` and `psa_key_derivation_input_key()`. For transparent drivers, when processing a call to `psa_key_derivation_input_key()`, the core always calls the applicable driver's `"key_derivation_input_bytes"` entry point.
|
||||
* `"key_derivation_input_integer"`: called by `psa_key_derivation_input_integer()`.
|
||||
* `"key_derivation_input_key"` (opaque drivers only)
|
||||
* `"key_derivation_output_bytes"`: called by `psa_key_derivation_output_bytes()`; also by `psa_key_derivation_output_key()` for transparent drivers.
|
||||
* `"key_derivation_output_key"`: called by `psa_key_derivation_output_key()` for transparent drivers when deriving an asymmetric key pair, and also for opaque drivers.
|
||||
* `"key_derivation_verify_bytes"` (opaque drivers only).
|
||||
* `"key_derivation_verify_key"` (opaque drivers only).
|
||||
* `"key_derivation_abort"`: called by all key derivation functions of the PSA Cryptography API.
|
||||
#### Key derivation driver dispatch logic
|
||||
|
||||
TODO: key input and output for opaque drivers; deterministic key generation for transparent drivers
|
||||
The core decides whether to dispatch a key derivation operation to a driver based on the location of the input step `PSA_KEY_DERIVATION_INPUT_SECRET`.
|
||||
|
||||
TODO
|
||||
1. If this step is passed via `psa_key_derivation_input_key()` for a key in a secure element:
|
||||
* If the driver for this secure element implements the `"key_derivation"` family for the specified key type and algorithm, the core calls that driver's `"key_derivation_setup"` and subsequent entry points.
|
||||
* Otherwise the core calls the secure element driver's [`"export_key"`](#key-management-with-opaque-drivers) entry point.
|
||||
2. Otherwise ([or on fallback?](#fallback-for-key-derivation-in-opaque-drivers)), if there is a transparent driver for the specified key type and algorithm, the core calls that driver's `"key_derivation_setup"` and subsequent entry points.
|
||||
3. Otherwise, or on fallback, the core uses its built-in implementation.
|
||||
|
||||
#### Summary of entry points for the operation family `"key_derivation"`
|
||||
|
||||
A key derivation driver has the following entry points:
|
||||
|
||||
* `"key_derivation_setup"` (mandatory): always the first entry point to be called. This entry point provides the [initial inputs](#key-derivation-driver-initial-inputs). See [“Key derivation driver setup”](#key-derivation-driver-setup).
|
||||
* `"key_derivation_input_step"` (optional): provide an extra input for the key derivation. This entry point is only mandatory in drivers that support algorithms that have extra inputs. See [“Key derivation driver extra inputs”](#key-derivation-driver-inputs).
|
||||
* `"key_derivation_output_bytes"` (mandatory): derive cryptographic material and output it. See [“Key derivation driver outputs”](#key-derivation-driver-outputs).
|
||||
* `"key_derivation_derive_key"`, `"key_derivation_verify_bytes"`, `"key_derivation_verify_key"` (optional, opaque drivers only): derive key material which remains inside the same secure element. See [“Key derivation driver outputs”](#key-derivation-driver-outputs).
|
||||
* `"key_derivation_set_capacity"` (mandatory for opaque drivers that implement `"key_derivation_output_bytes"` for non-raw-data key types): update the capacity policy on the operation. See [“Key derivation driver operation capacity”](#key-derivation-driver-operation-capacity).
|
||||
* `"key_derivation_abort"` (mandatory): always the last entry point to be called.
|
||||
|
||||
For naming purposes, here and in the following subsection, this specification takes the example of a driver with the prefix `"acme"` that implements the `"key_derivation"` entry point family with a capability that does not use the `"names"` property to declare different type and entry point names. Such a driver must implement the following type and functions, as well as the entry points listed above and described in the following subsections:
|
||||
```
|
||||
typedef ... acme_key_derivation_operation_t;
|
||||
psa_status_t acme_hash_abort(acme_key_derivation_operation_t *operation);
|
||||
```
|
||||
|
||||
#### Key derivation driver initial inputs
|
||||
|
||||
The core conveys the initial inputs for a key derivation via an opaque data structure of type `psa_crypto_driver_key_derivation_inputs_t`.
|
||||
|
||||
```
|
||||
typedef ... psa_crypto_driver_key_derivation_inputs_t; // implementation-specific type
|
||||
```
|
||||
|
||||
A driver receiving an argument that points to a `psa_crypto_driver_key_derivation_inputs_t` can retrieve its content using the following functions.
|
||||
|
||||
```
|
||||
psa_status_t psa_crypto_driver_key_derivation_get_input_size(
|
||||
const psa_crypto_driver_key_derivation_inputs_t *inputs,
|
||||
psa_key_derivation_step_t step,
|
||||
size_t *size);
|
||||
psa_status_t psa_crypto_driver_key_derivation_get_input_bytes(
|
||||
const psa_crypto_driver_key_derivation_inputs_t *inputs,
|
||||
psa_key_derivation_step_t step,
|
||||
uint8_t *output, size_t output_size, size_t *output_length);
|
||||
psa_status_t psa_crypto_driver_key_derivation_get_input_key(
|
||||
const psa_crypto_driver_key_derivation_inputs_t *inputs,
|
||||
psa_key_derivation_step_t step,
|
||||
uint8_t** p_key_buffer, size_t *key_buffer_size);
|
||||
psa_status_t psa_crypto_driver_key_derivation_get_input_integer(
|
||||
const psa_crypto_driver_key_derivation_inputs_t *inputs,
|
||||
psa_key_derivation_step_t step,
|
||||
uint64_t *value);
|
||||
```
|
||||
|
||||
These functions take the following parameters:
|
||||
|
||||
* The first parameter `inputs` must be a pointer passed by the core to a key derivation driver setup entry points which has not returned yet.
|
||||
* The `step` parameter indicates the input step whose content the driver wants to retrieve. The type of the input step must be compatible with the function:
|
||||
* `psa_crypto_driver_key_derivation_get_input_integer` for integer inputs (steps that the application passes with `psa_key_derivation_input_integer()`).
|
||||
* `psa_crypto_driver_key_derivation_get_input_size` and `psa_crypto_driver_key_derivation_get_input_bytes` for data inputs (steps that the application passes with `psa_key_derivation_input_bytes()` or `psa_key_derivation_input_key()`, excluding key inputs from the same secure element).
|
||||
* `psa_crypto_driver_key_derivation_get_input_key` for key inputs (steps that the application passes with `psa_key_derivation_input_key()`, only for secure element drivers receiving a key from the same secure element).
|
||||
* On a successful invocation of `psa_crypto_driver_key_derivation_get_input_size`, the core sets `*size` to the size of the desired input in bytes.
|
||||
* On a successful invocation of `psa_crypto_driver_key_derivation_get_input_bytes`, the core fills the first *N* bytes of `output` with the desired input and sets `*output_length` to *N*, where *N* is the length of the input in bytes. The value of `output_size` must be at least *N*, otherwise this function fails with the status `PSA_ERROR_BUFFER_TOO_SMALL`.
|
||||
* On a successful invocation of `psa_crypto_driver_key_derivation_get_input_key`, the core sets `*key_buffer` to a pointer to a buffer containing the key context and `*key_buffer_size` to the size of the key context in bytes. The key context buffer remains valid for the duration of the driver entry point. If the driver needs to access the key context after the current entry point returns, it must make a copy of the key context.
|
||||
* On a successful invocation of `psa_crypto_driver_key_derivation_get_input_integer`, the core sets `*value` to the value of the desired input.
|
||||
|
||||
These functions can return the following statuses:
|
||||
|
||||
* `PSA_SUCCESS`: the call succeeded and the desired value has been copied to the output parameter.
|
||||
* `PSA_ERROR_INSUFFICIENT_DATA`: the driver called `psa_crypto_driver_key_derivation_get_input_key` on a data input step which is available as a bytes input, or the driver called ``psa_crypto_driver_key_derivation_get_input_size` or `psa_crypto_driver_key_derivation_get_input_bytes` on a data input step which is available as a key input. This is not a fatal error and the driver is expected to call the appropriate function(s) instead.
|
||||
* `PSA_ERROR_DOES_NOT_EXIST`: the input step, is valid for this particular algorithm, but it is not part of the initial inputs. This is not a fatal error. The driver will receive the input later as a [long input](#key-derivation-driver-extra-inputs).
|
||||
* `PSA_ERROR_INVALID_ARGUMENT`: the input step is not valid for this particular algorithm, or the type of the input step is not suitable for this function. This is not a fatal error and the driver can, for example, subsequently call the appropriate function on the same step.
|
||||
* `PSA_ERROR_BUFFER_TOO_SMALL` (`psa_crypto_driver_key_derivation_get_input_bytes` only): the output buffer is too small. This is not a fatal error and the driver can, for example, subsequently call the same function again with a larger buffer. Call `psa_crypto_driver_key_derivation_get_input_size` to obtain the required size.
|
||||
* The core may return other errors such as `PSA_ERROR_CORRUPTION_DETECTED` or `PSA_ERROR_COMMUNICATION_FAILURE` to convey implementation-specific error conditions. Portable drivers should treat such conditions as fatal errors.
|
||||
|
||||
#### Key derivation driver setup
|
||||
|
||||
A key derivation driver must implement the following entry point:
|
||||
```
|
||||
psa_status_t acme_key_derivation_setup(
|
||||
acme_key_derivation_operation_t *operation,
|
||||
psa_algorithm_t alg,
|
||||
const psa_crypto_driver_key_derivation_inputs_t *inputs);
|
||||
```
|
||||
|
||||
* `operation` is a zero-initialized operation object.
|
||||
* `alg` is the algorithm for the key derivation operation. It does not include a key agreement component.
|
||||
* `inputs` is an opaque pointer to the [initial inputs](#key-derivation-driver-initial-inputs) for the key derivation.
|
||||
|
||||
The following process describes how a driver is expected to retrieve the inputs of the key derivation. For each input step that is valid for the algorithm `alg` and is not a [long input](#key-derivation-driver-long-inputs):
|
||||
|
||||
* If the step is a data step and the driver is an opaque driver, call `psa_crypto_driver_key_derivation_get_input_key`. This may either succeed or fail with `PSA_ERROR_INSUFFICIENT_DATA` depending on whether the input comes from the same secure element or not. Note that the driver obtains a pointer key context which only remains valid until the end of the call to the setup entry point. If the driver needs the context in subsequent steps of the operation, it must make a copy.
|
||||
* If the step is a data step and the driver is a transparent driver, or if `psa_crypto_driver_key_derivation_get_input_key` returned `PSA_ERROR_INSUFFICIENT_DATA`, call `psa_crypto_driver_key_derivation_get_input_size` to retrieve the size of the input, then call `psa_crypto_driver_key_derivation_get_input_bytes` with a large enough buffer to retrieve the input data.
|
||||
* If the step is an integer, call `psa_crypto_driver_key_derivation_get_input_integer`.
|
||||
|
||||
#### Key derivation driver long inputs
|
||||
|
||||
Some key derivation algorithms take long inputs which it would not be practical to pass in the [initial inputs](#key-derivation-driver-initial-inputs). A driver that implements a key derivation algorithm that takes such inputs must provide a `"key_derivation_input_step"` entry point. The core calls this input step for all the long inputs, in an unspecified order. Long input steps may be fragmented into multiple calls of `psa_key_derivation_input_bytes()`, and the core may reassemble or refragment those fragments before passing them to the driver.
|
||||
|
||||
```
|
||||
psa_status_t acme_key_derivation_input_step(
|
||||
acme_key_derivation_operation_t *operation,
|
||||
psa_key_derivation_step_t step,
|
||||
const uint8_t *input, size_t input_length);
|
||||
```
|
||||
|
||||
At the time of writing, no standard key derivation algorithm has long inputs. It is likely that such algorithms will be added in the future.
|
||||
|
||||
#### Key derivation driver operation capacity
|
||||
|
||||
The core keeps track of an operation's capacity and enforces it. The core guarantees that it will not request output beyond the capacity of the operation, with one exception: opaque drivers that support `"key_derivation_derive_key"` for key types where the derived key material is not a direct copy of the key derivation's output stream.
|
||||
|
||||
Such drivers must enforce the capacity limitation and must return `PSA_ERROR_INSUFFICIENT_CAPACITY` from any output request that exceeds the operation's capacity. Such drivers must provide the following entry point:
|
||||
```
|
||||
psa_status_t acme_key_derivation_set_capacity(
|
||||
acme_key_derivation_operation_t *operation,
|
||||
size_t capacity);
|
||||
```
|
||||
`capacity` is guaranteed to be less or equal to any value previously set through this entry point, and is guaraneed not to be `PSA_KEY_DERIVATION_UNLIMITED_CAPACITY`.
|
||||
|
||||
If this entry point has not been called, the operation has an unlimited capacity.
|
||||
|
||||
#### Key derivation driver outputs
|
||||
|
||||
A key derivation driver must provide the following entry point:
|
||||
```
|
||||
psa_status_t acme_key_derivation_output_bytes(
|
||||
acme_key_derivation_operation_t *operation,
|
||||
uint8_t *output, size_t length);
|
||||
```
|
||||
|
||||
An opaque key derivation driver may provide the following entry points:
|
||||
```
|
||||
psa_status_t acme_key_derivation_output_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
acme_key_derivation_operation_t *operation,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length);
|
||||
psa_status_t acme_key_derivation_verify_bytes(
|
||||
acme_key_derivation_operation_t *operation,
|
||||
const uint8_t *expected output, size_t length);
|
||||
psa_status_t acme_key_derivation_verify_key(
|
||||
acme_key_derivation_operation_t *operation,
|
||||
uint8_t *key_buffer, size_t key_buffer_size);
|
||||
```
|
||||
|
||||
The core calls a key derivation driver's output entry point when the application calls `psa_key_derivation_output_bytes()`, `psa_key_derivation_output_key()`, `psa_key_derivation_verify_bytes()` or `psa_key_derivation_verify_key()`.
|
||||
|
||||
If the key derivation's `PSA_KEY_DERIVATION_INPUT_SECRET` input is in a secure element and the derivation operation is handled by that secure element, the core performs the following steps:
|
||||
|
||||
1. For a call to `psa_key_derivation_output_key()` where the derived key is in the same secure element, if the driver has an `"key_derivation_output_key"` entry point, call that entry point. If the driver has no such entry point, or if that entry point returns `PSA_ERROR_NOT_SUPPORTED`, continue with the following steps, otherwise stop.
|
||||
1. For a call to `psa_key_derivation_output_key()`, if the driver's capabilities indicate that its `"import_key"` entry point does not support the derived key, stop and return `PSA_ERROR_NOT_SUPPORTED`.
|
||||
1. For a call to `psa_key_derivation_verify_key()`, if the driver has a `"key_derivation_verify_key"` entry point, call it and stop.
|
||||
1. For a call to `psa_key_derivation_verify_key()` or `psa_key_derivation_verify_bytes()`, if the driver has a `"key_derivation_verify_bytes"` entry point, call the driver's `"export_key"` entry point on the key object that contains the expected value, call the `"key_derivation_verify_bytes"` entry point on the exported material, and stop.
|
||||
1. Call the `"key_derivation_output_bytes"` entry point. The core may call this entry point multiple times to implement a single call from the application when deriving a non-raw key or if the output size exceeds some implementation limit.
|
||||
|
||||
If the key derivation operation is not handled by an opaque driver as described above, the core calls the `"key_derivation_output_bytes"` from the applicable transparent driver (or multiple drivers in succession if fallback applies). In some cases, the driver then calls additional entry points in the same or another driver:
|
||||
|
||||
* For a call to `psa_key_derivation_output_key()` for some key types, the core calls a transparent driver's `"derive_key"` entry point. See [“Transparent cooked key derivation”](#transparent-cooked-key-derivation).
|
||||
* For a call to `psa_key_derivation_output_key()` where the derived key is in a secure element, call that secure element driver's `"import_key"` entry point.
|
||||
|
||||
#### Transparent cooked key derivation
|
||||
|
||||
Key derivation is said to be *raw* for some key types, where the key material of a derived (8×*n*)-bit key consists of the next *n* bytes of output from the key derivation, and *cooked* otherwise. When deriving a raw key, the core only calls the driver's `"output_bytes"` entry point, except when deriving a key entirely inside a secure element as described in [“Key derivation driver outputs”](#key-derivation-driver-outputs). When deriving a cooked key, the core calls a transparent driver's `"derive_key"` entry point if available.
|
||||
|
||||
A capability for cooked key derivation contains the following properties (this is not a subset of [the usual entry point properties](#capability-syntax)):
|
||||
|
||||
* `"entry_points"` (mandatory, list of strings). Must be `["derive_key"]`.
|
||||
* `"derived_types"` (mandatory, list of strings). Each element is a [key type specification](#key-type-specifications). This capability only applies when deriving a key of the specified type.
|
||||
* `"derived_sizes"` (optional, list of integers). Each element is a [key type specification](#key-type-specifications). This capability only applies when deriving a key of the specified sizes, in bits. If absent, this capability applies to all sizes for the specified types.
|
||||
* `"memory"` (optional, boolean). If present and true, the driver must define a type `"derive_key_memory_t"` and the core will allocate an object of that type as specified below.
|
||||
* `"names"` (optional, object). A mapping from entry point names to C function and type names, as usual.
|
||||
* `"fallback"` (optional, boolean). If present and true, the driver may return `PSA_ERROR_NOT_SUPPORTED` if it only partially supports the specified mechanism, as usual.
|
||||
|
||||
A transparent driver with the prefix `"acme"` that implements cooked key derivation must provide the following type and function:
|
||||
|
||||
```
|
||||
typedef ... acme_derive_key_memory_t; // only if the "memory" property is true
|
||||
psa_status_t acme_derive_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *input, size_t input_length,
|
||||
acme_derive_key_memory_t *memory, // if the "memory" property is false: void*
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length);
|
||||
```
|
||||
|
||||
* `attributes` contains the attributes of the desired key. Note that only the key type and the bit-size are guaranteed to be set.
|
||||
* `input` is a buffer of `input_length` bytes which contains the raw key stream, i.e. the data that `psa_key_derivation_output_bytes()` would return.
|
||||
* If `"memory"` property in the driver capability is true, `memory` is a data structure that the driver may use to store data between successive calls of the `"derive_key"` entry point to derive the same key. If the `"memory"` property is false or absent, the `memory` parameter is a null pointer.
|
||||
* `key_buffer` is a buffer for the output material. Its size is `key_buffer_size` bytes.
|
||||
* On success, `*key_buffer_length` must contain the number of bytes written to `key_buffer`.
|
||||
|
||||
This entry point may return the following statuses:
|
||||
|
||||
* `PSA_SUCCESS`: a key was derived successfully. The driver has placed representation of the key is in `key_buffer`.
|
||||
* `PSA_ERROR_NOT_SUPPORTED` (for the first call only) (only if fallback is enabled): the driver cannot fulfill this request, but a fallback driver might.
|
||||
* `PSA_ERROR_INSUFFICIENT_DATA`: the core must call the `"derive_key"` entry point again with the same `memory` object and with subsequent data from the key stream.
|
||||
* Any other error is a fatal error.
|
||||
|
||||
The core calls the `"derive_key"` entry point in a loop until it returns a status other than `PSA_ERROR_INSUFFICIENT_DATA`. Each call has a successive fragment of the key stream. The `memory` object is guaranteed to be the same for successive calls, but note that its address may change between calls. Before the first call, `*memory` is initialized to all-bits-zero.
|
||||
|
||||
For standard key types, the `"derive_key"` entry point is called with a certain input length as follows:
|
||||
|
||||
* `PSA_KEY_TYPE_DES`: the length of the key.
|
||||
* `PSA_KEY_TYPE_ECC_KEY_PAIR(…)`, `PSA_KEY_TYPE_DH_KEY_PAIR(…)`: *m* bytes, where the bit-size of the key *n* satisfies *m*-1 < 8×*n* ≤ *m*.
|
||||
* `PSA_KEY_TYPE_RSA_KEY_PAIR`: an implementation-defined length. A future version of this specification may specify a length.
|
||||
* Other key types: not applicable.
|
||||
|
||||
#### Key agreement
|
||||
|
||||
The core always decouples key agreement from symmetric key derivation.
|
||||
|
||||
To implement a call to `psa_key_derivation_key_agreement()` where the private key is in a secure element that has a `"key_agreement_to_key"` entry point which is applicable for the given key type and algorithm, the core calls the secure element driver as follows:
|
||||
|
||||
1. Call the `"key_agreement_to_key"` entry point to create a key object containing the shared secret. The key object is volatile and has the type `PSA_KEY_TYPE_DERIVE`.
|
||||
2. Call the `"key_derivation_setup"` entry point, passing the resulting key object .
|
||||
3. Perform the rest of the key derivation, up to and including the call to the `"key_derivation_abort"` entry point.
|
||||
4. Call the `"destroy_key"` entry point to destroy the key containing the key object.
|
||||
|
||||
In other cases, the core treats `psa_key_derivation_key_agreement()` as if it was a call to `psa_raw_key_agreement()` followed by a call to `psa_key_derivation_input_bytes()` on the shared secret.
|
||||
|
||||
The entry points related to key agreement have the following prototypes for a driver with the prefix `"acme"`:
|
||||
```
|
||||
psa_status_t acme_key_agreement(psa_algorithm_t alg,
|
||||
const uint8_t *our_key_buffer,
|
||||
size_t our_key_buffer_length,
|
||||
const uint8_t *peer_key,
|
||||
size_t peer_key_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length);
|
||||
psa_status_t acme_key_agreement_to_key(psa_algorithm_t alg,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *our_key_buffer,
|
||||
size_t our_key_buffer_length,
|
||||
const uint8_t *peer_key,
|
||||
size_t peer_key_length,
|
||||
uint8_t *shared_secret_key_buffer,
|
||||
size_t shared_secret_key_buffer_size,
|
||||
size_t *shared_secret_key_buffer_length);
|
||||
```
|
||||
|
||||
### Driver entry points for key management
|
||||
|
||||
|
@ -336,8 +562,9 @@ psa_status_t acme_generate_key(const psa_key_attributes_t *attributes,
|
|||
size_t key_buffer_size,
|
||||
size_t *key_buffer_length);
|
||||
```
|
||||
Additionally, opaque drivers can create keys through their [`"key_derivation_output_key"`](#key-derivation-driver-outputs) and [`"key_agreement_key"`](#key-agreement) entry points. Transparent drivers can create key material through their [`"derive_key"`](#transparent-cooked-key-derivation) entry point.
|
||||
|
||||
TODO: derivation, copy
|
||||
TODO: copy
|
||||
|
||||
* The key attributes (`attributes`) have the same semantics as in the PSA Cryptography application interface.
|
||||
* For the `"import_key"` entry point, the input in the `data` buffer is either the export format or an implementation-specific format that the core documents as an acceptable input format for `psa_import_key()`.
|
||||
|
@ -660,7 +887,7 @@ If the key is stored in wrapped form outside the secure element, and the wrapped
|
|||
|
||||
Opaque drivers may provide the following key management entry points:
|
||||
|
||||
* `"export_key"`: called by `psa_export_key()`, or by `psa_copy_key()` when copying a key from or to a different [location](#lifetimes-and-locations).
|
||||
* `"export_key"`: called by `psa_export_key()`, or by `psa_copy_key()` when copying a key from or to a different [location](#lifetimes-and-locations), or [as a fallback for key derivation](#key-derivation-driver-dispatch-logic).
|
||||
* `"export_public_key"`: called by the core to obtain the public key of a key pair. The core may call this entry point at any time to obtain the public key, which can be for `psa_export_public_key()` but also at other times, including during a cryptographic operation that requires the public key such as a call to `psa_verify_message()` on a key pair object.
|
||||
* `"import_key"`: called by `psa_import_key()`, or by `psa_copy_key()` when copying a key from another location.
|
||||
* `"generate_key"`: called by `psa_generate_key()`.
|
||||
|
@ -974,6 +1201,12 @@ An example use case for updating the persistent state at arbitrary times is to r
|
|||
|
||||
`psa_crypto_driver_get_persistent_state` does not identify the calling driver, so the driver needs to remember which driver it's calling. This may require a thread-local variable in a multithreaded core. Is this ok?
|
||||
|
||||
#### Fallback for key derivation in opaque drivers
|
||||
|
||||
Should [dispatch to an opaque driver](#key-derivation-driver-dispatch-logic) allow fallback, so that if `"key_derivation_setup"` returns `PSA_ERROR_NOT_SUPPORTED` then the core exports the key from the secure element instead?
|
||||
|
||||
Should the ["`key_derivation_output_key`"](#key-derivation-driver-outputs) capability indicate which key types the driver can derive? How should fallback work? For example, consider a secure element that implements HMAC, HKDF and ECDSA, and that can derive an HMAC key from HKDF without exporting intermediate material but can only import or randomly generate ECC keys. How does this driver convey that it can't derive an ECC key with HKDF, but it can let the core do this and import the resulting key?
|
||||
|
||||
### Randomness
|
||||
|
||||
#### Input to `"add_entropy"`
|
||||
|
|
Loading…
Reference in a new issue