SE RT Services Utilities library

| SE RT Services Utilities library

Macros | Typedefs | Functions
Key derivation
IFX SE PSA crypto API

## General Description

Key derivation definitions.

## Macros
#define | IFX_SE_KEY_DERIVATION_OPERATION_INIT {0}
| This only zeroes out the first byte in the union, the rest is unspecified.
#define | IFX_SE_KEY_DERIVATION_INPUT_SECRET ((ifx_se_key_derivation_step_t)0x0101)
| A secret input for key derivation. More...
#define | IFX_SE_KEY_DERIVATION_INPUT_PASSWORD ((ifx_se_key_derivation_step_t)0x0102)
| A low-entropy secret input for password hashing / key stretching. More...
#define | IFX_SE_KEY_DERIVATION_INPUT_OTHER_SECRET ((ifx_se_key_derivation_step_t)0x0103)
| A high-entropy additional secret input for key derivation. More...
#define | IFX_SE_KEY_DERIVATION_INPUT_LABEL ((ifx_se_key_derivation_step_t)0x0201)
| A label for key derivation. More...
#define | IFX_SE_KEY_DERIVATION_INPUT_SALT ((ifx_se_key_derivation_step_t)0x0202)
| A salt for key derivation. More...
#define | IFX_SE_KEY_DERIVATION_INPUT_INFO ((ifx_se_key_derivation_step_t)0x0203)
| An information string for key derivation. More...
#define | IFX_SE_KEY_DERIVATION_INPUT_SEED ((ifx_se_key_derivation_step_t)0x0204)
| A seed for key derivation. More...
#define | IFX_SE_KEY_DERIVATION_INPUT_COST ((ifx_se_key_derivation_step_t)0x0205)
| A cost parameter for password hashing / key stretching. More...
#define | IFX_SE_KEY_DERIVATION_INPUT_FIXED_DATA ((ifx_se_key_derivation_step_t)0x0206)
| Fixed data for the key derivation. More...

## Typedefs
typedef struct ifx_se_key_derivation_s | ifx_se_key_derivation_operation_t
| The type of the state data structure for key derivation operations. More...
typedef uint16_t | ifx_se_key_derivation_step_t
| Encoding of the step of a key derivation.

## Functions
ifx_se_status_t | ifx_se_key_derivation_abort (ifx_se_key_derivation_operation_t *operation, void *ctx)
| Abort a key derivation operation. More...
ifx_se_status_t | ifx_se_key_derivation_setup (ifx_se_key_derivation_operation_t *operation, ifx_se_alg_fih_t alg, void *ctx)
| Set up a key derivation operation. More...
ifx_se_status_t | ifx_se_key_derivation_get_capacity (const ifx_se_key_derivation_operation_t *operation, ifx_se_fih_ptr_t capacity, void *ctx)
| Retrieve the current capacity of a key derivation operation. More...
ifx_se_status_t | ifx_se_key_derivation_set_capacity (ifx_se_key_derivation_operation_t *operation, ifx_se_fih_t capacity, void *ctx)
| Set the maximum capacity of a key derivation operation. More...
ifx_se_status_t | ifx_se_key_derivation_input_key (ifx_se_key_derivation_operation_t *operation, ifx_se_key_derivation_step_t step, ifx_se_key_id_fih_t key, void *ctx)
| Provide an input for key derivation in the form of a key. More...
ifx_se_status_t | ifx_se_key_derivation_input_bytes (ifx_se_key_derivation_operation_t *operation, ifx_se_key_derivation_step_t step, const ifx_se_fih_ptr_t data, ifx_se_fih_t data_length, void *ctx)
| Provide an input for key derivation or key agreement. More...
ifx_se_status_t | ifx_se_key_derivation_output_bytes (ifx_se_key_derivation_operation_t *operation, ifx_se_fih_ptr_t output, ifx_se_fih_t output_length, void *ctx)
| Read some data from a key derivation operation. More...
ifx_se_status_t | ifx_se_key_derivation_output_key (const ifx_se_key_attributes_t *attributes, ifx_se_key_derivation_operation_t *operation, ifx_se_fih_ptr_t key, void *ctx)
| Derive a key from an ongoing key derivation operation. More...
ifx_se_status_t | ifx_se_key_derivation_key_agreement (ifx_se_key_derivation_operation_t *operation, ifx_se_key_derivation_step_t step, ifx_se_key_id_fih_t private_key, const ifx_se_fih_ptr_t peer_key, ifx_se_fih_t peer_key_length, void *ctx)
| Perform a key agreement and use the shared secret as input to a key derivation. More...
ifx_se_status_t | ifx_se_raw_key_agreement (ifx_se_alg_fih_t alg, ifx_se_key_id_fih_t private_key, const ifx_se_fih_ptr_t peer_key, ifx_se_fih_t peer_key_length, ifx_se_fih_ptr_t output, ifx_se_fih_t output_size, ifx_se_fih_ptr_t output_length, void *ctx)
| Perform a key agreement and return the raw shared secret. More...
static struct ifx_se_key_derivation_s | ifx_se_key_derivation_operation_init (void)
| Initialize the key derivation context. More...

