Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions doc/crypto/api.db/psa/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ typedef /* implementation-defined type */ psa_mac_operation_t;
#define PSA_ALG_IS_SIGN(alg) /* specification-defined value */
#define PSA_ALG_IS_SIGN_HASH(alg) /* specification-defined value */
#define PSA_ALG_IS_SIGN_MESSAGE(alg) /* specification-defined value */
#define PSA_ALG_IS_SP800_108_COUNTER_HMAC(alg) \
/* specification-defined value */
#define PSA_ALG_IS_STANDALONE_KEY_AGREEMENT(alg) \
/* specification-defined value */
#define PSA_ALG_IS_STREAM_CIPHER(alg) /* specification-defined value */
Expand Down Expand Up @@ -144,6 +146,9 @@ typedef /* implementation-defined type */ psa_mac_operation_t;
#define PSA_ALG_SHA_512_224 ((psa_algorithm_t)0x0200000c)
#define PSA_ALG_SHA_512_256 ((psa_algorithm_t)0x0200000d)
#define PSA_ALG_SM3 ((psa_algorithm_t)0x02000014)
#define PSA_ALG_SP800_108_COUNTER_CMAC ((psa_algorithm_t)0x08000800)
#define PSA_ALG_SP800_108_COUNTER_HMAC(hash_alg) \
/* specification-defined value */
#define PSA_ALG_STREAM_CIPHER ((psa_algorithm_t)0x04800100)
#define PSA_ALG_TLS12_ECJPAKE_TO_PMS ((psa_algorithm_t)0x08000609)
#define PSA_ALG_TLS12_PRF(hash_alg) /* specification-defined value */
Expand Down
7 changes: 7 additions & 0 deletions doc/crypto/api/keys/types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ Symmetric keys
| `PSA_ALG_HKDF` (non-secret inputs)
| `PSA_ALG_HKDF_EXPAND` (non-secret inputs)
| `PSA_ALG_HKDF_EXTRACT` (non-secret inputs)
| `PSA_ALG_SP800_108_COUNTER_HMAC` (non-secret inputs)
| `PSA_ALG_SP800_108_COUNTER_CMAC` (non-secret inputs)
| `PSA_ALG_TLS12_PRF` (non-secret inputs)
| `PSA_ALG_TLS12_PSK_TO_MS` (non-secret inputs)

Expand All @@ -130,6 +132,7 @@ Symmetric keys
.. subsection:: Compatible algorithms

| `PSA_ALG_HMAC`
| `PSA_ALG_SP800_108_COUNTER_HMAC` (secret input)

.. macro:: PSA_KEY_TYPE_DERIVE
:definition: ((psa_key_type_t)0x1200)
Expand Down Expand Up @@ -234,6 +237,7 @@ Symmetric keys
| `PSA_ALG_ECB_NO_PADDING`
| `PSA_ALG_CCM`
| `PSA_ALG_GCM`
| `PSA_ALG_SP800_108_COUNTER_CMAC` (secret input)

.. macro:: PSA_KEY_TYPE_ARIA
:definition: ((psa_key_type_t)0x2406)
Expand Down Expand Up @@ -268,6 +272,7 @@ Symmetric keys
| `PSA_ALG_ECB_NO_PADDING`
| `PSA_ALG_CCM`
| `PSA_ALG_GCM`
| `PSA_ALG_SP800_108_COUNTER_CMAC` (secret input)

.. macro:: PSA_KEY_TYPE_DES
:definition: ((psa_key_type_t)0x2301)
Expand Down Expand Up @@ -333,6 +338,7 @@ Symmetric keys
| `PSA_ALG_ECB_NO_PADDING`
| `PSA_ALG_CCM`
| `PSA_ALG_GCM`
| `PSA_ALG_SP800_108_COUNTER_CMAC` (secret input)

.. macro:: PSA_KEY_TYPE_SM4
:definition: ((psa_key_type_t)0x2405)
Expand All @@ -359,6 +365,7 @@ Symmetric keys
| `PSA_ALG_ECB_NO_PADDING`
| `PSA_ALG_CCM`
| `PSA_ALG_GCM`
| `PSA_ALG_SP800_108_COUNTER_CMAC` (secret input)

