Skip to content

Conversation

@modules-kpd-app
Copy link

Pull request for series with
subject: lib/crypto: Move SHA3 to lib/crypto, add SHAKE* and add ML-DSA signing
version: 6
url: https://patchwork.kernel.org/project/linux-modules/list/?series=1012909

@modules-kpd-app
Copy link
Author

Upstream branch: 5eb4b9a
series: https://patchwork.kernel.org/project/linux-modules/list/?series=1012909
version: 6

@modules-kpd-app modules-kpd-app bot force-pushed the modules-next_base branch 2 times, most recently from e00514b to 0299e02 Compare October 22, 2025 10:24
Rename the s390 sha3_* functions to have an "s390_" prefix to avoid
conflict with generic code.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-By: Harald Freudenberger <freude@linux.ibm.com>
cc: Eric Biggers <ebiggers@kernel.org>
cc: Jason A. Donenfeld <Jason@zx2c4.com>
cc: Ard Biesheuvel <ardb@kernel.org>
cc: Holger Dengler <dengler@linux.ibm.com>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: Stephan Mueller <smueller@chronox.de>
cc: linux-crypto@vger.kernel.org
cc: linux-s390@vger.kernel.org
Rename the arm64 sha3_* functions to have an "arm64_" prefix to avoid
conflict with generic code.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Eric Biggers <ebiggers@kernel.org>
cc: Jason A. Donenfeld <Jason@zx2c4.com>
cc: Ard Biesheuvel <ardb@kernel.org>
cc: Catalin Marinas <catalin.marinas@arm.com>
cc: Will Deacon <will@kernel.org>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: Stephan Mueller <smueller@chronox.de>
cc: linux-crypto@vger.kernel.org
cc: linux-arm-kernel@lists.infradead.org
…KE256

Add SHA3, providing SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE128 and
SHAKE256 to lib/crypto.

Notes:

 (1) I've left hooks in sha3.c for asm-optimised variants, but as I don't
     entirely know what those might look like, not having implemented any,
     the hooks' usability is uncertain.

 (2) The SHAKE algorithms will be required for ML-DSA.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Eric Biggers <ebiggers@kernel.org>
cc: Jason A. Donenfeld <Jason@zx2c4.com>
cc: Ard Biesheuvel <ardb@kernel.org>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: Stephan Mueller <smueller@chronox.de>
cc: linux-crypto@vger.kernel.org

Changes
=======
v4)
 - Doc fixes:
   - Fix the description of the algorithm to be closer to the NIST spec's
     terminology.
   - Don't talk of finialising the context for XOFs.
   - Don't say "Return: None".
   - Declare the "Context" to be "Any context" and make no mention of the
     fact that it might use the FPU.
   - Change "initialise" to "initialize".
   - Don't warn that the context is relatively large for stack use.
 - Use size_t for size parameters/variables.
 - Make the module_exit unconditional.

v3)
 - Split the s390 function rename out to a separate patch.

v2)
 - Simplify things by keeping the state array in LE form and byteswapping
   all the 64-bit words before and after applying the keccak function on a
   BE system.  This means no byteswapping is required when XOR'ing data
   into the state array or when extracting the digest.  Further, this is a
   no-op on LE systems.

 - Rename sha3_final() to sha3_squeeze() and don't clear the context at the
   end as it's permitted to continue calling sha3_final() to extract
   continuations of the digest (needed by ML-DSA).

 - Don't reapply the end marker to the hash state in continuation
   sha3_squeeze() unless sha3_update() gets called again (needed by
   ML-DSA).

 - Give sha3_squeeze() the amount of digest to produce as a parameter
   rather than using ctx->digest_size and don't return the amount digested.

 - Reimplement sha3_final() as a wrapper around sha3_squeeze() that
   extracts ctx->digest_size amount of digest and then zeroes out the
   context.  The latter is necessary to avoid upsetting
   hash-test-template.h.

 - Provide a sha3_reinit() function to clear the state, but to leave the
   parameters that indicate the hash properties unaffected, allowing for
   reuse.

 - Provide a sha3_set_digestsize() function to change the size of the
   digest to be extracted by sha3_final().  sha3_squeeze() takes a
   parameter for this instead.

 - Don't pass the digest size as a parameter to shake128/256_init() but
   rather default to 128/256 bits as per the function name.

 - Provide a sha3_clear() function to zero out the context.
In crypto/sha3_generic.c, the keccakf() function calls keccakf_round() to
do most of the transforms, but not the Iota transform - presumably because
that is dependent on round number, whereas the Theta, Rho, Pi and Chi
transforms are not.

Note that the keccakf_round() function needs to be explicitly non-inlined
on certain architectures as gcc's produced output will (or used to) use
over 1KiB of stack space if inlined.