## Macro Definition Documentation

## ◆ IFX_SE_KEY_DERIVATION_INPUT_SECRET

#define IFX_SE_KEY_DERIVATION_INPUT_SECRET ((ifx_se_key_derivation_step_t)0x0101)

A secret input for key derivation.

This should be a key of type IFX_SE_KEY_TYPE_DERIVE (passed to ifx_se_key_derivation_input_key()) or the shared secret resulting from a key agreement (obtained via ifx_se_key_derivation_key_agreement()).

The secret can also be a direct input (passed to key_derivation_input_bytes()). In this case, the derivation operation may not be used to derive keys: the operation will only allow ifx_se_key_derivation_output_bytes(), ifx_se_key_derivation_verify_bytes(), or ifx_se_key_derivation_verify_key(), but not ifx_se_key_derivation_output_key().

## ◆ IFX_SE_KEY_DERIVATION_INPUT_PASSWORD

#define IFX_SE_KEY_DERIVATION_INPUT_PASSWORD ((ifx_se_key_derivation_step_t)0x0102)

A low-entropy secret input for password hashing / key stretching.

This is usually a key of type IFX_SE_KEY_TYPE_PASSWORD (passed to ifx_se_key_derivation_input_key()) or a direct input (passed to ifx_se_key_derivation_input_bytes()) that is a password or passphrase. It can also be high-entropy secret such as a key of type IFX_SE_KEY_TYPE_DERIVE or the shared secret resulting from a key agreement.

The secret can also be a direct input (passed to key_derivation_input_bytes()). In this case, the derivation operation may not be used to derive keys: the operation will only allow ifx_se_key_derivation_output_bytes(), ifx_se_key_derivation_verify_bytes(), or ifx_se_key_derivation_verify_key(), but not ifx_se_key_derivation_output_key().

## ◆ IFX_SE_KEY_DERIVATION_INPUT_OTHER_SECRET

#define IFX_SE_KEY_DERIVATION_INPUT_OTHER_SECRET ((ifx_se_key_derivation_step_t)0x0103)

A high-entropy additional secret input for key derivation.

This is typically the shared secret resulting from a key agreement obtained via `ifx_se_key_derivation_key_agreement()`. It may alternatively be a key of type `IFX_SE_KEY_TYPE_DERIVE` passed to `ifx_se_key_derivation_input_key()`, or a direct input passed to `ifx_se_key_derivation_input_bytes()`.

## ◆ IFX_SE_KEY_DERIVATION_INPUT_LABEL

#define IFX_SE_KEY_DERIVATION_INPUT_LABEL ((ifx_se_key_derivation_step_t)0x0201)

A label for key derivation.

This should be a direct input. It can also be a key of type IFX_SE_KEY_TYPE_RAW_DATA.

## ◆ IFX_SE_KEY_DERIVATION_INPUT_SALT

#define IFX_SE_KEY_DERIVATION_INPUT_SALT ((ifx_se_key_derivation_step_t)0x0202)

A salt for key derivation.

This should be a direct input. It can also be a key of type IFX_SE_KEY_TYPE_RAW_DATA or IFX_SE_KEY_TYPE_PEPPER.

## ◆ IFX_SE_KEY_DERIVATION_INPUT_INFO

#define IFX_SE_KEY_DERIVATION_INPUT_INFO ((ifx_se_key_derivation_step_t)0x0203)

An information string for key derivation.

This should be a direct input. It can also be a key of type IFX_SE_KEY_TYPE_RAW_DATA.

## ◆ IFX_SE_KEY_DERIVATION_INPUT_SEED

#define IFX_SE_KEY_DERIVATION_INPUT_SEED ((ifx_se_key_derivation_step_t)0x0204)

A seed for key derivation.

This should be a direct input. It can also be a key of type IFX_SE_KEY_TYPE_RAW_DATA.

## ◆ IFX_SE_KEY_DERIVATION_INPUT_COST

#define IFX_SE_KEY_DERIVATION_INPUT_COST ((ifx_se_key_derivation_step_t)0x0205)

A cost parameter for password hashing / key stretching.

This must be a direct input, passed to ifx_se_key_derivation_input_integer().