.. macro:: PSA_KEY_TYPE_ARC4
:definition: ((psa_key_type_t)0x2002)
Expand Down
115 changes: 115 additions & 0 deletions doc/crypto/api/ops/kdf.rst
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,103 @@ Key derivation algorithms
| `PSA_KEY_TYPE_DERIVE` (for the pseudorandom key)
| `PSA_KEY_TYPE_RAW_DATA` (for the info string)

.. macro:: PSA_ALG_SP800_108_COUNTER_HMAC
:definition: /* specification-defined value */

.. summary::
Macro to build a NIST SP 800-108 conformant, counter-mode KDF algorithm based on HMAC.

.. param:: hash_alg
A hash algorithm: a value of type `psa_algorithm_t` such that :code:`PSA_ALG_IS_HASH(hash_alg)` is true.

.. return::
The corresponding key derivation algorithm. For example, the counter-mode KDF using HMAC-SHA-256 is :code:`PSA_ALG_SP800_108_COUNTER_HMAC(PSA_ALG_SHA_256)`.

Unspecified if ``hash_alg`` is not a supported hash algorithm.

This is an HMAC-based, counter mode key derivation function, using the construction recommended by :cite-title:`SP800-108`, §4.1.

This key derivation algorithm uses the following inputs:

* `PSA_KEY_DERIVATION_INPUT_SECRET` is the secret input keying material, :math:`K_{IN}`.
* `PSA_KEY_DERIVATION_INPUT_LABEL` is the :math:`Label`. It is optional; if omitted, :math:`Label` is a zero-length string. If provided, it must not contain any null bytes.
* `PSA_KEY_DERIVATION_INPUT_CONTEXT` is the :math:`Context`. It is optional; if omitted, :math:`Context` is a zero-length string.

Each input can only be passed once. Inputs must be passed in the order above.

This algorithm uses the output length as part of the derivation process. In the derivation this value is :math:`L`, the required output size in bits. After setup, the initial capacity of the key derivation operation is :math:`2^{29}-1` bytes (``0x1fffffff``). The capacity can be set to a lower value by calling `psa_key_derivation_set_capacity()`.

When the first output is requested, the value of :math:`L` is calculated as :math:`L=8*cap`, where :math:`cap` is the value of `psa_key_derivation_get_capacity()`. Subsequent calls to `psa_key_derivation_set_capacity()` are not permitted for this algorithm.

The derivation is constructed as described in :cite:`SP800-108` §4.1, with the iteration counter :math:`i` and output length :math:`L` encoded as big-endian, 32-bit values. The resulting output stream :math:`K_1\ ||\ K_2\ ||\ K_3\ ||\ ...` is computed as:

.. math::

K_i = \text{HMAC}( K_{IN}, [i]_4\ ||\ Label\ ||\ \texttt{0x00}\ ||\ Context\ ||\ [L]_4 ),\quad\text{for }i = 1, 2, 3, ...

Where :math:`[x]_n` is the big-endian, :math:`n`-byte encoding of the integer :math:`x`.

.. rationale::

:cite:`SP800-108` describes a set of general constructions for key derivation algorithms, with flexibility for specific implementation requirements.

The precise definition provided here enables compatibility between different implementations of the |API|.

.. subsection:: Compatible key types

| `PSA_KEY_TYPE_HMAC` (for the secret key)
| `PSA_KEY_TYPE_DERIVE` (for the secret key)
| `PSA_KEY_TYPE_RAW_DATA` (for the other inputs)

.. macro:: PSA_ALG_SP800_108_COUNTER_CMAC
:definition: ((psa_algorithm_t)0x08000800)

.. summary::
Macro to build a NIST SP 800-108 conformant, counter-mode KDF algorithm based on CMAC.

This is a CMAC-based, counter mode key derivation function, using the construction recommended by :cite-title:`SP800-108`, §4.1.

