diff --git a/doc/crypto/api.db/psa/crypto.h b/doc/crypto/api.db/psa/crypto.h index 8cc8cf5c..60c41233 100644 --- a/doc/crypto/api.db/psa/crypto.h +++ b/doc/crypto/api.db/psa/crypto.h @@ -72,6 +72,9 @@ typedef struct psa_custom_key_parameters_t { #define PSA_ALG_CMAC ((psa_algorithm_t)0x03c00200) #define PSA_ALG_CTR ((psa_algorithm_t)0x04c01000) #define PSA_ALG_DETERMINISTIC_ECDSA(hash_alg) /* specification-defined value */ +#define PSA_ALG_DETERMINISTIC_HASH_ML_DSA(hash_alg) \ + /* specification-defined value */ +#define PSA_ALG_DETERMINISTIC_ML_DSA ((psa_algorithm_t) 0x06004500) #define PSA_ALG_ECB_NO_PADDING ((psa_algorithm_t)0x04404400) #define PSA_ALG_ECDH ((psa_algorithm_t)0x09020000) #define PSA_ALG_ECDSA(hash_alg) /* specification-defined value */ @@ -82,6 +85,7 @@ typedef struct psa_custom_key_parameters_t { #define PSA_ALG_FULL_LENGTH_MAC(mac_alg) /* specification-defined value */ #define PSA_ALG_GCM ((psa_algorithm_t)0x05500200) #define PSA_ALG_GET_HASH(alg) /* specification-defined value */ +#define PSA_ALG_HASH_ML_DSA(hash_alg) /* specification-defined value */ #define PSA_ALG_HKDF(hash_alg) /* specification-defined value */ #define PSA_ALG_HKDF_EXPAND(hash_alg) /* specification-defined value */ #define PSA_ALG_HKDF_EXTRACT(hash_alg) /* specification-defined value */ @@ -92,12 +96,16 @@ typedef struct psa_custom_key_parameters_t { #define PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) /* specification-defined value */ #define PSA_ALG_IS_CIPHER(alg) /* specification-defined value */ #define PSA_ALG_IS_DETERMINISTIC_ECDSA(alg) /* specification-defined value */ +#define PSA_ALG_IS_DETERMINISTIC_HASH_ML_DSA(alg) \ + /* specification-defined value */ #define PSA_ALG_IS_ECDH(alg) /* specification-defined value */ #define PSA_ALG_IS_ECDSA(alg) /* specification-defined value */ #define PSA_ALG_IS_FFDH(alg) /* specification-defined value */ #define PSA_ALG_IS_HASH(alg) /* specification-defined value */ #define PSA_ALG_IS_HASH_AND_SIGN(alg) /* specification-defined value */ #define PSA_ALG_IS_HASH_EDDSA(alg) /* specification-defined value */ +#define PSA_ALG_IS_HASH_ML_DSA(alg) /* specification-defined value */ +#define PSA_ALG_IS_HEDGED_HASH_ML_DSA(alg) /* specification-defined value */ #define PSA_ALG_IS_HKDF(alg) /* specification-defined value */ #define PSA_ALG_IS_HKDF_EXPAND(alg) /* specification-defined value */ #define PSA_ALG_IS_HKDF_EXTRACT(alg) /* specification-defined value */ @@ -108,6 +116,7 @@ typedef struct psa_custom_key_parameters_t { #define PSA_ALG_IS_KEY_DERIVATION_STRETCHING(alg) \ /* specification-defined value */ #define PSA_ALG_IS_MAC(alg) /* specification-defined value */ +#define PSA_ALG_IS_ML_DSA(alg) /* specification-defined value */ #define PSA_ALG_IS_PAKE(alg) /* specification-defined value */ #define PSA_ALG_IS_PBKDF2_HMAC(alg) /* specification-defined value */ #define PSA_ALG_IS_RANDOMIZED_ECDSA(alg) /* specification-defined value */ @@ -140,6 +149,7 @@ typedef struct psa_custom_key_parameters_t { #define PSA_ALG_MD2 ((psa_algorithm_t)0x02000001) #define PSA_ALG_MD4 ((psa_algorithm_t)0x02000002) #define PSA_ALG_MD5 ((psa_algorithm_t)0x02000003) +#define PSA_ALG_ML_DSA ((psa_algorithm_t) 0x06004400) #define PSA_ALG_NONE ((psa_algorithm_t)0) #define PSA_ALG_OFB ((psa_algorithm_t)0x04c01200) #define PSA_ALG_PBKDF2_AES_CMAC_PRF_128 ((psa_algorithm_t)0x08800200) @@ -156,6 +166,7 @@ typedef struct psa_custom_key_parameters_t { #define PSA_ALG_SHA3_256 ((psa_algorithm_t)0x02000011) #define PSA_ALG_SHA3_384 ((psa_algorithm_t)0x02000012) #define PSA_ALG_SHA3_512 ((psa_algorithm_t)0x02000013) +#define PSA_ALG_SHAKE128_256 ((psa_algorithm_t)0x02000016) #define PSA_ALG_SHAKE256_512 ((psa_algorithm_t)0x02000015) #define PSA_ALG_SHA_1 ((psa_algorithm_t)0x02000005) #define PSA_ALG_SHA_224 ((psa_algorithm_t)0x02000008) @@ -297,6 +308,7 @@ typedef struct psa_custom_key_parameters_t { #define PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type) /* specification-defined value */ #define PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type) /* specification-defined value */ #define PSA_KEY_TYPE_IS_KEY_PAIR(type) /* specification-defined value */ +#define PSA_KEY_TYPE_IS_ML_DSA(type) /* specification-defined value */ #define PSA_KEY_TYPE_IS_PUBLIC_KEY(type) /* specification-defined value */ #define PSA_KEY_TYPE_IS_RSA(type) /* specification-defined value */ #define PSA_KEY_TYPE_IS_SPAKE2P(type) /* specification-defined value */ @@ -307,6 +319,8 @@ typedef struct psa_custom_key_parameters_t { #define PSA_KEY_TYPE_IS_UNSTRUCTURED(type) /* specification-defined value */ #define PSA_KEY_TYPE_KEY_PAIR_OF_PUBLIC_KEY(type) \ /* specification-defined value */ +#define PSA_KEY_TYPE_ML_DSA_KEY_PAIR ((psa_key_type_t)0x7002) +#define PSA_KEY_TYPE_ML_DSA_PUBLIC_KEY ((psa_key_type_t)0x4002) #define PSA_KEY_TYPE_NONE ((psa_key_type_t)0x0000) #define PSA_KEY_TYPE_PASSWORD ((psa_key_type_t)0x1203) #define PSA_KEY_TYPE_PASSWORD_HASH ((psa_key_type_t)0x1205) diff --git a/doc/crypto/api/keys/types.rst b/doc/crypto/api/keys/types.rst index ea18391c..396f614d 100644 --- a/doc/crypto/api/keys/types.rst +++ b/doc/crypto/api/keys/types.rst @@ -1165,6 +1165,136 @@ The curve type affects the key format, the key derivation procedure, and the alg .. return:: psa_ecc_family_t The elliptic curve family id, if ``type`` is a supported elliptic curve key. Unspecified if ``type`` is not a supported elliptic curve key. +.. _ml-dsa-keys: + +Module Lattice-based Signature keys +----------------------------------- + +The |API| supports Module Lattice-based digital signatures (ML-DSA), as defined in :cite-title:`FIPS204`. + +.. macro:: PSA_KEY_TYPE_ML_DSA_KEY_PAIR + :definition: ((psa_key_type_t)0x7002) + + .. summary:: + ML-DSA key pair: both the private and public key. + + The key attribute size of an ML-DSA key is the numeric ML-DSA parameter-set identifier defined in `[FIPS204]`. + The values are based on the dimensions of the matrix :math:`A`, and do not directly define the key size in bytes: + + * ML-DSA-44 : ``key_bits = 44`` + * ML-DSA-65 : ``key_bits = 65`` + * ML-DSA-87 : ``key_bits = 87`` + + See also §4 in `[FIPS204]`. + + .. subsection:: Compatible algorithms + + .. hlist:: + + * `PSA_ALG_ML_DSA` + * `PSA_ALG_HASH_ML_DSA` + * `PSA_ALG_DETERMINISTIC_ML_DSA` + * `PSA_ALG_DETERMINISTIC_HASH_ML_DSA` + + .. subsection:: Key format + + .. warning:: + + The key format may change in a final version of this API. + The standardization of exchange formats for ML-DSA public and private keys is in progress, but final documents have not been published. + See :cite-title:`LAMPS-MLDSA`. + + The current proposed format is based on the current expected outcome of that process. + + An ML-DSA key pair is the :math:`(pk,sk)` pair of public key and secret key, which are generated from a secret 32-byte seed, :math:`\xi`. See `[FIPS204]` §5.1. + + The data format for import and export of the key pair is the 32-byte seed :math:`\xi`. + + .. rationale:: + + The IETF working group responsible for defining the format of the ML-DSA keys in *SubjectPublicKeyInfo* and *OneAsymmetricKey* structures is discussing the formats at present (September 2024), with the current consensus to using just the seed value as the private key, for the following reasons: + + * ML-DSA key-pairs are several kB in size, but can be recomputed efficiently from the initial 32-byte seed. + * There is no need to validate an imported ML-DSA private key --- every 32-byte seed values is valid. + * The public key cannot be derived from the secret key, so a key pair must store both the secret key and the public key. + The size of the key pair depends on the ML-DSA parameter set as follows: + + .. csv-table:: + :align: left + :header-rows: 1 + + Parameter set, Key-pair size in bytes + ML-DSA-44, 3872 + ML-DSA-65, 5984 + ML-DSA-87, 7488 + + * It is better for the standard to choose a single format to improve interoperability. + + See `PSA_KEY_TYPE_ML_DSA_PUBLIC_KEY` for the data format used when exporting the public key with `psa_export_public_key()`. + + .. admonition:: Implementation note + + An implementation can optionally compute and store the :math:`(pk,sk)` values, to accelerate operations that use the key. + It is recommended that an implementation retains the seed :math:`\xi` with the key pair, in order to export the key, or copy the key to a different location. + + .. subsection:: Key derivation + + A call to `psa_key_derivation_output_key()` will draw 32 bytes of output and use these as the 32-byte ML-DSA key-pair seed, :math:`xi`. + The key-pair :math:`(pk, sk)` is generated from the seed as defined by ``ML-DSA.KeyGen_internal()`` in `[FIPS204]` §6.1. + + .. admonition:: Implementation note + + It is :scterm:`implementation defined` whether the seed :math:`xi` is expanded to :math:`(pk, sk)` at the point of derivation, or only just before the key is used. + +.. macro:: PSA_KEY_TYPE_ML_DSA_PUBLIC_KEY + :definition: ((psa_key_type_t)0x4002) + + .. summary:: + ML-DSA public key. + + The key attribute size of an ML-DSA public key is the same as the corresponding private key. See `PSA_KEY_TYPE_ML_DSA_KEY_PAIR`. + + .. subsection:: Compatible algorithms + + .. hlist:: + + * `PSA_ALG_ML_DSA` + * `PSA_ALG_HASH_ML_DSA` + * `PSA_ALG_DETERMINISTIC_ML_DSA` + * `PSA_ALG_DETERMINISTIC_HASH_ML_DSA` + + .. subsection:: Key format + + .. warning:: + + The key format may change in a final version of this API. + The standardization of exchange formats for ML-DSA public and private keys is in progress, but final documents have not been published. + See :cite-title:`LAMPS-MLDSA`. + + The current proposed format is based on the current expected outcome of that process. + + An ML-DSA public key is the :math:`pk` output of ``ML-DSA.KeyGen()``, defined in `[FIPS204]` §5.1. + + The size of the public key depends on the ML-DSA parameter set as follows: + + .. csv-table:: + :align: left + :header-rows: 1 + + Parameter set, Public-key size in bytes + ML-DSA-44, 1312 + ML-DSA-65, 1952 + ML-DSA-87, 2592 + +.. macro:: PSA_KEY_TYPE_IS_ML_DSA + :definition: /* specification-defined value */ + + .. summary:: + Whether a key type is an ML-DSA key, either a key pair or a public key. + + .. param:: type + A key type: a value of type `psa_key_type_t`. + .. _dh-keys: Diffie Hellman keys diff --git a/doc/crypto/api/ops/algorithms.rst b/doc/crypto/api/ops/algorithms.rst index 98517b75..7ab28307 100644 --- a/doc/crypto/api/ops/algorithms.rst +++ b/doc/crypto/api/ops/algorithms.rst @@ -233,7 +233,9 @@ Support macros The following composite algorithms require a hash algorithm: * `PSA_ALG_DETERMINISTIC_ECDSA()` + * `PSA_ALG_DETERMINISTIC_HASH_ML_DSA()` * `PSA_ALG_ECDSA()` + * `PSA_ALG_HASH_ML_DSA()` * `PSA_ALG_HKDF()` * `PSA_ALG_HKDF_EXPAND()` * `PSA_ALG_HKDF_EXTRACT()` diff --git a/doc/crypto/api/ops/hash.rst b/doc/crypto/api/ops/hash.rst index 9f2e7089..91191c99 100644 --- a/doc/crypto/api/ops/hash.rst +++ b/doc/crypto/api/ops/hash.rst @@ -178,13 +178,26 @@ Hash algorithms SHA3-512 is defined in :cite:`FIPS202`. +.. macro:: PSA_ALG_SHAKE128_256 + :definition: ((psa_algorithm_t)0x02000016) + + .. summary:: + The first 256 bits (32 bytes) of the SHAKE128 output. + + This can be used as pre-hashing for ML-DSA (see `PSA_ALG_HASH_ML_DSA()`). + + SHAKE128 is defined in :cite:`FIPS202`. + + .. note:: + For other scenarios where a hash function based on SHA3 or SHAKE is required, SHA3-256 is recommended. SHA3-256 has the same output size, and a theoretically higher security strength. + .. macro:: PSA_ALG_SHAKE256_512 :definition: ((psa_algorithm_t)0x02000015) .. 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`), and can be used as pre-hashing for ML-DSA (see `PSA_ALG_HASH_ML_DSA()`). SHAKE256 is defined in :cite:`FIPS202`. diff --git a/doc/crypto/api/ops/signature.rst b/doc/crypto/api/ops/signature.rst index d802a9ea..a0dfa268 100644 --- a/doc/crypto/api/ops/signature.rst +++ b/doc/crypto/api/ops/signature.rst @@ -347,6 +347,292 @@ 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`. +.. _ml-dsa-algorithms: + +Module Lattice-based signature algorithms +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ML-DSA signature and verification scheme is defined in :cite-title:`FIPS204`. +ML-DSA has three parameter sets which provide differing security strengths. + +ML-DSA keys are large: 1.2--2.5kB for the public key, and triple that for the key pair. +ML-DSA signatures are much larger than those for RSA and Elliptic curve schemes, between 2.4kB and 4.6kB, depending on the selected parameter set. + +See `[FIPS204]` §4 for details on the parameter sets, and the key and generated signature sizes. + +The generation of an ML-DSA key depends on the full parameter specification. +The encoding of each parameter set into the key attributes is described in :secref:`ml-dsa-keys`. + +`[FIPS204]` defines pure and pre-hashed variants of the signature scheme, which can either be hedged (randomized) or deterministic. +Four algorithms are defined to support these variants: `PSA_ALG_ML_DSA`, `PSA_ALG_DETERMINISTIC_ML_DSA`, `PSA_ALG_HASH_ML_DSA()`, and `PSA_ALG_DETERMINISTIC_HASH_ML_DSA()`. + +.. _ml-dsa-deterministic-signatures: + +.. rubric:: Hedged and deterministic signatures + +Hedging incorporates fresh randomness in the signature computation, resulting in distinct signatures on every signing operation when given identical inputs. +Deterministic signatures do not require additional random data, and result in an identical signature for the same inputs. + +Signature verification does not distinguish between a hedged and a deterministic signature. +Either hedged or deterministic algorithms can be used when verifying a signature. + +When computing a signature, the key's permitted-algorithm policy must match the requested algorithm, treating hedged and deterministic versions as distinct. +When verifying a signature, the hedged and deterministic versions of each algorithm are considered equivalent when checking the key's permitted-algorithm policy. + +.. note:: + + The hedged version provides message secrecy and some protection against side-channels. + `[FIPS204]` recommends that users should use the hedged version if either of these issues are a concern. + The deterministic variant should only be used if the implementation does not include any source of randomness. + +.. admonition:: Implementation note + + `[FIPS204]` recommends that implementations use an approved random number generator to provide the random value in the hedged version. + However, it notes that use of the hedged variant with a weak RNG is generally preferable to the deterministic variant. + +.. rationale:: + + The use of fresh randomness, or not, when computing a signature seems like an implementation decision based on the capability of the system, and its vulnerability to specific threats, following the recommendations in `[FIPS204]`. + + However, the |API| gives distinct algorithm identifiers for the hedged and deterministic variants, to enable an application use case to require a specific variant. + +.. rubric:: Pure and pre-hashed algorithms + +The pre-hashed signature computation *HashML-DSA* generates distinct signatures to a pure signature *ML-DSA*, with the same key and message hashing algorithm. + +An ML-DSA signature can only be verified with an ML-DSA algorithm. +A HashML-DSA signature can only be verified with a HashML-DSA algorithm. + +.. rubric:: Contexts + +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 empty context string is used when computing or verifying ML-DSA signatures. + +A future version of this specification may add suitable functions and extend this algorithm to support contexts. + +.. macro:: PSA_ALG_ML_DSA + :definition: ((psa_algorithm_t) 0x06004400) + + .. summary:: + Module lattice-based digital signature algorithm without pre-hashing (ML-DSA). + + This algorithm can be only used with the `psa_sign_message()` and `psa_verify_message()` functions. + + This is the pure ML-DSA digital signature algorithm, defined by :cite-title:`FIPS204`, using hedging. + ML-DSA requires an ML-DSA key, which determines the ML-DSA parameter set for the operation. + + This algorithm is randomized: each invocation returns a different, equally valid signature. + See the `notes on hedged signatures `_. + + When `PSA_ALG_ML_DSA` is used as a permitted algorithm in a key policy, this permits: + + * `PSA_ALG_ML_DSA` as the algorithm in a call to `psa_sign_message()`. + * `PSA_ALG_ML_DSA` or `PSA_ALG_DETERMINISTIC_ML_DSA` as the algorithm in a call to `psa_verify_message()`. + + .. note:: + To sign or verify the pre-computed hash of a message using ML-DSA, the HashML-DSA algorithms (`PSA_ALG_HASH_ML_DSA()` and `PSA_ALG_DETERMINISTIC_HASH_ML_DSA()`) can also be used with `psa_sign_hash()` and `psa_verify_hash()`. + + The signature produced by HashML-DSA is distinct from that produced by ML-DSA. + + .. subsection:: Compatible key types + + | :code:`PSA_KEY_TYPE_ML_DSA_KEY_PAIR` + | :code:`PSA_KEY_TYPE_ML_DSA_PUBLIC_KEY` (signature verification only) + +.. macro:: PSA_ALG_DETERMINISTIC_ML_DSA + :definition: ((psa_algorithm_t) 0x06004500) + + .. summary:: + Deterministic module lattice-based digital signature algorithm without pre-hashing (ML-DSA). + + This algorithm can be only used with the `psa_sign_message()` and `psa_verify_message()` functions. + + This is the pure ML-DSA digital signature algorithm, defined by :cite-title:`FIPS204`, without hedging. + ML-DSA requires an ML-DSA key, which determines the ML-DSA parameter set for the operation. + + This algorithm is deterministic: each invocation with the same inputs returns an identical signature. + + .. warning:: + It is recommended to use the hedged `PSA_ALG_ML_DSA` algorithm instead, when supported by the implementation. + See the `notes on deterministic signatures `_. + + When `PSA_ALG_DETERMINISTIC_ML_DSA` is used as a permitted algorithm in a key policy, this permits: + + * `PSA_ALG_DETERMINISTIC_ML_DSA` as the algorithm in a call to `psa_sign_message()`. + * `PSA_ALG_ML_DSA` or `PSA_ALG_DETERMINISTIC_ML_DSA` as the algorithm in a call to `psa_verify_message()`. + + .. note:: + To sign or verify the pre-computed hash of a message using ML-DSA, the HashML-DSA algorithms (`PSA_ALG_HASH_ML_DSA()` and `PSA_ALG_DETERMINISTIC_HASH_ML_DSA()`) can also be used with `psa_sign_hash()` and `psa_verify_hash()`. + + The signature produced by HashML-DSA is distinct from that produced by ML-DSA. + + .. subsection:: Compatible key types + + | :code:`PSA_KEY_TYPE_ML_DSA_KEY_PAIR` + | :code:`PSA_KEY_TYPE_ML_DSA_PUBLIC_KEY` (signature verification only) + +.. macro:: PSA_ALG_HASH_ML_DSA + :definition: /* specification-defined value */ + + .. summary:: + Module lattice-based digital signature algorithm with pre-hashing (HashML-DSA). + + .. param:: hash_alg + A hash algorithm: a value of type `psa_algorithm_t` such that :code:`PSA_ALG_IS_HASH(hash_alg)` is true. + This includes `PSA_ALG_ANY_HASH` when specifying the algorithm in a key policy. + + .. return:: + The corresponding HashML-DSA signature algorithm, using ``hash_alg`` to pre-hash the message. + + Unspecified if ``hash_alg`` is not a supported hash algorithm. + + This algorithm can be used with both the message and hash signature functions. + + This is the pre-hashed ML-DSA digital signature algorithm, defined by :cite-title:`FIPS204`, using hedging. + ML-DSA requires an ML-DSA key, which determines the ML-DSA parameter set for the operation. + + .. note:: + For the pre-hashing, `[FIPS204]` §5.4 recommends the use of an approved hash function with an equivalent, or better, security strength than the chosen ML-DSA parameter set. + + This algorithm is randomized: each invocation returns a different, equally valid signature. + See the `notes on hedged signatures `_. + + When `PSA_ALG_HASH_ML_DSA()` is used as a permitted algorithm in a key policy, this permits: + + * `PSA_ALG_HASH_ML_DSA()` as the algorithm in a call to `psa_sign_message()` and `psa_sign_hash()`. + * `PSA_ALG_HASH_ML_DSA()` or `PSA_ALG_DETERMINISTIC_HASH_ML_DSA()` as the algorithm in a call to `psa_verify_message()` and `psa_verify_hash()`. + + .. note:: + The signature produced by HashML-DSA is distinct from that produced by ML-DSA. + + .. subsection:: Usage + + This is a hash-and-sign algorithm. To calculate a signature, use one of the following approaches: + + * Call `psa_sign_message()` with the message. + + * Calculate the hash of the message with `psa_hash_compute()`, or with a multi-part hash operation, using the ``hash_alg`` hash algorithm. + Note that ``hash_alg`` can be extracted from the signature algorithm using :code:`PSA_ALG_GET_HASH(sig_alg)`. + Then sign the calculated hash with `psa_sign_hash()`. + + Verifying a signature is similar, using `psa_verify_message()` or `psa_verify_hash()` instead of the signature function. + + .. subsection:: Compatible key types + + | :code:`PSA_KEY_TYPE_ML_DSA_KEY_PAIR` + | :code:`PSA_KEY_TYPE_ML_DSA_PUBLIC_KEY` (signature verification only) + +.. macro:: PSA_ALG_DETERMINISTIC_HASH_ML_DSA + :definition: /* specification-defined value */ + + .. summary:: + Deterministic module lattice-based digital signature algorithm with pre-hashing (HashML-DSA). + + .. param:: hash_alg + A hash algorithm: a value of type `psa_algorithm_t` such that :code:`PSA_ALG_IS_HASH(hash_alg)` is true. + This includes `PSA_ALG_ANY_HASH` when specifying the algorithm in a key policy. + + .. return:: + The corresponding deterministic HashML-DSA signature algorithm, using ``hash_alg`` to pre-hash the message. + + Unspecified if ``hash_alg`` is not a supported hash algorithm. + + This algorithm can be used with both the message and hash signature functions. + + This is the pre-hashed ML-DSA digital signature algorithm, defined by :cite-title:`FIPS204`, without hedging. + ML-DSA requires an ML-DSA key, which determines the ML-DSA parameter set for the operation. + + .. note:: + For the pre-hashing, `[FIPS204]` §5.4 recommends the use of an approved hash function with an equivalent, or better, security strength than the chosen ML-DSA parameter set. + + This algorithm is deterministic: each invocation with the same inputs returns an identical signature. + + .. warning:: + It is recommended to use the hedged `PSA_ALG_HASH_ML_DSA()` algorithm instead, when supported by the implementation. + See the `notes on deterministic signatures `_. + + When `PSA_ALG_DETERMINISTIC_HASH_ML_DSA()` is used as a permitted algorithm in a key policy, this permits: + + * `PSA_ALG_DETERMINISTIC_HASH_ML_DSA()` as the algorithm in a call to `psa_sign_message()` and `psa_sign_hash()`. + * `PSA_ALG_HASH_ML_DSA()` or `PSA_ALG_DETERMINISTIC_HASH_ML_DSA()` as the algorithm in a call to `psa_verify_message()` and `psa_verify_hash()`. + + .. note:: + The signature produced by HashML-DSA is distinct from that produced by ML-DSA. + + .. subsection:: Usage + + See `PSA_ALG_HASH_ML_DSA()` for example usage. + + .. subsection:: Compatible key types + + | :code:`PSA_KEY_TYPE_ML_DSA_KEY_PAIR` + | :code:`PSA_KEY_TYPE_ML_DSA_PUBLIC_KEY` (signature verification only) + +.. macro:: PSA_ALG_IS_ML_DSA + :definition: /* specification-defined value */ + + .. summary:: + Whether the specified algorithm is ML-DSA, without pre-hashing. + + .. param:: alg + An algorithm identifier: a value of type `psa_algorithm_t`. + + .. return:: + ``1`` if ``alg`` is a pure ML-DSA algorithm, ``0`` otherwise. + + This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. + + .. note:: + Use `PSA_ALG_IS_HASH_ML_DSA()` to determine if an algorithm identifier is a HashML-DSA algorithm. + +.. macro:: PSA_ALG_IS_HASH_ML_DSA + :definition: /* specification-defined value */ + + .. summary:: + Whether the specified algorithm is HashML-DSA. + + .. param:: alg + An algorithm identifier: a value of type `psa_algorithm_t`. + + .. return:: + ``1`` if ``alg`` is a HashML-DSA algorithm, ``0`` otherwise. + + This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. + + .. note:: + Use `PSA_ALG_IS_ML_DSA()` to determine if an algorithm identifier is a pre-hashed ML-DSA algorithm. + +.. macro:: PSA_ALG_IS_DETERMINISTIC_HASH_ML_DSA + :definition: /* specification-defined value */ + + .. summary:: + Whether the specified algorithm is deterministic HashML-DSA. + + .. param:: alg + An algorithm identifier: a value of type `psa_algorithm_t`. + + .. return:: + ``1`` if ``alg`` is a deterministic HashML-DSA algorithm, ``0`` otherwise. + + This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. + + See also `PSA_ALG_IS_HASH_ML_DSA()` and `PSA_ALG_IS_HEDGED_HASH_ML_DSA()`. + +.. macro:: PSA_ALG_IS_HEDGED_HASH_ML_DSA + :definition: /* specification-defined value */ + + .. summary:: + Whether the specified algorithm is hedged HashML-DSA. + + .. param:: alg + An algorithm identifier: a value of type `psa_algorithm_t`. + + .. return:: + ``1`` if ``alg`` is a hedged HashML-DSA algorithm, ``0`` otherwise. + + This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. + + See also `PSA_ALG_IS_HASH_ML_DSA()` and `PSA_ALG_IS_DETERMINISTIC_HASH_ML_DSA()`. Asymmetric signature functions ------------------------------ @@ -773,7 +1059,7 @@ 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, ...)`: diff --git a/doc/crypto/appendix/encodings.rst b/doc/crypto/appendix/encodings.rst index a1784f9a..a9971773 100644 --- a/doc/crypto/appendix/encodings.rst +++ b/doc/crypto/appendix/encodings.rst @@ -308,17 +308,21 @@ H = HASH-TYPE (see :numref:`table-hash-type`) for message signature algorithms t :widths: auto Signature algorithm, SIGN-TYPE, Algorithm identifier, Algorithm value - RSA PKCS#1 v1.5, ``0x02``, :code:`PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)`, ``0x060002hh`` :sup:`a` + RSA PKCS#1 v1.5, ``0x02``, :code:`PSA_ALG_RSA_PKCS1V15_SIGN(hash)`, ``0x060002hh`` :sup:`a` RSA PKCS#1 v1.5 no hash :sup:`b`, ``0x02``, `PSA_ALG_RSA_PKCS1V15_SIGN_RAW`, ``0x06000200`` - RSA PSS, ``0x03``, :code:`PSA_ALG_RSA_PSS(hash_alg)`, ``0x060003hh`` :sup:`a` - RSA PSS any salt length, ``0x13``, :code:`PSA_ALG_RSA_PSS_ANY_SALT(hash_alg)`, ``0x060013hh`` :sup:`a` - Randomized ECDSA, ``0x06``, :code:`PSA_ALG_ECDSA(hash_alg)`, ``0x060006hh`` :sup:`a` + RSA PSS, ``0x03``, :code:`PSA_ALG_RSA_PSS(hash)`, ``0x060003hh`` :sup:`a` + RSA PSS any salt length, ``0x13``, :code:`PSA_ALG_RSA_PSS_ANY_SALT(hash)`, ``0x060013hh`` :sup:`a` + Randomized ECDSA, ``0x06``, :code:`PSA_ALG_ECDSA(hash)`, ``0x060006hh`` :sup:`a` Randomized ECDSA no hash :sup:`b`, ``0x06``, `PSA_ALG_ECDSA_ANY`, ``0x06000600`` - Deterministic ECDSA, ``0x07``, :code:`PSA_ALG_DETERMINISTIC_ECDSA(hash_alg)`, ``0x060007hh`` :sup:`a` + Deterministic ECDSA, ``0x07``, :code:`PSA_ALG_DETERMINISTIC_ECDSA(hash)`, ``0x060007hh`` :sup:`a` PureEdDSA, ``0x08``, `PSA_ALG_PURE_EDDSA`, ``0x06000800`` HashEdDSA, ``0x09``, `PSA_ALG_ED25519PH` and `PSA_ALG_ED448PH`, ``0x060009hh`` :sup:`c` + Hedged ML-DSA, ``0x44``, `PSA_ALG_ML_DSA`, ``0x06004400`` + Deterministic ML-DSA, ``0x45``, `PSA_ALG_DETERMINISTIC_ML_DSA`, ``0x06004500`` + Hedged HashML-DSA, ``0x46``, :code:`PSA_ALG_HASH_ML_DSA(hash)`, ``0x060046hh`` :sup:`a` + Deterministic HashML-DSA, ``0x47``, :code:`PSA_ALG_DETERMINISTIC_HASH_ML_DSA(hash)`, ``0x060047hh`` :sup:`a` -a. ``hh`` is the HASH-TYPE for the hash algorithm, ``hash_alg``, used to construct the signature algorithm. +a. ``hh`` is the HASH-TYPE for the hash algorithm, ``hash``, used to construct the signature algorithm. b. Asymmetric signature algorithms without hashing can only be used with `psa_sign_hash()` and `psa_verify_hash()`. @@ -597,6 +601,8 @@ The defined values for NP-FAMILY and P are shown in :numref:`table-np-type`. Key family, Public/pair, PAIR, NP-FAMILY, P, Key type, Key value RSA, Public key, 0, 0, 1, `PSA_KEY_TYPE_RSA_PUBLIC_KEY`, ``0x4001`` , Key pair, 3, 0, 1, `PSA_KEY_TYPE_RSA_KEY_PAIR`, ``0x7001`` + ML-DSA, Public key, 0, 1, 0, `PSA_KEY_TYPE_ML_DSA_PUBLIC_KEY`, ``0x4002`` + , Key pair, 3, 1, 0, `PSA_KEY_TYPE_ML_DSA_KEY_PAIR`, ``0x7002`` .. _ecc-key-encoding: diff --git a/doc/crypto/appendix/history.rst b/doc/crypto/appendix/history.rst index a0e7d299..e197b9f7 100644 --- a/doc/crypto/appendix/history.rst +++ b/doc/crypto/appendix/history.rst @@ -33,6 +33,9 @@ Changes to the API See :secref:`asymmetric-key-encoding` and :secref:`appendix-specdef-key-values`. +* Added support for FIPS 204 ML-DSA signature algorithm and keys. + See :secref:`ml-dsa-keys` and :secref:`ml-dsa-algorithms`. + Clarifications and fixes ~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/crypto/appendix/specdef_values.rst b/doc/crypto/appendix/specdef_values.rst index 11d1ea2d..00a3a03c 100644 --- a/doc/crypto/appendix/specdef_values.rst +++ b/doc/crypto/appendix/specdef_values.rst @@ -39,6 +39,9 @@ Algorithm macros #define PSA_ALG_DETERMINISTIC_ECDSA(hash_alg) \ ((psa_algorithm_t) (0x06000700 | ((hash_alg) & 0x000000ff))) + #define PSA_ALG_DETERMINISTIC_HASH_ML_DSA(hash_alg) \ + ((psa_algorithm_t) (0x06004700 | ((hash_alg) & 0x000000ff))) + #define PSA_ALG_ECDSA(hash_alg) \ ((psa_algorithm_t) (0x06000600 | ((hash_alg) & 0x000000ff))) @@ -48,6 +51,9 @@ Algorithm macros #define PSA_ALG_GET_HASH(alg) \ (((alg) & 0x000000ff) == 0 ? PSA_ALG_NONE : 0x02000000 | ((alg) & 0x000000ff)) + #define PSA_ALG_HASH_ML_DSA(hash_alg) \ + ((psa_algorithm_t) (0x06004600 | ((hash_alg) & 0x000000ff))) + #define PSA_ALG_HKDF(hash_alg) \ ((psa_algorithm_t) (0x08000100 | ((hash_alg) & 0x000000ff))) @@ -78,6 +84,9 @@ Algorithm macros #define PSA_ALG_IS_DETERMINISTIC_ECDSA(alg) \ (((alg) & ~0x000000ff) == 0x06000700) + #define PSA_ALG_IS_DETERMINISTIC_HASH_ML_DSA(alg) \ + (((alg) & ~0x000000ff) == 0x06004700) + #define PSA_ALG_IS_ECDH(alg) \ (((alg) & 0x7fff0000) == 0x09020000) @@ -92,11 +101,18 @@ Algorithm macros #define PSA_ALG_IS_HASH_AND_SIGN(alg) \ (PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \ - PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_HASH_EDDSA(alg)) + PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_HASH_EDDSA(alg) || \ + PSA_ALG_IS_HASH_ML_DSA(alg)) #define PSA_ALG_IS_HASH_EDDSA(alg) \ (((alg) & ~0x000000ff) == 0x06000900) + #define PSA_ALG_IS_HASH_ML_DSA(alg) \ + (((alg) & ~0x000001ff) == 0x06004600) + + #define PSA_ALG_IS_HEDGED_HASH_ML_DSA(alg) \ + (((alg) & ~0x000000ff) == 0x06004600) + #define PSA_ALG_IS_HKDF(alg) \ (((alg) & ~0x000000ff) == 0x08000100) @@ -124,6 +140,9 @@ Algorithm macros #define PSA_ALG_IS_MAC(alg) \ (((alg) & 0x7f000000) == 0x03000000) + #define PSA_ALG_IS_ML_DSA(alg) \ + (((alg) & ~0x00000100) == 0x06004400) + #define PSA_ALG_IS_PAKE(alg) \ (((alg) & 0x7f000000) == 0x0a000000) @@ -152,7 +171,8 @@ Algorithm macros (((alg) & 0x7f000000) == 0x06000000) #define PSA_ALG_IS_SIGN_HASH(alg) \ - PSA_ALG_IS_SIGN(alg) + (PSA_ALG_IS_SIGN(alg) && \ + (alg) != PSA_ALG_PURE_EDDSA && !PSA_ALG_IS_ML_DSA(alg)) #define PSA_ALG_IS_SIGN_MESSAGE(alg) \ (PSA_ALG_IS_SIGN(alg) && \ @@ -298,6 +318,9 @@ Key type macros #define PSA_KEY_TYPE_IS_KEY_PAIR(type) \ (((type) & 0x7000) == 0x7000) + #define PSA_KEY_TYPE_IS_ML_DSA(type) \ + (PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) == 0x4002) + #define PSA_KEY_TYPE_IS_PUBLIC_KEY(type) \ (((type) & 0x7000) == 0x4000) diff --git a/doc/crypto/references b/doc/crypto/references index 196e15df..d9c7d995 100644 --- a/doc/crypto/references +++ b/doc/crypto/references @@ -396,3 +396,21 @@ :author: Thread Group :publication: July 2022 :url: www.threadgroup.org/ThreadSpec + +.. reference:: FIPS203 + :title: FIPS Publication 203: Module-Lattice-Based Key-Encapsulation Mechanism Standard + :author: NIST + :publication: August 2024 + :url: doi.org/10.6028/NIST.FIPS.203 + +.. reference:: FIPS204 + :title: FIPS Publication 204: Module-Lattice-Based Digital Signature Standard + :author: NIST + :publication: August 2024 + :url: doi.org/10.6028/NIST.FIPS.204 + +.. reference:: LAMPS-MLDSA + :title: Internet X.509 Public Key Infrastructure: Algorithm Identifiers for ML-DSA (Draft 04) + :author: IETF + :publication: July 2024 (DRAFT) + :url: datatracker.ietf.org/doc/draft-ietf-lamps-dilithium-certificates-04