linux-crypto.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto
@ 2025-09-26 14:19 David Howells
  2025-09-26 14:19 ` [PATCH v3 1/8] s390/sha3: Rename conflicting functions David Howells
                   ` (8 more replies)
  0 siblings, 9 replies; 27+ messages in thread
From: David Howells @ 2025-09-26 14:19 UTC (permalink / raw)
  Cc: David Howells, Eric Biggers, Jason A . Donenfeld, Ard Biesheuvel,
	Herbert Xu, Stephan Mueller, linux-crypto, linux-kernel

Hi Eric, Herbert,

Here's a set of patches does the following:

 (1) Renames s390 and arm64 sha3_* functions to avoid name collisions.

 (2) Copies the core of SHA3 support from crypto/ to lib/crypto/.

 (3) Simplifies the internal code to maintain the buffer in little endian
     form, thereby simplifying the update and extraction code which don't
     then need to worry about this.  Instead, the state buffer is
     byteswapped before and after.

 (4) Moves the Iota transform into the function with the rest of the
     transforms.

 (5) Adds SHAKE128 and SHAKE256 support (needed for ML-DSA).

 (6) Adds a kunit test for SHA3 in lib/crypto/tests/.

 (7) Adds proper API documentation for SHA3.

 (8) Makes crypto/sha3_generic.c use lib/crypto/sha3.  This necessitates a
     slight enlargement of the context buffers which might affect optimised
     assembly/hardware drivers.

Note that only the generic code is moved across; the asm-optimised stuff is
not touched as I'm not familiar with that.

I have done what Eric required and made a separate wrapper struct and set
of wrapper functions for each algorithm, though I think this is excessively
bureaucratic as this multiplies the API load by 7 (and maybe 9 in the
future[*]).

[*] The Kyber algorithm also uses CSHAKE variants in the SHA3 family - and
    NIST mentions some other variants too.

This does, however, cause a problem for what I need to do as the ML-DSA
prehash is dynamically selectable by certificate OID, so I have to add
SHAKE128/256 support to the crypto shash API too - though hopefully it will
only require an output of 16 or 32 bytes respectively for the prehash case
and won't require multiple squeezing.

This is based on Eric's libcrypto-next branch.

The patches can also be found here:

	https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/log/?h=keys-pqc

David

Changes
=======
ver #3)
 - Renamed conflicting arm64 functions.
 - Made a separate wrapper API for each algorithm in the family.
 - Removed sha3_init(), sha3_reinit() and sha3_final().
 - Removed sha3_ctx::digest_size.
 - Renamed sha3_ctx::partial to sha3_ctx::absorb_offset.
 - Refer to the output of SHAKE* as "output" not "digest".
 - Moved the Iota transform into the one-round function.
 - Made sha3_update() warn if called after sha3_squeeze().
 - Simplified the module-load test to not do update after squeeze.
 - Added Return: and Context: kdoc statements and expanded the kdoc
   headers.
 - Added an API description document.
 - Overhauled the kunit tests.
   - Only have one kunit test.
   - Only call the general hash tester on one algo.
   - Add separate simple cursory checks for the other algos.
   - Add resqueezing tests.
   - Add some NIST example tests.
 - Changed crypto/sha3_generic to use this
 - Added SHAKE128/256 to crypto/sha3_generic and crypto/testmgr
 - Folded struct sha3_state into struct sha3_ctx.

ver #2)
  - Simplify the endianness handling.
  - 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.