This key derivation algorithm uses the following inputs:

* `PSA_KEY_DERIVATION_INPUT_SECRET` is the secret input keying material, :math:`K_{IN}`. This must be a block-cipher key that is compatible with the CMAC algorithm, and must be input using `psa_key_derivation_input_key()`. See also `PSA_ALG_CMAC`.
* `PSA_KEY_DERIVATION_INPUT_LABEL` is the :math:`Label`. It is optional; if omitted, :math:`Label` is a zero-length string. If provided, it must not contain any null bytes.
* `PSA_KEY_DERIVATION_INPUT_CONTEXT` is the :math:`Context`. It is optional; if omitted, :math:`Context` is a zero-length string.

Each input can only be passed once. Inputs must be passed in the order above.

This algorithm uses the output length as part of the derivation process. In the derivation this value is :math:`L`, the required output size in bits. After setup, the initial capacity of the key derivation operation is :math:`2^{29}-1` bytes (``0x1fffffff``). The capacity can be set to a lower value by calling `psa_key_derivation_set_capacity()`.

When the first output is requested, the value of :math:`L` is calculated as :math:`L=8*cap`, where :math:`cap` is the value of `psa_key_derivation_get_capacity()`. Subsequent calls to `psa_key_derivation_set_capacity()` are not permitted for this algorithm.

The derivation is constructed as described in :cite:`SP800-108` §4.1, with the following details:

* The iteration counter :math:`i` and output length :math:`L` are encoded as big-endian, 32-bit values.
* The mitigation to make the CMAC-based construction robust is implemented.

The resulting output stream :math:`K_1\ ||\ K_2\ ||\ K_3\ ||\ ...` is computed as:

.. math::

K_0 &= \text{CMAC}( K_{IN}, Label\ ||\ \texttt{0x00}\ ||\ Context\ ||\ [L]_4\ )

K_i &= \text{CMAC}( K_{IN}, [i]_4\ ||\ Label\ ||\ \texttt{0x00}\ ||\ Context\ ||\ [L]_4\ ||\ K_0 ),\quad\text{for }i = 1, 2, 3, ...

Where :math:`[x]_n` is the big-endian, :math:`n`-byte encoding of the integer :math:`x`.

.. rationale::

:cite:`SP800-108` describes a set of general constructions for key derivation algorithms, with flexibility for specific implementation requirements.

The precise definition provided here enables compatibility between different implementations of the |API|.

.. subsection:: Compatible key types

| `PSA_KEY_TYPE_AES` (for the secret key)
| `PSA_KEY_TYPE_ARIA` (for the secret key)
| `PSA_KEY_TYPE_CAMELLIA` (for the secret key)
| `PSA_KEY_TYPE_SM4` (for the secret key)
Comment thread
athoelke marked this conversation as resolved.
| `PSA_KEY_TYPE_RAW_DATA` (for the other inputs)

.. macro:: PSA_ALG_TLS12_PRF
:definition: /* specification-defined value */

Expand Down Expand Up @@ -323,6 +420,8 @@ Input step types

This is typically a key of type `PSA_KEY_TYPE_DERIVE` passed to `psa_key_derivation_input_key()`, or the shared secret resulting from a key agreement obtained via `psa_key_derivation_key_agreement()`.

For some algorithms, a specific type of key is required. For example, see `PSA_ALG_SP800_108_COUNTER_CMAC`.

The secret can also be a direct input passed to `psa_key_derivation_input_bytes()`. In this case, the derivation operation cannot be used to derive keys: the operation will not permit a call to `psa_key_derivation_output_key()`.

.. macro:: PSA_KEY_DERIVATION_INPUT_OTHER_SECRET
Expand Down Expand Up @@ -545,6 +644,10 @@ Key derivation functions

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

.. note::

For some algorithms, the capacity value can affect the output of the key derivation. For example, see `PSA_ALG_SP800_108_COUNTER_HMAC`.

.. function:: psa_key_derivation_input_bytes

