SE RT Services Utilities library

| SE RT Services Utilities library

Functions
Key import and export
IFX SE PSA crypto API

## General Description

Key import and export definitions.

## Functions
ifx_se_status_t | ifx_se_destroy_key (ifx_se_key_id_fih_t key, void *ctx)
| Destroy a key. More...
ifx_se_status_t | ifx_se_purge_key (ifx_se_key_id_fih_t key, void *ctx)
| Remove non-essential copies of key material from memory. More...
ifx_se_status_t | ifx_se_generate_key (const ifx_se_key_attributes_t *attributes, ifx_se_fih_ptr_t key, void *ctx)
| Generate a key or key pair. More...
ifx_se_status_t | ifx_se_import_key (const ifx_se_key_attributes_t *attributes, const ifx_se_fih_ptr_t data, ifx_se_fih_t data_length, ifx_se_fih_ptr_t key, void *ctx)
| Import a key in binary format. More...
ifx_se_status_t | ifx_se_export_key (ifx_se_key_id_fih_t key, ifx_se_fih_ptr_t data, ifx_se_fih_t data_size, ifx_se_fih_ptr_t data_length, void *ctx)
| Export a key in binary format. More...
ifx_se_status_t | ifx_se_export_public_key (ifx_se_key_id_fih_t key, ifx_se_fih_ptr_t data, ifx_se_fih_t data_size, ifx_se_fih_ptr_t data_length, void *ctx)
| Export a public key or the public part of a key pair in binary format. More...
ifx_se_status_t | ifx_se_copy_key (ifx_se_key_id_fih_t source_key, const ifx_se_key_attributes_t *attributes, ifx_se_fih_ptr_t target_key, void *ctx)
| Make a copy of a key. More...

## Function Documentation

## ◆ ifx_se_destroy_key()

ifx_se_status_t ifx_se_destroy_key | ( | ifx_se_key_id_fih_t | key,
|  | void * | ctx
| ) |  |

Destroy a key.

This function destroys a key from both volatile memory and, if applicable, non-volatile storage. Implementations shall make a best effort to ensure that that the key material cannot be recovered.

This function also erases any metadata such as policies and frees resources associated with the key.

If a key is currently in use in a multipart operation, then destroying the key will cause the multipart operation to fail.

Parameters

  [in] | key | Identifier of the key to erase. If this is `0`, do nothing and return IFX_SE_SUCCESS.
  [in] | ctx | The pointer to the SE syscall context that contain a special syscall data (IPC release callback etc).

Return values

  IFX_SE_SUCCESS | `key` was a valid identifier and the key material that it referred to has been erased. Alternatively, `key` is `0`.
  IFX_SE_ERROR_NOT_PERMITTED | The key cannot be erased because it is read-only, either due to a policy or due to physical restrictions.
  IFX_SE_ERROR_INVALID_HANDLE | `key` is not a valid identifier nor `0`.
  IFX_SE_ERROR_COMMUNICATION_FAILURE | There was an failure in communication with the cryptoprocessor. The key material may still be present in the cryptoprocessor.
  IFX_SE_ERROR_DATA_INVALID | This error is typically a result of either storage corruption on a cleartext storage backend, or an attempt to read data that was written by an incompatible version of the library.
  IFX_SE_ERROR_STORAGE_FAILURE | The storage is corrupted. Implementations shall make a best effort to erase key material even in this stage, however applications should be aware that it may be impossible to guarantee that the key material is not recoverable in such cases.
  IFX_SE_ERROR_CORRUPTION_DETECTED | An unexpected condition which is not a storage corruption or a communication failure occurred. The cryptoprocessor may have been compromised.

## ◆ ifx_se_purge_key()

ifx_se_status_t ifx_se_purge_key | ( | ifx_se_key_id_fih_t | key,
|  | void * | ctx
| ) |  |

Remove non-essential copies of key material from memory.

If the key identifier designates a volatile key, this functions does not do anything and returns successfully.