## ◆ IFX_SE_KEY_DERIVATION_INPUT_FIXED_DATA

#define IFX_SE_KEY_DERIVATION_INPUT_FIXED_DATA ((ifx_se_key_derivation_step_t)0x0206)

Fixed data for the key derivation.

This should be a direct input.

## Typedef Documentation

## ◆ ifx_se_key_derivation_operation_t

typedef struct ifx_se_key_derivation_s ifx_se_key_derivation_operation_t

The type of the state data structure for key derivation operations.

This is an implementation-defined `struct`. Applications should not make any assumptions about the content of this structure except as directed by the documentation of a specific implementation.

## Function Documentation

## ◆ ifx_se_key_derivation_abort()

ifx_se_status_t ifx_se_key_derivation_abort | ( | ifx_se_key_derivation_operation_t * | operation,
|  | void * | ctx
| ) |  |

Abort a key derivation operation.

Aborting an operation frees all associated resources except for the `operation` structure itself. Once aborted, the operation object can be reused for another operation by calling ifx_se_key_derivation_setup() again.

This function may be called at any time after the operation object has been initialized as described in ifx_se_key_derivation_operation_t.

In particular, it is valid to call ifx_se_key_derivation_abort() twice, or to call ifx_se_key_derivation_abort() on an operation that has not been set up.

Parameters

  [in,out] | operation | The operation to abort.
  [in] | ctx | The pointer to the SE syscall context that contain a special syscall data (IPC release callback etc).

Return values

  IFX_SE_SUCCESS |
  IFX_SE_ERROR_COMMUNICATION_FAILURE |
  IFX_SE_ERROR_HARDWARE_FAILURE |
  IFX_SE_ERROR_CORRUPTION_DETECTED |

## ◆ ifx_se_key_derivation_setup()

ifx_se_status_t ifx_se_key_derivation_setup | ( | ifx_se_key_derivation_operation_t * | operation,
|  | ifx_se_alg_fih_t | alg,
|  | void * | ctx
| ) |  |

Set up a key derivation operation.

A key derivation algorithm takes some inputs and uses them to generate a byte stream in a deterministic way. This byte stream can be used to produce keys and other cryptographic material.

To derive a key:

1. Start with an initialized object of type ifx_se_key_derivation_operation_t.
2. Call ifx_se_key_derivation_setup() to select the algorithm.
3. Provide the inputs for the key derivation by calling ifx_se_key_derivation_input_bytes() or ifx_se_key_derivation_input_key() as appropriate. Which inputs are needed, in what order, and whether they may be keys and if so of what type depends on the algorithm.
4. Optionally set the operation's maximum capacity with ifx_se_key_derivation_set_capacity(). You may do this before, in the middle of or after providing inputs. For some algorithms, this step is mandatory because the output depends on the maximum capacity.
5. To derive a key, call ifx_se_key_derivation_output_key(). To derive a byte string for a different purpose, call ifx_se_key_derivation_output_bytes(). Successive calls to these functions use successive output bytes calculated by the key derivation algorithm.
6. Clean up the key derivation operation object with ifx_se_key_derivation_abort().

If this function returns an error, the key derivation operation object is not changed.

If an error occurs at any step after a call to ifx_se_key_derivation_setup(), the operation will need to be reset by a call to ifx_se_key_derivation_abort().

Implementations must reject an attempt to derive a key of size 0.

Parameters

  [in,out] | operation | The key derivation operation object to set up. It must have been initialized but not set up yet.
  [in] | alg | The key derivation algorithm to compute (`IFX_SE_ALG_XXX` value such that IFX_SE_ALG_IS_KEY_DERIVATION(`alg`) is true).
  [in] | ctx | The pointer to the SE syscall context that contain a special syscall data (IPC release callback etc).

Return values

  IFX_SE_SUCCESS | Success.
  IFX_SE_ERROR_INVALID_ARGUMENT | `alg` is not a key derivation algorithm.
  IFX_SE_ERROR_NOT_SUPPORTED | `alg` is not supported or is not a key derivation algorithm.
  IFX_SE_ERROR_INSUFFICIENT_MEMORY |
  IFX_SE_ERROR_COMMUNICATION_FAILURE |
  IFX_SE_ERROR_HARDWARE_FAILURE |
  IFX_SE_ERROR_CORRUPTION_DETECTED |
  IFX_SE_ERROR_STORAGE_FAILURE |
  IFX_SE_ERROR_BAD_STATE | The operation state is not valid (it must be inactive).

## ◆ ifx_se_key_derivation_get_capacity()

ifx_se_status_t ifx_se_key_derivation_get_capacity | ( | const ifx_se_key_derivation_operation_t * | operation,
|  | ifx_se_fih_ptr_t | capacity,
|  | void * | ctx
| ) |  |

