[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <3605112.1758233248@warthog.procyon.org.uk>
Date: Thu, 18 Sep 2025 23:07:28 +0100
From: David Howells <dhowells@...hat.com>
To: Eric Biggers <ebiggers@...nel.org>
cc: dhowells@...hat.com, "Jason A. Donenfeld" <Jason@...c4.com>,
Ard Biesheuvel <ardb@...nel.org>,
Herbert Xu <herbert@...dor.apana.org.au>,
Stephan Mueller <smueller@...onox.de>, linux-crypto@...r.kernel.org,
keyrings@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH] lib/crypto: Add SHA3-224, SHA3-256, SHA3-384, SHA-512, SHAKE128, SHAKE256
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@...hat.com>
cc: Eric Biggers <ebiggers@...nel.org>
cc: Jason A. Donenfeld <Jason@...c4.com>
cc: Ard Biesheuvel <ardb@...nel.org>
cc: Herbert Xu <herbert@...dor.apana.org.au>
cc: Stephan Mueller <smueller@...onox.de>
cc: linux-crypto@...r.kernel.org
---
include/crypto/sha3.h | 104 ++++++
lib/crypto/Kconfig | 7
lib/crypto/Makefile | 6
lib/crypto/sha3.c | 508 ++++++++++++++++++++++++++++++
lib/crypto/tests/Kconfig | 12
lib/crypto/tests/Makefile | 7
lib/crypto/tests/sha3_224_kunit.c | 32 +
lib/crypto/tests/sha3_224_testvecs.h | 231 +++++++++++++
lib/crypto/tests/sha3_256_kunit.c | 32 +
lib/crypto/tests/sha3_256_testvecs.h | 231 +++++++++++++
lib/crypto/tests/sha3_384_kunit.c | 32 +
lib/crypto/tests/sha3_384_testvecs.h | 281 ++++++++++++++++
lib/crypto/tests/sha3_512_kunit.c | 32 +
lib/crypto/tests/sha3_512_testvecs.h | 331 +++++++++++++++++++
lib/crypto/tests/sha3_shake128_kunit.c | 42 ++
lib/crypto/tests/sha3_shake128_testvecs.h | 181 ++++++++++
lib/crypto/tests/sha3_shake256_kunit.c | 42 ++
lib/crypto/tests/sha3_shake256_testvecs.h | 231 +++++++++++++
scripts/crypto/gen-hash-testvecs.py | 8
19 files changed, 2347 insertions(+), 3 deletions(-)
diff --git a/include/crypto/sha3.h b/include/crypto/sha3.h
index 41e1b83a6d91..8693261e19dc 100644
--- a/include/crypto/sha3.h
+++ b/include/crypto/sha3.h
@@ -23,6 +23,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 digest size, but this
+ * is needed for the kunit tests.
+ */
+#define SHAKE128_DIGEST_SIZE (128 / 8)
+#define SHAKE128_BLOCK_SIZE (200 - 2 * SHAKE128_DIGEST_SIZE)
+#define SHAKE256_DIGEST_SIZE (256 / 8)
+#define SHAKE256_BLOCK_SIZE (200 - 2 * SHAKE256_DIGEST_SIZE)
+
#define SHA3_STATE_SIZE 200
struct shash_desc;
@@ -31,6 +39,100 @@ struct sha3_state {
u64 st[SHA3_STATE_SIZE / 8];
};
+struct sha3_ctx {
+ struct sha3_state state;
+ __le64 buf[SHA3_224_BLOCK_SIZE / 8];
+ unsigned short block_size;
+ unsigned short digest_size;
+ unsigned short partial;
+ u8 padding;
+};
+
int crypto_sha3_init(struct shash_desc *desc);
-#endif
+void sha3_init(struct sha3_ctx *ctx);
+
+/**
+ * sha3_224_init() - Initialize a SHA3-224 context for a new message
+ * @ctx: the context to initialize
+ */
+static inline void sha3_224_init(struct sha3_ctx *ctx)
+{
+ sha3_init(ctx);
+ ctx->block_size = SHA3_224_BLOCK_SIZE;
+ ctx->digest_size = SHA3_224_DIGEST_SIZE;
+ ctx->padding = 0x06;
+}
+
+/**
+ * sha3_256_init() - Initialize a SHA3-256 context for a new message
+ * @ctx: the context to initialize
+ */
+static inline void sha3_256_init(struct sha3_ctx *ctx)
+{
+ sha3_init(ctx);
+ ctx->block_size = SHA3_256_BLOCK_SIZE;
+ ctx->digest_size = SHA3_256_DIGEST_SIZE;
+ ctx->padding = 0x06;
+}
+
+/**
+ * sha3_384_init() - Initialize a SHA3-384 context for a new message
+ * @ctx: the context to initialize
+ */
+static inline void sha3_384_init(struct sha3_ctx *ctx)
+{
+ sha3_init(ctx);
+ ctx->block_size = SHA3_384_BLOCK_SIZE;
+ ctx->digest_size = SHA3_384_DIGEST_SIZE;
+ ctx->padding = 0x06;
+}
+
+/**
+ * sha3_512_init() - Initialize a SHA3-512 context for a new message
+ * @ctx: the context to initialize
+ */
+static inline void sha3_512_init(struct sha3_ctx *ctx)
+{
+ sha3_init(ctx);
+ ctx->block_size = SHA3_512_BLOCK_SIZE;
+ ctx->digest_size = SHA3_512_DIGEST_SIZE;
+ ctx->padding = 0x06;
+}
+
+/**
+ * shake128_init() - Initialize a SHAKE128 context for a new message
+ * @ctx: The context to initialize
+ * @digest_size: The size of the digest desired
+ */
+static inline void shake128_init(struct sha3_ctx *ctx, unsigned int digest_size)
+{
+ sha3_init(ctx);
+ ctx->block_size = SHAKE128_BLOCK_SIZE;
+ ctx->digest_size = digest_size;
+ ctx->padding = 0x1f;
+}
+
+/**
+ * shake256_init() - Initialize a SHAKE256 context for a new message
+ * @ctx: the context to initialize
+ * @digest_size: The size of the digest desired
+ */
+static inline void shake256_init(struct sha3_ctx *ctx, unsigned int digest_size)
+{
+ sha3_init(ctx);
+ ctx->block_size = SHA3_256_BLOCK_SIZE;
+ ctx->digest_size = digest_size;
+ ctx->padding = 0x1f;
+}
+
+void sha3_update(struct sha3_ctx *ctx, const u8 *data, unsigned int len);
+int sha3_final(struct sha3_ctx *ctx, u8 *out);
+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]);
+int shake128(const u8 *in, size_t in_len, u8 *out, size_t out_len);
+int 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 1e6b008f8fca..5ea6abe934d6 100644
--- a/lib/crypto/Kconfig
+++ b/lib/crypto/Kconfig
@@ -191,6 +191,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 539d5d59a50e..bf73a2cfef86 100644
--- a/lib/crypto/Makefile
+++ b/lib/crypto/Makefile
@@ -149,6 +149,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..459ef9855468
--- /dev/null
+++ b/lib/crypto/sha3.c
@@ -0,0 +1,508 @@
+// 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@...zik.org>
+ * Ard Biesheuvel <ard.biesheuvel@...aro.org>
+ * David Howells <dhowells@...hat.com>
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <crypto/sha3.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/unaligned.h>
+
+#if 0
+static void sha3_dump_state(const struct sha3_ctx *ctx, const char *prefix)
+{
+ const __be64 *p = (const __be64 *)ctx->state.st;
+
+ for (int i = 0; i < 6; i++) {
+ pr_debug("SHA3 %s %016llx %016llx %016llx %016llx\n",
+ prefix,
+ be64_to_cpu(p[0]), be64_to_cpu(p[1]),
+ be64_to_cpu(p[2]), be64_to_cpu(p[3]));
+ p += 4;
+ }
+ pr_debug("SHA3 %s %016llx\n", prefix, be64_to_cpu(p[0]));
+}
+#endif
+
+/*
+ * 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];
+}
+
+/*
+ * Perform the mixing step.
+ */
+static void sha3_keccakf_generic(u64 st[25])
+{
+ int round;
+
+ for (round = 0; round < KECCAK_ROUNDS; round++) {
+ keccakf_round(st);
+ /* Iota */
+ st[0] ^= keccakf_rndc[round];
+ }
+}
+
+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_le64(data + 8 * i);
+ sha3_keccakf_generic(state->st);
+}
+
+/*
+ * 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 len)
+{
+ unsigned int partial = ctx->partial;
+ u8 *buf = (u8 *)ctx->state.st;
+
+#ifdef __LITTLE_ENDIAN
+ buf += partial;
+ for (int i = 0; i < len; i++)
+ *buf++ ^= *data++;
+#else
+ for (int i = 0; i < len; i++) {
+ unsigned int woff = (partial + i) & ~7;
+ unsigned int boff = (partial + i) & 7;
+
+ buf[woff | 7 - boff] ^= *data++;
+ }
+#endif
+ ctx->partial += len;
+}
+
+/**
+ * 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. It adds the message data to the digest.
+ */
+void sha3_update(struct sha3_ctx *ctx, const u8 *data, unsigned int len)
+{
+ unsigned int partial = ctx->partial;
+ unsigned int bsize = ctx->block_size;
+
+ if (partial && partial + len >= bsize) {
+ sha3_absorb_xorle(ctx, data, bsize - partial);
+ len -= bsize - partial;
+ data += bsize - partial;
+ sha3_keccakf(ctx->state.st);
+ ctx->partial = 0;
+ }
+
+ if (len >= bsize) {
+ size_t nblocks = len / bsize;
+
+ if (nblocks) {
+ sha3_absorb_blocks(ctx, data, nblocks);
+ data += nblocks * bsize;
+ len -= nblocks * bsize;
+ }
+ }
+
+ if (len)
+ sha3_absorb_xorle(ctx, data, len);
+}
+EXPORT_SYMBOL_GPL(sha3_update);
+
+/**
+ * sha3_final() - Finish computing a SHA3 message digest of any type
+ * @ctx: the context to finalize; must have been initialized
+ * @out: (output) the resulting message digest
+ *
+ * Finish the computation of a SHA3 message digest of any type and perform the
+ * "Keccak sponge squeezing" phase. The digest is written to @out buffer and
+ * the size of the digest is returned. Before returning, the context @ctx is
+ * cleared so that the caller does not need to do it.
+ */
+int sha3_final(struct sha3_ctx *ctx, u8 *out)
+{
+ struct sha3_state *state = &ctx->state;
+ unsigned int digest_size = ctx->digest_size;
+ unsigned int bsize = ctx->block_size;
+ u8 end_marker = 0x80;
+
+ sha3_absorb_xorle(ctx, &ctx->padding, 1);
+ ctx->partial = bsize - 1;
+ sha3_absorb_xorle(ctx, &end_marker, 1);
+ sha3_keccakf(ctx->state.st);
+
+#ifdef __LITTLE_ENDIAN
+ for (;;) {
+ unsigned int part = umin(digest_size, bsize);
+
+ memcpy(out, state->st, part);
+ digest_size -= part;
+ if (!digest_size)
+ goto done;
+ out += part;
+ sha3_keccakf(ctx->state.st);
+ }
+#else
+ __le64 *digest = (__le64 *)out, *s;
+
+ while (digest_size >= bsize) {
+ for (int i = 0; i < bsize / 8; i++)
+ put_unaligned_le64(state->st[i], digest++);
+ digest_size -= bsize;
+ if (!digest_size)
+ goto done;
+ sha3_keccakf(ctx->state.st);
+ }
+
+ s = state->st;
+ for (; digest_size >= 8; digest_size -= 8)
+ put_unaligned_le64(*s++, digest++);
+
+ u8 *sc = (u8 *)s;
+ u8 *dc = (u8 *)digest;
+
+ for (; digest_size >= 1; digest_size -= 1)
+ *dc++ = *sc++;
+#endif
+done:
+ digest_size = ctx->digest_size;
+ memzero_explicit(ctx, sizeof(*ctx));
+ return digest_size;
+}
+EXPORT_SYMBOL_GPL(sha3_final);
+
+/**
+ * sha3_init() - Initialize a SHA3 context for a new message
+ * @ctx: the context to initialize
+ *
+ * Initialize a SHA3 context for any size of SHA-3 digest.
+ */
+void sha3_init(struct sha3_ctx *ctx)
+{
+ memset(ctx, 0, sizeof(*ctx));
+}
+EXPORT_SYMBOL_GPL(sha3_init);
+
+/**
+ * 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
+ * @out: The buffer into which the digest will be stored (size not checked)
+ */
+void sha3_224(const u8 *in, size_t in_len, u8 out[SHA3_224_DIGEST_SIZE])
+{
+ struct sha3_ctx ctx;
+
+ sha3_224_init(&ctx);
+ sha3_update(&ctx, in, in_len);
+ sha3_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
+ * @out: The buffer into which the digest will be stored (size not checked)
+ */
+void sha3_256(const u8 *in, size_t in_len, u8 out[SHA3_256_DIGEST_SIZE])
+{
+ struct sha3_ctx ctx;
+
+ sha3_256_init(&ctx);
+ sha3_update(&ctx, in, in_len);
+ sha3_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
+ * @out: The buffer into which the digest will be stored (size not checked)
+ */
+void sha3_384(const u8 *in, size_t in_len, u8 out[SHA3_384_DIGEST_SIZE])
+{
+ struct sha3_ctx ctx;
+
+ sha3_384_init(&ctx);
+ sha3_update(&ctx, in, in_len);
+ sha3_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_len: The amount of data to be digested
+ * @out: The buffer into which the digest will be stored (size not checked)
+ */
+void sha3_512(const u8 *in, size_t in_len, u8 out[SHA3_512_DIGEST_SIZE])
+{
+ struct sha3_ctx ctx;
+
+ sha3_512_init(&ctx);
+ sha3_update(&ctx, in, in_len);
+ sha3_final(&ctx, out);
+}
+EXPORT_SYMBOL(sha3_512);
+
+/**
+ * shake128() - Convenience wrapper to digest a simple buffer as SHAKE128
+ * @in: The data to be digested
+ * @in_len: The amount of data to be digested
+ * @out: The buffer into which the digest will be stored
+ * @out_len: The size of the digest desired (variable length)
+ */
+int shake128(const u8 *in, size_t in_len, u8 *out, size_t out_len)
+{
+ struct sha3_ctx ctx;
+
+ shake128_init(&ctx, out_len);
+ sha3_update(&ctx, in, in_len);
+ return sha3_final(&ctx, out);
+}
+EXPORT_SYMBOL(shake128);
+
+/**
+ * shake256() - Convenience wrapper to digest a simple buffer as SHAKE256
+ * @in: The data to be digested
+ * @in_len: The amount of data to be digested
+ * @out: The buffer into which the digest will be stored
+ * @out_len: The size of the digest desired (variable length)
+ */
+int shake256(const u8 *in, size_t in_len, u8 *out, size_t out_len)
+{
+ struct sha3_ctx ctx;
+
+ shake256_init(&ctx, out_len);
+ sha3_update(&ctx, in, in_len);
+ return sha3_final(&ctx, out);
+}
+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)
+{
+ u8 digest[8 + 200 + 8] = {};
+ int n;
+
+#ifdef sha3_mod_init_arch
+ sha3_mod_init_arch();
+#endif
+
+ n = shake256(sha3_sample, sizeof(sha3_sample) - 1, digest + 8, 200);
+
+ if (n != 200 ||
+ sizeof(digest) != sizeof(sha3_sample_shake256_200) ||
+ memcmp(digest, sha3_sample_shake256_200, sizeof(digest)) != 0) {
+ pr_err("SHAKE256(200) failed: len=%u\n", n);
+ for (int i = 0; i < sizeof(digest);) {
+ int part = min(sizeof(digest) - i, 32);
+
+ pr_err("%*phN\n", part, digest + i);
+ i += part;
+ }
+ }
+ 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");
diff --git a/lib/crypto/tests/Kconfig b/lib/crypto/tests/Kconfig
index de7e8babb6af..43b39616dce1 100644
--- a/lib/crypto/tests/Kconfig
+++ b/lib/crypto/tests/Kconfig
@@ -43,6 +43,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 8601dccd6fdd..efbe1bf2e1a9 100644
--- a/lib/crypto/tests/Makefile
+++ b/lib/crypto/tests/Makefile
@@ -4,3 +4,10 @@ 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_224_kunit.o \
+ sha3_256_kunit.o \
+ sha3_384_kunit.o \
+ sha3_512_kunit.o \
+ sha3_shake128_kunit.o \
+ sha3_shake256_kunit.o
diff --git a/lib/crypto/tests/sha3_224_kunit.c b/lib/crypto/tests/sha3_224_kunit.c
new file mode 100644
index 000000000000..c09aab76660a
--- /dev/null
+++ b/lib/crypto/tests/sha3_224_kunit.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@...hat.com)
+ */
+#include <crypto/sha3.h>
+#include "sha3_224_testvecs.h"
+
+#define HASH sha3_224
+#define HASH_CTX sha3_ctx
+#define HASH_SIZE SHA3_224_DIGEST_SIZE
+#define HASH_INIT sha3_224_init
+#define HASH_UPDATE sha3_update
+#define HASH_FINAL sha3_final
+#include "hash-test-template.h"
+
+static struct kunit_case hash_test_cases[] = {
+ HASH_KUNIT_CASES,
+ KUNIT_CASE(benchmark_hash),
+ {},
+};
+
+static struct kunit_suite hash_test_suite = {
+ .name = "sha3_224",
+ .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-224");
+MODULE_LICENSE("GPL");
diff --git a/lib/crypto/tests/sha3_224_testvecs.h b/lib/crypto/tests/sha3_224_testvecs.h
new file mode 100644
index 000000000000..0c4493117151
--- /dev/null
+++ b/lib/crypto/tests/sha3_224_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-224 */
+
+static const struct {
+ size_t data_len;
+ u8 digest[SHA3_224_DIGEST_SIZE];
+} hash_testvecs[] = {
+ {
+ .data_len = 0,
+ .digest = {
+ 0x6b, 0x4e, 0x03, 0x42, 0x36, 0x67, 0xdb, 0xb7,
+ 0x3b, 0x6e, 0x15, 0x45, 0x4f, 0x0e, 0xb1, 0xab,
+ 0xd4, 0x59, 0x7f, 0x9a, 0x1b, 0x07, 0x8e, 0x3f,
+ 0x5b, 0x5a, 0x6b, 0xc7,
+ },
+ },
+ {
+ .data_len = 1,
+ .digest = {
+ 0xe1, 0x62, 0xe9, 0x68, 0xe7, 0xd3, 0xeb, 0x6a,
+ 0xec, 0x68, 0x77, 0x5f, 0x34, 0xd4, 0xbc, 0x4b,
+ 0xe4, 0x5c, 0x3c, 0x1c, 0x92, 0x17, 0x20, 0x20,
+ 0x08, 0xc4, 0x42, 0x1c,
+ },
+ },
+ {
+ .data_len = 2,
+ .digest = {
+ 0x6c, 0xc1, 0x0c, 0xee, 0xd9, 0xc3, 0x82, 0xf4,
+ 0x55, 0x8c, 0xfd, 0xe7, 0x60, 0x66, 0xeb, 0xcd,
+ 0x8e, 0x5a, 0xac, 0xb8, 0x3f, 0x0e, 0x17, 0x84,
+ 0xed, 0x2d, 0xd5, 0x30,
+ },
+ },
+ {
+ .data_len = 3,
+ .digest = {
+ 0x6a, 0x40, 0xa0, 0x99, 0x78, 0x43, 0xbb, 0x63,
+ 0x38, 0x80, 0x44, 0x4b, 0xa9, 0x2e, 0x30, 0xb8,
+ 0xef, 0x93, 0x7b, 0xe1, 0x9f, 0x71, 0xeb, 0xe0,
+ 0xe8, 0xfe, 0x70, 0x09,
+ },
+ },
+ {
+ .data_len = 16,
+ .digest = {
+ 0x26, 0xce, 0x12, 0x43, 0xde, 0x89, 0x52, 0xf4,
+ 0x9a, 0x21, 0x77, 0xb0, 0x8a, 0xc0, 0x21, 0x2b,
+ 0x71, 0xd0, 0x77, 0x10, 0xdb, 0xec, 0x1f, 0xe3,
+ 0x32, 0xa9, 0xac, 0x47,
+ },
+ },
+ {
+ .data_len = 32,
+ .digest = {
+ 0x40, 0x35, 0x0c, 0xf3, 0xa7, 0x15, 0xbf, 0xfc,
+ 0xf0, 0xe2, 0x14, 0x3b, 0x97, 0x8a, 0x47, 0x5d,
+ 0x65, 0x1e, 0xd0, 0x49, 0x0d, 0x44, 0x45, 0x0b,
+ 0x01, 0x48, 0x11, 0xe1,
+ },
+ },
+ {
+ .data_len = 48,
+ .digest = {
+ 0x92, 0xa6, 0x33, 0x68, 0x48, 0xd2, 0xf1, 0xdc,
+ 0xf7, 0xcc, 0xf7, 0x7f, 0x14, 0x1e, 0x2a, 0x56,
+ 0x93, 0xcb, 0x40, 0x8c, 0x86, 0xfd, 0xef, 0xcf,
+ 0xbf, 0xc1, 0x3b, 0x3c,
+ },
+ },
+ {
+ .data_len = 49,
+ .digest = {
+ 0x97, 0xbf, 0xd2, 0x14, 0xe9, 0x95, 0x63, 0x0b,
+ 0xee, 0x16, 0x60, 0x15, 0x03, 0x19, 0xa0, 0xad,
+ 0x89, 0x7d, 0xb1, 0x50, 0x46, 0xef, 0x17, 0xd8,
+ 0xba, 0x1e, 0x92, 0x2e,
+ },
+ },
+ {
+ .data_len = 63,
+ .digest = {
+ 0x03, 0xe4, 0x9c, 0x28, 0x6e, 0x18, 0xf1, 0xb9,
+ 0x2a, 0x1a, 0xf4, 0xd4, 0x14, 0xe2, 0x69, 0x56,
+ 0x48, 0xe6, 0x02, 0x3b, 0xab, 0x17, 0xb2, 0x15,
+ 0xdd, 0x83, 0x3a, 0xa7,
+ },
+ },
+ {
+ .data_len = 64,
+ .digest = {
+ 0xdc, 0x46, 0x53, 0x27, 0x3b, 0x68, 0x2c, 0x4f,
+ 0xc2, 0x05, 0xe3, 0xa2, 0x56, 0x4f, 0x61, 0xf9,
+ 0xd9, 0x9b, 0x16, 0xf8, 0x1d, 0xb4, 0x7c, 0x30,
+ 0x85, 0xce, 0xa3, 0x00,
+ },
+ },
+ {
+ .data_len = 65,
+ .digest = {
+ 0x6c, 0x2d, 0x3b, 0x1a, 0x2d, 0xec, 0x94, 0xfa,
+ 0x1e, 0x0a, 0xc6, 0xa0, 0x62, 0x8f, 0x54, 0x0d,
+ 0xa9, 0x44, 0xdc, 0x2d, 0xb8, 0x6c, 0xb0, 0xb0,
+ 0x3f, 0x7b, 0x5e, 0xce,
+ },
+ },
+ {
+ .data_len = 127,
+ .digest = {
+ 0x71, 0xf5, 0x33, 0x38, 0x48, 0x84, 0x0a, 0x34,
+ 0xfc, 0x46, 0x1f, 0x06, 0x73, 0xab, 0x2e, 0xb0,
+ 0x3b, 0x46, 0xfb, 0x8a, 0xa6, 0x4d, 0x8e, 0xc0,
+ 0xfc, 0xd3, 0xef, 0xc8,
+ },
+ },
+ {
+ .data_len = 128,
+ .digest = {
+ 0xea, 0x18, 0xcd, 0x7b, 0x08, 0x9b, 0x2c, 0xb5,
+ 0xed, 0x5d, 0xc4, 0x86, 0xdf, 0xe9, 0x77, 0x3b,
+ 0x26, 0x49, 0x04, 0x81, 0xf1, 0x75, 0xe2, 0xcd,
+ 0x49, 0xe4, 0x38, 0xe0,
+ },
+ },
+ {
+ .data_len = 129,
+ .digest = {
+ 0xc8, 0x18, 0xde, 0x8d, 0xbc, 0xc1, 0x2d, 0xe3,
+ 0x9b, 0xad, 0xea, 0xed, 0x03, 0xa3, 0x6f, 0x69,
+ 0xd0, 0xa7, 0x40, 0x85, 0x66, 0xee, 0x6b, 0xb0,
+ 0xc9, 0x14, 0x85, 0x3a,
+ },
+ },
+ {
+ .data_len = 256,
+ .digest = {
+ 0xa9, 0x43, 0xe4, 0xbe, 0x81, 0xb9, 0xbf, 0xbf,
+ 0x2d, 0x61, 0xe0, 0x8b, 0x21, 0x83, 0xd0, 0x35,
+ 0x17, 0xf6, 0x01, 0x15, 0xde, 0x38, 0x5a, 0x7c,
+ 0x93, 0x54, 0xf2, 0x82,
+ },
+ },
+ {
+ .data_len = 511,
+ .digest = {
+ 0xb7, 0xf2, 0x8c, 0x76, 0x36, 0x8a, 0x60, 0xbd,
+ 0xf0, 0x6c, 0x08, 0x1a, 0xef, 0x6d, 0xf3, 0x4f,
+ 0x3c, 0x3c, 0x04, 0x46, 0x49, 0xb1, 0x32, 0x40,
+ 0xc5, 0x16, 0xb9, 0xce,
+ },
+ },
+ {
+ .data_len = 513,
+ .digest = {
+ 0xbf, 0xef, 0x10, 0xc6, 0x91, 0x04, 0xe2, 0x7d,
+ 0x51, 0x65, 0x88, 0xb3, 0xab, 0xdb, 0x9e, 0x98,
+ 0x8a, 0x24, 0x25, 0x19, 0xa3, 0x9d, 0x47, 0x6c,
+ 0xa0, 0xbe, 0x63, 0xee,
+ },
+ },
+ {
+ .data_len = 1000,
+ .digest = {
+ 0x8e, 0xb3, 0xa6, 0xf6, 0x13, 0x16, 0x6e, 0xbe,
+ 0x85, 0xa8, 0x38, 0x28, 0x34, 0x3b, 0x70, 0x62,
+ 0x84, 0x2e, 0x0c, 0xcb, 0xe0, 0x03, 0x6c, 0x6a,
+ 0x3d, 0xfc, 0x34, 0x4b,
+ },
+ },
+ {
+ .data_len = 3333,
+ .digest = {
+ 0x80, 0x77, 0x1f, 0x95, 0xe6, 0x1f, 0x0e, 0xa8,
+ 0xf8, 0x5f, 0xad, 0x36, 0x2c, 0xe5, 0x43, 0x9d,
+ 0x7d, 0x09, 0x17, 0x71, 0x70, 0x5a, 0x77, 0xdc,
+ 0x11, 0x28, 0x9c, 0x41,
+ },
+ },
+ {
+ .data_len = 4096,
+ .digest = {
+ 0x8b, 0x70, 0x82, 0x24, 0x53, 0x8d, 0xca, 0x05,
+ 0x95, 0x15, 0xc8, 0x1b, 0xca, 0xcc, 0x25, 0x63,
+ 0xfe, 0x73, 0x83, 0xf0, 0x8f, 0xfb, 0xb9, 0x1b,
+ 0x48, 0xa3, 0x54, 0x91,
+ },
+ },
+ {
+ .data_len = 4128,
+ .digest = {
+ 0x50, 0x2a, 0x17, 0x3f, 0xd4, 0x65, 0x81, 0x41,
+ 0x34, 0x17, 0x34, 0xe8, 0x12, 0xbd, 0x2e, 0x66,
+ 0x93, 0x30, 0xf5, 0xc9, 0xae, 0x31, 0x9f, 0x97,
+ 0xd7, 0x0e, 0xfe, 0x7b,
+ },
+ },
+ {
+ .data_len = 4160,
+ .digest = {
+ 0x9f, 0x8d, 0x09, 0xe4, 0x05, 0x3c, 0x54, 0x8b,
+ 0x26, 0xf9, 0x65, 0x9b, 0x16, 0xbe, 0x0a, 0x48,
+ 0xf1, 0x5a, 0x93, 0xb4, 0xfe, 0xca, 0x93, 0x39,
+ 0x86, 0x4c, 0xe2, 0xaa,
+ },
+ },
+ {
+ .data_len = 4224,
+ .digest = {
+ 0xd9, 0x0f, 0x61, 0xfa, 0xb8, 0x13, 0xb2, 0xc8,
+ 0x84, 0xb6, 0x0e, 0x53, 0x43, 0xe1, 0x28, 0x23,
+ 0xab, 0xb9, 0x4a, 0x5a, 0xb3, 0x39, 0x31, 0xf6,
+ 0x5d, 0x36, 0x1e, 0x6b,
+ },
+ },
+ {
+ .data_len = 16384,
+ .digest = {
+ 0x74, 0xd4, 0x26, 0x55, 0x7f, 0xef, 0x2a, 0x4a,
+ 0x4f, 0xf9, 0x6f, 0x29, 0xf2, 0xd4, 0xd7, 0x5d,
+ 0xc9, 0x88, 0x7a, 0xfb, 0x5f, 0x75, 0xde, 0x0a,
+ 0x46, 0x83, 0x2a, 0x76,
+ },
+ },
+};
+
+static const u8 hash_testvec_consolidated[SHA3_224_DIGEST_SIZE] = {
+ 0x83, 0xf2, 0x88, 0x34, 0x20, 0x45, 0x9f, 0xd2,
+ 0x5e, 0x9d, 0x36, 0xc0, 0x42, 0xcc, 0x74, 0xd8,
+ 0x06, 0xd9, 0x9f, 0xbf, 0x39, 0x32, 0x59, 0x4e,
+ 0x6e, 0x12, 0x62, 0x8b,
+};
diff --git a/lib/crypto/tests/sha3_256_kunit.c b/lib/crypto/tests/sha3_256_kunit.c
new file mode 100644
index 000000000000..04f0ebce6223
--- /dev/null
+++ b/lib/crypto/tests/sha3_256_kunit.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@...hat.com)
+ */
+#include <crypto/sha3.h>
+#include "sha3_256_testvecs.h"
+
+#define HASH sha3_256
+#define HASH_CTX sha3_ctx
+#define HASH_SIZE SHA3_256_DIGEST_SIZE
+#define HASH_INIT sha3_256_init
+#define HASH_UPDATE sha3_update
+#define HASH_FINAL sha3_final
+#include "hash-test-template.h"
+
+static struct kunit_case hash_test_cases[] = {
+ HASH_KUNIT_CASES,
+ KUNIT_CASE(benchmark_hash),
+ {},
+};
+
+static struct kunit_suite hash_test_suite = {
+ .name = "sha3_256",
+ .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_256_testvecs.h b/lib/crypto/tests/sha3_256_testvecs.h
new file mode 100644
index 000000000000..9c4c403cc6e0
--- /dev/null
+++ b/lib/crypto/tests/sha3_256_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/lib/crypto/tests/sha3_384_kunit.c b/lib/crypto/tests/sha3_384_kunit.c
new file mode 100644
index 000000000000..5521f4ae3c25
--- /dev/null
+++ b/lib/crypto/tests/sha3_384_kunit.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@...hat.com)
+ */
+#include <crypto/sha3.h>
+#include "sha3_384_testvecs.h"
+
+#define HASH sha3_384
+#define HASH_CTX sha3_ctx
+#define HASH_SIZE SHA3_384_DIGEST_SIZE
+#define HASH_INIT sha3_384_init
+#define HASH_UPDATE sha3_update
+#define HASH_FINAL sha3_final
+#include "hash-test-template.h"
+
+static struct kunit_case hash_test_cases[] = {
+ HASH_KUNIT_CASES,
+ KUNIT_CASE(benchmark_hash),
+ {},
+};
+
+static struct kunit_suite hash_test_suite = {
+ .name = "sha3_384",
+ .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-384");
+MODULE_LICENSE("GPL");
diff --git a/lib/crypto/tests/sha3_384_testvecs.h b/lib/crypto/tests/sha3_384_testvecs.h
new file mode 100644
index 000000000000..ec412de7c759
--- /dev/null
+++ b/lib/crypto/tests/sha3_384_testvecs.h
@@ -0,0 +1,281 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* This file was generated by: ../../../scripts/crypto/gen-hash-testvecs.py sha3-384 */
+
+static const struct {
+ size_t data_len;
+ u8 digest[SHA3_384_DIGEST_SIZE];
+} hash_testvecs[] = {
+ {
+ .data_len = 0,
+ .digest = {
+ 0x0c, 0x63, 0xa7, 0x5b, 0x84, 0x5e, 0x4f, 0x7d,
+ 0x01, 0x10, 0x7d, 0x85, 0x2e, 0x4c, 0x24, 0x85,
+ 0xc5, 0x1a, 0x50, 0xaa, 0xaa, 0x94, 0xfc, 0x61,
+ 0x99, 0x5e, 0x71, 0xbb, 0xee, 0x98, 0x3a, 0x2a,
+ 0xc3, 0x71, 0x38, 0x31, 0x26, 0x4a, 0xdb, 0x47,
+ 0xfb, 0x6b, 0xd1, 0xe0, 0x58, 0xd5, 0xf0, 0x04,
+ },
+ },
+ {
+ .data_len = 1,
+ .digest = {
+ 0x15, 0x3b, 0x5d, 0xa0, 0x54, 0x73, 0x3c, 0x20,
+ 0x43, 0xdd, 0xec, 0x9c, 0x6b, 0xed, 0xf8, 0x3a,
+ 0x2d, 0xfa, 0x90, 0x72, 0x80, 0x0c, 0x6d, 0x3c,
+ 0x24, 0x4f, 0x00, 0xb6, 0xab, 0xd2, 0x16, 0xa0,
+ 0xd3, 0x4e, 0x8a, 0x10, 0x09, 0xaa, 0x28, 0x42,
+ 0xe0, 0x31, 0x06, 0x14, 0x2f, 0x31, 0x90, 0xe7,
+ },
+ },
+ {
+ .data_len = 2,
+ .digest = {
+ 0x5e, 0xa7, 0x88, 0xb5, 0x41, 0x4a, 0x47, 0xe7,
+ 0x1c, 0x42, 0xf3, 0xe8, 0x5e, 0x74, 0x35, 0x15,
+ 0x19, 0xa0, 0x81, 0xb3, 0xf2, 0x4d, 0x75, 0xc2,
+ 0x99, 0x24, 0x37, 0x69, 0xfe, 0xad, 0x31, 0x3b,
+ 0xd6, 0xdf, 0x33, 0xce, 0x20, 0x2a, 0xf3, 0x73,
+ 0xf3, 0x64, 0xba, 0x33, 0x2a, 0x7d, 0x03, 0x03,
+ },
+ },
+ {
+ .data_len = 3,
+ .digest = {
+ 0x51, 0x65, 0xc3, 0xb5, 0xed, 0x48, 0x29, 0xfd,
+ 0x6e, 0x6d, 0xc8, 0x49, 0x60, 0xd3, 0x51, 0xa1,
+ 0xec, 0x79, 0xf8, 0x43, 0x98, 0x87, 0x0c, 0x4c,
+ 0x7f, 0xca, 0x32, 0x29, 0x68, 0xe8, 0xf2, 0x59,
+ 0x01, 0x89, 0x2e, 0xbf, 0x42, 0xd1, 0x46, 0x55,
+ 0x0b, 0x3a, 0x50, 0xa2, 0x83, 0x47, 0xb4, 0x14,
+ },
+ },
+ {
+ .data_len = 16,
+ .digest = {
+ 0x2a, 0x91, 0x68, 0x9c, 0x07, 0x3c, 0x40, 0x42,
+ 0xcc, 0x8e, 0xfb, 0x90, 0xe7, 0x77, 0x14, 0x05,
+ 0x5f, 0x90, 0xf8, 0x57, 0x3c, 0x55, 0x79, 0xc3,
+ 0x59, 0x28, 0xd8, 0x1d, 0x9a, 0xeb, 0x86, 0xe9,
+ 0xfe, 0x39, 0xc2, 0xce, 0x40, 0xd0, 0xb7, 0xe2,
+ 0xba, 0xfc, 0xeb, 0x18, 0x3a, 0xaf, 0x71, 0xa2,
+ },
+ },
+ {
+ .data_len = 32,
+ .digest = {
+ 0x98, 0x36, 0x92, 0xec, 0xb6, 0xe8, 0x46, 0xc9,
+ 0x8e, 0x61, 0x2e, 0x71, 0x06, 0xfd, 0xe1, 0x23,
+ 0xff, 0x6a, 0x1d, 0xb1, 0x3b, 0x6c, 0x3d, 0x8e,
+ 0x07, 0x09, 0xf9, 0xaa, 0x89, 0xa8, 0x6b, 0x5f,
+ 0xb3, 0xf3, 0xdf, 0x09, 0xb7, 0x4d, 0xf2, 0x60,
+ 0x3c, 0x99, 0x0b, 0x75, 0xec, 0x3c, 0xe0, 0x45,
+ },
+ },
+ {
+ .data_len = 48,
+ .digest = {
+ 0xc2, 0xef, 0x71, 0x18, 0x6e, 0x8a, 0x91, 0xbf,
+ 0x8b, 0x87, 0x8b, 0xa4, 0x54, 0x32, 0x66, 0x5a,
+ 0x79, 0x6d, 0xfc, 0x19, 0x24, 0x1e, 0xa8, 0x12,
+ 0xc6, 0xf6, 0x16, 0x72, 0x10, 0xd4, 0x31, 0x52,
+ 0x70, 0x55, 0x9c, 0xa0, 0x4e, 0xab, 0x5a, 0xf5,
+ 0x8d, 0x8d, 0x28, 0x76, 0x8b, 0x55, 0x5f, 0x1d,
+ },
+ },
+ {
+ .data_len = 49,
+ .digest = {
+ 0x36, 0x8d, 0x27, 0xd9, 0x43, 0x14, 0x2e, 0xb2,
+ 0x38, 0x99, 0x10, 0x65, 0x01, 0x31, 0x6c, 0x21,
+ 0x29, 0x39, 0x4b, 0xb7, 0x82, 0x6e, 0xb8, 0xf4,
+ 0x7c, 0x0b, 0x4c, 0x6c, 0xee, 0xd9, 0xd1, 0xf0,
+ 0x36, 0x62, 0x62, 0xb3, 0x85, 0x23, 0x36, 0x17,
+ 0x83, 0x57, 0x31, 0x86, 0x21, 0x59, 0x03, 0x53,
+ },
+ },
+ {
+ .data_len = 63,
+ .digest = {
+ 0x0e, 0xb5, 0x98, 0x1c, 0x4e, 0xc1, 0x26, 0x61,
+ 0xef, 0xc4, 0xc2, 0x2d, 0xb6, 0x69, 0xfa, 0x7c,
+ 0x5a, 0xd5, 0x70, 0x87, 0x81, 0x02, 0xac, 0xfe,
+ 0x76, 0xf6, 0x78, 0x88, 0xa3, 0xc3, 0x0d, 0xa1,
+ 0xdc, 0x5e, 0xdc, 0xa3, 0x9c, 0xb2, 0x52, 0x33,
+ 0x4c, 0x3f, 0x29, 0xdc, 0x30, 0xde, 0xc5, 0x8e,
+ },
+ },
+ {
+ .data_len = 64,
+ .digest = {
+ 0xce, 0x96, 0x41, 0x75, 0x82, 0x8b, 0xac, 0xdf,
+ 0x5a, 0xce, 0x49, 0xff, 0x01, 0x96, 0x76, 0xca,
+ 0x9d, 0xdc, 0x30, 0x19, 0x64, 0x0e, 0x05, 0xd1,
+ 0x3c, 0x98, 0xc2, 0xa4, 0x95, 0xf7, 0x98, 0x9b,
+ 0x9e, 0x68, 0x5e, 0x1f, 0xb9, 0xe4, 0x9a, 0x09,
+ 0xed, 0xd9, 0xbe, 0x92, 0x9e, 0xb2, 0x20, 0x32,
+ },
+ },
+ {
+ .data_len = 65,
+ .digest = {
+ 0x0e, 0x0a, 0xb6, 0xb8, 0x4a, 0x14, 0xcd, 0xe6,
+ 0xdd, 0x02, 0xba, 0xeb, 0xb4, 0x80, 0x0f, 0x46,
+ 0x68, 0x33, 0xb4, 0x7d, 0x4c, 0x58, 0x94, 0x52,
+ 0x48, 0xdf, 0xbb, 0x7b, 0xee, 0xdd, 0x62, 0xbc,
+ 0x87, 0xa7, 0x2b, 0xdc, 0xe3, 0x20, 0x3c, 0xa2,
+ 0x49, 0x6a, 0xd7, 0x90, 0x28, 0x27, 0xe7, 0x6a,
+ },
+ },
+ {
+ .data_len = 127,
+ .digest = {
+ 0x3a, 0x13, 0xf6, 0x17, 0x77, 0xad, 0xce, 0x92,
+ 0xb8, 0xf7, 0xed, 0x1d, 0x30, 0x6c, 0x6e, 0x0e,
+ 0xdd, 0xd5, 0xab, 0x04, 0x1e, 0xe4, 0x2f, 0xaa,
+ 0xb8, 0xba, 0xc7, 0x0a, 0xa5, 0x1e, 0xcb, 0x14,
+ 0xa9, 0xec, 0x32, 0x4b, 0x12, 0x96, 0x44, 0x86,
+ 0x08, 0xbd, 0x3c, 0x38, 0x98, 0xc4, 0xe9, 0x68,
+ },
+ },
+ {
+ .data_len = 128,
+ .digest = {
+ 0x9f, 0x1b, 0x78, 0x80, 0xa9, 0x92, 0x06, 0xa4,
+ 0x18, 0x2f, 0x0d, 0xc1, 0x49, 0xa3, 0x92, 0xec,
+ 0x0a, 0xdb, 0xe0, 0xe6, 0x56, 0xa5, 0x45, 0xef,
+ 0x88, 0x14, 0x9f, 0xfc, 0x1d, 0x6e, 0x79, 0xf2,
+ 0x3c, 0x9a, 0x05, 0x55, 0xe2, 0x03, 0xa3, 0xea,
+ 0x14, 0xb4, 0x2e, 0x23, 0x63, 0xf6, 0x92, 0xcb,
+ },
+ },
+ {
+ .data_len = 129,
+ .digest = {
+ 0xd7, 0x5b, 0xb8, 0xad, 0x54, 0xfe, 0x84, 0x16,
+ 0x23, 0x02, 0x22, 0x11, 0x13, 0x1f, 0xa5, 0x16,
+ 0x43, 0xc7, 0x1d, 0x1d, 0x7f, 0x7a, 0xd1, 0x9d,
+ 0x82, 0x33, 0x4f, 0x8b, 0x29, 0x26, 0x46, 0x68,
+ 0x3c, 0x24, 0x42, 0x7e, 0x4c, 0x42, 0x5d, 0x16,
+ 0xbb, 0x18, 0xdf, 0x6e, 0xee, 0x9f, 0xcd, 0xbd,
+ },
+ },
+ {
+ .data_len = 256,
+ .digest = {
+ 0x37, 0x3c, 0x52, 0xc8, 0xc9, 0x58, 0xb8, 0x6a,
+ 0xec, 0x44, 0x92, 0x40, 0x51, 0x82, 0x0e, 0xd0,
+ 0xed, 0x33, 0x2a, 0xd0, 0x37, 0xa4, 0x96, 0x87,
+ 0x7c, 0x8c, 0xb7, 0x82, 0x1a, 0xad, 0xf7, 0x2f,
+ 0xa0, 0x31, 0xba, 0x7f, 0xcf, 0x36, 0x06, 0x0b,
+ 0x14, 0xb6, 0xdd, 0x5e, 0x22, 0xac, 0x52, 0xf8,
+ },
+ },
+ {
+ .data_len = 511,
+ .digest = {
+ 0x75, 0xfe, 0x6c, 0x93, 0xa6, 0x39, 0x07, 0x4a,
+ 0xdd, 0x74, 0x36, 0xe7, 0x80, 0xd2, 0xfd, 0xa1,
+ 0x30, 0x2e, 0x23, 0x2a, 0x50, 0xfe, 0xad, 0x14,
+ 0x3c, 0x1b, 0x62, 0x0d, 0x6e, 0x2d, 0x44, 0xe4,
+ 0x35, 0x3e, 0x90, 0x1b, 0x81, 0x3b, 0x43, 0x71,
+ 0xb8, 0xea, 0xd1, 0x92, 0xaa, 0x56, 0xec, 0x26,
+ },
+ },
+ {
+ .data_len = 513,
+ .digest = {
+ 0x18, 0xd9, 0xf5, 0x21, 0x9c, 0x8d, 0x63, 0x7a,
+ 0x64, 0x26, 0xd3, 0xe8, 0x63, 0x06, 0x3b, 0x43,
+ 0xf8, 0xfd, 0x93, 0xac, 0x06, 0x7d, 0x13, 0xac,
+ 0x26, 0x98, 0x4b, 0x51, 0x9f, 0x9b, 0x39, 0x57,
+ 0xe7, 0x3e, 0xa8, 0x32, 0x7f, 0x84, 0xd5, 0x87,
+ 0x4c, 0xd4, 0xe0, 0xd2, 0x57, 0x3a, 0x43, 0x00,
+ },
+ },
+ {
+ .data_len = 1000,
+ .digest = {
+ 0x53, 0xb5, 0xd8, 0x9d, 0x76, 0xed, 0xcf, 0xa3,
+ 0xb8, 0x3c, 0x5a, 0x37, 0xdb, 0xb4, 0xea, 0x1e,
+ 0x40, 0x67, 0xda, 0x46, 0x61, 0x18, 0xa1, 0x8d,
+ 0xaa, 0x5d, 0xf2, 0x32, 0x2c, 0x37, 0x02, 0x70,
+ 0x7d, 0x18, 0x02, 0x4e, 0xec, 0x57, 0x86, 0x71,
+ 0xfe, 0xdb, 0xa2, 0xd2, 0x39, 0x91, 0x98, 0xaa,
+ },
+ },
+ {
+ .data_len = 3333,
+ .digest = {
+ 0x34, 0xb3, 0x9a, 0x58, 0x30, 0x1f, 0x4b, 0x56,
+ 0x13, 0x32, 0x05, 0x48, 0x39, 0x3f, 0x36, 0xd5,
+ 0x5b, 0x61, 0xe7, 0x6b, 0x47, 0x2a, 0x33, 0xf5,
+ 0x76, 0x7c, 0x0c, 0x84, 0xa4, 0x04, 0x0b, 0x4e,
+ 0xb5, 0xc0, 0x7e, 0xca, 0x36, 0x04, 0x58, 0xfc,
+ 0x4d, 0x6f, 0xd1, 0x1f, 0x7d, 0x5a, 0x14, 0xa5,
+ },
+ },
+ {
+ .data_len = 4096,
+ .digest = {
+ 0x7d, 0x41, 0xba, 0xea, 0x79, 0xb9, 0xd1, 0x35,
+ 0x53, 0xc5, 0x2f, 0x54, 0x5d, 0xfc, 0x10, 0x0e,
+ 0xf0, 0xf8, 0x34, 0x57, 0x14, 0xc2, 0xc7, 0x1a,
+ 0xf8, 0x27, 0x99, 0x72, 0xa2, 0x1a, 0x7f, 0x48,
+ 0x39, 0x6d, 0x4c, 0x2a, 0xe5, 0x45, 0x7b, 0x67,
+ 0xd5, 0xbd, 0x9d, 0x5e, 0x25, 0x78, 0xc7, 0x70,
+ },
+ },
+ {
+ .data_len = 4128,
+ .digest = {
+ 0xea, 0x11, 0xff, 0x7f, 0x16, 0xab, 0x00, 0xa5,
+ 0x13, 0x23, 0x17, 0xec, 0x78, 0x63, 0xbf, 0x64,
+ 0x16, 0xc8, 0x36, 0x8b, 0xe9, 0x75, 0x80, 0x05,
+ 0x78, 0x03, 0x0d, 0x1b, 0x9d, 0xdc, 0xbc, 0xe9,
+ 0xd3, 0x71, 0x9b, 0xec, 0xa0, 0xea, 0xff, 0x1e,
+ 0xef, 0x5f, 0x85, 0xcb, 0x14, 0x43, 0x7e, 0x48,
+ },
+ },
+ {
+ .data_len = 4160,
+ .digest = {
+ 0x1b, 0x6d, 0xc4, 0x38, 0x60, 0x1b, 0xf1, 0x26,
+ 0x01, 0x24, 0x32, 0x69, 0x1f, 0x35, 0x46, 0xb6,
+ 0x0e, 0x5c, 0x3a, 0x2b, 0x5c, 0xda, 0xfa, 0x17,
+ 0x8a, 0x58, 0xb1, 0x67, 0x65, 0xb8, 0xe7, 0x3c,
+ 0x3e, 0x14, 0x64, 0xa6, 0xe5, 0xdd, 0xf6, 0x7c,
+ 0x7a, 0x0c, 0xa3, 0xa4, 0x70, 0x2a, 0xbe, 0x45,
+ },
+ },
+ {
+ .data_len = 4224,
+ .digest = {
+ 0x4a, 0x57, 0x3f, 0xe4, 0xbf, 0x4c, 0xfd, 0x2d,
+ 0x0d, 0x06, 0xdf, 0xc6, 0x13, 0xb4, 0x36, 0x51,
+ 0xc5, 0xe2, 0x65, 0xc0, 0x6d, 0x02, 0x7b, 0x68,
+ 0xd2, 0x70, 0x67, 0x5a, 0x94, 0xb3, 0x23, 0xb3,
+ 0xbb, 0x1b, 0x8b, 0x53, 0x48, 0x04, 0xcc, 0x69,
+ 0x85, 0x13, 0x6e, 0xbe, 0xdb, 0xd3, 0x31, 0x90,
+ },
+ },
+ {
+ .data_len = 16384,
+ .digest = {
+ 0x33, 0xbe, 0x6e, 0x2d, 0x97, 0x65, 0x4f, 0xe1,
+ 0xc9, 0x5f, 0xf9, 0x7c, 0x1e, 0x2a, 0xf0, 0x99,
+ 0xed, 0xa5, 0xaf, 0xac, 0x39, 0xf2, 0x33, 0x01,
+ 0x9b, 0xce, 0x33, 0x9f, 0x30, 0xa1, 0x87, 0xce,
+ 0x51, 0x45, 0x01, 0x96, 0x22, 0x40, 0xf1, 0x3f,
+ 0xca, 0xb4, 0xe7, 0x3e, 0x62, 0xbb, 0x4b, 0xc9,
+ },
+ },
+};
+
+static const u8 hash_testvec_consolidated[SHA3_384_DIGEST_SIZE] = {
+ 0x2d, 0x63, 0xd8, 0xee, 0x11, 0x58, 0x7d, 0xae,
+ 0xd9, 0x34, 0x57, 0xae, 0x99, 0x12, 0x0b, 0x04,
+ 0x94, 0x38, 0x29, 0xef, 0xcf, 0xdd, 0x65, 0xec,
+ 0xcf, 0xe6, 0x99, 0x54, 0x5f, 0x32, 0xd2, 0x57,
+ 0x8d, 0x76, 0xe5, 0x89, 0x1d, 0x28, 0x07, 0x5c,
+ 0x3b, 0xda, 0x08, 0xef, 0x85, 0x16, 0x10, 0x09,
+};
diff --git a/lib/crypto/tests/sha3_512_kunit.c b/lib/crypto/tests/sha3_512_kunit.c
new file mode 100644
index 000000000000..2762dae16aa0
--- /dev/null
+++ b/lib/crypto/tests/sha3_512_kunit.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@...hat.com)
+ */
+#include <crypto/sha3.h>
+#include "sha3_512_testvecs.h"
+
+#define HASH sha3_512
+#define HASH_CTX sha3_ctx
+#define HASH_SIZE SHA3_512_DIGEST_SIZE
+#define HASH_INIT sha3_512_init
+#define HASH_UPDATE sha3_update
+#define HASH_FINAL sha3_final
+#include "hash-test-template.h"
+
+static struct kunit_case hash_test_cases[] = {
+ HASH_KUNIT_CASES,
+ KUNIT_CASE(benchmark_hash),
+ {},
+};
+
+static struct kunit_suite hash_test_suite = {
+ .name = "sha3_512",
+ .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 SHA-512 and HMAC-SHA512");
+MODULE_LICENSE("GPL");
diff --git a/lib/crypto/tests/sha3_512_testvecs.h b/lib/crypto/tests/sha3_512_testvecs.h
new file mode 100644
index 000000000000..141223038786
--- /dev/null
+++ b/lib/crypto/tests/sha3_512_testvecs.h
@@ -0,0 +1,331 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* This file was generated by: ../../../scripts/crypto/gen-hash-testvecs.py sha3-512 */
+
+static const struct {
+ size_t data_len;
+ u8 digest[SHA3_512_DIGEST_SIZE];
+} hash_testvecs[] = {
+ {
+ .data_len = 0,
+ .digest = {
+ 0xa6, 0x9f, 0x73, 0xcc, 0xa2, 0x3a, 0x9a, 0xc5,
+ 0xc8, 0xb5, 0x67, 0xdc, 0x18, 0x5a, 0x75, 0x6e,
+ 0x97, 0xc9, 0x82, 0x16, 0x4f, 0xe2, 0x58, 0x59,
+ 0xe0, 0xd1, 0xdc, 0xc1, 0x47, 0x5c, 0x80, 0xa6,
+ 0x15, 0xb2, 0x12, 0x3a, 0xf1, 0xf5, 0xf9, 0x4c,
+ 0x11, 0xe3, 0xe9, 0x40, 0x2c, 0x3a, 0xc5, 0x58,
+ 0xf5, 0x00, 0x19, 0x9d, 0x95, 0xb6, 0xd3, 0xe3,
+ 0x01, 0x75, 0x85, 0x86, 0x28, 0x1d, 0xcd, 0x26,
+ },
+ },
+ {
+ .data_len = 1,
+ .digest = {
+ 0x76, 0x8b, 0xbf, 0xff, 0xfe, 0x4f, 0xc3, 0xfc,
+ 0xb6, 0xec, 0x19, 0x02, 0x04, 0x1a, 0x82, 0x77,
+ 0xf1, 0xf1, 0x88, 0x71, 0x6d, 0xea, 0xab, 0x1e,
+ 0x4b, 0x5a, 0x23, 0x0e, 0x03, 0x2e, 0x8d, 0x9f,
+ 0x77, 0xdf, 0x9f, 0xb1, 0x1e, 0x39, 0x9e, 0x9f,
+ 0x0c, 0x37, 0x3f, 0x67, 0x89, 0x52, 0xa6, 0x88,
+ 0x0b, 0x91, 0x82, 0x83, 0x8b, 0xc5, 0x51, 0xc9,
+ 0xe2, 0x87, 0xc8, 0x48, 0x51, 0x33, 0x88, 0x1a,
+ },
+ },
+ {
+ .data_len = 2,
+ .digest = {
+ 0x2a, 0x3c, 0x9b, 0x70, 0x53, 0xd7, 0x5b, 0x42,
+ 0x7c, 0xe8, 0x52, 0x4c, 0xe3, 0x40, 0xd6, 0xbb,
+ 0x08, 0x1e, 0x97, 0x89, 0x55, 0x89, 0xe2, 0x83,
+ 0x3b, 0x85, 0x17, 0x38, 0x00, 0x0c, 0x5c, 0x82,
+ 0x1c, 0xb2, 0x25, 0x94, 0x45, 0xb4, 0x06, 0x62,
+ 0x7e, 0xe4, 0x32, 0x50, 0xae, 0x2a, 0xce, 0x4b,
+ 0x94, 0xb3, 0x02, 0xd0, 0xc9, 0x44, 0x46, 0xa0,
+ 0x77, 0x85, 0xa5, 0x38, 0xf6, 0xe3, 0x7f, 0xb5,
+ },
+ },
+ {
+ .data_len = 3,
+ .digest = {
+ 0x24, 0x08, 0x49, 0x5e, 0x5f, 0x90, 0xb2, 0x8c,
+ 0x8e, 0x41, 0x0f, 0xe6, 0x96, 0xfe, 0xb6, 0x2b,
+ 0x5c, 0x52, 0x2c, 0xba, 0x41, 0x84, 0x33, 0xd5,
+ 0xb4, 0x7c, 0xbb, 0xd8, 0x20, 0x49, 0x58, 0x0d,
+ 0x30, 0x88, 0x26, 0x92, 0x9e, 0x51, 0x78, 0x70,
+ 0x42, 0x08, 0x64, 0xb5, 0xa9, 0xf1, 0x8b, 0xea,
+ 0x75, 0x9a, 0x2b, 0x6c, 0x61, 0x9d, 0x37, 0xa3,
+ 0x48, 0x7a, 0x4d, 0xbf, 0x5c, 0x43, 0x14, 0xe7,
+ },
+ },
+ {
+ .data_len = 16,
+ .digest = {
+ 0x47, 0x4d, 0xa3, 0xec, 0xa8, 0x6d, 0x3a, 0x76,
+ 0xb4, 0x2c, 0x6c, 0xad, 0x57, 0xf6, 0x18, 0xc9,
+ 0x1b, 0xf6, 0xe4, 0x9a, 0xe3, 0xbf, 0x23, 0xf0,
+ 0x4f, 0x4b, 0xca, 0x08, 0x2b, 0xb4, 0x8c, 0xa6,
+ 0x5e, 0x61, 0xf2, 0x63, 0x85, 0xc0, 0xc6, 0x6a,
+ 0x01, 0xea, 0x84, 0x7a, 0x71, 0x08, 0x2f, 0x72,
+ 0xc1, 0x64, 0x01, 0xe9, 0x2e, 0x96, 0xe9, 0x1d,
+ 0x9a, 0x85, 0x16, 0x9c, 0xda, 0xc5, 0xa3, 0xd4,
+ },
+ },
+ {
+ .data_len = 32,
+ .digest = {
+ 0xc4, 0xfe, 0x9a, 0x2b, 0xb1, 0xb8, 0x03, 0xa5,
+ 0x9b, 0x5f, 0xd1, 0xcf, 0x8d, 0xc3, 0x16, 0xbb,
+ 0x5f, 0xbb, 0x70, 0x6b, 0x63, 0xd6, 0x7c, 0x7d,
+ 0x5f, 0xe0, 0x11, 0xeb, 0xb5, 0x39, 0x0e, 0x3f,
+ 0x12, 0x4c, 0x2e, 0x6e, 0xa6, 0xb9, 0x24, 0xa2,
+ 0x0c, 0x02, 0xf9, 0x94, 0x3c, 0x48, 0xc3, 0x8a,
+ 0x26, 0x7a, 0x80, 0x26, 0x33, 0xea, 0xaf, 0xaf,
+ 0xca, 0x92, 0x16, 0xfe, 0xec, 0xf9, 0x01, 0x6c,
+ },
+ },
+ {
+ .data_len = 48,
+ .digest = {
+ 0xa9, 0x89, 0x4c, 0x42, 0xc7, 0x77, 0x15, 0x6c,
+ 0xbc, 0x0d, 0xab, 0x5a, 0x0c, 0x4c, 0x1d, 0x47,
+ 0xc6, 0x4e, 0x0a, 0xbe, 0x6c, 0xc1, 0x6e, 0xa2,
+ 0xe9, 0x3e, 0xed, 0x9c, 0x95, 0x0b, 0xfe, 0xcb,
+ 0x7a, 0xb4, 0xb9, 0x99, 0xa0, 0x2d, 0xda, 0xf9,
+ 0xdd, 0x2a, 0x68, 0x84, 0x1d, 0x3e, 0xe1, 0x1c,
+ 0x16, 0x2c, 0x05, 0x52, 0x5d, 0x55, 0xb2, 0x97,
+ 0x16, 0x94, 0xd2, 0xa8, 0x02, 0x00, 0x1b, 0x0f,
+ },
+ },
+ {
+ .data_len = 49,
+ .digest = {
+ 0x9c, 0xeb, 0x9f, 0x21, 0x48, 0x58, 0x6f, 0x0c,
+ 0x90, 0xfc, 0x57, 0x4c, 0x36, 0xef, 0x52, 0x06,
+ 0x9b, 0x86, 0x37, 0x25, 0x96, 0x78, 0x6f, 0xb2,
+ 0x99, 0x2d, 0xad, 0x3a, 0x2b, 0xd3, 0x1b, 0x1e,
+ 0xeb, 0x82, 0x7e, 0xe2, 0x80, 0xe4, 0x89, 0x28,
+ 0x34, 0x09, 0x10, 0xd9, 0xb9, 0x67, 0xaf, 0x92,
+ 0x29, 0xfc, 0x5e, 0xa4, 0x5d, 0xd0, 0x9c, 0x57,
+ 0x58, 0xe8, 0x29, 0x77, 0x9f, 0xd3, 0x93, 0x82,
+ },
+ },
+ {
+ .data_len = 63,
+ .digest = {
+ 0x8c, 0x7b, 0x97, 0xf5, 0xfa, 0x62, 0x1a, 0xf0,
+ 0x33, 0x17, 0x24, 0xea, 0x15, 0x96, 0x34, 0x6b,
+ 0xa0, 0xb6, 0x9a, 0x01, 0xe7, 0x00, 0x19, 0x2f,
+ 0x97, 0xfb, 0x66, 0xce, 0x47, 0x72, 0x42, 0xfd,
+ 0x05, 0x3e, 0x1b, 0x27, 0xae, 0xc2, 0xa2, 0xa0,
+ 0x1d, 0x3f, 0x3a, 0x2f, 0x31, 0xd6, 0xec, 0x23,
+ 0x17, 0xb6, 0x78, 0x00, 0xfd, 0x5d, 0x00, 0x47,
+ 0xc7, 0x5b, 0xea, 0x4d, 0xee, 0xb8, 0xef, 0x86,
+ },
+ },
+ {
+ .data_len = 64,
+ .digest = {
+ 0x4d, 0xcb, 0x7b, 0xad, 0xc7, 0xd0, 0x89, 0xc7,
+ 0x2d, 0x9b, 0x4f, 0x18, 0x86, 0x1e, 0x8b, 0xfb,
+ 0xd2, 0x7c, 0xd8, 0xf4, 0xb5, 0xa4, 0x91, 0x2c,
+ 0xee, 0xc7, 0x6a, 0x97, 0xb1, 0x75, 0x23, 0xbe,
+ 0x0a, 0x29, 0x5f, 0xfa, 0x78, 0x71, 0x01, 0x71,
+ 0x04, 0xaf, 0x7a, 0xd1, 0xa4, 0xc7, 0xe0, 0xe7,
+ 0x7d, 0xc0, 0x3e, 0x3f, 0xd1, 0x11, 0x8c, 0x68,
+ 0xc6, 0x1e, 0xc4, 0xb6, 0x4d, 0x61, 0xf4, 0xed,
+ },
+ },
+ {
+ .data_len = 65,
+ .digest = {
+ 0xb4, 0x0c, 0xf8, 0x3b, 0xfe, 0x89, 0xc4, 0xc3,
+ 0x2e, 0x38, 0xd7, 0x83, 0xe2, 0x9c, 0xee, 0xbd,
+ 0x1d, 0xc3, 0xcc, 0xf0, 0x65, 0x7a, 0xf7, 0x44,
+ 0x4b, 0xec, 0xa7, 0xd3, 0x0a, 0x49, 0x8b, 0x23,
+ 0x4c, 0xee, 0x41, 0x3f, 0xfb, 0x73, 0xd3, 0x9b,
+ 0x70, 0x63, 0x1f, 0x0f, 0x88, 0x44, 0x55, 0xec,
+ 0xda, 0x7d, 0x7b, 0xfc, 0xf3, 0x58, 0xc9, 0x7c,
+ 0xb8, 0xbc, 0x92, 0xa1, 0xaf, 0xda, 0x98, 0xa8,
+ },
+ },
+ {
+ .data_len = 127,
+ .digest = {
+ 0x7d, 0xb5, 0x9f, 0xa3, 0x2e, 0x02, 0x58, 0x82,
+ 0x43, 0xd0, 0x54, 0x33, 0x7b, 0x29, 0xf5, 0x95,
+ 0x46, 0xee, 0xa9, 0x11, 0x88, 0xee, 0xbf, 0x6f,
+ 0xab, 0x70, 0xc6, 0xd0, 0x77, 0x48, 0xc1, 0x0b,
+ 0x98, 0x95, 0xb5, 0xfa, 0xb7, 0xc1, 0xe0, 0x45,
+ 0x6d, 0x01, 0x59, 0xce, 0x09, 0xaa, 0x05, 0x8d,
+ 0xed, 0x67, 0xc0, 0xf7, 0x88, 0x6f, 0xc3, 0x3f,
+ 0xd1, 0xe8, 0x12, 0x97, 0xc4, 0xcc, 0x35, 0x11,
+ },
+ },
+ {
+ .data_len = 128,
+ .digest = {
+ 0xb9, 0xf9, 0xba, 0xdc, 0xea, 0xd7, 0x15, 0x06,
+ 0xaa, 0x4a, 0x68, 0x78, 0x20, 0xcc, 0xbd, 0x08,
+ 0x4d, 0x36, 0x4f, 0x69, 0x60, 0x3f, 0x29, 0x6b,
+ 0x21, 0x8f, 0xcd, 0xb4, 0xca, 0x5a, 0xed, 0xf3,
+ 0xe8, 0x00, 0x6c, 0x5e, 0x01, 0x22, 0x4a, 0xcb,
+ 0x58, 0x34, 0x17, 0xed, 0xbe, 0x78, 0x2b, 0xd6,
+ 0x09, 0x76, 0x72, 0x9c, 0xac, 0x95, 0x76, 0x9e,
+ 0x1c, 0xdc, 0xa4, 0x18, 0x6b, 0x28, 0x7e, 0x39,
+ },
+ },
+ {
+ .data_len = 129,
+ .digest = {
+ 0xe6, 0x9e, 0xd1, 0x79, 0xbc, 0xc2, 0x1a, 0x84,
+ 0xa3, 0xb9, 0xc0, 0x7b, 0x0a, 0x08, 0xd5, 0x9a,
+ 0xe0, 0x9a, 0x24, 0xc2, 0xe3, 0x7d, 0x25, 0x2f,
+ 0xa2, 0xd7, 0x6c, 0xd5, 0xda, 0x06, 0x41, 0xe8,
+ 0x66, 0xe5, 0xbc, 0x08, 0xa6, 0x27, 0x88, 0xca,
+ 0xdc, 0x9f, 0xfd, 0x21, 0xb5, 0x11, 0x31, 0x1f,
+ 0xcc, 0xf3, 0x9c, 0xbf, 0x89, 0xda, 0x4d, 0x9c,
+ 0x04, 0xed, 0x0e, 0x30, 0xb5, 0x93, 0xb9, 0xd7,
+ },
+ },
+ {
+ .data_len = 256,
+ .digest = {
+ 0xda, 0x47, 0x2c, 0xbb, 0xe6, 0x34, 0xef, 0xaa,
+ 0x16, 0xd2, 0x6e, 0x0e, 0xd2, 0x46, 0x1b, 0xcc,
+ 0x29, 0xbe, 0xde, 0x16, 0xef, 0x7e, 0x66, 0x19,
+ 0x03, 0x37, 0x80, 0x97, 0x15, 0x45, 0x58, 0xcb,
+ 0x26, 0x21, 0xdb, 0x55, 0x8b, 0x69, 0x40, 0x9e,
+ 0x23, 0x2b, 0x95, 0xfb, 0x20, 0x96, 0x1d, 0x6e,
+ 0x3b, 0xec, 0xe3, 0x9d, 0x6a, 0x32, 0xfd, 0x07,
+ 0x88, 0x09, 0x3f, 0xca, 0x08, 0xee, 0xb2, 0x6d,
+ },
+ },
+ {
+ .data_len = 511,
+ .digest = {
+ 0x05, 0xb6, 0x9b, 0x75, 0x2d, 0x5d, 0xbd, 0xd3,
+ 0xc5, 0xb3, 0xf6, 0x58, 0x75, 0x20, 0xba, 0x38,
+ 0x57, 0xc9, 0x35, 0xce, 0xab, 0x3d, 0xd4, 0x13,
+ 0x68, 0xd0, 0x93, 0xef, 0x37, 0x16, 0x39, 0x41,
+ 0xa7, 0xe4, 0x19, 0xa0, 0x0c, 0x47, 0x1d, 0xc2,
+ 0x9d, 0xda, 0x8d, 0x02, 0x7b, 0x08, 0x23, 0x32,
+ 0xb4, 0x08, 0x09, 0xc1, 0x57, 0xb2, 0x52, 0xda,
+ 0x09, 0x24, 0x3c, 0x03, 0x13, 0x12, 0x92, 0xb0,
+ },
+ },
+ {
+ .data_len = 513,
+ .digest = {
+ 0xbf, 0x52, 0xcd, 0x71, 0xe7, 0x8d, 0x59, 0x05,
+ 0x75, 0x3a, 0xad, 0x7c, 0xc3, 0x2c, 0xbc, 0xac,
+ 0x6f, 0x13, 0xf3, 0xce, 0xbd, 0x1f, 0x1f, 0xd0,
+ 0x02, 0xbf, 0x8e, 0x59, 0xd4, 0xd7, 0xb1, 0x47,
+ 0xb5, 0x21, 0x26, 0x0f, 0x8b, 0x1e, 0xce, 0xf2,
+ 0x36, 0x29, 0x40, 0xbd, 0x27, 0xd3, 0x2f, 0x61,
+ 0x59, 0x5f, 0xed, 0xaf, 0x75, 0xe1, 0x43, 0xc0,
+ 0x1a, 0xda, 0x01, 0x7c, 0xc2, 0x6a, 0xba, 0x4e,
+ },
+ },
+ {
+ .data_len = 1000,
+ .digest = {
+ 0x0f, 0xcc, 0xcd, 0xa0, 0x1f, 0x05, 0xa1, 0xd4,
+ 0x40, 0xb1, 0xfe, 0x64, 0xa3, 0x3c, 0x02, 0x47,
+ 0x8b, 0x6b, 0xf8, 0xe0, 0xf0, 0x62, 0xf1, 0x72,
+ 0xf5, 0xd5, 0xfa, 0xb6, 0x99, 0xcd, 0xb7, 0xbe,
+ 0x7f, 0xae, 0xcc, 0xd3, 0xd9, 0x33, 0x1d, 0xc0,
+ 0x82, 0xf5, 0xef, 0xb6, 0x7c, 0xd1, 0x3d, 0x49,
+ 0xef, 0x38, 0x4e, 0xb3, 0xda, 0x48, 0xef, 0xf6,
+ 0x56, 0x62, 0x49, 0x5e, 0x19, 0x1d, 0x89, 0x8b,
+ },
+ },
+ {
+ .data_len = 3333,
+ .digest = {
+ 0x12, 0x7c, 0xfd, 0xed, 0xb2, 0x03, 0x74, 0x25,
+ 0xfc, 0x41, 0xf6, 0xd6, 0x21, 0x08, 0xcf, 0x28,
+ 0x10, 0xbe, 0xfb, 0xb8, 0x97, 0x12, 0x12, 0x7c,
+ 0x5f, 0xbc, 0x8c, 0x0d, 0xa3, 0xaa, 0xa0, 0xf2,
+ 0xc3, 0xa0, 0xab, 0xc7, 0xb5, 0xcb, 0xc0, 0xff,
+ 0x93, 0x4e, 0xae, 0x5c, 0xea, 0xef, 0x7e, 0x4f,
+ 0xc2, 0xe1, 0xca, 0x7e, 0xda, 0xb1, 0x9b, 0xb6,
+ 0x8e, 0xcf, 0x3d, 0x6d, 0x3a, 0x83, 0x29, 0x7b,
+ },
+ },
+ {
+ .data_len = 4096,
+ .digest = {
+ 0x8b, 0x07, 0xf7, 0x29, 0x0c, 0xd7, 0xba, 0x42,
+ 0x99, 0xfc, 0xb2, 0x79, 0x59, 0x8a, 0xc2, 0x87,
+ 0x80, 0x0e, 0x4d, 0x18, 0xe9, 0xb3, 0x4c, 0x50,
+ 0xd5, 0xd5, 0xd4, 0x25, 0xf0, 0x30, 0x33, 0x77,
+ 0x6c, 0xc8, 0x3e, 0xfb, 0xbc, 0xc0, 0x34, 0xeb,
+ 0xf9, 0xfb, 0x80, 0x80, 0x75, 0x1a, 0x42, 0x68,
+ 0x76, 0x7b, 0x63, 0xc1, 0xf3, 0xca, 0x28, 0x53,
+ 0xba, 0x28, 0x19, 0xa4, 0xa0, 0x0d, 0xa6, 0x29,
+ },
+ },
+ {
+ .data_len = 4128,
+ .digest = {
+ 0xee, 0xbe, 0x8d, 0xf1, 0x23, 0x57, 0x62, 0xf7,
+ 0xd6, 0x6d, 0xa0, 0x22, 0xdb, 0x0f, 0x66, 0xc3,
+ 0x0e, 0x40, 0x00, 0x1b, 0x6f, 0xc3, 0x85, 0x35,
+ 0x86, 0xe9, 0x91, 0x65, 0xc8, 0xfd, 0xb4, 0x5b,
+ 0x65, 0x43, 0x6b, 0xd6, 0xd8, 0xaf, 0xd2, 0x70,
+ 0xae, 0x8f, 0x48, 0xd5, 0x29, 0x26, 0x79, 0xc5,
+ 0x5b, 0xad, 0xe5, 0xee, 0x3b, 0x20, 0x45, 0x78,
+ 0xe0, 0x74, 0x14, 0x4e, 0xa7, 0x90, 0xb4, 0x7e,
+ },
+ },
+ {
+ .data_len = 4160,
+ .digest = {
+ 0x7f, 0x27, 0xac, 0xc0, 0x20, 0x89, 0x8b, 0x2a,
+ 0x4c, 0x93, 0x79, 0x98, 0x91, 0x17, 0x11, 0x44,
+ 0xdb, 0x21, 0x53, 0x72, 0x90, 0x1c, 0xbe, 0xa6,
+ 0x76, 0xfb, 0x59, 0x2e, 0x68, 0x6a, 0xad, 0xff,
+ 0x5b, 0x9d, 0xfa, 0x83, 0xf5, 0x26, 0xcb, 0x89,
+ 0x33, 0xbf, 0x51, 0x87, 0x1a, 0x94, 0xb2, 0x4f,
+ 0x77, 0xee, 0xab, 0xe0, 0xc8, 0x8a, 0xa2, 0x79,
+ 0x5e, 0xb0, 0xe0, 0x2d, 0x25, 0x9b, 0xff, 0x1b,
+ },
+ },
+ {
+ .data_len = 4224,
+ .digest = {
+ 0xa5, 0x86, 0x6d, 0x50, 0xbf, 0x35, 0xe6, 0x35,
+ 0x21, 0xb1, 0xab, 0x55, 0x48, 0xad, 0xbd, 0x31,
+ 0x6a, 0xb2, 0xd0, 0x4d, 0x27, 0x0b, 0x9a, 0x54,
+ 0x00, 0x53, 0xa6, 0x02, 0x5a, 0x11, 0x2e, 0xcd,
+ 0x4d, 0xa0, 0x62, 0x16, 0xf5, 0x18, 0xc1, 0x53,
+ 0x69, 0x2b, 0xd3, 0x11, 0x6f, 0x19, 0xf2, 0xbc,
+ 0x64, 0xa4, 0xce, 0xe7, 0x62, 0x97, 0xb6, 0xb3,
+ 0x4f, 0xf5, 0x2c, 0x8c, 0xa0, 0xe2, 0x36, 0xdc,
+ },
+ },
+ {
+ .data_len = 16384,
+ .digest = {
+ 0x57, 0xd6, 0xfc, 0x07, 0xa0, 0x38, 0x35, 0x9f,
+ 0x76, 0xcc, 0x39, 0xe7, 0xdc, 0x8c, 0x53, 0x75,
+ 0x71, 0x18, 0x42, 0x92, 0xea, 0xc1, 0x57, 0xce,
+ 0xf5, 0xb6, 0xdc, 0x31, 0xf1, 0x0c, 0xfb, 0x51,
+ 0xb3, 0x18, 0xd6, 0x1e, 0xd0, 0x83, 0xa5, 0xe4,
+ 0x86, 0xbe, 0xfe, 0x2c, 0xe9, 0x65, 0x1f, 0xe3,
+ 0x95, 0xce, 0x6d, 0xdf, 0x57, 0xfd, 0x44, 0x8a,
+ 0x24, 0xbd, 0x4a, 0x89, 0xb7, 0xc4, 0xdc, 0x43,
+ },
+ },
+};
+
+static const u8 hash_testvec_consolidated[SHA3_512_DIGEST_SIZE] = {
+ 0xf7, 0xdd, 0x09, 0x36, 0xf8, 0x51, 0x62, 0x2b,
+ 0xa6, 0x90, 0x6c, 0x22, 0x83, 0xe7, 0xea, 0xd3,
+ 0xbe, 0x6c, 0xb0, 0xb4, 0xef, 0x18, 0x49, 0x20,
+ 0xf6, 0x29, 0x26, 0x5e, 0xdf, 0x6d, 0x2f, 0x4d,
+ 0x74, 0xa8, 0xba, 0x68, 0x42, 0xc0, 0x9e, 0xb5,
+ 0x41, 0x33, 0x61, 0x29, 0x31, 0x59, 0x04, 0x86,
+ 0x25, 0x5f, 0x06, 0xb0, 0xc8, 0x3d, 0x5e, 0xfa,
+ 0x40, 0x99, 0x91, 0x46, 0x18, 0x2e, 0x31, 0xa5,
+};
diff --git a/lib/crypto/tests/sha3_shake128_kunit.c b/lib/crypto/tests/sha3_shake128_kunit.c
new file mode 100644
index 000000000000..9277327cba61
--- /dev/null
+++ b/lib/crypto/tests/sha3_shake128_kunit.c
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@...hat.com)
+ */
+#include <crypto/sha3.h>
+#include "sha3_shake128_testvecs.h"
+
+static int test_shake128_128(const u8 *in, size_t in_len, u8 *out)
+{
+ return shake128(in, in_len, out, SHAKE128_DIGEST_SIZE);
+}
+
+static void test_shake128_init_128(struct sha3_ctx *ctx)
+{
+ return shake128_init(ctx, SHAKE128_DIGEST_SIZE);
+}
+
+#define HASH test_shake128_128
+#define HASH_CTX sha3_ctx
+#define HASH_SIZE SHAKE128_DIGEST_SIZE
+#define HASH_INIT test_shake128_init_128
+#define HASH_UPDATE sha3_update
+#define HASH_FINAL sha3_final
+#include "hash-test-template.h"
+
+static struct kunit_case hash_test_cases[] = {
+ HASH_KUNIT_CASES,
+ KUNIT_CASE(benchmark_hash),
+ {},
+};
+
+static struct kunit_suite hash_test_suite = {
+ .name = "shake128",
+ .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 SHAKE-128 with 128-bit digest");
+MODULE_LICENSE("GPL");
diff --git a/lib/crypto/tests/sha3_shake128_testvecs.h b/lib/crypto/tests/sha3_shake128_testvecs.h
new file mode 100644
index 000000000000..0b7e5393de4d
--- /dev/null
+++ b/lib/crypto/tests/sha3_shake128_testvecs.h
@@ -0,0 +1,181 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* This file was generated by: ../../../scripts/crypto/gen-hash-testvecs.py shake128 */
+
+static const struct {
+ size_t data_len;
+ u8 digest[SHAKE128_DIGEST_SIZE];
+} hash_testvecs[] = {
+ {
+ .data_len = 0,
+ .digest = {
+ 0x7f, 0x9c, 0x2b, 0xa4, 0xe8, 0x8f, 0x82, 0x7d,
+ 0x61, 0x60, 0x45, 0x50, 0x76, 0x05, 0x85, 0x3e,
+ },
+ },
+ {
+ .data_len = 1,
+ .digest = {
+ 0xa6, 0x5e, 0xcf, 0x33, 0x0f, 0x30, 0x76, 0x6c,
+ 0x64, 0x9f, 0x94, 0x7a, 0x7f, 0xfa, 0x3a, 0x3a,
+ },
+ },
+ {
+ .data_len = 2,
+ .digest = {
+ 0x61, 0x70, 0x9c, 0xe0, 0x22, 0xed, 0xff, 0xad,
+ 0xfe, 0x2c, 0x70, 0xde, 0x54, 0x66, 0xe0, 0x36,
+ },
+ },
+ {
+ .data_len = 3,
+ .digest = {
+ 0xfc, 0xb1, 0x3e, 0x14, 0xc7, 0x37, 0xe4, 0xd9,
+ 0x91, 0x78, 0x88, 0x80, 0x23, 0xa5, 0xe0, 0xac,
+ },
+ },
+ {
+ .data_len = 16,
+ .digest = {
+ 0xaa, 0x42, 0x2f, 0xfb, 0x5e, 0x87, 0xf3, 0xf4,
+ 0x73, 0x28, 0x21, 0x34, 0x41, 0xc6, 0x34, 0xa4,
+ },
+ },
+ {
+ .data_len = 32,
+ .digest = {
+ 0x66, 0x01, 0x42, 0x87, 0x59, 0x1a, 0x47, 0x67,
+ 0x4e, 0x4f, 0xfc, 0x25, 0x61, 0x44, 0xda, 0x25,
+ },
+ },
+ {
+ .data_len = 48,
+ .digest = {
+ 0x76, 0xa2, 0x47, 0xff, 0x72, 0x60, 0x53, 0x86,
+ 0x7d, 0x53, 0x0f, 0xbe, 0xb6, 0x47, 0x2d, 0xee,
+ },
+ },
+ {
+ .data_len = 49,
+ .digest = {
+ 0xb2, 0xbe, 0xc4, 0x58, 0xc5, 0x92, 0x06, 0x61,
+ 0x5a, 0x08, 0x58, 0xb7, 0x43, 0xf8, 0x53, 0x95,
+ },
+ },
+ {
+ .data_len = 63,
+ .digest = {
+ 0x00, 0x45, 0xf4, 0xdf, 0x8c, 0xf9, 0xc4, 0x5e,
+ 0xb5, 0x01, 0x95, 0x4f, 0xcf, 0xd5, 0xd7, 0x3f,
+ },
+ },
+ {
+ .data_len = 64,
+ .digest = {
+ 0xff, 0x23, 0xf8, 0x05, 0x6a, 0x35, 0xe8, 0xec,
+ 0x42, 0xec, 0x8c, 0x76, 0x1e, 0x0d, 0x75, 0x38,
+ },
+ },
+ {
+ .data_len = 65,
+ .digest = {
+ 0x11, 0xcd, 0x3e, 0xcc, 0xf7, 0x2f, 0x75, 0xc5,
+ 0x5a, 0x46, 0x0c, 0x80, 0x2b, 0xed, 0xf4, 0x33,
+ },
+ },
+ {
+ .data_len = 127,
+ .digest = {
+ 0x8d, 0x00, 0xe7, 0x21, 0xbc, 0x6c, 0x29, 0xd2,
+ 0x49, 0x3f, 0x66, 0x39, 0xf2, 0xa3, 0x54, 0xa9,
+ },
+ },
+ {
+ .data_len = 128,
+ .digest = {
+ 0xf7, 0x3d, 0x71, 0x74, 0x6b, 0xd2, 0x4c, 0xe0,
+ 0x11, 0x9b, 0x14, 0xcd, 0x1e, 0x2b, 0xae, 0xd2,
+ },
+ },
+ {
+ .data_len = 129,
+ .digest = {
+ 0x8e, 0xa7, 0xdf, 0xa6, 0x32, 0x9f, 0x5c, 0x9a,
+ 0x01, 0xa2, 0xf9, 0x02, 0xf1, 0x34, 0x36, 0x30,
+ },
+ },
+ {
+ .data_len = 256,
+ .digest = {
+ 0x5c, 0x9f, 0x55, 0x8c, 0x5e, 0x08, 0x8e, 0xd8,
+ 0xa6, 0x07, 0xa9, 0xa1, 0x51, 0x42, 0xd3, 0xff,
+ },
+ },
+ {
+ .data_len = 511,
+ .digest = {
+ 0xb5, 0xc5, 0x92, 0x5b, 0xc6, 0x07, 0xd6, 0xca,
+ 0x30, 0x4d, 0x12, 0x98, 0x67, 0x8d, 0x1f, 0x0c,
+ },
+ },
+ {
+ .data_len = 513,
+ .digest = {
+ 0x99, 0x33, 0xe9, 0xf2, 0x2b, 0xd5, 0xdf, 0xc4,
+ 0x03, 0x7b, 0x48, 0xca, 0x28, 0x4d, 0x40, 0x6e,
+ },
+ },
+ {
+ .data_len = 1000,
+ .digest = {
+ 0x86, 0xbd, 0xe0, 0x6f, 0x54, 0xd7, 0xb1, 0xb2,
+ 0xda, 0xc6, 0xec, 0x26, 0xa2, 0xbf, 0x4e, 0xa4,
+ },
+ },
+ {
+ .data_len = 3333,
+ .digest = {
+ 0x8a, 0xd9, 0xb2, 0xb2, 0xbc, 0x35, 0x6e, 0x80,
+ 0x6d, 0x43, 0xe8, 0xf5, 0x3a, 0x89, 0xb8, 0x25,
+ },
+ },
+ {
+ .data_len = 4096,
+ .digest = {
+ 0xff, 0x86, 0x5d, 0xe3, 0x4f, 0xb4, 0x75, 0xb2,
+ 0x12, 0x29, 0xd0, 0xd3, 0xeb, 0x2d, 0x65, 0x91,
+ },
+ },
+ {
+ .data_len = 4128,
+ .digest = {
+ 0x99, 0x84, 0x6b, 0xaa, 0x2d, 0x54, 0xb4, 0x81,
+ 0x9d, 0x97, 0xa3, 0x23, 0x8c, 0x97, 0xfc, 0x7c,
+ },
+ },
+ {
+ .data_len = 4160,
+ .digest = {
+ 0xa8, 0x25, 0x51, 0x1c, 0x48, 0xea, 0xb4, 0xe3,
+ 0x59, 0xbb, 0x30, 0x84, 0x3e, 0x98, 0x14, 0x28,
+ },
+ },
+ {
+ .data_len = 4224,
+ .digest = {
+ 0xa4, 0x8d, 0x19, 0xff, 0xf3, 0xec, 0xa9, 0xff,
+ 0xe9, 0x16, 0x48, 0x26, 0x29, 0x4b, 0xb8, 0x8d,
+ },
+ },
+ {
+ .data_len = 16384,
+ .digest = {
+ 0x31, 0xd9, 0x5c, 0xc7, 0xbc, 0xd5, 0x6f, 0xfb,
+ 0x49, 0xd3, 0x75, 0x52, 0xcd, 0xc2, 0x1a, 0xa4,
+ },
+ },
+};
+
+static const u8 hash_testvec_consolidated[SHAKE128_DIGEST_SIZE] = {
+ 0x6f, 0x31, 0x9a, 0x7f, 0xbb, 0x0a, 0x36, 0x25,
+ 0x0e, 0x98, 0x4c, 0xe1, 0x16, 0x9a, 0xf7, 0xdd,
+};
diff --git a/lib/crypto/tests/sha3_shake256_kunit.c b/lib/crypto/tests/sha3_shake256_kunit.c
new file mode 100644
index 000000000000..8fe495811f97
--- /dev/null
+++ b/lib/crypto/tests/sha3_shake256_kunit.c
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@...hat.com)
+ */
+#include <crypto/sha3.h>
+#include "sha3_shake256_testvecs.h"
+
+static int test_shake256_256(const u8 *in, size_t in_len, u8 *out)
+{
+ return shake256(in, in_len, out, SHAKE256_DIGEST_SIZE);
+}
+
+static void test_shake256_init_256(struct sha3_ctx *ctx)
+{
+ return shake256_init(ctx, SHAKE256_DIGEST_SIZE);
+}
+
+#define HASH test_shake256_256
+#define HASH_CTX sha3_ctx
+#define HASH_SIZE SHAKE256_DIGEST_SIZE
+#define HASH_INIT test_shake256_init_256
+#define HASH_UPDATE sha3_update
+#define HASH_FINAL sha3_final
+#include "hash-test-template.h"
+
+static struct kunit_case hash_test_cases[] = {
+ HASH_KUNIT_CASES,
+ KUNIT_CASE(benchmark_hash),
+ {},
+};
+
+static struct kunit_suite hash_test_suite = {
+ .name = "shake256",
+ .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 SHAKE-256 with 256-bit digest");
+MODULE_LICENSE("GPL");
diff --git a/lib/crypto/tests/sha3_shake256_testvecs.h b/lib/crypto/tests/sha3_shake256_testvecs.h
new file mode 100644
index 000000000000..ee70a677a44e
--- /dev/null
+++ b/lib/crypto/tests/sha3_shake256_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 shake256 */
+
+static const struct {
+ size_t data_len;
+ u8 digest[SHAKE256_DIGEST_SIZE];
+} hash_testvecs[] = {
+ {
+ .data_len = 0,
+ .digest = {
+ 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,
+ },
+ },
+ {
+ .data_len = 1,
+ .digest = {
+ 0x54, 0x96, 0x57, 0xea, 0x93, 0x2b, 0xb5, 0x8f,
+ 0xe5, 0xfc, 0x76, 0xe8, 0x01, 0xdd, 0xc8, 0x25,
+ 0x4e, 0x22, 0x0b, 0xa7, 0xb4, 0xe1, 0x50, 0xe2,
+ 0x34, 0x8b, 0x9e, 0xdb, 0xc2, 0xc9, 0x51, 0xa3,
+ },
+ },
+ {
+ .data_len = 2,
+ .digest = {
+ 0xf3, 0xfc, 0x74, 0x4a, 0x54, 0x34, 0x01, 0xf7,
+ 0xa7, 0xf2, 0x50, 0xa0, 0x0b, 0x2a, 0x3c, 0x4b,
+ 0x12, 0xd4, 0xd3, 0xf7, 0xd6, 0x89, 0x5d, 0xce,
+ 0xcb, 0xfe, 0xd9, 0x57, 0x28, 0x4f, 0xdc, 0x9d,
+ },
+ },
+ {
+ .data_len = 3,
+ .digest = {
+ 0x36, 0x3d, 0xd3, 0xf7, 0xf4, 0xf3, 0x1b, 0xca,
+ 0xba, 0x75, 0x81, 0x0d, 0xad, 0xb5, 0xeb, 0xad,
+ 0x74, 0x4e, 0x3c, 0xad, 0x33, 0x62, 0x4b, 0xee,
+ 0xdc, 0x15, 0x66, 0xaa, 0x61, 0x65, 0x2e, 0x5c,
+ },
+ },
+ {
+ .data_len = 16,
+ .digest = {
+ 0xc7, 0xce, 0xcb, 0x21, 0xce, 0x45, 0xbd, 0xd5,
+ 0x76, 0x31, 0x76, 0x41, 0xf4, 0x3f, 0x77, 0xbf,
+ 0x17, 0xa2, 0xd8, 0xa9, 0x8e, 0x35, 0xc2, 0x8f,
+ 0x16, 0xba, 0x50, 0x50, 0x7c, 0xf5, 0x3c, 0xa4,
+ },
+ },
+ {
+ .data_len = 32,
+ .digest = {
+ 0x61, 0x82, 0xc8, 0xea, 0x8c, 0x26, 0x46, 0x6b,
+ 0xc4, 0x54, 0xf8, 0x5f, 0x12, 0x15, 0x00, 0xe8,
+ 0xab, 0xac, 0x39, 0xb9, 0xbb, 0x60, 0x24, 0x5e,
+ 0x55, 0x2d, 0x24, 0xcc, 0x91, 0x46, 0x21, 0x8b,
+ },
+ },
+ {
+ .data_len = 48,
+ .digest = {
+ 0x68, 0xcd, 0xc9, 0x90, 0x16, 0xca, 0x72, 0xcb,
+ 0xb5, 0x84, 0x0d, 0x02, 0x89, 0x3b, 0x9c, 0x0e,
+ 0x67, 0x24, 0x0a, 0xbb, 0x5a, 0xe6, 0x3c, 0xca,
+ 0x62, 0x75, 0x0a, 0x93, 0x8e, 0xe3, 0xae, 0xed,
+ },
+ },
+ {
+ .data_len = 49,
+ .digest = {
+ 0x0c, 0xc1, 0xb0, 0xd8, 0xcb, 0xf7, 0xa7, 0x55,
+ 0x7a, 0x87, 0xb8, 0x65, 0x9c, 0x23, 0xfa, 0x02,
+ 0x34, 0x45, 0xb9, 0xe9, 0x35, 0xe8, 0x9f, 0xf2,
+ 0xcf, 0x02, 0xaa, 0x7a, 0x8d, 0x49, 0x69, 0xd0,
+ },
+ },
+ {
+ .data_len = 63,
+ .digest = {
+ 0x9b, 0x76, 0x53, 0xed, 0x46, 0x2b, 0x7d, 0x40,
+ 0xd1, 0xc7, 0x83, 0xda, 0x5e, 0xbd, 0x73, 0x69,
+ 0xc7, 0x40, 0x65, 0x44, 0x5a, 0x0e, 0xf3, 0xb5,
+ 0xfc, 0x30, 0x98, 0x00, 0x32, 0x50, 0xb8, 0x26,
+ },
+ },
+ {
+ .data_len = 64,
+ .digest = {
+ 0xab, 0xfa, 0x35, 0xcb, 0xf2, 0xc3, 0xf8, 0x8b,
+ 0x0a, 0xec, 0xb4, 0x5a, 0x45, 0x54, 0x33, 0xf7,
+ 0x13, 0x26, 0x62, 0x1c, 0x94, 0x37, 0x47, 0x07,
+ 0x24, 0xfc, 0xd4, 0x2a, 0x8e, 0x71, 0x3f, 0xf3,
+ },
+ },
+ {
+ .data_len = 65,
+ .digest = {
+ 0x45, 0x7d, 0xbb, 0x96, 0x0c, 0xb0, 0x63, 0x4e,
+ 0xc5, 0xe6, 0xfe, 0x6e, 0x78, 0x55, 0xaf, 0x2d,
+ 0x0b, 0x2b, 0x08, 0x2e, 0xbf, 0xfd, 0x4b, 0xf3,
+ 0xe0, 0x0b, 0xa7, 0x11, 0x52, 0xf7, 0x43, 0xe1,
+ },
+ },
+ {
+ .data_len = 127,
+ .digest = {
+ 0xc2, 0x66, 0xdb, 0x73, 0x17, 0x6e, 0xc1, 0xf0,
+ 0xb7, 0xad, 0x8c, 0xa8, 0x4f, 0xfc, 0x6d, 0x6b,
+ 0x96, 0xff, 0x9d, 0x63, 0x7e, 0x2a, 0x49, 0x93,
+ 0x16, 0xca, 0x78, 0x7b, 0x80, 0x19, 0x3d, 0x48,
+ },
+ },
+ {
+ .data_len = 128,
+ .digest = {
+ 0x08, 0x23, 0xfb, 0x6c, 0xcd, 0x62, 0x9d, 0x95,
+ 0x44, 0xf1, 0x62, 0xd2, 0x41, 0x54, 0x2d, 0xe4,
+ 0x55, 0x2b, 0xc6, 0x1c, 0xec, 0xb9, 0x34, 0x29,
+ 0x21, 0x4d, 0x39, 0x8e, 0xbe, 0x6c, 0x9c, 0xb3,
+ },
+ },
+ {
+ .data_len = 129,
+ .digest = {
+ 0x68, 0xe6, 0xf1, 0x5e, 0x57, 0x3a, 0x04, 0xc0,
+ 0x6a, 0x59, 0x7c, 0x80, 0x09, 0x1f, 0x9d, 0x4d,
+ 0x88, 0x73, 0xd5, 0xb3, 0x69, 0x57, 0x8a, 0xf0,
+ 0x00, 0x6c, 0xe3, 0x59, 0x8e, 0x1e, 0xcc, 0x21,
+ },
+ },
+ {
+ .data_len = 256,
+ .digest = {
+ 0x0b, 0xc3, 0xb8, 0xb5, 0x6e, 0x03, 0x62, 0xb5,
+ 0x52, 0x0a, 0xab, 0x64, 0x6a, 0xc1, 0x06, 0x50,
+ 0x57, 0xdf, 0x4a, 0x50, 0x20, 0x5e, 0x06, 0x4c,
+ 0xa3, 0xa6, 0x7c, 0x28, 0x86, 0x54, 0x67, 0x1d,
+ },
+ },
+ {
+ .data_len = 511,
+ .digest = {
+ 0x25, 0xa8, 0x9b, 0xc4, 0xee, 0xcf, 0xe8, 0xf7,
+ 0xe1, 0xb2, 0x3b, 0x91, 0xf4, 0x05, 0x89, 0x04,
+ 0x9c, 0xb0, 0x9a, 0xe4, 0x06, 0xea, 0xc0, 0x8f,
+ 0x2f, 0x7c, 0xf9, 0x4b, 0x6c, 0x53, 0x68, 0x56,
+ },
+ },
+ {
+ .data_len = 513,
+ .digest = {
+ 0x49, 0x56, 0x69, 0x90, 0x94, 0x8c, 0xbc, 0x28,
+ 0x60, 0x09, 0x87, 0xd8, 0x32, 0x9b, 0x33, 0xd6,
+ 0x6b, 0xd9, 0x1b, 0x11, 0x9a, 0x50, 0x62, 0xbf,
+ 0x8a, 0x43, 0x96, 0x5d, 0xdd, 0xef, 0x2a, 0x54,
+ },
+ },
+ {
+ .data_len = 1000,
+ .digest = {
+ 0xa2, 0xf3, 0xa6, 0x25, 0xb9, 0x4f, 0xfc, 0xa1,
+ 0x43, 0xae, 0x12, 0x03, 0x7f, 0xa7, 0x2a, 0x0b,
+ 0xcc, 0x0f, 0xd4, 0x7c, 0x22, 0x57, 0x99, 0xfe,
+ 0x9a, 0x68, 0x30, 0x64, 0xf1, 0xb1, 0xa3, 0xeb,
+ },
+ },
+ {
+ .data_len = 3333,
+ .digest = {
+ 0xba, 0x0a, 0x14, 0xbc, 0xa0, 0x6d, 0xf3, 0x68,
+ 0xb9, 0x36, 0xc4, 0x8f, 0xf8, 0x0e, 0x4c, 0x21,
+ 0x48, 0x33, 0xfe, 0x7b, 0x2d, 0x30, 0x2e, 0xed,
+ 0x43, 0xc0, 0x95, 0xf0, 0x4c, 0x6e, 0xd0, 0x31,
+ },
+ },
+ {
+ .data_len = 4096,
+ .digest = {
+ 0x8d, 0x60, 0x87, 0x64, 0x6f, 0xf0, 0xbc, 0xfd,
+ 0xb6, 0x29, 0x5d, 0xfc, 0xe5, 0x2d, 0x7d, 0x1d,
+ 0x8f, 0xd0, 0x20, 0xdd, 0xaf, 0x2c, 0x71, 0x65,
+ 0xfd, 0x95, 0x6c, 0x1b, 0x97, 0x6c, 0xd9, 0x51,
+ },
+ },
+ {
+ .data_len = 4128,
+ .digest = {
+ 0x8d, 0x1b, 0xb3, 0xdc, 0x75, 0x75, 0x90, 0x35,
+ 0x8c, 0x09, 0x26, 0x9c, 0x4a, 0x90, 0x08, 0x2e,
+ 0xd8, 0x7c, 0xf7, 0x9b, 0x57, 0xe8, 0xee, 0xe4,
+ 0xa5, 0xb0, 0xa4, 0x5f, 0x4f, 0x3b, 0x0f, 0xe2,
+ },
+ },
+ {
+ .data_len = 4160,
+ .digest = {
+ 0x24, 0xf4, 0xb6, 0x6e, 0x3f, 0x00, 0x29, 0x69,
+ 0x29, 0xc2, 0x0e, 0x9f, 0x7c, 0x6c, 0x69, 0x74,
+ 0xb6, 0x6f, 0x5e, 0xfc, 0xee, 0x71, 0xe8, 0x29,
+ 0xeb, 0x61, 0x16, 0xa8, 0xe7, 0x78, 0xe5, 0xc5,
+ },
+ },
+ {
+ .data_len = 4224,
+ .digest = {
+ 0x07, 0x42, 0xd7, 0xc8, 0x91, 0x72, 0x45, 0xe5,
+ 0x32, 0xb8, 0xa8, 0x4f, 0xf6, 0x69, 0xca, 0xae,
+ 0x2a, 0x5a, 0x67, 0x8d, 0x87, 0x63, 0x4c, 0xaa,
+ 0xc6, 0xe3, 0x5d, 0x8d, 0xf6, 0x54, 0x29, 0xbb,
+ },
+ },
+ {
+ .data_len = 16384,
+ .digest = {
+ 0x35, 0x9d, 0xd4, 0x76, 0xa9, 0xf3, 0xd8, 0x8b,
+ 0x27, 0xe8, 0x94, 0x01, 0xdd, 0xb3, 0x75, 0x03,
+ 0xd5, 0xa4, 0x96, 0xf4, 0xa0, 0x04, 0x48, 0xfd,
+ 0x5f, 0x34, 0x0e, 0x0d, 0x41, 0x3a, 0x06, 0xc8,
+ },
+ },
+};
+
+static const u8 hash_testvec_consolidated[SHAKE256_DIGEST_SIZE] = {
+ 0x4b, 0xb0, 0x5b, 0x22, 0x55, 0x3d, 0x33, 0x1a,
+ 0xe7, 0x1c, 0x8f, 0xbe, 0xcb, 0xec, 0xbd, 0x88,
+ 0x1e, 0x83, 0x49, 0x25, 0xe2, 0xff, 0xb4, 0xf6,
+ 0x10, 0xe4, 0x9c, 0x59, 0x24, 0x38, 0xe7, 0x1a,
+};
diff --git a/scripts/crypto/gen-hash-testvecs.py b/scripts/crypto/gen-hash-testvecs.py
index 4ac927d40cf5..f0bc057bd76d 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):
@@ -117,7 +121,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))
def gen_additional_poly1305_testvecs():
key = b'\xff' * POLY1305_KEY_SIZE
@@ -143,5 +147,5 @@ print(f'/* This file was generated by: {sys.argv[0]} {" ".join(sys.argv[1:])} */
gen_unkeyed_testvecs(alg)
if alg == 'poly1305':
gen_additional_poly1305_testvecs()
-else:
+elif alg != 'shake128' and alg != 'shake256':
gen_hmac_testvecs(alg)
Powered by blists - more mailing lists