If the key identifier designates a persistent key, then this function will free all resources associated with the key in volatile memory. The key data in persistent storage is not affected and the key can still be used.

Parameters

  [in] | key | Identifier of the key to purge.
  [in] | ctx | The pointer to the SE syscall context that contain a special syscall data (IPC release callback etc).

Return values

  IFX_SE_SUCCESS | The key material will have been removed from memory if it is not currently required.
  IFX_SE_ERROR_INVALID_ARGUMENT | `key` is not a valid key identifier.
  IFX_SE_ERROR_BAD_STATE | The operation state is not valid (it must be inactive).

## ◆ ifx_se_generate_key()

ifx_se_status_t ifx_se_generate_key | ( | const ifx_se_key_attributes_t * | attributes,
|  | ifx_se_fih_ptr_t | key,
|  | void * | ctx
| ) |  |

Generate a key or key pair.

The key is generated randomly. Its location, usage policy, type and size are taken from `attributes`.

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

Parameters

  [in] | attributes | The attributes for the new key.
  [out] | key | On success, a pointer to identifier of 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_NOT_SUPPORTED |
  IFX_SE_ERROR_INVALID_ARGUMENT |
  IFX_SE_ERROR_INSUFFICIENT_MEMORY |
  IFX_SE_ERROR_INSUFFICIENT_ENTROPY |
  IFX_SE_ERROR_COMMUNICATION_FAILURE |
  IFX_SE_ERROR_HARDWARE_FAILURE |
  IFX_SE_ERROR_CORRUPTION_DETECTED |
  IFX_SE_ERROR_INSUFFICIENT_STORAGE |
  IFX_SE_ERROR_DATA_INVALID |
  IFX_SE_ERROR_DATA_CORRUPT |
  IFX_SE_ERROR_STORAGE_FAILURE |

## ◆ ifx_se_import_key()

ifx_se_status_t ifx_se_import_key | ( | const ifx_se_key_attributes_t * | attributes,
|  | const ifx_se_fih_ptr_t | data,
|  | ifx_se_fih_t | data_length,
|  | ifx_se_fih_ptr_t | key,
|  | void * | ctx
| ) |  |

Import a key in binary format.

This function supports any output from ifx_se_export_key(). Refer to the documentation of ifx_se_export_public_key() for the format of public keys and to the documentation of ifx_se_export_key() for the format for other key types.

The key data determines the key size. The attributes may optionally specify a key size; in this case it must match the size determined from the key data. A key size of 0 in `attributes` indicates that the key size is solely determined by the key data.

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

This specification supports a single format for each key type. Implementations may support other formats as long as the standard format is supported. Implementations that support other formats should ensure that the formats are clearly unambiguous so as to minimize the risk that an invalid input is accidentally interpreted according to a different format.

Parameters

  [in] | attributes | The attributes for the new key. The key size is always determined from the `data` buffer. If the key size in `attributes` is nonzero, it must be equal to the size from `data`.
  [out] | key | On success, an identifier to 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] | data | Buffer containing the key data (encoded pointer to input data). The content of this buffer is interpreted according to the type declared in `attributes`. All implementations must support at least the format described in the documentation of ifx_se_export_key() or ifx_se_export_public_key() for the chosen type. Implementations may allow other formats, but should be conservative: implementations should err on the side of rejecting content if it may be erroneous (e.g. wrong type or truncated data).
  [in] | data_length | Size of the `data` buffer with CRC included 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. 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_NOT_SUPPORTED | The key type or key size is not supported, either by the implementation in general or in this particular persistent location.
  IFX_SE_ERROR_INVALID_ARGUMENT | The key attributes, as a whole, are invalid, or the key data is not correctly formatted, or the size in `attributes` is nonzero and does not match the size of the key data.
  IFX_SE_ERROR_INSUFFICIENT_MEMORY |
  IFX_SE_ERROR_INSUFFICIENT_STORAGE |
  IFX_SE_ERROR_COMMUNICATION_FAILURE |
  IFX_SE_ERROR_DATA_CORRUPT |
  IFX_SE_ERROR_DATA_INVALID |
  IFX_SE_ERROR_STORAGE_FAILURE |
  IFX_SE_ERROR_HARDWARE_FAILURE |
  IFX_SE_ERROR_CORRUPTION_DETECTED |