Retrieve the current capacity of a key derivation operation.

The capacity of a key derivation is the maximum number of bytes that it can return. When you get N bytes of output from a key derivation operation, this reduces its capacity by N.

Parameters

  [in] | operation | The operation to query.
  [out] | capacity | On success, the capacity of the operation (encoded pointer to size_t variable).
  [in] | ctx | The pointer to the SE syscall context that contain a special syscall data (IPC release callback etc).

Return values

  IFX_SE_SUCCESS |
  IFX_SE_ERROR_COMMUNICATION_FAILURE |
  IFX_SE_ERROR_HARDWARE_FAILURE |
  IFX_SE_ERROR_CORRUPTION_DETECTED |
  IFX_SE_ERROR_BAD_STATE | The operation state is not valid (it must be active).

## ◆ ifx_se_key_derivation_set_capacity()

ifx_se_status_t ifx_se_key_derivation_set_capacity | ( | ifx_se_key_derivation_operation_t * | operation,
|  | ifx_se_fih_t | capacity,
|  | void * | ctx
| ) |  |

Set the maximum capacity of a key derivation operation.

The capacity of a key derivation operation is the maximum number of bytes that the key derivation operation can return from this point onwards.

Parameters

  [in,out] | operation | The key derivation operation object to modify.
  [in] | capacity | The new capacity of the operation. It must be less or equal to the operation's current capacity.
  [in] | ctx | The pointer to the SE syscall context that contain a special syscall data (IPC release callback etc).

Return values

  IFX_SE_SUCCESS |
  IFX_SE_ERROR_INVALID_ARGUMENT | `capacity` is larger than the operation's current capacity. In this case, the operation object remains valid and its capacity remains unchanged.
  IFX_SE_ERROR_COMMUNICATION_FAILURE |
  IFX_SE_ERROR_HARDWARE_FAILURE |
  IFX_SE_ERROR_CORRUPTION_DETECTED |
  IFX_SE_ERROR_BAD_STATE | The operation state is not valid (it must be active).

## ◆ ifx_se_key_derivation_input_key()

ifx_se_status_t ifx_se_key_derivation_input_key | ( | ifx_se_key_derivation_operation_t * | operation,
|  | ifx_se_key_derivation_step_t | step,
|  | ifx_se_key_id_fih_t | key,
|  | void * | ctx
| ) |  |

Provide an input for key derivation in the form of a key.

Which inputs are required and in what order depends on the algorithm. Refer to the documentation of each key derivation or key agreement algorithm for information.

This function obtains input from a key object, which is usually correct for secret inputs or for non-secret personalization strings kept in the key store. To pass a non-secret parameter which is not in the key store, call ifx_se_key_derivation_input_bytes() instead of this function. Refer to the documentation of individual step types (`IFX_SE_KEY_DERIVATION_INPUT_xxx` values of type ifx_se_key_derivation_step_t) for more information.

If this function returns an error status, the operation enters an error state and must be aborted by calling ifx_se_key_derivation_abort().

Parameters

  [in,out] | operation | The key derivation operation object to use. It must have been set up with ifx_se_key_derivation_setup() and must not have produced any output yet.
  [in] | step | Which step the input data is for.
  [in] | key | Identifier of the key. It must have an appropriate type for step and must allow the usage IFX_SE_KEY_USAGE_DERIVE or IFX_SE_KEY_USAGE_VERIFY_DERIVATION (see note) and the algorithm used by the operation.
  [in] | ctx | The pointer to the SE syscall context that contain a special syscall data (IPC release callback etc).

Note
  Once all inputs steps are completed, the operations will allow:
  - ifx_se_key_derivation_output_bytes() if each input was either a direct input or a key with IFX_SE_KEY_USAGE_DERIVE set;
  - ifx_se_key_derivation_output_key() if the input for step IFX_SE_KEY_DERIVATION_INPUT_SECRET or IFX_SE_KEY_DERIVATION_INPUT_PASSWORD was from a key slot with IFX_SE_KEY_USAGE_DERIVE and each other input was either a direct input or a key with IFX_SE_KEY_USAGE_DERIVE set;
  - ifx_se_key_derivation_verify_bytes() if each input was either a direct input or a key with IFX_SE_KEY_USAGE_VERIFY_DERIVATION set;
  - ifx_se_key_derivation_verify_key() under the same conditions as ifx_se_key_derivation_verify_bytes().

Return values

  IFX_SE_SUCCESS | Success.
  IFX_SE_ERROR_INVALID_HANDLE |
  IFX_SE_ERROR_NOT_PERMITTED | The key allows neither IFX_SE_KEY_USAGE_DERIVE nor IFX_SE_KEY_USAGE_VERIFY_DERIVATION, or it doesn't allow this algorithm. Also operation rejected with this response when HUK key is selected in SECURE life cycle and debug port is opened or enabled by policy.
  IFX_SE_ERROR_INVALID_ARGUMENT | `step` is not compatible with the operation's algorithm, or `step` does not allow key inputs of the given type or does not allow key inputs at all.
  IFX_SE_ERROR_INSUFFICIENT_MEMORY |
  IFX_SE_ERROR_COMMUNICATION_FAILURE |
  IFX_SE_ERROR_HARDWARE_FAILURE |
  IFX_SE_ERROR_CORRUPTION_DETECTED |
  IFX_SE_ERROR_STORAGE_FAILURE |
  IFX_SE_ERROR_BAD_STATE | The operation state is not valid for this input `step`.

## ◆ ifx_se_key_derivation_input_bytes()

ifx_se_status_t ifx_se_key_derivation_input_bytes | ( | ifx_se_key_derivation_operation_t * | operation,
|  | ifx_se_key_derivation_step_t | step,
|  | const ifx_se_fih_ptr_t | data,
|  | ifx_se_fih_t | data_length,
|  | void * | ctx
| ) |  |

Provide an input for key derivation or key agreement.

Which inputs are required and in what order depends on the algorithm. Refer to the documentation of each key derivation or key agreement algorithm for information.

This function passes direct inputs, which is usually correct for non-secret inputs. To pass a secret input, which should be in a key object, call ifx_se_key_derivation_input_key() instead of this function. Refer to the documentation of individual step types (`IFX_SE_KEY_DERIVATION_INPUT_xxx` values of type ifx_se_key_derivation_step_t) for more information.

If this function returns an error status, the operation enters an error state and must be aborted by calling ifx_se_key_derivation_abort().

Parameters

  [in,out] | operation | The key derivation operation object to use. It must have been set up with ifx_se_key_derivation_setup() and must not have produced any output yet.
  [in] | step | Which step the input data is for.
  [in] | data | Input data to use (encoded pointer to input data).
  [in] | data_length | Size of the `data` buffer in bytes (size_t).
  [in] | ctx | The pointer to the SE syscall context that contain a special syscall data (IPC release callback etc).

Return values

  IFX_SE_SUCCESS | Success.
  IFX_SE_ERROR_INVALID_ARGUMENT | `step` is not compatible with the operation's algorithm, or `step` does not allow direct inputs.
  IFX_SE_ERROR_INSUFFICIENT_MEMORY |
  IFX_SE_ERROR_COMMUNICATION_FAILURE |
  IFX_SE_ERROR_HARDWARE_FAILURE |
  IFX_SE_ERROR_CORRUPTION_DETECTED |
  IFX_SE_ERROR_STORAGE_FAILURE |
  IFX_SE_ERROR_BAD_STATE | The operation state is not valid for this input `step`.

## ◆ ifx_se_key_derivation_output_bytes()

ifx_se_status_t ifx_se_key_derivation_output_bytes | ( | ifx_se_key_derivation_operation_t * | operation,
|  | ifx_se_fih_ptr_t | output,
|  | ifx_se_fih_t | output_length,
|  | void * | ctx
| ) |  |

Read some data from a key derivation operation.

This function calculates output bytes from a key derivation algorithm and return those bytes. If you view the key derivation's output as a stream of bytes, this function destructively reads the requested number of bytes from the stream. The operation's capacity decreases by the number of bytes read.

If this function returns an error status other than IFX_SE_ERROR_INSUFFICIENT_DATA, the operation enters an error state and must be aborted by calling ifx_se_key_derivation_abort().

Parameters

  [in,out] | operation | The key derivation operation object to read from.
  [out] | output | Buffer where the output will be written (encoded pointer to output buffer).
  [in] | output_length | Number of bytes to output.
  [in] | ctx | The pointer to the SE syscall context that contain a special syscall data (IPC release callback etc).

Return values

  IFX_SE_SUCCESS |
  IFX_SE_ERROR_NOT_PERMITTED | One of the inputs was a key whose policy didn't allow IFX_SE_KEY_USAGE_DERIVE.
  IFX_SE_ERROR_INSUFFICIENT_DATA | The operation's capacity was less than `output_length` bytes. Note that in this case, no output is written to the output buffer. The operation's capacity is set to 0, thus subsequent calls to this function will not succeed, even with a smaller output buffer.
  IFX_SE_ERROR_INSUFFICIENT_MEMORY |
  IFX_SE_ERROR_COMMUNICATION_FAILURE |
  IFX_SE_ERROR_HARDWARE_FAILURE |
  IFX_SE_ERROR_CORRUPTION_DETECTED |
  IFX_SE_ERROR_STORAGE_FAILURE |
  IFX_SE_ERROR_BAD_STATE | The operation state is not valid (it must be active and completed all required input steps).