David Howells (8):
  s390/sha3: Rename conflicting functions
  arm64/sha3: Rename conflicting functions
  lib/crypto: Add SHA3-224, SHA3-256, SHA3-384, SHA-512, SHAKE128,
    SHAKE256
  lib/crypto: Move the SHA3 Iota transform into the single round
    function
  lib/crypto: Add SHA3 kunit tests
  crypto/sha3: Use lib/crypto/sha3
  crypto/sha3: Add SHAKE128/256 support
  crypto: SHAKE tests

 Documentation/crypto/index.rst      |   1 +
 Documentation/crypto/sha3.rst       | 241 +++++++++++++
 arch/arm64/crypto/sha3-ce-glue.c    |  47 +--
 arch/s390/crypto/sha3_256_s390.c    |  26 +-
 arch/s390/crypto/sha3_512_s390.c    |  26 +-
 crypto/sha3_generic.c               | 233 +++---------
 crypto/testmgr.c                    |  14 +
 crypto/testmgr.h                    |  59 ++++
 include/crypto/sha3.h               | 467 +++++++++++++++++++++++-
 lib/crypto/Kconfig                  |   7 +
 lib/crypto/Makefile                 |   6 +
 lib/crypto/sha3.c                   | 529 ++++++++++++++++++++++++++++
 lib/crypto/tests/Kconfig            |  12 +
 lib/crypto/tests/Makefile           |   1 +
 lib/crypto/tests/sha3_kunit.c       | 338 ++++++++++++++++++
 lib/crypto/tests/sha3_testvecs.h    | 231 ++++++++++++
 scripts/crypto/gen-hash-testvecs.py |   8 +-
 17 files changed, 2012 insertions(+), 234 deletions(-)
 create mode 100644 Documentation/crypto/sha3.rst
 create mode 100644 lib/crypto/sha3.c
 create mode 100644 lib/crypto/tests/sha3_kunit.c
 create mode 100644 lib/crypto/tests/sha3_testvecs.h


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v3 1/8] s390/sha3: Rename conflicting functions
  2025-09-26 14:19 [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto David Howells
@ 2025-09-26 14:19 ` David Howells
  2025-09-29 11:39   ` Harald Freudenberger
  2025-09-26 14:19 ` [PATCH v3 2/8] arm64/sha3: " David Howells
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 27+ messages in thread
From: David Howells @ 2025-09-26 14:19 UTC (permalink / raw)
  Cc: David Howells, Eric Biggers, Jason A . Donenfeld, Ard Biesheuvel,
	Herbert Xu, Stephan Mueller, linux-crypto, linux-kernel,
	Harald Freudenberger, Holger Dengler, linux-s390

Rename the s390 sha3_* functions to have an "s390_" 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: Harald Freudenberger <freude@linux.ibm.com>
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
---
 arch/s390/crypto/sha3_256_s390.c | 26 +++++++++++++-------------
 arch/s390/crypto/sha3_512_s390.c | 26 +++++++++++++-------------
 2 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/arch/s390/crypto/sha3_256_s390.c b/arch/s390/crypto/sha3_256_s390.c
index 03bb4f4bab70..fd5ecae60a57 100644
--- a/arch/s390/crypto/sha3_256_s390.c
+++ b/arch/s390/crypto/sha3_256_s390.c
@@ -19,7 +19,7 @@
 
 #include "sha.h"
 
-static int sha3_256_init(struct shash_desc *desc)
+static int s390_sha3_256_init(struct shash_desc *desc)
 {
 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
 
@@ -32,7 +32,7 @@ static int sha3_256_init(struct shash_desc *desc)
 	return 0;
 }
 
-static int sha3_256_export(struct shash_desc *desc, void *out)
+static int s390_sha3_256_export(struct shash_desc *desc, void *out)
 {
 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
 	union {
@@ -50,7 +50,7 @@ static int sha3_256_export(struct shash_desc *desc, void *out)
 	return 0;
 }
 
-static int sha3_256_import(struct shash_desc *desc, const void *in)
+static int s390_sha3_256_import(struct shash_desc *desc, const void *in)
 {
 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
 	union {
@@ -68,22 +68,22 @@ static int sha3_256_import(struct shash_desc *desc, const void *in)
 	return 0;
 }
 
-static int sha3_224_import(struct shash_desc *desc, const void *in)
+static int s390_sha3_224_import(struct shash_desc *desc, const void *in)
 {
 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
 
-	sha3_256_import(desc, in);
+	s390_sha3_256_import(desc, in);
 	sctx->func = CPACF_KIMD_SHA3_224;
 	return 0;
 }
 
 static struct shash_alg sha3_256_alg = {
 	.digestsize	=	SHA3_256_DIGEST_SIZE,	   /* = 32 */
-	.init		=	sha3_256_init,
+	.init		=	s390_sha3_256_init,
 	.update		=	s390_sha_update_blocks,
 	.finup		=	s390_sha_finup,
-	.export		=	sha3_256_export,
-	.import		=	sha3_256_import,
+	.export		=	s390_sha3_256_export,
+	.import		=	s390_sha3_256_import,
 	.descsize	=	S390_SHA_CTX_SIZE,
 	.statesize	=	SHA3_STATE_SIZE,
 	.base		=	{
@@ -96,22 +96,22 @@ static struct shash_alg sha3_256_alg = {
 	}
 };
 
-static int sha3_224_init(struct shash_desc *desc)
+static int s390_sha3_224_init(struct shash_desc *desc)
 {
 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
 
-	sha3_256_init(desc);
+	s390_sha3_256_init(desc);
 	sctx->func = CPACF_KIMD_SHA3_224;
 	return 0;
 }
 
 static struct shash_alg sha3_224_alg = {
 	.digestsize	=	SHA3_224_DIGEST_SIZE,
-	.init		=	sha3_224_init,
+	.init		=	s390_sha3_224_init,
 	.update		=	s390_sha_update_blocks,
 	.finup		=	s390_sha_finup,
-	.export		=	sha3_256_export, /* same as for 256 */
-	.import		=	sha3_224_import, /* function code different! */
+	.export		=	s390_sha3_256_export, /* same as for 256 */
+	.import		=	s390_sha3_224_import, /* function code different! */
 	.descsize	=	S390_SHA_CTX_SIZE,
 	.statesize	=	SHA3_STATE_SIZE,
 	.base		=	{
diff --git a/arch/s390/crypto/sha3_512_s390.c b/arch/s390/crypto/sha3_512_s390.c
index a5c9690eecb1..f4b52a3a0433 100644
--- a/arch/s390/crypto/sha3_512_s390.c
+++ b/arch/s390/crypto/sha3_512_s390.c
@@ -18,7 +18,7 @@
 
 #include "sha.h"
 
-static int sha3_512_init(struct shash_desc *desc)
+static int s390_sha3_512_init(struct shash_desc *desc)
 {
 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
 
@@ -31,7 +31,7 @@ static int sha3_512_init(struct shash_desc *desc)
 	return 0;
 }
 
-static int sha3_512_export(struct shash_desc *desc, void *out)
+static int s390_sha3_512_export(struct shash_desc *desc, void *out)
 {
 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
 	union {
@@ -49,7 +49,7 @@ static int sha3_512_export(struct shash_desc *desc, void *out)
 	return 0;
 }
 
-static int sha3_512_import(struct shash_desc *desc, const void *in)
+static int s390_sha3_512_import(struct shash_desc *desc, const void *in)
 {
 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
 	union {
@@ -67,22 +67,22 @@ static int sha3_512_import(struct shash_desc *desc, const void *in)
 	return 0;
 }
 
-static int sha3_384_import(struct shash_desc *desc, const void *in)
+static int s390_sha3_384_import(struct shash_desc *desc, const void *in)
 {
 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
 
-	sha3_512_import(desc, in);
+	s390_sha3_512_import(desc, in);
 	sctx->func = CPACF_KIMD_SHA3_384;
 	return 0;
 }
 
 static struct shash_alg sha3_512_alg = {
 	.digestsize	=	SHA3_512_DIGEST_SIZE,
-	.init		=	sha3_512_init,
+	.init		=	s390_sha3_512_init,
 	.update		=	s390_sha_update_blocks,
 	.finup		=	s390_sha_finup,
-	.export		=	sha3_512_export,
-	.import		=	sha3_512_import,
+	.export		=	s390_sha3_512_export,
+	.import		=	s390_sha3_512_import,
 	.descsize	=	S390_SHA_CTX_SIZE,
 	.statesize	=	SHA3_STATE_SIZE,
 	.base		=	{
@@ -97,22 +97,22 @@ static struct shash_alg sha3_512_alg = {
 
 MODULE_ALIAS_CRYPTO("sha3-512");
 
-static int sha3_384_init(struct shash_desc *desc)
+static int s390_sha3_384_init(struct shash_desc *desc)
 {
 	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
 
-	sha3_512_init(desc);
+	s390_sha3_512_init(desc);
 	sctx->func = CPACF_KIMD_SHA3_384;
 	return 0;
 }
 
 static struct shash_alg sha3_384_alg = {
 	.digestsize	=	SHA3_384_DIGEST_SIZE,
-	.init		=	sha3_384_init,
+	.init		=	s390_sha3_384_init,
 	.update		=	s390_sha_update_blocks,
 	.finup		=	s390_sha_finup,
-	.export		=	sha3_512_export, /* same as for 512 */
-	.import		=	sha3_384_import, /* function code different! */
+	.export		=	s390_sha3_512_export, /* same as for 512 */
+	.import		=	s390_sha3_384_import, /* function code different! */
 	.descsize	=	S390_SHA_CTX_SIZE,
 	.statesize	=	SHA3_STATE_SIZE,
 	.base		=	{


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 2/8] arm64/sha3: Rename conflicting functions
  2025-09-26 14:19 [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto David Howells
  2025-09-26 14:19 ` [PATCH v3 1/8] s390/sha3: Rename conflicting functions David Howells
@ 2025-09-26 14:19 ` David Howells
  2025-09-26 14:19 ` [PATCH v3 3/8] lib/crypto: Add SHA3-224, SHA3-256, SHA3-384, SHA-512, SHAKE128, SHAKE256 David Howells
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 27+ messages in thread
From: David Howells @ 2025-09-26 14:19 UTC (permalink / raw)
  Cc: David Howells, Eric Biggers, Jason A . Donenfeld, Ard Biesheuvel,
	Herbert Xu, Stephan Mueller, linux-crypto, linux-kernel,
	Catalin Marinas, Will Deacon, linux-arm-kernel

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
---
 arch/arm64/crypto/sha3-ce-glue.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/crypto/sha3-ce-glue.c b/arch/arm64/crypto/sha3-ce-glue.c
index b4f1001046c9..426d8044535a 100644
--- a/arch/arm64/crypto/sha3-ce-glue.c
+++ b/arch/arm64/crypto/sha3-ce-glue.c
@@ -31,7 +31,7 @@ MODULE_ALIAS_CRYPTO("sha3-512");
 asmlinkage int sha3_ce_transform(u64 *st, const u8 *data, int blocks,
 				 int md_len);
 
-static int sha3_update(struct shash_desc *desc, const u8 *data,
+static int arm64_sha3_update(struct shash_desc *desc, const u8 *data,
 		       unsigned int len)
 {
 	struct sha3_state *sctx = shash_desc_ctx(desc);
@@ -55,8 +55,8 @@ static int sha3_update(struct shash_desc *desc, const u8 *data,
 	return len;
 }
 
-static int sha3_finup(struct shash_desc *desc, const u8 *src, unsigned int len,
-		      u8 *out)
+static int arm64_sha3_finup(struct shash_desc *desc, const u8 *src, unsigned int len,
+			    u8 *out)
 {
 	struct sha3_state *sctx = shash_desc_ctx(desc);
 	struct crypto_shash *tfm = desc->tfm;
@@ -90,8 +90,8 @@ static int sha3_finup(struct shash_desc *desc, const u8 *src, unsigned int len,
 static struct shash_alg algs[] = { {
 	.digestsize		= SHA3_224_DIGEST_SIZE,
 	.init			= crypto_sha3_init,
-	.update			= sha3_update,
-	.finup			= sha3_finup,
+	.update			= arm64_sha3_update,
+	.finup			= arm64_sha3_finup,
 	.descsize		= SHA3_STATE_SIZE,
 	.base.cra_name		= "sha3-224",
 	.base.cra_driver_name	= "sha3-224-ce",
@@ -102,8 +102,8 @@ static struct shash_alg algs[] = { {
 }, {
 	.digestsize		= SHA3_256_DIGEST_SIZE,
 	.init			= crypto_sha3_init,
-	.update			= sha3_update,
-	.finup			= sha3_finup,
+	.update			= arm64_sha3_update,
+	.finup			= arm64_sha3_finup,
 	.descsize		= SHA3_STATE_SIZE,
 	.base.cra_name		= "sha3-256",
 	.base.cra_driver_name	= "sha3-256-ce",
@@ -114,8 +114,8 @@ static struct shash_alg algs[] = { {
 }, {
 	.digestsize		= SHA3_384_DIGEST_SIZE,
 	.init			= crypto_sha3_init,
-	.update			= sha3_update,
-	.finup			= sha3_finup,
+	.update			= arm64_sha3_update,
+	.finup			= arm64_sha3_finup,
 	.descsize		= SHA3_STATE_SIZE,
 	.base.cra_name		= "sha3-384",
 	.base.cra_driver_name	= "sha3-384-ce",
@@ -126,8 +126,8 @@ static struct shash_alg algs[] = { {
 }, {
 	.digestsize		= SHA3_512_DIGEST_SIZE,
 	.init			= crypto_sha3_init,
-	.update			= sha3_update,
-	.finup			= sha3_finup,
+	.update			= arm64_sha3_update,
+	.finup			= arm64_sha3_finup,
 	.descsize		= SHA3_STATE_SIZE,
 	.base.cra_name		= "sha3-512",
 	.base.cra_driver_name	= "sha3-512-ce",


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 3/8] lib/crypto: Add SHA3-224, SHA3-256, SHA3-384, SHA-512, SHAKE128, SHAKE256
  2025-09-26 14:19 [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto David Howells
  2025-09-26 14:19 ` [PATCH v3 1/8] s390/sha3: Rename conflicting functions David Howells
  2025-09-26 14:19 ` [PATCH v3 2/8] arm64/sha3: " David Howells
@ 2025-09-26 14:19 ` David Howells
  2025-09-26 21:09   ` Eric Biggers
  2025-09-26 14:19 ` [PATCH v3 4/8] lib/crypto: Move the SHA3 Iota transform into the single round function David Howells
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 27+ messages in thread
From: David Howells @ 2025-09-26 14:19 UTC (permalink / raw)
  Cc: David Howells, Eric Biggers, Jason A . Donenfeld, Ard Biesheuvel,
	Herbert Xu, Stephan Mueller, linux-crypto, linux-kernel

Add SHA3, providing SHA3-224, SHA3-256, SHA3-384, SHA-512, SHAKE128 and
SHAKE256 to lib/crypto.  Also add kunit tests for each of these.

gen-hash-testvecs.py is also modified to be able to generate SHAKE hashes
because Python's hashlib requires the output digest size supplying for
those two algorithms as they produce arbitrary length digests.

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
=======
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.
---
 Documentation/crypto/index.rst |   1 +
 Documentation/crypto/sha3.rst  | 245 +++++++++++++++
 include/crypto/sha3.h          | 467 ++++++++++++++++++++++++++++-
 lib/crypto/Kconfig             |   7 +
 lib/crypto/Makefile            |   6 +
 lib/crypto/sha3.c              | 529 +++++++++++++++++++++++++++++++++
 6 files changed, 1254 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/crypto/sha3.rst
 create mode 100644 lib/crypto/sha3.c

diff --git a/Documentation/crypto/index.rst b/Documentation/crypto/index.rst
index 100b47d049c0..4ee667c446f9 100644
--- a/Documentation/crypto/index.rst
+++ b/Documentation/crypto/index.rst
@@ -27,3 +27,4 @@ for cryptographic use cases, as well as programming examples.
    descore-readme
    device_drivers/index
    krb5
+   sha3
diff --git a/Documentation/crypto/sha3.rst b/Documentation/crypto/sha3.rst
new file mode 100644
index 000000000000..ae4902895882
--- /dev/null
+++ b/Documentation/crypto/sha3.rst
@@ -0,0 +1,245 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+==========================
+SHA-3 Algorithm collection
+==========================
+
+.. Contents:
+
+  - Overview
+  - Basic API
+    - Extendable-Output Functions
+  - Convenience API
+  - Internal API
+    - Testing
+  - References
+  - API Function Reference
+
+
+Overview
+========
+
+The SHA-3 algorithm base, as specified in NIST FIPS-202[1], provides a number
+of specific algorithms all based on the same engine (Keccak).  The differences
+between them are: the block size (how much of the common state buffer gets
+updated with new data between invocations of the Keccak mixing function), what
+termination markers get mixed in upon finalisation and how much data is
+extracted at the end.  The Keccak engine is designed such that arbitrary
+amounts of output can be obtained for certain algorithms.
+
+Four standard digest algorithms are provided:
+
+ - SHA3-224
+ - SHA3-256
+ - SHA3-384
+ - SHA3-512
+
+and two Extendable-Output Functions (XOF):
+
+ - SHAKE128
+ - SHAKE256
+
+Caution: The algorithm(s) may be accelerated with optimised assembly and, as
+such, may have to sync with or modify the FPU or CPU Vector Unit state.  How
+this is done is arch specific and might involve waiting or locking.
+
+If selectable algorithms are required then the crypto_hash API must be used
+instead as this binds each algorithm to a specific C type.
+
+
+Basic API
+=========
+
+The basic API has a separate context struct for each algorithm in the SHA3
+suite, none of the contents of which are expected to be accessed directly::
+
+	struct sha3_224_ctx { ... };
+	struct sha3_256_ctx { ... };
+	struct sha3_384_ctx { ... };
+	struct sha3_512_ctx { ... };
+	struct shake128_ctx { ... };
+	struct shake256_ctx { ... };
+
+Note that these are relatively large structures, so may not be suitable for
+placing on the stack.
+
+There are a collection of initialisation functions, one for each algorithm
+supported, that initialise the context appropriately for that algorithm::
+
+	void sha3_224_init(struct sha3_224_ctx *ctx);
+	void sha3_256_init(struct sha3_256_ctx *ctx);
+	void sha3_384_init(struct sha3_384_ctx *ctx);
+	void sha3_512_init(struct sha3_512_ctx *ctx);
+	void shake128_init(struct shake128_ctx *ctx);
+	void shake256_init(struct shake256_ctx *ctx);
+
+Data is then added with the appropriate update function, again one per
+algorithm::
+
+	void sha3_224_update(struct sha3_224_ctx *ctx,
+			     const u8 *data, unsigned int len);
+	void sha3_256_update(struct sha3_256_ctx *ctx,
+			     const u8 *data, unsigned int len);
+	void sha3_384_update(struct sha3_384_ctx *ctx,
+			     const u8 *data, unsigned int len);
+	void sha3_512_update(struct sha3_512_ctx *ctx,
+			     const u8 *data, unsigned int len);
+	void shake128_update(struct shake128_ctx *ctx,
+			     const u8 *data, unsigned int len);
+	void shake256_update(struct shake256_ctx *ctx,
+			     const u8 *data, unsigned int len);
+
+The update function may be called multiple times if need be to add
+non-contiguous data.
+
+For digest algorithms, the digest is finalised and extracted with the
+algorithm-specific function::
+
+	unsigned int sha3_224_final(struct sha3_224_ctx *ctx,
+				    u8 out[SHA3_224_DIGEST_SIZE]);
+	unsigned int sha3_256_final(struct sha3_256_ctx *ctx,
+				    u8 out[SHA3_256_DIGEST_SIZE]);
+	unsigned int sha3_384_final(struct sha3_384_ctx *ctx,
+				    u8 out[SHA3_384_DIGEST_SIZE]);
+	unsigned int sha3_512_final(struct sha3_512_ctx *ctx,
+				    u8 out[SHA3_512_DIGEST_SIZE]);
+
+which also explicitly clears the context.  The amount of data extracted is
+determined by the type.
+
+
+Extendable-Output Functions
+---------------------------
+
+For XOFs, once the data has been added to a context, a variable amount of data
+may be extracted.  This can be done by calling the appropriate squeeze
+function::
+
+	void shake128_squeeze(struct shake128_ctx *ctx, u8 *out, size_t out_len);
+	void shake256_squeeze(struct shake256_ctx *ctx, u8 *out, size_t out_len);
+
+and telling it how much data should be extracted.  The squeeze function may be
+called multiple times but it will only finalise the context on the first
+invocation.
+
+Note that performing a number of squeezes, with the output laid consequitively
+in a buffer, gets exactly the same output as doing a single squeeze for the
+combined amount over the same buffer.
+
+Once all the desired output has been extracted, the context should be cleared
+with the clear function appropriate to the algorithm::
+
+	void shake128_clear(struct shake128_ctx *ctx);
+	void shake256_clear(struct shake256_ctx *ctx);
+
+
+Convenience API
+===============
+
+It only a single contiguous buffer of input needs to be added and only a single
+buffer of digest or XOF output is required, then a convenience API is provided
+that wraps all the required steps into a single function.  There is one
+function for each algorithm supported::
+
+	void sha3_224(const u8 *in, size_t in_len, u8 out[SHA3_224_DIGEST_SIZE]);
+	void sha3_256(const u8 *in, size_t in_len, u8 out[SHA3_256_DIGEST_SIZE]);
+	void sha3_384(const u8 *in, size_t in_len, u8 out[SHA3_384_DIGEST_SIZE]);
+	void sha3_512(const u8 *in, size_t in_len, u8 out[SHA3_512_DIGEST_SIZE]);
+	void shake128(const u8 *in, size_t in_len, u8 *out, size_t out_len);
+	void shake256(const u8 *in, size_t in_len, u8 *out, size_t out_len);
+
+
+Internal API
+============
+
+There is a common internal API underlying all of this that may be used to build
+further algorithms or APIs as the engine in the same in all cases.  The
+algorithm APIs all wrap the common context structure::
+
+	struct sha3_ctx {
+		struct sha3_state	state;
+		u8			block_size;
+		u8			padding;
+		u8			absorb_offset;
+		u8			squeeze_offset;
+		bool			end_marked;
+	};
+
+	struct sha3_state {
+		u64			st[SHA3_STATE_SIZE / 8];
+	};
+
+The fields are as follows:
+
+ * ``state.st``
+
+   An array of 25 64-bit state buckets that are used to hold the mathematical
+   state of the Keccak engine.  Data is XOR'd onto part of this, the engine is
+   cranked and then the output is copied from this.
+
+   For the convenience of adding input and extract output from it, the array is
+   kept in little-endian order most of the time, but is byteswapped to
+   host-endian in order to perform the Keccak function and then byteswapped
+   back again.  On an LE machine, the byteswapping is a no-op.
+
+ * ``block_size``
+
+   The size of the block of state that can be updated or extracted at a time.
+   This is related to the algorithm size.
+
+ * ``padding``
+
+   The terminating byte to add when finalising the stat.  This may differ
+   between algorithms.
+
+ * ``absorb_offset``
+
+   This tracks which is the next byte of state to be updated; when it hits
+   ``block_size``, the engine is cranked and this is reset to 0.
+
+ * ``squeeze_offset``
+
+   This tracks which is the next byte of state to be extracted; similar to
+   ``partial``, when it hits ``block_size``, if more output is requested, the
+   engine is cranked to generate more and this is reset to 0.
+
+ * ``end_marked``
+
+   This is set to true when the end marker has been added into the state to
+   prevent multiple squeezings from XOF algorithms from re-terminating the
+   state.
+
+Note that the size of the digest is *not* included in here as that's only needed
+at finalisation/squeezing time and can be supplied then.
+
+To make use of the context, the following internal functions are provided::
+
+	void sha3_update(struct sha3_ctx *ctx, const u8 *data, unsigned int len);
+	void sha3_squeeze(struct sha3_ctx *ctx, u8 *out, size_t out_len);
+	void sha3_clear(struct sha3_ctx *ctx);
+
+These allow data to be added (absorbed) into the state, output to be extracted
+(squeezed) from the state and the the state be cleared.  Note that there is no
+"final" function, per se, but that can be constructed by squeezing and
+clearing.
+
+
+Testing
+-------
+
+The sha3 module does a basic sanity test on initialisation, but there is also a
+kunit test module available.
+
+
+References
+==========
+
+[1] https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
+
+
+
+API Function Reference
+======================
+
+.. kernel-doc:: crypto/lib/sha3.c
+.. kernel-doc:: include/crypto/sha3.c
diff --git a/include/crypto/sha3.h b/include/crypto/sha3.h
index 41e1b83a6d91..41bc211afa0b 100644
--- a/include/crypto/sha3.h
+++ b/include/crypto/sha3.h
@@ -1,11 +1,14 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Common values for SHA-3 algorithms
+ *
+ * See also Documentation/crypto/sha3.rst
  */
 #ifndef __CRYPTO_SHA3_H__
 #define __CRYPTO_SHA3_H__
 
 #include <linux/types.h>
+#include <linux/string.h>
 
 #define SHA3_224_DIGEST_SIZE	(224 / 8)
 #define SHA3_224_BLOCK_SIZE	(200 - 2 * SHA3_224_DIGEST_SIZE)
@@ -23,6 +26,14 @@
 #define SHA3_512_BLOCK_SIZE	(200 - 2 * SHA3_512_DIGEST_SIZE)
 #define SHA3_512_EXPORT_SIZE	SHA3_STATE_SIZE + SHA3_512_BLOCK_SIZE + 1
 
+/* SHAKE128 and SHAKE256 actually have variable output size, but this
+ * is needed for the kunit tests.
+ */
+#define SHAKE128_DEFAULT_SIZE	(128 / 8)
+#define SHAKE128_BLOCK_SIZE	(200 - 2 * SHAKE128_DEFAULT_SIZE)
+#define SHAKE256_DEFAULT_SIZE	(256 / 8)
+#define SHAKE256_BLOCK_SIZE	(200 - 2 * SHAKE256_DEFAULT_SIZE)
+
 #define SHA3_STATE_SIZE		200
 
 struct shash_desc;
@@ -31,6 +42,460 @@ struct sha3_state {
 	u64		st[SHA3_STATE_SIZE / 8];
 };
 
+/*
+ * The SHA3 context structure and state buffer.
+ *
+ * To avoid the need to byteswap when adding input and extracting output from
+ * the state array, the state array is kept in little-endian order most of the
+ * time, but is byteswapped to host-endian in order to perform the Keccak
+ * function and then byteswapped back again after.  On a LE machine, the
+ * byteswap step is a no-op.
+ */
+struct sha3_ctx {
+	struct sha3_state	state;
+	u8			block_size;	/* Block size in bytes */
+	u8			padding;	/* Padding byte */
+	u8			absorb_offset;	/* Next state byte to absorb into */
+	u8			squeeze_offset;	/* Next state byte to extract */
+	bool			end_marked;	/* T if end marker inserted */
+};
+
 int crypto_sha3_init(struct shash_desc *desc);
 
-#endif
+/**
+ * sha3_clear() - Explicitly clear the entire context
+ * @ctx: the context to clear
+ *
+ * Explicitly clear the entire context, including the type parameters; after
+ * this, the context must be fully initialised again.
+ *
+ * Return: None.
+ *
+ * Context: Any context.
+ */
+static inline void sha3_clear(struct sha3_ctx *ctx)
+{
+	memzero_explicit(ctx, sizeof(*ctx));
+}
+
+void sha3_update(struct sha3_ctx *ctx, const u8 *data, unsigned int len);
+void sha3_squeeze(struct sha3_ctx *ctx, u8 *out, size_t out_len);
+
+/*
+ * Context wrapper for SHA3-224.
+ */
+struct sha3_224_ctx {
+	struct sha3_ctx ctx;
+};
+
+/**
+ * sha3_224_init() - Set a SHA3 context for SHA3-224
+ * @ctx: the context to initialise
+ *
+ * Initialise a SHA3 context for the production of a SHA3-224 digest of a
+ * message.
+ *
+ * Return: None.
+ *
+ * Context: Any context.
+ */
+static inline void sha3_224_init(struct sha3_224_ctx *ctx)
+{
+	*ctx = (struct sha3_224_ctx){
+		.ctx.block_size	= SHA3_224_BLOCK_SIZE,
+		.ctx.padding	= 0x06,
+	};
+}
+
+/**
+ * sha3_224_update() - Update a SHA3-224 hash with message data
+ * @ctx: the context to update; must have been initialized
+ * @data: the message data
+ * @len: the data length in bytes
+ *
+ * This can be called any number of times to add data to the hash, performing
+ * the "keccak sponge absorbing" phase.
+ *
+ * Return: None.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+static inline void sha3_224_update(struct sha3_224_ctx *ctx, const u8 *data, unsigned int len)
+{
+	return sha3_update(&ctx->ctx, data, len);
+}
+
+/**
+ * sha3_224_final() - Finalise a SHA3-224 hash and extract the digest
+ * @ctx: The context to finalise; must have been initialised
+ * @out: Where to write the resulting message digest
+ *
+ * Finish the computation of a SHA3-224 hash and perform the "Keccak sponge
+ * squeezing" phase.  The digest is written to @out buffer and the context will
+ * be completely zeroed out.
+ *
+ * Return: None.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+static inline void sha3_224_final(struct sha3_224_ctx *ctx, u8 out[SHA3_224_DIGEST_SIZE])
+{
+	sha3_squeeze(&ctx->ctx, out, SHA3_224_DIGEST_SIZE);
+	sha3_clear(&ctx->ctx);
+}
+
+/*
+ * Context wrapper for SHA3-256.
+ */
+struct sha3_256_ctx {
+	struct sha3_ctx ctx;
+};
+
+/**
+ * sha3_256_init() - Set a SHA3 context for SHA3-256
+ * @ctx: the context to initialise
+ *
+ * Initialise a SHA3 context for the production of a SHA3-256 digest of a
+ * message.
+ *
+ * Return: None.
+ *
+ * Context: Any context.
+ */
+static inline void sha3_256_init(struct sha3_256_ctx *ctx)
+{
+	*ctx = (struct sha3_256_ctx){
+		.ctx.block_size	= SHA3_256_BLOCK_SIZE,
+		.ctx.padding	= 0x06,
+	};
+}
+
+/**
+ * sha3_256_update() - Update a SHA3-256 hash with message data
+ * @ctx: the context to update; must have been initialized
+ * @data: the message data
+ * @len: the data length in bytes
+ *
+ * This can be called any number of times to add data to the hash, performing
+ * the "keccak sponge absorbing" phase.
+ *
+ * Return: None.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+static inline void sha3_256_update(struct sha3_256_ctx *ctx, const u8 *data, unsigned int len)
+{
+	return sha3_update(&ctx->ctx, data, len);
+}
+
+/**
+ * sha3_256_final() - Finalise a SHA3-256 hash and extract the digest
+ * @ctx: The context to finalise; must have been initialised
+ * @out: Where to write the resulting message digest
+ *
+ * Finish the computation of a SHA3-256 hash and perform the "Keccak sponge
+ * squeezing" phase.  The digest is written to @out buffer and the context will
+ * be completely zeroed out.
+ *
+ * Return: None.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+static inline void sha3_256_final(struct sha3_256_ctx *ctx, u8 out[SHA3_256_DIGEST_SIZE])
+{
+	sha3_squeeze(&ctx->ctx, out, SHA3_256_DIGEST_SIZE);
+	sha3_clear(&ctx->ctx);
+}
+
+/*
+ * Context wrapper for SHA3-384.
+ */
+struct sha3_384_ctx {
+	struct sha3_ctx ctx;
+};
+
+/**
+ * sha3_384_init() - Set a SHA3 context for SHA3-384
+ * @ctx: the context to initialise
+ *
+ * Initialise a SHA3 context for the production of a SHA3-384 digest of a
+ * message.
+ *
+ * Return: None.
+ *
+ * Context: Any context.
+ */
+static inline void sha3_384_init(struct sha3_384_ctx *ctx)
+{
+	*ctx = (struct sha3_384_ctx){
+		.ctx.block_size	= SHA3_384_BLOCK_SIZE,
+		.ctx.padding	= 0x06,
+	};
+}
+
+/**
+ * sha3_384_update() - Update a SHA3-384 hash with message data
+ * @ctx: the context to update; must have been initialized
+ * @data: the message data
+ * @len: the data length in bytes
+ *
+ * This can be called any number of times to add data to the hash, performing
+ * the "keccak sponge absorbing" phase.
+ *
+ * Return: None.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+static inline void sha3_384_update(struct sha3_384_ctx *ctx, const u8 *data, unsigned int len)
+{
+	return sha3_update(&ctx->ctx, data, len);
+}
+
+/**
+ * sha3_384_final() - Finalise a SHA3-384 hash and extract the digest
+ * @ctx: The context to finalise; must have been initialised
+ * @out: Where to write the resulting message digest
+ *
+ * Finish the computation of a SHA3-384 hash and perform the "Keccak sponge
+ * squeezing" phase.  The digest is written to @out buffer and the context will
+ * be completely zeroed out.
+ *
+ * Return: None.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+static inline void sha3_384_final(struct sha3_384_ctx *ctx, u8 out[SHA3_384_DIGEST_SIZE])
+{
+	sha3_squeeze(&ctx->ctx, out, SHA3_384_DIGEST_SIZE);
+	sha3_clear(&ctx->ctx);
+}
+
+/*
+ * Context wrapper for SHA3-512.
+ */
+struct sha3_512_ctx {
+	struct sha3_ctx ctx;
+};
+
+/**
+ * sha3_512_init() - Set a SHA3 context for SHA3-512
+ * @ctx: the context to initialise
+ *
+ * Initialise a SHA3 context for the production of a SHA3-512 digest of a
+ * message.
+ *
+ * Return: None.
+ *
+ * Context: Any context.
+ */
+static inline void sha3_512_init(struct sha3_512_ctx *ctx)
+{
+	*ctx = (struct sha3_512_ctx){
+		.ctx.block_size	= SHA3_512_BLOCK_SIZE,
+		.ctx.padding	= 0x06,
+	};
+}
+
+/**
+ * sha3_512_update() - Update a SHA3-512 hash with message data
+ * @ctx: the context to update; must have been initialized
+ * @data: the message data
+ * @len: the data length in bytes
+ *
+ * This can be called any number of times to add data to the hash, performing
+ * the "keccak sponge absorbing" phase.
+ *
+ * Return: None.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+static inline void sha3_512_update(struct sha3_512_ctx *ctx, const u8 *data, unsigned int len)
+{
+	return sha3_update(&ctx->ctx, data, len);
+}
+
+/**
+ * sha3_512_final() - Finalise a SHA3-512 hash and extract the digest
+ * @ctx: The context to finalise; must have been initialised
+ * @out: Where to write the resulting message digest
+ *
+ * Finish the computation of a SHA3-512 hash and perform the "Keccak sponge
+ * squeezing" phase.  The digest is written to @out buffer and the context will
+ * be completely zeroed out.
+ *
+ * Return: None.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+static inline void sha3_512_final(struct sha3_512_ctx *ctx, u8 out[SHA3_512_DIGEST_SIZE])
+{
+	sha3_squeeze(&ctx->ctx, out, SHA3_512_DIGEST_SIZE);
+	sha3_clear(&ctx->ctx);
+}
+
+/*
+ * Context wrapper for SHAKE128.
+ */
+struct shake128_ctx {
+	struct sha3_ctx ctx;
+};
+
+/**
+ * shake128_init() - Set a SHA3 context for SHAKE128
+ * @ctx: The context to initialise
+ *
+ * Initialise a SHA3 context for the production of SHAKE128 output generation
+ * from a message.  The sha3_squeeze() function can be used to extract an
+ * arbitrary amount of data from the context.
+ *
+ * Context: Any context.
+ */
+static inline void shake128_init(struct shake128_ctx *ctx)
+{
+	*ctx = (struct shake128_ctx){
+		.ctx.block_size	= SHAKE128_BLOCK_SIZE,
+		.ctx.padding	= 0x1f,
+	};
+}
+
+/**
+ * shake128_update() - Update a SHAKE128 hash with message data
+ * @ctx: the context to update; must have been initialized
+ * @data: the message data
+ * @len: the data length in bytes
+ *
+ * This can be called any number of times to add data to the XOF state,
+ * performing the "keccak sponge absorbing" phase.
+ *
+ * Return: None.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+static inline void shake128_update(struct shake128_ctx *ctx, const u8 *data, unsigned int len)
+{
+	return sha3_update(&ctx->ctx, data, len);
+}
+
+/**
+ * shake128_squeeze() - Finalize a SHAKE128 digest of any type and extract the digest
+ * @ctx: the context to finalize; must have been initialized
+ * @out: Where to write the resulting message digest
+ * @out_size: The amount of digest to extract to @out in bytes
+ *
+ * Finish the computation of a SHAKE128 XOF and perform the "Keccak sponge
+ * squeezing" phase.  @out_size amount of digest is written to @out buffer.
+ *
+ * This may be called multiple times to extract continuations of the digest.
+ * Note that, a number of consecutive squeezes laid end-to-end will yield the
+ * same output as one big squeeze generating the same total amount of output.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+static inline void shake128_squeeze(struct shake128_ctx *ctx, u8 *out, size_t out_size)
+{
+	return sha3_squeeze(&ctx->ctx, out, out_size);
+}
+
+/**
+ * shake128_clear() - Explicitly clear the entire SHAKE128 context
+ * @ctx: the context to clear
+ *
+ * Explicitly clear the entire context; after this, the context must be
+ * initialised again.
+ *
+ * Return: None.
+ *
+ * Context: Any context.
+ */
+static inline void shake128_clear(struct shake128_ctx *ctx)
+{
+	sha3_clear(&ctx->ctx);
+}
+
+/*
+ * Context wrapper for SHAKE256.
+ */
+struct shake256_ctx {
+	struct sha3_ctx ctx;
+};
+
+/**
+ * shake256_init() - Set a SHA3 context for SHAKE256
+ * @ctx: The context to initialise
+ *
+ * Initialise a SHA3 context for the production of SHAKE256 output generation
+ * from a message.  The sha3_squeeze() function can be used to extract an
+ * arbitrary amount of data from the context.
+ *
+ * Context: Any context.
+ */
+static inline void shake256_init(struct shake256_ctx *ctx)
+{
+	*ctx = (struct shake256_ctx){
+		.ctx.block_size	= SHAKE256_BLOCK_SIZE,
+		.ctx.padding	= 0x1f,
+	};
+}
+
+/**
+ * shake256_update() - Update a SHAKE256 hash with message data
+ * @ctx: the context to update; must have been initialized
+ * @data: the message data
+ * @len: the data length in bytes
+ *
+ * This can be called any number of times to add data to the XOF state,
+ * performing the "keccak sponge absorbing" phase.
+ *
+ * Return: None.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+static inline void shake256_update(struct shake256_ctx *ctx, const u8 *data, unsigned int len)
+{
+	return sha3_update(&ctx->ctx, data, len);
+}
+
+/**
+ * shake256_squeeze() - Finalize a SHAKE256 digest of any type and extract the digest
+ * @ctx: the context to finalize; must have been initialized
+ * @out: Where to write the resulting message digest
+ * @out_size: The amount of digest to extract to @out in bytes
+ *
+ * Finish the computation of a SHAKE256 XOF and perform the "Keccak sponge
+ * squeezing" phase.  @out_size amount of digest is written to @out buffer.
+ *
+ * This may be called multiple times to extract continuations of the digest.
+ * Note that, a number of consecutive squeezes laid end-to-end will yield the
+ * same output as one big squeeze generating the same total amount of output.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+static inline void shake256_squeeze(struct shake256_ctx *ctx, u8 *out, size_t out_size)
+{
+	return sha3_squeeze(&ctx->ctx, out, out_size);
+}
+
+/**
+ * shake256_clear() - Explicitly clear the entire SHAKE256 context
+ * @ctx: the context to clear
+ *
+ * Explicitly clear the entire context; after this, the context must be
+ * initialised again.
+ *
+ * Return: None.
+ *
+ * Context: Any context.
+ */
+static inline void shake256_clear(struct shake256_ctx *ctx)
+{
+	sha3_clear(&ctx->ctx);
+}
+
+void sha3_224(const u8 *in, size_t in_len, u8 out[SHA3_224_DIGEST_SIZE]);
+void sha3_256(const u8 *in, size_t in_len, u8 out[SHA3_256_DIGEST_SIZE]);
+void sha3_384(const u8 *in, size_t in_len, u8 out[SHA3_384_DIGEST_SIZE]);
+void sha3_512(const u8 *in, size_t in_len, u8 out[SHA3_512_DIGEST_SIZE]);
+void shake128(const u8 *in, size_t in_len, u8 *out, size_t out_len);
+void shake256(const u8 *in, size_t in_len, u8 *out, size_t out_len);
+
+#endif /* __CRYPTO_SHA3_H__ */
diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig
index eea17e36a22b..1caf3fbe24bf 100644
--- a/lib/crypto/Kconfig
+++ b/lib/crypto/Kconfig
@@ -184,6 +184,13 @@ config CRYPTO_LIB_SHA512_ARCH
 	default y if SPARC64
 	default y if X86_64
 
+config CRYPTO_LIB_SHA3
+	tristate
+	help
+	  The SHA3 library functions.
+	  Select this if your module uses any of these functions from
+	  <crypto/sha3.h>.
+
 config CRYPTO_LIB_SM3
 	tristate
 
diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile
index bded351aeace..b7fa51bfeebb 100644
--- a/lib/crypto/Makefile
+++ b/lib/crypto/Makefile
@@ -268,6 +268,12 @@ endif # CONFIG_CRYPTO_LIB_SHA512_ARCH
 
 ################################################################################
 
+#obj-$(CONFIG_CRYPTO_LIB_SHA3) += libsha3.o
+#libsha3-y := sha3.o
+obj-$(CONFIG_CRYPTO_SHA3) += sha3.o
+
+################################################################################
+
 obj-$(CONFIG_MPILIB) += mpi/
 
 obj-$(CONFIG_CRYPTO_SELFTESTS_FULL)		+= simd.o
diff --git a/lib/crypto/sha3.c b/lib/crypto/sha3.c
new file mode 100644
index 000000000000..a8eaa25a837f
--- /dev/null
+++ b/lib/crypto/sha3.c
@@ -0,0 +1,529 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Cryptographic API.
+ *
+ * SHA-3, as specified in
+ * https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
+ *
+ * SHA-3 code by Jeff Garzik <jeff@garzik.org>
+ *               Ard Biesheuvel <ard.biesheuvel@linaro.org>
+ *		 David Howells <dhowells@redhat.com>
+ *
+ * See also Documentation/crypto/sha3.rst
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <crypto/sha3.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/unaligned.h>
+
+/*
+ * On some 32-bit architectures, such as h8300, GCC ends up using over 1 KB of
+ * stack if the round calculation gets inlined into the loop in
+ * sha3_keccakf_rounds_generic().  On the other hand, on 64-bit architectures
+ * with plenty of [64-bit wide] general purpose registers, not inlining it
+ * severely hurts performance.  So let's use 64-bitness as a heuristic to
+ * decide whether to inline or not.
+ */
+#ifdef CONFIG_64BIT
+#define SHA3_INLINE	inline
+#else
+#define SHA3_INLINE	noinline
+#endif
+
+#define SHA3_KECCAK_ROUNDS 24
+
+static const u64 sha3_keccakf_rndc[24] = {
+	0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL,
+	0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL,
+	0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL,
+	0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL,
+	0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL,
+	0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL,
+	0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL,
+	0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL
+};
+
+/*
+ * Perform a single round of Keccak mixing.
+ */
+static SHA3_INLINE void sha3_keccakf_one_round_generic(struct sha3_state *state)
+{
+	u64 *st = state->st;
+	u64 t[5], tt, bc[5];
+
+	/* Theta */
+	bc[0] = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20];
+	bc[1] = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21];
+	bc[2] = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22];
+	bc[3] = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23];
+	bc[4] = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24];
+
+	t[0] = bc[4] ^ rol64(bc[1], 1);
+	t[1] = bc[0] ^ rol64(bc[2], 1);
+	t[2] = bc[1] ^ rol64(bc[3], 1);
+	t[3] = bc[2] ^ rol64(bc[4], 1);
+	t[4] = bc[3] ^ rol64(bc[0], 1);
+
+	st[0] ^= t[0];
+
+	/* Rho Pi */
+	tt = st[1];
+	st[ 1] = rol64(st[ 6] ^ t[1], 44);
+	st[ 6] = rol64(st[ 9] ^ t[4], 20);
+	st[ 9] = rol64(st[22] ^ t[2], 61);
+	st[22] = rol64(st[14] ^ t[4], 39);
+	st[14] = rol64(st[20] ^ t[0], 18);
+	st[20] = rol64(st[ 2] ^ t[2], 62);
+	st[ 2] = rol64(st[12] ^ t[2], 43);
+	st[12] = rol64(st[13] ^ t[3], 25);
+	st[13] = rol64(st[19] ^ t[4],  8);
+	st[19] = rol64(st[23] ^ t[3], 56);
+	st[23] = rol64(st[15] ^ t[0], 41);
+	st[15] = rol64(st[ 4] ^ t[4], 27);
+	st[ 4] = rol64(st[24] ^ t[4], 14);
+	st[24] = rol64(st[21] ^ t[1],  2);
+	st[21] = rol64(st[ 8] ^ t[3], 55);
+	st[ 8] = rol64(st[16] ^ t[1], 45);
+	st[16] = rol64(st[ 5] ^ t[0], 36);
+	st[ 5] = rol64(st[ 3] ^ t[3], 28);
+	st[ 3] = rol64(st[18] ^ t[3], 21);
+	st[18] = rol64(st[17] ^ t[2], 15);
+	st[17] = rol64(st[11] ^ t[1], 10);
+	st[11] = rol64(st[ 7] ^ t[2],  6);
+	st[ 7] = rol64(st[10] ^ t[0],  3);
+	st[10] = rol64(    tt ^ t[1],  1);
+
+	/* Chi */
+	bc[ 0] = ~st[ 1] & st[ 2];
+	bc[ 1] = ~st[ 2] & st[ 3];
+	bc[ 2] = ~st[ 3] & st[ 4];
+	bc[ 3] = ~st[ 4] & st[ 0];
+	bc[ 4] = ~st[ 0] & st[ 1];
+	st[ 0] ^= bc[ 0];
+	st[ 1] ^= bc[ 1];
+	st[ 2] ^= bc[ 2];
+	st[ 3] ^= bc[ 3];
+	st[ 4] ^= bc[ 4];
+
+	bc[ 0] = ~st[ 6] & st[ 7];
+	bc[ 1] = ~st[ 7] & st[ 8];
+	bc[ 2] = ~st[ 8] & st[ 9];
+	bc[ 3] = ~st[ 9] & st[ 5];
+	bc[ 4] = ~st[ 5] & st[ 6];
+	st[ 5] ^= bc[ 0];
+	st[ 6] ^= bc[ 1];
+	st[ 7] ^= bc[ 2];
+	st[ 8] ^= bc[ 3];
+	st[ 9] ^= bc[ 4];
+
+	bc[ 0] = ~st[11] & st[12];
+	bc[ 1] = ~st[12] & st[13];
+	bc[ 2] = ~st[13] & st[14];
+	bc[ 3] = ~st[14] & st[10];
+	bc[ 4] = ~st[10] & st[11];
+	st[10] ^= bc[ 0];
+	st[11] ^= bc[ 1];
+	st[12] ^= bc[ 2];
+	st[13] ^= bc[ 3];
+	st[14] ^= bc[ 4];
+
+	bc[ 0] = ~st[16] & st[17];
+	bc[ 1] = ~st[17] & st[18];
+	bc[ 2] = ~st[18] & st[19];
+	bc[ 3] = ~st[19] & st[15];
+	bc[ 4] = ~st[15] & st[16];
+	st[15] ^= bc[ 0];
+	st[16] ^= bc[ 1];
+	st[17] ^= bc[ 2];
+	st[18] ^= bc[ 3];
+	st[19] ^= bc[ 4];
+
+	bc[ 0] = ~st[21] & st[22];
+	bc[ 1] = ~st[22] & st[23];
+	bc[ 2] = ~st[23] & st[24];
+	bc[ 3] = ~st[24] & st[20];
+	bc[ 4] = ~st[20] & st[21];
+	st[20] ^= bc[ 0];
+	st[21] ^= bc[ 1];
+	st[22] ^= bc[ 2];
+	st[23] ^= bc[ 3];
+	st[24] ^= bc[ 4];
+}
+
+static void sha3_keccakf_rounds_generic(struct sha3_state *state)
+{
+	for (int round = 0; round < SHA3_KECCAK_ROUNDS; round++) {
+		sha3_keccakf_one_round_generic(state);
+		/* Iota */
+		state->st[0] ^= sha3_keccakf_rndc[round];
+	}
+}
+
+/*
+ * Byteswap the state buckets to CPU-endian if we're not on a little-endian
+ * machine for the duration of the Keccak mixing function.  Note that these
+ * loops are no-ops on LE machines and will be optimised away.
+ */
+static void sha3_keccakf_generic(struct sha3_state *state)
+{
+	for (int  i = 0; i < ARRAY_SIZE(state->st); i++)
+		cpu_to_le64s(&state->st[i]);
+
+	sha3_keccakf_rounds_generic(state);
+
+	for (int  i = 0; i < ARRAY_SIZE(state->st); i++)
+		le64_to_cpus(&state->st[i]);
+}
+
+static void sha3_absorb_block_generic(struct sha3_ctx *ctx, const u8 *data)
+{
+	struct sha3_state *state = &ctx->state;
+	unsigned int bsize = ctx->block_size;
+
+	for (int i = 0; i < bsize / 8; i++)
+		state->st[i] ^= get_unaligned((u64 *)(data + 8 * i));
+	sha3_keccakf_generic(state);
+}
+
+/*
+ * Perform rounds of XOR'ing whole blocks of data into the state buffer and
+ * then performing a keccak mix step.
+ */
+static void sha3_absorb_blocks_generic(struct sha3_ctx *ctx,
+				       const u8 *data, size_t nblocks)
+{
+	do {
+		sha3_absorb_block_generic(ctx, data);
+		data += ctx->block_size;
+	} while (--nblocks);
+}
+
+#ifdef CONFIG_CRYPTO_LIB_SHA3_ARCH
+#include "sha3.h" /* $(SRCARCH)/sha3.h */
+#else
+#define sha3_keccakf		sha3_keccakf_generic
+#define sha3_absorb_blocks	sha3_absorb_blocks_generic
+#endif
+
+/*
+ * XOR in partial data that's insufficient to fill a whole block.
+ */
+static void sha3_absorb_xorle(struct sha3_ctx *ctx, const u8 *data,
+			      unsigned int partial, unsigned int len)
+{
+	u8 *buf = (u8 *)ctx->state.st;
+
+	buf += partial;
+	for (int i = 0; i < len; i++)
+		*buf++ ^= *data++;
+}
+
+/**
+ * sha3_update() - Update a SHA3 context of any type with message data
+ * @ctx: the context to update; must have been initialized
+ * @data: the message data
+ * @len: the data length in bytes
+ *
+ * This can be called any number of times to perform the "keccak sponge
+ * absorbing" phase.
+ *
+ * Return: None.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+void sha3_update(struct sha3_ctx *ctx, const u8 *data, unsigned int len)
+{
+	unsigned int absorb_offset = ctx->absorb_offset;
+	unsigned int bsize = ctx->block_size;
+
+	WARN_ON_ONCE(ctx->end_marked);
+
+	if (absorb_offset && absorb_offset + len >= bsize) {
+		sha3_absorb_xorle(ctx, data, absorb_offset, bsize - absorb_offset);
+		len  -= bsize - absorb_offset;
+		data += bsize - absorb_offset;
+		sha3_keccakf(&ctx->state);
+		ctx->absorb_offset = 0;
+	}
+
+	if (len >= bsize) {
+		size_t nblocks = len / bsize;
+
+		sha3_absorb_blocks(ctx, data, nblocks);
+		data += nblocks * bsize;
+		len  -= nblocks * bsize;
+	}
+
+	if (len) {
+		sha3_absorb_xorle(ctx, data, ctx->absorb_offset, len);
+		ctx->absorb_offset += len;
+	}
+}
+EXPORT_SYMBOL_GPL(sha3_update);
+
+/**
+ * sha3_squeeze() - Finalize a SHA3 digest of any type and extract the digest
+ * @ctx: the context to finalize; must have been initialized
+ * @out: Where to write the resulting message digest
+ * @out_size: The amount of digest to extract to @out
+ *
+ * Finish the computation of a SHA3 message digest of any type and perform the
+ * "Keccak sponge squeezing" phase.  @out_size amount of digest is written to
+ * @out buffer.
+ *
+ * This may be called multiple times to extract continuations of the digest.
+ * Note that, for example, two consecutive 16-byte squeezes laid end-to-end
+ * will yield the same as one 32-byte squeeze.
+ *
+ * Return: None.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+void sha3_squeeze(struct sha3_ctx *ctx, u8 *out, size_t out_size)
+{
+	unsigned int squeeze_offset = ctx->squeeze_offset;
+	unsigned int bsize = ctx->block_size;
+	u8 *p = (u8 *)ctx->state.st, end_marker = 0x80;
+
+	if (!ctx->end_marked) {
+		sha3_absorb_xorle(ctx, &ctx->padding, ctx->absorb_offset, 1);
+		sha3_absorb_xorle(ctx, &end_marker, bsize - 1, 1);
+		ctx->end_marked = true;
+	}
+
+	for (;;) {
+		if (squeeze_offset == 0)
+			sha3_keccakf(&ctx->state);
+
+		unsigned int part = umin(out_size, bsize - squeeze_offset);
+
+		if (part > 0) {
+			memcpy(out, p + squeeze_offset, part);
+			out_size -= part;
+			out += part;
+			squeeze_offset += part;
+		}
+		if (!out_size)
+			break;
+		if (squeeze_offset >= bsize)
+			squeeze_offset = 0;
+	}
+
+	ctx->squeeze_offset = squeeze_offset;
+}
+EXPORT_SYMBOL_GPL(sha3_squeeze);
+
+/**
+ * sha3_224() - Convenience wrapper to digest a simple buffer as SHA3-224
+ * @in: The data to be digested
+ * @in_len: The amount of data to be digested in bytes
+ * @out: The buffer into which the digest will be stored (size not checked)
+ *
+ * Convenience wrapper to initialise a SHA3 context for SHA-224, add the input
+ * data to it, finalise it, extract 28 bytes of digest and clear the context.
+ *
+ * Return: None.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+void sha3_224(const u8 *in, size_t in_len, u8 out[SHA3_224_DIGEST_SIZE])
+{
+	struct sha3_224_ctx ctx;
+
+	sha3_224_init(&ctx);
+	sha3_224_update(&ctx, in, in_len);
+	sha3_224_final(&ctx, out);
+}
+EXPORT_SYMBOL(sha3_224);
+
+/**
+ * sha3_256() - Convenience wrapper to digest a simple buffer as SHA3-256
+ * @in: The data to be digested
+ * @in_len: The amount of data to be digested in bytes
+ * @out: The buffer into which the digest will be stored (size not checked)
+ *
+ * Convenience wrapper to initialise a SHA3 context for SHA-256, add the input
+ * data to it, finalise it, extract 32 bytes of digest and clear the context.
+ *
+ * Return: None.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+void sha3_256(const u8 *in, size_t in_len, u8 out[SHA3_256_DIGEST_SIZE])
+{
+	struct sha3_256_ctx ctx;
+
+	sha3_256_init(&ctx);
+	sha3_256_update(&ctx, in, in_len);
+	sha3_256_final(&ctx, out);
+}
+EXPORT_SYMBOL(sha3_256);
+
+/**
+ * sha3_384() - Convenience wrapper to digest a simple buffer as SHA3-384
+ * @in: The data to be digested
+ * @in_len: The amount of data to be digested in bytes
+ * @out: The buffer into which the digest will be stored (size not checked)
+ *
+ * Convenience wrapper to initialise a SHA3 context for SHA-384, add the input
+ * data to it, finalise it, extract 48 bytes of digest and clear the context.
+ *
+ * Return: None.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+void sha3_384(const u8 *in, size_t in_len, u8 out[SHA3_384_DIGEST_SIZE])
+{
+	struct sha3_384_ctx ctx;
+
+	sha3_384_init(&ctx);
+	sha3_384_update(&ctx, in, in_len);
+	sha3_384_final(&ctx, out);
+}
+EXPORT_SYMBOL(sha3_384);
+
+/**
+ * sha3_512() - Convenience wrapper to digest a simple buffer as SHA3-512
+ * @in: The data to be digested in bytes
+ * @in_len: The amount of data to be digested in bytes
+ * @out: The buffer into which the digest will be stored (size not checked)
+ *
+ * Convenience wrapper to initialise a SHA3 context for SHA-512, add the input
+ * data to it, finalise it, extract 64 bytes of digest and clear the context.
+ *
+ * Return: None.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+void sha3_512(const u8 *in, size_t in_len, u8 out[SHA3_512_DIGEST_SIZE])
+{
+	struct sha3_512_ctx ctx;
+
+	sha3_512_init(&ctx);
+	sha3_512_update(&ctx, in, in_len);
+	sha3_512_final(&ctx, out);
+}
+EXPORT_SYMBOL(sha3_512);
+
+/**
+ * shake128() - Convenience wrapper to apply SHAKE128 to a simple buffer
+ * @in: The input data to be used
+ * @in_len: The amount of input data in bytes
+ * @out: The buffer in which to store the output
+ * @out_len: The amount of output to store in bytes (variable length)
+ *
+ * Convenience wrapper to initialise a SHA3 context for SHAKE128, add the input
+ * data to it, finalise it, extract the requested amount of output and clear
+ * the context.
+ *
+ * Return: None.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+void shake128(const u8 *in, size_t in_len, u8 *out, size_t out_len)
+{
+	struct shake128_ctx ctx;
+
+	shake128_init(&ctx);
+	shake128_update(&ctx, in, in_len);
+	shake128_squeeze(&ctx, out, out_len);
+	shake128_clear(&ctx);
+}
+EXPORT_SYMBOL(shake128);
+
+/**
+ * shake256() - Convenience wrapper to apply SHAKE256 to a simple buffer
+ * @in: The input data to be used
+ * @in_len: The amount of input data in bytes
+ * @out: The buffer in which to store the output
+ * @out_len: The amount of output to store in bytes (variable length)
+ *
+ * Convenience wrapper to initialise a SHA3 context for SHAKE128, add the input
+ * data to it, finalise it, extract the requested amount of output and clear
+ * the context.
+ *
+ * Return: None.
+ *
+ * Context: May use the FPU/Vector unit registers.
+ */
+void shake256(const u8 *in, size_t in_len, u8 *out, size_t out_len)
+{
+	struct shake256_ctx ctx;
+
+	shake256_init(&ctx);
+	shake256_update(&ctx, in, in_len);
+	shake256_squeeze(&ctx, out, out_len);
+	shake256_clear(&ctx);
+}
+EXPORT_SYMBOL(shake256);
+
+/*
+ * Do a quick test using SHAKE256 and a 200 byte digest.
+ */
+static const u8 sha3_sample[] __initconst =
+	"The quick red fox jumped over the lazy brown dog!\n"
+	"The quick red fox jumped over the lazy brown dog!\n"
+	"The quick red fox jumped over the lazy brown dog!\n"
+	"The quick red fox jumped over the lazy brown dog!\n";
+
+static const u8 sha3_sample_shake256_200[] __initconst = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
+	0xab, 0x06, 0xd4, 0xf9, 0x8b, 0xfd, 0xb2, 0xc4, 0xfe, 0xf1, 0xcc, 0xe2,
+	0x40, 0x45, 0xdd, 0x15, 0xcb, 0xdd, 0x02, 0x8d, 0xb7, 0x9f, 0x1e, 0x67,
+	0xd6, 0x7f, 0x98, 0x5e, 0x1b, 0x19, 0xf8, 0x01, 0x43, 0x82, 0xcb, 0xd8,
+	0x5d, 0x21, 0x64, 0xa8, 0x80, 0xc9, 0x22, 0xe5, 0x07, 0xaf, 0xe2, 0x5d,
+	0xcd, 0xc6, 0x23, 0x36, 0x2b, 0xc7, 0xc7, 0x7d, 0x09, 0x9d, 0x68, 0x05,
+	0xe4, 0x62, 0x63, 0x1b, 0x67, 0xbc, 0xf8, 0x95, 0x07, 0xd2, 0xe4, 0xd0,
+	0xba, 0xa2, 0x67, 0xf5, 0xe3, 0x15, 0xbc, 0x85, 0xa1, 0x50, 0xd6, 0x6f,
+	0x6f, 0xd4, 0x54, 0x4c, 0x3f, 0x4f, 0xe5, 0x1f, 0xb7, 0x00, 0x27, 0xfc,
+	0x15, 0x33, 0xc2, 0xf9, 0xb3, 0x4b, 0x9e, 0x81, 0xe5, 0x96, 0xbe, 0x05,
+	0x6c, 0xac, 0xf9, 0x9f, 0x65, 0x36, 0xbb, 0x11, 0x47, 0x6d, 0xf6, 0x8f,
+	0x9f, 0xa2, 0x77, 0x37, 0x3b, 0x18, 0x77, 0xcf, 0x65, 0xc5, 0xa1, 0x7e,
+	0x2c, 0x0e, 0x71, 0xf0, 0x4d, 0x18, 0x67, 0xb9, 0xc4, 0x8c, 0x64, 0x3b,
+	0x4b, 0x45, 0xea, 0x16, 0xb2, 0x4a, 0xc5, 0xf5, 0x85, 0xdc, 0xd2, 0xd9,
+	0x13, 0x77, 0xb3, 0x19, 0xd9, 0x8c, 0x9f, 0x28, 0xe7, 0x64, 0x91, 0x0f,
+	0x6f, 0x32, 0xbf, 0xa8, 0xa8, 0xa3, 0xff, 0x99, 0x0e, 0x0b, 0x62, 0x50,
+	0xf8, 0x3a, 0xc2, 0xf5, 0x98, 0x21, 0xeb, 0x9d, 0xe8, 0x45, 0xf4, 0x46,
+	0x1e, 0x8b, 0xbd, 0x10, 0x59, 0x2c, 0x87, 0xe2,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
+};
+
+static int __init sha3_mod_init(void)
+{
+#define out_len 200
+	u8 out[8 + out_len + 8] = {};
+
+#ifdef sha3_mod_init_arch
+	sha3_mod_init_arch();
+#endif
+
+	BUILD_BUG_ON(sizeof(out) != sizeof(sha3_sample_shake256_200));
+
+	shake256(sha3_sample, sizeof(sha3_sample) - 1, out + 8, out_len);
+
+	if (memcmp(out, sha3_sample_shake256_200,
+		   sizeof(sha3_sample_shake256_200)) != 0) {
+		pr_err("SHAKE256(200) failed\n");
+		for (int i = 0; i < out_len;) {
+			int part = min(out_len - i, 32);
+
+			pr_err("%*phN\n", part, out + i);
+			i += part;
+		}
+		return -EBADMSG;
+	}
+	return 0;
+}
+subsys_initcall(sha3_mod_init);
+
+#ifdef sha3_mod_init_arch
+static void __exit sha3_mod_exit(void)
+{
+}
+module_exit(sha3_mod_exit);
+#endif
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SHA-3 Secure Hash Algorithm");


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 4/8] lib/crypto: Move the SHA3 Iota transform into the single round function
  2025-09-26 14:19 [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto David Howells
                   ` (2 preceding siblings ...)
  2025-09-26 14:19 ` [PATCH v3 3/8] lib/crypto: Add SHA3-224, SHA3-256, SHA3-384, SHA-512, SHAKE128, SHAKE256 David Howells
@ 2025-09-26 14:19 ` David Howells
  2025-09-26 14:19 ` [PATCH v3 5/8] lib/crypto: Add SHA3 kunit tests David Howells
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 27+ messages in thread
From: David Howells @ 2025-09-26 14:19 UTC (permalink / raw)
  Cc: David Howells, Eric Biggers, Jason A . Donenfeld, Ard Biesheuvel,
	Herbert Xu, Stephan Mueller, linux-crypto, linux-kernel

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
---
 lib/crypto/sha3.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/lib/crypto/sha3.c b/lib/crypto/sha3.c
index a8eaa25a837f..227d45bd9680 100644
--- a/lib/crypto/sha3.c
+++ b/lib/crypto/sha3.c
@@ -48,7 +48,8 @@ static const u64 sha3_keccakf_rndc[24] = {
 /*
  * Perform a single round of Keccak mixing.
  */
-static SHA3_INLINE void sha3_keccakf_one_round_generic(struct sha3_state *state)
+static SHA3_INLINE void sha3_keccakf_one_round_generic(struct sha3_state *state,
+						       int round)
 {
 	u64 *st = state->st;
 	u64 t[5], tt, bc[5];
@@ -150,15 +151,15 @@ static SHA3_INLINE void sha3_keccakf_one_round_generic(struct sha3_state *state)
 	st[22] ^= bc[ 2];
 	st[23] ^= bc[ 3];
 	st[24] ^= bc[ 4];
+
+	/* Iota */
+	state->st[0] ^= sha3_keccakf_rndc[round];
 }
 
 static void sha3_keccakf_rounds_generic(struct sha3_state *state)
 {
-	for (int round = 0; round < SHA3_KECCAK_ROUNDS; round++) {
-		sha3_keccakf_one_round_generic(state);
-		/* Iota */
-		state->st[0] ^= sha3_keccakf_rndc[round];
-	}
+	for (int round = 0; round < SHA3_KECCAK_ROUNDS; round++)
+		sha3_keccakf_one_round_generic(state, round);
 }
 
 /*


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 5/8] lib/crypto: Add SHA3 kunit tests
  2025-09-26 14:19 [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto David Howells
                   ` (3 preceding siblings ...)
  2025-09-26 14:19 ` [PATCH v3 4/8] lib/crypto: Move the SHA3 Iota transform into the single round function David Howells
@ 2025-09-26 14:19 ` David Howells
  2025-10-01 16:04   ` Eric Biggers
  2025-09-26 14:19 ` [PATCH v3 6/8] crypto/sha3: Use lib/crypto/sha3 David Howells
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 27+ messages in thread
From: David Howells @ 2025-09-26 14:19 UTC (permalink / raw)
  Cc: David Howells, Eric Biggers, Jason A . Donenfeld, Ard Biesheuvel,
	Herbert Xu, Stephan Mueller, linux-crypto, linux-kernel

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 to be able to generate SHAKE hashes
because Python's hashlib requires the output digest size supplying for
those two algorithms as they produce arbitrary length digests.

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
---
 lib/crypto/tests/Kconfig            |  12 +
 lib/crypto/tests/Makefile           |   1 +
 lib/crypto/tests/sha3_kunit.c       | 338 ++++++++++++++++++++++++++++
 lib/crypto/tests/sha3_testvecs.h    | 231 +++++++++++++++++++
 scripts/crypto/gen-hash-testvecs.py |   8 +-
 5 files changed, 588 insertions(+), 2 deletions(-)
 create mode 100644 lib/crypto/tests/sha3_kunit.c
 create mode 100644 lib/crypto/tests/sha3_testvecs.h

diff --git a/lib/crypto/tests/Kconfig b/lib/crypto/tests/Kconfig
index 578af717e13a..becc781352b1 100644
--- a/lib/crypto/tests/Kconfig
+++ b/lib/crypto/tests/Kconfig
@@ -72,6 +72,18 @@ config CRYPTO_LIB_SHA512_KUNIT_TEST
 	  KUnit tests for the SHA-384 and SHA-512 cryptographic hash functions
 	  and their corresponding HMACs.
 
+config CRYPTO_LIB_SHA3_KUNIT_TEST
+	tristate "KUnit tests for SHA-3" if !KUNIT_ALL_TESTS
+	depends on KUNIT
+	default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS
+	select CRYPTO_LIB_BENCHMARK_VISIBLE
+	select CRYPTO_LIB_SHA3
+	help
+	  KUnit tests for the SHA3 cryptographic hash functions, including
+	  SHA3-224, SHA3-256, SHA3-386, SHA3-512, SHAKE128 and SHAKE256.  Note
+	  that whilst the SHAKE* hash functions can support arbitrary-length
+	  digests, these tests only check the nominal digest sizes for now.
+
 config CRYPTO_LIB_BENCHMARK_VISIBLE
 	bool
 
diff --git a/lib/crypto/tests/Makefile b/lib/crypto/tests/Makefile
index a71fad19922b..9c61b29ac4ca 100644
--- a/lib/crypto/tests/Makefile
+++ b/lib/crypto/tests/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_CRYPTO_LIB_POLY1305_KUNIT_TEST) += poly1305_kunit.o
 obj-$(CONFIG_CRYPTO_LIB_SHA1_KUNIT_TEST) += sha1_kunit.o
 obj-$(CONFIG_CRYPTO_LIB_SHA256_KUNIT_TEST) += sha224_kunit.o sha256_kunit.o
 obj-$(CONFIG_CRYPTO_LIB_SHA512_KUNIT_TEST) += sha384_kunit.o sha512_kunit.o
+obj-$(CONFIG_CRYPTO_LIB_SHA3_KUNIT_TEST) += sha3_kunit.o
diff --git a/lib/crypto/tests/sha3_kunit.c b/lib/crypto/tests/sha3_kunit.c
new file mode 100644
index 000000000000..ed31cf37018d
--- /dev/null
+++ b/lib/crypto/tests/sha3_kunit.c
@@ -0,0 +1,338 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ */
+#include <crypto/sha3.h>
+#include "sha3_testvecs.h"
+
+#define HASH		sha3_256
+#define HASH_CTX	sha3_256_ctx
+#define HASH_SIZE	SHA3_256_DIGEST_SIZE
+#define HASH_INIT	sha3_256_init
+#define HASH_UPDATE	sha3_256_update
+#define HASH_FINAL	sha3_256_final
+#include "hash-test-template.h"
+
+static const u8 test_sha3_sample[] =
+	"The quick red fox jumped over the lazy brown dog!\n"
+	"The quick red fox jumped over the lazy brown dog!\n"
+	"The quick red fox jumped over the lazy brown dog!\n"
+	"The quick red fox jumped over the lazy brown dog!\n";
+
+static const u8 test_sha3_224[8 + SHA3_224_DIGEST_SIZE + 8] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
+	0xd6, 0xe8, 0xd8, 0x80, 0xfa, 0x42, 0x80, 0x70,
+	0x7e, 0x7f, 0xd7, 0xd2, 0xd7, 0x7a, 0x35, 0x65,
+	0xf0, 0x0b, 0x4f, 0x9f, 0x2a, 0x33, 0xca, 0x0a,
+	0xef, 0xa6, 0x4c, 0xb8,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
+};
+
+static const u8 test_sha3_256[8 + SHA3_256_DIGEST_SIZE + 8] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
+	0xdb, 0x3b, 0xb0, 0xb8, 0x8d, 0x15, 0x78, 0xe5,
+	0x78, 0x76, 0x8e, 0x39, 0x7e, 0x89, 0x86, 0xb9,
+	0x14, 0x3a, 0x1e, 0xe7, 0x96, 0x7c, 0xf3, 0x25,
+	0x70, 0xbd, 0xc3, 0xa9, 0xae, 0x63, 0x71, 0x1d,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
+};
+
+static const u8 test_sha3_384[8 + SHA3_384_DIGEST_SIZE + 8] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
+	0x2d, 0x4b, 0x29, 0x85, 0x19, 0x94, 0xaa, 0x31,
+	0x9b, 0x04, 0x9d, 0x6e, 0x79, 0x66, 0xc7, 0x56,
+	0x8a, 0x2e, 0x99, 0x84, 0x06, 0xcf, 0x10, 0x2d,
+	0xec, 0xf0, 0x03, 0x04, 0x1f, 0xd5, 0x99, 0x63,
+	0x2f, 0xc3, 0x2b, 0x0d, 0xd9, 0x45, 0xf7, 0xbb,
+	0x0a, 0xc3, 0x46, 0xab, 0xfe, 0x4d, 0x94, 0xc2,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
+};
+
+static const u8 test_sha3_512[8 + SHA3_512_DIGEST_SIZE + 8] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
+	0xdd, 0x71, 0x3b, 0x44, 0xb6, 0x6c, 0xd7, 0x78,
+	0xe7, 0x93, 0xa1, 0x4c, 0xd7, 0x24, 0x16, 0xf1,
+	0xfd, 0xa2, 0x82, 0x4e, 0xed, 0x59, 0xe9, 0x83,
+	0x15, 0x38, 0x89, 0x7d, 0x39, 0x17, 0x0c, 0xb2,
+	0xcf, 0x12, 0x80, 0x78, 0xa1, 0x78, 0x41, 0xeb,
+	0xed, 0x21, 0x4c, 0xa4, 0x4a, 0x5f, 0x30, 0x1a,
+	0x70, 0x98, 0x4f, 0x14, 0xa2, 0xd1, 0x64, 0x1b,
+	0xc2, 0x0a, 0xff, 0x3b, 0xe8, 0x26, 0x41, 0x8f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
+};
+
+static const u8 test_shake128[8 + SHAKE128_DEFAULT_SIZE + 8] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
+	0x41, 0xd6, 0xb8, 0x9c, 0xf8, 0xe8, 0x54, 0xf2,
+	0x5c, 0xde, 0x51, 0x12, 0xaf, 0x9e, 0x0d, 0x91,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
+};
+
+static const u8 test_shake256[8 + SHAKE256_DEFAULT_SIZE + 8] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
+	0xab, 0x06, 0xd4, 0xf9, 0x8b, 0xfd, 0xb2, 0xc4,
+	0xfe, 0xf1, 0xcc, 0xe2, 0x40, 0x45, 0xdd, 0x15,
+	0xcb, 0xdd, 0x02, 0x8d, 0xb7, 0x9f, 0x1e, 0x67,
+	0xd6, 0x7f, 0x98, 0x5e, 0x1b, 0x19, 0xf8, 0x01,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
+};
+
+static void test_sha3_224_basic(struct kunit *test)
+{
+	u8 out[8 + SHA3_224_DIGEST_SIZE + 8];
+
+	BUILD_BUG_ON(sizeof(out) != sizeof(test_sha3_224));
+
+	memset(out, 0, sizeof(out));
+	sha3_224(test_sha3_sample, sizeof(test_sha3_sample) - 1, out + 8);
+
+	KUNIT_ASSERT_MEMEQ_MSG(test, out, test_sha3_224, sizeof(test_sha3_224),
+			       "SHA3-224 gives wrong output");
+}
+
+static void test_sha3_256_basic(struct kunit *test)
+{
+	u8 out[8 + SHA3_256_DIGEST_SIZE + 8];
+
+	BUILD_BUG_ON(sizeof(out) != sizeof(test_sha3_256));
+
+	memset(out, 0, sizeof(out));
+	sha3_256(test_sha3_sample, sizeof(test_sha3_sample) - 1, out + 8);
+
+	KUNIT_ASSERT_MEMEQ_MSG(test, out, test_sha3_256, sizeof(test_sha3_256),
+			       "SHA3-256 gives wrong output");
+}
+
+static void test_sha3_384_basic(struct kunit *test)
+{
+	u8 out[8 + SHA3_384_DIGEST_SIZE + 8];
+
+	BUILD_BUG_ON(sizeof(out) != sizeof(test_sha3_384));
+
+	memset(out, 0, sizeof(out));
+	sha3_384(test_sha3_sample, sizeof(test_sha3_sample) - 1, out + 8);
+
+	KUNIT_ASSERT_MEMEQ_MSG(test, out, test_sha3_384, sizeof(test_sha3_384),
+			       "SHA3-384 gives wrong output");
+}
+
+static void test_sha3_512_basic(struct kunit *test)
+{
+	u8 out[8 + SHA3_512_DIGEST_SIZE + 8];
+
+	BUILD_BUG_ON(sizeof(out) != sizeof(test_sha3_512));
+
+	memset(out, 0, sizeof(out));
+	sha3_512(test_sha3_sample, sizeof(test_sha3_sample) - 1, out + 8);
+
+	KUNIT_ASSERT_MEMEQ_MSG(test, out, test_sha3_512, sizeof(test_sha3_512),
+			       "SHA3-512 gives wrong output");
+}
+
+static void test_shake128_basic(struct kunit *test)
+{
+	u8 out[8 + SHAKE128_DEFAULT_SIZE + 8];
+
+	BUILD_BUG_ON(sizeof(out) != sizeof(test_shake128));
+
+	memset(out, 0, sizeof(out));
+	shake128(test_sha3_sample, sizeof(test_sha3_sample) - 1,
+		 out + 8, sizeof(out) - 16);
+
+	KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake128, sizeof(test_shake128),
+			       "SHAKE128 gives wrong output");
+}
+
+static void test_shake256_basic(struct kunit *test)
+{
+	u8 out[8 + SHAKE256_DEFAULT_SIZE + 8];
+
+	BUILD_BUG_ON(sizeof(out) != sizeof(test_shake256));
+
+	memset(out, 0, sizeof(out));
+	shake256(test_sha3_sample, sizeof(test_sha3_sample) - 1,
+		 out + 8, sizeof(out) - 16);
+
+	KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256, sizeof(test_shake256),
+			       "SHAKE256 gives wrong output");
+}
+
+/*
+ * Usable NIST tests.
+ *
+ * From: https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/example-values
+ */
+static const u8 test_nist_1600_sample[] = {
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3
+};
+
+static const u8 test_shake128_nist_0[] = {
+	0x7f, 0x9c, 0x2b, 0xa4, 0xe8, 0x8f, 0x82, 0x7d,
+	0x61, 0x60, 0x45, 0x50, 0x76, 0x05, 0x85, 0x3e
+};
+
+static const u8 test_shake128_nist_1600[] = {
+	0x13, 0x1a, 0xb8, 0xd2, 0xb5, 0x94, 0x94, 0x6b,
+	0x9c, 0x81, 0x33, 0x3f, 0x9b, 0xb6, 0xe0, 0xce,
+};
+
+static const u8 test_shake256_nist_0[] = {
+	0x46, 0xb9, 0xdd, 0x2b, 0x0b, 0xa8, 0x8d, 0x13,
+	0x23, 0x3b, 0x3f, 0xeb, 0x74, 0x3e, 0xeb, 0x24,
+	0x3f, 0xcd, 0x52, 0xea, 0x62, 0xb8, 0x1b, 0x82,
+	0xb5, 0x0c, 0x27, 0x64, 0x6e, 0xd5, 0x76, 0x2f
+};
+
+static const u8 test_shake256_nist_1600[] = {
+	0xcd, 0x8a, 0x92, 0x0e, 0xd1, 0x41, 0xaa, 0x04,
+	0x07, 0xa2, 0x2d, 0x59, 0x28, 0x86, 0x52, 0xe9,
+	0xd9, 0xf1, 0xa7, 0xee, 0x0c, 0x1e, 0x7c, 0x1c,
+	0xa6, 0x99, 0x42, 0x4d, 0xa8, 0x4a, 0x90, 0x4d,
+};
+
+static void test_shake128_nist(struct kunit *test)
+{
+	u8 out[SHAKE128_DEFAULT_SIZE];
+
+	shake128("", 0, out, sizeof(out));
+	KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake128_nist_0, sizeof(out),
+			       "SHAKE128 gives wrong output for NIST.0");
+
+	shake128(test_nist_1600_sample, sizeof(test_nist_1600_sample),
+		 out, sizeof(out));
+	KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake128_nist_1600, sizeof(out),
+			       "SHAKE128 gives wrong output for NIST.1600");
+}
+
+static void test_shake256_nist(struct kunit *test)
+{
+	u8 out[SHAKE256_DEFAULT_SIZE];
+
+	shake256("", 0, out, sizeof(out));
+	KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256_nist_0, sizeof(out),
+			       "SHAKE256 gives wrong output for NIST.0");
+
+	shake256(test_nist_1600_sample, sizeof(test_nist_1600_sample),
+		 out, sizeof(out));
+	KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256_nist_1600, sizeof(out),
+			       "SHAKE256 gives wrong output for NIST.1600");
+}
+
+/*
+ * Output tiling test of SHAKE256; equal output tiles barring the last.  A
+ * series of squeezings of the same context should, if laid end-to-end, match a
+ * single squeezing of the combined size.
+ */
+static void test_shake256_tiling(struct kunit *test)
+{
+	struct shake256_ctx ctx;
+	u8 out[8 + SHA3_512_DIGEST_SIZE + 8];
+
+	for (int tile_size = 1; tile_size < SHAKE256_DEFAULT_SIZE; tile_size++) {
+		int left = SHAKE256_DEFAULT_SIZE;
+		u8 *p = out + 8;
+
+		memset(out, 0, sizeof(out));
+		shake256_init(&ctx);
+		shake256_update(&ctx, test_sha3_sample, sizeof(test_sha3_sample) - 1);
+		while (left > 0) {
+			int part = umin(tile_size, left);
+
+			shake256_squeeze(&ctx, p, part);
+			p += part;
+			left -= part;
+		}
+
+		KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256, sizeof(test_shake256),
+				       "SHAKE tile %u gives wrong output", tile_size);
+	}
+}
+
+/*
+ * Output tiling test of SHAKE256; output tiles getting gradually smaller and
+ * then cycling round to medium sized ones.  A series of squeezings of the same
+ * context should, if laid end-to-end, match a single squeezing of the combined
+ * size.
+ */
+static void test_shake256_tiling2(struct kunit *test)
+{
+	struct shake256_ctx ctx;
+	u8 out[8 + SHA3_512_DIGEST_SIZE + 8];
+
+	for (int first_tile_size = 3;
+	     first_tile_size < SHAKE256_DEFAULT_SIZE;
+	     first_tile_size++) {
+		int tile_size = first_tile_size;
+		int left = SHAKE256_DEFAULT_SIZE;
+		u8 *p = out + 8;
+
+		memset(out, 0, sizeof(out));
+		shake256_init(&ctx);
+		shake256_update(&ctx, test_sha3_sample, sizeof(test_sha3_sample) - 1);
+		while (left > 0) {
+			int part = umin(tile_size, left);
+
+			shake256_squeeze(&ctx, p, part);
+			p += part;
+			left -= part;
+			tile_size--;
+			if (tile_size < 1)
+				tile_size = 5;
+		}
+
+		KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256, sizeof(test_shake256),
+				       "SHAKE tile %u gives wrong output", tile_size);
+	}
+}
+
+static struct kunit_case hash_test_cases[] = {
+	KUNIT_CASE(test_sha3_224_basic),
+	KUNIT_CASE(test_sha3_256_basic),
+	KUNIT_CASE(test_sha3_384_basic),
+	KUNIT_CASE(test_sha3_512_basic),
+	KUNIT_CASE(test_shake128_basic),
+	KUNIT_CASE(test_shake256_basic),
+	KUNIT_CASE(test_shake128_nist),
+	KUNIT_CASE(test_shake256_nist),
+	KUNIT_CASE(test_shake256_tiling),
+	KUNIT_CASE(test_shake256_tiling2),
+	HASH_KUNIT_CASES,
+	KUNIT_CASE(benchmark_hash),
+	{},
+};
+
+static struct kunit_suite hash_test_suite = {
+	.name = "sha3",
+	.test_cases = hash_test_cases,
+	.suite_init = hash_suite_init,
+	.suite_exit = hash_suite_exit,
+};
+kunit_test_suite(hash_test_suite);
+
+MODULE_DESCRIPTION("KUnit tests and benchmark for SHA3-256");
+MODULE_LICENSE("GPL");
diff --git a/lib/crypto/tests/sha3_testvecs.h b/lib/crypto/tests/sha3_testvecs.h
new file mode 100644
index 000000000000..9c4c403cc6e0
--- /dev/null
+++ b/lib/crypto/tests/sha3_testvecs.h
@@ -0,0 +1,231 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* This file was generated by: ./scripts/crypto/gen-hash-testvecs.py sha3-256 */
+
+static const struct {
+	size_t data_len;
+	u8 digest[SHA3_256_DIGEST_SIZE];
+} hash_testvecs[] = {
+	{
+		.data_len = 0,
+		.digest = {
+			0xa7, 0xff, 0xc6, 0xf8, 0xbf, 0x1e, 0xd7, 0x66,
+			0x51, 0xc1, 0x47, 0x56, 0xa0, 0x61, 0xd6, 0x62,
+			0xf5, 0x80, 0xff, 0x4d, 0xe4, 0x3b, 0x49, 0xfa,
+			0x82, 0xd8, 0x0a, 0x4b, 0x80, 0xf8, 0x43, 0x4a,
+		},
+	},
+	{
+		.data_len = 1,
+		.digest = {
+			0x11, 0x03, 0xe7, 0x84, 0x51, 0x50, 0x86, 0x35,
+			0x71, 0x8a, 0x70, 0xe3, 0xc4, 0x26, 0x7b, 0x21,
+			0x02, 0x13, 0xa0, 0x81, 0xe8, 0xe6, 0x14, 0x25,
+			0x07, 0x34, 0xe5, 0xc5, 0x40, 0x06, 0xf2, 0x8b,
+		},
+	},
+	{
+		.data_len = 2,
+		.digest = {
+			0x2f, 0x6f, 0x6d, 0x47, 0x48, 0x52, 0x11, 0xb9,
+			0xe4, 0x3d, 0xc8, 0x71, 0xcf, 0xb2, 0xee, 0xae,
+			0x5b, 0xf4, 0x12, 0x84, 0x5b, 0x1c, 0xec, 0x6c,
+			0xc1, 0x66, 0x88, 0xaa, 0xc3, 0x40, 0xbd, 0x7e,
+		},
+	},
+	{
+		.data_len = 3,
+		.digest = {
+			0xec, 0x02, 0xe8, 0x81, 0x4f, 0x84, 0x41, 0x69,
+			0x06, 0xd8, 0xdc, 0x1d, 0x01, 0x78, 0xd7, 0xcb,
+			0x39, 0xdf, 0xd3, 0x12, 0x1c, 0x99, 0xfd, 0xf3,
+			0x5c, 0x83, 0xc9, 0xc2, 0x7a, 0x7b, 0x6a, 0x05,
+		},
+	},
+	{
+		.data_len = 16,
+		.digest = {
+			0xff, 0x6f, 0xc3, 0x41, 0xc3, 0x5f, 0x34, 0x6d,
+			0xa7, 0xdf, 0x3e, 0xc2, 0x8b, 0x29, 0xb6, 0xf1,
+			0xf8, 0x67, 0xfd, 0xcd, 0xb1, 0x9f, 0x38, 0x08,
+			0x1d, 0x8d, 0xd9, 0xc2, 0x43, 0x66, 0x18, 0x6c,
+		},
+	},
+	{
+		.data_len = 32,
+		.digest = {
+			0xe4, 0xb1, 0x06, 0x17, 0xf8, 0x8b, 0x91, 0x95,
+			0xe7, 0x57, 0x66, 0xac, 0x08, 0xb2, 0x03, 0x3e,
+			0xf7, 0x84, 0x1f, 0xe3, 0x25, 0xa3, 0x11, 0xd2,
+			0x11, 0xa4, 0x78, 0x74, 0x2a, 0x43, 0x20, 0xa5,
+		},
+	},
+	{
+		.data_len = 48,
+		.digest = {
+			0xeb, 0x57, 0x5f, 0x20, 0xa3, 0x6b, 0xc7, 0xb4,
+			0x66, 0x2a, 0xa0, 0x30, 0x3b, 0x52, 0x00, 0xc9,
+			0xce, 0x6a, 0xd8, 0x1e, 0xbe, 0xed, 0xa1, 0xd1,
+			0xbe, 0x63, 0xc7, 0xe1, 0xe2, 0x66, 0x67, 0x0c,
+		},
+	},
+	{
+		.data_len = 49,
+		.digest = {
+			0xf0, 0x67, 0xad, 0x66, 0xbe, 0xec, 0x5a, 0xfd,
+			0x29, 0xd2, 0x4f, 0x1d, 0xb2, 0x24, 0xb8, 0x90,
+			0x05, 0x28, 0x0e, 0x66, 0x67, 0x74, 0x2d, 0xee,
+			0x66, 0x25, 0x11, 0xd1, 0x76, 0xa2, 0xfc, 0x3a,
+		},
+	},
+	{
+		.data_len = 63,
+		.digest = {
+			0x57, 0x56, 0x21, 0xb3, 0x2d, 0x2d, 0xe1, 0x9d,
+			0xbf, 0x2c, 0x82, 0xa8, 0xad, 0x7e, 0x6c, 0x46,
+			0xfb, 0x30, 0xeb, 0xce, 0xcf, 0xed, 0x2d, 0x65,
+			0xe7, 0xe4, 0x96, 0x69, 0xe0, 0x48, 0xd2, 0xb6,
+		},
+	},
+	{
+		.data_len = 64,
+		.digest = {
+			0x7b, 0xba, 0x67, 0x15, 0xe5, 0x21, 0xc4, 0x69,
+			0xd3, 0xef, 0x5c, 0x97, 0x9f, 0x5b, 0xba, 0x9c,
+			0xfa, 0x55, 0x64, 0xec, 0xb5, 0x37, 0x53, 0x1b,
+			0x3f, 0x4c, 0x0a, 0xed, 0x51, 0x98, 0x2b, 0x52,
+		},
+	},
+	{
+		.data_len = 65,
+		.digest = {
+			0x44, 0xb6, 0x6b, 0x83, 0x09, 0x83, 0x55, 0x83,
+			0xde, 0x1f, 0xcc, 0x33, 0xef, 0xdc, 0x05, 0xbb,
+			0x3b, 0x63, 0x76, 0x45, 0xe4, 0x8e, 0x14, 0x7a,
+			0x2d, 0xae, 0x90, 0xce, 0x68, 0xc3, 0xa4, 0xf2,
+		},
+	},
+	{
+		.data_len = 127,
+		.digest = {
+			0x50, 0x3e, 0x99, 0x4e, 0x28, 0x2b, 0xc9, 0xf4,
+			0xf5, 0xeb, 0x2b, 0x16, 0x04, 0x2d, 0xf5, 0xbe,
+			0xc0, 0x91, 0x41, 0x2a, 0x8e, 0x69, 0x5e, 0x39,
+			0x53, 0x2c, 0xc1, 0x18, 0xa5, 0xeb, 0xd8, 0xda,
+		},
+	},
+	{
+		.data_len = 128,
+		.digest = {
+			0x90, 0x0b, 0xa6, 0x92, 0x84, 0x30, 0xaf, 0xee,
+			0x38, 0x59, 0x83, 0x83, 0xe9, 0xfe, 0xab, 0x86,
+			0x79, 0x1b, 0xcd, 0xe7, 0x0a, 0x0f, 0x58, 0x53,
+			0x36, 0xab, 0x12, 0xe1, 0x5c, 0x97, 0xc1, 0xfb,
+		},
+	},
+	{
+		.data_len = 129,
+		.digest = {
+			0x2b, 0x52, 0x1e, 0x54, 0xbe, 0x38, 0x4c, 0x3e,
+			0x73, 0x37, 0x18, 0xf5, 0x25, 0x2c, 0xc8, 0xc7,
+			0xda, 0x7e, 0xb6, 0x47, 0x9d, 0xf4, 0x46, 0xce,
+			0xfa, 0x80, 0x20, 0x6b, 0xbd, 0xfd, 0x2a, 0xd8,
+		},
+	},
+	{
+		.data_len = 256,
+		.digest = {
+			0x45, 0xf0, 0xf5, 0x9b, 0xd9, 0x91, 0x26, 0xd5,
+			0x91, 0x3b, 0xf8, 0x87, 0x8b, 0x34, 0x02, 0x31,
+			0x64, 0xab, 0xf4, 0x1c, 0x6e, 0x34, 0x72, 0xdf,
+			0x32, 0x6d, 0xe5, 0xd2, 0x67, 0x5e, 0x86, 0x93,
+		},
+	},
+	{
+		.data_len = 511,
+		.digest = {
+			0xb3, 0xaf, 0x71, 0x64, 0xfa, 0xd4, 0xf1, 0x07,
+			0x38, 0xef, 0x04, 0x8e, 0x89, 0xf4, 0x02, 0xd2,
+			0xa5, 0xaf, 0x3b, 0xf5, 0x67, 0x56, 0xcf, 0xa9,
+			0x8e, 0x43, 0xf5, 0xb5, 0xe3, 0x91, 0x8e, 0xe7,
+		},
+	},
+	{
+		.data_len = 513,
+		.digest = {
+			0x51, 0xac, 0x0a, 0x65, 0xb7, 0x96, 0x20, 0xcf,
+			0x88, 0xf6, 0x97, 0x35, 0x89, 0x0d, 0x31, 0x0f,
+			0xbe, 0x17, 0xbe, 0x62, 0x03, 0x67, 0xc0, 0xee,
+			0x4f, 0xc1, 0xe3, 0x7f, 0x6f, 0xab, 0xac, 0xb4,
+		},
+	},
+	{
+		.data_len = 1000,
+		.digest = {
+			0x7e, 0xea, 0xa8, 0xd7, 0xde, 0x20, 0x1b, 0x58,
+			0x24, 0xd8, 0x26, 0x40, 0x36, 0x5f, 0x3f, 0xaa,
+			0xe5, 0x5a, 0xea, 0x98, 0x58, 0xd4, 0xd6, 0xfc,
+			0x20, 0x4c, 0x5c, 0x4f, 0xaf, 0x56, 0xc7, 0xc3,
+		},
+	},
+	{
+		.data_len = 3333,
+		.digest = {
+			0x61, 0xb1, 0xb1, 0x3e, 0x0e, 0x7e, 0x90, 0x3d,
+			0x31, 0x54, 0xbd, 0xc9, 0x0d, 0x53, 0x62, 0xf1,
+			0xcd, 0x18, 0x80, 0xf9, 0x91, 0x75, 0x41, 0xb3,
+			0x51, 0x39, 0x57, 0xa7, 0xa8, 0x1e, 0xfb, 0xc9,
+		},
+	},
+	{
+		.data_len = 4096,
+		.digest = {
+			0xab, 0x29, 0xda, 0x10, 0xc4, 0x11, 0x2d, 0x5c,
+			0xd1, 0xce, 0x1c, 0x95, 0xfa, 0xc6, 0xc7, 0xb0,
+			0x1b, 0xd1, 0xdc, 0x6f, 0xa0, 0x9d, 0x1b, 0x23,
+			0xfb, 0x6e, 0x90, 0x97, 0xd0, 0x75, 0x44, 0x7a,
+		},
+	},
+	{
+		.data_len = 4128,
+		.digest = {
+			0x02, 0x45, 0x95, 0xf4, 0x19, 0xb5, 0x93, 0x29,
+			0x90, 0xf2, 0x63, 0x3f, 0x89, 0xe8, 0xa5, 0x31,
+			0x76, 0xf2, 0x89, 0x79, 0x66, 0xd3, 0x96, 0xdf,
+			0x33, 0xd1, 0xa6, 0x17, 0x73, 0xb1, 0xd0, 0x45,
+		},
+	},
+	{
+		.data_len = 4160,
+		.digest = {
+			0xd1, 0x8e, 0x22, 0xea, 0x44, 0x87, 0x6e, 0x9d,
+			0xfb, 0x36, 0x02, 0x20, 0x63, 0xb7, 0x69, 0x45,
+			0x25, 0x41, 0x69, 0xe0, 0x9b, 0x87, 0xcf, 0xa3,
+			0x51, 0xbb, 0xfc, 0x8d, 0xf7, 0x29, 0xa7, 0xea,
+		},
+	},
+	{
+		.data_len = 4224,
+		.digest = {
+			0x11, 0x86, 0x7d, 0x84, 0xf9, 0x8c, 0x6e, 0xc4,
+			0x64, 0x36, 0xc6, 0xf3, 0x42, 0x92, 0x31, 0x2b,
+			0x1e, 0x12, 0xe6, 0x4d, 0xbe, 0xfa, 0x77, 0x3f,
+			0x89, 0x41, 0x33, 0x58, 0x1c, 0x98, 0x16, 0x0a,
+		},
+	},
+	{
+		.data_len = 16384,
+		.digest = {
+			0xb2, 0xba, 0x0c, 0x8c, 0x9d, 0xbb, 0x1e, 0xb0,
+			0x03, 0xb5, 0xdf, 0x4f, 0xf5, 0x35, 0xdb, 0xec,
+			0x60, 0xf2, 0x5b, 0xb6, 0xd0, 0x49, 0xd3, 0xed,
+			0x55, 0xc0, 0x7a, 0xd7, 0xaf, 0xa1, 0xea, 0x53,
+		},
+	},
+};
+
+static const u8 hash_testvec_consolidated[SHA3_256_DIGEST_SIZE] = {
+	0x3b, 0x33, 0x67, 0xf8, 0xea, 0x92, 0x78, 0x62,
+	0xdd, 0xbe, 0x72, 0x15, 0xbd, 0x6f, 0xfa, 0xe5,
+	0x5e, 0xab, 0x9f, 0xb1, 0xe4, 0x23, 0x7c, 0x2c,
+	0x80, 0xcf, 0x09, 0x75, 0xf8, 0xe2, 0xfa, 0x30,
+};
diff --git a/scripts/crypto/gen-hash-testvecs.py b/scripts/crypto/gen-hash-testvecs.py
index fc063f2ee95f..a5b0abd8dabe 100755
--- a/scripts/crypto/gen-hash-testvecs.py
+++ b/scripts/crypto/gen-hash-testvecs.py
@@ -61,6 +61,10 @@ def hash_update(ctx, data):
     ctx.update(data)
 
 def hash_final(ctx):