.. summary::
Expand Down Expand Up @@ -1126,6 +1229,18 @@ Support macros
.. return::
``1`` if ``alg`` is an HKDF-Expand algorithm, ``0`` otherwise. This macro can return either ``0`` or ``1`` if ``alg`` is not a supported key derivation algorithm identifier.

.. macro:: PSA_ALG_IS_SP800_108_COUNTER_HMAC
:definition: /* specification-defined value */

.. summary::
Whether the specified algorithm is a key derivation algorithm constructed using :code:`PSA_ALG_SP800_108_COUNTER_HMAC(hash_alg)`.

.. param:: alg
An algorithm identifier: a value of type `psa_algorithm_t`.

.. return::
``1`` if ``alg`` is a key derivation algorithm constructed using :code:`PSA_ALG_SP800_108_COUNTER_HMAC()`, ``0`` otherwise. This macro can return either ``0`` or ``1`` if ``alg`` is not a supported key derivation algorithm identifier.

.. macro:: PSA_ALG_IS_TLS12_PRF
:definition: /* specification-defined value */

Expand Down
16 changes: 9 additions & 7 deletions doc/crypto/appendix/encodings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -265,16 +265,18 @@ The permitted values of HASH-TYPE (see :numref:`table-hash-type`) depend on the
:widths: auto

Key derivation algorithm, S, KDF-TYPE, Algorithm identifier, Algorithm value
HKDF, 0, ``0x01``, :code:`PSA_ALG_HKDF(hash_alg)`, ``0x080001hh`` :sup:`a`
TLS-1.2 PRF, 0, ``0x02``, :code:`PSA_ALG_TLS12_PRF(hash_alg)`, ``0x080002hh`` :sup:`a`
TLS-1.2 PSK-to-MasterSecret, 0, ``0x03``, :code:`PSA_ALG_TLS12_PSK_TO_MS(hash_alg)`, ``0x080003hh`` :sup:`a`
HKDF, 0, ``0x01``, :code:`PSA_ALG_HKDF(hash)`, ``0x080001hh`` :sup:`a`
TLS-1.2 PRF, 0, ``0x02``, :code:`PSA_ALG_TLS12_PRF(hash)`, ``0x080002hh`` :sup:`a`
TLS-1.2 PSK-to-MasterSecret, 0, ``0x03``, :code:`PSA_ALG_TLS12_PSK_TO_MS(hash)`, ``0x080003hh`` :sup:`a`
HKDF-Extract, 0, ``0x04``, :code:`PSA_ALG_HKDF_EXTRACT(hash)`, ``0x080004hh`` :sup:`a`
HKDF-Expand, 0, ``0x05``, :code:`PSA_ALG_HKDF_EXPAND(hash)`, ``0x080005hh`` :sup:`a`
TLS 1.2 ECJPAKE-to-PMS, 0, ``0x06``, :code:`PSA_ALG_TLS12_ECJPAKE_TO_PMS`, ``0x08000609``
HKDF-Extract, 0, ``0x04``, :code:`PSA_ALG_HKDF_EXTRACT(hash_alg)`, ``0x080004hh`` :sup:`a`
HKDF-Expand, 0, ``0x05``, :code:`PSA_ALG_HKDF_EXPAND(hash_alg)`, ``0x080005hh`` :sup:`a`
PBKDF2-HMAC, 1, ``0x01``, :code:`PSA_ALG_PBKDF2_HMAC(hash_alg)`, ``0x088001hh`` :sup:`a`
SP 800-108 Counter HMAC, 0, ``0x07``, :code:`PSA_ALG_SP800_108_COUNTER_HMAC(hash)`, ``0x080007hh`` :sup:`a`
SP 800-108 Counter CMAC, 0, ``0x08``, :code:`PSA_ALG_SP800_108_COUNTER_CMAC`, ``0x08000800``
PBKDF2-HMAC, 1, ``0x01``, :code:`PSA_ALG_PBKDF2_HMAC(hash)`, ``0x088001hh`` :sup:`a`
PBKDF2-AES-CMAC-PRF-128, 1, ``0x02``, :code:`PSA_ALG_PBKDF2_AES_CMAC_PRF_128`, ``0x08800200``