## ◆ ifx_se_key_derivation_output_key()

ifx_se_status_t ifx_se_key_derivation_output_key | ( | const ifx_se_key_attributes_t * | attributes,
|  | ifx_se_key_derivation_operation_t * | operation,
|  | ifx_se_fih_ptr_t | key,
|  | void * | ctx
| ) |  |

Derive a key from an ongoing key derivation operation.

This function calculates output bytes from a key derivation algorithm and uses those bytes to generate a key deterministically. The key's location, usage policy, type and size are taken from `attributes`.

If you view the key derivation's output as a stream of bytes, this function destructively reads as many bytes as required from the stream. The operation's capacity decreases by the number of bytes read.

If this function returns an error status other than IFX_SE_ERROR_INSUFFICIENT_DATA, the operation enters an error state and must be aborted by calling ifx_se_key_derivation_abort().

How much output is produced and consumed from the operation, and how the key is derived, depends on the key type and on the key size (denoted `bits` below):

- For key types for which the key is an arbitrary sequence of bytes of a given size, this function is functionally equivalent to calling ifx_se_key_derivation_output_bytes and passing the resulting output to ifx_se_import_key. However, this function has a security benefit: if the implementation provides an isolation boundary then the key material is not exposed outside the isolation boundary. As a consequence, for these key types, this function always consumes exactly (`bits` / 8) bytes from the operation. The following key types defined in this specification follow this scheme:
  - IFX_SE_KEY_TYPE_AES;
  - IFX_SE_KEY_TYPE_ARIA;
  - IFX_SE_KEY_TYPE_CAMELLIA;
  - IFX_SE_KEY_TYPE_DERIVE;
  - IFX_SE_KEY_TYPE_HMAC;
  - IFX_SE_KEY_TYPE_PASSWORD_HASH.
- For ECC keys on a Montgomery elliptic curve (IFX_SE_KEY_TYPE_ECC_KEY_PAIR(`curve`) where `curve` designates a Montgomery curve), this function always draws a byte string whose length is determined by the curve, and sets the mandatory bits accordingly. That is:
  - Curve25519 (IFX_SE_ECC_FAMILY_MONTGOMERY, 255 bits): draw a 32-byte string and process it as specified in RFC 7748 §5.
  - Curve448 (IFX_SE_ECC_FAMILY_MONTGOMERY, 448 bits): draw a 56-byte string and process it as specified in RFC 7748 §5.