+    if ctx.name == "shake_128":
+        return ctx.digest(16)
+    if ctx.name == "shake_256":
+        return ctx.digest(32)
     return ctx.digest()
 
 def compute_hash(alg, data):
@@ -122,7 +126,7 @@ def gen_hmac_testvecs(alg):
         ctx.update(mac)
     print_static_u8_array_definition(
             f'hmac_testvec_consolidated[{alg.upper()}_DIGEST_SIZE]',
-            ctx.digest())
+            hash_final(ctx))
 
 BLAKE2S_KEY_SIZE = 32
 BLAKE2S_HASH_SIZE = 32
@@ -164,5 +168,5 @@ if alg == 'blake2s':
     gen_additional_blake2s_testvecs()
 elif alg == 'poly1305':
     gen_additional_poly1305_testvecs()
-else:
+elif alg != 'shake128' and alg != 'shake256':
     gen_hmac_testvecs(alg)


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 6/8] crypto/sha3: Use lib/crypto/sha3
  2025-09-26 14:19 [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto David Howells
                   ` (4 preceding siblings ...)
  2025-09-26 14:19 ` [PATCH v3 5/8] lib/crypto: Add SHA3 kunit tests David Howells
@ 2025-09-26 14:19 ` David Howells
  2025-09-26 21:25   ` Eric Biggers
  2025-09-26 14:19 ` [PATCH v3 7/8] crypto/sha3: Add SHAKE128/256 support David Howells
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 27+ messages in thread
From: David Howells @ 2025-09-26 14:19 UTC (permalink / raw)
  Cc: David Howells, Eric Biggers, Jason A . Donenfeld, Ard Biesheuvel,
	Herbert Xu, Stephan Mueller, linux-crypto, linux-kernel

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.

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
---
 Documentation/crypto/sha3.rst    |   8 +-
 arch/arm64/crypto/sha3-ce-glue.c |  25 ++--
 crypto/sha3_generic.c            | 201 +++----------------------------
 include/crypto/sha3.h            |   6 +-
 lib/crypto/sha3.c                |  35 +++---
 5 files changed, 52 insertions(+), 223 deletions(-)

diff --git a/Documentation/crypto/sha3.rst b/Documentation/crypto/sha3.rst
index ae4902895882..82c9abe45614 100644
--- a/Documentation/crypto/sha3.rst
+++ b/Documentation/crypto/sha3.rst
@@ -157,7 +157,7 @@ further algorithms or APIs as the engine in the same in all cases.  The
 algorithm APIs all wrap the common context structure::
 
 	struct sha3_ctx {
-		struct sha3_state	state;
+		u64			st[SHA3_STATE_SIZE / 8];
 		u8			block_size;
 		u8			padding;
 		u8			absorb_offset;
@@ -165,13 +165,9 @@ algorithm APIs all wrap the common context structure::
 		bool			end_marked;
 	};
 
-	struct sha3_state {
-		u64			st[SHA3_STATE_SIZE / 8];
-	};
-
 The fields are as follows:
 
- * ``state.st``
+ * ``st``
 
    An array of 25 64-bit state buckets that are used to hold the mathematical
    state of the Keccak engine.  Data is XOR'd onto part of this, the engine is
diff --git a/arch/arm64/crypto/sha3-ce-glue.c b/arch/arm64/crypto/sha3-ce-glue.c
index 426d8044535a..f6cdff4cd103 100644
--- a/arch/arm64/crypto/sha3-ce-glue.c
+++ b/arch/arm64/crypto/sha3-ce-glue.c
@@ -28,13 +28,18 @@ MODULE_ALIAS_CRYPTO("sha3-256");
 MODULE_ALIAS_CRYPTO("sha3-384");
 MODULE_ALIAS_CRYPTO("sha3-512");
 
+static struct sha3_ctx *crypto_sha3_desc(struct shash_desc *desc)
+{
+	return shash_desc_ctx(desc);
+}
+
 asmlinkage int sha3_ce_transform(u64 *st, const u8 *data, int blocks,
 				 int md_len);
 
 static int arm64_sha3_update(struct shash_desc *desc, const u8 *data,
 		       unsigned int len)
 {
-	struct sha3_state *sctx = shash_desc_ctx(desc);
+	struct sha3_ctx *ctx = crypto_sha3_desc(desc);
 	struct crypto_shash *tfm = desc->tfm;
 	unsigned int bs, ds;
 	int blocks;
@@ -47,7 +52,7 @@ static int arm64_sha3_update(struct shash_desc *desc, const u8 *data,
 		int rem;
 
 		kernel_neon_begin();
-		rem = sha3_ce_transform(sctx->st, data, blocks, ds);
+		rem = sha3_ce_transform(ctx->state.st, data, blocks, ds);
 		kernel_neon_end();
 		data += (blocks - rem) * bs;
 		blocks = rem;
@@ -58,7 +63,7 @@ static int arm64_sha3_update(struct shash_desc *desc, const u8 *data,
 static int arm64_sha3_finup(struct shash_desc *desc, const u8 *src, unsigned int len,
 			    u8 *out)
 {
-	struct sha3_state *sctx = shash_desc_ctx(desc);
+	struct sha3_ctx *ctx = crypto_sha3_desc(desc);
 	struct crypto_shash *tfm = desc->tfm;
 	__le64 *digest = (__le64 *)out;
 	u8 block[SHA3_224_BLOCK_SIZE];
@@ -74,15 +79,15 @@ static int arm64_sha3_finup(struct shash_desc *desc, const u8 *src, unsigned int
 	block[bs - 1] |= 0x80;
 
 	kernel_neon_begin();
-	sha3_ce_transform(sctx->st, block, 1, ds);
+	sha3_ce_transform(sctx->state.st, block, 1, ds);
 	kernel_neon_end();
 	memzero_explicit(block , sizeof(block));
 
 	for (i = 0; i < ds / 8; i++)
-		put_unaligned_le64(sctx->st[i], digest++);
+		put_unaligned_le64(sctx->state.st[i], digest++);
 
 	if (ds & 4)
-		put_unaligned_le32(sctx->st[i], (__le32 *)digest);
+		put_unaligned_le32(sctx->state.st[i], (__le32 *)digest);
 
 	return 0;
 }
@@ -92,7 +97,7 @@ static struct shash_alg algs[] = { {
 	.init			= crypto_sha3_init,
 	.update			= arm64_sha3_update,
 	.finup			= arm64_sha3_finup,
-	.descsize		= SHA3_STATE_SIZE,
+	.descsize		= sizeof(struct sha3_ctx),
 	.base.cra_name		= "sha3-224",
 	.base.cra_driver_name	= "sha3-224-ce",
 	.base.cra_flags		= CRYPTO_AHASH_ALG_BLOCK_ONLY,
@@ -104,7 +109,7 @@ static struct shash_alg algs[] = { {
 	.init			= crypto_sha3_init,
 	.update			= arm64_sha3_update,
 	.finup			= arm64_sha3_finup,
-	.descsize		= SHA3_STATE_SIZE,
+	.descsize		= sizeof(struct sha3_ctx),
 	.base.cra_name		= "sha3-256",
 	.base.cra_driver_name	= "sha3-256-ce",
 	.base.cra_flags		= CRYPTO_AHASH_ALG_BLOCK_ONLY,
@@ -116,7 +121,7 @@ static struct shash_alg algs[] = { {
 	.init			= crypto_sha3_init,
 	.update			= arm64_sha3_update,
 	.finup			= arm64_sha3_finup,
-	.descsize		= SHA3_STATE_SIZE,
+	.descsize		= sizeof(struct sha3_ctx),
 	.base.cra_name		= "sha3-384",
 	.base.cra_driver_name	= "sha3-384-ce",
 	.base.cra_flags		= CRYPTO_AHASH_ALG_BLOCK_ONLY,
@@ -128,7 +133,7 @@ static struct shash_alg algs[] = { {
 	.init			= crypto_sha3_init,
 	.update			= arm64_sha3_update,
 	.finup			= arm64_sha3_finup,
-	.descsize		= SHA3_STATE_SIZE,
+	.descsize		= sizeof(struct sha3_ctx),
 	.base.cra_name		= "sha3-512",
 	.base.cra_driver_name	= "sha3-512-ce",
 	.base.cra_flags		= CRYPTO_AHASH_ALG_BLOCK_ONLY,
diff --git a/crypto/sha3_generic.c b/crypto/sha3_generic.c
index 41d1e506e6de..6917a1aeb8e5 100644
--- a/crypto/sha3_generic.c
+++ b/crypto/sha3_generic.c
@@ -13,156 +13,19 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/string.h>
-#include <linux/unaligned.h>
 
-/*
- * On some 32-bit architectures (h8300), GCC ends up using
- * over 1 KB of stack if we inline the round calculation into the loop
- * in keccakf(). On the other hand, on 64-bit architectures with plenty
- * of [64-bit wide] general purpose registers, not inlining it severely
- * hurts performance. So let's use 64-bitness as a heuristic to decide
- * whether to inline or not.
- */
-#ifdef CONFIG_64BIT
-#define SHA3_INLINE	inline
-#else
-#define SHA3_INLINE	noinline
-#endif
-
-#define KECCAK_ROUNDS 24
-
-static const u64 keccakf_rndc[24] = {
-	0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL,
-	0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL,
-	0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL,
-	0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL,
-	0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL,
-	0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL,
-	0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL,
-	0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL
-};
-
-/* update the state with given number of rounds */
-
-static SHA3_INLINE void keccakf_round(u64 st[25])
-{
-	u64 t[5], tt, bc[5];
-
-	/* Theta */
-	bc[0] = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20];
-	bc[1] = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21];
-	bc[2] = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22];
-	bc[3] = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23];
-	bc[4] = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24];
-
-	t[0] = bc[4] ^ rol64(bc[1], 1);
-	t[1] = bc[0] ^ rol64(bc[2], 1);
-	t[2] = bc[1] ^ rol64(bc[3], 1);
-	t[3] = bc[2] ^ rol64(bc[4], 1);
-	t[4] = bc[3] ^ rol64(bc[0], 1);
-
-	st[0] ^= t[0];
-
-	/* Rho Pi */
-	tt = st[1];
-	st[ 1] = rol64(st[ 6] ^ t[1], 44);
-	st[ 6] = rol64(st[ 9] ^ t[4], 20);
-	st[ 9] = rol64(st[22] ^ t[2], 61);
-	st[22] = rol64(st[14] ^ t[4], 39);
-	st[14] = rol64(st[20] ^ t[0], 18);
-	st[20] = rol64(st[ 2] ^ t[2], 62);
-	st[ 2] = rol64(st[12] ^ t[2], 43);
-	st[12] = rol64(st[13] ^ t[3], 25);
-	st[13] = rol64(st[19] ^ t[4],  8);
-	st[19] = rol64(st[23] ^ t[3], 56);
-	st[23] = rol64(st[15] ^ t[0], 41);
-	st[15] = rol64(st[ 4] ^ t[4], 27);
-	st[ 4] = rol64(st[24] ^ t[4], 14);
-	st[24] = rol64(st[21] ^ t[1],  2);
-	st[21] = rol64(st[ 8] ^ t[3], 55);
-	st[ 8] = rol64(st[16] ^ t[1], 45);
-	st[16] = rol64(st[ 5] ^ t[0], 36);
-	st[ 5] = rol64(st[ 3] ^ t[3], 28);
-	st[ 3] = rol64(st[18] ^ t[3], 21);
-	st[18] = rol64(st[17] ^ t[2], 15);
-	st[17] = rol64(st[11] ^ t[1], 10);
-	st[11] = rol64(st[ 7] ^ t[2],  6);
-	st[ 7] = rol64(st[10] ^ t[0],  3);
-	st[10] = rol64(    tt ^ t[1],  1);
-
-	/* Chi */
-	bc[ 0] = ~st[ 1] & st[ 2];
-	bc[ 1] = ~st[ 2] & st[ 3];
-	bc[ 2] = ~st[ 3] & st[ 4];
-	bc[ 3] = ~st[ 4] & st[ 0];
-	bc[ 4] = ~st[ 0] & st[ 1];
-	st[ 0] ^= bc[ 0];
-	st[ 1] ^= bc[ 1];
-	st[ 2] ^= bc[ 2];
-	st[ 3] ^= bc[ 3];
-	st[ 4] ^= bc[ 4];
-
-	bc[ 0] = ~st[ 6] & st[ 7];
-	bc[ 1] = ~st[ 7] & st[ 8];
-	bc[ 2] = ~st[ 8] & st[ 9];
-	bc[ 3] = ~st[ 9] & st[ 5];
-	bc[ 4] = ~st[ 5] & st[ 6];
-	st[ 5] ^= bc[ 0];
-	st[ 6] ^= bc[ 1];
-	st[ 7] ^= bc[ 2];
-	st[ 8] ^= bc[ 3];
-	st[ 9] ^= bc[ 4];
-
-	bc[ 0] = ~st[11] & st[12];
-	bc[ 1] = ~st[12] & st[13];
-	bc[ 2] = ~st[13] & st[14];
-	bc[ 3] = ~st[14] & st[10];
-	bc[ 4] = ~st[10] & st[11];
-	st[10] ^= bc[ 0];
-	st[11] ^= bc[ 1];
-	st[12] ^= bc[ 2];
-	st[13] ^= bc[ 3];
-	st[14] ^= bc[ 4];
-
-	bc[ 0] = ~st[16] & st[17];
-	bc[ 1] = ~st[17] & st[18];
-	bc[ 2] = ~st[18] & st[19];
-	bc[ 3] = ~st[19] & st[15];
-	bc[ 4] = ~st[15] & st[16];
-	st[15] ^= bc[ 0];
-	st[16] ^= bc[ 1];
-	st[17] ^= bc[ 2];
-	st[18] ^= bc[ 3];
-	st[19] ^= bc[ 4];
-
-	bc[ 0] = ~st[21] & st[22];
-	bc[ 1] = ~st[22] & st[23];
-	bc[ 2] = ~st[23] & st[24];
-	bc[ 3] = ~st[24] & st[20];
-	bc[ 4] = ~st[20] & st[21];
-	st[20] ^= bc[ 0];
-	st[21] ^= bc[ 1];
-	st[22] ^= bc[ 2];
-	st[23] ^= bc[ 3];
-	st[24] ^= bc[ 4];
-}
-
-static void keccakf(u64 st[25])
+static struct sha3_ctx *crypto_sha3_desc(struct shash_desc *desc)
 {
-	int round;
-
-	for (round = 0; round < KECCAK_ROUNDS; round++) {
-		keccakf_round(st);
-		/* Iota */
-		st[0] ^= keccakf_rndc[round];
-	}
+	return shash_desc_ctx(desc);
 }
 
 int crypto_sha3_init(struct shash_desc *desc)
 {
-	struct sha3_state *sctx = shash_desc_ctx(desc);
+	struct sha3_ctx *ctx = crypto_sha3_desc(desc);
 
-	memset(sctx->st, 0, sizeof(sctx->st));
+	memset(ctx, 0, sizeof(*ctx));
+	ctx->block_size = crypto_shash_blocksize(desc->tfm);
+	ctx->padding = 0x06;
 	return 0;
 }
 EXPORT_SYMBOL(crypto_sha3_init);
@@ -170,51 +33,21 @@ EXPORT_SYMBOL(crypto_sha3_init);
 static int crypto_sha3_update(struct shash_desc *desc, const u8 *data,
 			      unsigned int len)
 {
-	unsigned int rsiz = crypto_shash_blocksize(desc->tfm);
-	struct sha3_state *sctx = shash_desc_ctx(desc);
-	unsigned int rsizw = rsiz / 8;
-
-	do {
-		int i;
+	struct sha3_ctx *ctx = crypto_sha3_desc(desc);
 
-		for (i = 0; i < rsizw; i++)
-			sctx->st[i] ^= get_unaligned_le64(data + 8 * i);
-		keccakf(sctx->st);
-
-		data += rsiz;
-		len -= rsiz;
-	} while (len >= rsiz);
+	sha3_update(ctx, data, len);
 	return len;
 }
 
 static int crypto_sha3_finup(struct shash_desc *desc, const u8 *src,
 			     unsigned int len, u8 *out)
 {
-	unsigned int digest_size = crypto_shash_digestsize(desc->tfm);
-	unsigned int rsiz = crypto_shash_blocksize(desc->tfm);
-	struct sha3_state *sctx = shash_desc_ctx(desc);
-	__le64 block[SHA3_224_BLOCK_SIZE / 8] = {};
-	__le64 *digest = (__le64 *)out;
-	unsigned int rsizw = rsiz / 8;
-	u8 *p;
-	int i;
-
-	p = memcpy(block, src, len);
-	p[len++] = 0x06;
-	p[rsiz - 1] |= 0x80;
-
-	for (i = 0; i < rsizw; i++)
-		sctx->st[i] ^= le64_to_cpu(block[i]);
-	memzero_explicit(block, sizeof(block));
-
-	keccakf(sctx->st);
-
-	for (i = 0; i < digest_size / 8; i++)
-		put_unaligned_le64(sctx->st[i], digest++);
-
-	if (digest_size & 4)
-		put_unaligned_le32(sctx->st[i], (__le32 *)digest);
+	struct sha3_ctx *ctx = crypto_sha3_desc(desc);
 
+	if (len && src)
+		sha3_update(ctx, src, len);
+	sha3_squeeze(ctx, out, crypto_shash_digestsize(desc->tfm));
+	sha3_clear(ctx);
 	return 0;
 }
 
@@ -223,7 +56,7 @@ static struct shash_alg algs[] = { {
 	.init			= crypto_sha3_init,
 	.update			= crypto_sha3_update,
 	.finup			= crypto_sha3_finup,
-	.descsize		= SHA3_STATE_SIZE,
+	.descsize		= sizeof(struct sha3_ctx),
 	.base.cra_name		= "sha3-224",
 	.base.cra_driver_name	= "sha3-224-generic",
 	.base.cra_flags		= CRYPTO_AHASH_ALG_BLOCK_ONLY,
@@ -234,7 +67,7 @@ static struct shash_alg algs[] = { {
 	.init			= crypto_sha3_init,
 	.update			= crypto_sha3_update,
 	.finup			= crypto_sha3_finup,
-	.descsize		= SHA3_STATE_SIZE,
+	.descsize		= sizeof(struct sha3_ctx),
 	.base.cra_name		= "sha3-256",
 	.base.cra_driver_name	= "sha3-256-generic",
 	.base.cra_flags		= CRYPTO_AHASH_ALG_BLOCK_ONLY,
@@ -245,7 +78,7 @@ static struct shash_alg algs[] = { {
 	.init			= crypto_sha3_init,
 	.update			= crypto_sha3_update,
 	.finup			= crypto_sha3_finup,
-	.descsize		= SHA3_STATE_SIZE,
+	.descsize		= sizeof(struct sha3_ctx),
 	.base.cra_name		= "sha3-384",
 	.base.cra_driver_name	= "sha3-384-generic",
 	.base.cra_flags		= CRYPTO_AHASH_ALG_BLOCK_ONLY,
@@ -256,7 +89,7 @@ static struct shash_alg algs[] = { {
 	.init			= crypto_sha3_init,
 	.update			= crypto_sha3_update,
 	.finup			= crypto_sha3_finup,
-	.descsize		= SHA3_STATE_SIZE,
+	.descsize		= sizeof(struct sha3_ctx),
 	.base.cra_name		= "sha3-512",
 	.base.cra_driver_name	= "sha3-512-generic",
 	.base.cra_flags		= CRYPTO_AHASH_ALG_BLOCK_ONLY,
diff --git a/include/crypto/sha3.h b/include/crypto/sha3.h
index 41bc211afa0b..183261995fa1 100644
--- a/include/crypto/sha3.h
+++ b/include/crypto/sha3.h
@@ -38,10 +38,6 @@
 
 struct shash_desc;
 
-struct sha3_state {
-	u64		st[SHA3_STATE_SIZE / 8];
-};
-
 /*
  * The SHA3 context structure and state buffer.
  *
@@ -52,7 +48,7 @@ struct sha3_state {
  * byteswap step is a no-op.
  */
 struct sha3_ctx {
-	struct sha3_state	state;
+	u64			st[SHA3_STATE_SIZE / 8];
 	u8			block_size;	/* Block size in bytes */
 	u8			padding;	/* Padding byte */
 	u8			absorb_offset;	/* Next state byte to absorb into */
diff --git a/lib/crypto/sha3.c b/lib/crypto/sha3.c
index 227d45bd9680..398669c4d7ca 100644
--- a/lib/crypto/sha3.c
+++ b/lib/crypto/sha3.c
@@ -48,10 +48,10 @@ static const u64 sha3_keccakf_rndc[24] = {
 /*
  * Perform a single round of Keccak mixing.
  */
-static SHA3_INLINE void sha3_keccakf_one_round_generic(struct sha3_state *state,
+static SHA3_INLINE void sha3_keccakf_one_round_generic(struct sha3_ctx *ctx,
 						       int round)
 {
-	u64 *st = state->st;
+	u64 *st = ctx->st;
 	u64 t[5], tt, bc[5];
 
 	/* Theta */
@@ -153,13 +153,13 @@ static SHA3_INLINE void sha3_keccakf_one_round_generic(struct sha3_state *state,
 	st[24] ^= bc[ 4];
 
 	/* Iota */
-	state->st[0] ^= sha3_keccakf_rndc[round];
+	ctx->st[0] ^= sha3_keccakf_rndc[round];
 }
 
-static void sha3_keccakf_rounds_generic(struct sha3_state *state)
+static void sha3_keccakf_rounds_generic(struct sha3_ctx *ctx)
 {
 	for (int round = 0; round < SHA3_KECCAK_ROUNDS; round++)
-		sha3_keccakf_one_round_generic(state, round);
+		sha3_keccakf_one_round_generic(ctx, round);
 }
 
 /*
@@ -167,25 +167,24 @@ static void sha3_keccakf_rounds_generic(struct sha3_state *state)
  * machine for the duration of the Keccak mixing function.  Note that these
  * loops are no-ops on LE machines and will be optimised away.
  */
-static void sha3_keccakf_generic(struct sha3_state *state)
+static void sha3_keccakf_generic(struct sha3_ctx *ctx)
 {
-	for (int  i = 0; i < ARRAY_SIZE(state->st); i++)
-		cpu_to_le64s(&state->st[i]);
+	for (int  i = 0; i < ARRAY_SIZE(ctx->st); i++)
+		cpu_to_le64s(&ctx->st[i]);
 
-	sha3_keccakf_rounds_generic(state);
+	sha3_keccakf_rounds_generic(ctx);
 
-	for (int  i = 0; i < ARRAY_SIZE(state->st); i++)
-		le64_to_cpus(&state->st[i]);
+	for (int  i = 0; i < ARRAY_SIZE(ctx->st); i++)
+		le64_to_cpus(&ctx->st[i]);
 }
 
 static void sha3_absorb_block_generic(struct sha3_ctx *ctx, const u8 *data)
 {
-	struct sha3_state *state = &ctx->state;
 	unsigned int bsize = ctx->block_size;
 
 	for (int i = 0; i < bsize / 8; i++)
-		state->st[i] ^= get_unaligned((u64 *)(data + 8 * i));
-	sha3_keccakf_generic(state);
+		ctx->st[i] ^= get_unaligned((u64 *)(data + 8 * i));
+	sha3_keccakf_generic(ctx);
 }
 
 /*
@@ -214,7 +213,7 @@ static void sha3_absorb_blocks_generic(struct sha3_ctx *ctx,
 static void sha3_absorb_xorle(struct sha3_ctx *ctx, const u8 *data,
 			      unsigned int partial, unsigned int len)
 {
-	u8 *buf = (u8 *)ctx->state.st;
+	u8 *buf = (u8 *)ctx->st;
 
 	buf += partial;
 	for (int i = 0; i < len; i++)
@@ -245,7 +244,7 @@ void sha3_update(struct sha3_ctx *ctx, const u8 *data, unsigned int len)
 		sha3_absorb_xorle(ctx, data, absorb_offset, bsize - absorb_offset);
 		len  -= bsize - absorb_offset;
 		data += bsize - absorb_offset;
-		sha3_keccakf(&ctx->state);
+		sha3_keccakf(ctx);
 		ctx->absorb_offset = 0;
 	}
 
@@ -286,7 +285,7 @@ void sha3_squeeze(struct sha3_ctx *ctx, u8 *out, size_t out_size)
 {
 	unsigned int squeeze_offset = ctx->squeeze_offset;
 	unsigned int bsize = ctx->block_size;
-	u8 *p = (u8 *)ctx->state.st, end_marker = 0x80;
+	u8 *p = (u8 *)ctx->st, end_marker = 0x80;
 
 	if (!ctx->end_marked) {
 		sha3_absorb_xorle(ctx, &ctx->padding, ctx->absorb_offset, 1);
@@ -296,7 +295,7 @@ void sha3_squeeze(struct sha3_ctx *ctx, u8 *out, size_t out_size)
 
 	for (;;) {
 		if (squeeze_offset == 0)
-			sha3_keccakf(&ctx->state);
+			sha3_keccakf(ctx);
 
 		unsigned int part = umin(out_size, bsize - squeeze_offset);
 


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 7/8] crypto/sha3: Add SHAKE128/256 support
  2025-09-26 14:19 [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto David Howells
                   ` (5 preceding siblings ...)
  2025-09-26 14:19 ` [PATCH v3 6/8] crypto/sha3: Use lib/crypto/sha3 David Howells
@ 2025-09-26 14:19 ` David Howells
  2025-09-26 21:14   ` Eric Biggers
  2025-09-26 14:19 ` [PATCH v3 8/8] crypto: SHAKE tests David Howells
  2025-09-26 19:59 ` [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto Eric Biggers
  8 siblings, 1 reply; 27+ messages in thread
From: David Howells @ 2025-09-26 14:19 UTC (permalink / raw)
  Cc: David Howells, Eric Biggers, Jason A . Donenfeld, Ard Biesheuvel,
	Herbert Xu, Stephan Mueller, linux-crypto, linux-kernel

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.

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
---
 crypto/sha3_generic.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/crypto/sha3_generic.c b/crypto/sha3_generic.c
index 6917a1aeb8e5..4fae066ec3f5 100644
--- a/crypto/sha3_generic.c
+++ b/crypto/sha3_generic.c
@@ -95,6 +95,28 @@ static struct shash_alg algs[] = { {
 	.base.cra_flags		= CRYPTO_AHASH_ALG_BLOCK_ONLY,
 	.base.cra_blocksize	= SHA3_512_BLOCK_SIZE,
 	.base.cra_module	= THIS_MODULE,
+}, {
+	.digestsize		= SHAKE128_DEFAULT_SIZE,
+	.init			= crypto_sha3_init,
+	.update			= crypto_sha3_update,
+	.finup			= crypto_sha3_finup,
+	.descsize		= sizeof(struct sha3_ctx),
+	.base.cra_name		= "shake128",
+	.base.cra_driver_name	= "shake128-generic",
+	.base.cra_flags		= CRYPTO_AHASH_ALG_BLOCK_ONLY,
+	.base.cra_blocksize	= SHAKE128_BLOCK_SIZE,
+	.base.cra_module	= THIS_MODULE,
+}, {
+	.digestsize		= SHAKE256_DEFAULT_SIZE,
+	.init			= crypto_sha3_init,
+	.update			= crypto_sha3_update,
+	.finup			= crypto_sha3_finup,
+	.descsize		= sizeof(struct sha3_ctx),
+	.base.cra_name		= "shake256",
+	.base.cra_driver_name	= "shake256-generic",
+	.base.cra_flags		= CRYPTO_AHASH_ALG_BLOCK_ONLY,
+	.base.cra_blocksize	= SHAKE256_BLOCK_SIZE,
+	.base.cra_module	= THIS_MODULE,
 } };
 
 static int __init sha3_generic_mod_init(void)
@@ -121,3 +143,7 @@ MODULE_ALIAS_CRYPTO("sha3-384");
 MODULE_ALIAS_CRYPTO("sha3-384-generic");
 MODULE_ALIAS_CRYPTO("sha3-512");
 MODULE_ALIAS_CRYPTO("sha3-512-generic");
+MODULE_ALIAS_CRYPTO("shake128");
+MODULE_ALIAS_CRYPTO("shake128-generic");
+MODULE_ALIAS_CRYPTO("shake256");
+MODULE_ALIAS_CRYPTO("shake256-generic");


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v3 8/8] crypto: SHAKE tests
  2025-09-26 14:19 [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto David Howells
                   ` (6 preceding siblings ...)
  2025-09-26 14:19 ` [PATCH v3 7/8] crypto/sha3: Add SHAKE128/256 support David Howells
@ 2025-09-26 14:19 ` David Howells
  2025-09-26 19:59 ` [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto Eric Biggers
  8 siblings, 0 replies; 27+ messages in thread
From: David Howells @ 2025-09-26 14:19 UTC (permalink / raw)
  Cc: David Howells, Eric Biggers, Jason A . Donenfeld, Ard Biesheuvel,
	Herbert Xu, Stephan Mueller, linux-crypto, linux-kernel

---
 crypto/sha3_generic.c | 14 ++++++++--
 crypto/testmgr.c      | 14 ++++++++++
 crypto/testmgr.h      | 59 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/crypto/sha3_generic.c b/crypto/sha3_generic.c
index 4fae066ec3f5..61ba1cf6eadb 100644
--- a/crypto/sha3_generic.c
+++ b/crypto/sha3_generic.c
@@ -30,6 +30,16 @@ int crypto_sha3_init(struct shash_desc *desc)
 }
 EXPORT_SYMBOL(crypto_sha3_init);
 
+static int crypto_shake_init(struct shash_desc *desc)
+{
+	struct sha3_ctx *ctx = crypto_sha3_desc(desc);
+
+	memset(ctx, 0, sizeof(*ctx));
+	ctx->block_size = crypto_shash_blocksize(desc->tfm);
+	ctx->padding = 0x1f;
+	return 0;
+}
+
 static int crypto_sha3_update(struct shash_desc *desc, const u8 *data,
 			      unsigned int len)
 {
@@ -97,7 +107,7 @@ static struct shash_alg algs[] = { {
 	.base.cra_module	= THIS_MODULE,
 }, {
 	.digestsize		= SHAKE128_DEFAULT_SIZE,
-	.init			= crypto_sha3_init,
+	.init			= crypto_shake_init,
 	.update			= crypto_sha3_update,
 	.finup			= crypto_sha3_finup,
 	.descsize		= sizeof(struct sha3_ctx),
@@ -108,7 +118,7 @@ static struct shash_alg algs[] = { {
 	.base.cra_module	= THIS_MODULE,
 }, {
 	.digestsize		= SHAKE256_DEFAULT_SIZE,
-	.init			= crypto_sha3_init,
+	.init			= crypto_shake_init,
 	.update			= crypto_sha3_update,
 	.finup			= crypto_sha3_finup,
 	.descsize		= sizeof(struct sha3_ctx),
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 9dca41e7ee73..988bda74371e 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -5511,6 +5511,20 @@ static const struct alg_test_desc alg_test_descs[] = {
 		.suite = {
 			.hash = __VECS(sha512_tv_template)
 		}
+	}, {
+		.alg = "shake128",
+		.test = alg_test_hash,
+		.fips_allowed = 1,
+		.suite = {
+			.hash = __VECS(shake128_tv_template)
+		}
+	}, {
+		.alg = "shake256",
+		.test = alg_test_hash,
+		.fips_allowed = 1,
+		.suite = {
+			.hash = __VECS(shake256_tv_template)
+		}
 	}, {
 		.alg = "sm3",
 		.test = alg_test_hash,
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 268231227282..c0eca7f72aa0 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -4690,6 +4690,65 @@ static const struct hash_testvec sha3_512_tv_template[] = {
 };
 
 
+/* From: https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/example-values */
+static const struct hash_testvec shake128_tv_template[] = {
+	{
+		.plaintext = "",
+		.psize	= 0,
+		.digest	=
+		"\x7f\x9c\x2b\xa4\xe8\x8f\x82\x7d\x61\x60\x45\x50\x76\x05\x85\x3e",
+	}, {
+		.plaintext =
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3",
+		.psize	= 200,
+		.digest	=
+		"\x13\x1a\xb8\xd2\xb5\x94\x94\x6b\x9c\x81\x33\x3f\x9b\xb6\xe0\xce",
+	}
+};
+
+/* From: https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/example-values */
+static const struct hash_testvec shake256_tv_template[] = {
+	{
+		.plaintext = "",
+		.psize	= 0,
+		.digest	=
+		"\x46\xb9\xdd\x2b\x0b\xa8\x8d\x13\x23\x3b\x3f\xeb\x74\x3e\xeb\x24"
+		"\x3f\xcd\x52\xea\x62\xb8\x1b\x82\xb5\x0c\x27\x64\x6e\xd5\x76\x2f"
+	}, {
+		.plaintext =
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3"
+		"\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3",
+		.psize	= 200,
+		.digest	=
+		"\xcd\x8a\x92\x0e\xd1\x41\xaa\x04\x07\xa2\x2d\x59\x28\x86\x52\xe9"
+		"\xd9\xf1\xa7\xee\x0c\x1e\x7c\x1c\xa6\x99\x42\x4d\xa8\x4a\x90\x4d",
+	}
+};
+
+
 /*
  * MD5 test vectors from RFC1321
  */


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto
  2025-09-26 14:19 [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto David Howells
                   ` (7 preceding siblings ...)
  2025-09-26 14:19 ` [PATCH v3 8/8] crypto: SHAKE tests David Howells
@ 2025-09-26 19:59 ` Eric Biggers
  2025-10-01 15:28   ` Eric Biggers
  8 siblings, 1 reply; 27+ messages in thread
From: Eric Biggers @ 2025-09-26 19:59 UTC (permalink / raw)
  To: David Howells
  Cc: Jason A . Donenfeld, Ard Biesheuvel, Herbert Xu, Stephan Mueller,
	linux-crypto, linux-kernel

Hi David,

On Fri, Sep 26, 2025 at 03:19:43PM +0100, David Howells wrote:
> I have done what Eric required and made a separate wrapper struct and set
> of wrapper functions for each algorithm, though I think this is excessively
> bureaucratic as this multiplies the API load by 7 (and maybe 9 in the
> future[*]).

I don't think I "required" that it be implemented in exactly this way.
Sorry if I wasn't clear.  Let me quote what I wrote:

    First, this patch's proposed API is error-prone due to the weak
    typing that allows mixing steps of different algorithms together.
    For example, users could initialize a sha3_ctx with sha3_256_init()
    and then squeeze an arbitrary amount from it, incorrectly treating
    it as a XOF.  It would be worth considering separating the APIs for
    the different algorithms that are part of SHA-3, similar to what I
    did with SHA-224 and SHA-256.  (They would of course still share
    code internally, just like SHA-2.)

So I asked that to prevent usage errors such as treating a digest as a
XOF, you consider separating the APIs.  There is more than one way to do
that, and I was hoping that you'd consider different ways.  One way is
separate functions and types for all six SHA-3 algorithms.

However, if that is not scaling well, then we could instead just
separate the SHA-3 algorithms into two groups, the digests and the XOFs:

    void sha3_224_init(struct sha3_ctx *ctx);
    void sha3_256_init(struct sha3_ctx *ctx);
    void sha3_384_init(struct sha3_ctx *ctx);
    void sha3_512_init(struct sha3_ctx *ctx);
    void sha3_update(struct sha3_ctx *ctx, const u8 *data, size_t data_len);
    void sha3_final(struct sha3_ctx *ctx, u8 *out);

    void shake128_init(struct shake_ctx *ctx);
    void shake256_init(struct shake_ctx *ctx);
    void shake_update(struct shake_ctx *ctx, const u8 *data, size_t data_len);
    void shake_squeeze(struct shake_ctx *ctx, u8 *out, size_t out_len);
    void shake_clear(struct shake_ctx *ctx);

(With "sha3_ctx" being used for the digests specifically, the internal
context struct would then have to have a third name, like "__sha3_ctx".)

The *_init() functions would store the correct information in the
context so that the other functions would know what to do.  This would
be similar to how blake2s_init() saves the 'outlen' for blake2s_final().

That would be sufficient to prevent misuse errors where steps of
different algorithms are mixed together, right?

Keep in mind that for SHA-2 we have to have completely different code
and underlying state for the 32-bit hashes (SHA-224 and SHA-256) and
64-bit hashes (SHA-384 and SHA-512) anyway.  We also traditionally
haven't kept any information in the SHA-2 context about which SHA-2
algorithm is being executed.  So that led us more down the road of the
separate functions and types for each SHA-2 algorithm.  With SHA-3,
where e.g. the 224, 256, 384, and 512-bit digests all use the same
underlying state, a slightly more unified API might be appropriate.

All I'm really requesting is that we don't create footguns, like the
following that the API in the v2 patch permitted:

    1. sha3_init() + sha3_update()
        [infinite loop]

    2. sha3_256_init() + sha3_update() + sha3_squeeze()
        [not valid, treats SHA3-256 as a XOF]

    3. sha3_update() + sha3_squeeze() + sha3_update() + sha3_squeeze()
        [not valid, as discussed]

(1) is prevented just by not having the internal function sha3_init() as
a public function.

Splitting the context into two types, one for the digests and one for
the XOFs, is sufficient to prevent (2), as long as there's still one
init function per algorithm.  We don't necessarily need six types.

(3) isn't preventable via the type system, but it's detectable by a
run-time check, which you've done by adding a WARN_ON_ONCE() to
sha3_update().

So, I think we'd be in a good position with just the digests and XOFs
separated out into different functions + types.

> This does, however, cause a problem for what I need to do as the ML-DSA
> prehash is dynamically selectable by certificate OID, so I have to add
> SHAKE128/256 support to the crypto shash API too - though hopefully it will
> only require an output of 16 or 32 bytes respectively for the prehash case
> and won't require multiple squeezing.

When there's only a small number of supported algorithms, just doing the
dispatch in the calling code tends to be simpler than using
crypto_shash.  For example, see the recent conversion of fs/verity/ to
use the SHA-2 library API instead of crypto_shash.

- Eric

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 3/8] lib/crypto: Add SHA3-224, SHA3-256, SHA3-384, SHA-512, SHAKE128, SHAKE256
  2025-09-26 14:19 ` [PATCH v3 3/8] lib/crypto: Add SHA3-224, SHA3-256, SHA3-384, SHA-512, SHAKE128, SHAKE256 David Howells
@ 2025-09-26 21:09   ` Eric Biggers
  0 siblings, 0 replies; 27+ messages in thread
From: Eric Biggers @ 2025-09-26 21:09 UTC (permalink / raw)
  To: David Howells
  Cc: Jason A . Donenfeld, Ard Biesheuvel, Herbert Xu, Stephan Mueller,
	linux-crypto, linux-kernel

On Fri, Sep 26, 2025 at 03:19:46PM +0100, David Howells wrote:
> Add SHA3, providing SHA3-224, SHA3-256, SHA3-384, SHA-512, SHAKE128 and

SHA-512 => SHA3-512

> SHAKE256 to lib/crypto.  Also add kunit tests for each of these.
> 
> gen-hash-testvecs.py is also modified to be able to generate SHAKE hashes
> because Python's hashlib requires the output digest size supplying for
> those two algorithms as they produce arbitrary length digests.

Now that the tests are in a separate patch, the above needs to be
updated.  Either remove it, or change it to say that the tests come in a
later patch.

> diff --git a/Documentation/crypto/sha3.rst b/Documentation/crypto/sha3.rst
> new file mode 100644
> index 000000000000..ae4902895882
> --- /dev/null
> +++ b/Documentation/crypto/sha3.rst
> @@ -0,0 +1,245 @@
> +.. SPDX-License-Identifier: GPL-2.0-or-later
> +
> +==========================
> +SHA-3 Algorithm collection
> +==========================
> +
> +.. Contents:
> +
> +  - Overview
> +  - Basic API
> +    - Extendable-Output Functions
> +  - Convenience API
> +  - Internal API
> +    - Testing
> +  - References
> +  - API Function Reference
> +
> +
> +Overview
> +========
> +
> +The SHA-3 algorithm base, as specified in NIST FIPS-202[1], provides a number
> +of specific algorithms all based on the same engine (Keccak).  The differences
> +between them are: the block size (how much of the common state buffer gets
> +updated with new data between invocations of the Keccak mixing function), what
> +termination markers get mixed in upon finalisation and how much data is
> +extracted at the end.  The Keccak engine is designed such that arbitrary
> +amounts of output can be obtained for certain algorithms.

Calling Keccak an "engine" and a "mixing function" is nonstandard
terminology.  It should be called a sponge function, or a permutation
when referring specifically to the permutation part (Keccak-f).

"Block size" is also not what the SHA-3 spec or publications about
Keccak use.  They call it the "rate".  Though, "block size" is widely
used in the code for other hash functions already.  So "block size" is
probably fine, but we should make sure to explicitly document that it's
also known as the rate.

> +Caution: The algorithm(s) may be accelerated with optimised assembly and, as
> +such, may have to sync with or modify the FPU or CPU Vector Unit state.  How
> +this is done is arch specific and might involve waiting or locking.

As I've mentioned, the functions should be callable in any context.  See
how the existing FPU/vector/SIMD accelerated functions in lib/crypto/
and lib/crc/ achieve this.

> +If selectable algorithms are required then the crypto_hash API must be used
> +instead as this binds each algorithm to a specific C type.

Users can choose to dispatch to different library functions themselves.
There's no requirement to use crypto_hash (or rather crypto_shash or
crypto_ahash, since "crypto_hash" doesn't exist).  They could, but it's
not required.

> +Note that these are relatively large structures, so may not be suitable for
> +placing on the stack.

Not really.  It's 208 bytes, which is a lot less than the widely-used
SHASH_DESC_ON_STACK() which uses almost 400.  And the crypto functions
tend to be called near the leaves of the call tree anyway.

Considering that as well as how much stack allocation simplifies and
optimizes the calling code, warning against it seems a bit misplaced.

> +Data is then added with the appropriate update function, again one per
> +algorithm::
> +
> +	void sha3_224_update(struct sha3_224_ctx *ctx,
> +			     const u8 *data, unsigned int len);
> +	void sha3_256_update(struct sha3_256_ctx *ctx,
> +			     const u8 *data, unsigned int len);
> +	void sha3_384_update(struct sha3_384_ctx *ctx,
> +			     const u8 *data, unsigned int len);
> +	void sha3_512_update(struct sha3_512_ctx *ctx,
> +			     const u8 *data, unsigned int len);
> +	void shake128_update(struct shake128_ctx *ctx,
> +			     const u8 *data, unsigned int len);
> +	void shake256_update(struct shake256_ctx *ctx,
> +			     const u8 *data, unsigned int len);

Lengths should be size_t.

> +	unsigned int sha3_224_final(struct sha3_224_ctx *ctx,
> +				    u8 out[SHA3_224_DIGEST_SIZE]);
> +	unsigned int sha3_256_final(struct sha3_256_ctx *ctx,
> +				    u8 out[SHA3_256_DIGEST_SIZE]);
> +	unsigned int sha3_384_final(struct sha3_384_ctx *ctx,
> +				    u8 out[SHA3_384_DIGEST_SIZE]);
> +	unsigned int sha3_512_final(struct sha3_512_ctx *ctx,
> +				    u8 out[SHA3_512_DIGEST_SIZE]);

The return value should be void.

In fact, it is void in the actual code.  This demonstrates the problem
with documenting functions in a separate Documentation/ file instead of
with standard kerneldoc right next to the functions themselves...

> +Extendable-Output Functions
> +---------------------------
> +
> +For XOFs, once the data has been added to a context, a variable amount of data
> +may be extracted.  This can be done by calling the appropriate squeeze
> +function::
> +
> +	void shake128_squeeze(struct shake128_ctx *ctx, u8 *out, size_t out_len);
> +	void shake256_squeeze(struct shake256_ctx *ctx, u8 *out, size_t out_len);
> +
> +and telling it how much data should be extracted.  The squeeze function may be
> +called multiple times but it will only finalise the context on the first
> +invocation.

The word "finalise" above should be replaced with something clearer.
Normally, in the hash function APIs, "finalizing the context" means
calling the *_final() function, which produces the digest and zeroizes
the context.  That's not what is meant here, though.

> +Internal API
> +============
> +
> +There is a common internal API underlying all of this that may be used to build
> +further algorithms or APIs as the engine in the same in all cases.  The
> +algorithm APIs all wrap the common context structure::
> +
> +	struct sha3_ctx {
> +		struct sha3_state	state;
> +		u8			block_size;
> +		u8			padding;
> +		u8			absorb_offset;
> +		u8			squeeze_offset;
> +		bool			end_marked;
> +	};
> +
> +	struct sha3_state {
> +		u64			st[SHA3_STATE_SIZE / 8];
> +	};
> +
> +The fields are as follows:

This part especially, where it documents implementation details
including individual fields, really feels like it should go in the code
itself.  Then it will be easier to find and keep in sync with the code.
Interestingly, it's *already* out of sync with the code...

> +/* SHAKE128 and SHAKE256 actually have variable output size, but this
> + * is needed for the kunit tests.
> + */
> +#define SHAKE128_DEFAULT_SIZE	(128 / 8)
> +#define SHAKE128_BLOCK_SIZE	(200 - 2 * SHAKE128_DEFAULT_SIZE)
> +#define SHAKE256_DEFAULT_SIZE	(256 / 8)
> +#define SHAKE256_BLOCK_SIZE	(200 - 2 * SHAKE256_DEFAULT_SIZE)

Test-only definitions should go in the tests, not the public header.

> +/**
> + * sha3_clear() - Explicitly clear the entire context
> + * @ctx: the context to clear
> + *
> + * Explicitly clear the entire context, including the type parameters; after
> + * this, the context must be fully initialised again.
> + *
> + * Return: None.
> + *
> + * Context: Any context.
> + */

"Return: None." doesn't add anything useful when the function returns
void.  I recommend omitting that, as is usually done.

> +/**
> + * sha3_224_init() - Set a SHA3 context for SHA3-224
> + * @ctx: the context to initialise
> + *
> + * Initialise a SHA3 context for the production of a SHA3-224 digest of a
> + * message.

Would you mind doing "initialise" => "initialize"?  The z spelling is
about 10x more common in the kernel, and it's what include/crypto/ uses.

> +static int __init sha3_mod_init(void)
> +{
> +#define out_len 200
> +	u8 out[8 + out_len + 8] = {};
> +
> +#ifdef sha3_mod_init_arch
> +	sha3_mod_init_arch();
> +#endif
> +
> +	BUILD_BUG_ON(sizeof(out) != sizeof(sha3_sample_shake256_200));
> +
> +	shake256(sha3_sample, sizeof(sha3_sample) - 1, out + 8, out_len);
> +
> +	if (memcmp(out, sha3_sample_shake256_200,
> +		   sizeof(sha3_sample_shake256_200)) != 0) {
> +		pr_err("SHAKE256(200) failed\n");
> +		for (int i = 0; i < out_len;) {
> +			int part = min(out_len - i, 32);
> +
> +			pr_err("%*phN\n", part, out + i);
> +			i += part;
> +		}
> +		return -EBADMSG;
> +	}
> +	return 0;
> +}
> +subsys_initcall(sha3_mod_init);
> +
> +#ifdef sha3_mod_init_arch
> +static void __exit sha3_mod_exit(void)
> +{
> +}
> +module_exit(sha3_mod_exit);
> +#endif

sha3_mod_exit() should be defined unconditionally, given that
sha3_mod_init() is defined unconditionally.  Otherwise, it would be
possible for this code to be built as a loadable module that can't be
unloaded, which is not desirable.

- Eric

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 7/8] crypto/sha3: Add SHAKE128/256 support
  2025-09-26 14:19 ` [PATCH v3 7/8] crypto/sha3: Add SHAKE128/256 support David Howells
@ 2025-09-26 21:14   ` Eric Biggers
  2025-10-01 13:02     ` David Howells
  0 siblings, 1 reply; 27+ messages in thread
From: Eric Biggers @ 2025-09-26 21:14 UTC (permalink / raw)
  To: David Howells
  Cc: Jason A . Donenfeld, Ard Biesheuvel, Herbert Xu, Stephan Mueller,
	linux-crypto, linux-kernel

On Fri, Sep 26, 2025 at 03:19:50PM +0100, David Howells wrote:
> 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.
> 
> 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
> ---
>  crypto/sha3_generic.c | 26 ++++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)