## ◆ ifx_se_export_key()

ifx_se_status_t ifx_se_export_key | ( | ifx_se_key_id_fih_t | key,
|  | ifx_se_fih_ptr_t | data,
|  | ifx_se_fih_t | data_size,
|  | ifx_se_fih_ptr_t | data_length,
|  | void * | ctx
| ) |  |

Export a key in binary format.

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

If the implementation of ifx_se_import_key() supports other formats beyond the format specified here, the output from ifx_se_export_key() must use the representation specified here, not the original representation.

For standard key types, the output format is as follows:

- For symmetric keys (including MAC keys), the format is the raw bytes of the key.
- For DES, the key data consists of 8 bytes. The parity bits must be correct.
- For Triple-DES, the format is the concatenation of the two or three DES keys.
- For RSA key pairs (IFX_SE_KEY_TYPE_RSA_KEY_PAIR), the format is the non-encrypted DER encoding of the representation defined by PKCS#1 (RFC 8017) as `RSAPrivateKey`, version 0.
  RSAPrivateKey ::= SEQUENCE {
  version INTEGER, -- must be 0
  modulus INTEGER, -- n
  publicExponent INTEGER, -- e
  privateExponent INTEGER, -- d
  prime1 INTEGER, -- p
  prime2 INTEGER, -- q
  exponent1 INTEGER, -- d mod (p-1)
  exponent2 INTEGER, -- d mod (q-1)
  coefficient INTEGER, -- (inverse of q) mod p
  }
- For elliptic curve key pairs (key types for which IFX_SE_KEY_TYPE_IS_ECC_KEY_PAIR is true), the format is a representation of the private value as a `ceiling(m/8)`-byte string where `m` is the bit size associated with the curve, i.e. the bit size of the order of the curve's coordinate field. This byte string is in little-endian order for Montgomery curves (curve types `IFX_SE_ECC_FAMILY_CURVEXXX`), and in big-endian order for Weierstrass curves (curve types `IFX_SE_ECC_FAMILY_SECTXXX`, `IFX_SE_ECC_FAMILY_SECPXXX` and `IFX_SE_ECC_FAMILY_BRAINPOOL_PXXX`). For Weierstrass curves, this is the content of the `privateKey` field of the `ECPrivateKey` format defined by RFC 5915. For Montgomery curves, the format is defined by RFC 7748, and output is masked according to p.5. For twisted Edwards curves, the private key is as defined by RFC 8032 (a 32-byte string for Edwards25519, a 57-byte string for Edwards448).
- For Diffie-Hellman key exchange key pairs (key types for which IFX_SE_KEY_TYPE_IS_DH_KEY_PAIR is true), the format is the representation of the private key `x` as a big-endian byte string. The length of the byte string is the private key size in bytes (leading zeroes are not stripped).
- For public keys (key types for which IFX_SE_KEY_TYPE_IS_PUBLIC_KEY is true), the format is the same as for ifx_se_export_public_key().

The policy on the key must have the usage flag IFX_SE_KEY_USAGE_EXPORT set.

Parameters

  [in] | key | Identifier of the key to export. It must allow the usage IFX_SE_KEY_USAGE_EXPORT, unless it is a public key.
  [out] | data | Buffer where the key data is to be written (encoded pointer to output buffer).
  [in] | data_size | Size of the `data` buffer with CRC included in bytes (size_t).
  [out] | data_length | On success, the number of bytes that make up the key data (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_INVALID_HANDLE |
  IFX_SE_ERROR_NOT_PERMITTED | The key does not have the IFX_SE_KEY_USAGE_EXPORT flag.
  IFX_SE_ERROR_NOT_SUPPORTED |
  IFX_SE_ERROR_BUFFER_TOO_SMALL | The size of the `data` buffer is too small. You can determine a sufficient buffer size by calling IFX_SE_EXPORT_KEY_OUTPUT_SIZE(`type`, `bits`) where `type` is the key type and `bits` is the key size in bits.
  IFX_SE_ERROR_COMMUNICATION_FAILURE |
  IFX_SE_ERROR_HARDWARE_FAILURE |
  IFX_SE_ERROR_CORRUPTION_DETECTED |
  IFX_SE_ERROR_STORAGE_FAILURE |
  IFX_SE_ERROR_INSUFFICIENT_MEMORY |

## ◆ ifx_se_export_public_key()

ifx_se_status_t ifx_se_export_public_key | ( | ifx_se_key_id_fih_t | key,
|  | ifx_se_fih_ptr_t | data,
|  | ifx_se_fih_t | data_size,
|  | ifx_se_fih_ptr_t | data_length,
|  | void * | ctx
| ) |  |

Export a public key or the public part of a key pair in binary format.

The output of this function can be passed to ifx_se_import_key() to create an object that is equivalent to the public key.

This specification supports a single format for each key type. Implementations may support other formats as long as the standard format is supported. Implementations that support other formats should ensure that the formats are clearly unambiguous so as to minimize the risk that an invalid input is accidentally interpreted according to a different format.

For standard key types, the output format is as follows:

- For RSA public keys (IFX_SE_KEY_TYPE_RSA_PUBLIC_KEY), the DER encoding of the representation defined by RFC 3279 §2.3.1 as `RSAPublicKey`.
  RSAPublicKey ::= SEQUENCE {
  modulus INTEGER, -- n
  publicExponent INTEGER } -- e
- For elliptic curve keys on a twisted Edwards curve (key types for which IFX_SE_KEY_TYPE_IS_ECC_PUBLIC_KEY is true and IFX_SE_KEY_TYPE_ECC_GET_FAMILY returns IFX_SE_ECC_FAMILY_TWISTED_EDWARDS), the public key is as defined by RFC 8032 (a 32-byte string for Edwards25519, a 57-byte string for Edwards448).
- For other elliptic curve public keys (key types for which IFX_SE_KEY_TYPE_IS_ECC_PUBLIC_KEY is true), the format is the uncompressed representation defined by SEC1 §2.3.3 as the content of an ECPoint. Let `m` be the bit size associated with the curve, i.e. the bit size of `q` for a curve over `F_q`. The representation consists of:
  - The byte 0x04;
  - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
  - `y_P` as a `ceiling(m/8)`-byte string, big-endian.
- For Diffie-Hellman key exchange public keys (key types for which IFX_SE_KEY_TYPE_IS_DH_PUBLIC_KEY is true), the format is the representation of the public key `y = g^x mod p` as a big-endian byte string. The length of the byte string is the length of the base prime `p` in bytes (size_t).

Exporting a public key object or the public part of a key pair is always permitted, regardless of the key's usage flags.

Parameters

  [in] | key | Identifier of the key to export.
  [out] | data | Buffer where the key data is to be written (encoded pointer to output buffer).
  [in] | data_size | Size of the `data` buffer with CRC included in bytes (size_t).
  [out] | data_length | On success, the number of bytes that make up the key data (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_INVALID_HANDLE |
  IFX_SE_ERROR_INVALID_ARGUMENT | The key is neither a public key nor a key pair.
  IFX_SE_ERROR_NOT_SUPPORTED |
  IFX_SE_ERROR_BUFFER_TOO_SMALL | The size of the `data` buffer is too small. You can determine a sufficient buffer size by calling IFX_SE_EXPORT_KEY_OUTPUT_SIZE(IFX_SE_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(`type`), `bits`) where `type` is the key type and `bits` is the key size in bits.
  IFX_SE_ERROR_COMMUNICATION_FAILURE |
  IFX_SE_ERROR_HARDWARE_FAILURE |
  IFX_SE_ERROR_CORRUPTION_DETECTED |
  IFX_SE_ERROR_STORAGE_FAILURE |
  IFX_SE_ERROR_INSUFFICIENT_MEMORY |

## ◆ ifx_se_copy_key()

ifx_se_status_t ifx_se_copy_key | ( | ifx_se_key_id_fih_t | source_key,
|  | const ifx_se_key_attributes_t * | attributes,
|  | ifx_se_fih_ptr_t | target_key,
|  | void * | ctx
| ) |  |

Make a copy of a key.

Copy key material from one location to another.

This function is primarily useful to copy a key from one location to another, since it populates a key using the material from another key which may have a different lifetime.

This function may be used to share a key with a different party, subject to implementation-defined restrictions on key sharing.

The policy on the source key must have the usage flag IFX_SE_KEY_USAGE_COPY set. This flag is sufficient to permit the copy if the key has the lifetime IFX_SE_KEY_LIFETIME_VOLATILE or IFX_SE_KEY_LIFETIME_PERSISTENT. Some secure elements do not provide a way to copy a key without making it extractable from the secure element. If a key is located in such a secure element, then the key must have both usage flags IFX_SE_KEY_USAGE_COPY and IFX_SE_KEY_USAGE_EXPORT in order to make a copy of the key outside the secure element.

The resulting key may only be used in a way that conforms to both the policy of the original key and the policy specified in the `attributes` parameter:

- The usage flags on the resulting key are the bitwise-and of the usage flags on the source policy and the usage flags in `attributes`.
- If both allow the same algorithm or wildcard-based algorithm policy, the resulting key has the same algorithm policy.
- If either of the policies allows an algorithm and the other policy allows a wildcard-based algorithm policy that includes this algorithm, the resulting key allows the same algorithm.
- If the policies do not allow any algorithm in common, this function fails with the status IFX_SE_ERROR_INVALID_ARGUMENT.

The effect of this function on implementation-defined attributes is implementation-defined.

Parameters

  [in] | source_key | The key to copy. It must allow the usage IFX_SE_KEY_USAGE_COPY. If a private or secret key is being copied outside of a secure element it must also allow IFX_SE_KEY_USAGE_EXPORT.
  [in] | attributes | The attributes for the new key. They are used as follows: The key type and size may be 0. If either is nonzero, it must match the corresponding attribute of the source key. The key location (the lifetime and, for persistent keys, the key identifier) is used directly. The policy constraints (usage flags and algorithm policy) are combined from the source key and `attributes` so that both sets of restrictions apply, as described in the documentation of this function.
  [out] | target_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 |
  IFX_SE_ERROR_INVALID_HANDLE | `source_key` is invalid.
  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_INVALID_ARGUMENT | The lifetime or identifier in `attributes` are invalid, or the policy constraints on the source and specified in `attributes` are incompatible, or `attributes` specifies a key type or key size which does not match the attributes of the source key.
  IFX_SE_ERROR_NOT_PERMITTED | The source key does not have the IFX_SE_KEY_USAGE_COPY usage flag, or the source key is not exportable and its lifetime does not allow copying it to the target's lifetime.
  IFX_SE_ERROR_INSUFFICIENT_MEMORY |
  IFX_SE_ERROR_INSUFFICIENT_STORAGE |
  IFX_SE_ERROR_COMMUNICATION_FAILURE |
  IFX_SE_ERROR_HARDWARE_FAILURE |
  IFX_SE_ERROR_DATA_INVALID |
  IFX_SE_ERROR_DATA_CORRUPT |
  IFX_SE_ERROR_STORAGE_FAILURE |
  IFX_SE_ERROR_CORRUPTION_DETECTED |