- For key types for which the key is represented by a single sequence of `bits` bits with constraints as to which bit sequences are acceptable, this function draws a byte string of length (`bits` / 8) bytes rounded up to the nearest whole number of bytes. If the resulting byte string is acceptable, it becomes the key, otherwise the drawn bytes are discarded. This process is repeated until an acceptable byte string is drawn. The byte string drawn from the operation is interpreted as specified for the output produced by ifx_se_export_key(). The following key types defined in this specification follow this scheme:
  - IFX_SE_KEY_TYPE_DES. Force-set the parity bits, but discard forbidden weak keys. For 2-key and 3-key triple-DES, the three keys are generated successively (for example, for 3-key triple-DES, if the first 8 bytes specify a weak key and the next 8 bytes do not, discard the first 8 bytes, use the next 8 bytes as the first key, and continue reading output from the operation to derive the other two keys).
  - Finite-field Diffie-Hellman keys (IFX_SE_KEY_TYPE_DH_KEY_PAIR(`group`) where `group` designates any Diffie-Hellman group) and ECC keys on a Weierstrass elliptic curve (IFX_SE_KEY_TYPE_ECC_KEY_PAIR(`curve`) where `curve` designates a Weierstrass curve). For these key types, interpret the byte string as integer in big-endian order. Discard it if it is not in the range [0, N - 2] where N is the boundary of the private key domain (the prime p for Diffie-Hellman, the subprime q for DSA, or the order of the curve's base point for ECC). Add 1 to the resulting integer and use this as the private key x. This method allows compliance to NIST standards, specifically the methods titled "key-pair generation by testing candidates" in NIST SP 800-56A §5.6.1.1.4 for Diffie-Hellman, in FIPS 186-4 §B.1.2 for DSA, and in NIST SP 800-56A §5.6.1.2.2 or FIPS 186-4 §B.4.2 for elliptic curve keys.
- For other key types, including IFX_SE_KEY_TYPE_RSA_KEY_PAIR, the way in which the operation output is consumed is implementation-defined.

In all cases, the data that is read is discarded from the operation. The operation's capacity is decreased by the number of bytes read.

For algorithms that take an input step IFX_SE_KEY_DERIVATION_INPUT_SECRET, the input to that step must be provided with ifx_se_key_derivation_input_key(). Future versions of this specification may include additional restrictions on the derived key based on the attributes and strength of the secret key.

Parameters

  [in] | attributes | The attributes for the new key. If the key type to be created is IFX_SE_KEY_TYPE_PASSWORD_HASH then the algorithm in the policy must be the same as in the current operation.
  [in,out] | operation | The key derivation operation object to read from.
  [out] | key | On success, an identifier for the newly created key (encoded pointer to ifx_se_key_id_fih_t variable). For persistent keys, this is the key identifier defined in `attributes`. `0` on failure.
  [in] | ctx | The pointer to the SE syscall context that contain a special syscall data (IPC release callback etc).

Return values

  IFX_SE_SUCCESS | Success. If the key is persistent, the key material and the key's metadata have been saved to persistent storage.
  IFX_SE_ERROR_ALREADY_EXISTS | This is an attempt to create a persistent key, and there is already a persistent key with the given identifier.
  IFX_SE_ERROR_INSUFFICIENT_DATA | There was not enough data to create the desired key. Note that in this case, no output is written to the output buffer. The operation's capacity is set to 0, thus subsequent calls to this function will not succeed, even with a smaller output buffer.
  IFX_SE_ERROR_NOT_SUPPORTED | The key type or key size is not supported, either by the implementation in general or in this particular location.
  IFX_SE_ERROR_INVALID_ARGUMENT | The provided key attributes are not valid for the operation.
  IFX_SE_ERROR_NOT_PERMITTED | The IFX_SE_KEY_DERIVATION_INPUT_SECRET or IFX_SE_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a key; or one of the inputs was a key whose policy didn't allow IFX_SE_KEY_USAGE_DERIVE.
  IFX_SE_ERROR_INSUFFICIENT_MEMORY |
  IFX_SE_ERROR_INSUFFICIENT_STORAGE |
  IFX_SE_ERROR_COMMUNICATION_FAILURE |
  IFX_SE_ERROR_HARDWARE_FAILURE |
  IFX_SE_ERROR_CORRUPTION_DETECTED |
  IFX_SE_ERROR_DATA_INVALID |
  IFX_SE_ERROR_DATA_CORRUPT |
  IFX_SE_ERROR_STORAGE_FAILURE |
  IFX_SE_ERROR_BAD_STATE | The operation state is not valid (it must be active and completed all required input steps).

## ◆ ifx_se_key_derivation_key_agreement()

ifx_se_status_t ifx_se_key_derivation_key_agreement | ( | ifx_se_key_derivation_operation_t * | operation,
|  | ifx_se_key_derivation_step_t | step,
|  | ifx_se_key_id_fih_t | private_key,
|  | const ifx_se_fih_ptr_t | peer_key,
|  | ifx_se_fih_t | peer_key_length,
|  | void * | ctx
| ) |  |

Perform a key agreement and use the shared secret as input to a key derivation.

A key agreement algorithm takes two inputs: a private key `private_key` a public key `peer_key`. The result of this function is passed as input to a key derivation. The output of this key derivation can be extracted by reading from the resulting operation to produce keys and other cryptographic material.

If this function returns an error status, the operation enters an error state and must be aborted by calling ifx_se_key_derivation_abort().

Parameters

  [in,out] | operation | The key derivation operation object to use. It must have been set up with ifx_se_key_derivation_setup() with a key agreement and derivation algorithm `alg` (`IFX_SE_ALG_XXX` value such that IFX_SE_ALG_IS_KEY_AGREEMENT(`alg`) is true and IFX_SE_ALG_IS_RAW_KEY_AGREEMENT(`alg`) is false). The operation must be ready for an input of the type given by `step`.
  [in] | step | Which step the input data is for.
  [in] | private_key | Identifier of the private key to use. It must allow the usage IFX_SE_KEY_USAGE_DERIVE.
  [in] | peer_key | Public key of the peer (encoded pointer to input data). The peer key must be in the same format that ifx_se_import_key() accepts for the public key type corresponding to the type of private_key. That is, this function performs the equivalent of ifx_se_import_key(..., `peer_key`, `peer_key_length`) where with key attributes indicating the public key type corresponding to the type of `private_key`. For example, for EC keys, this means that peer_key is interpreted as a point on the curve that the private key is on. The standard formats for public keys are documented in the documentation of ifx_se_export_public_key().
  [in] | peer_key_length | Size of `peer_key` in bytes (size_t).
  [in] | ctx | The pointer to the SE syscall context that contain a special syscall data (IPC release callback etc).

Return values

  IFX_SE_SUCCESS | Success.
  IFX_SE_ERROR_INVALID_HANDLE |
  IFX_SE_ERROR_NOT_PERMITTED |
  IFX_SE_ERROR_INVALID_ARGUMENT | `private_key` is not compatible with `alg`, or `peer_key` is not valid for `alg` or not compatible with `private_key`, or `step` does not allow an input resulting from a key agreement.
  IFX_SE_ERROR_NOT_SUPPORTED | `alg` is not supported or is not a key derivation algorithm.
  IFX_SE_ERROR_INSUFFICIENT_MEMORY |
  IFX_SE_ERROR_COMMUNICATION_FAILURE |
  IFX_SE_ERROR_HARDWARE_FAILURE |
  IFX_SE_ERROR_CORRUPTION_DETECTED |
  IFX_SE_ERROR_STORAGE_FAILURE |
  IFX_SE_ERROR_BAD_STATE | The operation state is not valid for this key agreement `step`, or the library has not been previously initialized by ifx_se_crypto_init(). It is implementation-dependent whether a failure to initialize results in this error code.

## ◆ ifx_se_raw_key_agreement()

ifx_se_status_t ifx_se_raw_key_agreement | ( | ifx_se_alg_fih_t | alg,
|  | ifx_se_key_id_fih_t | private_key,
|  | const ifx_se_fih_ptr_t | peer_key,
|  | ifx_se_fih_t | peer_key_length,
|  | ifx_se_fih_ptr_t | output,
|  | ifx_se_fih_t | output_size,
|  | ifx_se_fih_ptr_t | output_length,
|  | void * | ctx
| ) |  |

Perform a key agreement and return the raw shared secret.

Warning
  The raw result of a key agreement algorithm such as finite-field Diffie-Hellman or elliptic curve Diffie-Hellman has biases and should not be used directly as key material. It should instead be passed as input to a key derivation algorithm. To chain a key agreement with a key derivation, use ifx_se_key_derivation_key_agreement() and other functions from the key derivation interface.

Parameters

  | alg | The key agreement algorithm to compute (`IFX_SE_ALG_XXX` value such that IFX_SE_ALG_IS_RAW_KEY_AGREEMENT(`alg`) is true).
  [in] | private_key | Identifier of the private key to use. It must allow the usage IFX_SE_KEY_USAGE_DERIVE.
  [in] | peer_key | Public key of the peer (encoded pointer to input data). It must be in the same format that ifx_se_import_key() accepts. The standard formats for public keys are documented in the documentation of ifx_se_export_public_key().
  [in] | peer_key_length | Size of `peer_key` in bytes (size_t).
  [out] | output | Buffer where the raw shared secret is to be written (encoded pointer to output buffer).
  [in] | output_size | Size of the `output` buffer in bytes (size_t).
  [out] | output_length | On success, the number of bytes that make up the returned output (encoded pointer to size_t variable).
  [in] | ctx | The pointer to the SE syscall context that contain a special syscall data (IPC release callback etc).

Return values

  IFX_SE_SUCCESS | Success.
  IFX_SE_ERROR_INVALID_HANDLE |
  IFX_SE_ERROR_NOT_PERMITTED |
  IFX_SE_ERROR_INVALID_ARGUMENT | `alg` is not a key agreement algorithm, or `private_key` is not compatible with `alg`, or `peer_key` is not valid for `alg` or not compatible with `private_key`.
  IFX_SE_ERROR_BUFFER_TOO_SMALL | `output_size` is too small
  IFX_SE_ERROR_NOT_SUPPORTED | `alg` is not a supported key agreement algorithm.
  IFX_SE_ERROR_INSUFFICIENT_MEMORY |
  IFX_SE_ERROR_COMMUNICATION_FAILURE |
  IFX_SE_ERROR_HARDWARE_FAILURE |
  IFX_SE_ERROR_CORRUPTION_DETECTED |
  IFX_SE_ERROR_STORAGE_FAILURE |
  IFX_SE_ERROR_BAD_STATE | The library has not been previously initialized by ifx_se_crypto_init(). It is implementation-dependent whether a failure to initialize results in this error code.

## ◆ ifx_se_key_derivation_operation_init()

static struct ifx_se_key_derivation_s ifx_se_key_derivation_operation_init | ( | void |  | ) |
| inlinestatic

Initialize the key derivation context.

Returns
  ifx_se_key_derivation_s structure