I recommend holding off on this part until you have a try at using the
SHAKE library API directly.  The dispatch to different algorithms could
be done in the calling code.  This patch would also limit the ML-DSA
code to fixed-size SHAKE outputs; is that really going to be enough?

- Eric

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 6/8] crypto/sha3: Use lib/crypto/sha3
  2025-09-26 14:19 ` [PATCH v3 6/8] crypto/sha3: Use lib/crypto/sha3 David Howells
@ 2025-09-26 21:25   ` Eric Biggers
  0 siblings, 0 replies; 27+ messages in thread
From: Eric Biggers @ 2025-09-26 21:25 UTC (permalink / raw)
  To: David Howells
  Cc: Jason A . Donenfeld, Ard Biesheuvel, Herbert Xu, Stephan Mueller,
	linux-crypto, linux-kernel

On Fri, Sep 26, 2025 at 03:19:49PM +0100, David Howells wrote:
> 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.
> 
> 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
> ---
>  Documentation/crypto/sha3.rst    |   8 +-
>  arch/arm64/crypto/sha3-ce-glue.c |  25 ++--
>  crypto/sha3_generic.c            | 201 +++----------------------------
>  include/crypto/sha3.h            |   6 +-
>  lib/crypto/sha3.c                |  35 +++---
>  5 files changed, 52 insertions(+), 223 deletions(-)

What's worked well for the other algorithms is to do things in this
order:

    1. Move the arch-specific implementations into lib/crypto/,
       making them available via the library API and temporarily
       removing them from the crypto_shash API.  One patch per arch.

    2. Replace crypto/${alg}_generic.c with crypto/${alg}.c that is
       built directly on the library API.  The algorithms are called
       "*-lib" instead of "*-generic", and they don't use the
       crypto_shash generic partial block handling.

Again, if you don't want to do all that, I'd be glad to do it.  I'd be a
bit hesitant to take this patch instead, as it sort of starts out going
in a different direction.  So it would create a temporary situation, and
we'd need to make sure that temporary situation works.  (FWIW, this
patch breaks the build of sha3-ce-glue.c, so that's not a great start.)

- Eric

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 1/8] s390/sha3: Rename conflicting functions
  2025-09-26 14:19 ` [PATCH v3 1/8] s390/sha3: Rename conflicting functions David Howells
@ 2025-09-29 11:39   ` Harald Freudenberger
  0 siblings, 0 replies; 27+ messages in thread
From: Harald Freudenberger @ 2025-09-29 11:39 UTC (permalink / raw)
  To: David Howells
  Cc: Eric Biggers, Jason A . Donenfeld, Ard Biesheuvel, Herbert Xu,
	Stephan Mueller, linux-crypto, linux-kernel, Holger Dengler,
	linux-s390