a. ``hh`` is the HASH-TYPE for the hash algorithm, ``hash_alg``, used to construct the key derivation algorithm.
a. ``hh`` is the HASH-TYPE for the hash algorithm, ``hash``, used to construct the key derivation algorithm.

.. _sign-encoding:

Expand Down
1 change: 1 addition & 0 deletions doc/crypto/appendix/history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Changes to the API
* Added support for TLS 1.2 ECJPAKE-to-PMS key-derivation. See `PSA_ALG_TLS12_ECJPAKE_TO_PMS`.
* Changed the policy for `psa_key_derivation_verify_bytes()` and `psa_key_derivation_verify_key()`, so that these functions are also permitted when an input key has the `PSA_KEY_USAGE_DERIVE` usage flag.
* Removed the special treatment of :code:`PSA_ERROR_INVALID_SIGNATURE` for key derivation operations. A verification failure in `psa_key_derivation_verify_bytes()` and `psa_key_derivation_verify_key()` now puts the operation into an error state.
* Defined key derivation algorithms based on the Counter mode recommendations in :cite-title:`SP800-108`. See `PSA_ALG_SP800_108_COUNTER_HMAC()` and `PSA_ALG_SP800_108_COUNTER_CMAC`.

* Added `psa_key_agreement()` for standalone key agreement that outputs to a new key object. Also added `PSA_ALG_IS_STANDALONE_KEY_AGREEMENT()` as a synonym for `PSA_ALG_IS_RAW_KEY_AGREEMENT()`.

Expand Down
8 changes: 7 additions & 1 deletion doc/crypto/appendix/specdef_values.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.. SPDX-FileCopyrightText: Copyright 2020-2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
.. SPDX-FileCopyrightText: Copyright 2020-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
.. SPDX-License-Identifier: CC-BY-SA-4.0 AND LicenseRef-Patent-license

.. _appendix-specdef-values:
Expand Down Expand Up @@ -152,6 +152,9 @@ Algorithm macros
(PSA_ALG_IS_SIGN(alg) && \
(alg) != PSA_ALG_ECDSA_ANY && (alg) != PSA_ALG_RSA_PKCS1V15_SIGN_RAW)

#define PSA_ALG_IS_SP800_108_COUNTER_HMAC(alg) \
(((alg) & ~0x000000ff) == 0x08000700)

#define PSA_ALG_IS_STANDALONE_KEY_AGREEMENT(alg) \
(((alg) & 0x7f00ffff) == 0x09000000)

Expand Down Expand Up @@ -193,6 +196,9 @@ Algorithm macros
#define PSA_ALG_RSA_PSS_ANY_SALT(hash_alg) \
((psa_algorithm_t)(0x06001300 | ((hash_alg) & 0x000000ff)))

#define PSA_ALG_SP800_108_COUNTER_HMAC(hash_alg) \
((psa_algorithm_t) (0x08000700 | ((hash_alg) & 0x000000ff)))

#define PSA_ALG_TLS12_PRF(hash_alg) \
((psa_algorithm_t) (0x08000200 | ((hash_alg) & 0x000000ff)))

Expand Down
8 changes: 7 additions & 1 deletion doc/crypto/references
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.. SPDX-FileCopyrightText: Copyright 2020-2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
.. SPDX-FileCopyrightText: Copyright 2020-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
.. SPDX-License-Identifier: CC-BY-SA-4.0 AND LicenseRef-Patent-license

.. reference:: PSA-PAKE
Expand Down Expand Up @@ -147,6 +147,12 @@
:publication: November 2017
:url: doi.org/10.6028/NIST.SP.800-67r2

.. reference:: SP800-108
:title: NIST Special Publication 800-108r1: Recommendation for Key Derivation Using Pseudorandom Functions
:author: NIST
:publication: August 2022
:url: doi.org/10.6028/NIST.SP.800-108r1

.. reference:: RFC1319
:title: The MD2 Message-Digest Algorithm
:author: IETF
Expand Down