[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250611020923.1482701-5-ebiggers@kernel.org>
Date: Tue, 10 Jun 2025 19:09:11 -0700
From: Eric Biggers <ebiggers@...nel.org>
To: linux-crypto@...r.kernel.org
Cc: linux-kernel@...r.kernel.org,
linux-arm-kernel@...ts.infradead.org,
linux-mips@...r.kernel.org,
linux-riscv@...ts.infradead.org,
linux-s390@...r.kernel.org,
sparclinux@...r.kernel.org,
x86@...nel.org,
Ard Biesheuvel <ardb@...nel.org>,
"Jason A . Donenfeld " <Jason@...c4.com>,
Linus Torvalds <torvalds@...ux-foundation.org>
Subject: [PATCH 04/16] lib/crypto/sha512: add KUnit tests for SHA-384 and SHA-512
From: Eric Biggers <ebiggers@...gle.com>
Add KUnit tests for the SHA-384 and SHA-512 library functions, including
the corresponding HMAC support.
Testing strategy:
- Each SHA variant gets its own KUnit test suite, but a header is used
to share most of the test code among the SHA variants.
- Test against vectors generated by the Python hashlib and hmac modules.
- Test incremental computation.
- Test with a guard page to catch buffer overruns even in assembly code.
- Test various overlap and alignment cases.
- Compute hashes in task, softirq, and hardirq context in parallel, to
verify that the functions work as expected in all contexts and that
fallback code paths are exercised.
- Test that the finalization functions zeroize their context.
- Include benchmarks, guarded by a separate Kconfig option.
Signed-off-by: Eric Biggers <ebiggers@...gle.com>
---
lib/crypto/Kconfig | 2 +
lib/crypto/Makefile | 2 +
lib/crypto/tests/Kconfig | 16 +
lib/crypto/tests/Makefile | 4 +
lib/crypto/tests/hash-test-template.h | 512 ++++++++++++++++++++
lib/crypto/tests/sha384-testvecs.h | 566 ++++++++++++++++++++++
lib/crypto/tests/sha384_kunit.c | 48 ++
lib/crypto/tests/sha512-testvecs.h | 662 ++++++++++++++++++++++++++
lib/crypto/tests/sha512_kunit.c | 48 ++
scripts/crypto/gen-hash-testvecs.py | 83 ++++
10 files changed, 1943 insertions(+)
create mode 100644 lib/crypto/tests/Kconfig
create mode 100644 lib/crypto/tests/Makefile
create mode 100644 lib/crypto/tests/hash-test-template.h
create mode 100644 lib/crypto/tests/sha384-testvecs.h
create mode 100644 lib/crypto/tests/sha384_kunit.c
create mode 100644 lib/crypto/tests/sha512-testvecs.h
create mode 100644 lib/crypto/tests/sha512_kunit.c
create mode 100755 scripts/crypto/gen-hash-testvecs.py
diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig
index 2ef61c69ae709..34b249ca3db23 100644
--- a/lib/crypto/Kconfig
+++ b/lib/crypto/Kconfig
@@ -1,9 +1,11 @@
# SPDX-License-Identifier: GPL-2.0
menu "Crypto library routines"
+source "lib/crypto/tests/Kconfig"
+
config CRYPTO_LIB_UTILS
tristate
config CRYPTO_LIB_AES
tristate
diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile
index 7e8baa4590896..7df76ab5fe692 100644
--- a/lib/crypto/Makefile
+++ b/lib/crypto/Makefile
@@ -1,7 +1,9 @@
# SPDX-License-Identifier: GPL-2.0
+obj-y += tests/
+
obj-$(CONFIG_CRYPTO_LIB_UTILS) += libcryptoutils.o
libcryptoutils-y := memneq.o utils.o
# chacha is used by the /dev/random driver which is always builtin
obj-y += chacha.o
diff --git a/lib/crypto/tests/Kconfig b/lib/crypto/tests/Kconfig
new file mode 100644
index 0000000000000..90be320c25bd2
--- /dev/null
+++ b/lib/crypto/tests/Kconfig
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config CRYPTO_LIB_SHA512_KUNIT_TEST
+ tristate "KUnit tests for SHA-384 and SHA-512" if !KUNIT_ALL_TESTS
+ depends on KUNIT
+ default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS
+ select CRYPTO_LIB_SHA512
+ help
+ KUnit tests for the SHA-384 and SHA-512 cryptographic hash functions
+ and their corresponding HMACs.
+
+config CRYPTO_LIB_BENCHMARK
+ bool "Include benchmarks in KUnit tests for cryptographic functions"
+ depends on CRYPTO_LIB_SHA512_KUNIT_TEST
+ help
+ Include benchmarks in the KUnit tests for cryptographic functions.
diff --git a/lib/crypto/tests/Makefile b/lib/crypto/tests/Makefile
new file mode 100644
index 0000000000000..3925dcb6513d8
--- /dev/null
+++ b/lib/crypto/tests/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_CRYPTO_LIB_SHA512_KUNIT_TEST) += sha384_kunit.o
+obj-$(CONFIG_CRYPTO_LIB_SHA512_KUNIT_TEST) += sha512_kunit.o
diff --git a/lib/crypto/tests/hash-test-template.h b/lib/crypto/tests/hash-test-template.h
new file mode 100644
index 0000000000000..3d5b838aa572a
--- /dev/null
+++ b/lib/crypto/tests/hash-test-template.h
@@ -0,0 +1,512 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright 2025 Google LLC
+ */
+#include <kunit/test.h>
+#include <linux/hrtimer.h>
+#include <linux/vmalloc.h>
+#include <linux/workqueue.h>
+
+/* test_buf is a guarded buffer, i.e. &test_buf[TEST_BUF_LEN] is not mapped. */
+#define TEST_BUF_LEN 16384
+static u8 *test_buf;
+
+static u8 *orig_test_buf;
+
+static u64 random_seed;
+
+/*
+ * This is a simple linear congruential generator. It is used only for testing,
+ * which does not require cryptographically secure random numbers. A hard-coded
+ * algorithm is used instead of <linux/prandom.h> so that it matches the
+ * algorithm used by the test vector generation script. This allows the input
+ * data in random test vectors to be concisely stored as just the seed.
+ */
+static u32 rand32(void)
+{
+ random_seed = (random_seed * 25214903917 + 11) & ((1ULL << 48) - 1);
+ return random_seed >> 16;
+}
+
+static void rand_bytes(u8 *out, size_t len)
+{
+ for (size_t i = 0; i < len; i++)
+ out[i] = rand32();
+}
+
+static bool rand_bool(void)
+{
+ return rand32() % 2;
+}
+
+/* Generate a random length, preferring small lengths. */
+static size_t rand_length(size_t max_len)
+{
+ size_t len;
+
+ switch (rand32() % 3) {
+ case 0:
+ len = rand32() % 128;
+ break;
+ case 1:
+ len = rand32() % 3072;
+ break;
+ default:
+ len = rand32();
+ break;
+ }
+ return len % (max_len + 1);
+}
+
+static size_t rand_offset(size_t max_offset)
+{
+ return min(rand32() % 128, max_offset);
+}
+
+static int hash_suite_init(struct kunit_suite *suite)
+{
+ /*
+ * Allocate the test buffer using vmalloc() with a page-aligned length
+ * so that it is immediately followed by a guard page. This allows
+ * buffer overreads to be detected, even in assembly code.
+ */
+ size_t alloc_len = round_up(TEST_BUF_LEN, PAGE_SIZE);
+
+ orig_test_buf = vmalloc(alloc_len);
+ if (!orig_test_buf)
+ return -ENOMEM;
+
+ test_buf = orig_test_buf + alloc_len - TEST_BUF_LEN;
+ rand_bytes(test_buf, TEST_BUF_LEN);
+ return 0;
+}
+
+static void hash_suite_exit(struct kunit_suite *suite)
+{
+ vfree(orig_test_buf);
+ orig_test_buf = NULL;
+}
+
+static void rand_bytes_seeded_from_len(u8 *out, size_t len)
+{
+ random_seed = len;
+ rand_bytes(out, len);
+}
+
+/*
+ * Test that the hash function produces the expected results from the test
+ * vectors.
+ *
+ * Note that it's only necessary to run each test vector in one way (e.g.,
+ * one-shot instead of a chain of incremental updates), since consistency
+ * between different ways of using the APIs is verified by other test cases.
+ */
+static void test_hash_test_vectors(struct kunit *test)
+{
+ for (size_t i = 0; i < ARRAY_SIZE(HASH_TESTVECS); i++) {
+ size_t data_len = HASH_TESTVECS[i].data_len;
+ u8 actual_digest[HASH_SIZE];
+
+ KUNIT_ASSERT_LE(test, data_len, TEST_BUF_LEN);
+
+ rand_bytes_seeded_from_len(test_buf, data_len);
+
+ HASH(test_buf, data_len, actual_digest);
+ KUNIT_ASSERT_MEMEQ_MSG(
+ test, actual_digest, HASH_TESTVECS[i].digest, HASH_SIZE,
+ "Wrong result with test vector %zu; data_len=%zu", i,
+ data_len);
+ }
+}
+
+/*
+ * Test that the hash function produces the same result for a one-shot
+ * computation vs. an incremental computation.
+ */
+static void test_hash_incremental_updates(struct kunit *test)
+{
+ for (size_t i = 0; i < 1000; i++) {
+ size_t total_len, offset;
+ struct HASH_CTX ctx;
+ u8 hash1[HASH_SIZE];
+ u8 hash2[HASH_SIZE];
+ size_t num_parts = 0;
+ size_t remaining_len, cur_offset;
+
+ total_len = rand_length(TEST_BUF_LEN);
+ offset = rand_offset(TEST_BUF_LEN - total_len);
+
+ if (rand32() % 8 == 0)
+ /* Refresh the data occasionally. */
+ rand_bytes(&test_buf[offset], total_len);
+
+ /* Compute the hash value in one step. */
+ HASH(&test_buf[offset], total_len, hash1);
+
+ /* Compute the hash value incrementally. */
+ HASH_INIT(&ctx);
+ remaining_len = total_len;
+ cur_offset = offset;
+ while (rand_bool()) {
+ size_t part_len = rand_length(remaining_len);
+
+ HASH_UPDATE(&ctx, &test_buf[cur_offset], part_len);
+ num_parts++;
+ cur_offset += part_len;
+ remaining_len -= part_len;
+ }
+ if (remaining_len != 0 || rand_bool()) {
+ HASH_UPDATE(&ctx, &test_buf[cur_offset], remaining_len);
+ num_parts++;
+ }
+ HASH_FINAL(&ctx, hash2);
+
+ /* Compare the two hash values. */
+ KUNIT_ASSERT_MEMEQ_MSG(
+ test, hash1, hash2, HASH_SIZE,
+ "Incremental test failed with total_len=%zu num_parts=%zu offset=%zu\n",
+ total_len, num_parts, offset);
+ }
+}
+
+/*
+ * Test that the hash function does not overrun any buffers. Uses a guard page
+ * to catch buffer overruns even if they occur in assembly code.
+ */
+static void test_hash_buffer_overruns(struct kunit *test)
+{
+ const size_t max_tested_len = TEST_BUF_LEN - sizeof(struct HASH_CTX);
+ void *const buf_end = &test_buf[TEST_BUF_LEN];
+ struct HASH_CTX *guarded_ctx = buf_end - sizeof(*guarded_ctx);
+
+ for (size_t i = 0; i < 100; i++) {
+ size_t len = rand_length(max_tested_len);
+ u8 hash[HASH_SIZE];
+ struct HASH_CTX ctx;
+
+ /* Check for overruns of the data buffer. */
+ HASH(buf_end - len, len, hash);
+ HASH_INIT(&ctx);
+ HASH_UPDATE(&ctx, buf_end - len, len);
+ HASH_FINAL(&ctx, hash);
+
+ /* Check for overruns of the hash value buffer. */
+ HASH(test_buf, len, buf_end - HASH_SIZE);
+ HASH_INIT(&ctx);
+ HASH_UPDATE(&ctx, test_buf, len);
+ HASH_FINAL(&ctx, buf_end - HASH_SIZE);
+
+ /* Check for overuns of the hash context. */
+ HASH_INIT(guarded_ctx);
+ HASH_UPDATE(guarded_ctx, test_buf, len);
+ HASH_FINAL(guarded_ctx, hash);
+ }
+}
+
+/*
+ * Test that the caller is permitted to alias the output digest and source data
+ * buffer, and also modify the source data buffer after it has been used.
+ */
+static void test_hash_overlaps(struct kunit *test)
+{
+ const size_t max_tested_len = TEST_BUF_LEN - HASH_SIZE;
+ u8 hash[HASH_SIZE];
+ struct HASH_CTX ctx;
+
+ for (size_t i = 0; i < 100; i++) {
+ size_t len = rand_length(max_tested_len);
+ size_t offset = HASH_SIZE + rand_offset(max_tested_len - len);
+ bool left_end = rand_bool();
+ u8 *ovl_hash = left_end ? &test_buf[offset] :
+ &test_buf[offset + len - HASH_SIZE];
+
+ HASH(&test_buf[offset], len, hash);
+ HASH(&test_buf[offset], len, ovl_hash);
+ KUNIT_ASSERT_MEMEQ_MSG(
+ test, hash, ovl_hash, HASH_SIZE,
+ "Overlap test 1 failed with len=%zu offset=%zu left_end=%d\n",
+ len, offset, left_end);
+
+ HASH(&test_buf[offset], len, hash);
+ HASH_INIT(&ctx);
+ HASH_UPDATE(&ctx, &test_buf[offset], len);
+ HASH_FINAL(&ctx, ovl_hash);
+ KUNIT_ASSERT_MEMEQ_MSG(
+ test, hash, ovl_hash, HASH_SIZE,
+ "Overlap test 2 failed with len=%zu offset=%zu left_end=%d\n",
+ len, offset, left_end);
+
+ HASH(&test_buf[offset], len, hash);
+ HASH_INIT(&ctx);
+ HASH_UPDATE(&ctx, &test_buf[offset], len);
+ rand_bytes(&test_buf[offset], len);
+ HASH_FINAL(&ctx, ovl_hash);
+ KUNIT_ASSERT_MEMEQ_MSG(
+ test, hash, ovl_hash, HASH_SIZE,
+ "Overlap test 3 failed with len=%zu offset=%zu left_end=%d\n",
+ len, offset, left_end);
+ }
+}
+
+/*
+ * Test that if the same data is hashed at different alignments in memory, the
+ * results are the same.
+ */
+static void test_hash_alignment_consistency(struct kunit *test)
+{
+ u8 hash1[128 + HASH_SIZE];
+ u8 hash2[128 + HASH_SIZE];
+
+ for (size_t i = 0; i < 100; i++) {
+ size_t len = rand_length(TEST_BUF_LEN);
+ size_t data_offs1 = rand_offset(TEST_BUF_LEN - len);
+ size_t data_offs2 = rand_offset(TEST_BUF_LEN - len);
+ size_t hash_offs1 = rand_offset(128);
+ size_t hash_offs2 = rand_offset(128);
+
+ rand_bytes(&test_buf[data_offs1], len);
+ HASH(&test_buf[data_offs1], len, &hash1[hash_offs1]);
+ memmove(&test_buf[data_offs2], &test_buf[data_offs1], len);
+ HASH(&test_buf[data_offs2], len, &hash2[hash_offs2]);
+ KUNIT_ASSERT_MEMEQ_MSG(
+ test, &hash1[hash_offs1], &hash2[hash_offs2], HASH_SIZE,
+ "Alignment consistency test failed with len=%zu data_offs=(%zu,%zu) hash_offs=(%zu,%zu)\n",
+ len, data_offs1, data_offs2, hash_offs1, hash_offs2);
+ }
+}
+
+/* Test that HASH_FINAL zeroizes the context. */
+static void test_hash_ctx_zeroization(struct kunit *test)
+{
+ static const u8 zeroes[sizeof(struct HASH_CTX)];
+ struct HASH_CTX ctx;
+
+ HASH_INIT(&ctx);
+ HASH_UPDATE(&ctx, test_buf, 128);
+ HASH_FINAL(&ctx, test_buf);
+ KUNIT_EXPECT_MEMEQ_MSG(test, &ctx, zeroes, sizeof(ctx),
+ "Hash context was not zeroized by finalization");
+}
+
+#define IRQ_TEST_DATA_LEN 256
+#define IRQ_TEST_NUM_BUFFERS 3
+#define IRQ_TEST_HRTIMER_INTERVAL us_to_ktime(5)
+
+struct irq_test_state {
+ struct hrtimer timer;
+ struct work_struct bh_work;
+ u8 expected_hashes[IRQ_TEST_NUM_BUFFERS][HASH_SIZE];
+ atomic_t seqno;
+ atomic_t timer_func_calls;
+ atomic_t bh_func_calls;
+ bool task_wrong_result;
+ bool timer_func_wrong_result;
+ bool bh_func_wrong_result;
+};
+
+/*
+ * Compute a hash of one of the test messages and check for the expected result
+ * that was saved earlier in @state->expected_hashes. To increase the chance of
+ * detecting problems, this cycles through multiple messages.
+ */
+static bool irq_test_step(struct irq_test_state *state)
+{
+ u32 i = (u32)atomic_inc_return(&state->seqno) % IRQ_TEST_NUM_BUFFERS;
+ u8 actual_hash[HASH_SIZE];
+
+ HASH(&test_buf[i * IRQ_TEST_DATA_LEN], IRQ_TEST_DATA_LEN, actual_hash);
+ return memcmp(actual_hash, state->expected_hashes[i], HASH_SIZE) == 0;
+}
+
+/*
+ * This is the timer function run by the IRQ test. It is called in hardirq
+ * context. It computes a hash, checks for the correct result, then reschedules
+ * the timer and also the BH work.
+ */
+static enum hrtimer_restart irq_test_timer_func(struct hrtimer *timer)
+{
+ struct irq_test_state *state =
+ container_of(timer, typeof(*state), timer);
+
+ WARN_ON_ONCE(!in_hardirq());
+ atomic_inc(&state->timer_func_calls);
+ if (!irq_test_step(state))
+ state->timer_func_wrong_result = true;
+
+ hrtimer_forward_now(&state->timer, IRQ_TEST_HRTIMER_INTERVAL);
+ queue_work(system_bh_wq, &state->bh_work);
+ return HRTIMER_RESTART;
+}
+
+/* Compute a hash in softirq context and check for the expected result. */
+static void irq_test_bh_func(struct work_struct *work)
+{
+ struct irq_test_state *state =
+ container_of(work, typeof(*state), bh_work);
+
+ WARN_ON_ONCE(!in_serving_softirq());
+ atomic_inc(&state->bh_func_calls);
+ if (!irq_test_step(state))
+ state->bh_func_wrong_result = true;
+}
+
+/*
+ * Test that if hashes are computed in parallel in task, softirq, and hardirq
+ * context, then all results are as expected.
+ *
+ * The primary purpose of this test is to verify the correctness of fallback
+ * code paths that runs in contexts where the normal code path cannot be used,
+ * e.g. !may_use_simd(). These code paths are not covered by any of the other
+ * tests, which are executed by the KUnit test runner thread in task context.
+ *
+ * In addition, this test may detect issues with the architecture's
+ * irq_fpu_usable() and kernel_fpu_begin/end() or equivalent functions.
+ */
+static void test_hash_interrupt_context(struct kunit *test)
+{
+ struct irq_test_state state = {};
+ size_t i;
+ unsigned long end_jiffies;
+
+ /* Prepare some test messages and compute the expected hash of each. */
+ rand_bytes(test_buf, IRQ_TEST_NUM_BUFFERS * IRQ_TEST_DATA_LEN);
+ for (i = 0; i < IRQ_TEST_NUM_BUFFERS; i++)
+ HASH(&test_buf[i * IRQ_TEST_DATA_LEN], IRQ_TEST_DATA_LEN,
+ state.expected_hashes[i]);
+
+ /*
+ * Set up a hrtimer (the way we access hardirq context) and a work
+ * struct for the BH workqueue (the way we access softirq context).
+ */
+ hrtimer_setup_on_stack(&state.timer, irq_test_timer_func,
+ CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ INIT_WORK(&state.bh_work, irq_test_bh_func);
+
+ /* Run for up to 100000 hashes or 1 second, whichever comes first. */
+ end_jiffies = jiffies + HZ;
+ hrtimer_start(&state.timer, IRQ_TEST_HRTIMER_INTERVAL,
+ HRTIMER_MODE_REL);
+ for (i = 0; i < 100000 && !time_after(jiffies, end_jiffies); i++) {
+ if (!irq_test_step(&state))
+ state.task_wrong_result = true;
+ }
+
+ /* Cancel the timer and work. */
+ hrtimer_cancel(&state.timer);
+ flush_work(&state.bh_work);
+
+ /* Sanity check: the timer and BH functions should have been run. */
+ KUNIT_EXPECT_GT_MSG(test, atomic_read(&state.timer_func_calls), 0,
+ "IRQ test failed; timer function was not called");
+ KUNIT_EXPECT_GT_MSG(test, atomic_read(&state.bh_func_calls), 0,
+ "IRQ test failed; BH work function was not called");
+
+ /* Check the results. */
+ KUNIT_EXPECT_FALSE_MSG(test, state.task_wrong_result,
+ "IRQ test failed; wrong result in task context");
+ KUNIT_EXPECT_FALSE_MSG(
+ test, state.timer_func_wrong_result,
+ "IRQ test failed; wrong result in timer function (hardirq context)");
+ KUNIT_EXPECT_FALSE_MSG(
+ test, state.bh_func_wrong_result,
+ "IRQ test failed; wrong result in BH work function (softirq context)");
+}
+
+#ifdef HMAC
+/*
+ * Test the corresponding HMAC variant. This is a bit less thorough than the
+ * tests for the hash function, since HMAC is just a small C wrapper around the
+ * unkeyed hash function.
+ */
+static void test_hmac(struct kunit *test)
+{
+ u8 *raw_key = kunit_kmalloc(test, TEST_BUF_LEN, GFP_KERNEL);
+ static const u8 zeroes[sizeof(struct HMAC_CTX)];
+
+ KUNIT_ASSERT_NOT_NULL(test, raw_key);
+
+ for (size_t i = 0; i < ARRAY_SIZE(HMAC_TESTVECS); i++) {
+ size_t data_len = HMAC_TESTVECS[i].data_len;
+ size_t key_len = HMAC_TESTVECS[i].key_len;
+ struct HMAC_CTX ctx;
+ struct HMAC_KEY key;
+ u8 actual_mac[HASH_SIZE];
+
+ KUNIT_ASSERT_LE(test, data_len, TEST_BUF_LEN);
+ KUNIT_ASSERT_LE(test, key_len, TEST_BUF_LEN);
+
+ rand_bytes_seeded_from_len(test_buf, data_len);
+ rand_bytes_seeded_from_len(raw_key, key_len);
+
+ HMAC_USINGRAWKEY(raw_key, key_len, test_buf, data_len,
+ actual_mac);
+ KUNIT_ASSERT_MEMEQ_MSG(
+ test, actual_mac, HMAC_TESTVECS[i].mac, HASH_SIZE,
+ "Wrong result with HMAC test vector %zu using raw key; data_len=%zu key_len=%zu",
+ i, data_len, key_len);
+
+ memset(actual_mac, 0xff, HASH_SIZE);
+ HMAC_SETKEY(&key, raw_key, key_len);
+ HMAC(&key, test_buf, data_len, actual_mac);
+ KUNIT_ASSERT_MEMEQ_MSG(
+ test, actual_mac, HMAC_TESTVECS[i].mac, HASH_SIZE,
+ "Wrong result with HMAC test vector %zu using key struct; data_len=%zu key_len=%zu",
+ i, data_len, key_len);
+
+ memset(actual_mac, 0xff, HASH_SIZE);
+ HMAC_INIT(&ctx, &key);
+ HMAC_UPDATE(&ctx, test_buf, data_len);
+ HMAC_FINAL(&ctx, actual_mac);
+ KUNIT_ASSERT_MEMEQ_MSG(
+ test, actual_mac, HMAC_TESTVECS[i].mac, HASH_SIZE,
+ "Wrong result with HMAC test vector %zu on init+update+final; data_len=%zu key_len=%zu",
+ i, data_len, key_len);
+ KUNIT_ASSERT_MEMEQ_MSG(
+ test, &ctx, zeroes, sizeof(ctx),
+ "HMAC context was not zeroized by finalization");
+
+ memset(actual_mac, 0xff, HASH_SIZE);
+ HMAC_INIT(&ctx, &key);
+ HMAC_UPDATE(&ctx, test_buf, data_len / 2);
+ HMAC_UPDATE(&ctx, &test_buf[data_len / 2], (data_len + 1) / 2);
+ HMAC_FINAL(&ctx, actual_mac);
+ KUNIT_ASSERT_MEMEQ_MSG(
+ test, actual_mac, HMAC_TESTVECS[i].mac, HASH_SIZE,
+ "Wrong result with HMAC test vector %zu on init+update+update+final; data_len=%zu key_len=%zu",
+ i, data_len, key_len);
+ }
+}
+#endif /* HMAC */
+
+/* Benchmark the hash function on various data lengths. */
+static void benchmark_hash(struct kunit *test)
+{
+ static const size_t lens_to_test[] = {
+ 1, 16, 64, 127, 128, 200, 256,
+ 511, 512, 1024, 3173, 4096, 16384,
+ };
+ size_t len, i, j, num_iters;
+ u8 hash[HASH_SIZE];
+ u64 t;
+
+ if (!IS_ENABLED(CONFIG_CRYPTO_LIB_BENCHMARK))
+ kunit_skip(test, "not enabled");
+
+ /* warm-up */
+ for (i = 0; i < 10000000; i += TEST_BUF_LEN)
+ HASH(test_buf, TEST_BUF_LEN, hash);
+
+ for (i = 0; i < ARRAY_SIZE(lens_to_test); i++) {
+ len = lens_to_test[i];
+ KUNIT_ASSERT_LE(test, len, TEST_BUF_LEN);
+ num_iters = 10000000 / (len + 128);
+ preempt_disable();
+ t = ktime_get_ns();
+ for (j = 0; j < num_iters; j++)
+ HASH(test_buf, len, hash);
+ t = ktime_get_ns() - t;
+ preempt_enable();
+ kunit_info(test, "len=%zu: %llu MB/s\n", len,
+ div64_u64((u64)len * num_iters * 1000, t));
+ }
+}
diff --git a/lib/crypto/tests/sha384-testvecs.h b/lib/crypto/tests/sha384-testvecs.h
new file mode 100644
index 0000000000000..7ea330dfe54f3
--- /dev/null
+++ b/lib/crypto/tests/sha384-testvecs.h
@@ -0,0 +1,566 @@
+/* This file was generated by: ./scripts/crypto/gen-hash-testvecs.py sha384 */
+
+static const struct {
+ size_t data_len;
+ u8 digest[SHA384_DIGEST_SIZE];
+} sha384_testvecs[] = {
+ {
+ .data_len = 0,
+ .digest = {
+ 0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38,
+ 0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a,
+ 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43,
+ 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda,
+ 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb,
+ 0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b,
+ },
+ },
+ {
+ .data_len = 1,
+ .digest = {
+ 0x07, 0x34, 0x9d, 0x74, 0x48, 0x76, 0xa5, 0x72,
+ 0x78, 0x02, 0xb8, 0x6e, 0x21, 0x59, 0xb0, 0x75,
+ 0x09, 0x68, 0x11, 0x39, 0x53, 0x61, 0xee, 0x8d,
+ 0xf2, 0x01, 0xf3, 0x90, 0x53, 0x7c, 0xd3, 0xde,
+ 0x13, 0x9f, 0xd2, 0x74, 0x28, 0xfe, 0xe1, 0xc8,
+ 0x2e, 0x95, 0xc6, 0x7d, 0x69, 0x4d, 0x04, 0xc6,
+ },
+ },
+ {
+ .data_len = 2,
+ .digest = {
+ 0xc4, 0xef, 0x6e, 0x8c, 0x19, 0x1c, 0xaa, 0x0e,
+ 0x86, 0xf2, 0x68, 0xa1, 0xa0, 0x2d, 0x2e, 0xb2,
+ 0x84, 0xbc, 0x5d, 0x53, 0x31, 0xf8, 0x03, 0x75,
+ 0x56, 0xf4, 0x8b, 0x23, 0x1a, 0x68, 0x15, 0x9a,
+ 0x60, 0xb2, 0xec, 0x05, 0xe1, 0xd4, 0x5e, 0x9e,
+ 0xe8, 0x7c, 0x9d, 0xe4, 0x0f, 0x9c, 0x3a, 0xdd,
+ },
+ },
+ {
+ .data_len = 3,
+ .digest = {
+ 0x29, 0xd2, 0x02, 0xa2, 0x77, 0x24, 0xc7, 0xa7,
+ 0x23, 0x0c, 0x3e, 0x30, 0x56, 0x47, 0xdb, 0x75,
+ 0xd4, 0x41, 0xf8, 0xb3, 0x8e, 0x26, 0xf6, 0x92,
+ 0xbc, 0x20, 0x2e, 0x96, 0xcc, 0x81, 0x5f, 0x32,
+ 0x82, 0x60, 0xe2, 0xcf, 0x23, 0xd7, 0x3c, 0x90,
+ 0xb2, 0x56, 0x8f, 0xb6, 0x0f, 0xf0, 0x6b, 0x80,
+ },
+ },
+ {
+ .data_len = 16,
+ .digest = {
+ 0x21, 0x4c, 0xac, 0xfe, 0xbd, 0x40, 0x74, 0x1f,
+ 0xa2, 0x2d, 0x2f, 0x35, 0x91, 0xfd, 0xc9, 0x97,
+ 0x88, 0x12, 0x6c, 0x0c, 0x6e, 0xd8, 0x50, 0x0b,
+ 0x4b, 0x2c, 0x89, 0xa6, 0xa6, 0x4a, 0xad, 0xd7,
+ 0x72, 0x62, 0x2c, 0x62, 0x81, 0xcd, 0x24, 0x74,
+ 0xf5, 0x44, 0x05, 0xa0, 0x97, 0xea, 0xf1, 0x78,
+ },
+ },
+ {
+ .data_len = 32,
+ .digest = {
+ 0x06, 0x8b, 0x92, 0x9f, 0x8b, 0x64, 0xb2, 0x80,
+ 0xde, 0xcc, 0xde, 0xc3, 0x2f, 0x22, 0x27, 0xe8,
+ 0x3b, 0x6e, 0x16, 0x21, 0x14, 0x81, 0xbe, 0x5b,
+ 0xa7, 0xa7, 0x14, 0x8a, 0x00, 0x8f, 0x0d, 0x38,
+ 0x11, 0x63, 0xe8, 0x3e, 0xb9, 0xf1, 0xcf, 0x87,
+ 0xb1, 0x28, 0xe5, 0xa1, 0x89, 0xa8, 0x7a, 0xde,
+ },
+ },
+ {
+ .data_len = 48,
+ .digest = {
+ 0x9e, 0x37, 0x76, 0x62, 0x98, 0x39, 0xbe, 0xfd,
+ 0x2b, 0x91, 0x20, 0x54, 0x8f, 0x21, 0xe7, 0x30,
+ 0x0a, 0x01, 0x7a, 0x65, 0x0b, 0xc9, 0xb3, 0x89,
+ 0x3c, 0xb6, 0xd3, 0xa8, 0xff, 0xc9, 0x1b, 0x5c,
+ 0xd4, 0xac, 0xb4, 0x7e, 0xba, 0x94, 0xc3, 0x8a,
+ 0x26, 0x41, 0xf6, 0xd5, 0xed, 0x6f, 0x27, 0xa7,
+ },
+ },
+ {
+ .data_len = 49,
+ .digest = {
+ 0x03, 0x1f, 0xef, 0x5a, 0x16, 0x28, 0x78, 0x10,
+ 0x29, 0xe8, 0xe2, 0xe4, 0x84, 0x36, 0x19, 0x10,
+ 0xaa, 0xea, 0xde, 0x06, 0x39, 0x5f, 0xb2, 0x36,
+ 0xca, 0x24, 0x4f, 0x7b, 0x66, 0xf7, 0xe7, 0x31,
+ 0xf3, 0x9b, 0x74, 0x1e, 0x17, 0x20, 0x88, 0x62,
+ 0x50, 0xeb, 0x5f, 0x9a, 0xa7, 0x2c, 0xf4, 0xc9,
+ },
+ },
+ {
+ .data_len = 63,
+ .digest = {
+ 0x10, 0xce, 0xed, 0x26, 0xb8, 0xac, 0xc1, 0x1b,
+ 0xe6, 0xb9, 0xeb, 0x7c, 0xae, 0xcd, 0x55, 0x5a,
+ 0x20, 0x2a, 0x7b, 0x43, 0xe6, 0x3e, 0xf0, 0x3f,
+ 0xd9, 0x2f, 0x8c, 0x52, 0xe2, 0xf0, 0xb6, 0x24,
+ 0x2e, 0xa4, 0xac, 0x24, 0x3a, 0x54, 0x99, 0x71,
+ 0x65, 0xab, 0x97, 0x2d, 0xb6, 0xe6, 0x94, 0x20,
+ },
+ },
+ {
+ .data_len = 64,
+ .digest = {
+ 0x24, 0x6d, 0x9f, 0x59, 0x42, 0x36, 0xca, 0x34,
+ 0x36, 0x41, 0xa2, 0xcd, 0x69, 0xdf, 0x3d, 0xcb,
+ 0x64, 0x94, 0x54, 0xb2, 0xed, 0xc1, 0x1c, 0x31,
+ 0xe3, 0x26, 0xcb, 0x71, 0xe6, 0x98, 0xb2, 0x56,
+ 0x74, 0x30, 0xa9, 0x15, 0x98, 0x9d, 0xb3, 0x07,
+ 0xcc, 0xa8, 0xcc, 0x6f, 0x42, 0xb0, 0x9d, 0x2b,
+ },
+ },
+ {
+ .data_len = 65,
+ .digest = {
+ 0x85, 0x1f, 0xbc, 0x5e, 0x2a, 0x00, 0x7d, 0xc2,
+ 0x21, 0x4c, 0x28, 0x14, 0xc5, 0xd8, 0x0c, 0xe8,
+ 0x55, 0xa5, 0xa0, 0x77, 0xda, 0x8f, 0xce, 0xd4,
+ 0xf0, 0xcb, 0x30, 0xb8, 0x9c, 0x47, 0xe1, 0x33,
+ 0x92, 0x18, 0xc5, 0x1f, 0xf2, 0xef, 0xb5, 0xe5,
+ 0xbc, 0x63, 0xa6, 0xe5, 0x9a, 0xc9, 0xcc, 0xf1,
+ },
+ },
+ {
+ .data_len = 127,
+ .digest = {
+ 0x26, 0xd2, 0x4c, 0xb6, 0xce, 0xd8, 0x22, 0x2b,
+ 0x44, 0x10, 0x6f, 0x59, 0xf7, 0x0d, 0xb9, 0x3f,
+ 0x7d, 0x29, 0x75, 0xf1, 0x71, 0xb2, 0x71, 0x23,
+ 0xef, 0x68, 0xb7, 0x25, 0xae, 0xb8, 0x45, 0xf8,
+ 0xa3, 0xb2, 0x2d, 0x7a, 0x83, 0x0a, 0x05, 0x61,
+ 0xbc, 0x73, 0xf1, 0xf9, 0xba, 0xfb, 0x3d, 0xc2,
+ },
+ },
+ {
+ .data_len = 128,
+ .digest = {
+ 0x7c, 0xe5, 0x7f, 0x5e, 0xea, 0xd9, 0x7e, 0x54,
+ 0x14, 0x30, 0x6f, 0x37, 0x02, 0x71, 0x0f, 0xf1,
+ 0x14, 0x16, 0xfa, 0xeb, 0x6e, 0x1e, 0xf0, 0xbe,
+ 0x10, 0xed, 0x01, 0xbf, 0xa0, 0x9d, 0xcb, 0x07,
+ 0x5f, 0x8b, 0x7f, 0x44, 0xe1, 0xd9, 0x13, 0xf0,
+ 0x29, 0xa2, 0x54, 0x32, 0xd9, 0xb0, 0x69, 0x69,
+ },
+ },
+ {
+ .data_len = 129,
+ .digest = {
+ 0xc5, 0x54, 0x1f, 0xcb, 0x9d, 0x8f, 0xdf, 0xbf,
+ 0xab, 0x55, 0x92, 0x1d, 0x3b, 0x93, 0x79, 0x26,
+ 0xdf, 0xba, 0x9a, 0x28, 0xff, 0xa0, 0x6c, 0xae,
+ 0x7b, 0x53, 0x8d, 0xfa, 0xef, 0x35, 0x88, 0x19,
+ 0x16, 0xb8, 0x72, 0x86, 0x76, 0x2a, 0xf5, 0xe6,
+ 0xec, 0xb2, 0xd7, 0xd4, 0xbe, 0x1a, 0xe4, 0x9f,
+ },
+ },
+ {
+ .data_len = 256,
+ .digest = {
+ 0x74, 0x9d, 0x77, 0xfb, 0xe8, 0x0f, 0x0c, 0x2d,
+ 0x86, 0x0d, 0x49, 0xea, 0x2b, 0xd0, 0x13, 0xd1,
+ 0xe8, 0xb8, 0xe1, 0xa3, 0x7b, 0x48, 0xab, 0x6a,
+ 0x21, 0x2b, 0x4c, 0x48, 0x32, 0xb5, 0xdc, 0x31,
+ 0x7f, 0xd0, 0x32, 0x67, 0x9a, 0xc0, 0x85, 0x53,
+ 0xef, 0xe9, 0xfb, 0xe1, 0x8b, 0xd8, 0xcc, 0xc2,
+ },
+ },
+ {
+ .data_len = 511,
+ .digest = {
+ 0x7b, 0xa9, 0xde, 0xa3, 0x07, 0x5c, 0x4c, 0xaa,
+ 0x31, 0xc6, 0x9e, 0x55, 0xd4, 0x3f, 0x52, 0xdd,
+ 0xde, 0x36, 0x70, 0x96, 0x59, 0x6e, 0x90, 0x78,
+ 0x4c, 0x6a, 0x27, 0xde, 0x83, 0x84, 0xc3, 0x35,
+ 0x53, 0x76, 0x1d, 0xbf, 0x83, 0x64, 0xcf, 0xf2,
+ 0xb0, 0x3e, 0x07, 0x27, 0xe4, 0x25, 0x6c, 0x56,
+ },
+ },
+ {
+ .data_len = 513,
+ .digest = {
+ 0x53, 0x50, 0xf7, 0x3b, 0x86, 0x1d, 0x7a, 0xe2,
+ 0x5d, 0x9b, 0x71, 0xfa, 0x25, 0x23, 0x5a, 0xfe,
+ 0x8c, 0xb9, 0xac, 0x8a, 0x9d, 0x6c, 0x99, 0xbc,
+ 0x01, 0x9e, 0xa0, 0xd6, 0x3c, 0x03, 0x46, 0x21,
+ 0xb6, 0xd0, 0xb0, 0xb3, 0x23, 0x23, 0x58, 0xf1,
+ 0xea, 0x4e, 0xf2, 0x1a, 0x2f, 0x14, 0x2b, 0x5a,
+ },
+ },
+ {
+ .data_len = 1000,
+ .digest = {
+ 0x06, 0x03, 0xb3, 0xba, 0x14, 0xe0, 0x28, 0x07,
+ 0xd5, 0x15, 0x97, 0x1f, 0x87, 0xef, 0x80, 0xba,
+ 0x48, 0x03, 0xb6, 0xc5, 0x47, 0xca, 0x8c, 0x95,
+ 0xed, 0x95, 0xfd, 0x27, 0xb6, 0x83, 0xda, 0x6d,
+ 0xa7, 0xb2, 0x1a, 0xd2, 0xb5, 0x89, 0xbb, 0xb4,
+ 0x00, 0xbc, 0x86, 0x54, 0x7d, 0x5a, 0x91, 0x63,
+ },
+ },
+ {
+ .data_len = 3333,
+ .digest = {
+ 0xd3, 0xe0, 0x6e, 0x7d, 0x80, 0x08, 0x53, 0x07,
+ 0x8c, 0x0f, 0xc2, 0xce, 0x9f, 0x09, 0x86, 0x31,
+ 0x28, 0x24, 0x3c, 0x3e, 0x2d, 0x36, 0xb4, 0x28,
+ 0xc7, 0x1b, 0x70, 0xf9, 0x35, 0x9b, 0x10, 0xfa,
+ 0xc8, 0x5e, 0x2b, 0x32, 0x7f, 0x65, 0xd2, 0x68,
+ 0xb2, 0x84, 0x90, 0xf6, 0xc8, 0x6e, 0xb8, 0xdb,
+ },
+ },
+ {
+ .data_len = 4096,
+ .digest = {
+ 0x39, 0xeb, 0xc4, 0xb3, 0x08, 0xe2, 0xdd, 0xf3,
+ 0x9f, 0x5e, 0x44, 0x93, 0x63, 0x8b, 0x39, 0x57,
+ 0xd7, 0xe8, 0x7e, 0x3d, 0x74, 0xf8, 0xf6, 0xab,
+ 0xfe, 0x74, 0x51, 0xe4, 0x1b, 0x4a, 0x23, 0xbc,
+ 0x69, 0xfc, 0xbb, 0xa7, 0x71, 0xa7, 0x86, 0x24,
+ 0xcc, 0x85, 0x70, 0xf2, 0x31, 0x0d, 0x47, 0xc0,
+ },
+ },
+ {
+ .data_len = 4128,
+ .digest = {
+ 0x23, 0xc3, 0x97, 0x06, 0x79, 0xbe, 0x8a, 0xe9,
+ 0x1f, 0x1a, 0x43, 0xad, 0xe6, 0x76, 0x23, 0x13,
+ 0x64, 0xae, 0xda, 0xe7, 0x8b, 0x88, 0x96, 0xb6,
+ 0xa9, 0x1a, 0xb7, 0x80, 0x8e, 0x1c, 0x94, 0x98,
+ 0x09, 0x08, 0xdb, 0x8e, 0x4d, 0x0a, 0x09, 0x65,
+ 0xe5, 0x21, 0x1c, 0xd9, 0xab, 0x64, 0xbb, 0xea,
+ },
+ },
+ {
+ .data_len = 4160,
+ .digest = {
+ 0x4f, 0x4a, 0x88, 0x9f, 0x40, 0x89, 0xfe, 0xb6,
+ 0xda, 0x9d, 0xcd, 0xa5, 0x27, 0xd2, 0x29, 0x71,
+ 0x58, 0x60, 0xd4, 0x55, 0xfe, 0x92, 0xcd, 0x51,
+ 0x8b, 0xec, 0x3b, 0xd3, 0xd1, 0x3e, 0x8d, 0x36,
+ 0x7b, 0xb1, 0x41, 0xef, 0xec, 0x9d, 0xdf, 0xcd,
+ 0x4e, 0xde, 0x5a, 0xe5, 0xe5, 0x16, 0x14, 0x54,
+ },
+ },
+ {
+ .data_len = 4224,
+ .digest = {
+ 0xb5, 0xa5, 0x3e, 0x86, 0x39, 0x20, 0x49, 0x4c,
+ 0xcd, 0xb6, 0xdd, 0x03, 0xfe, 0x36, 0x6e, 0xa6,
+ 0xfc, 0xff, 0x19, 0x33, 0x0c, 0x52, 0xea, 0x37,
+ 0x94, 0xda, 0x5b, 0x27, 0xd1, 0x99, 0x5a, 0x89,
+ 0x40, 0x78, 0xfa, 0x96, 0xb9, 0x2f, 0xa0, 0x48,
+ 0xc9, 0xf8, 0x5c, 0xf0, 0x95, 0xf4, 0xea, 0x61,
+ },
+ },
+ {
+ .data_len = 16384,
+ .digest = {
+ 0x6f, 0x48, 0x6f, 0x21, 0xb9, 0xc1, 0xcc, 0x92,
+ 0x4e, 0xed, 0x6b, 0xef, 0x51, 0x88, 0xdf, 0xfd,
+ 0xcb, 0x3d, 0x44, 0x9c, 0x37, 0x85, 0xb4, 0xc5,
+ 0xeb, 0x60, 0x55, 0x58, 0x01, 0x47, 0xbf, 0x75,
+ 0x9b, 0xa8, 0x82, 0x8c, 0xec, 0xe8, 0x0e, 0x58,
+ 0xc1, 0x26, 0xa2, 0x45, 0x87, 0x3e, 0xfb, 0x8d,
+ },
+ },
+};
+
+static const struct {
+ size_t data_len;
+ size_t key_len;
+ u8 mac[SHA384_DIGEST_SIZE];
+} hmac_sha384_testvecs[] = {
+ {
+ .data_len = 0,
+ .key_len = 0,
+ .mac = {
+ 0x6c, 0x1f, 0x2e, 0xe9, 0x38, 0xfa, 0xd2, 0xe2,
+ 0x4b, 0xd9, 0x12, 0x98, 0x47, 0x43, 0x82, 0xca,
+ 0x21, 0x8c, 0x75, 0xdb, 0x3d, 0x83, 0xe1, 0x14,
+ 0xb3, 0xd4, 0x36, 0x77, 0x76, 0xd1, 0x4d, 0x35,
+ 0x51, 0x28, 0x9e, 0x75, 0xe8, 0x20, 0x9c, 0xd4,
+ 0xb7, 0x92, 0x30, 0x28, 0x40, 0x23, 0x4a, 0xdc,
+ },
+ },
+ {
+ .data_len = 1,
+ .key_len = 1,
+ .mac = {
+ 0xe5, 0x20, 0x5e, 0xd4, 0x0a, 0xd8, 0x37, 0xff,
+ 0xf9, 0x0e, 0x2b, 0xf2, 0xca, 0x15, 0x65, 0xec,
+ 0xb3, 0xfb, 0x14, 0xa1, 0xc3, 0xdc, 0x9e, 0xa0,
+ 0x96, 0x99, 0xeb, 0x18, 0x24, 0x90, 0x42, 0xef,
+ 0x63, 0x3c, 0x38, 0xd3, 0x19, 0x6b, 0x7f, 0xef,
+ 0x07, 0xb3, 0xb8, 0xb0, 0x43, 0x5f, 0xef, 0xed,
+ },
+ },
+ {
+ .data_len = 2,
+ .key_len = 31,
+ .mac = {
+ 0x47, 0x08, 0x60, 0x37, 0xe9, 0x47, 0x0d, 0x56,
+ 0xa9, 0x81, 0xa1, 0xdf, 0x05, 0x1e, 0x41, 0x4e,
+ 0x7f, 0xf9, 0x51, 0xb3, 0x47, 0x7e, 0x04, 0x4f,
+ 0x0a, 0x05, 0x13, 0x6e, 0xd8, 0x4e, 0x6d, 0x98,
+ 0x91, 0x89, 0xe1, 0xdc, 0x7f, 0x23, 0x03, 0x2e,
+ 0x47, 0x9e, 0x7c, 0xe0, 0x68, 0x08, 0xd2, 0x57,
+ },
+ },
+ {
+ .data_len = 3,
+ .key_len = 32,
+ .mac = {
+ 0xb9, 0x83, 0xdc, 0x7c, 0xb2, 0x48, 0x04, 0xc7,
+ 0xdf, 0x9f, 0x8b, 0xbe, 0x17, 0x80, 0xc5, 0x13,
+ 0x24, 0x10, 0x1c, 0xf1, 0x38, 0x75, 0x87, 0xe6,
+ 0x3a, 0x2e, 0xa2, 0xed, 0x33, 0xdb, 0xfc, 0xd7,
+ 0x0c, 0x8e, 0x89, 0x92, 0x14, 0x19, 0xef, 0x43,
+ 0xef, 0x6b, 0xc7, 0xc5, 0x4d, 0x3f, 0xa4, 0x41,
+ },
+ },
+ {
+ .data_len = 16,
+ .key_len = 33,
+ .mac = {
+ 0xee, 0x3b, 0x6b, 0x7f, 0xec, 0xe1, 0xc4, 0x8f,
+ 0x01, 0x91, 0xc9, 0x1a, 0x18, 0xb3, 0x0f, 0x34,
+ 0xad, 0xe5, 0x1f, 0x51, 0x9a, 0x0b, 0xec, 0xa3,
+ 0xc1, 0x0e, 0xf7, 0x7e, 0xb5, 0xd5, 0xe6, 0x22,
+ 0x44, 0x23, 0x85, 0x2c, 0xe0, 0xb6, 0x81, 0xac,
+ 0x7b, 0x41, 0x49, 0x18, 0x92, 0x0a, 0xd5, 0xc1,
+ },
+ },
+ {
+ .data_len = 32,
+ .key_len = 64,
+ .mac = {
+ 0x4d, 0x1f, 0xd0, 0x53, 0x5e, 0x04, 0x2b, 0xd6,
+ 0xfd, 0xd6, 0xa2, 0xed, 0xa2, 0x49, 0x36, 0xbf,
+ 0x44, 0x8e, 0x42, 0x1c, 0x8a, 0xde, 0x44, 0xbb,
+ 0x43, 0x84, 0xec, 0x70, 0xbb, 0x2d, 0xd3, 0x66,
+ 0x51, 0xc0, 0xed, 0xd1, 0xcd, 0x5b, 0x11, 0xf2,
+ 0x1c, 0xe6, 0x7d, 0xe9, 0xcd, 0xab, 0xff, 0x02,
+ },
+ },
+ {
+ .data_len = 48,
+ .key_len = 65,
+ .mac = {
+ 0x12, 0xfc, 0x9f, 0x95, 0xcd, 0x88, 0xed, 0x8a,
+ 0x6a, 0x87, 0x36, 0x45, 0x63, 0xb9, 0xc8, 0x46,
+ 0xf5, 0x06, 0x97, 0x24, 0x19, 0xc8, 0xfa, 0xfd,
+ 0xcf, 0x2b, 0x78, 0x5d, 0x44, 0xf1, 0x82, 0xbf,
+ 0x93, 0xea, 0x9c, 0x84, 0xe5, 0xba, 0x27, 0x21,
+ 0x2f, 0x3b, 0xd0, 0xfe, 0x2c, 0x53, 0x72, 0x31,
+ },
+ },
+ {
+ .data_len = 49,
+ .key_len = 66,
+ .mac = {
+ 0x8e, 0x8f, 0x3d, 0xd7, 0xe6, 0x14, 0x0c, 0xf2,
+ 0xf6, 0x9a, 0x19, 0xda, 0x4c, 0xb2, 0xc4, 0x84,
+ 0x63, 0x76, 0x5b, 0xae, 0x17, 0xe0, 0xdf, 0x92,
+ 0x82, 0xcf, 0x85, 0xbd, 0xce, 0xde, 0x3b, 0x49,
+ 0xfe, 0x0a, 0xfb, 0xdc, 0x9a, 0xc0, 0x9e, 0xc7,
+ 0x4f, 0x2c, 0x0f, 0xd3, 0xb9, 0x82, 0x1a, 0xaa,
+ },
+ },
+ {
+ .data_len = 63,
+ .key_len = 127,
+ .mac = {
+ 0xc9, 0x17, 0xbb, 0x8f, 0x4f, 0x13, 0xba, 0x99,
+ 0x4e, 0x48, 0x6a, 0x23, 0x12, 0x61, 0x7b, 0xa0,
+ 0x63, 0xcb, 0x47, 0xfd, 0xbd, 0xd3, 0xfd, 0x94,
+ 0xe7, 0x0b, 0xec, 0x04, 0x44, 0x5a, 0xfe, 0xb0,
+ 0x97, 0x5b, 0x80, 0x4c, 0x02, 0x5c, 0x92, 0x05,
+ 0x45, 0xe6, 0xe3, 0x0d, 0x21, 0xa5, 0x9a, 0x11,
+ },
+ },
+ {
+ .data_len = 64,
+ .key_len = 128,
+ .mac = {
+ 0xbf, 0x20, 0x44, 0xe1, 0x91, 0xcf, 0x2b, 0x53,
+ 0xcb, 0xcb, 0x89, 0xc2, 0x1b, 0x8e, 0xcb, 0xb0,
+ 0x12, 0xd2, 0x77, 0x21, 0x7e, 0x8f, 0x40, 0x0f,
+ 0x1e, 0xa4, 0xe7, 0x38, 0x69, 0x0f, 0x58, 0xba,
+ 0x42, 0x78, 0x57, 0x4e, 0x7a, 0xf0, 0xb0, 0xf2,
+ 0xe0, 0x17, 0x17, 0xcf, 0xee, 0x26, 0x53, 0x81,
+ },
+ },
+ {
+ .data_len = 65,
+ .key_len = 129,
+ .mac = {
+ 0x44, 0xe7, 0x53, 0x94, 0xaa, 0x33, 0xb0, 0xde,
+ 0x8e, 0xef, 0x85, 0x19, 0x69, 0x1e, 0xba, 0x69,
+ 0x7f, 0xe1, 0x17, 0xc3, 0x91, 0xd6, 0x7b, 0x07,
+ 0x61, 0xed, 0x81, 0x4c, 0x01, 0x65, 0x36, 0xbd,
+ 0x7d, 0x4f, 0x70, 0xd7, 0x0d, 0xb8, 0xfc, 0xaf,
+ 0x48, 0x1c, 0x96, 0x37, 0xf9, 0xc8, 0x72, 0x00,
+ },
+ },
+ {
+ .data_len = 127,
+ .key_len = 1000,
+ .mac = {
+ 0x98, 0x11, 0x57, 0xfe, 0xa5, 0xd0, 0xed, 0x5e,
+ 0xc5, 0x7e, 0xb3, 0x53, 0x9d, 0x12, 0x38, 0x41,
+ 0x0a, 0x78, 0x75, 0xd4, 0x0f, 0xa6, 0x9f, 0x05,
+ 0xd3, 0x2e, 0xcd, 0xad, 0x78, 0xea, 0x09, 0xdc,
+ 0xdc, 0x2b, 0x56, 0x41, 0xb1, 0x5a, 0x6b, 0xd8,
+ 0x3e, 0xe7, 0xac, 0x01, 0x4b, 0xb8, 0x52, 0x42,
+ },
+ },
+ {
+ .data_len = 128,
+ .key_len = 1024,
+ .mac = {
+ 0xaa, 0x48, 0xa9, 0x1a, 0x47, 0xbf, 0x87, 0xec,
+ 0x9e, 0xe6, 0x0f, 0x98, 0x2a, 0xb0, 0xa7, 0x84,
+ 0x9a, 0x87, 0x5c, 0x75, 0x7e, 0xb5, 0xf1, 0x0a,
+ 0x01, 0x20, 0x75, 0xfd, 0xbf, 0xb8, 0x59, 0xad,
+ 0x1d, 0xa6, 0x59, 0x2c, 0xf2, 0x5e, 0xfd, 0xdc,
+ 0x3c, 0x39, 0x4c, 0xcd, 0x0a, 0x5f, 0xb0, 0x1f,
+ },
+ },
+ {
+ .data_len = 129,
+ .key_len = 0,
+ .mac = {
+ 0x0a, 0xa9, 0x08, 0xdf, 0x29, 0xc4, 0x9e, 0xb3,
+ 0x80, 0x32, 0xab, 0xf5, 0x61, 0xb2, 0xdf, 0x31,
+ 0xc7, 0x7b, 0xb6, 0xb6, 0x30, 0x45, 0x85, 0x6b,
+ 0x76, 0xbc, 0x83, 0xfd, 0x94, 0xe5, 0x91, 0x33,
+ 0x40, 0x01, 0x2d, 0xcf, 0x22, 0x27, 0x35, 0x5e,
+ 0x25, 0xac, 0xfe, 0x14, 0xb4, 0xec, 0x13, 0xa7,
+ },
+ },
+ {
+ .data_len = 256,
+ .key_len = 1,
+ .mac = {
+ 0x0d, 0x94, 0xcc, 0xcd, 0xbd, 0x89, 0xdc, 0xb4,
+ 0xcf, 0x93, 0x02, 0x8c, 0x1d, 0x37, 0xbd, 0x00,
+ 0xa4, 0x9c, 0x24, 0xb2, 0xf7, 0xa5, 0xbf, 0x97,
+ 0x5a, 0x9b, 0x27, 0xc2, 0x28, 0xcf, 0xce, 0x3e,
+ 0x8d, 0xa0, 0x14, 0x03, 0x64, 0xc2, 0x80, 0xec,
+ 0x09, 0xcb, 0x57, 0x81, 0x2f, 0x70, 0x15, 0x1f,
+ },
+ },
+ {
+ .data_len = 511,
+ .key_len = 31,
+ .mac = {
+ 0xb7, 0x4b, 0x98, 0x94, 0x29, 0xfd, 0x21, 0xba,
+ 0x99, 0xc4, 0x36, 0x2b, 0x8d, 0x71, 0xa5, 0x15,
+ 0xd0, 0x2f, 0xc2, 0x4d, 0x15, 0x33, 0xa2, 0x52,
+ 0x58, 0x74, 0xe7, 0x40, 0x5e, 0x75, 0x32, 0x70,
+ 0x64, 0x7d, 0xce, 0x13, 0xf2, 0x01, 0x38, 0x71,
+ 0x0e, 0x8d, 0xea, 0x8b, 0x78, 0x23, 0x65, 0x28,
+ },
+ },
+ {
+ .data_len = 513,
+ .key_len = 32,
+ .mac = {
+ 0xba, 0xc4, 0x7a, 0xf3, 0x62, 0xfc, 0x56, 0x8b,
+ 0x77, 0xde, 0x56, 0x64, 0x51, 0x0d, 0xaa, 0x50,
+ 0x7c, 0x77, 0xbc, 0xd4, 0x44, 0x78, 0x0e, 0xae,
+ 0x8a, 0xa2, 0x52, 0x7b, 0x3b, 0x87, 0x5f, 0x66,
+ 0xf9, 0x28, 0x6a, 0x0a, 0xd6, 0xbf, 0x40, 0xcf,
+ 0xa3, 0xb0, 0x70, 0x60, 0xb1, 0x36, 0x4d, 0x3b,
+ },
+ },
+ {
+ .data_len = 1000,
+ .key_len = 33,
+ .mac = {
+ 0xf7, 0x54, 0x6b, 0x0d, 0x52, 0x46, 0x95, 0x1b,
+ 0xb2, 0xc1, 0xd9, 0x89, 0x8c, 0xdf, 0x56, 0xfc,
+ 0x05, 0xd5, 0x1c, 0x0a, 0x60, 0xef, 0x06, 0xfa,
+ 0x40, 0x18, 0xf7, 0xa3, 0xdb, 0x5e, 0xcb, 0x94,
+ 0xa7, 0x8f, 0x6f, 0x01, 0x8d, 0x40, 0x83, 0x1e,
+ 0x32, 0x22, 0xa5, 0xa6, 0x83, 0xb7, 0x57, 0x9e,
+ },
+ },
+ {
+ .data_len = 3333,
+ .key_len = 64,
+ .mac = {
+ 0x46, 0x1f, 0x32, 0xf7, 0x8e, 0x21, 0x52, 0x70,
+ 0xe6, 0x45, 0xa4, 0xb5, 0x13, 0x92, 0xbe, 0x5e,
+ 0x5b, 0x9e, 0xa8, 0x9a, 0x22, 0x3a, 0x49, 0xbb,
+ 0xc5, 0xab, 0xfb, 0x05, 0xed, 0x13, 0xcb, 0xe2,
+ 0x71, 0xc1, 0x22, 0xca, 0x3b, 0x65, 0x08, 0xb3,
+ 0x9c, 0x1a, 0x03, 0xd0, 0x8e, 0xf8, 0xf0, 0x8b,
+ },
+ },
+ {
+ .data_len = 4096,
+ .key_len = 65,
+ .mac = {
+ 0xb4, 0x0d, 0x90, 0x01, 0x69, 0x2b, 0xc8, 0xab,
+ 0x6b, 0xe9, 0x8c, 0xa5, 0xa9, 0x46, 0xc0, 0x90,
+ 0x84, 0xec, 0x6d, 0x6b, 0x64, 0x88, 0x66, 0x55,
+ 0x61, 0x04, 0x2d, 0xd8, 0x30, 0x9a, 0x2f, 0x3b,
+ 0x3d, 0xa3, 0x11, 0x50, 0xcc, 0x6a, 0xe4, 0xb2,
+ 0x41, 0x18, 0xd7, 0x70, 0x57, 0x01, 0x67, 0x1c,
+ },
+ },
+ {
+ .data_len = 4128,
+ .key_len = 66,
+ .mac = {
+ 0xbd, 0x68, 0x84, 0xea, 0x22, 0xbf, 0xe2, 0x0e,
+ 0x86, 0x61, 0x5e, 0x58, 0x38, 0xfd, 0xce, 0x91,
+ 0x3a, 0x67, 0xda, 0x2b, 0xce, 0x71, 0xaf, 0xbc,
+ 0xf2, 0x75, 0xa5, 0xa8, 0xa2, 0xe2, 0x45, 0x12,
+ 0xab, 0x67, 0x3d, 0x4e, 0x1c, 0x42, 0xe1, 0x5d,
+ 0x6c, 0xb1, 0xd2, 0xb0, 0x16, 0xd5, 0x5c, 0xaf,
+ },
+ },
+ {
+ .data_len = 4160,
+ .key_len = 127,
+ .mac = {
+ 0x91, 0xe1, 0x89, 0x46, 0x28, 0x01, 0xe1, 0xd3,
+ 0x21, 0x12, 0xda, 0x6e, 0xe0, 0x17, 0x14, 0xd0,
+ 0x07, 0x5a, 0x9f, 0xca, 0xad, 0x6a, 0x6b, 0x89,
+ 0xf3, 0x6e, 0x21, 0x92, 0x52, 0x18, 0x21, 0x9d,
+ 0xc6, 0xe6, 0x5d, 0xca, 0xc3, 0x4d, 0xed, 0xe7,
+ 0xb9, 0x51, 0x51, 0x13, 0x12, 0xff, 0x73, 0x91,
+ },
+ },
+ {
+ .data_len = 4224,
+ .key_len = 128,
+ .mac = {
+ 0x15, 0x8f, 0xae, 0x57, 0xa2, 0x69, 0xe0, 0xb7,
+ 0x15, 0xb2, 0xd9, 0x33, 0xfd, 0x62, 0x5d, 0xc9,
+ 0x38, 0xad, 0xc0, 0xbc, 0x9c, 0xd4, 0x8f, 0xed,
+ 0x93, 0x2d, 0x66, 0x6b, 0x57, 0x26, 0xda, 0xdc,
+ 0x4b, 0x14, 0x00, 0x82, 0x0d, 0x1a, 0x27, 0x37,
+ 0xa6, 0x91, 0x61, 0x04, 0x20, 0xc9, 0x6b, 0x61,
+ },
+ },
+ {
+ .data_len = 16384,
+ .key_len = 129,
+ .mac = {
+ 0x65, 0x25, 0x4f, 0xfc, 0x9b, 0x4d, 0xe5, 0xd7,
+ 0x2c, 0xb7, 0xb1, 0x2f, 0xf9, 0xb7, 0x7b, 0x98,
+ 0x80, 0x45, 0x23, 0xdc, 0x0b, 0xd1, 0x76, 0xc1,
+ 0x81, 0xfd, 0x89, 0x08, 0x96, 0x9a, 0x35, 0xbd,
+ 0x0c, 0x7c, 0x0e, 0x26, 0xab, 0xa4, 0x03, 0x55,
+ 0x4d, 0x3a, 0xc0, 0x0a, 0x10, 0x45, 0x1a, 0x46,
+ },
+ },
+};
diff --git a/lib/crypto/tests/sha384_kunit.c b/lib/crypto/tests/sha384_kunit.c
new file mode 100644
index 0000000000000..54c33dd3430d9
--- /dev/null
+++ b/lib/crypto/tests/sha384_kunit.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2025 Google LLC
+ */
+#include <crypto/sha2.h>
+#include "sha384-testvecs.h"
+
+#define HASH sha384
+#define HASH_CTX sha384_ctx
+#define HASH_SIZE SHA384_DIGEST_SIZE
+#define HASH_INIT sha384_init
+#define HASH_UPDATE sha384_update
+#define HASH_FINAL sha384_final
+#define HASH_TESTVECS sha384_testvecs
+#define HMAC_KEY hmac_sha384_key
+#define HMAC_CTX hmac_sha384_ctx
+#define HMAC_SETKEY hmac_sha384_preparekey
+#define HMAC_INIT hmac_sha384_init
+#define HMAC_UPDATE hmac_sha384_update
+#define HMAC_FINAL hmac_sha384_final
+#define HMAC hmac_sha384
+#define HMAC_USINGRAWKEY hmac_sha384_usingrawkey
+#define HMAC_TESTVECS hmac_sha384_testvecs
+#include "hash-test-template.h"
+
+static struct kunit_case hash_test_cases[] = {
+ KUNIT_CASE(test_hash_test_vectors),
+ KUNIT_CASE(test_hash_incremental_updates),
+ KUNIT_CASE(test_hash_buffer_overruns),
+ KUNIT_CASE(test_hash_overlaps),
+ KUNIT_CASE(test_hash_alignment_consistency),
+ KUNIT_CASE(test_hash_interrupt_context),
+ KUNIT_CASE(test_hash_ctx_zeroization),
+ KUNIT_CASE(test_hmac),
+ KUNIT_CASE(benchmark_hash),
+ {},
+};
+
+static struct kunit_suite hash_test_suite = {
+ .name = "sha384",
+ .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-384 and HMAC-SHA384");
+MODULE_LICENSE("GPL");
diff --git a/lib/crypto/tests/sha512-testvecs.h b/lib/crypto/tests/sha512-testvecs.h
new file mode 100644
index 0000000000000..d91e11fd6879e
--- /dev/null
+++ b/lib/crypto/tests/sha512-testvecs.h
@@ -0,0 +1,662 @@
+/* This file was generated by: ./scripts/crypto/gen-hash-testvecs.py sha512 */
+
+static const struct {
+ size_t data_len;
+ u8 digest[SHA512_DIGEST_SIZE];
+} sha512_testvecs[] = {
+ {
+ .data_len = 0,
+ .digest = {
+ 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd,
+ 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07,
+ 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc,
+ 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce,
+ 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
+ 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f,
+ 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81,
+ 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e,
+ },
+ },
+ {
+ .data_len = 1,
+ .digest = {
+ 0x12, 0xf2, 0xb6, 0xec, 0x84, 0xa0, 0x8e, 0xcf,
+ 0x0d, 0xec, 0x17, 0xfd, 0x1f, 0x91, 0x15, 0x69,
+ 0xd2, 0xb9, 0x89, 0xff, 0x89, 0x9d, 0xd9, 0x0b,
+ 0x7a, 0x0f, 0x82, 0x94, 0x57, 0x5b, 0xf3, 0x08,
+ 0x42, 0x45, 0x23, 0x08, 0x44, 0x54, 0x35, 0x36,
+ 0xed, 0x4b, 0xb3, 0xa5, 0xbf, 0x17, 0xc1, 0x3c,
+ 0xdd, 0x25, 0x4a, 0x30, 0x64, 0xed, 0x66, 0x06,
+ 0x72, 0x05, 0xc2, 0x71, 0x5a, 0x6c, 0xd0, 0x75,
+ },
+ },
+ {
+ .data_len = 2,
+ .digest = {
+ 0x01, 0x37, 0x97, 0xcc, 0x0a, 0xcb, 0x61, 0xa4,
+ 0x93, 0x26, 0x36, 0x4b, 0xd2, 0x27, 0xea, 0xaf,
+ 0xda, 0xfa, 0x8f, 0x86, 0x12, 0x99, 0x7b, 0xc8,
+ 0x94, 0xa9, 0x1c, 0x70, 0x3f, 0x43, 0xf3, 0x9a,
+ 0x02, 0xc5, 0x0d, 0x8e, 0x01, 0xf8, 0x3a, 0xa6,
+ 0xec, 0xaa, 0xc5, 0xc7, 0x9d, 0x3d, 0x7f, 0x9d,
+ 0x47, 0x0e, 0x58, 0x2d, 0x9a, 0x2d, 0x51, 0x1d,
+ 0xc3, 0x77, 0xb2, 0x7f, 0x69, 0x9a, 0xc3, 0x50,
+ },
+ },
+ {
+ .data_len = 3,
+ .digest = {
+ 0xd4, 0xa3, 0xc2, 0x50, 0xa0, 0x33, 0xc6, 0xe4,
+ 0x50, 0x08, 0xea, 0xc9, 0xb8, 0x35, 0x55, 0x34,
+ 0x61, 0xb8, 0x2e, 0xa2, 0xe5, 0xdc, 0x04, 0x70,
+ 0x99, 0x86, 0x5f, 0xee, 0x2e, 0x1e, 0xd4, 0x40,
+ 0xf8, 0x88, 0x01, 0x84, 0x97, 0x16, 0x6a, 0xd3,
+ 0x0a, 0xb4, 0xe2, 0x34, 0xca, 0x1f, 0xfc, 0x6b,
+ 0x61, 0xf3, 0x7f, 0x72, 0xfa, 0x8d, 0x22, 0xcf,
+ 0x7f, 0x2d, 0x87, 0x9d, 0xbb, 0x59, 0xac, 0x53,
+ },
+ },
+ {
+ .data_len = 16,
+ .digest = {
+ 0x3b, 0xae, 0x66, 0x48, 0x0f, 0x35, 0x3c, 0xcd,
+ 0x92, 0xa9, 0xb6, 0xb9, 0xfe, 0x19, 0x90, 0x92,
+ 0x52, 0xa5, 0x02, 0xd1, 0x89, 0xcf, 0x98, 0x86,
+ 0x29, 0x28, 0xab, 0xc4, 0x9e, 0xcc, 0x75, 0x38,
+ 0x95, 0xa7, 0x59, 0x43, 0xef, 0x8c, 0x3a, 0xeb,
+ 0x40, 0xa3, 0xbe, 0x2b, 0x75, 0x0d, 0xfd, 0xc3,
+ 0xaf, 0x69, 0x08, 0xad, 0x9f, 0xc9, 0xf4, 0x96,
+ 0xa9, 0xc2, 0x2b, 0x1b, 0x66, 0x6f, 0x1d, 0x28,
+ },
+ },
+ {
+ .data_len = 32,
+ .digest = {
+ 0x9c, 0xfb, 0x3c, 0x40, 0xd5, 0x3b, 0xc4, 0xff,
+ 0x07, 0xa7, 0xf0, 0x24, 0xb7, 0xd6, 0x5e, 0x12,
+ 0x5b, 0x85, 0xb5, 0xa5, 0xe0, 0x82, 0xa6, 0xda,
+ 0x30, 0x13, 0x2f, 0x1a, 0xe3, 0xd0, 0x55, 0xcb,
+ 0x14, 0x19, 0xe2, 0x09, 0x91, 0x96, 0x26, 0xf9,
+ 0x38, 0xd7, 0xfa, 0x4a, 0xfb, 0x2f, 0x6f, 0xc0,
+ 0xf4, 0x95, 0xc3, 0x40, 0xf6, 0xdb, 0xe7, 0xc2,
+ 0x79, 0x23, 0xa4, 0x20, 0x96, 0x3a, 0x00, 0xbb,
+ },
+ },
+ {
+ .data_len = 48,
+ .digest = {
+ 0x92, 0x1a, 0x21, 0x06, 0x6e, 0x08, 0x84, 0x09,
+ 0x23, 0x8d, 0x63, 0xec, 0xd6, 0x72, 0xd3, 0x21,
+ 0x51, 0xe8, 0x65, 0x94, 0xf8, 0x1f, 0x5f, 0xa7,
+ 0xab, 0x6b, 0xae, 0x1c, 0x2c, 0xaf, 0xf9, 0x0c,
+ 0x7c, 0x5a, 0x74, 0x1d, 0x90, 0x26, 0x4a, 0xc3,
+ 0xa1, 0x60, 0xf4, 0x1d, 0xd5, 0x3c, 0x86, 0xe8,
+ 0x00, 0xb3, 0x99, 0x27, 0xb8, 0x9d, 0x3e, 0x17,
+ 0x32, 0x5a, 0x34, 0x3e, 0xc2, 0xb2, 0x6e, 0xbd,
+ },
+ },
+ {
+ .data_len = 49,
+ .digest = {
+ 0x5a, 0x1f, 0x40, 0x5f, 0xee, 0xf2, 0xdd, 0x67,
+ 0x01, 0xcb, 0x26, 0x58, 0xf5, 0x1b, 0xe8, 0x7e,
+ 0xeb, 0x7d, 0x9d, 0xef, 0xd3, 0x55, 0xd6, 0x89,
+ 0x2e, 0xfc, 0x14, 0xe2, 0x98, 0x4c, 0x31, 0xaa,
+ 0x69, 0x00, 0xf9, 0x4e, 0xb0, 0x75, 0x1b, 0x71,
+ 0x93, 0x60, 0xdf, 0xa1, 0xaf, 0xba, 0xc2, 0xd3,
+ 0x6a, 0x22, 0xa0, 0xff, 0xb5, 0x66, 0x15, 0x66,
+ 0xd2, 0x24, 0x9a, 0x7e, 0xe4, 0xe5, 0x84, 0xdb,
+ },
+ },
+ {
+ .data_len = 63,
+ .digest = {
+ 0x32, 0xbd, 0xcf, 0x72, 0xa9, 0x74, 0x87, 0xe6,
+ 0x2a, 0x53, 0x7e, 0x6d, 0xac, 0xc2, 0xdd, 0x2c,
+ 0x87, 0xb3, 0xf7, 0x90, 0x29, 0xc9, 0x16, 0x59,
+ 0xd2, 0x7e, 0x6e, 0x84, 0x1d, 0xa6, 0xaf, 0x3c,
+ 0xca, 0xd6, 0x1a, 0x24, 0xa4, 0xcd, 0x59, 0x44,
+ 0x20, 0xd7, 0xd2, 0x5b, 0x97, 0xda, 0xd5, 0xa9,
+ 0x23, 0xb1, 0xa4, 0x60, 0xb8, 0x05, 0x98, 0xdc,
+ 0xef, 0x89, 0x81, 0xe3, 0x3a, 0xf9, 0x24, 0x37,
+ },
+ },
+ {
+ .data_len = 64,
+ .digest = {
+ 0x96, 0x3a, 0x1a, 0xdd, 0x1b, 0xeb, 0x1a, 0x55,
+ 0x24, 0x52, 0x3d, 0xec, 0x9d, 0x52, 0x2e, 0xa6,
+ 0xfe, 0x81, 0xd6, 0x98, 0xac, 0xcc, 0x60, 0x56,
+ 0x04, 0x9d, 0xa3, 0xf3, 0x56, 0x05, 0xe4, 0x8a,
+ 0x61, 0xaf, 0x6f, 0x6e, 0x8e, 0x75, 0x67, 0x3a,
+ 0xd2, 0xb0, 0x85, 0x2d, 0x17, 0xd2, 0x86, 0x8c,
+ 0x50, 0x4b, 0xdd, 0xef, 0x35, 0x00, 0xde, 0x29,
+ 0x3d, 0x4b, 0x04, 0x12, 0x8a, 0x81, 0xe2, 0xcc,
+ },
+ },
+ {
+ .data_len = 65,
+ .digest = {
+ 0x9c, 0x6e, 0xf0, 0x6f, 0x71, 0x77, 0xd5, 0xd0,
+ 0xbb, 0x70, 0x1f, 0xcb, 0xbd, 0xd3, 0xfe, 0x23,
+ 0x71, 0x78, 0xad, 0x3a, 0xd2, 0x1e, 0x34, 0xf4,
+ 0x6d, 0xb4, 0xa2, 0x0a, 0x24, 0xcb, 0xe1, 0x99,
+ 0x07, 0xd0, 0x79, 0x8f, 0x7e, 0x69, 0x31, 0x68,
+ 0x29, 0xb5, 0x85, 0x82, 0x67, 0xdc, 0x4a, 0x8d,
+ 0x44, 0x04, 0x02, 0xc0, 0xfb, 0xd2, 0x19, 0x66,
+ 0x1e, 0x25, 0x8b, 0xd2, 0x5a, 0x59, 0x68, 0xc0,
+ },
+ },
+ {
+ .data_len = 127,
+ .digest = {
+ 0xb8, 0x8f, 0xa8, 0x29, 0x4d, 0xcf, 0x5f, 0x73,
+ 0x3c, 0x55, 0x43, 0xd9, 0x1c, 0xbc, 0x0c, 0x17,
+ 0x75, 0x0b, 0xc7, 0xb1, 0x1d, 0x9f, 0x7b, 0x2f,
+ 0x4c, 0x3d, 0x2a, 0x71, 0xfb, 0x1b, 0x0e, 0xca,
+ 0x4e, 0x96, 0xa0, 0x95, 0xee, 0xf4, 0x93, 0x76,
+ 0x36, 0xfb, 0x5d, 0xd3, 0x46, 0xc4, 0x1d, 0x41,
+ 0x32, 0x92, 0x9d, 0xed, 0xdb, 0x7f, 0xfa, 0xb3,
+ 0x91, 0x61, 0x3e, 0xd6, 0xb2, 0xca, 0x8d, 0x81,
+ },
+ },
+ {
+ .data_len = 128,
+ .digest = {
+ 0x54, 0xac, 0x1a, 0xa1, 0xa6, 0xa3, 0x47, 0x2a,
+ 0x5a, 0xac, 0x1a, 0x3a, 0x4b, 0xa1, 0x11, 0x08,
+ 0xa7, 0x90, 0xec, 0x52, 0xcb, 0xaf, 0x68, 0x41,
+ 0x38, 0x44, 0x53, 0x94, 0x93, 0x30, 0xaf, 0x3a,
+ 0xec, 0x99, 0x3a, 0x7d, 0x2a, 0xd5, 0xb6, 0x05,
+ 0xf5, 0xa6, 0xbb, 0x9b, 0x82, 0xc2, 0xbd, 0x98,
+ 0x28, 0x62, 0x98, 0x3e, 0xe4, 0x27, 0x9b, 0xaa,
+ 0xce, 0x0a, 0x6f, 0xab, 0x1b, 0x16, 0xf3, 0xdd,
+ },
+ },
+ {
+ .data_len = 129,
+ .digest = {
+ 0x04, 0x37, 0x60, 0xbc, 0xb3, 0xb1, 0xc6, 0x2d,
+ 0x42, 0xc5, 0xd7, 0x7e, 0xd9, 0x86, 0x82, 0xe0,
+ 0xf4, 0x62, 0xad, 0x75, 0x68, 0x0b, 0xc7, 0xa8,
+ 0xd6, 0x9a, 0x76, 0xe5, 0x29, 0xb8, 0x37, 0x30,
+ 0x0f, 0xc0, 0xbc, 0x81, 0x94, 0x7c, 0x13, 0xf4,
+ 0x9c, 0x27, 0xbc, 0x59, 0xa1, 0x70, 0x6a, 0x87,
+ 0x20, 0x12, 0x0a, 0x2a, 0x62, 0x5e, 0x6f, 0xca,
+ 0x91, 0x6b, 0x34, 0x7e, 0x4c, 0x0d, 0xf0, 0x6c,
+ },
+ },
+ {
+ .data_len = 256,
+ .digest = {
+ 0x4b, 0x7c, 0x1f, 0x53, 0x52, 0xcc, 0x30, 0xed,
+ 0x91, 0x44, 0x6f, 0x0d, 0xb5, 0x41, 0x79, 0x99,
+ 0xaf, 0x82, 0x65, 0x52, 0x03, 0xf8, 0x55, 0x74,
+ 0x7c, 0xd9, 0x41, 0xd6, 0xe8, 0x91, 0xa4, 0x85,
+ 0xcb, 0x0a, 0x60, 0x08, 0x76, 0x07, 0x60, 0x99,
+ 0x89, 0x76, 0xba, 0x84, 0xbd, 0x0b, 0xf2, 0xb3,
+ 0xdc, 0xf3, 0x33, 0xd1, 0x9b, 0x0b, 0x2e, 0x5d,
+ 0xf6, 0x9d, 0x0f, 0x67, 0xf4, 0x86, 0xb3, 0xd5,
+ },
+ },
+ {
+ .data_len = 511,
+ .digest = {
+ 0x7d, 0x83, 0x78, 0x6a, 0x5d, 0x52, 0x42, 0x2a,
+ 0xb1, 0x97, 0xc6, 0x62, 0xa2, 0x2a, 0x7c, 0x8b,
+ 0xcd, 0x4f, 0xa4, 0x86, 0x19, 0xa4, 0x5b, 0x1d,
+ 0xc7, 0x6f, 0x2f, 0x9c, 0x03, 0xc3, 0x45, 0x2e,
+ 0xa7, 0x8e, 0x38, 0xf2, 0x57, 0x55, 0x89, 0x47,
+ 0xed, 0xeb, 0x81, 0xe2, 0xe0, 0x55, 0x9f, 0xe6,
+ 0xca, 0x03, 0x59, 0xd3, 0xd4, 0xba, 0xc9, 0x2d,
+ 0xaf, 0xbb, 0x62, 0x2e, 0xe6, 0x89, 0xe4, 0x11,
+ },
+ },
+ {
+ .data_len = 513,
+ .digest = {
+ 0xe9, 0x14, 0xe7, 0x01, 0xd0, 0x81, 0x09, 0x51,
+ 0x78, 0x1c, 0x8e, 0x6c, 0x00, 0xd3, 0x28, 0xa0,
+ 0x2a, 0x7b, 0xd6, 0x25, 0xca, 0xd0, 0xf9, 0xb8,
+ 0xd8, 0xcf, 0xd0, 0xb7, 0x48, 0x25, 0xb7, 0x6a,
+ 0x53, 0x8e, 0xf8, 0x52, 0x9c, 0x1f, 0x7d, 0xae,
+ 0x4c, 0x22, 0xd5, 0x9d, 0xf0, 0xaf, 0x98, 0x91,
+ 0x19, 0x1f, 0x99, 0xbd, 0xa6, 0xc2, 0x0f, 0x05,
+ 0xa5, 0x9f, 0x3e, 0x87, 0xed, 0xc3, 0xab, 0x92,
+ },
+ },
+ {
+ .data_len = 1000,
+ .digest = {
+ 0x2e, 0xf4, 0x72, 0xd2, 0xd9, 0x4a, 0xd5, 0xf9,
+ 0x20, 0x03, 0x4a, 0xad, 0xed, 0xa9, 0x1b, 0x64,
+ 0x73, 0x38, 0xc6, 0x30, 0xa8, 0x7f, 0xf9, 0x3b,
+ 0x8c, 0xbc, 0xa1, 0x2d, 0x22, 0x7b, 0x84, 0x37,
+ 0xf5, 0xba, 0xee, 0xf0, 0x80, 0x9d, 0xe3, 0x82,
+ 0xbd, 0x07, 0x68, 0x15, 0x01, 0x22, 0xf6, 0x88,
+ 0x07, 0x0b, 0xfd, 0xb7, 0xb1, 0xc0, 0x68, 0x4b,
+ 0x8d, 0x05, 0xec, 0xfb, 0xcd, 0xde, 0xa4, 0x2a,
+ },
+ },
+ {
+ .data_len = 3333,
+ .digest = {
+ 0x73, 0xe3, 0xe5, 0x87, 0x01, 0x0a, 0x29, 0x4d,
+ 0xad, 0x92, 0x67, 0x64, 0xc7, 0x71, 0x0b, 0x22,
+ 0x80, 0x8a, 0x6e, 0x8b, 0x20, 0x73, 0xb2, 0xd7,
+ 0x98, 0x20, 0x35, 0x42, 0x42, 0x5d, 0x85, 0x12,
+ 0xb0, 0x06, 0x69, 0x63, 0x5f, 0x5b, 0xe7, 0x63,
+ 0x6f, 0xe6, 0x18, 0xa6, 0xc1, 0xa6, 0xae, 0x27,
+ 0xa7, 0x6a, 0x73, 0x6b, 0x27, 0xd5, 0x47, 0xe1,
+ 0xa2, 0x7d, 0xe4, 0x0d, 0xbd, 0x23, 0x7b, 0x7a,
+ },
+ },
+ {
+ .data_len = 4096,
+ .digest = {
+ 0x11, 0x5b, 0x77, 0x36, 0x6b, 0x3b, 0xe4, 0x42,
+ 0xe4, 0x92, 0x23, 0xcb, 0x0c, 0x06, 0xff, 0xb7,
+ 0x0c, 0x71, 0x64, 0xd9, 0x8a, 0x57, 0x75, 0x7b,
+ 0xa2, 0xd2, 0x17, 0x19, 0xbb, 0xb5, 0x3c, 0xb3,
+ 0x5f, 0xae, 0x35, 0x75, 0x8e, 0xa8, 0x97, 0x43,
+ 0xce, 0xfe, 0x41, 0x84, 0xfe, 0xcb, 0x18, 0x70,
+ 0x68, 0x2e, 0x16, 0x19, 0xd5, 0x10, 0x0d, 0x2f,
+ 0x61, 0x87, 0x79, 0xee, 0x5f, 0x24, 0xdd, 0x76,
+ },
+ },
+ {
+ .data_len = 4128,
+ .digest = {
+ 0x9e, 0x96, 0xe1, 0x0a, 0xb2, 0xd5, 0xba, 0xcf,
+ 0x27, 0xba, 0x6f, 0x85, 0xe9, 0xbf, 0x96, 0xb9,
+ 0x5a, 0x00, 0x00, 0x06, 0xdc, 0xb7, 0xaf, 0x0a,
+ 0x8f, 0x1d, 0x31, 0xf6, 0xce, 0xc3, 0x50, 0x2e,
+ 0x61, 0x3a, 0x8b, 0x28, 0xaf, 0xb2, 0x50, 0x0d,
+ 0x00, 0x98, 0x02, 0x11, 0x6b, 0xfa, 0x51, 0xc1,
+ 0xde, 0xe1, 0x34, 0x9f, 0xda, 0x11, 0x63, 0xfa,
+ 0x0a, 0xa0, 0xa2, 0x67, 0x39, 0xeb, 0x9b, 0xf1,
+ },
+ },
+ {
+ .data_len = 4160,
+ .digest = {
+ 0x46, 0x4e, 0x81, 0xd1, 0x08, 0x2a, 0x46, 0x12,
+ 0x4e, 0xae, 0x1f, 0x5d, 0x57, 0xe5, 0x19, 0xbc,
+ 0x76, 0x38, 0xb6, 0xa7, 0xe3, 0x72, 0x6d, 0xaf,
+ 0x80, 0x3b, 0xd0, 0xbc, 0x06, 0xe8, 0xab, 0xab,
+ 0x86, 0x4b, 0x0b, 0x7a, 0x61, 0xa6, 0x13, 0xff,
+ 0x64, 0x47, 0x89, 0xb7, 0x63, 0x8a, 0xa5, 0x4c,
+ 0x9f, 0x52, 0x70, 0xeb, 0x21, 0xe5, 0x2d, 0xe9,
+ 0xe7, 0xab, 0x1c, 0x0e, 0x74, 0xf5, 0x72, 0xec,
+ },
+ },
+ {
+ .data_len = 4224,
+ .digest = {
+ 0xfa, 0x6e, 0xff, 0x3c, 0xc1, 0x98, 0x49, 0x42,
+ 0x34, 0x67, 0xd4, 0xd3, 0xfa, 0xae, 0x27, 0xe4,
+ 0x77, 0x11, 0x84, 0xd2, 0x57, 0x99, 0xf8, 0xfd,
+ 0x41, 0x50, 0x84, 0x80, 0x7f, 0xf7, 0xb2, 0xd3,
+ 0x88, 0x21, 0x9c, 0xe8, 0xb9, 0x05, 0xd3, 0x48,
+ 0x64, 0xc5, 0xb7, 0x29, 0xd9, 0x21, 0x17, 0xad,
+ 0x89, 0x9c, 0x79, 0x55, 0x51, 0x0b, 0x96, 0x3e,
+ 0x10, 0x40, 0xe1, 0xdd, 0x7b, 0x39, 0x40, 0x86,
+ },
+ },
+ {
+ .data_len = 16384,
+ .digest = {
+ 0x41, 0xb3, 0xd2, 0x93, 0xcd, 0x79, 0x84, 0xc2,
+ 0xf5, 0xea, 0xf3, 0xb3, 0x94, 0x23, 0xaa, 0x76,
+ 0x87, 0x5f, 0xe3, 0xd2, 0x03, 0xd8, 0x00, 0xbb,
+ 0xa1, 0x55, 0xe4, 0xcb, 0x16, 0x04, 0x5b, 0xdf,
+ 0xf8, 0xd2, 0x63, 0x51, 0x02, 0x22, 0xc6, 0x0f,
+ 0x98, 0x2b, 0x12, 0x52, 0x25, 0x64, 0x93, 0xd9,
+ 0xab, 0xe9, 0x4d, 0x16, 0x4b, 0xf6, 0x09, 0x83,
+ 0x5c, 0x63, 0x1c, 0x41, 0x19, 0xf6, 0x76, 0xe3,
+ },
+ },
+};
+
+static const struct {
+ size_t data_len;
+ size_t key_len;
+ u8 mac[SHA512_DIGEST_SIZE];
+} hmac_sha512_testvecs[] = {
+ {
+ .data_len = 0,
+ .key_len = 0,
+ .mac = {
+ 0xb9, 0x36, 0xce, 0xe8, 0x6c, 0x9f, 0x87, 0xaa,
+ 0x5d, 0x3c, 0x6f, 0x2e, 0x84, 0xcb, 0x5a, 0x42,
+ 0x39, 0xa5, 0xfe, 0x50, 0x48, 0x0a, 0x6e, 0xc6,
+ 0x6b, 0x70, 0xab, 0x5b, 0x1f, 0x4a, 0xc6, 0x73,
+ 0x0c, 0x6c, 0x51, 0x54, 0x21, 0xb3, 0x27, 0xec,
+ 0x1d, 0x69, 0x40, 0x2e, 0x53, 0xdf, 0xb4, 0x9a,
+ 0xd7, 0x38, 0x1e, 0xb0, 0x67, 0xb3, 0x38, 0xfd,
+ 0x7b, 0x0c, 0xb2, 0x22, 0x47, 0x22, 0x5d, 0x47,
+ },
+ },
+ {
+ .data_len = 1,
+ .key_len = 1,
+ .mac = {
+ 0x1b, 0xee, 0x4e, 0x7f, 0x67, 0xb3, 0x40, 0x78,
+ 0xd6, 0x68, 0x16, 0xf9, 0x84, 0xf1, 0xcf, 0x0e,
+ 0xca, 0x51, 0x26, 0xb4, 0x50, 0x6d, 0xa9, 0xe4,
+ 0x78, 0x1b, 0xac, 0x7c, 0xe2, 0xe1, 0x5b, 0x75,
+ 0x85, 0xb8, 0xe3, 0xfa, 0x9a, 0x8d, 0x30, 0x46,
+ 0x78, 0x0c, 0x86, 0xc6, 0x72, 0x2b, 0xb9, 0xac,
+ 0xda, 0xe4, 0x37, 0x00, 0x8f, 0xad, 0x69, 0xf7,
+ 0xb7, 0x3a, 0x25, 0xcb, 0x3a, 0x24, 0xe3, 0x8e,
+ },
+ },
+ {
+ .data_len = 2,
+ .key_len = 31,
+ .mac = {
+ 0x39, 0xb9, 0xad, 0xca, 0xe2, 0xf1, 0x2f, 0x29,
+ 0x4c, 0x52, 0x55, 0x7f, 0x0c, 0xe0, 0x6f, 0x90,
+ 0x10, 0x4e, 0xe1, 0x2b, 0x08, 0x9c, 0x13, 0x9a,
+ 0x09, 0xb2, 0x0f, 0x26, 0x26, 0xa9, 0x41, 0x54,
+ 0x06, 0xa0, 0x8f, 0x81, 0xba, 0x22, 0xae, 0x01,
+ 0xf8, 0x3b, 0x50, 0x46, 0x46, 0xf6, 0x8a, 0xc4,
+ 0x17, 0x84, 0xf4, 0x8c, 0x4e, 0x40, 0xa2, 0x26,
+ 0x3e, 0x5b, 0x81, 0x42, 0xef, 0xee, 0xb9, 0xdb,
+ },
+ },
+ {
+ .data_len = 3,
+ .key_len = 32,
+ .mac = {
+ 0x90, 0x82, 0xb5, 0x56, 0xb1, 0x0b, 0x23, 0x38,
+ 0xb4, 0x26, 0x99, 0x7a, 0x4e, 0x3e, 0x3a, 0x0b,
+ 0x36, 0x0a, 0x03, 0xc9, 0x79, 0xba, 0x37, 0x8f,
+ 0xab, 0x42, 0x6f, 0x51, 0x5f, 0x8e, 0x75, 0x0d,
+ 0x7e, 0xd5, 0x2b, 0xa7, 0x0b, 0x53, 0xe7, 0xab,
+ 0x95, 0x8a, 0x01, 0x80, 0x8a, 0x55, 0x28, 0x30,
+ 0x2f, 0x4f, 0xef, 0x7e, 0x60, 0xe2, 0xe5, 0xf2,
+ 0x52, 0xc7, 0xae, 0xf2, 0xe4, 0x96, 0x16, 0xf2,
+ },
+ },
+ {
+ .data_len = 16,
+ .key_len = 33,
+ .mac = {
+ 0x51, 0x34, 0xa4, 0xe8, 0x53, 0xab, 0xf3, 0xa4,
+ 0x78, 0x78, 0xff, 0xbe, 0xaa, 0x8f, 0xf0, 0xad,
+ 0xb9, 0x6d, 0x87, 0x7d, 0x43, 0x76, 0x60, 0x71,
+ 0x10, 0xbc, 0x7b, 0x99, 0x48, 0xc8, 0xf4, 0x78,
+ 0xe5, 0xd0, 0x28, 0x06, 0x75, 0x60, 0xa0, 0xbd,
+ 0xd5, 0xdc, 0xb6, 0x74, 0x7f, 0x2e, 0x4b, 0xd8,
+ 0xc9, 0x58, 0x64, 0xe2, 0x40, 0xf0, 0xe8, 0xaf,
+ 0x2e, 0x4b, 0x2f, 0xe8, 0xa6, 0x29, 0xc4, 0xcf,
+ },
+ },
+ {
+ .data_len = 32,
+ .key_len = 64,
+ .mac = {
+ 0x08, 0x7e, 0xc1, 0x64, 0xe4, 0xa7, 0xe2, 0xb7,
+ 0x32, 0x86, 0xd8, 0x68, 0x96, 0x20, 0x6c, 0x88,
+ 0x62, 0x8f, 0xe4, 0x93, 0xd4, 0x18, 0x11, 0xce,
+ 0x2d, 0x58, 0xaa, 0x3b, 0xa0, 0xd7, 0x19, 0x67,
+ 0xb4, 0x5d, 0x43, 0x0d, 0x98, 0x09, 0x75, 0x73,
+ 0xbf, 0xb3, 0xa4, 0x68, 0x84, 0x47, 0x14, 0x65,
+ 0x11, 0xa8, 0xc6, 0x65, 0x19, 0x53, 0x31, 0x96,
+ 0x4e, 0x51, 0x42, 0x50, 0x76, 0x3a, 0xa3, 0x03,
+ },
+ },
+ {
+ .data_len = 48,
+ .key_len = 65,
+ .mac = {
+ 0x29, 0xd3, 0x6d, 0x5f, 0x4f, 0x3e, 0x99, 0xa7,
+ 0x70, 0x9e, 0xe8, 0xfb, 0x26, 0xbd, 0xcb, 0xff,
+ 0x45, 0xa2, 0x77, 0x4a, 0x5d, 0xaa, 0xd0, 0xa6,
+ 0xc5, 0xaf, 0xca, 0xda, 0xbc, 0x93, 0x5f, 0xd2,
+ 0x5d, 0x9d, 0x71, 0xb1, 0x5f, 0x92, 0x66, 0xc0,
+ 0xe8, 0x62, 0x69, 0x86, 0x1d, 0xb4, 0xcd, 0x53,
+ 0x3e, 0xf4, 0x51, 0xbc, 0x32, 0x65, 0x06, 0x6c,
+ 0x71, 0x2a, 0x12, 0xcc, 0x04, 0x10, 0x44, 0x1d,
+ },
+ },
+ {
+ .data_len = 49,
+ .key_len = 66,
+ .mac = {
+ 0x2f, 0xb9, 0x24, 0x49, 0x5c, 0x68, 0x92, 0x3e,
+ 0xfd, 0x3a, 0x47, 0x96, 0xb0, 0x76, 0xab, 0x3e,
+ 0x19, 0xb4, 0x64, 0xcf, 0x3a, 0x83, 0x18, 0xf7,
+ 0xb4, 0xa1, 0xb7, 0xcb, 0xd4, 0xea, 0x4b, 0x33,
+ 0x68, 0x5f, 0x7a, 0x29, 0xa8, 0x08, 0x3d, 0x64,
+ 0x09, 0x7a, 0x8e, 0xe1, 0x6f, 0xbb, 0x22, 0xba,
+ 0xd9, 0xec, 0xd8, 0x46, 0xd2, 0x8e, 0xd8, 0xf6,
+ 0xf8, 0x39, 0x55, 0x36, 0xe4, 0x8d, 0x7a, 0xb6,
+ },
+ },
+ {
+ .data_len = 63,
+ .key_len = 127,
+ .mac = {
+ 0xf7, 0x10, 0xdc, 0xc9, 0x08, 0xca, 0x65, 0x98,
+ 0xb5, 0xa5, 0x04, 0x1b, 0xce, 0x0f, 0xe6, 0x13,
+ 0x55, 0x93, 0x3b, 0x73, 0xc9, 0x83, 0xb2, 0x99,
+ 0x0a, 0xd6, 0xbb, 0x75, 0x92, 0x46, 0x96, 0xa0,
+ 0x28, 0x8f, 0xf0, 0xb0, 0x0c, 0x43, 0xcc, 0x45,
+ 0x77, 0xc9, 0xda, 0x0a, 0x63, 0x45, 0x4e, 0xc0,
+ 0x59, 0x53, 0xba, 0xbe, 0xbc, 0x56, 0x6c, 0xee,
+ 0x7a, 0x1e, 0x54, 0xd1, 0x6b, 0xc0, 0xe8, 0x58,
+ },
+ },
+ {
+ .data_len = 64,
+ .key_len = 128,
+ .mac = {
+ 0x3b, 0x7d, 0x49, 0x7b, 0x8e, 0x67, 0x2f, 0xe1,
+ 0x71, 0xd9, 0x3f, 0xbd, 0x61, 0xd1, 0x51, 0x4b,
+ 0xd7, 0xa8, 0x6d, 0x27, 0x94, 0x9c, 0x55, 0x87,
+ 0x51, 0xaa, 0xce, 0xbc, 0x0e, 0x13, 0x38, 0x85,
+ 0x80, 0x20, 0x9a, 0x86, 0x7c, 0x6f, 0x6d, 0x40,
+ 0xf9, 0xff, 0xde, 0x17, 0x38, 0x40, 0xe3, 0xc3,
+ 0xf2, 0x58, 0xd4, 0xf8, 0x0d, 0x2f, 0x8c, 0x1e,
+ 0xcd, 0x27, 0xac, 0x87, 0xd9, 0x47, 0x25, 0x52,
+ },
+ },
+ {
+ .data_len = 65,
+ .key_len = 129,
+ .mac = {
+ 0x74, 0xac, 0x10, 0x6b, 0x4d, 0x68, 0xbb, 0x6c,
+ 0xc8, 0x14, 0x23, 0xd9, 0xfa, 0xd1, 0xbe, 0x40,
+ 0xac, 0x85, 0x8c, 0xcd, 0x75, 0xbf, 0x4e, 0x51,
+ 0xe7, 0x72, 0x6e, 0x64, 0xb1, 0x36, 0x97, 0xee,
+ 0xc3, 0x1c, 0xdc, 0x8a, 0x07, 0x79, 0xc6, 0xac,
+ 0x4d, 0x2b, 0x53, 0xca, 0x91, 0xac, 0xa4, 0x85,
+ 0x7f, 0x08, 0x6c, 0x2c, 0x7a, 0xa8, 0x5c, 0xb3,
+ 0x28, 0x5f, 0x3c, 0xf1, 0x26, 0x6a, 0x2a, 0xaf,
+ },
+ },
+ {
+ .data_len = 127,
+ .key_len = 1000,
+ .mac = {
+ 0x68, 0xb9, 0x3b, 0x1c, 0x35, 0x75, 0x84, 0xe7,
+ 0x00, 0xcb, 0x23, 0xa6, 0x40, 0xb2, 0x4b, 0x2c,
+ 0x39, 0x63, 0x61, 0xf1, 0x71, 0x57, 0xd4, 0xd8,
+ 0xa3, 0xdd, 0xcb, 0xca, 0x7e, 0x7d, 0x14, 0xf7,
+ 0x85, 0xbe, 0xc6, 0xce, 0x51, 0x55, 0x60, 0xe0,
+ 0x84, 0x3e, 0xda, 0xec, 0x39, 0x19, 0x82, 0xc1,
+ 0x3e, 0xac, 0x0c, 0x5c, 0x9a, 0x40, 0x5e, 0xa2,
+ 0xfa, 0x4e, 0xe2, 0x65, 0xc3, 0x17, 0x7d, 0x60,
+ },
+ },
+ {
+ .data_len = 128,
+ .key_len = 1024,
+ .mac = {
+ 0x76, 0xe0, 0x17, 0x27, 0x0a, 0xed, 0xfa, 0xfb,
+ 0x51, 0xc7, 0x52, 0x19, 0xbe, 0xbe, 0xe3, 0x1a,
+ 0x28, 0xc0, 0x28, 0xe0, 0x0c, 0x94, 0xb6, 0x3a,
+ 0x50, 0x06, 0x78, 0x5f, 0x04, 0x2a, 0x98, 0x19,
+ 0x96, 0xb6, 0x98, 0xc7, 0x26, 0x50, 0x60, 0xd0,
+ 0x52, 0x3f, 0x48, 0xc0, 0x06, 0x2d, 0xf4, 0xcc,
+ 0xe9, 0x62, 0x5e, 0x12, 0xff, 0x4e, 0x8f, 0x41,
+ 0x48, 0xe6, 0x92, 0xac, 0x84, 0x82, 0x12, 0x92,
+ },
+ },
+ {
+ .data_len = 129,
+ .key_len = 0,
+ .mac = {
+ 0x9e, 0xe3, 0x94, 0xcb, 0x6d, 0x88, 0x3a, 0x47,
+ 0xc4, 0xdd, 0xdb, 0xf0, 0x38, 0x01, 0x22, 0x4c,
+ 0xcc, 0x5f, 0x2f, 0x73, 0xf6, 0x0d, 0xa9, 0xf2,
+ 0x29, 0xbe, 0xc9, 0x37, 0xeb, 0x5c, 0xb0, 0x90,
+ 0x86, 0x0a, 0x86, 0x48, 0xff, 0xf7, 0xd7, 0xd8,
+ 0x4d, 0x6e, 0xbf, 0x72, 0xa6, 0x67, 0xee, 0xf7,
+ 0x9d, 0x29, 0x96, 0x02, 0x4e, 0x17, 0x8a, 0x32,
+ 0x1e, 0x59, 0xeb, 0xfb, 0xd6, 0xd7, 0xaa, 0x7d,
+ },
+ },
+ {
+ .data_len = 256,
+ .key_len = 1,
+ .mac = {
+ 0x07, 0x2e, 0xcc, 0x0e, 0xd3, 0xd4, 0xf2, 0xbc,
+ 0xb1, 0xd1, 0x57, 0x66, 0x06, 0xce, 0x64, 0xd4,
+ 0x0a, 0x62, 0xd4, 0x84, 0x5c, 0x88, 0x27, 0xa1,
+ 0x5c, 0x0d, 0xb5, 0x1e, 0xf4, 0x3e, 0x79, 0x6a,
+ 0x6e, 0x50, 0x8f, 0x39, 0xe6, 0x8b, 0xed, 0x9b,
+ 0x0d, 0xe4, 0x32, 0xd6, 0x72, 0xfd, 0x17, 0x33,
+ 0x92, 0xb6, 0x88, 0xfd, 0xe0, 0xfb, 0x85, 0x39,
+ 0x27, 0xc7, 0x96, 0xad, 0x8a, 0x68, 0xf7, 0xde,
+ },
+ },
+ {
+ .data_len = 511,
+ .key_len = 31,
+ .mac = {
+ 0xc2, 0xef, 0x28, 0xbd, 0xf6, 0x30, 0x74, 0xed,
+ 0xfd, 0x2e, 0x52, 0x30, 0xf3, 0xcb, 0x42, 0x75,
+ 0x58, 0x35, 0x2c, 0xad, 0x2a, 0x5b, 0x73, 0xa3,
+ 0xe0, 0x18, 0x0b, 0x96, 0x7e, 0x07, 0xce, 0x1e,
+ 0xf1, 0xe3, 0x08, 0x31, 0x6f, 0x18, 0x79, 0xa0,
+ 0x5e, 0xbc, 0xad, 0x15, 0xce, 0x32, 0xef, 0x78,
+ 0x1c, 0x3e, 0x83, 0xb6, 0xa0, 0x41, 0xf0, 0x26,
+ 0xdd, 0xe2, 0x7d, 0xec, 0x99, 0x4a, 0x73, 0xe2,
+ },
+ },
+ {
+ .data_len = 513,
+ .key_len = 32,
+ .mac = {
+ 0x11, 0x35, 0x64, 0x72, 0x68, 0x9b, 0xd3, 0xd8,
+ 0x09, 0x54, 0x99, 0x32, 0x63, 0x6c, 0x45, 0x13,
+ 0x70, 0x71, 0x34, 0xd3, 0x56, 0x9c, 0xbd, 0x10,
+ 0x8f, 0x33, 0xbe, 0xe8, 0x60, 0x14, 0x59, 0x8b,
+ 0x23, 0xee, 0xeb, 0xc8, 0x72, 0xfe, 0x1b, 0x88,
+ 0x9e, 0xd7, 0xf3, 0x6c, 0xd8, 0xe9, 0x73, 0xd0,
+ 0xfe, 0xa2, 0x9a, 0xc8, 0xb1, 0xf7, 0x65, 0x48,
+ 0xd0, 0x53, 0x31, 0x82, 0x04, 0xd5, 0x9d, 0x44,
+ },
+ },
+ {
+ .data_len = 1000,
+ .key_len = 33,
+ .mac = {
+ 0x02, 0x25, 0xf7, 0x45, 0x56, 0xd1, 0x99, 0xf2,
+ 0xfb, 0x9b, 0x8c, 0x64, 0xac, 0x85, 0x6c, 0x6c,
+ 0x4b, 0x2e, 0x03, 0x0d, 0x78, 0x2d, 0xa4, 0x89,
+ 0x7e, 0x2e, 0x32, 0x7a, 0xce, 0x4f, 0x0d, 0xdb,
+ 0x54, 0xf2, 0xb3, 0x01, 0x9f, 0xc4, 0x61, 0x9e,
+ 0xa8, 0xb3, 0x72, 0xa9, 0x65, 0x37, 0xfa, 0xb3,
+ 0x57, 0xce, 0x41, 0xb1, 0x7c, 0xb9, 0x08, 0xab,
+ 0xfd, 0x0a, 0xdf, 0xc0, 0x07, 0xd9, 0xaa, 0x19,
+ },
+ },
+ {
+ .data_len = 3333,
+ .key_len = 64,
+ .mac = {
+ 0x22, 0xfe, 0x0d, 0xae, 0x67, 0x4f, 0xfb, 0x5d,
+ 0xa9, 0x89, 0xf7, 0xa4, 0xc6, 0xf2, 0xb2, 0xf0,
+ 0x7f, 0xfd, 0xa5, 0x69, 0xb2, 0x7f, 0xa4, 0xd7,
+ 0x9b, 0xbf, 0xca, 0xd9, 0x22, 0xd3, 0xca, 0x9f,
+ 0x22, 0x6e, 0x49, 0xbe, 0xf3, 0x38, 0xad, 0x47,
+ 0xc9, 0xfb, 0x58, 0x72, 0xc2, 0x0e, 0xc8, 0xca,
+ 0xcf, 0xc5, 0x49, 0xdb, 0xa7, 0xbe, 0x80, 0x69,
+ 0x58, 0xd8, 0x35, 0x7a, 0xf8, 0x33, 0x13, 0x29,
+ },
+ },
+ {
+ .data_len = 4096,
+ .key_len = 65,
+ .mac = {
+ 0xc4, 0x3b, 0x53, 0xe6, 0x98, 0x8c, 0xed, 0xca,
+ 0x5e, 0xb3, 0xac, 0xa1, 0x6e, 0xda, 0xb7, 0x25,
+ 0x94, 0x53, 0xad, 0xf5, 0x72, 0xa5, 0xd6, 0xd3,
+ 0x35, 0xce, 0x4a, 0xd9, 0x86, 0x9c, 0x8d, 0x28,
+ 0x4a, 0xfb, 0x2b, 0x04, 0x23, 0xd1, 0xe9, 0x03,
+ 0xfa, 0xf6, 0x60, 0x31, 0x85, 0x62, 0x48, 0x54,
+ 0x1e, 0x2d, 0xd2, 0x9f, 0xfb, 0xeb, 0xf6, 0x1c,
+ 0xc7, 0x72, 0x8d, 0x2a, 0x95, 0x38, 0xf0, 0x12,
+ },
+ },
+ {
+ .data_len = 4128,
+ .key_len = 66,
+ .mac = {
+ 0xf1, 0x1c, 0x03, 0xbb, 0x96, 0x3e, 0xe3, 0x42,
+ 0x6e, 0xcf, 0x6b, 0xed, 0x72, 0xc3, 0xf8, 0x9d,
+ 0xb9, 0x65, 0x03, 0xc0, 0xaf, 0x97, 0x3e, 0x8e,
+ 0x0f, 0x6b, 0x85, 0x59, 0xb7, 0x2b, 0x03, 0x9d,
+ 0x0c, 0x6b, 0xa6, 0x36, 0x84, 0xb1, 0x79, 0x02,
+ 0x12, 0x31, 0x66, 0x75, 0xb9, 0xa4, 0x7c, 0x61,
+ 0xce, 0xbf, 0x6e, 0x13, 0x40, 0xd2, 0x52, 0xc2,
+ 0xe1, 0x3c, 0xee, 0x58, 0xf6, 0xb4, 0x7e, 0x51,
+ },
+ },
+ {
+ .data_len = 4160,
+ .key_len = 127,
+ .mac = {
+ 0xb9, 0x05, 0x0a, 0xf6, 0x43, 0x3a, 0xc1, 0xf5,
+ 0xd7, 0x37, 0x8a, 0xaf, 0x05, 0x5f, 0x7e, 0x9f,
+ 0x59, 0xaf, 0xa7, 0x2b, 0x91, 0x47, 0x91, 0x5b,
+ 0xeb, 0xca, 0xab, 0x25, 0x66, 0x0c, 0x06, 0x13,
+ 0x23, 0x29, 0x18, 0x5c, 0x34, 0x66, 0x8b, 0x40,
+ 0x0e, 0x05, 0x0f, 0x31, 0x97, 0x24, 0x53, 0x60,
+ 0xba, 0x98, 0x7b, 0x85, 0xd6, 0x8b, 0xef, 0x99,
+ 0xb6, 0x49, 0x00, 0x1a, 0xb9, 0xef, 0x1b, 0xeb,
+ },
+ },
+ {
+ .data_len = 4224,
+ .key_len = 128,
+ .mac = {
+ 0x66, 0x52, 0x8d, 0xd1, 0x45, 0x3e, 0xde, 0x65,
+ 0x57, 0xc2, 0x45, 0x08, 0x2c, 0xe2, 0xcd, 0xb0,
+ 0xe5, 0x26, 0x04, 0x4c, 0x42, 0xac, 0x44, 0x25,
+ 0x59, 0x63, 0x42, 0x3c, 0xfe, 0x9b, 0xcd, 0xe0,
+ 0xf6, 0x8d, 0x59, 0x1b, 0x1c, 0xa0, 0xde, 0x67,
+ 0xb2, 0x3b, 0x4b, 0xec, 0x7b, 0x00, 0x67, 0xa9,
+ 0x3a, 0x69, 0x2e, 0x6d, 0x59, 0x4e, 0x2b, 0x87,
+ 0x9a, 0x90, 0x66, 0xab, 0x12, 0xc4, 0x90, 0x23,
+ },
+ },
+ {
+ .data_len = 16384,
+ .key_len = 129,
+ .mac = {
+ 0x9e, 0x4e, 0xad, 0x30, 0xc4, 0xf1, 0x48, 0xf8,
+ 0x9d, 0x1d, 0x01, 0x4f, 0xa2, 0xf2, 0x12, 0x08,
+ 0x8f, 0xca, 0xc3, 0x31, 0x6c, 0x51, 0xe1, 0xc4,
+ 0x46, 0x75, 0x78, 0x83, 0xbe, 0x29, 0x66, 0xb7,
+ 0x7b, 0x91, 0x09, 0xc5, 0xb3, 0xd7, 0xc7, 0x78,
+ 0xc3, 0x48, 0x63, 0x2f, 0x15, 0x7b, 0xe3, 0x7c,
+ 0xe5, 0x45, 0x7b, 0xd3, 0x8f, 0xf6, 0x2b, 0x4b,
+ 0x93, 0x72, 0xe9, 0x01, 0xf8, 0xe3, 0xfa, 0x2b,
+ },
+ },
+};
diff --git a/lib/crypto/tests/sha512_kunit.c b/lib/crypto/tests/sha512_kunit.c
new file mode 100644
index 0000000000000..8a93b86c36657
--- /dev/null
+++ b/lib/crypto/tests/sha512_kunit.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2025 Google LLC
+ */
+#include <crypto/sha2.h>
+#include "sha512-testvecs.h"
+
+#define HASH sha512
+#define HASH_CTX sha512_ctx
+#define HASH_SIZE SHA512_DIGEST_SIZE
+#define HASH_INIT sha512_init
+#define HASH_UPDATE sha512_update
+#define HASH_FINAL sha512_final
+#define HASH_TESTVECS sha512_testvecs
+#define HMAC_KEY hmac_sha512_key
+#define HMAC_CTX hmac_sha512_ctx
+#define HMAC_SETKEY hmac_sha512_preparekey
+#define HMAC_INIT hmac_sha512_init
+#define HMAC_UPDATE hmac_sha512_update
+#define HMAC_FINAL hmac_sha512_final
+#define HMAC hmac_sha512
+#define HMAC_USINGRAWKEY hmac_sha512_usingrawkey
+#define HMAC_TESTVECS hmac_sha512_testvecs
+#include "hash-test-template.h"
+
+static struct kunit_case hash_test_cases[] = {
+ KUNIT_CASE(test_hash_test_vectors),
+ KUNIT_CASE(test_hash_incremental_updates),
+ KUNIT_CASE(test_hash_buffer_overruns),
+ KUNIT_CASE(test_hash_overlaps),
+ KUNIT_CASE(test_hash_alignment_consistency),
+ KUNIT_CASE(test_hash_interrupt_context),
+ KUNIT_CASE(test_hash_ctx_zeroization),
+ KUNIT_CASE(test_hmac),
+ KUNIT_CASE(benchmark_hash),
+ {},
+};
+
+static struct kunit_suite hash_test_suite = {
+ .name = "sha512",
+ .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/scripts/crypto/gen-hash-testvecs.py b/scripts/crypto/gen-hash-testvecs.py
new file mode 100755
index 0000000000000..9e4baa9201579
--- /dev/null
+++ b/scripts/crypto/gen-hash-testvecs.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Script that generates test vectors for the given cryptographic hash function.
+#
+# Copyright 2025 Google LLC
+
+import hashlib
+import hmac
+import sys
+
+DATA_LENS = [0, 1, 2, 3, 16, 32, 48, 49, 63, 64, 65, 127, 128, 129, 256, 511, 513,
+ 1000, 3333, 4096, 4128, 4160, 4224, 16384]
+KEY_LENS = [0, 1, 31, 32, 33, 64, 65, 66, 127, 128, 129, 1000, 1024]
+
+# Generate the given number of random bytes, using the length itself as the seed
+# for a simple random number generator. The test uses the same seed and random
+# number generator to reconstruct the data, so it doesn't have to be explicitly
+# included in the test vector (as long as all test vectors use random data).
+def rand_bytes(length):
+ seed = length
+ out = []
+ for _ in range(length):
+ seed = (seed * 25214903917 + 11) % 2**48
+ out.append((seed >> 16) % 256)
+ return bytes(out)
+
+def gen_unkeyed_testvecs(alg):
+ print('')
+ print('static const struct {')
+ print('\tsize_t data_len;')
+ print(f'\tu8 digest[{alg.upper()}_DIGEST_SIZE];')
+ print(f'}} {alg}_testvecs[] = {{')
+ for data_len in DATA_LENS:
+ data = rand_bytes(data_len)
+ h = hashlib.new(alg)
+ h.update(data)
+ digest = h.digest()
+
+ print('\t{')
+ print(f'\t\t.data_len = {data_len},')
+ print('\t\t.digest = {')
+ for i in range(0, len(digest), 8):
+ line = '\t\t\t' + ''.join(f'0x{b:02x}, ' for b in digest[i:i+8])
+ print(f'{line.rstrip()}')
+ print('\t\t},')
+ print('\t},')
+ print('};')
+
+def gen_hmac_testvecs(alg):
+ print('')
+ print('static const struct {')
+ print('\tsize_t data_len;')
+ print('\tsize_t key_len;')
+ print(f'\tu8 mac[{alg.upper()}_DIGEST_SIZE];')
+ print(f'}} hmac_{alg}_testvecs[] = {{')
+ for (i, data_len) in enumerate(DATA_LENS):
+ key_len = KEY_LENS[i % len(KEY_LENS)]
+ data = rand_bytes(data_len)
+ key = rand_bytes(key_len)
+ mac = hmac.digest(key, data, alg)
+
+ print('\t{')
+ print(f'\t\t.data_len = {data_len},')
+ print(f'\t\t.key_len = {key_len},')
+ print('\t\t.mac = {')
+ for i in range(0, len(mac), 8):
+ line = '\t\t\t' + ''.join(f'0x{b:02x}, ' for b in mac[i:i+8])
+ print(f'{line.rstrip()}')
+ print('\t\t},')
+ print('\t},')
+ print('};')
+
+if len(sys.argv) != 2:
+ sys.stderr.write('Usage: gen-hash-testvecs.py ALGORITHM\n')
+ sys.stderr.write('ALGORITHM may be any supported by Python hashlib.\n')
+ sys.stderr.write('Example: gen-hash-testvecs.py sha512\n')
+ sys.exit(1)
+
+alg = sys.argv[1]
+print(f'/* This file was generated by: {sys.argv[0]} {" ".join(sys.argv[1:])} */')
+gen_unkeyed_testvecs(alg)
+gen_hmac_testvecs(alg)
--
2.49.0
Powered by blists - more mailing lists