On 2025-09-26 16:19, David Howells wrote:
> Rename the s390 sha3_* functions to have an "s390_" 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: Harald Freudenberger <freude@linux.ibm.com>
> 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
> ---
>  arch/s390/crypto/sha3_256_s390.c | 26 +++++++++++++-------------
>  arch/s390/crypto/sha3_512_s390.c | 26 +++++++++++++-------------
>  2 files changed, 26 insertions(+), 26 deletions(-)
> 
> diff --git a/arch/s390/crypto/sha3_256_s390.c 
> b/arch/s390/crypto/sha3_256_s390.c
> index 03bb4f4bab70..fd5ecae60a57 100644
> --- a/arch/s390/crypto/sha3_256_s390.c
> +++ b/arch/s390/crypto/sha3_256_s390.c
> @@ -19,7 +19,7 @@
> 
>  #include "sha.h"
> 
> -static int sha3_256_init(struct shash_desc *desc)
> +static int s390_sha3_256_init(struct shash_desc *desc)
>  {
>  	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
> 
> @@ -32,7 +32,7 @@ static int sha3_256_init(struct shash_desc *desc)
>  	return 0;
>  }
> 
> -static int sha3_256_export(struct shash_desc *desc, void *out)
> +static int s390_sha3_256_export(struct shash_desc *desc, void *out)
>  {
>  	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
>  	union {
> @@ -50,7 +50,7 @@ static int sha3_256_export(struct shash_desc *desc, 
> void *out)
>  	return 0;
>  }
> 
> -static int sha3_256_import(struct shash_desc *desc, const void *in)
> +static int s390_sha3_256_import(struct shash_desc *desc, const void 
> *in)
>  {
>  	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
>  	union {
> @@ -68,22 +68,22 @@ static int sha3_256_import(struct shash_desc
> *desc, const void *in)
>  	return 0;
>  }
> 
> -static int sha3_224_import(struct shash_desc *desc, const void *in)
> +static int s390_sha3_224_import(struct shash_desc *desc, const void 
> *in)
>  {
>  	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
> 
> -	sha3_256_import(desc, in);
> +	s390_sha3_256_import(desc, in);
>  	sctx->func = CPACF_KIMD_SHA3_224;
>  	return 0;
>  }
> 
>  static struct shash_alg sha3_256_alg = {
>  	.digestsize	=	SHA3_256_DIGEST_SIZE,	   /* = 32 */
> -	.init		=	sha3_256_init,
> +	.init		=	s390_sha3_256_init,
>  	.update		=	s390_sha_update_blocks,
>  	.finup		=	s390_sha_finup,
> -	.export		=	sha3_256_export,
> -	.import		=	sha3_256_import,
> +	.export		=	s390_sha3_256_export,
> +	.import		=	s390_sha3_256_import,
>  	.descsize	=	S390_SHA_CTX_SIZE,
>  	.statesize	=	SHA3_STATE_SIZE,
>  	.base		=	{
> @@ -96,22 +96,22 @@ static struct shash_alg sha3_256_alg = {
>  	}
>  };
> 
> -static int sha3_224_init(struct shash_desc *desc)
> +static int s390_sha3_224_init(struct shash_desc *desc)
>  {
>  	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
> 
> -	sha3_256_init(desc);
> +	s390_sha3_256_init(desc);
>  	sctx->func = CPACF_KIMD_SHA3_224;
>  	return 0;
>  }
> 
>  static struct shash_alg sha3_224_alg = {
>  	.digestsize	=	SHA3_224_DIGEST_SIZE,
> -	.init		=	sha3_224_init,
> +	.init		=	s390_sha3_224_init,
>  	.update		=	s390_sha_update_blocks,
>  	.finup		=	s390_sha_finup,
> -	.export		=	sha3_256_export, /* same as for 256 */
> -	.import		=	sha3_224_import, /* function code different! */
> +	.export		=	s390_sha3_256_export, /* same as for 256 */
> +	.import		=	s390_sha3_224_import, /* function code different! */
>  	.descsize	=	S390_SHA_CTX_SIZE,
>  	.statesize	=	SHA3_STATE_SIZE,
>  	.base		=	{
> diff --git a/arch/s390/crypto/sha3_512_s390.c 
> b/arch/s390/crypto/sha3_512_s390.c
> index a5c9690eecb1..f4b52a3a0433 100644
> --- a/arch/s390/crypto/sha3_512_s390.c
> +++ b/arch/s390/crypto/sha3_512_s390.c
> @@ -18,7 +18,7 @@
> 
>  #include "sha.h"
> 
> -static int sha3_512_init(struct shash_desc *desc)
> +static int s390_sha3_512_init(struct shash_desc *desc)
>  {
>  	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
> 
> @@ -31,7 +31,7 @@ static int sha3_512_init(struct shash_desc *desc)
>  	return 0;
>  }
> 
> -static int sha3_512_export(struct shash_desc *desc, void *out)
> +static int s390_sha3_512_export(struct shash_desc *desc, void *out)
>  {
>  	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
>  	union {
> @@ -49,7 +49,7 @@ static int sha3_512_export(struct shash_desc *desc, 
> void *out)
>  	return 0;
>  }
> 
> -static int sha3_512_import(struct shash_desc *desc, const void *in)
> +static int s390_sha3_512_import(struct shash_desc *desc, const void 
> *in)
>  {
>  	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
>  	union {
> @@ -67,22 +67,22 @@ static int sha3_512_import(struct shash_desc
> *desc, const void *in)
>  	return 0;
>  }
> 
> -static int sha3_384_import(struct shash_desc *desc, const void *in)
> +static int s390_sha3_384_import(struct shash_desc *desc, const void 
> *in)
>  {
>  	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
> 
> -	sha3_512_import(desc, in);
> +	s390_sha3_512_import(desc, in);
>  	sctx->func = CPACF_KIMD_SHA3_384;
>  	return 0;
>  }
> 
>  static struct shash_alg sha3_512_alg = {
>  	.digestsize	=	SHA3_512_DIGEST_SIZE,
> -	.init		=	sha3_512_init,
> +	.init		=	s390_sha3_512_init,
>  	.update		=	s390_sha_update_blocks,
>  	.finup		=	s390_sha_finup,
> -	.export		=	sha3_512_export,
> -	.import		=	sha3_512_import,
> +	.export		=	s390_sha3_512_export,
> +	.import		=	s390_sha3_512_import,
>  	.descsize	=	S390_SHA_CTX_SIZE,
>  	.statesize	=	SHA3_STATE_SIZE,
>  	.base		=	{
> @@ -97,22 +97,22 @@ static struct shash_alg sha3_512_alg = {
> 
>  MODULE_ALIAS_CRYPTO("sha3-512");
> 
> -static int sha3_384_init(struct shash_desc *desc)
> +static int s390_sha3_384_init(struct shash_desc *desc)
>  {
>  	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
> 
> -	sha3_512_init(desc);
> +	s390_sha3_512_init(desc);
>  	sctx->func = CPACF_KIMD_SHA3_384;
>  	return 0;
>  }
> 
>  static struct shash_alg sha3_384_alg = {
>  	.digestsize	=	SHA3_384_DIGEST_SIZE,
> -	.init		=	sha3_384_init,
> +	.init		=	s390_sha3_384_init,
>  	.update		=	s390_sha_update_blocks,
>  	.finup		=	s390_sha_finup,
> -	.export		=	sha3_512_export, /* same as for 512 */
> -	.import		=	sha3_384_import, /* function code different! */
> +	.export		=	s390_sha3_512_export, /* same as for 512 */
> +	.import		=	s390_sha3_384_import, /* function code different! */
>  	.descsize	=	S390_SHA_CTX_SIZE,
>  	.statesize	=	SHA3_STATE_SIZE,
>  	.base		=	{

Acked-By: Harald Freudenberger <freude@linux.ibm.com>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 7/8] crypto/sha3: Add SHAKE128/256 support
  2025-09-26 21:14   ` Eric Biggers
@ 2025-10-01 13:02     ` David Howells
  2025-10-01 15:25       ` Eric Biggers
  0 siblings, 1 reply; 27+ messages in thread
From: David Howells @ 2025-10-01 13:02 UTC (permalink / raw)
  To: Eric Biggers
  Cc: dhowells, Jason A . Donenfeld, Ard Biesheuvel, Herbert Xu,
	Stephan Mueller, linux-crypto, linux-kernel

Eric Biggers <ebiggers@kernel.org> wrote:

> I recommend holding off on this part until you have a try at using the
> SHAKE library API directly.  The dispatch to different algorithms could
> be done in the calling code.  This patch would also limit the ML-DSA
> code to fixed-size SHAKE outputs; is that really going to be enough?

Actually, ML-DSA also allows SHA2 hashes for the prehash, so if I use
crypto_shash for that, then I maintain the flexibility through that.

> When there's only a small number of supported algorithms, just doing the
> dispatch in the calling code tends to be simpler than using
> crypto_shash.  For example, see the recent conversion of fs/verity/ to
> use the SHA-2 library API instead of crypto_shash.

That's reinventing the wheel.  Why have crypto_shash at all if we're going to
encourage people to ignore that and use a union and an enum/ops table.

Is the goal to get rid of crypto/ entirely and use lib/crypto/ instead?  Not
that I wouldn't mind a better crypto offloading API - the one we have kind of
sucks, especially for offloading to async crypto h/w (sorry Herbert;-)).

David


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 7/8] crypto/sha3: Add SHAKE128/256 support
  2025-10-01 13:02     ` David Howells
@ 2025-10-01 15:25       ` Eric Biggers
  0 siblings, 0 replies; 27+ messages in thread
From: Eric Biggers @ 2025-10-01 15:25 UTC (permalink / raw)
  To: David Howells
  Cc: Jason A . Donenfeld, Ard Biesheuvel, Herbert Xu, Stephan Mueller,
	linux-crypto, linux-kernel

On Wed, Oct 01, 2025 at 02:02:26PM +0100, David Howells wrote:
> Eric Biggers <ebiggers@kernel.org> wrote:
> 
> > I recommend holding off on this part until you have a try at using the
> > SHAKE library API directly.  The dispatch to different algorithms could
> > be done in the calling code.  This patch would also limit the ML-DSA
> > code to fixed-size SHAKE outputs; is that really going to be enough?
> 
> Actually, ML-DSA also allows SHA2 hashes for the prehash, so if I use
> crypto_shash for that, then I maintain the flexibility through that.
> 
> > When there's only a small number of supported algorithms, just doing the
> > dispatch in the calling code tends to be simpler than using
> > crypto_shash.  For example, see the recent conversion of fs/verity/ to
> > use the SHA-2 library API instead of crypto_shash.
> 
> That's reinventing the wheel.

Not really.  As I said, in fs/verity/ it was simpler to use the library
APIs, even with multiple algorithms.  I got similar results in net/sctp/
too.  The library APIs are also faster, due to eliminating overhead such
as algorithm lookup by name and indirect calls.

With the library it's also much easier to implement things that don't
fit into the existing paradigm well, such as XOFs.  Case in this point:
this patch adds "shake128" and "shake256" to crypto_shash, but only
offers fixed-size digests.  Which kind of defeats the point of SHAKE.

> Why have crypto_shash at all if we're going to
> encourage people to ignore that and use a union and an enum/ops table.

Mainly because some subsystems accept an arbitrary string in "Crypto API
algorithm syntax" from userspace, and they have to continue supporting
that for backwards compatibility.

Anyway, I'm not saying that you *can't* use crypto_shash.  Just the way
you described it, where using crypto_shash is *required* as soon as
there are two possible algorithms, is not correct.  It's an option.

- Eric

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto
  2025-09-26 19:59 ` [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto Eric Biggers
@ 2025-10-01 15:28   ` Eric Biggers
  2025-10-02 13:14     ` David Howells
  0 siblings, 1 reply; 27+ messages in thread
From: Eric Biggers @ 2025-10-01 15:28 UTC (permalink / raw)
  To: David Howells
  Cc: Jason A . Donenfeld, Ard Biesheuvel, Herbert Xu, Stephan Mueller,
	linux-crypto, linux-kernel

Hi David,

On Fri, Sep 26, 2025 at 12:59:58PM -0700, Eric Biggers wrote:
> Hi David,
> 
> On Fri, Sep 26, 2025 at 03:19:43PM +0100, David Howells wrote:
> > I have done what Eric required and made a separate wrapper struct and set
> > of wrapper functions for each algorithm, though I think this is excessively
> > bureaucratic as this multiplies the API load by 7 (and maybe 9 in the
> > future[*]).
> 
> I don't think I "required" that it be implemented in exactly this way.
> Sorry if I wasn't clear.  Let me quote what I wrote:

Have you had a chance to read this reply?  In the v4 patchset I don't
see any evidence that you read this reply.  And you didn't respond to it
either.

- Eric

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 5/8] lib/crypto: Add SHA3 kunit tests
  2025-09-26 14:19 ` [PATCH v3 5/8] lib/crypto: Add SHA3 kunit tests David Howells
@ 2025-10-01 16:04   ` Eric Biggers
  2025-10-01 16:08     ` Eric Biggers
  2025-10-02 13:05     ` David Howells
  0 siblings, 2 replies; 27+ messages in thread
From: Eric Biggers @ 2025-10-01 16:04 UTC (permalink / raw)
  To: David Howells
  Cc: Jason A . Donenfeld, Ard Biesheuvel, Herbert Xu, Stephan Mueller,
	linux-crypto, linux-kernel

On Fri, Sep 26, 2025 at 03:19:48PM +0100, David Howells wrote:
> +config CRYPTO_LIB_SHA3_KUNIT_TEST
> +	tristate "KUnit tests for SHA-3" if !KUNIT_ALL_TESTS
> +	depends on KUNIT
> +	default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS
> +	select CRYPTO_LIB_BENCHMARK_VISIBLE
> +	select CRYPTO_LIB_SHA3
> +	help
> +	  KUnit tests for the SHA3 cryptographic hash functions, including
> +	  SHA3-224, SHA3-256, SHA3-386, SHA3-512, SHAKE128 and SHAKE256.  Note

SHA3-386 => SHA3-384

> +	  that whilst the SHAKE* hash functions can support arbitrary-length
> +	  digests, these tests only check the nominal digest sizes for now.

Arbitrary-length output support needs to be tested.  It looks like it is
now, and you just forgot to update this help text?

> +static const u8 test_sha3_sample[] =
> +	"The quick red fox jumped over the lazy brown dog!\n"
> +	"The quick red fox jumped over the lazy brown dog!\n"
> +	"The quick red fox jumped over the lazy brown dog!\n"
> +	"The quick red fox jumped over the lazy brown dog!\n";
> +
> +static const u8 test_sha3_224[8 + SHA3_224_DIGEST_SIZE + 8] = {
> +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
> +	0xd6, 0xe8, 0xd8, 0x80, 0xfa, 0x42, 0x80, 0x70,
> +	0x7e, 0x7f, 0xd7, 0xd2, 0xd7, 0x7a, 0x35, 0x65,
> +	0xf0, 0x0b, 0x4f, 0x9f, 0x2a, 0x33, 0xca, 0x0a,
> +	0xef, 0xa6, 0x4c, 0xb8,
> +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
> +};
> +
> +static const u8 test_sha3_256[8 + SHA3_256_DIGEST_SIZE + 8] = {
> +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
> +	0xdb, 0x3b, 0xb0, 0xb8, 0x8d, 0x15, 0x78, 0xe5,
> +	0x78, 0x76, 0x8e, 0x39, 0x7e, 0x89, 0x86, 0xb9,
> +	0x14, 0x3a, 0x1e, 0xe7, 0x96, 0x7c, 0xf3, 0x25,
> +	0x70, 0xbd, 0xc3, 0xa9, 0xae, 0x63, 0x71, 0x1d,
> +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
> +};
> +
> +static const u8 test_sha3_384[8 + SHA3_384_DIGEST_SIZE + 8] = {
> +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
> +	0x2d, 0x4b, 0x29, 0x85, 0x19, 0x94, 0xaa, 0x31,
> +	0x9b, 0x04, 0x9d, 0x6e, 0x79, 0x66, 0xc7, 0x56,
> +	0x8a, 0x2e, 0x99, 0x84, 0x06, 0xcf, 0x10, 0x2d,
> +	0xec, 0xf0, 0x03, 0x04, 0x1f, 0xd5, 0x99, 0x63,
> +	0x2f, 0xc3, 0x2b, 0x0d, 0xd9, 0x45, 0xf7, 0xbb,
> +	0x0a, 0xc3, 0x46, 0xab, 0xfe, 0x4d, 0x94, 0xc2,
> +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
> +};
> +
> +static const u8 test_sha3_512[8 + SHA3_512_DIGEST_SIZE + 8] = {
> +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
> +	0xdd, 0x71, 0x3b, 0x44, 0xb6, 0x6c, 0xd7, 0x78,
> +	0xe7, 0x93, 0xa1, 0x4c, 0xd7, 0x24, 0x16, 0xf1,
> +	0xfd, 0xa2, 0x82, 0x4e, 0xed, 0x59, 0xe9, 0x83,
> +	0x15, 0x38, 0x89, 0x7d, 0x39, 0x17, 0x0c, 0xb2,
> +	0xcf, 0x12, 0x80, 0x78, 0xa1, 0x78, 0x41, 0xeb,
> +	0xed, 0x21, 0x4c, 0xa4, 0x4a, 0x5f, 0x30, 0x1a,
> +	0x70, 0x98, 0x4f, 0x14, 0xa2, 0xd1, 0x64, 0x1b,
> +	0xc2, 0x0a, 0xff, 0x3b, 0xe8, 0x26, 0x41, 0x8f,
> +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
> +};
> +
> +static const u8 test_shake128[8 + SHAKE128_DEFAULT_SIZE + 8] = {
> +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
> +	0x41, 0xd6, 0xb8, 0x9c, 0xf8, 0xe8, 0x54, 0xf2,
> +	0x5c, 0xde, 0x51, 0x12, 0xaf, 0x9e, 0x0d, 0x91,
> +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
> +};
> +
> +static const u8 test_shake256[8 + SHAKE256_DEFAULT_SIZE + 8] = {
> +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
> +	0xab, 0x06, 0xd4, 0xf9, 0x8b, 0xfd, 0xb2, 0xc4,
> +	0xfe, 0xf1, 0xcc, 0xe2, 0x40, 0x45, 0xdd, 0x15,
> +	0xcb, 0xdd, 0x02, 0x8d, 0xb7, 0x9f, 0x1e, 0x67,
> +	0xd6, 0x7f, 0x98, 0x5e, 0x1b, 0x19, 0xf8, 0x01,
> +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
> +};

If these expected outputs are from an external source, then that source
needs to be documented.  If they aren't, then the way in which they were
generated needs to be easily reproducible and documented, e.g. by adding
support for generating them to gen-hash-testvecs.py.

> +MODULE_DESCRIPTION("KUnit tests and benchmark for SHA3-256");

SHA3-256 => SHA3

> diff --git a/lib/crypto/tests/sha3_testvecs.h b/lib/crypto/tests/sha3_testvecs.h
> new file mode 100644
> index 000000000000..9c4c403cc6e0
> --- /dev/null
> +++ b/lib/crypto/tests/sha3_testvecs.h
> @@ -0,0 +1,231 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/* This file was generated by: ./scripts/crypto/gen-hash-testvecs.py sha3-256 */

If that's the case, then running "./scripts/crypto/gen-hash-testvecs.py
sha3-256 > lib/crypto/tests/sha3_testvecs.h" should reproduce this file
exactly.  But it doesn't, so you must have manually edited this file.

It should match exactly.  That can be done by tweaking
gen-hash-testvecs.py to use the correct *_DIGEST_SIZE constant and
skipping the HMAC test if sha3-256 is requested.

> diff --git a/scripts/crypto/gen-hash-testvecs.py b/scripts/crypto/gen-hash-testvecs.py
> index fc063f2ee95f..a5b0abd8dabe 100755
> --- a/scripts/crypto/gen-hash-testvecs.py
> +++ b/scripts/crypto/gen-hash-testvecs.py
> @@ -61,6 +61,10 @@ def hash_update(ctx, data):
>      ctx.update(data)
>  
>  def hash_final(ctx):
> +    if ctx.name == "shake_128":
> +        return ctx.digest(16)
> +    if ctx.name == "shake_256":
> +        return ctx.digest(32)

This addition is unnecessary.

>      return ctx.digest()
>  
>  def compute_hash(alg, data):
> @@ -122,7 +126,7 @@ def gen_hmac_testvecs(alg):
>          ctx.update(mac)
>      print_static_u8_array_definition(
>              f'hmac_testvec_consolidated[{alg.upper()}_DIGEST_SIZE]',
> -            ctx.digest())
> +            hash_final(ctx))
>  
>  BLAKE2S_KEY_SIZE = 32
>  BLAKE2S_HASH_SIZE = 32
> @@ -164,5 +168,5 @@ if alg == 'blake2s':
>      gen_additional_blake2s_testvecs()
>  elif alg == 'poly1305':
>      gen_additional_poly1305_testvecs()
> -else:
> +elif alg != 'shake128' and alg != 'shake256':
>      gen_hmac_testvecs(alg)

Likewise.  Except it really needs to be 'sha3-256', as I mentioned.

- Eric

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 5/8] lib/crypto: Add SHA3 kunit tests
  2025-10-01 16:04   ` Eric Biggers
@ 2025-10-01 16:08     ` Eric Biggers
  2025-10-02 13:05     ` David Howells
  1 sibling, 0 replies; 27+ messages in thread
From: Eric Biggers @ 2025-10-01 16:08 UTC (permalink / raw)
  To: David Howells
  Cc: Jason A . Donenfeld, Ard Biesheuvel, Herbert Xu, Stephan Mueller,
	linux-crypto, linux-kernel

On Wed, Oct 01, 2025 at 09:04:35AM -0700, Eric Biggers wrote:
> On Fri, Sep 26, 2025 at 03:19:48PM +0100, David Howells wrote:
> > +config CRYPTO_LIB_SHA3_KUNIT_TEST
> > +	tristate "KUnit tests for SHA-3" if !KUNIT_ALL_TESTS
> > +	depends on KUNIT
> > +	default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS
> > +	select CRYPTO_LIB_BENCHMARK_VISIBLE
> > +	select CRYPTO_LIB_SHA3
> > +	help
> > +	  KUnit tests for the SHA3 cryptographic hash functions, including
> > +	  SHA3-224, SHA3-256, SHA3-386, SHA3-512, SHAKE128 and SHAKE256.  Note
> 
> SHA3-386 => SHA3-384
> 
> > +	  that whilst the SHAKE* hash functions can support arbitrary-length
> > +	  digests, these tests only check the nominal digest sizes for now.
> 
> Arbitrary-length output support needs to be tested.  It looks like it is
> now, and you just forgot to update this help text?
> 
> > +static const u8 test_sha3_sample[] =
> > +	"The quick red fox jumped over the lazy brown dog!\n"
> > +	"The quick red fox jumped over the lazy brown dog!\n"
> > +	"The quick red fox jumped over the lazy brown dog!\n"
> > +	"The quick red fox jumped over the lazy brown dog!\n";
> > +
> > +static const u8 test_sha3_224[8 + SHA3_224_DIGEST_SIZE + 8] = {
> > +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
> > +	0xd6, 0xe8, 0xd8, 0x80, 0xfa, 0x42, 0x80, 0x70,
> > +	0x7e, 0x7f, 0xd7, 0xd2, 0xd7, 0x7a, 0x35, 0x65,
> > +	0xf0, 0x0b, 0x4f, 0x9f, 0x2a, 0x33, 0xca, 0x0a,
> > +	0xef, 0xa6, 0x4c, 0xb8,
> > +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
> > +};
> > +
> > +static const u8 test_sha3_256[8 + SHA3_256_DIGEST_SIZE + 8] = {
> > +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
> > +	0xdb, 0x3b, 0xb0, 0xb8, 0x8d, 0x15, 0x78, 0xe5,
> > +	0x78, 0x76, 0x8e, 0x39, 0x7e, 0x89, 0x86, 0xb9,
> > +	0x14, 0x3a, 0x1e, 0xe7, 0x96, 0x7c, 0xf3, 0x25,
> > +	0x70, 0xbd, 0xc3, 0xa9, 0xae, 0x63, 0x71, 0x1d,
> > +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
> > +};
> > +
> > +static const u8 test_sha3_384[8 + SHA3_384_DIGEST_SIZE + 8] = {
> > +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
> > +	0x2d, 0x4b, 0x29, 0x85, 0x19, 0x94, 0xaa, 0x31,
> > +	0x9b, 0x04, 0x9d, 0x6e, 0x79, 0x66, 0xc7, 0x56,
> > +	0x8a, 0x2e, 0x99, 0x84, 0x06, 0xcf, 0x10, 0x2d,
> > +	0xec, 0xf0, 0x03, 0x04, 0x1f, 0xd5, 0x99, 0x63,
> > +	0x2f, 0xc3, 0x2b, 0x0d, 0xd9, 0x45, 0xf7, 0xbb,
> > +	0x0a, 0xc3, 0x46, 0xab, 0xfe, 0x4d, 0x94, 0xc2,
> > +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
> > +};
> > +
> > +static const u8 test_sha3_512[8 + SHA3_512_DIGEST_SIZE + 8] = {
> > +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
> > +	0xdd, 0x71, 0x3b, 0x44, 0xb6, 0x6c, 0xd7, 0x78,
> > +	0xe7, 0x93, 0xa1, 0x4c, 0xd7, 0x24, 0x16, 0xf1,
> > +	0xfd, 0xa2, 0x82, 0x4e, 0xed, 0x59, 0xe9, 0x83,
> > +	0x15, 0x38, 0x89, 0x7d, 0x39, 0x17, 0x0c, 0xb2,
> > +	0xcf, 0x12, 0x80, 0x78, 0xa1, 0x78, 0x41, 0xeb,
> > +	0xed, 0x21, 0x4c, 0xa4, 0x4a, 0x5f, 0x30, 0x1a,
> > +	0x70, 0x98, 0x4f, 0x14, 0xa2, 0xd1, 0x64, 0x1b,
> > +	0xc2, 0x0a, 0xff, 0x3b, 0xe8, 0x26, 0x41, 0x8f,
> > +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
> > +};
> > +
> > +static const u8 test_shake128[8 + SHAKE128_DEFAULT_SIZE + 8] = {
> > +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
> > +	0x41, 0xd6, 0xb8, 0x9c, 0xf8, 0xe8, 0x54, 0xf2,
> > +	0x5c, 0xde, 0x51, 0x12, 0xaf, 0x9e, 0x0d, 0x91,
> > +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
> > +};
> > +
> > +static const u8 test_shake256[8 + SHAKE256_DEFAULT_SIZE + 8] = {
> > +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */
> > +	0xab, 0x06, 0xd4, 0xf9, 0x8b, 0xfd, 0xb2, 0xc4,
> > +	0xfe, 0xf1, 0xcc, 0xe2, 0x40, 0x45, 0xdd, 0x15,
> > +	0xcb, 0xdd, 0x02, 0x8d, 0xb7, 0x9f, 0x1e, 0x67,
> > +	0xd6, 0x7f, 0x98, 0x5e, 0x1b, 0x19, 0xf8, 0x01,
> > +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */
> > +};
> 
> If these expected outputs are from an external source, then that source
> needs to be documented.  If they aren't, then the way in which they were
> generated needs to be easily reproducible and documented, e.g. by adding
> support for generating them to gen-hash-testvecs.py.
> 
> > +MODULE_DESCRIPTION("KUnit tests and benchmark for SHA3-256");
> 
> SHA3-256 => SHA3
> 
> > diff --git a/lib/crypto/tests/sha3_testvecs.h b/lib/crypto/tests/sha3_testvecs.h
> > new file mode 100644
> > index 000000000000..9c4c403cc6e0
> > --- /dev/null
> > +++ b/lib/crypto/tests/sha3_testvecs.h
> > @@ -0,0 +1,231 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/* This file was generated by: ./scripts/crypto/gen-hash-testvecs.py sha3-256 */
> 
> If that's the case, then running "./scripts/crypto/gen-hash-testvecs.py
> sha3-256 > lib/crypto/tests/sha3_testvecs.h" should reproduce this file
> exactly.  But it doesn't, so you must have manually edited this file.
> 
> It should match exactly.  That can be done by tweaking
> gen-hash-testvecs.py to use the correct *_DIGEST_SIZE constant and
> skipping the HMAC test if sha3-256 is requested.
> 
> > diff --git a/scripts/crypto/gen-hash-testvecs.py b/scripts/crypto/gen-hash-testvecs.py
> > index fc063f2ee95f..a5b0abd8dabe 100755
> > --- a/scripts/crypto/gen-hash-testvecs.py
> > +++ b/scripts/crypto/gen-hash-testvecs.py
> > @@ -61,6 +61,10 @@ def hash_update(ctx, data):
> >      ctx.update(data)
> >  
> >  def hash_final(ctx):
> > +    if ctx.name == "shake_128":
> > +        return ctx.digest(16)
> > +    if ctx.name == "shake_256":
> > +        return ctx.digest(32)
> 
> This addition is unnecessary.
> 
> >      return ctx.digest()
> >  
> >  def compute_hash(alg, data):
> > @@ -122,7 +126,7 @@ def gen_hmac_testvecs(alg):
> >          ctx.update(mac)
> >      print_static_u8_array_definition(
> >              f'hmac_testvec_consolidated[{alg.upper()}_DIGEST_SIZE]',
> > -            ctx.digest())
> > +            hash_final(ctx))
> >  
> >  BLAKE2S_KEY_SIZE = 32
> >  BLAKE2S_HASH_SIZE = 32
> > @@ -164,5 +168,5 @@ if alg == 'blake2s':
> >      gen_additional_blake2s_testvecs()
> >  elif alg == 'poly1305':
> >      gen_additional_poly1305_testvecs()
> > -else:
> > +elif alg != 'shake128' and alg != 'shake256':
> >      gen_hmac_testvecs(alg)
> 
> Likewise.  Except it really needs to be 'sha3-256', as I mentioned.

Ah sorry, I meant to leave this feedback on v4.  This patch is identical
in v3 and v4, though, so all this still applies.

- Eric

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 5/8] lib/crypto: Add SHA3 kunit tests
  2025-10-01 16:04   ` Eric Biggers
  2025-10-01 16:08     ` Eric Biggers
@ 2025-10-02 13:05     ` David Howells
  2025-10-02 16:07       ` Eric Biggers
  1 sibling, 1 reply; 27+ messages in thread
From: David Howells @ 2025-10-02 13:05 UTC (permalink / raw)
  To: Eric Biggers
  Cc: dhowells, Jason A . Donenfeld, Ard Biesheuvel, Herbert Xu,
	Stephan Mueller, linux-crypto, linux-kernel

Eric Biggers <ebiggers@kernel.org> wrote:

> SHA3-386 => SHA3-384

Hah.  Possibly I'm too practised at writing "386".

> If these expected outputs are from an external source, then that source
> needs to be documented.  If they aren't, then the way in which they were
> generated needs to be easily reproducible and documented, e.g. by adding
> support for generating them to gen-hash-testvecs.py.

I generated them with openssl.  I'll add a note in the code.

> If that's the case, then running "./scripts/crypto/gen-hash-testvecs.py
> sha3-256 > lib/crypto/tests/sha3_testvecs.h" should reproduce this file
> exactly.  But it doesn't, so you must have manually edited this file.
> 
> It should match exactly.  That can be done by tweaking
> gen-hash-testvecs.py to use the correct *_DIGEST_SIZE constant and
> skipping the HMAC test if sha3-256 is requested.

gen-hash-testvecs.py doesn't know how to handle dashes in the algo name and
they end up coming in the output as "SHA3-256_DIGEST_SIZE".

It also generated an HMAC thing despite sha3-256 not having HMAC support, so I
just trimmed that off.

Anyway, I can modify the gen script to deal with both of those.

> >  def hash_final(ctx):
> > +    if ctx.name == "shake_128":
> > +        return ctx.digest(16)
> > +    if ctx.name == "shake_256":
> > +        return ctx.digest(32)
> 
> This addition is unnecessary.

Well, you can't generate SHAKE128 or SHAKE256 without it as the digest()
method has a mandatory parameter for XOF algorithms.  This fixes that.

David


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto
  2025-10-01 15:28   ` Eric Biggers
@ 2025-10-02 13:14     ` David Howells
  2025-10-02 16:27       ` Eric Biggers
  0 siblings, 1 reply; 27+ messages in thread
From: David Howells @ 2025-10-02 13:14 UTC (permalink / raw)
  To: Eric Biggers
  Cc: dhowells, Jason A . Donenfeld, Ard Biesheuvel, Herbert Xu,
	Stephan Mueller, linux-crypto, linux-kernel

Eric Biggers <ebiggers@kernel.org> wrote:

> Have you had a chance to read this reply?

I have.

You held up your implementation of sha256 and sha224 as an example of how it
perhaps should be implemented:

	It would be worth considering separating the APIs for the different
	algorithms that are part of SHA-3, similar to what I did with SHA-224
	and SHA-256.

so I have followed that.  That defines a type for each, so I'll leave it at
that.

> All I'm really requesting is that we don't create footguns, like the
> following that the API in the v2 patch permitted:

The way you did a separate type for each removed one more footgun - and
arguably a more important one - as the *type* enforces[1] the output buffer
size and the sha3_*_final() function has the same sized-array as the
convenience wrappers.

It also eliminates the need to store the digest size as this is only needed at
the final step for the digest variant algorithms.

David

[1] Inasmuch as this is effective in C.


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 5/8] lib/crypto: Add SHA3 kunit tests
  2025-10-02 13:05     ` David Howells
@ 2025-10-02 16:07       ` Eric Biggers
  0 siblings, 0 replies; 27+ messages in thread
From: Eric Biggers @ 2025-10-02 16:07 UTC (permalink / raw)
  To: David Howells
  Cc: Jason A . Donenfeld, Ard Biesheuvel, Herbert Xu, Stephan Mueller,
	linux-crypto, linux-kernel

On Thu, Oct 02, 2025 at 02:05:47PM +0100, David Howells wrote:
> Eric Biggers <ebiggers@kernel.org> wrote:
> 
> > SHA3-386 => SHA3-384
> 
> Hah.  Possibly I'm too practised at writing "386".
> 
> > If these expected outputs are from an external source, then that source
> > needs to be documented.  If they aren't, then the way in which they were
> > generated needs to be easily reproducible and documented, e.g. by adding
> > support for generating them to gen-hash-testvecs.py.
> 
> I generated them with openssl.  I'll add a note in the code.
> 
> > If that's the case, then running "./scripts/crypto/gen-hash-testvecs.py
> > sha3-256 > lib/crypto/tests/sha3_testvecs.h" should reproduce this file
> > exactly.  But it doesn't, so you must have manually edited this file.
> > 
> > It should match exactly.  That can be done by tweaking
> > gen-hash-testvecs.py to use the correct *_DIGEST_SIZE constant and
> > skipping the HMAC test if sha3-256 is requested.
> 
> gen-hash-testvecs.py doesn't know how to handle dashes in the algo name and
> they end up coming in the output as "SHA3-256_DIGEST_SIZE".
> 
> It also generated an HMAC thing despite sha3-256 not having HMAC support, so I
> just trimmed that off.
> 
> Anyway, I can modify the gen script to deal with both of those.

Yes, that's what I'm asking for.

> > >  def hash_final(ctx):
> > > +    if ctx.name == "shake_128":
> > > +        return ctx.digest(16)
> > > +    if ctx.name == "shake_256":
> > > +        return ctx.digest(32)
> > 
> > This addition is unnecessary.
> 
> Well, you can't generate SHAKE128 or SHAKE256 without it as the digest()
> method has a mandatory parameter for XOF algorithms.  This fixes that.

I know, but the script is never actually used with SHAKE128 or SHAKE256.

- Eric

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto
  2025-10-02 13:14     ` David Howells
@ 2025-10-02 16:27       ` Eric Biggers
  2025-10-11  0:26         ` Eric Biggers
  2025-10-16 12:35         ` David Howells
  0 siblings, 2 replies; 27+ messages in thread
From: Eric Biggers @ 2025-10-02 16:27 UTC (permalink / raw)
  To: David Howells
  Cc: Jason A . Donenfeld, Ard Biesheuvel, Herbert Xu, Stephan Mueller,
	linux-crypto, linux-kernel

On Thu, Oct 02, 2025 at 02:14:44PM +0100, David Howells wrote:
> Eric Biggers <ebiggers@kernel.org> wrote:
> 
> > Have you had a chance to read this reply?
> 
> I have.
> 
> You held up your implementation of sha256 and sha224 as an example of how it
> perhaps should be implemented:
> 
> 	It would be worth considering separating the APIs for the different
> 	algorithms that are part of SHA-3, similar to what I did with SHA-224
> 	and SHA-256.
> 
> so I have followed that.  That defines a type for each, so I'll leave it at
> that.

In v3, you were pretty clear that you don't like the six-types solution:

    I have done what Eric required and made a separate wrapper struct
    and set of wrapper functions for each algorithm, though I think this
    is excessively bureaucratic as this multiplies the API load by 7
    (and maybe 9 in the future[*]).

    [*] The Kyber algorithm also uses CSHAKE variants in the SHA3 family - and
        NIST mentions some other variants too.

    This does, however, cause a problem for what I need to do as the
    ML-DSA prehash is dynamically selectable by certificate OID, so I
    have to add SHAKE128/256 support to the crypto shash API too -
    though hopefully it will only require an output of 16 or 32 bytes
    respectively for the prehash case and won't require multiple
    squeezing.

So, I listened.  And I realized that we can address my concern about the
digest vs. XOF confusion using just two types.

And I explained I didn't intend to require that we fully split the API
into all six variants, and apologized for not being clear.

Remember, we haven't done a SHA-3 library API before.  We're both
learning as we go...

If you've now changed your mind and strongly prefer six types, I can
tolerate that too.  But I want to make sure you actually want that, and
aren't choosing it just to try to prove a point or something.

> > All I'm really requesting is that we don't create footguns, like the
> > following that the API in the v2 patch permitted:
> 
> The way you did a separate type for each removed one more footgun - and
> arguably a more important one - as the *type* enforces[1] the output buffer
> size and the sha3_*_final() function has the same sized-array as the
> convenience wrappers.
> 
> It also eliminates the need to store the digest size as this is only needed at
> the final step for the digest variant algorithms.
> 
> David
> 
> [1] Inasmuch as this is effective in C.

Well, that "Inasmuch as this is effective in C" disclaimer is really
important, because it means it doesn't actually work properly.

Effectively, array bounds in function parameters are for humans, not the
compiler.

Which is still useful, but probably not to the extent that we should
have all those extra functions and types, vs. just documenting that
sha3_final() produces output of length matching the init function that
was called.  (As I mentioned, the BLAKE2s API does something similar.)

- Eric

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto
  2025-10-02 16:27       ` Eric Biggers
@ 2025-10-11  0:26         ` Eric Biggers
  2025-10-16 12:35         ` David Howells
  1 sibling, 0 replies; 27+ messages in thread
From: Eric Biggers @ 2025-10-11  0:26 UTC (permalink / raw)
  To: David Howells
  Cc: Jason A . Donenfeld, Ard Biesheuvel, Herbert Xu, Stephan Mueller,
	linux-crypto, linux-kernel

Hi David,

On Thu, Oct 02, 2025 at 09:27:05AM -0700, Eric Biggers wrote:
> On Thu, Oct 02, 2025 at 02:14:44PM +0100, David Howells wrote:
> > Eric Biggers <ebiggers@kernel.org> wrote:
> > 
> > > Have you had a chance to read this reply?
> > 
> > I have.
> > 
> > You held up your implementation of sha256 and sha224 as an example of how it
> > perhaps should be implemented:
> > 
> > 	It would be worth considering separating the APIs for the different
> > 	algorithms that are part of SHA-3, similar to what I did with SHA-224
> > 	and SHA-256.
> > 
> > so I have followed that.  That defines a type for each, so I'll leave it at
> > that.
> 
> In v3, you were pretty clear that you don't like the six-types solution:

Let me know if you have a new version of this patchset planned.
Otherwise I'll work on cleaning it up and finishing the remaining parts,
like incorporating the arch-optimized SHA-3 code.

- Eric

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto
  2025-10-02 16:27       ` Eric Biggers
  2025-10-11  0:26         ` Eric Biggers
@ 2025-10-16 12:35         ` David Howells
  2025-10-16 14:34           ` David Howells
  1 sibling, 1 reply; 27+ messages in thread
From: David Howells @ 2025-10-16 12:35 UTC (permalink / raw)
  To: Eric Biggers
  Cc: dhowells, Jason A . Donenfeld, Ard Biesheuvel, Herbert Xu,
	Stephan Mueller, linux-crypto, linux-kernel

Eric Biggers <ebiggers@kernel.org> wrote:

> If you've now changed your mind and strongly prefer six types, I can
> tolerate that too.

I'll stick with it for the moment.  It does have the aforementioned minor
advantage of having the output buffer sizes encoded in the final functions.
Hopefully, there won't be so many places that actually #include it.

Further, this is something that can probably be changed relatively easily
later.

Since the merge window was still open and much flux happening upstream, I
decided to press ahead with stripping down the ML-DSA stuff and leave
reissuing the patches till after -rc1, so that I could be more sure of what I
actually needed for that.

I have ML-DSA working as far as being able to load keys and check signatures
in the kernel - but hit a minor bump of openssl not apparently being able to
actually generate CMS signatures for it:-/.  It seems the standard is not
settled quite yet...

I have them rebased and will repost them hopefully today with the ML-DSA
patches, such as they are, attached for reference.

David


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto
  2025-10-16 12:35         ` David Howells
@ 2025-10-16 14:34           ` David Howells
  2025-10-16 14:56             ` Stephan Mueller
  0 siblings, 1 reply; 27+ messages in thread
From: David Howells @ 2025-10-16 14:34 UTC (permalink / raw)
  Cc: dhowells, Eric Biggers, Jason A . Donenfeld, Ard Biesheuvel,
	Herbert Xu, Stephan Mueller, linux-crypto, linux-kernel

David Howells <dhowells@redhat.com> wrote:

> I have ML-DSA working as far as being able to load keys and check signatures
> in the kernel - but hit a minor bump of openssl not apparently being able to
> actually generate CMS signatures for it:-/.  It seems the standard is not
> settled quite yet...

Actually, openssl CMS can generate ML-DSA signatures, but only if CMS_NOATTR
is not specified.

David


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto
  2025-10-16 14:34           ` David Howells
@ 2025-10-16 14:56             ` Stephan Mueller
  0 siblings, 0 replies; 27+ messages in thread
From: Stephan Mueller @ 2025-10-16 14:56 UTC (permalink / raw)
  To: David Howells
  Cc: dhowells, Eric Biggers, Jason A . Donenfeld, Ard Biesheuvel,
	Herbert Xu, linux-crypto, linux-kernel

Am Donnerstag, 16. Oktober 2025, 16:34:11 Mitteleuropäische Sommerzeit schrieb 
David Howells:

Hi David,

> David Howells <dhowells@redhat.com> wrote:
> > I have ML-DSA working as far as being able to load keys and check
> > signatures in the kernel - but hit a minor bump of openssl not apparently
> > being able to actually generate CMS signatures for it:-/.  It seems the
> > standard is not settled quite yet...
> 
> Actually, openssl CMS can generate ML-DSA signatures, but only if CMS_NOATTR
> is not specified.

If you want to test it, perhaps the lc_x509_generator or lc_pkcs7_generator 
from leancrypto could be used [1].

[1] https://leancrypto.org/leancrypto/x509_support/index.html
> 
> David


Ciao
Stephan



^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2025-10-16 14:59 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-26 14:19 [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto David Howells
2025-09-26 14:19 ` [PATCH v3 1/8] s390/sha3: Rename conflicting functions David Howells
2025-09-29 11:39   ` Harald Freudenberger
2025-09-26 14:19 ` [PATCH v3 2/8] arm64/sha3: " David Howells
2025-09-26 14:19 ` [PATCH v3 3/8] lib/crypto: Add SHA3-224, SHA3-256, SHA3-384, SHA-512, SHAKE128, SHAKE256 David Howells
2025-09-26 21:09   ` Eric Biggers
2025-09-26 14:19 ` [PATCH v3 4/8] lib/crypto: Move the SHA3 Iota transform into the single round function David Howells
2025-09-26 14:19 ` [PATCH v3 5/8] lib/crypto: Add SHA3 kunit tests David Howells
2025-10-01 16:04   ` Eric Biggers
2025-10-01 16:08     ` Eric Biggers
2025-10-02 13:05     ` David Howells
2025-10-02 16:07       ` Eric Biggers
2025-09-26 14:19 ` [PATCH v3 6/8] crypto/sha3: Use lib/crypto/sha3 David Howells
2025-09-26 21:25   ` Eric Biggers
2025-09-26 14:19 ` [PATCH v3 7/8] crypto/sha3: Add SHAKE128/256 support David Howells
2025-09-26 21:14   ` Eric Biggers
2025-10-01 13:02     ` David Howells
2025-10-01 15:25       ` Eric Biggers
2025-09-26 14:19 ` [PATCH v3 8/8] crypto: SHAKE tests David Howells
2025-09-26 19:59 ` [PATCH v3 0/8] crypto, lib/crypto: Add SHAKE128/256 support and move SHA3 to lib/crypto Eric Biggers
2025-10-01 15:28   ` Eric Biggers
2025-10-02 13:14     ` David Howells
2025-10-02 16:27       ` Eric Biggers
2025-10-11  0:26         ` Eric Biggers
2025-10-16 12:35         ` David Howells
2025-10-16 14:34           ` David Howells
2025-10-16 14:56             ` Stephan Mueller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).