Now, this code was copied more or less verbatim into lib/crypto/sha3.c, so
that has the same aesthetic issue.  Fix this there by passing the round
number into sha3_keccakf_one_round_generic() and doing the Iota transform
there.

crypto/sha3_generic.c is left untouched as that will be converted to use
lib/crypto/sha3.c at some point.

Suggested-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Eric Biggers <ebiggers@kernel.org>
cc: Jason A. Donenfeld <Jason@zx2c4.com>
cc: Ard Biesheuvel <ardb@kernel.org>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: Stephan Mueller <smueller@chronox.de>
cc: linux-crypto@vger.kernel.org
Add a SHA3 kunit test, providing the following:

 (*) A simple test of each of SHA3-224, SHA3-256, SHA3-384, SHA-512,
     SHAKE128 and SHAKE256.

 (*) NIST 0- and 1600-bit test vectors for SHAKE128 and SHAKE256.

 (*) Output tiling (multiple squeezing) tests for SHAKE256.

 (*) Standard hash template test for SHA3-256.

 (*) Standard benchmark test for SHA3-256.

gen-hash-testvecs.py is also modified in a number of ways:

 (1) To be able to generate SHAKE* testvecs because Python's hashlib
     requires the output digest size supplying for those two algorithms as
     they produce arbitrary length digests.

 (2) To change '-' in the algo name into '_' when generating symbols from
     it.

 (3) To not generate HMAC for SHA3 or SHAKE as support for that isn't
     currently implemented.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Eric Biggers <ebiggers@kernel.org>
cc: Jason A. Donenfeld <Jason@zx2c4.com>
cc: Ard Biesheuvel <ardb@kernel.org>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: Stephan Mueller <smueller@chronox.de>
cc: linux-crypto@vger.kernel.org

Changes
=======
v5)
 - Fix gen-hash-testvecs.py to correctly handle algo names that contain a
   dash.
 - Fix gen-hash-testvecs.py to not generate HMAC for SHA3-* or SHAKE* as
   these don't currently have HMAC variants.
 - Fix algo names to be correct.
 - Fix kunit module description as it now tests all SHA3 variants.
Make the jitterentropy RNG use lib/crypto/sha3 rather than crypto/sha3.

For some reason it goes absolutely wild if crypto/sha3 is reimplemented
to use lib/crypto/sha3, but it's fine if it uses lib directly.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Stephan Mueller <smueller@chronox.de>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: linux-crypto@vger.kernel.org
Switch crypto/sha3_generic.c to use lib/crypto/sha3.  Note that this makes
use of the internal general API rather implementing a separate set of
init/update/finup handlers for each algorithm.

Whilst we're at it, eliminate the sha3_state struct and move the st[] state
array into the sha3_ctx struct.

Note that this also eliminates the need to set CRYPTO_AHASH_ALG_BLOCK_ONLY
as the lib/crypto/sha3.c code handles misalignment itself without the need
for a place to stash a block at the cost of a few extra bytes of state.
This may mean that HASH_MAX_STATESIZE can be reduced.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Eric Biggers <ebiggers@kernel.org>
cc: Jason A. Donenfeld <Jason@zx2c4.com>
cc: Ard Biesheuvel <ardb@kernel.org>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: Stephan Mueller <smueller@chronox.de>
cc: linux-crypto@vger.kernel.org
SHAKE128/256 'digest' algos need to be available for the ML-DSA pre-digest,
which is a selectable algorithm and need to be available through the same
API as, say, SHA3-512 and SHA512 both.  Resqueezability (probably) isn't
required for this and they'll produce the default number of bytes as the
digest size.

Also, increase MAX_ALGAPI_BLOCKSIZE to accommodate SHAKE128.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Eric Biggers <ebiggers@kernel.org>
cc: Jason A. Donenfeld <Jason@zx2c4.com>
cc: Ard Biesheuvel <ardb@kernel.org>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: Stephan Mueller <smueller@chronox.de>
cc: linux-crypto@vger.kernel.org
Port Stephan Mueller's Leancrypto implementation of ML-DSA/Dilithium to the
kernel.

[!] NOTE: This isn't entirely cleaned up yet!  This includes converting the
documentation comments and removing more compatibility macros.  I wanted to
concentrate on getting it actually working first.

Apologies to Stephan, but I've stripped out a bunch of macros to do return
checking and suchlike and removed a bunch of "lc_" prefixes from the code.

The code retains the following features, some of which probably need to
be separated out or dropped entirely:

 - Signature verification
 - Signing
 - Prehash support
 - External Mu support

Composite signature support is mostly removed and none of the arch-specific
code from Leancrypto has been included for the moment, so this is pure C.

