diff --git a/doc/crypto/api.db/psa/crypto.h b/doc/crypto/api.db/psa/crypto.h index 74bb334a..3135fd91 100644 --- a/doc/crypto/api.db/psa/crypto.h +++ b/doc/crypto/api.db/psa/crypto.h @@ -109,6 +109,7 @@ typedef struct psa_custom_key_parameters_t { #define PSA_ALG_IS_KEY_DERIVATION_STRETCHING(alg) \ /* specification-defined value */ #define PSA_ALG_IS_KEY_ENCAPSULATION(alg) /* specification-defined value */ +#define PSA_ALG_IS_KEY_WRAP(alg) /* specification-defined value */ #define PSA_ALG_IS_MAC(alg) /* specification-defined value */ #define PSA_ALG_IS_PAKE(alg) /* specification-defined value */ #define PSA_ALG_IS_PBKDF2_HMAC(alg) /* specification-defined value */ @@ -139,6 +140,8 @@ typedef struct psa_custom_key_parameters_t { /* specification-defined value */ #define PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) /* specification-defined value */ #define PSA_ALG_KEY_AGREEMENT_GET_KDF(alg) /* specification-defined value */ +#define PSA_ALG_KW ((psa_algorithm_t)0x0B400100) +#define PSA_ALG_KWP ((psa_algorithm_t)0x0BC00200) #define PSA_ALG_MD2 ((psa_algorithm_t)0x02000001) #define PSA_ALG_MD4 ((psa_algorithm_t)0x02000002) #define PSA_ALG_MD5 ((psa_algorithm_t)0x02000003) @@ -335,9 +338,11 @@ typedef struct psa_custom_key_parameters_t { #define PSA_KEY_USAGE_EXPORT ((psa_key_usage_t)0x00000001) #define PSA_KEY_USAGE_SIGN_HASH ((psa_key_usage_t)0x00001000) #define PSA_KEY_USAGE_SIGN_MESSAGE ((psa_key_usage_t)0x00000400) +#define PSA_KEY_USAGE_UNWRAP ((psa_key_usage_t)0x00020000) #define PSA_KEY_USAGE_VERIFY_DERIVATION ((psa_key_usage_t)0x00008000) #define PSA_KEY_USAGE_VERIFY_HASH ((psa_key_usage_t)0x00002000) #define PSA_KEY_USAGE_VERIFY_MESSAGE ((psa_key_usage_t)0x00000800) +#define PSA_KEY_USAGE_WRAP ((psa_key_usage_t)0x00010000) #define PSA_MAC_LENGTH(key_type, key_bits, alg) \ /* implementation-defined value */ #define PSA_MAC_MAX_SIZE /* implementation-defined value */ @@ -380,6 +385,9 @@ typedef struct psa_custom_key_parameters_t { /* implementation-defined value */ #define PSA_TLS12_ECJPAKE_TO_PMS_OUTPUT_SIZE 32 #define PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE /* implementation-defined value */ +#define PSA_WRAP_KEY_OUTPUT_SIZE(wrap_key_type, alg, key_type, key_bits) \ + /* implementation-defined value */ +#define PSA_WRAP_KEY_PAIR_MAX_SIZE /* implementation-defined value */ psa_status_t psa_aead_abort(psa_aead_operation_t * operation); psa_status_t psa_aead_decrypt(psa_key_id_t key, psa_algorithm_t alg, @@ -735,6 +743,12 @@ psa_status_t psa_sign_message(psa_key_id_t key, uint8_t * signature, size_t signature_size, size_t * signature_length); +psa_status_t psa_unwrap_key(const psa_key_attributes_t * attributes, + psa_key_id_t wrapping_key, + psa_algorithm_t alg, + const uint8_t * data, + size_t data_length, + psa_key_id_t * key); psa_status_t psa_verify_hash(psa_key_id_t key, psa_algorithm_t alg, const uint8_t * hash, @@ -747,3 +761,9 @@ psa_status_t psa_verify_message(psa_key_id_t key, size_t input_length, const uint8_t * signature, size_t signature_length); +psa_status_t psa_wrap_key(psa_key_id_t wrapping_key, + psa_algorithm_t alg, + psa_key_id_t key, + uint8_t * data, + size_t data_size, + size_t * data_length); diff --git a/doc/crypto/api/keys/policy.rst b/doc/crypto/api/keys/policy.rst index 46fa6122..a5bd7a37 100644 --- a/doc/crypto/api/keys/policy.rst +++ b/doc/crypto/api/keys/policy.rst @@ -267,6 +267,28 @@ The usage flags are encoded in a bitmask, which has the type `psa_key_usage_t`. If this flag is present on all keys used in calls to `psa_key_derivation_input_key()` for a key-derivation operation, then it permits calling `psa_key_derivation_verify_bytes()` or `psa_key_derivation_verify_key()` at the end of the operation. +.. macro:: PSA_KEY_USAGE_WRAP + :definition: ((psa_key_usage_t)0x00010000) + + .. summary:: + Permission to wrap another key with the key. + + This flag is required to use the key in a key-wrapping operation. + The flag must be present on keys used with the following APIs: + + * `psa_wrap_key()` + +.. macro:: PSA_KEY_USAGE_UNWRAP + :definition: ((psa_key_usage_t)0x00020000) + + .. summary:: + Permission to unwrap another key with the key. + + This flag is required to use the key in a key-unwrapping operation. + The flag must be present on keys used with the following APIs: + + * `psa_unwrap_key()` + .. function:: psa_set_key_usage_flags .. summary:: diff --git a/doc/crypto/api/keys/types.rst b/doc/crypto/api/keys/types.rst index 5a411938..f54f1dfb 100644 --- a/doc/crypto/api/keys/types.rst +++ b/doc/crypto/api/keys/types.rst @@ -322,6 +322,8 @@ Symmetric keys * `PSA_ALG_ECB_NO_PADDING` * `PSA_ALG_CCM` * `PSA_ALG_GCM` + * `PSA_ALG_KW` + * `PSA_ALG_KWP` * `PSA_ALG_SP800_108_COUNTER_CMAC` (secret input) .. subsection:: Key format @@ -369,6 +371,8 @@ Symmetric keys * `PSA_ALG_ECB_NO_PADDING` * `PSA_ALG_CCM` * `PSA_ALG_GCM` + * `PSA_ALG_KW` + * `PSA_ALG_KWP` * `PSA_ALG_SP800_108_COUNTER_CMAC` (secret input) .. subsection:: Key format @@ -463,6 +467,8 @@ Symmetric keys * `PSA_ALG_ECB_NO_PADDING` * `PSA_ALG_CCM` * `PSA_ALG_GCM` + * `PSA_ALG_KW` + * `PSA_ALG_KWP` * `PSA_ALG_SP800_108_COUNTER_CMAC` (secret input) .. subsection:: Key format @@ -500,6 +506,8 @@ Symmetric keys * `PSA_ALG_ECB_NO_PADDING` * `PSA_ALG_CCM` * `PSA_ALG_GCM` + * `PSA_ALG_KW` + * `PSA_ALG_KWP` * `PSA_ALG_SP800_108_COUNTER_CMAC` (secret input) .. subsection:: Key format diff --git a/doc/crypto/api/ops/algorithms.rst b/doc/crypto/api/ops/algorithms.rst index 828f3f9b..96e766de 100644 --- a/doc/crypto/api/ops/algorithms.rst +++ b/doc/crypto/api/ops/algorithms.rst @@ -19,6 +19,7 @@ The specific algorithm identifiers are described alongside the cryptographic ope * :secref:`mac-algorithms` * :secref:`cipher-algorithms` * :secref:`aead-algorithms` +* :secref:`key-wrapping-algorithms` * :secref:`key-derivation-algorithms` * :secref:`sign` * :secref:`asymmetric-encryption-algorithms` @@ -125,6 +126,20 @@ Algorithm categories See :secref:`aead-algorithms` for a list of defined AEAD algorithms. +.. macro:: PSA_ALG_IS_KEY_WRAP + :definition: /* specification-defined value */ + + .. summary:: + Whether the specified algorithm is a key wrapping algorithm. + + .. param:: alg + An algorithm identifier: a value of type `psa_algorithm_t`. + + .. return:: + ``1`` if ``alg`` is a key-wrapping algorithm, ``0`` otherwise. This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. + + See :secref:`key-wrapping-algorithms` for a list of defined key-wrapping algorithms. + .. macro:: PSA_ALG_IS_KEY_DERIVATION :definition: /* specification-defined value */ diff --git a/doc/crypto/api/ops/index.rst b/doc/crypto/api/ops/index.rst index d7f1b458..34891fde 100644 --- a/doc/crypto/api/ops/index.rst +++ b/doc/crypto/api/ops/index.rst @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: Copyright 2018-2022, 2024 Arm Limited and/or its affiliates +.. SPDX-FileCopyrightText: Copyright 2018-2025 Arm Limited and/or its affiliates .. SPDX-License-Identifier: CC-BY-SA-4.0 AND LicenseRef-Patent-license .. _crypto-operations: @@ -14,6 +14,7 @@ Cryptographic operation reference mac cipher aead + key-wrapping key-derivation signature pk-encryption diff --git a/doc/crypto/api/ops/key-wrapping.rst b/doc/crypto/api/ops/key-wrapping.rst new file mode 100644 index 00000000..951f1d2d --- /dev/null +++ b/doc/crypto/api/ops/key-wrapping.rst @@ -0,0 +1,318 @@ +.. SPDX-FileCopyrightText: Copyright 2024-2025 Arm Limited and/or its affiliates +.. SPDX-License-Identifier: CC-BY-SA-4.0 AND LicenseRef-Patent-license + +.. header:: psa/crypto + :seq: 245 + +.. _key-wrapping: + +Key wrapping +============ + +Key wrapping is the process of encrypting a key, so that the resulting ciphertext can be stored, or transported, in a form that maintains the confidentiality of the key material. +Key unwrapping reverses this process, extracting the key from the ciphertext. +Some key-wrapping schemes also provide integrity protection, to ensure that modification of the ciphertext can be detected. + +Some key-wrapping algorithms operate on arbitrary data, and provide authenticated encryption that is specifically designed for key values. +For example, the AES Key-wrap algorithm AES-KW. +For this type of algorithm, the |API| provides a simple pair of functions, `psa_unwrap_key()` and `psa_wrap_key()`, that unwrap or wrap key data in the default export format. +When using one of these key-wrapping algorithms, the key attributes are managed by the application. + +.. note:: + Other key-wrapping schemes define both the format of the wrapped key material and the algorithm that is used to perform the wrapping. + For example PKCS#8 defines *EncryptedPrivateKeyInfo*, which is also described in :rfc-title:`5958`. + Wrapped-key formats typically encode the key type and wrapping algorithm within the output data, and can also include other key attributes. + This version of the |API| does not support these key-wrapping schemes, but this is planned for a future version. + +.. rationale:: + + Key-wrapping algorithms are categorized separately to other authenticated encryption algorithms in the |API|. Key-wrapping algorithms ideally have the following properties: + + * Deterministic --- not requiring a nonce or IV to be provided by the application, or generated randomly. + * Robust --- every bit of plaintext can affect every bit of ciphertext. + + As a result, key-wrapping algorithms are typically special-purpose authenticated encryption algorithms. + +.. _key-wrapping-algorithms: + +Key-wrapping algorithms +----------------------- + +.. macro:: PSA_ALG_KW + :definition: ((psa_algorithm_t)0x0B400100) + + .. summary:: + A key-wrapping algorithm based on the NIST Key Wrap (KW) mode of a block cipher. + + .. versionadded:: 1.4 + + KW is defined for block ciphers that have a 128-bit block size. + The underlying block cipher is determined by the key type. + + Keys to be wrapped must have a length equal to a multiple of the 'semi-block' size for the block cipher. + That is, a multiple of 8 bytes. + + To wrap keys that are not a multiple of the semi-block size, `PSA_ALG_KWP` can be used. + + This is the NIST Key Wrap algorithm, using any block-cipher that operates on 128-bit blocks, as defined in :cite-title:`SP800-38F`. + A definition of AES-KW is also found in :rfc-title:`3394`. + + .. subsection:: Compatible key types + + | `PSA_KEY_TYPE_AES` + | `PSA_KEY_TYPE_ARIA` + | `PSA_KEY_TYPE_CAMELLIA` + | `PSA_KEY_TYPE_SM4` + +.. macro:: PSA_ALG_KWP + :definition: ((psa_algorithm_t)0x0BC00200) + + .. summary:: + A key-wrapping algorithm based on the NIST Key Wrap with Padding (KWP) mode of a block cipher. + + .. versionadded:: 1.4 + + KWP is defined for block ciphers that have a 128-bit block size. + The underlying block cipher is determined by the key type. + + This algorithm can wrap a key of any length. + + This is the NIST Key Wrap with Padding algorithm, using any block-cipher that operates on 128-bit blocks, as defined in :cite-title:`SP800-38F`. + A definition of AES-KWP is also found in :rfc-title:`5649`. + + .. subsection:: Compatible key types + + | `PSA_KEY_TYPE_AES` + | `PSA_KEY_TYPE_ARIA` + | `PSA_KEY_TYPE_CAMELLIA` + | `PSA_KEY_TYPE_SM4` + +Key wrapping functions +---------------------- + +.. function:: psa_unwrap_key + + .. summary:: + Unwrap and import a key using a specified wrapping key. + + .. versionadded:: 1.4 + + .. param:: const psa_key_attributes_t * attributes + The attributes for the new key. + + The following attributes are required for all keys: + + * The key type determines how the decrypted ``data`` buffer is interpreted. + + The following attributes must be set for keys used in cryptographic operations: + + * The key permitted-algorithm policy, see :secref:`permitted-algorithms`. + * The key usage flags, see :secref:`key-usage-flags`. + + The following attributes must be set for keys that do not use the default volatile lifetime: + + * The key lifetime, see :secref:`key-lifetimes`. + * The key identifier is required for a key with a persistent lifetime, see :secref:`key-identifiers`. + + The following attributes are optional: + + * If the key size is nonzero, it must be equal to the key size determined from ``data``. + + .. note:: + This is an input parameter: it is not updated with the final key attributes. + The final attributes of the new key can be queried by calling `psa_get_key_attributes()` with the key's identifier. + .. param:: psa_key_id_t wrapping_key + Identifier of the key to use for the unwrapping operation. + It must permit the usage `PSA_KEY_USAGE_UNWRAP`. + .. param:: psa_algorithm_t alg + The key-wrapping algorithm: a value of type :code:`psa_algorithm_t` such that :code:`PSA_ALG_IS_KEY_WRAP(alg)` is true. + .. param:: const uint8_t * data + Buffer containing the wrapped key data. + The content of this buffer is unwrapped using the algorithm ``alg``, and then interpreted according to the type declared in ``attributes``. + .. param:: size_t data_length + Size of the ``data`` buffer in bytes. + .. param:: psa_key_id_t * key + On success, an identifier for the newly created key. + `PSA_KEY_ID_NULL` on failure. + + .. return:: psa_status_t + .. retval:: PSA_SUCCESS + Success. + If the key is persistent, the key material and the key's metadata have been saved to persistent storage. + .. retval:: PSA_ERROR_ALREADY_EXISTS + This is an attempt to create a persistent key, and there is already a persistent key with the given identifier. + .. retval:: PSA_ERROR_INVALID_SIGNATURE + The wrapped key data could not be authenticated. + .. retval:: PSA_ERROR_INVALID_HANDLE + ``wrapping_key`` is not a valid key identifier. + .. retval:: PSA_ERROR_NOT_SUPPORTED + The following conditions can result in this error: + + * ``alg`` is not supported or is not a key-wrapping algorithm. + * ``wrapping_key`` is not supported for use with ``alg``. + * The key attributes, as a whole, are not supported, either by the implementation in general or in the specified storage location. + .. retval:: PSA_ERROR_INVALID_ARGUMENT + The following conditions can result in this error: + + * ``alg`` is not a key-wrapping algorithm. + * ``wrapping_key`` is not compatible with ``alg``. + * The key type is invalid. + * The key size is nonzero, and is incompatible with the wrapped key data in ``data``. + * The key lifetime is invalid. + * The key identifier is not valid for the key lifetime. + * The key usage flags include invalid values. + * The key's permitted-usage algorithm is invalid. + * The key attributes, as a whole, are invalid. + * The key data is not correctly formatted for the key type. + .. retval:: PSA_ERROR_NOT_PERMITTED + The following conditions can result in this error: + + * The wrapping key does not have the `PSA_KEY_USAGE_UNWRAP` flag, or it does not permit the requested algorithm. + * The implementation does not permit creating a key with the specified attributes due to some implementation-specific policy. + .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY + .. retval:: PSA_ERROR_INSUFFICIENT_STORAGE + .. retval:: PSA_ERROR_COMMUNICATION_FAILURE + .. retval:: PSA_ERROR_STORAGE_FAILURE + .. retval:: PSA_ERROR_DATA_CORRUPT + .. retval:: PSA_ERROR_DATA_INVALID + .. retval:: PSA_ERROR_CORRUPTION_DETECTED + .. retval:: PSA_ERROR_BAD_STATE + The library requires initializing by a call to `psa_crypto_init()`. + + The key is unwrapped and extracted from the provided ``data`` buffer. Its location, policy, and type are taken from ``attributes``. + + The wrapped key data determines the key size. + :code:``psa_get_key_bits(attributes)`` must either match the determined key size or be ``0``. + + Implementations must reject an attempt to unwrap a key if the determined key size is ``0``. + + .. note:: + A call to `psa_unwrap_key()` first applies the decryption procedure associated with the key-wrapping algorithm ``alg``, using the ``wrapping_key`` key, to the supplied ``data`` buffer. + The resulting plaintext is retained within the cryptoprocessor, and used with the provided ``attributes`` to create a key, as if they were inputs to `psa_import_key()`. + + .. note:: + The |API| does not support asymmetric private key objects outside of a key pair. + When unwrapping a private key, the corresponding key-pair type is created. + If the imported key data does not contain the public key, then the implementation will reconstruct the public key from the private key as needed. + + .. admonition:: Implementation note + + It is recommended that the implementation supports unwrapping any key data that can be produced by a call to `psa_wrap_key()`, with the same key-wrapping algorithm and key, and matching key attributes. + + It is recommended that implementations reject wrapped key data if it might be erroneous, for example, if it is the wrong type or is truncated. + +.. function:: psa_wrap_key + + .. summary:: + Wrap and export a key using a specified wrapping key. + + .. versionadded:: 1.4 + + .. param:: psa_key_id_t wrapping_key + Identifier of the key to use for the wrapping operation. + It must permit the usage `PSA_KEY_USAGE_WRAP`. + .. param:: psa_algorithm_t alg + The key-wrapping algorithm: a value of type :code:`psa_algorithm_t` such that :code:`PSA_ALG_IS_KEY_WRAP(alg)` is true. + .. param:: psa_key_id_t key + Identifier of the key to wrap. + It must permit the usage `PSA_KEY_USAGE_EXPORT`. + .. param:: uint8_t * data + Buffer where the wrapped key data is to be written. + .. param:: size_t data_size + Size of the ``data`` buffer in bytes. + This must be appropriate for the key: + + * The required output size is :code:`PSA_WRAP_KEY_OUTPUT_SIZE(wrap_key_type, alg, type, bits)`, where ``wrap_key_type`` is the type of the wrapping key, ``alg`` is the key-wrapping algorithm, ``type`` is the type of the key being wrapped, and ``bits`` is the bit-size of the key being wrapped. + * `PSA_WRAP_KEY_PAIR_MAX_SIZE` evaluates to the maximum wrapped output size of any supported key pair, in any supported combination of key-wrapping algorithm and wrapping-key type. + * This API defines no maximum size for wrapped symmetric keys. + Arbitrarily large data items can be stored in the key store, for example certificates that correspond to a stored private key or input material for key derivation. + .. param:: size_t * data_length + On success, the number of bytes that make up the wrapped key data. + + .. return:: psa_status_t + .. retval:: PSA_SUCCESS + Success. + The first ``(*data_length)`` bytes of ``data`` contain the wrapped key. + .. retval:: PSA_ERROR_INVALID_HANDLE + The following conditions can result in this error: + + * ``wrapping_key`` is not a valid key identifier. + * ``key`` is not a valid key identifier. + .. retval:: PSA_ERROR_NOT_PERMITTED + The following conditions can result in this error: + + * The wrapping key does not have the `PSA_KEY_USAGE_WRAP` flag, or it does not permit the requested algorithm. + * The key to be wrapped does not have the `PSA_KEY_USAGE_EXPORT` flag. + .. retval:: PSA_ERROR_INVALID_ARGUMENT + The following conditions can result in this error: + + * ``alg`` is not a key-wrapping algorithm. + * ``wrapping_key`` is not compatible with ``alg``. + * ``key`` has a size that is not valid for ``alg``. + .. retval:: PSA_ERROR_NOT_SUPPORTED + The following conditions can result in this error: + + * ``alg`` is not supported or is not a key-wrapping algorithm. + * ``wrapping_key`` is not supported for use with ``alg``. + * The storage location of ``key`` does not support export of the key. + * The implementation does not support export of keys with the type of ``key``. + .. retval:: PSA_ERROR_BUFFER_TOO_SMALL + The size of the ``data`` buffer is too small. + `PSA_WRAP_KEY_OUTPUT_SIZE()` or `PSA_WRAP_KEY_PAIR_MAX_SIZE` can be used to determine a sufficient buffer size. + .. retval:: PSA_ERROR_COMMUNICATION_FAILURE + .. retval:: PSA_ERROR_CORRUPTION_DETECTED + .. retval:: PSA_ERROR_STORAGE_FAILURE + .. retval:: PSA_ERROR_DATA_CORRUPT + .. retval:: PSA_ERROR_DATA_INVALID + .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY + .. retval:: PSA_ERROR_BAD_STATE + The library requires initializing by a call to `psa_crypto_init()`. + + Wrap a key from the key store into a data buffer using a specified key-wrapping algorithm and key-wrapping key. + On success, the output contains the wrapped key value. + The policy of the key to be wrapped must have the usage flag `PSA_KEY_USAGE_EXPORT` set. + + The output of this function can be passed to `psa_unwrap_key()`, specifying the same algorithm and wrapping key, with the same attributes as ``key``, to create an equivalent key object. + + .. note:: + A call to `psa_wrap_key()` first evaluates the key data for ``key``, as if `psa_export_key()` is called, but retaining the key data within the cryptoprocessor. + If this succeeds, the encryption procedure associated with the key-wrapping algorithm ``alg``, using the ``wrapping_key`` key, is applied to the key data. + The resulting ciphertext is then returned. + + +Support macros +-------------- + +.. macro:: PSA_WRAP_KEY_OUTPUT_SIZE + :definition: /* implementation-defined value */ + + .. summary:: + Sufficient output buffer size for `psa_wrap_key()`. + + .. versionadded:: 1.4 + + .. param:: wrap_key_type + A supported key-wrapping key type. + .. param:: alg + A supported key-wrapping algorithm. + .. param:: key_type + A supported key type. + .. param:: key_bits + The size of the key in bits. + + .. return:: + If the parameters are valid and supported, return a buffer size in bytes that guarantees that `psa_wrap_key()` will not fail with :code:`PSA_ERROR_BUFFER_TOO_SMALL`. If the parameters are a valid combination that is not supported by the implementation, this macro must return either a sensible size or ``0``. If the parameters are not valid, the return value is unspecified. + + See also `PSA_WRAP_KEY_PAIR_MAX_SIZE`. + +.. macro:: PSA_WRAP_KEY_PAIR_MAX_SIZE + :definition: /* implementation-defined value */ + + .. summary:: + Sufficient buffer size for wrapping any asymmetric key pair. + + .. versionadded:: 1.4 + + This value must be a sufficient buffer size when calling `psa_wrap_key()` to export any asymmetric key pair that is supported by the implementation, regardless of the exact key type and key size. + + See also `PSA_WRAP_KEY_OUTPUT_SIZE()`. diff --git a/doc/crypto/appendix/encodings.rst b/doc/crypto/appendix/encodings.rst index 5ff7f7bf..544ec243 100644 --- a/doc/crypto/appendix/encodings.rst +++ b/doc/crypto/appendix/encodings.rst @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: Copyright 2022-2024 Arm Limited and/or its affiliates +.. SPDX-FileCopyrightText: Copyright 2022-2025 Arm Limited and/or its affiliates .. SPDX-License-Identifier: CC-BY-SA-4.0 AND LicenseRef-Patent-license .. _appendix-encodings: @@ -46,6 +46,8 @@ Algorithm identifiers are 32-bit integer values of the type `psa_algorithm_t`. A - [23] - For a cipher algorithm, this flag indicates a stream cipher when S=1. + For a key-wrapping algorithm, this flag indicates an algorithm that accepts non-aligned input lengths when S=1. + For a key-derivation algorithm, this flag indicates a key-stretching or password-hashing algorithm when S=1. * - B - [22] @@ -79,6 +81,7 @@ The CAT field in an algorithm identifier takes the values shown in :numref:`tabl MAC, ``0x03``, See :secref:`mac-encoding` Cipher, ``0x04``, See :secref:`cipher-encoding` AEAD, ``0x05``, See :secref:`aead-encoding` + Key wrapping, ``0x0B``, See :secref:`key-wrap-encoding` Key derivation, ``0x08``, See :secref:`kdf-encoding` Asymmetric signature, ``0x06``, See :secref:`sign-encoding` Asymmetric encryption, ``0x07``, See :secref:`pke-encoding` @@ -250,6 +253,30 @@ a. This is an AEAD mode of an underlying block cipher. The block cipher is dete b. This is the default algorithm identifier, specifying the default tag length for the algorithm. `PSA_ALG_AEAD_WITH_SHORTENED_TAG()` generates identifiers with alternative LEN values. `PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG()` generates wildcard permitted-algorithm policies with W = 1. +.. _key-wrap-encoding: + +Key-wrapping algorithm encoding +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The algorithm identifier for key-wrapping algorithms defined in this specification are encoded as shown in :numref:`fig-key-wrap-fields`. + +.. figure:: ../figure/encoding/key-wrap.* + :name: fig-key-wrap-fields + + Key-wrapping algorithm encoding + +The defined values for S, B, and WRAP-TYPE are shown in :numref:`table-key-wrap-type`. + +.. csv-table:: Key-wrapping algorithm sub-type values + :name: table-key-wrap-type + :header-rows: 1 + :align: left + :widths: auto + + Key-wrapping algorithm, S, B, WRAP-TYPE, Algorithm identifier, Algorithm value + AES-KW, 0, 1, ``0x01``, `PSA_ALG_KW`, ``0x0B400100`` + AES-KWP, 1, 1, ``0x02``, `PSA_ALG_KWP`, ``0x0BC00200`` + .. _kdf-encoding: Key-derivation algorithm encoding diff --git a/doc/crypto/appendix/history.rst b/doc/crypto/appendix/history.rst index 7c6ded68..6a09f661 100644 --- a/doc/crypto/appendix/history.rst +++ b/doc/crypto/appendix/history.rst @@ -18,6 +18,7 @@ Changes to the API ~~~~~~~~~~~~~~~~~~ * Added `psa_attach_key()` to register existing key material as a volatile key within the implementation. +* Added support for key wrapping using key-wrapping algorithms. See :secref:`key-wrapping`. Clarifications and fixes ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -848,7 +849,6 @@ Future additions Major additions to the API will be defined in future drafts and editions of a 1.x or 2.x version of this specification. Features that are being considered include: * Multi-part operations for hybrid cryptography. For example, this includes hash-and-sign for EdDSA, and hybrid encryption for ECIES. -* Key wrapping mechanisms to extract and import keys in an encrypted and authenticated form. * Key discovery mechanisms. This would enable an application to locate a key by its name or attributes. * Implementation capability description. This would enable an application to determine the algorithms, key types and storage lifetimes that the implementation provides. * An ownership and access control mechanism allowing a multi-client implementation to have privileged clients that are able to manage keys of other clients. diff --git a/doc/crypto/appendix/specdef_values.rst b/doc/crypto/appendix/specdef_values.rst index 1702167b..a2b72545 100644 --- a/doc/crypto/appendix/specdef_values.rst +++ b/doc/crypto/appendix/specdef_values.rst @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: Copyright 2020-2024 Arm Limited and/or its affiliates +.. SPDX-FileCopyrightText: Copyright 2020-2025 Arm Limited and/or its affiliates .. SPDX-License-Identifier: CC-BY-SA-4.0 AND LicenseRef-Patent-license .. _appendix-specdef-values: @@ -124,6 +124,9 @@ Algorithm macros #define PSA_ALG_IS_KEY_ENCAPSULATION(alg) \ (((alg) & 0x7f000000) == 0x0c000000) + #define PSA_ALG_IS_KEY_WRAP(alg) \ + (((alg) & 0x7f000000) == 0x0b000000) + #define PSA_ALG_IS_MAC(alg) \ (((alg) & 0x7f000000) == 0x03000000) diff --git a/doc/crypto/figure/encoding/key-wrap.json b/doc/crypto/figure/encoding/key-wrap.json new file mode 100644 index 00000000..bf34820f --- /dev/null +++ b/doc/crypto/figure/encoding/key-wrap.json @@ -0,0 +1,18 @@ +{ + "reg": [ + { "name": "0", "bits": 8 }, + { "name": "WRAP-TYPE", "bits": 8 }, + { "name": "0", "bits": 6 }, + { "name": "B", "bits": 1 }, + { "name": "S", "bits": 1 }, + { "name": "0x0B", "bits": 7 }, + { "name": "0", "bits": 1 } + ], + "options": { + "lanes": 1, + "fontfamily": "lato", + "fontsize": 11, + "vspace": 52, + "hspace": 600 + } +} diff --git a/doc/crypto/figure/encoding/key-wrap.json.license b/doc/crypto/figure/encoding/key-wrap.json.license new file mode 100644 index 00000000..17e2c3b5 --- /dev/null +++ b/doc/crypto/figure/encoding/key-wrap.json.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright 2024-2025 Arm Limited and/or its affiliates +SPDX-License-Identifier: CC-BY-SA-4.0 AND LicenseRef-Patent-license diff --git a/doc/crypto/figure/encoding/key-wrap.pdf b/doc/crypto/figure/encoding/key-wrap.pdf new file mode 100644 index 00000000..b708f0c9 Binary files /dev/null and b/doc/crypto/figure/encoding/key-wrap.pdf differ diff --git a/doc/crypto/figure/encoding/key-wrap.pdf.license b/doc/crypto/figure/encoding/key-wrap.pdf.license new file mode 100644 index 00000000..17e2c3b5 --- /dev/null +++ b/doc/crypto/figure/encoding/key-wrap.pdf.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright 2024-2025 Arm Limited and/or its affiliates +SPDX-License-Identifier: CC-BY-SA-4.0 AND LicenseRef-Patent-license diff --git a/doc/crypto/figure/encoding/key-wrap.svg b/doc/crypto/figure/encoding/key-wrap.svg new file mode 100644 index 00000000..8170d07c --- /dev/null +++ b/doc/crypto/figure/encoding/key-wrap.svg @@ -0,0 +1,2 @@ + +07815162122232430310WRAP-TYPE0BS0x0B0 \ No newline at end of file diff --git a/doc/crypto/figure/encoding/key-wrap.svg.license b/doc/crypto/figure/encoding/key-wrap.svg.license new file mode 100644 index 00000000..17e2c3b5 --- /dev/null +++ b/doc/crypto/figure/encoding/key-wrap.svg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright 2024-2025 Arm Limited and/or its affiliates +SPDX-License-Identifier: CC-BY-SA-4.0 AND LicenseRef-Patent-license diff --git a/doc/crypto/references b/doc/crypto/references index baf1fca4..6c2e31d6 100644 --- a/doc/crypto/references +++ b/doc/crypto/references @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: Copyright 2020-2024 Arm Limited and/or its affiliates +.. SPDX-FileCopyrightText: Copyright 2020-2025 Arm Limited and/or its affiliates .. SPDX-License-Identifier: CC-BY-SA-4.0 AND LicenseRef-Patent-license .. reference:: PSM @@ -401,3 +401,27 @@ :title: PSA Certified Crypto API 1.3 PQC Extension :doc_no: ARM AES 0119 :url: arm-software.github.io/psa-api/crypto + +.. reference:: RFC5958 + :title: Asymmetric Key Packages + :author: IETF + :publication: August 2010 + :url: tools.ietf.org/html/rfc5958.html + +.. reference:: RFC3394 + :title: Advanced Encryption Standard (AES) Key Wrap Algorithm + :author: IETF + :publication: September 2002 + :url: tools.ietf.org/html/rfc3394.html + +.. reference:: RFC5649 + :title: Advanced Encryption Standard (AES) Key Wrap with Padding Algorithm + :author: IETF + :publication: August 2009 + :url: tools.ietf.org/html/rfc5649.html + +.. reference:: SP800-38F + :title: NIST Special Publication 800-38F: Recommendation for Block Cipher Modes of Operation: Methods for Key Wrapping + :author: NIST + :publication: December 2012 + :url: doi.org/10.6028/NIST.SP.800-38F