diff --git a/doc/crypto/api/keys/policy.rst b/doc/crypto/api/keys/policy.rst index 614cb78b..40b56db2 100644 --- a/doc/crypto/api/keys/policy.rst +++ b/doc/crypto/api/keys/policy.rst @@ -204,7 +204,9 @@ The usage flags are encoded in a bitmask, which has the type `psa_key_usage_t`. .. summary:: Permission to sign a message hash with the key. - This flag is required to use the key to sign a message hash in an asymmetric signature operation. The flag must be present on keys used when calling `psa_sign_hash()`. + This flag is required to use the key to sign a pre-computed message hash in an asymmetric signature operation. The flag must be present on keys used with the following APIs: + + * `psa_sign_hash()` This flag automatically sets `PSA_KEY_USAGE_SIGN_MESSAGE`: if an application sets the flag `PSA_KEY_USAGE_SIGN_HASH` when creating a key, then the key always has the permissions conveyed by `PSA_KEY_USAGE_SIGN_MESSAGE`, and the flag `PSA_KEY_USAGE_SIGN_MESSAGE` will also be present when the application queries the usage flags of the key. @@ -216,7 +218,9 @@ The usage flags are encoded in a bitmask, which has the type `psa_key_usage_t`. .. summary:: Permission to verify a message hash with the key. - This flag is required to use the key to verify a message hash in an asymmetric signature verification operation. The flag must be present on keys used when calling `psa_verify_hash()`. + This flag is required to use the key to verify a pre-computed message hash in an asymmetric signature verification operation. The flag must be present on keys used with the following APIs: + + * `psa_verify_hash()` This flag automatically sets `PSA_KEY_USAGE_VERIFY_MESSAGE`: if an application sets the flag `PSA_KEY_USAGE_VERIFY_HASH` when creating a key, then the key always has the permissions conveyed by `PSA_KEY_USAGE_VERIFY_MESSAGE`, and the flag `PSA_KEY_USAGE_VERIFY_MESSAGE` will also be present when the application queries the usage flags of the key. diff --git a/doc/crypto/api/library/status.rst b/doc/crypto/api/library/status.rst index 93a15d98..a23e58e8 100644 --- a/doc/crypto/api/library/status.rst +++ b/doc/crypto/api/library/status.rst @@ -12,29 +12,29 @@ The following elements are defined in :file:`psa/error.h` from :cite-title:`PSA- .. code-block:: xref - typedef int32_t psa_status_t; - - #define PSA_SUCCESS ((psa_status_t)0) - - #define PSA_ERROR_GENERIC_ERROR ((psa_status_t)-132) - #define PSA_ERROR_NOT_PERMITTED ((psa_status_t)-133) - #define PSA_ERROR_NOT_SUPPORTED ((psa_status_t)-134) - #define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)-135) - #define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136) - #define PSA_ERROR_BAD_STATE ((psa_status_t)-137) - #define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t)-138) - #define PSA_ERROR_ALREADY_EXISTS ((psa_status_t)-139) - #define PSA_ERROR_DOES_NOT_EXIST ((psa_status_t)-140) - #define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t)-141) - #define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t)-142) - #define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t)-143) - #define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t)-145) - #define PSA_ERROR_STORAGE_FAILURE ((psa_status_t)-146) - #define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t)-147) - #define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t)-149) - #define PSA_ERROR_CORRUPTION_DETECTED ((psa_status_t)-151) - #define PSA_ERROR_DATA_CORRUPT ((psa_status_t)-152) - #define PSA_ERROR_DATA_INVALID ((psa_status_t)-153) + typedef int32_t psa_status_t; + + #define PSA_SUCCESS ((psa_status_t)0) + + #define PSA_ERROR_GENERIC_ERROR ((psa_status_t)-132) + #define PSA_ERROR_NOT_PERMITTED ((psa_status_t)-133) + #define PSA_ERROR_NOT_SUPPORTED ((psa_status_t)-134) + #define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)-135) + #define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136) + #define PSA_ERROR_BAD_STATE ((psa_status_t)-137) + #define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t)-138) + #define PSA_ERROR_ALREADY_EXISTS ((psa_status_t)-139) + #define PSA_ERROR_DOES_NOT_EXIST ((psa_status_t)-140) + #define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t)-141) + #define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t)-142) + #define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t)-143) + #define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t)-145) + #define PSA_ERROR_STORAGE_FAILURE ((psa_status_t)-146) + #define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t)-147) + #define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t)-149) + #define PSA_ERROR_CORRUPTION_DETECTED ((psa_status_t)-151) + #define PSA_ERROR_DATA_CORRUPT ((psa_status_t)-152) + #define PSA_ERROR_DATA_INVALID ((psa_status_t)-153) These definitions must be available to an application that includes the :file:`psa/crypto.h` header file. @@ -89,7 +89,7 @@ Some of the common status codes have a more precise meaning when returned by a f .. _specific-errors: Error codes specific to the |API| -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. header:: psa/crypto :seq: 2 diff --git a/doc/crypto/api/ops/algorithms.rst b/doc/crypto/api/ops/algorithms.rst index 98517b75..8a5cd299 100644 --- a/doc/crypto/api/ops/algorithms.rst +++ b/doc/crypto/api/ops/algorithms.rst @@ -20,7 +20,7 @@ The specific algorithm identifiers are described alongside the cryptographic ope * :secref:`cipher-algorithms` * :secref:`aead-algorithms` * :secref:`key-derivation-algorithms` -* :secref:`sign-algorithms` +* :secref:`sign` * :secref:`asymmetric-encryption-algorithms` * :secref:`key-agreement-algorithms` * :secref:`pake` @@ -150,7 +150,7 @@ Algorithm categories .. return:: ``1`` if ``alg`` is an asymmetric signature algorithm, ``0`` otherwise. This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. - See :secref:`sign-algorithms` for a list of defined signature algorithms. + See :secref:`sign` for a list of defined signature algorithms. .. macro:: PSA_ALG_IS_ASYMMETRIC_ENCRYPTION :definition: /* specification-defined value */ diff --git a/doc/crypto/api/ops/hash.rst b/doc/crypto/api/ops/hash.rst index 9f2e7089..e84eb78d 100644 --- a/doc/crypto/api/ops/hash.rst +++ b/doc/crypto/api/ops/hash.rst @@ -184,7 +184,7 @@ Hash algorithms .. summary:: The first 512 bits (64 bytes) of the SHAKE256 output. - This is the prehashing for Ed448ph (see `PSA_ALG_ED448PH`). + This is the pre-hashing for Ed448ph (see `PSA_ALG_ED448PH`). SHAKE256 is defined in :cite:`FIPS202`. diff --git a/doc/crypto/api/ops/signature.rst b/doc/crypto/api/ops/signature.rst index d802a9ea..e2621ad9 100644 --- a/doc/crypto/api/ops/signature.rst +++ b/doc/crypto/api/ops/signature.rst @@ -9,18 +9,81 @@ Asymmetric signature ==================== -There are two pairs of single-part functions for asymmetric signature: +An asymmetric signature algorithm provides two functions: -* The signature and verification functions `psa_sign_message()` and `psa_verify_message()` take a message as one of their inputs and perform a hash-and-sign algorithm. +* **Sign**: Calculate a message signature using a private, or secret, key. +* **Verify**: Check that a signature matches a message using a public key. -* The functions `psa_sign_hash()` and `psa_verify_hash()` take a message hash as one of their inputs. This is useful for signing pre-computed hashes, or for implementing hash-and-sign using a :ref:`multi-part hash operation ` before signing the resulting hash. To determine which hash algorithm to use, call the macro `PSA_ALG_GET_HASH()` on the corresponding signature algorithm. +Successful verification indicates that the message signature was calculated using the private key that is associated with the public key. - Some hash-and-sign algorithms add padding to the message hash before completing the signing operation. The format of the padding that is used depends on the algorithm used to construct the signature, see the description of the specific algorithm for details. +In the |API|, an asymmetric-sign function requires an asymmetric key-pair; and an asymmetric-verify function requires an asymmetric public-key or key-pair. -.. _sign-algorithms: +.. rubric:: Signature schemes -Asymmetric signature algorithms -------------------------------- +The |API| supports the following signature schemes: + +* :secref:`rsa-sign-algorithms` +* :secref:`ecdsa-sign-algorithms` +* :secref:`eddsa-sign-algorithms` + +.. rubric:: Types of signature algorithm + +There are three categories of asymmetric signature algorithm in the |API|: + +* Hash-and-sign algorithms, that have two distinct phases: + + - Calculate a hash of the message + - Calculate a signature over the hash + + For these algorithms, the asymmetric signature API allows applications to either calculate the full message signature, or calculate the signature of a pre-computed hash. For example, this enables the application to use a multi-part hash operation to calculate the hash of a large message, prior to calculating or verifying a signature on the calculated hash. + + The following algorithms are in this category: + + | `PSA_ALG_RSA_PKCS1V15_SIGN` + | `PSA_ALG_RSA_PSS` + | `PSA_ALG_RSA_PSS_ANY_SALT` + | `PSA_ALG_ECDSA` + | `PSA_ALG_DETERMINISTIC_ECDSA` + | `PSA_ALG_ED25519PH` + | `PSA_ALG_ED448PH` + +* Message signature algorithms that do not separate the message processing from the signature calculations. This approach can provide better security against certain types of attack. + + For these algorithms, it is not possible to inject a pre-computed hash into the middle of the algorithm. An application can choose to calculate a message hash, and sign that instead of the message --- but this is not functionally equivalent to signing the message, and eliminates the security benefits of signing the message directly. + + Some of these algorithms still permit the signature of a large message to be calculated, or verified, by providing the message data in fragments. This is possible when the algorithm only processes the message data once. See the individual algorithm descriptions for details. + + The following algorithms are in this category: + + | `PSA_ALG_PURE_EDDSA` + +* Specialized signature algorithms, that use part of a standard signature algorithm within a specific protocol. It is recommended that these algorithms are only used for that purpose, with inputs as specified by the higher-level protocol. See the individual algorithm descriptions for details on their usage. + + The following algorithms are in this category: + + | `PSA_ALG_RSA_PKCS1V15_SIGN_RAW` + | `PSA_ALG_ECDSA_ANY` + +.. rubric:: Signature functions + +The |API| provides several functions for calculating and verifying signatures: + +* The single-part signature and verification functions, `psa_sign_message()` and `psa_verify_message()`, take a message as one of their inputs, and perform the sign or verify algorithm. + + These functions can be used on any hash-and-sign, or message signature, algorithms. See also `PSA_ALG_IS_SIGN_MESSAGE()`. + +* The single-part functions, `psa_sign_hash()` and `psa_verify_hash()`, typically take a message hash as one of their inputs, and perform the sign or verify algorithm. + + These functions can be used on any hash-and-sign signature algorithm. It is recommended that the input to these functions is a hash, computed using the corresponding hash algorithm. To determine which hash algorithm to use, the macro `PSA_ALG_GET_HASH()` can be called on the signature algorithm identifier. + + These functions can also be used on the specialized signature algorithms, with a hash or encoded-hash as input. See also `PSA_ALG_IS_SIGN_HASH()`. + +See :secref:`single-part-signature`. + +.. _rsa-sign-algorithms: + +RSA signature algorithms +------------------------ .. macro:: PSA_ALG_RSA_PKCS1V15_SIGN :definition: /* specification-defined value */ @@ -36,7 +99,7 @@ Asymmetric signature algorithms Unspecified if ``hash_alg`` is not a supported hash algorithm. - This algorithm can be used with both the message and hash signature functions. + This hash-and-sign signature algorithm can be used with both the message and hash signature functions. This signature scheme is defined by :RFC-title:`8017#8.2` under the name RSASSA-PKCS1-v1_5. @@ -53,7 +116,7 @@ Asymmetric signature algorithms .. summary:: The raw RSA PKCS#1 v1.5 signature algorithm, without hashing. - This algorithm can be only used with the `psa_sign_hash()` and `psa_verify_hash()` functions. + This specialized signature algorithm can be only used with the `psa_sign_hash()` and `psa_verify_hash()` functions. This signature scheme is defined by :RFC-title:`8017#8.2` under the name RSASSA-PKCS1-v1_5. @@ -87,7 +150,7 @@ Asymmetric signature algorithms Unspecified if ``hash_alg`` is not a supported hash algorithm. - This algorithm can be used with both the message and hash signature functions. + This hash-and-sign signature algorithm can be used with both the message and hash signature functions. This algorithm is randomized: each invocation returns a different, equally valid signature. @@ -124,7 +187,7 @@ Asymmetric signature algorithms Unspecified if ``hash_alg`` is not a supported hash algorithm. - This algorithm can be used with both the message and hash signature functions. + This hash-and-sign signature algorithm can be used with both the message and hash signature functions. This algorithm is randomized: each invocation returns a different, equally valid signature. @@ -146,6 +209,77 @@ Asymmetric signature algorithms | `PSA_KEY_TYPE_RSA_KEY_PAIR` | `PSA_KEY_TYPE_RSA_PUBLIC_KEY` (signature verification only) +.. macro:: PSA_ALG_IS_RSA_PKCS1V15_SIGN + :definition: /* specification-defined value */ + + .. summary:: + Whether the specified algorithm is an RSA PKCS#1 v1.5 signature algorithm. + + .. param:: alg + An algorithm identifier: a value of type `psa_algorithm_t`. + + .. return:: + ``1`` if ``alg`` is an RSA PKCS#1 v1.5 signature algorithm, ``0`` otherwise. + + This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. + +.. macro:: PSA_ALG_IS_RSA_PSS + :definition: /* specification-defined value */ + + .. summary:: + Whether the specified algorithm is an RSA PSS signature algorithm. + + .. param:: alg + An algorithm identifier: a value of type `psa_algorithm_t`. + + .. return:: + ``1`` if ``alg`` is an RSA PSS signature algorithm, ``0`` otherwise. + + This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. + + This macro returns ``1`` for algorithms constructed using either `PSA_ALG_RSA_PSS()` or `PSA_ALG_RSA_PSS_ANY_SALT()`. + +.. macro:: PSA_ALG_IS_RSA_PSS_ANY_SALT + :definition: /* specification-defined value */ + + .. summary:: + Whether the specified algorithm is an RSA PSS signature algorithm that permits any salt length. + + .. param:: alg + An algorithm identifier: a value of type `psa_algorithm_t`. + + .. return:: + ``1`` if ``alg`` is an RSA PSS signature algorithm that permits any salt length, ``0`` otherwise. + + This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. + + An RSA PSS signature algorithm that permits any salt length is constructed using `PSA_ALG_RSA_PSS_ANY_SALT()`. + + See also `PSA_ALG_IS_RSA_PSS()` and `PSA_ALG_IS_RSA_PSS_STANDARD_SALT()`. + +.. macro:: PSA_ALG_IS_RSA_PSS_STANDARD_SALT + :definition: /* specification-defined value */ + + .. summary:: + Whether the specified algorithm is an RSA PSS signature algorithm that requires the standard salt length. + + .. param:: alg + An algorithm identifier: a value of type `psa_algorithm_t`. + + .. return:: + ``1`` if ``alg`` is an RSA PSS signature algorithm that requires the standard salt length, ``0`` otherwise. + + This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. + + An RSA PSS signature algorithm that requires the standard salt length is constructed using `PSA_ALG_RSA_PSS()`. + + See also `PSA_ALG_IS_RSA_PSS()` and `PSA_ALG_IS_RSA_PSS_ANY_SALT()`. + +.. _ecdsa-sign-algorithms: + +ECDSA signature algorithms +-------------------------- + .. macro:: PSA_ALG_ECDSA :definition: /* specification-defined value */ @@ -160,7 +294,7 @@ Asymmetric signature algorithms Unspecified if ``hash_alg`` is not a supported hash algorithm. - This algorithm can be used with both the message and hash signature functions. + This hash-and-sign signature algorithm can be used with both the message and hash signature functions. When used with `psa_sign_hash()` or `psa_verify_hash()`, the provided ``hash`` parameter is the message digest, computed using the ``hash_alg`` hash algorithm. @@ -194,13 +328,15 @@ Asymmetric signature algorithms .. summary:: The randomized ECDSA signature scheme, without hashing. - This algorithm can be only used with the `psa_sign_hash()` and `psa_verify_hash()` functions. + This specialized signature algorithm can be only used with the `psa_sign_hash()` and `psa_verify_hash()` functions. This algorithm is randomized: each invocation returns a different, equally valid signature. This is the same signature scheme as `PSA_ALG_ECDSA()`, but without specifying a hash algorithm, and skipping the message hashing operation. - This algorithm is only recommended to sign or verify a sequence of bytes that are an already-calculated hash. Note that the input is padded with zeros on the left or truncated on the right as required to fit the curve size. + .. warning:: + + This algorithm is only recommended to sign or verify a sequence of bytes that are a pre-computed hash. Note that the input is padded with zeros on the left or truncated on the right as required to fit the curve size. This algorithm cannot be used with the wildcard key policy :code:`PSA_ALG_ECDSA(PSA_ALG_ANY_HASH)`. It is only permitted when `PSA_ALG_ECDSA_ANY` is the key's permitted-algorithm policy. @@ -230,7 +366,7 @@ Asymmetric signature algorithms Unspecified if ``hash_alg`` is not a supported hash algorithm. - This algorithm can be used with both the message and hash signature functions. + This hash-and-sign signature algorithm can be used with both the message and hash signature functions. When used with `psa_sign_hash()` or `psa_verify_hash()`, the provided ``hash`` parameter is the message digest, computed using the ``hash_alg`` hash algorithm. @@ -256,13 +392,64 @@ Asymmetric signature algorithms * `PSA_ECC_FAMILY_FRP` * `PSA_ECC_FAMILY_BRAINPOOL_P_R1` +.. macro:: PSA_ALG_IS_ECDSA + :definition: /* specification-defined value */ + + .. summary:: + Whether the specified algorithm is ECDSA. + + .. param:: alg + An algorithm identifier: a value of type `psa_algorithm_t`. + + .. return:: + ``1`` if ``alg`` is an ECDSA algorithm, ``0`` otherwise. + + This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. + +.. macro:: PSA_ALG_IS_DETERMINISTIC_ECDSA + :definition: /* specification-defined value */ + + .. summary:: + Whether the specified algorithm is deterministic ECDSA. + + .. param:: alg + An algorithm identifier: a value of type `psa_algorithm_t`. + + .. return:: + ``1`` if ``alg`` is a deterministic ECDSA algorithm, ``0`` otherwise. + + This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. + + See also `PSA_ALG_IS_ECDSA()` and `PSA_ALG_IS_RANDOMIZED_ECDSA()`. + +.. macro:: PSA_ALG_IS_RANDOMIZED_ECDSA + :definition: /* specification-defined value */ + + .. summary:: + Whether the specified algorithm is randomized ECDSA. + + .. param:: alg + An algorithm identifier: a value of type `psa_algorithm_t`. + + .. return:: + ``1`` if ``alg`` is a randomized ECDSA algorithm, ``0`` otherwise. + + This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. + + See also `PSA_ALG_IS_ECDSA()` and `PSA_ALG_IS_DETERMINISTIC_ECDSA()`. + +.. _eddsa-sign-algorithms: + +EdDSA signature algorithms +-------------------------- + .. macro:: PSA_ALG_PURE_EDDSA :definition: ((psa_algorithm_t) 0x06000800) .. summary:: - Edwards-curve digital signature algorithm without prehashing (PureEdDSA), using standard parameters. + Edwards-curve digital signature algorithm without pre-hashing (PureEdDSA), using standard parameters. - This algorithm can be only used with the `psa_sign_message()` and `psa_verify_message()` functions. + This message signature algorithm can be only used with the `psa_sign_message()` and `psa_verify_message()` functions. This is the PureEdDSA digital signature algorithm defined by :RFC-title:`8032`, using standard parameters. @@ -273,13 +460,13 @@ Asymmetric signature algorithms * Edwards448: the Ed448 algorithm is computed with an empty string as the context. The output signature is a 114-byte string: the concatenation of :math:`R` and :math:`S` as defined by :RFC:`8032#5.2.6`. .. note:: - Contexts are not supported in the current version of this specification because there is no suitable signature interface that can take the context as a parameter. A future version of this specification may add suitable functions and extend this algorithm to support contexts. - - .. note:: - To sign or verify the pre-computed hash of a message using EdDSA, the HashEdDSA algorithms (`PSA_ALG_ED25519PH` and `PSA_ALG_ED448PH`) can be used with `psa_sign_hash()` and `psa_verify_hash()`. + To sign or verify the pre-computed hash of a message using EdDSA, the HashEdDSA algorithms (`PSA_ALG_ED25519PH` and `PSA_ALG_ED448PH`) can be used. The signature produced by HashEdDSA is distinct from that produced by PureEdDSA. + .. note:: + Contexts are not supported in the current version of this specification because there is no suitable signature interface that can take the context as a parameter. A future version of this specification may add suitable functions and extend this algorithm to support contexts. + .. subsection:: Compatible key types | :code:`PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_TWISTED_EDWARDS)` @@ -289,11 +476,11 @@ Asymmetric signature algorithms :definition: ((psa_algorithm_t) 0x0600090B) .. summary:: - Edwards-curve digital signature algorithm with prehashing (HashEdDSA), using the Edwards25519 curve. + Edwards-curve digital signature algorithm with pre-hashing (HashEdDSA), using the Edwards25519 curve. - This algorithm can be used with both the message and hash signature functions. + This hash-and-sign signature algorithm can be used with both the message and hash signature functions. - This computes the Ed25519ph algorithm as specified in :RFC-title:`8032#5.1`, and requires an Edwards25519 curve key. An empty string is used as the context. The prehash function is SHA-512. + This calculates the Ed25519ph algorithm as specified in :RFC-title:`8032#5.1`, and requires an Edwards25519 curve key. An empty string is used as the context. The pre-hash function is SHA-512, see `PSA_ALG_SHA_512`. When used with `psa_sign_hash()` or `psa_verify_hash()`, the provided ``hash`` parameter is the SHA-512 message digest. @@ -320,11 +507,11 @@ Asymmetric signature algorithms :definition: ((psa_algorithm_t) 0x06000915) .. summary:: - Edwards-curve digital signature algorithm with prehashing (HashEdDSA), using the Edwards448 curve. + Edwards-curve digital signature algorithm with pre-hashing (HashEdDSA), using the Edwards448 curve. - This algorithm can be used with both the message and hash signature functions. + This hash-and-sign signature algorithm can be used with both the message and hash signature functions. - This computes the Ed448ph algorithm as specified in :RFC-title:`8032#5.2`, and requires an Edwards448 curve key. An empty string is used as the context. The prehash function is the first 64 bytes of the output from SHAKE256. + This calculates the Ed448ph algorithm as specified in :RFC-title:`8032#5.2`, and requires an Edwards448 curve key. An empty string is used as the context. The pre-hash function is the first 64 bytes of the output from SHAKE256, see `PSA_ALG_SHAKE256_512`. When used with `psa_sign_hash()` or `psa_verify_hash()`, the provided ``hash`` parameter is the truncated SHAKE256 message digest. @@ -347,6 +534,22 @@ Asymmetric signature algorithms When used with `psa_sign_hash()` or `psa_verify_hash()`, the ``hash`` parameter to the call should be used as :math:`\text{PH}(M)` in the algorithms defined in :RFC:`8032#5.2`. +.. macro:: PSA_ALG_IS_HASH_EDDSA + :definition: /* specification-defined value */ + + .. summary:: + Whether the specified algorithm is HashEdDSA. + + .. param:: alg + An algorithm identifier: a value of type `psa_algorithm_t`. + + .. return:: + ``1`` if ``alg`` is a HashEdDSA algorithm, ``0`` otherwise. + + This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. + + +.. _single-part-signature: Asymmetric signature functions ------------------------------ @@ -390,13 +593,13 @@ Asymmetric signature functions .. retval:: PSA_ERROR_NOT_SUPPORTED The following conditions can result in this error: - * ``alg`` is not supported or is not an asymmetric signature algorithm. + * ``alg`` is not supported, or is not an asymmetric signature algorithm that permits signing a message. * ``key`` is not supported for use with ``alg``. * ``input_length`` is too large for the implementation. .. retval:: PSA_ERROR_INVALID_ARGUMENT The following conditions can result in this error: - * ``alg`` is not an asymmetric signature algorithm. + * ``alg`` is not an asymmetric signature algorithm that permits signing a message. * ``key`` is not an asymmetric key pair, that is compatible with ``alg``. * ``input_length`` is too large for the algorithm and key type. .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY @@ -443,13 +646,13 @@ Asymmetric signature functions .. retval:: PSA_ERROR_NOT_SUPPORTED The following conditions can result in this error: - * ``alg`` is not supported or is not an asymmetric signature algorithm. + * ``alg`` is not supported, or is not an asymmetric signature algorithm that permits verifying a message. * ``key`` is not supported for use with ``alg``. * ``input_length`` is too large for the implementation. .. retval:: PSA_ERROR_INVALID_ARGUMENT The following conditions can result in this error: - * ``alg`` is not an asymmetric signature algorithm. + * ``alg`` is not an asymmetric signature algorithm that permits verifying a message. * ``key`` is not a public key or an asymmetric key pair, that is compatible with ``alg``. * ``input_length`` is too large for the algorithm and key type. .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY @@ -467,7 +670,7 @@ Asymmetric signature functions .. function:: psa_sign_hash .. summary:: - Sign an already-calculated hash with a private key. + Sign a pre-computed hash with a private key. .. param:: psa_key_id_t key Identifier of the key to use for the operation. It must be an asymmetric key pair. The key must permit the usage `PSA_KEY_USAGE_SIGN_HASH`. @@ -505,12 +708,12 @@ Asymmetric signature functions .. retval:: PSA_ERROR_NOT_SUPPORTED The following conditions can result in this error: - * ``alg`` is not supported or is not an asymmetric signature algorithm. + * ``alg`` is not supported, or is not an asymmetric signature algorithm that permits signing a pre-computed hash. * ``key`` is not supported for use with ``alg``. .. retval:: PSA_ERROR_INVALID_ARGUMENT The following conditions can result in this error: - * ``alg`` is not an asymmetric signature algorithm. + * ``alg`` is not an asymmetric signature algorithm that permits signing a pre-computed hash. * ``key`` is not an asymmetric key pair, that is compatible with ``alg``. * ``hash_length`` is not valid for the algorithm and key type. * ``hash`` is not a valid input value for the algorithm and key type. @@ -524,20 +727,9 @@ Asymmetric signature functions .. retval:: PSA_ERROR_BAD_STATE The library requires initializing by a call to `psa_crypto_init()`. - With most signature algorithms that follow the hash-and-sign paradigm, the ``hash`` input to this function is the hash of the message to sign. The algorithm used to compute this hash is encoded in the signature algorithm. For such algorithms, ``hash_length`` must equal the length of the hash output, and the following condition is true: - - .. code-block:: xref - - hash_length == PSA_HASH_LENGTH(PSA_ALG_GET_HASH(alg)) - - The current version of this specification defines the following signature algorithms with this property: `PSA_ALG_RSA_PKCS1V15_SIGN`, `PSA_ALG_RSA_PSS`, `PSA_ALG_ECDSA`, `PSA_ALG_DETERMINISTIC_ECDSA`, `PSA_ALG_ED25519PH`, and `PSA_ALG_ED448PH`. + For hash-and-sign signature algorithms, the ``hash`` input to this function is the hash of the message to sign. The algorithm used to calculate this hash is encoded in the signature algorithm. For such algorithms, ``hash_length`` must equal the length of the hash output: :code:`hash_length == PSA_HASH_LENGTH(PSA_ALG_GET_HASH(alg))`. - Some hash-and-sign mechanisms apply a padding or encoding to the hash. In such cases, the encoded hash must be passed to this function. The current version of this specification defines one such signature algorithm: `PSA_ALG_RSA_PKCS1V15_SIGN_RAW`. - - .. note:: - To perform a hash-and-sign signature algorithm, the hash must be calculated before passing it to this function. This can be done by calling `psa_hash_compute()` or with a multi-part hash operation. The correct hash algorithm to use can be determined using `PSA_ALG_GET_HASH()`. - - Alternatively, to hash and sign a message in a single call, use `psa_sign_message()`. + Specialized signature algorithms can apply a padding or encoding to the hash. In such cases, the encoded hash must be passed to this function. For example, see `PSA_ALG_RSA_PKCS1V15_SIGN_RAW`. .. function:: psa_verify_hash @@ -572,12 +764,12 @@ Asymmetric signature functions .. retval:: PSA_ERROR_NOT_SUPPORTED The following conditions can result in this error: - * ``alg`` is not supported or is not an asymmetric signature algorithm. + * ``alg`` is not supported, or is not an asymmetric signature algorithm that permits verifying a pre-computed hash. * ``key`` is not supported for use with ``alg``. .. retval:: PSA_ERROR_INVALID_ARGUMENT The following conditions can result in this error: - * ``alg`` is not an asymmetric signature algorithm. + * ``alg`` is not an asymmetric signature algorithm that permits verifying a pre-computed hash. * ``key`` is not a public key or an asymmetric key pair, that is compatible with ``alg``. * ``hash_length`` is not valid for the algorithm and key type. * ``hash`` is not a valid input value for the algorithm and key type. @@ -590,20 +782,10 @@ Asymmetric signature functions .. retval:: PSA_ERROR_BAD_STATE The library requires initializing by a call to `psa_crypto_init()`. - With most signature algorithms that follow the hash-and-sign paradigm, the ``hash`` input to this function is the hash of the message to verify. The algorithm used to compute this hash is encoded in the signature algorithm. For such algorithms, ``hash_length`` must equal the length of the hash output, and the following condition is true: - - .. code-block:: xref + For hash-and-sign signature algorithms, the ``hash`` input to this function is the hash of the message to verify. The algorithm used to calculate this hash is encoded in the signature algorithm. For such algorithms, ``hash_length`` must equal the length of the hash output: :code:`hash_length == PSA_HASH_LENGTH(PSA_ALG_GET_HASH(alg))`. - hash_length == PSA_HASH_LENGTH(PSA_ALG_GET_HASH(alg)) + Specialized signature algorithms can apply a padding or encoding to the hash. In such cases, the encoded hash must be passed to this function. For example, see `PSA_ALG_RSA_PKCS1V15_SIGN_RAW`. - The current version of this specification defines the following signature algorithms with this property: `PSA_ALG_RSA_PKCS1V15_SIGN`, `PSA_ALG_RSA_PSS`, `PSA_ALG_ECDSA`, `PSA_ALG_DETERMINISTIC_ECDSA`, `PSA_ALG_ED25519PH`, and `PSA_ALG_ED448PH`. - - Some hash-and-sign mechanisms apply a padding or encoding to the hash. In such cases, the encoded hash must be passed to this function. The current version of this specification defines one such signature algorithm: `PSA_ALG_RSA_PKCS1V15_SIGN_RAW`. - - .. note:: - To perform a hash-and-sign verification algorithm, the hash must be calculated before passing it to this function. This can be done by calling `psa_hash_compute()` or with a multi-part hash operation. The correct hash algorithm to use can be determined using `PSA_ALG_GET_HASH()`. - - Alternatively, to hash and verify a message in a single call, use `psa_verify_message()`. Support macros -------------- @@ -618,7 +800,9 @@ Support macros An algorithm identifier: a value of type `psa_algorithm_t`. .. return:: - ``1`` if ``alg`` is a signature algorithm that can be used to sign a message. ``0`` if ``alg`` is a signature algorithm that can only be used to sign an already-calculated hash. ``0`` if ``alg`` is not a signature algorithm. This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. + ``1`` if ``alg`` is a signature algorithm that can be used to sign a message. ``0`` if ``alg`` is a signature algorithm that can only be used to sign a pre-computed hash. ``0`` if ``alg`` is not a signature algorithm. This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. + + This macro evaluates to ``1`` for hash-and-sign and message-signature algorithms. .. macro:: PSA_ALG_IS_SIGN_HASH :definition: /* specification-defined value */ @@ -632,134 +816,7 @@ Support macros .. return:: ``1`` if ``alg`` is a signature algorithm that can be used to sign a hash. ``0`` if ``alg`` is a signature algorithm that can only be used to sign a message. ``0`` if ``alg`` is not a signature algorithm. This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. - - This includes all algorithms such that `PSA_ALG_IS_HASH_AND_SIGN()` is true, as well as signature algorithms for which the input to `psa_sign_hash()` or `psa_verify_hash()` is not directly a hash, such as `PSA_ALG_IS_RSA_PKCS1V15_SIGN`. - -.. macro:: PSA_ALG_IS_RSA_PKCS1V15_SIGN - :definition: /* specification-defined value */ - - .. summary:: - Whether the specified algorithm is an RSA PKCS#1 v1.5 signature algorithm. - - .. param:: alg - An algorithm identifier: a value of type `psa_algorithm_t`. - - .. return:: - ``1`` if ``alg`` is an RSA PKCS#1 v1.5 signature algorithm, ``0`` otherwise. - - This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. - -.. macro:: PSA_ALG_IS_RSA_PSS - :definition: /* specification-defined value */ - - .. summary:: - Whether the specified algorithm is an RSA PSS signature algorithm. - - .. param:: alg - An algorithm identifier: a value of type `psa_algorithm_t`. - - .. return:: - ``1`` if ``alg`` is an RSA PSS signature algorithm, ``0`` otherwise. - - This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. - - This macro returns ``1`` for algorithms constructed using either `PSA_ALG_RSA_PSS()` or `PSA_ALG_RSA_PSS_ANY_SALT()`. - -.. macro:: PSA_ALG_IS_RSA_PSS_ANY_SALT - :definition: /* specification-defined value */ - - .. summary:: - Whether the specified algorithm is an RSA PSS signature algorithm that permits any salt length. - - .. param:: alg - An algorithm identifier: a value of type `psa_algorithm_t`. - - .. return:: - ``1`` if ``alg`` is an RSA PSS signature algorithm that permits any salt length, ``0`` otherwise. - - This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. - - An RSA PSS signature algorithm that permits any salt length is constructed using `PSA_ALG_RSA_PSS_ANY_SALT()`. - - See also `PSA_ALG_IS_RSA_PSS()` and `PSA_ALG_IS_RSA_PSS_STANDARD_SALT()`. - -.. macro:: PSA_ALG_IS_RSA_PSS_STANDARD_SALT - :definition: /* specification-defined value */ - - .. summary:: - Whether the specified algorithm is an RSA PSS signature algorithm that requires the standard salt length. - - .. param:: alg - An algorithm identifier: a value of type `psa_algorithm_t`. - - .. return:: - ``1`` if ``alg`` is an RSA PSS signature algorithm that requires the standard salt length, ``0`` otherwise. - - This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. - - An RSA PSS signature algorithm that requires the standard salt length is constructed using `PSA_ALG_RSA_PSS()`. - - See also `PSA_ALG_IS_RSA_PSS()` and `PSA_ALG_IS_RSA_PSS_ANY_SALT()`. - -.. macro:: PSA_ALG_IS_ECDSA - :definition: /* specification-defined value */ - - .. summary:: - Whether the specified algorithm is ECDSA. - - .. param:: alg - An algorithm identifier: a value of type `psa_algorithm_t`. - - .. return:: - ``1`` if ``alg`` is an ECDSA algorithm, ``0`` otherwise. - - This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. - -.. macro:: PSA_ALG_IS_DETERMINISTIC_ECDSA - :definition: /* specification-defined value */ - - .. summary:: - Whether the specified algorithm is deterministic ECDSA. - - .. param:: alg - An algorithm identifier: a value of type `psa_algorithm_t`. - - .. return:: - ``1`` if ``alg`` is a deterministic ECDSA algorithm, ``0`` otherwise. - - This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. - - See also `PSA_ALG_IS_ECDSA()` and `PSA_ALG_IS_RANDOMIZED_ECDSA()`. - -.. macro:: PSA_ALG_IS_RANDOMIZED_ECDSA - :definition: /* specification-defined value */ - - .. summary:: - Whether the specified algorithm is randomized ECDSA. - - .. param:: alg - An algorithm identifier: a value of type `psa_algorithm_t`. - - .. return:: - ``1`` if ``alg`` is a randomized ECDSA algorithm, ``0`` otherwise. - - This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. - - See also `PSA_ALG_IS_ECDSA()` and `PSA_ALG_IS_DETERMINISTIC_ECDSA()`. - -.. macro:: PSA_ALG_IS_HASH_EDDSA - :definition: /* specification-defined value */ - - .. summary:: - Whether the specified algorithm is HashEdDSA. - - .. param:: alg - An algorithm identifier: a value of type `psa_algorithm_t`. - - .. return:: - ``1`` if ``alg`` is a HashEdDSA algorithm, ``0`` otherwise. - - This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. + This macro evaluates to ``1`` for hash-and-sign and specialized signature algorithms. .. macro:: PSA_ALG_IS_HASH_AND_SIGN :definition: /* specification-defined value */ @@ -773,22 +830,18 @@ Support macros .. return:: ``1`` if ``alg`` is a hash-and-sign algorithm that signs exactly the hash value, ``0`` otherwise. This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. - A wildcard signature algorithm policy, using `PSA_ALG_ANY_HASH`, returns the same value as the signature algorithm parameterised with a valid hash algorithm. + A wildcard signature algorithm policy, using `PSA_ALG_ANY_HASH`, returns the same value as the signature algorithm parameterized with a valid hash algorithm. This macro identifies algorithms that can be used with `psa_sign_hash()` that use the exact message hash value as an input the signature operation. For example, if :code:`PSA_ALG_IS_HASH_AND_SIGN(alg)` is true, the following call sequence is equivalent to :code:`psa_sign_message(key, alg, msg, msg_len, ...)`: .. code-block:: xref - psa_hash_operation_t op = {0}; uint8_t hash[PSA_HASH_MAX_SIZE]; size_t hash_len; - psa_hash_setup(&op, PSA_ALG_GET_HASH(alg)); - psa_hash_update(&op, msg, msg_len); - psa_hash_finish(&op, hash, sizeof(hash), &hash_len); + psa_hash_compute(PSA_ALG_GET_HASH(alg), msg, msg_len, + hash, sizeof(hash), &hash_len); psa_sign_hash(key, alg, hash, hash_len, ...); - This excludes hash-and-sign algorithms that require a encoded or modified hash for the signature step in the algorithm, such as `PSA_ALG_RSA_PKCS1V15_SIGN_RAW`. For such algorithms, `PSA_ALG_IS_SIGN_HASH()` is true but `PSA_ALG_IS_HASH_AND_SIGN()` is false. - .. macro:: PSA_ALG_ANY_HASH :definition: ((psa_algorithm_t)0x020000ff) diff --git a/doc/crypto/appendix/history.rst b/doc/crypto/appendix/history.rst index a0e7d299..8d5597c6 100644 --- a/doc/crypto/appendix/history.rst +++ b/doc/crypto/appendix/history.rst @@ -44,6 +44,8 @@ Clarifications and fixes * Documented the use of context parameters in J-PAKE and SPAKE2+ PAKE operations. See :secref:`jpake-operation` and :secref:`spake2p-operation`. +* Clarified asymmetric signature support by categorizing the different types of signature algorithm. + Other changes ~~~~~~~~~~~~~ diff --git a/doc/crypto/overview/functionality.rst b/doc/crypto/overview/functionality.rst index 9de78add..c3a6a9b1 100644 --- a/doc/crypto/overview/functionality.rst +++ b/doc/crypto/overview/functionality.rst @@ -6,36 +6,25 @@ Functionality overview ====================== -This section provides a high-level overview of the functionality provided by the -interface defined in this specification. Refer to the -API definition for a detailed description, which begins with :secref:`library-management`. +This section provides a high-level overview of the functionality provided by the interface defined in this specification. Refer to the API definition for a detailed description, which begins with :secref:`library-management`. -:secref:`future` describes features that might be included in future versions of this -specification. +:secref:`future` describes features that might be included in future versions of this specification. -Due to the modularity of the interface, almost every part of the library is -optional. The only mandatory function is `psa_crypto_init()`. +Due to the modularity of the interface, almost every part of the library is optional. The only mandatory function is `psa_crypto_init()`. Library management ------------------ -Applications must call `psa_crypto_init()` to initialize the library before -using any other function. +Applications must call `psa_crypto_init()` to initialize the library before using any other function. .. _key-overview: Key management -------------- -Applications always access keys indirectly via an identifier, and can perform -operations using a key without accessing the key material. This allows keys to -be *non-extractable*, where an application can use a key but is not permitted to -obtain the key material. Non-extractable keys are bound to the device, can be -rate-limited and can have their usage restricted by policies. +Applications always access keys indirectly via an identifier, and can perform operations using a key without accessing the key material. This allows keys to be *non-extractable*, where an application can use a key but is not permitted to obtain the key material. Non-extractable keys are bound to the device, can be rate-limited and can have their usage restricted by policies. -Each key has a set of attributes that describe the key and the policy for using -the key. A `psa_key_attributes_t` object contains all of the attributes, which -is used when creating a key and when querying key attributes. +Each key has a set of attributes that describe the key and the policy for using the key. A `psa_key_attributes_t` object contains all of the attributes, which is used when creating a key and when querying key attributes. The key attributes include: @@ -57,15 +46,9 @@ Keys are created using one of the *key creation functions*: These output the key identifier, that is used to access the key in all other parts of the API. -All of the key attributes are set when the key is created and cannot be changed -without destroying the key first. If the original key permits copying, then the -application can specify a different lifetime or restricted policy for the -copy of the key. +All of the key attributes are set when the key is created and cannot be changed without destroying the key first. If the original key permits copying, then the application can specify a different lifetime or restricted policy for the copy of the key. -A call to `psa_destroy_key()` destroys the key material, and will cause any active -operations that are using the key to fail. Therefore an application must not -destroy a key while an operation using that key is in progress, unless the -application is prepared to handle a failure of the operation. +A call to `psa_destroy_key()` destroys the key material, and will cause any active operations that are using the key to fail. Therefore an application must not destroy a key while an operation using that key is in progress, unless the application is prepared to handle a failure of the operation. .. _key-types-intro: @@ -87,9 +70,7 @@ Key identifiers are integral values that act as permanent names for persistent k Key identifiers are output from a successful call to one of the key creation functions. -Valid key identifiers must have distinct values within the same application. If -the implementation provides :term:`caller isolation`, then key -identifiers are local to each application. +Valid key identifiers must have distinct values within the same application. If the implementation provides :term:`caller isolation`, then key identifiers are local to each application. See :secref:`key-identifiers`. @@ -120,52 +101,43 @@ Recommendations of minimum standards for key management Most implementations provide the following functions: -* `psa_import_key()`. The exceptions are implementations that only give access - to a key or keys that are provisioned by proprietary means, and do not allow - the main application to use its own cryptographic material. +* `psa_import_key()`. The exceptions are implementations that only give access to a key or keys that are provisioned by proprietary means, and do not allow the main application to use its own cryptographic material. -* `psa_get_key_attributes()` and the ``psa_get_key_xxx()`` accessor functions. - They are easy to implement, and it is difficult to write applications and to - diagnose issues without being able to check the metadata. +* `psa_get_key_attributes()` and the ``psa_get_key_xxx()`` accessor functions. They are easy to implement, and it is difficult to write applications and to diagnose issues without being able to check the metadata. -* `psa_export_public_key()`. This function is usually provided if the - implementation supports any asymmetric algorithm, since public-key - cryptography often requires the delivery of a public key that is associated - with a protected private key. +* `psa_export_public_key()`. This function is usually provided if the implementation supports any asymmetric algorithm, since public-key cryptography often requires the delivery of a public key that is associated with a protected private key. -* `psa_export_key()`. However, highly constrained implementations that are - designed to work only with short-term keys, or only with long-term - non-extractable keys, do not need to provide this function. +* `psa_export_key()`. However, highly constrained implementations that are designed to work only with short-term keys, or only with long-term non-extractable keys, do not need to provide this function. Cryptographic operations ------------------------ -For each type of cryptographic operation, the API can include: +The API supports cryptographic operations through two kinds of interfaces: -* One or more *single-part* functions, which perform a whole operation in a single function call. For example, compute, verify, encrypt or decrypt. -* A *multi-part operation* --- which is a series of functions that work with a stored operation state. +* A *single-part* function performs a whole operation in a single function call. For example, compute, verify, encrypt or decrypt. See :secref:`single-part-functions`. + +* A *multi-part operation* is a set of functions that work with a stored operation state. This provides more control over operation configuration, piecewise processing of large input data, or handling for multi-step processes. See :secref:`multi-part-operations`. + +Depending on the mechanism, one or both kind of interfaces may be provided. + +.. _single-part-functions: Single-part Functions ~~~~~~~~~~~~~~~~~~~~~ -Single-part functions are APIs that implement the cryptographic operation in a -single function call. This is the easiest API to use when all of the inputs and -outputs fit into the application memory. +Single-part functions are APIs that implement the cryptographic operation in a single function call. This is the easiest API to use when all of the inputs and outputs fit into the application memory. + +Single-part functions do not meet the needs of all use cases: + +* Some use cases involve messages that are too large to be assembled in memory, or require non-default configuration of the algorithm. These use cases require the use of a `multi-part operation `. -Some use cases involve messages that are too large to be assembled in memory, or -require non-default configuration of the algorithm. These use cases require the -use of a `multi-part operation `. .. _multi-part-operations: Multi-part operations ~~~~~~~~~~~~~~~~~~~~~ -Multi-part operations are APIs which split a single cryptographic operation into -a sequence of separate steps. This enables fine control over the configuration -of the cryptographic operation, and allows the message data to be processed in -fragments instead of all at once. For example, the following situations require -the use of a multi-part operation: +Multi-part operations are APIs which split a single cryptographic operation into a sequence of separate steps. This enables fine control over the configuration of the cryptographic operation, and allows the message data to be processed in fragments instead of all at once. For example, the following situations require the use of a multi-part operation: * Processing messages that cannot be assembled in memory. * Using a deterministic IV for unauthenticated encryption. @@ -173,8 +145,7 @@ the use of a multi-part operation: * Separating the AEAD authentication tag from the cipher text. * Password-authenticated key exchange (PAKE) is a multi-step process. -Each multi-part operation defines a specific object type to maintain the state -of the operation. These types are implementation-defined. +Each multi-part operation defines a specific object type to maintain the state of the operation. These types are implementation-defined. All multi-part operations follow the same pattern of use, which is shown in :numref:`fig-multi-part`. @@ -185,59 +156,36 @@ All multi-part operations follow the same pattern of use, which is shown in :num The typical sequence of actions with a multi-part operation is as follows: -1. **Allocate:** Allocate memory for an operation object of the appropriate - type. The application can use any allocation strategy: stack, heap, static, etc. +1. **Allocate:** Allocate memory for an operation object of the appropriate type. The application can use any allocation strategy: stack, heap, static, etc. -#. **Initialize:** Initialize or assign the operation object by one of the - following methods: +#. **Initialize:** Initialize or assign the operation object by one of the following methods: - - Set it to logical zero. This is automatic for static and global - variables. Explicit initialization must use the associated - ``PSA_xxx_INIT`` macro as the type is implementation-defined. - - Set it to all-bits zero. This is automatic if the object was - allocated with ``calloc()``. - - Assign the value of the associated macro ``PSA_xxx_INIT``. - - Assign the result of calling the associated function - ``psa_xxx_init()``. + - Set it to logical zero. This is automatic for static and global variables. Explicit initialization must use the associated ``PSA_xxx_OPERATION_INIT`` macro as the type is implementation-defined. + - Set it to all-bits zero. This is automatic if the object was allocated with ``calloc()``. + - Assign the value of the associated macro ``PSA_xxx_OPERATION_INIT``. + - Assign the result of calling the associated function ``psa_xxx_operation_init()``. The resulting object is now *inactive*. - It is an error to initialize an operation object that is in *active* or - *error* states. This can leak memory or other resources. + It is an error to initialize an operation object that is in *active* or *error* states. This can leak memory or other resources. -#. **Setup:** Start a new multi-part operation on an *inactive* operation - object. Each operation object will define one or more setup functions to - start a specific operation. +#. **Setup:** Start a new multi-part operation on an *inactive* operation object. Each operation object will define one or more setup functions to start a specific operation. - On success, a setup function will put an operation object into an *active* - state. On failure, the operation object will remain *inactive*. + On success, a setup function will put an operation object into an *active* state. On failure, the operation object will remain *inactive*. -#. **Update:** Update an *active* operation object. Each operation object - defines one or more update functions, which are used to provide additional - parameters, supply data for processing or generate outputs. +#. **Update:** Update an *active* operation object. Each operation object defines one or more update functions, which are used to provide additional parameters, supply data for processing or generate outputs. - On success, the operation object remains *active*. On failure, the - operation object will enter an *error* state. + On success, the operation object remains *active*. On failure, the operation object will enter an *error* state. -#. **Finish:** To end the operation, call the applicable finishing function. - This will take any final inputs, produce any final outputs, and then - release any resources associated with the operation. +#. **Finish:** To end the operation, call the applicable finishing function. This will take any final inputs, produce any final outputs, and then release any resources associated with the operation. - On success, the operation object returns to the *inactive* state. On - failure, the operation object will enter an *error* state. + On success, the operation object returns to the *inactive* state. On failure, the operation object will enter an *error* state. -#. **Abort:** An operation can be aborted at any stage during its use by - calling the associated ``psa_xxx_abort()`` function. This will release any - resources associated with the operation and return the operation object to - the *inactive* state. +#. **Abort:** An operation can be aborted at any stage during its use by calling the associated ``psa_xxx_abort()`` function. This will release any resources associated with the operation and return the operation object to the *inactive* state. - Any error that occurs to an operation while it is in an *active* state - will result in the operation entering an *error* state. The application - must call the associated ``psa_xxx_abort()`` function to release the - operation resources and return the object to the *inactive* state. + Any error that occurs to an operation while it is in an *active* state will result in the operation entering an *error* state. The application must call the associated ``psa_xxx_abort()`` function to release the operation resources and return the object to the *inactive* state. - ``psa_xxx_abort()`` can be called on an *inactive* operation, and this - has no effect. + ``psa_xxx_abort()`` can be called on an *inactive* operation, and this has no effect. .. rationale:: @@ -258,32 +206,18 @@ The typical sequence of actions with a multi-part operation is as follows: Once an operation object is returned to the *inactive* state, it can be reused by calling one of the applicable setup functions again. -If a multi-part operation object is not initialized before use, the behavior is -undefined. +If a multi-part operation object is not initialized before use, the behavior is undefined. -If a multi-part operation function determines that the operation object is not in -any valid state, it can return :code:`PSA_ERROR_CORRUPTION_DETECTED`. +If a multi-part operation function determines that the operation object is not in any valid state, it can return :code:`PSA_ERROR_CORRUPTION_DETECTED`. -If a multi-part operation function is called with an operation object in the -wrong state, the function will return :code:`PSA_ERROR_BAD_STATE` and the operation -object will enter the *error* state. +If a multi-part operation function is called with an operation object in the wrong state, the function will return :code:`PSA_ERROR_BAD_STATE` and the operation object will enter the *error* state. -It is safe to move a multi-part operation object to a different memory location, -for example, using a bitwise copy, and then to use the object in the new -location. For example, an application can allocate an operation object on the -stack and return it, or the operation object can be allocated within memory -managed by a garbage collector. However, this does not permit the following -behaviors: +It is safe to move a multi-part operation object to a different memory location, for example, using a bitwise copy, and then to use the object in the new location. For example, an application can allocate an operation object on the stack and return it, or the operation object can be allocated within memory managed by a garbage collector. However, this does not permit the following behaviors: -* Moving the object while a function is being called on the object. This is - not safe. See also :secref:`concurrency`. -* Working with both the original and the copied operation objects. This - requires cloning the operation, which is only available for hash operations - using `psa_hash_clone()`. +* Moving the object while a function is being called on the object. This is not safe. See also :secref:`concurrency`. +* Working with both the original and the copied operation objects. This requires cloning the operation, which is only available for hash operations using `psa_hash_clone()`. -Each type of multi-part operation can have multiple *active* states. -Documentation for the specific operation describes the configuration and update -functions, and any requirements about their usage and ordering. +Each type of multi-part operation can have multiple *active* states. Documentation for the specific operation describes the configuration and update functions, and any requirements about their usage and ordering. Symmetric cryptography ~~~~~~~~~~~~~~~~~~~~~~ @@ -304,31 +238,22 @@ Key derivation only provides multi-part operation, to support the flexibility re Example of the symmetric cryptography API ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Here is an example of a use case where a master key is used to generate both a -message encryption key and an IV for the encryption, and the derived key and IV -are then used to encrypt a message. +Here is an example of a use case where a master key is used to generate both a message encryption key and an IV for the encryption, and the derived key and IV are then used to encrypt a message. 1. Derive the message encryption material from the master key. - a. Initialize a `psa_key_derivation_operation_t` object to zero or to - `PSA_KEY_DERIVATION_OPERATION_INIT`. + a. Initialize a `psa_key_derivation_operation_t` object to zero or to `PSA_KEY_DERIVATION_OPERATION_INIT`. #. Call `psa_key_derivation_setup()` with `PSA_ALG_HKDF` as the algorithm. - #. Call `psa_key_derivation_input_key()` with the step - `PSA_KEY_DERIVATION_INPUT_SECRET` and the master key. - #. Call `psa_key_derivation_input_bytes()` with the step - `PSA_KEY_DERIVATION_INPUT_INFO` and a public value that uniquely - identifies the message. - #. Populate a `psa_key_attributes_t` object with the derived message - encryption key’s attributes. + #. Call `psa_key_derivation_input_key()` with the step `PSA_KEY_DERIVATION_INPUT_SECRET` and the master key. + #. Call `psa_key_derivation_input_bytes()` with the step `PSA_KEY_DERIVATION_INPUT_INFO` and a public value that uniquely identifies the message. + #. Populate a `psa_key_attributes_t` object with the derived message encryption key’s attributes. #. Call `psa_key_derivation_output_key()` to create the derived message key. #. Call `psa_key_derivation_output_bytes()` to generate the derived IV. - #. Call `psa_key_derivation_abort()` to release the key derivation operation - memory. + #. Call `psa_key_derivation_abort()` to release the key derivation operation memory. #. Encrypt the message with the derived material. - a. Initialize a `psa_cipher_operation_t` object to zero or to - `PSA_CIPHER_OPERATION_INIT`. + a. Initialize a `psa_cipher_operation_t` object to zero or to `PSA_CIPHER_OPERATION_INIT`. #. Call `psa_cipher_encrypt_setup()` with the derived message encryption key. #. Call `psa_cipher_set_iv()` using the derived IV retrieved above. #. Call `psa_cipher_update()` one or more times to encrypt the message. @@ -346,21 +271,18 @@ This specification defines interfaces for the following types of asymmetric cryp * Two-way key agreement (also known as key establishment). See :secref:`key-agreement`. * Password-authenticated key exchange (PAKE). See :secref:`pake`. -For asymmetric encryption and signature, the API provides *single-part* functions. For key agreement, the API provides single-part functions and an additional input method for a key derivation operation. For PAKE, the API provides a multi-part operation. +For asymmetric encryption, the API provides *single-part* functions. + +For asymmetric signature, the API provides single-part functions. + +For key agreement, the API provides single-part functions and an additional input method for a key derivation operation. + +For PAKE, the API provides a *multi-part* operation. + Randomness and key generation ----------------------------- -We strongly recommended that implementations include a random generator, -consisting of a cryptographically secure pseudo-random generator (CSPRNG), which -is adequately seeded with a cryptographic-quality hardware entropy source, -commonly referred to as a true random number generator (TRNG). Constrained -implementations can omit the random generation functionality if they do not -implement any algorithm that requires randomness internally, and they do not -provide a key generation functionality. For example, a special-purpose component -for signature verification can omit this. - -It is recommended that applications use `psa_generate_key()`, -`psa_cipher_generate_iv()` or `psa_aead_generate_nonce()` to generate -suitably-formatted random data, as applicable. In addition, the API includes a -function `psa_generate_random()` to generate and extract arbitrary random data. +We strongly recommended that implementations include a random generator, consisting of a cryptographically secure pseudo-random generator (CSPRNG), which is adequately seeded with a cryptographic-quality hardware entropy source, commonly referred to as a true random number generator (TRNG). Constrained implementations can omit the random generation functionality if they do not implement any algorithm that requires randomness internally, and they do not provide a key generation functionality. For example, a special-purpose component for signature verification can omit this. + +It is recommended that applications use `psa_generate_key()`, `psa_cipher_generate_iv()` or `psa_aead_generate_nonce()` to generate suitably-formatted random data, as applicable. In addition, the API includes a function `psa_generate_random()` to generate and extract arbitrary random data.