The interface to this code is through the crypto_sig API as the PKCS#7 code
wants to use that rather than calling it directly.  As such, I've placed it
in crypto/ rather than lib/crypto/.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Stephan Mueller <smueller@chronox.de>
cc: Eric Biggers <ebiggers@kernel.org>
cc: Jason A. Donenfeld <Jason@zx2c4.com>
cc: Ard Biesheuvel <ardb@kernel.org>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: linux-crypto@vger.kernel.org
Add generation of keypairs.  I suspect we don't want to do this in the
kernel.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Stephan Mueller <smueller@chronox.de>
cc: Eric Biggers <ebiggers@kernel.org>
cc: Jason A. Donenfeld <Jason@zx2c4.com>
cc: Ard Biesheuvel <ardb@kernel.org>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: linux-crypto@vger.kernel.org
Add the "Pure rejection tests" from Stephan Mueller's Leancrypto
implementation of ML-DSA/Dilithium 44 to the kernel as a kunit test.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Stephan Mueller <smueller@chronox.de>
cc: Eric Biggers <ebiggers@kernel.org>
cc: Jason A. Donenfeld <Jason@zx2c4.com>
cc: Ard Biesheuvel <ardb@kernel.org>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: linux-crypto@vger.kernel.org
Add the "Pure rejection tests" from Stephan Mueller's Leancrypto
implementation of ML-DSA/Dilithium 65 to the kernel as a kunit test.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Stephan Mueller <smueller@chronox.de>
cc: Eric Biggers <ebiggers@kernel.org>
cc: Jason A. Donenfeld <Jason@zx2c4.com>
cc: Ard Biesheuvel <ardb@kernel.org>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: linux-crypto@vger.kernel.org
Add the "Pure rejection tests" from Stephan Mueller's Leancrypto
implementation of ML-DSA/Dilithium 87 to the kernel as a kunit test.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Stephan Mueller <smueller@chronox.de>
cc: Eric Biggers <ebiggers@kernel.org>
cc: Jason A. Donenfeld <Jason@zx2c4.com>
cc: Ard Biesheuvel <ardb@kernel.org>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: linux-crypto@vger.kernel.org
The ML-DSA public key algorithm really wants to calculate the message
digest itself, rather than having the digest precalculated and fed to it
separately as RSA does[*].  The kernel's PKCS#7 parser, however, is
designed around the latter approach.

  [*] ML-DSA does allow for an "external mu", but CMS doesn't yet have that
  standardised.

Fix this by noting in the public_key_signature struct when the signing
algorithm is going to want this and then, rather than doing the digest of
the authenticatedAttributes ourselves and overwriting the sig->digest with
that, replace sig->digest with a copy of the contents of the
authenticatedAttributes section and adjust the digest length to match.

This will then be fed to the public key algorithm as normal which can do
what it wants with the data.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Lukas Wunner <lukas@wunner.de>
cc: Ignat Korchagin <ignat@cloudflare.com>
cc: Stephan Mueller <smueller@chronox.de>
cc: Eric Biggers <ebiggers@kernel.org>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: keyrings@vger.kernel.org
cc: linux-crypto@vger.kernel.org
@modules-kpd-app
Copy link
Author

Upstream branch: 5eb4b9a
series: https://patchwork.kernel.org/project/linux-modules/list/?series=1012909
version: 6

Add support for ML-DSA keys and signatures to the PKCS#7 and X.509
implementations.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Lukas Wunner <lukas@wunner.de>
cc: Ignat Korchagin <ignat@cloudflare.com>
cc: Stephan Mueller <smueller@chronox.de>
cc: Eric Biggers <ebiggers@kernel.org>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: keyrings@vger.kernel.org
cc: linux-crypto@vger.kernel.org
Allow ML-DSA module signing to be enabled.

Note that openssl's CMS_*() function suite does not, as of openssl-3.5.1,
support the use of CMS_NOATTR with ML-DSA, so the prohibition against using
authenticatedAttributes with module signing has to be removed.  The selected
digest then applies only to the algorithm used to calculate the digest
stored in the messageDigest attribute.

The ML-DSA algorithm uses its own internal choice of digest (SHAKE256)
without regard to what's specified in the CMS message.  This is, in theory,
configurable, but there's currently no hook in the crypto_sig API to do
that, though possibly it could be done by parameterising the name of the
algorithm, e.g. ("ml-dsa87(sha512)").

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Lukas Wunner <lukas@wunner.de>
cc: Ignat Korchagin <ignat@cloudflare.com>
cc: Stephan Mueller <smueller@chronox.de>
cc: Eric Biggers <ebiggers@kernel.org>
cc: Herbert Xu <herbert@gondor.apana.org.au>
cc: keyrings@vger.kernel.org
cc: linux-crypto@vger.kernel.org
@modules-kpd-app modules-kpd-app bot force-pushed the series/1012909=>modules-next branch from 70b2ca8 to a0ff594 Compare October 22, 2025 10:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants