Skip to content

Commit 783fdc3

Browse files
authored
Merge pull request #118 from athoelke/crypto-kdf-clarification
KDF relaxations and clarifications
2 parents b402181 + c162a20 commit 783fdc3

3 files changed

Lines changed: 43 additions & 23 deletions

File tree

doc/crypto/api/keys/policy.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ The usage flags are encoded in a bitmask, which has the type `psa_key_usage_t`.
234234
* `psa_key_derivation_key_agreement()`
235235
* `psa_raw_key_agreement()`
236236

237-
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_output_bytes()` or `psa_key_derivation_output_key()` at the end of the operation.
237+
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_output_bytes()`, `psa_key_derivation_output_key()`, `psa_key_derivation_verify_bytes()`, or `psa_key_derivation_verify_key()` at the end of the operation.
238238

239239
.. macro:: PSA_KEY_USAGE_VERIFY_DERIVATION
240240
:definition: ((psa_key_usage_t)0x00008000)

doc/crypto/api/ops/kdf.rst

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ Key derivation functions
685685

686686
* `psa_key_derivation_output_bytes()` --- if each input was either a direct input or a key with usage flag `PSA_KEY_USAGE_DERIVE`.
687687
* `psa_key_derivation_output_key()` --- if the input for step `PSA_KEY_DERIVATION_INPUT_SECRET` or `PSA_KEY_DERIVATION_INPUT_PASSWORD` was a key with usage flag `PSA_KEY_USAGE_DERIVE`, and every other input was either a direct input or a key with usage flag `PSA_KEY_USAGE_DERIVE`.
688-
* `psa_key_derivation_verify_bytes()` --- if each input was either a direct input or a key with usage flag `PSA_KEY_USAGE_VERIFY_DERIVATION`.
688+
* `psa_key_derivation_verify_bytes()` --- if each input was either a direct input, a key with usage flag `PSA_KEY_USAGE_DERIVE`, or a key with usage flag `PSA_KEY_USAGE_VERIFY_DERIVATION`.
689689
* `psa_key_derivation_verify_key()` --- under the same conditions as `psa_key_derivation_verify_bytes()`.
690690

691691
If this function returns an error status, the operation enters an error state and must be aborted by calling `psa_key_derivation_abort()`.
@@ -712,7 +712,7 @@ Key derivation functions
712712
The operation's capacity was less than ``output_length`` bytes. In this case, the following occurs:
713713

714714
* No output is written to the output buffer.
715-
* The operation's capacity is set to zero --- subsequent calls to this function will not succeed, even with a smaller output buffer.
715+
* The operation's capacity is set to zero.
716716
.. retval:: PSA_ERROR_BAD_STATE
717717
The following conditions can result in this error:
718718

@@ -727,6 +727,10 @@ Key derivation functions
727727

728728
This function calculates output bytes from a key derivation algorithm and returns those bytes. If the key derivation's output is viewed as a stream of bytes, this function consumes the requested number of bytes from the stream and returns them to the caller. The operation's capacity decreases by the number of bytes read.
729729

730+
A request to extract more data than the remaining capacity --- :code:`output_length > psa_key_derivation_get_capacity()` --- fails with :code:`PSA_ERROR_INSUFFICIENT_DATA`, and sets the remaining capacity to zero.
731+
732+
If the operation's capacity is zero, and ``output_length`` is zero, then it is :scterm:`implementation defined` whether this function returns :code:`PSA_SUCCESS` or :code:`PSA_ERROR_INSUFFICIENT_DATA`.
733+
730734
If this function returns an error status other than :code:`PSA_ERROR_INSUFFICIENT_DATA`, the operation enters an error state and must be aborted by calling `psa_key_derivation_abort()`.
731735

732736
.. function:: psa_key_derivation_output_key
@@ -765,7 +769,7 @@ Key derivation functions
765769
There was not enough data to create the desired key. In this case, the following occurs:
766770

767771
* No key is generated.
768-
* The operation's capacity is set to zero --- subsequent calls to this function will not succeed, even if they require less data.
772+
* The operation's capacity is set to zero.
769773
.. retval:: PSA_ERROR_NOT_SUPPORTED
770774
The key attributes, as a whole, are not supported, either by the implementation in general or in the specified storage location.
771775
.. retval:: PSA_ERROR_INVALID_ARGUMENT
@@ -802,6 +806,8 @@ Key derivation functions
802806

803807
If the key derivation's output is viewed as a stream of bytes, this function consumes the required number of bytes from the stream. The operation's capacity decreases by the number of bytes used to derive the key.
804808

809+
A request that needs to extract more data than the remaining capacity fails with :code:`PSA_ERROR_INSUFFICIENT_DATA`, and sets the remaining capacity to zero.
810+
805811
If this function returns an error status other than :code:`PSA_ERROR_INSUFFICIENT_DATA`, the operation enters an error state and must be aborted by calling `psa_key_derivation_abort()`.
806812

807813
How much output is produced and consumed from the operation, and how the key is derived, depends on the key type. :numref:`std-key-derivation` describes the required key derivation procedures for standard key derivation algorithms. Implementations can use other methods for implementation-specific algorithms.
@@ -810,8 +816,6 @@ Key derivation functions
810816

811817
Permitting implementation defined methods for algorithms not specified in the |API| permits implementations to use other appropriate procedures in cases where interoperability with other implementations is not required.
812818

813-
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.
814-
815819
.. list-table:: Standard key derivation process
816820
:name: std-key-derivation
817821
:class: longtable
@@ -928,18 +932,18 @@ Key derivation functions
928932
.. param:: const uint8_t *expected_output
929933
Buffer containing the expected derivation output.
930934
.. param:: size_t output_length
931-
Length ot the expected output. This is also the number of bytes that will be read.
935+
Length of the expected output. This is also the number of bytes that will be read.
932936

933937
.. return:: psa_status_t
934938
.. retval:: PSA_SUCCESS
935939
Success.
936940
The output of the key derivation operation matches ``expected_output``.
937941
.. retval:: PSA_ERROR_NOT_PERMITTED
938-
One of the inputs is a key whose policy does not permit `PSA_KEY_USAGE_VERIFY_DERIVATION`.
942+
One of the inputs is a key whose policy permits neither `PSA_KEY_USAGE_DERIVE` nor `PSA_KEY_USAGE_VERIFY_DERIVATION`.
939943
.. retval:: PSA_ERROR_INVALID_SIGNATURE
940944
The output of the key derivation operation does not match the value in ``expected_output``.
941945
.. retval:: PSA_ERROR_INSUFFICIENT_DATA
942-
The operation's capacity was less than ``output_length`` bytes. In this case, the operation's capacity is set to zero --- subsequent calls to this function will not succeed, even with a smaller expected output length.
946+
The operation's capacity was less than ``output_length`` bytes. In this case, the operation's capacity is set to zero.
943947
.. retval:: PSA_ERROR_INSUFFICIENT_MEMORY
944948
.. retval:: PSA_ERROR_COMMUNICATION_FAILURE
945949
.. retval:: PSA_ERROR_CORRUPTION_DETECTED
@@ -956,20 +960,27 @@ Key derivation functions
956960
If the key derivation's output is viewed as a stream of bytes, this function destructively reads ``output_length`` bytes from the stream before comparing them with ``expected_output``.
957961
The operation's capacity decreases by the number of bytes read.
958962

959-
This is functionally equivalent to the following code:
963+
A request to extract more data than the remaining capacity --- :code:`output_length > psa_key_derivation_get_capacity()` --- fails with :code:`PSA_ERROR_INSUFFICIENT_DATA`, and sets the remaining capacity to zero.
960964

961-
.. code-block:: xref
965+
If the operation's capacity is zero, and ``output_length`` is zero, then it is :scterm:`implementation defined` whether this function returns :code:`PSA_SUCCESS` or :code:`PSA_ERROR_INSUFFICIENT_DATA`.
962966

963-
uint8_t tmp[output_length];
964-
psa_key_derivation_output_bytes(operation, tmp, output_length);
965-
if (memcmp(expected_output, tmp, output_length) != 0)
966-
return PSA_ERROR_INVALID_SIGNATURE;
967+
If this function returns an error status other than :code:`PSA_ERROR_INSUFFICIENT_DATA`, the operation enters an error state and must be aborted by calling `psa_key_derivation_abort()`.
967968

968-
However, calling `psa_key_derivation_verify_bytes()` works even if the key's policy does not permit output of the bytes.
969+
.. note::
969970

970-
If this function returns an error status other than :code:`PSA_ERROR_INSUFFICIENT_DATA` or :code:`PSA_ERROR_INVALID_SIGNATURE`, the operation enters an error state and must be aborted by calling `psa_key_derivation_abort()`.
971+
A call to `psa_key_derivation_verify_bytes()` is functionally equivalent to the following code:
972+
973+
.. code-block:: xref
974+
975+
uint8_t tmp[output_length];
976+
psa_key_derivation_output_bytes(operation, tmp, output_length);
977+
if (memcmp(expected_output, tmp, output_length) != 0)
978+
return PSA_ERROR_INVALID_SIGNATURE;
979+
980+
However, calling `psa_key_derivation_verify_bytes()` works even if the key's policy does not permit output of the bytes.
981+
982+
.. admonition:: Implementation note
971983

972-
.. note::
973984
Implementations must make the best effort to ensure that the comparison between the actual key derivation output and the expected output is performed in constant time.
974985

975986
.. function:: psa_key_derivation_verify_key
@@ -996,12 +1007,12 @@ Key derivation functions
9961007
.. retval:: PSA_ERROR_NOT_PERMITTED
9971008
The following conditions can result in this error:
9981009

999-
* The key does not have the `PSA_KEY_USAGE_VERIFY_DERIVATION` flag, or it does not permit the requested algorithm.
1000-
* One of the inputs is a key whose policy does not permit `PSA_KEY_USAGE_VERIFY_DERIVATION`.
1010+
* The ``expected`` key does not have the `PSA_KEY_USAGE_VERIFY_DERIVATION` flag, or it does not permit the requested algorithm.
1011+
* One of the inputs is a key whose policy permits neither `PSA_KEY_USAGE_DERIVE` nor `PSA_KEY_USAGE_VERIFY_DERIVATION`.
10011012
.. retval:: PSA_ERROR_INVALID_SIGNATURE
10021013
The output of the key derivation operation does not match the value of the ``expected`` key.
10031014
.. retval:: PSA_ERROR_INSUFFICIENT_DATA
1004-
The operation's capacity was less than the length of the ``expected`` key. In this case, the operation's capacity is set to zero --- subsequent calls to this function will not succeed, even with a smaller expected key length.
1015+
The operation's capacity was less than the length of the ``expected`` key. In this case, the operation's capacity is set to zero.
10051016
.. retval:: PSA_ERROR_INSUFFICIENT_MEMORY
10061017
.. retval:: PSA_ERROR_COMMUNICATION_FAILURE
10071018
.. retval:: PSA_ERROR_CORRUPTION_DETECTED
@@ -1019,11 +1030,16 @@ Key derivation functions
10191030
If the key derivation's output is viewed as a stream of bytes, this function destructively reads the number of bytes corresponding to the length of the ``expected`` key from the stream before comparing them with the key value.
10201031
The operation's capacity decreases by the number of bytes read.
10211032

1022-
This is functionally equivalent to exporting the ``expected`` key and calling `psa_key_derivation_verify_bytes()` on the result, except that it works when the key cannot be exported.
1033+
A request that needs to extract more data than the remaining capacity fails with :code:`PSA_ERROR_INSUFFICIENT_DATA`, and sets the remaining capacity to zero.
10231034

1024-
If this function returns an error status other than :code:`PSA_ERROR_INSUFFICIENT_DATA` or :code:`PSA_ERROR_INVALID_SIGNATURE`, the operation enters an error state and must be aborted by calling `psa_key_derivation_abort()`.
1035+
If this function returns an error status other than :code:`PSA_ERROR_INSUFFICIENT_DATA`, the operation enters an error state and must be aborted by calling `psa_key_derivation_abort()`.
10251036

10261037
.. note::
1038+
1039+
A call to `psa_key_derivation_verify_key()` is functionally equivalent to exporting the ``expected`` key and calling `psa_key_derivation_verify_bytes()` on the result, except that it works when the key cannot be exported.
1040+
1041+
.. admonition:: Implementation note
1042+
10271043
Implementations must make the best effort to ensure that the comparison between the actual key derivation output and the expected output is performed in constant time.
10281044

10291045
.. function:: psa_key_derivation_abort

doc/crypto/appendix/history.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,14 @@ Changes to the API
1818
~~~~~~~~~~~~~~~~~~
1919

2020
* Added support for TLS 1.2 ECJPAKE-to-PMS key-derivation. See `PSA_ALG_TLS12_ECJPAKE_TO_PMS`.
21+
* 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.
22+
* 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.
2123

2224
Clarifications and fixes
2325
~~~~~~~~~~~~~~~~~~~~~~~~
2426

27+
* Clarified the behavior of a key derivation operation when there is insufficient capacity for a call to `psa_key_derivation_output_bytes()`, `psa_key_derivation_output_key()`, `psa_key_derivation_verify_bytes()`, or `psa_key_derivation_verify_key()`.
28+
2529
Other changes
2630
~~~~~~~~~~~~~
2731

0 commit comments

Comments
 (0)