mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 11:06:41 -05:00
Merge tag 'libcrypto-tests-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux
Pull crypto library test updates from Eric Biggers: "Add KUnit test suites for the Poly1305, SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512 library functions. These are the first KUnit tests for lib/crypto/. So in addition to being useful tests for these specific algorithms, they also establish some conventions for lib/crypto/ testing going forwards. The new tests are fairly comprehensive: more comprehensive than the generic crypto infrastructure's tests. They use a variety of techniques to check for the types of implementation bugs that tend to occur in the real world, rather than just naively checking some test vectors. (Interestingly, poly1305_kunit found a bug in QEMU) The core test logic is shared by all six algorithms, rather than being duplicated for each algorithm. Each algorithm's test suite also optionally includes a benchmark" * tag 'libcrypto-tests-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux: lib/crypto: tests: Annotate worker to be on stack lib/crypto: tests: Add KUnit tests for SHA-1 and HMAC-SHA1 lib/crypto: tests: Add KUnit tests for Poly1305 lib/crypto: tests: Add KUnit tests for SHA-384 and SHA-512 lib/crypto: tests: Add KUnit tests for SHA-224 and SHA-256 lib/crypto: tests: Add hash-test-template.h and gen-hash-testvecs.py
This commit is contained in:
@@ -194,6 +194,8 @@ config CRYPTO_LIB_SHA512_ARCH
|
||||
config CRYPTO_LIB_SM3
|
||||
tristate
|
||||
|
||||
source "lib/crypto/tests/Kconfig"
|
||||
|
||||
if !KMSAN # avoid false positives from assembly
|
||||
if ARM
|
||||
source "lib/crypto/arm/Kconfig"
|
||||
|
||||
@@ -8,6 +8,8 @@ quiet_cmd_perlasm = PERLASM $@
|
||||
quiet_cmd_perlasm_with_args = PERLASM $@
|
||||
cmd_perlasm_with_args = $(PERL) $(<) void $(@)
|
||||
|
||||
obj-$(CONFIG_KUNIT) += tests/
|
||||
|
||||
obj-$(CONFIG_CRYPTO_HASH_INFO) += hash_info.o
|
||||
|
||||
obj-$(CONFIG_CRYPTO_LIB_UTILS) += libcryptoutils.o
|
||||
|
||||
60
lib/crypto/tests/Kconfig
Normal file
60
lib/crypto/tests/Kconfig
Normal file
@@ -0,0 +1,60 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
config CRYPTO_LIB_POLY1305_KUNIT_TEST
|
||||
tristate "KUnit tests for Poly1305" if !KUNIT_ALL_TESTS
|
||||
depends on KUNIT
|
||||
default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS
|
||||
select CRYPTO_LIB_BENCHMARK_VISIBLE
|
||||
select CRYPTO_LIB_POLY1305
|
||||
help
|
||||
KUnit tests for the Poly1305 library functions.
|
||||
|
||||
config CRYPTO_LIB_SHA1_KUNIT_TEST
|
||||
tristate "KUnit tests for SHA-1" if !KUNIT_ALL_TESTS
|
||||
depends on KUNIT
|
||||
default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS
|
||||
select CRYPTO_LIB_BENCHMARK_VISIBLE
|
||||
select CRYPTO_LIB_SHA1
|
||||
help
|
||||
KUnit tests for the SHA-1 cryptographic hash function and its
|
||||
corresponding HMAC.
|
||||
|
||||
# Option is named *_SHA256_KUNIT_TEST, though both SHA-224 and SHA-256 tests are
|
||||
# included, for consistency with the naming used elsewhere (e.g. CRYPTO_SHA256).
|
||||
config CRYPTO_LIB_SHA256_KUNIT_TEST
|
||||
tristate "KUnit tests for SHA-224 and SHA-256" if !KUNIT_ALL_TESTS
|
||||
depends on KUNIT
|
||||
default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS
|
||||
select CRYPTO_LIB_BENCHMARK_VISIBLE
|
||||
select CRYPTO_LIB_SHA256
|
||||
help
|
||||
KUnit tests for the SHA-224 and SHA-256 cryptographic hash functions
|
||||
and their corresponding HMACs.
|
||||
|
||||
# Option is named *_SHA512_KUNIT_TEST, though both SHA-384 and SHA-512 tests are
|
||||
# included, for consistency with the naming used elsewhere (e.g. CRYPTO_SHA512).
|
||||
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_BENCHMARK_VISIBLE
|
||||
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_VISIBLE
|
||||
bool
|
||||
|
||||
config CRYPTO_LIB_BENCHMARK
|
||||
bool "Include benchmarks in KUnit tests for cryptographic functions"
|
||||
depends on CRYPTO_LIB_BENCHMARK_VISIBLE
|
||||
help
|
||||
Include benchmarks in the KUnit tests for cryptographic functions.
|
||||
The benchmark results are printed to the kernel log when the
|
||||
corresponding KUnit test suite runs.
|
||||
|
||||
This is useful for evaluating the performance of the cryptographic
|
||||
functions. However, it will increase the runtime of the KUnit tests.
|
||||
|
||||
If you're only interested in correctness testing, leave this disabled.
|
||||
6
lib/crypto/tests/Makefile
Normal file
6
lib/crypto/tests/Makefile
Normal file
@@ -0,0 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
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
|
||||
683
lib/crypto/tests/hash-test-template.h
Normal file
683
lib/crypto/tests/hash-test-template.h
Normal file
@@ -0,0 +1,683 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Test cases for hash functions, including a benchmark. This is included by
|
||||
* KUnit test suites that want to use it. See sha512_kunit.c for an example.
|
||||
*
|
||||
* Copyright 2025 Google LLC
|
||||
*/
|
||||
#include <kunit/test.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/timekeeping.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 void rand_bytes_seeded_from_len(u8 *out, size_t len)
|
||||
{
|
||||
random_seed = len;
|
||||
rand_bytes(out, len);
|
||||
}
|
||||
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hash_suite_exit(struct kunit_suite *suite)
|
||||
{
|
||||
vfree(orig_test_buf);
|
||||
orig_test_buf = NULL;
|
||||
test_buf = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the hash function against a list of test vectors.
|
||||
*
|
||||
* Note that it's only necessary to run each test vector in one way (e.g.,
|
||||
* one-shot instead of incremental), 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_hash[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_hash);
|
||||
KUNIT_ASSERT_MEMEQ_MSG(
|
||||
test, actual_hash, hash_testvecs[i].digest, HASH_SIZE,
|
||||
"Wrong result with test vector %zu; data_len=%zu", i,
|
||||
data_len);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test that the hash function produces correct results for *every* length up to
|
||||
* 4096 bytes. To do this, generate seeded random data, then calculate a hash
|
||||
* value for each length 0..4096, then hash the hash values. Verify just the
|
||||
* final hash value, which should match only when all hash values were correct.
|
||||
*/
|
||||
static void test_hash_all_lens_up_to_4096(struct kunit *test)
|
||||
{
|
||||
struct HASH_CTX ctx;
|
||||
u8 hash[HASH_SIZE];
|
||||
|
||||
static_assert(TEST_BUF_LEN >= 4096);
|
||||
rand_bytes_seeded_from_len(test_buf, 4096);
|
||||
HASH_INIT(&ctx);
|
||||
for (size_t len = 0; len <= 4096; len++) {
|
||||
HASH(test_buf, len, hash);
|
||||
HASH_UPDATE(&ctx, hash, HASH_SIZE);
|
||||
}
|
||||
HASH_FINAL(&ctx, hash);
|
||||
KUNIT_ASSERT_MEMEQ(test, hash, hash_testvec_consolidated, HASH_SIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test that the hash function produces the same result with a one-shot
|
||||
* computation as it does with an incremental computation.
|
||||
*/
|
||||
static void test_hash_incremental_updates(struct kunit *test)
|
||||
{
|
||||
for (int 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);
|
||||
rand_bytes(&test_buf[offset], total_len);
|
||||
|
||||
/* Compute the hash value in one shot. */
|
||||
HASH(&test_buf[offset], total_len, hash1);
|
||||
|
||||
/*
|
||||
* Compute the hash value incrementally, using a randomly
|
||||
* selected sequence of update lengths that sum to total_len.
|
||||
*/
|
||||
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);
|
||||
|
||||
/* Verify that the two hash values are the same. */
|
||||
KUNIT_ASSERT_MEMEQ_MSG(
|
||||
test, hash1, hash2, HASH_SIZE,
|
||||
"Incremental test failed with total_len=%zu num_parts=%zu offset=%zu",
|
||||
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);
|
||||
|
||||
rand_bytes(test_buf, TEST_BUF_LEN);
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
size_t len = rand_length(max_tested_len);
|
||||
struct HASH_CTX ctx;
|
||||
u8 hash[HASH_SIZE];
|
||||
|
||||
/* 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;
|
||||
struct HASH_CTX ctx;
|
||||
u8 hash[HASH_SIZE];
|
||||
|
||||
rand_bytes(test_buf, TEST_BUF_LEN);
|
||||
|
||||
for (int 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",
|
||||
len, offset, left_end);
|
||||
|
||||
/* Repeat the above test, but this time use init+update+final */
|
||||
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",
|
||||
len, offset, left_end);
|
||||
|
||||
/* Test modifying the source data after it was used. */
|
||||
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",
|
||||
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 (int 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)",
|
||||
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;
|
||||
|
||||
rand_bytes(test_buf, 128);
|
||||
HASH_INIT(&ctx);
|
||||
HASH_UPDATE(&ctx, test_buf, 128);
|
||||
HASH_FINAL(&ctx, test_buf);
|
||||
KUNIT_ASSERT_MEMEQ_MSG(test, &ctx, zeroes, sizeof(ctx),
|
||||
"Hash context was not zeroized by finalization");
|
||||
}
|
||||
|
||||
#define IRQ_TEST_HRTIMER_INTERVAL us_to_ktime(5)
|
||||
|
||||
struct hash_irq_test_state {
|
||||
bool (*func)(void *test_specific_state);
|
||||
void *test_specific_state;
|
||||
bool task_func_reported_failure;
|
||||
bool hardirq_func_reported_failure;
|
||||
bool softirq_func_reported_failure;
|
||||
unsigned long hardirq_func_calls;
|
||||
unsigned long softirq_func_calls;
|
||||
struct hrtimer timer;
|
||||
struct work_struct bh_work;
|
||||
};
|
||||
|
||||
static enum hrtimer_restart hash_irq_test_timer_func(struct hrtimer *timer)
|
||||
{
|
||||
struct hash_irq_test_state *state =
|
||||
container_of(timer, typeof(*state), timer);
|
||||
|
||||
WARN_ON_ONCE(!in_hardirq());
|
||||
state->hardirq_func_calls++;
|
||||
|
||||
if (!state->func(state->test_specific_state))
|
||||
state->hardirq_func_reported_failure = true;
|
||||
|
||||
hrtimer_forward_now(&state->timer, IRQ_TEST_HRTIMER_INTERVAL);
|
||||
queue_work(system_bh_wq, &state->bh_work);
|
||||
return HRTIMER_RESTART;
|
||||
}
|
||||
|
||||
static void hash_irq_test_bh_work_func(struct work_struct *work)
|
||||
{
|
||||
struct hash_irq_test_state *state =
|
||||
container_of(work, typeof(*state), bh_work);
|
||||
|
||||
WARN_ON_ONCE(!in_serving_softirq());
|
||||
state->softirq_func_calls++;
|
||||
|
||||
if (!state->func(state->test_specific_state))
|
||||
state->softirq_func_reported_failure = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function which repeatedly runs the given @func in task, softirq, and
|
||||
* hardirq context concurrently, and reports a failure to KUnit if any
|
||||
* invocation of @func in any context returns false. @func is passed
|
||||
* @test_specific_state as its argument. At most 3 invocations of @func will
|
||||
* run concurrently: one in each of task, softirq, and hardirq context.
|
||||
*
|
||||
* The main purpose of this interrupt context testing is to validate fallback
|
||||
* code paths that run in contexts where the normal code path cannot be used,
|
||||
* typically due to the FPU or vector registers already being in-use in kernel
|
||||
* mode. These code paths aren't covered when the test code is executed only by
|
||||
* the KUnit test runner thread in task context. The reason for the concurrency
|
||||
* is because merely using hardirq context is not sufficient to reach a fallback
|
||||
* code path on some architectures; the hardirq actually has to occur while the
|
||||
* FPU or vector unit was already in-use in kernel mode.
|
||||
*
|
||||
* Another purpose of this testing is to detect issues with the architecture's
|
||||
* irq_fpu_usable() and kernel_fpu_begin/end() or equivalent functions,
|
||||
* especially in softirq context when the softirq may have interrupted a task
|
||||
* already using kernel-mode FPU or vector (if the arch didn't prevent that).
|
||||
* Crypto functions are often executed in softirqs, so this is important.
|
||||
*/
|
||||
static void run_irq_test(struct kunit *test, bool (*func)(void *),
|
||||
int max_iterations, void *test_specific_state)
|
||||
{
|
||||
struct hash_irq_test_state state = {
|
||||
.func = func,
|
||||
.test_specific_state = test_specific_state,
|
||||
};
|
||||
unsigned long end_jiffies;
|
||||
|
||||
/*
|
||||
* 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, hash_irq_test_timer_func,
|
||||
CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD);
|
||||
INIT_WORK_ONSTACK(&state.bh_work, hash_irq_test_bh_work_func);
|
||||
|
||||
/* Run for up to max_iterations or 1 second, whichever comes first. */
|
||||
end_jiffies = jiffies + HZ;
|
||||
hrtimer_start(&state.timer, IRQ_TEST_HRTIMER_INTERVAL,
|
||||
HRTIMER_MODE_REL_HARD);
|
||||
for (int i = 0; i < max_iterations && !time_after(jiffies, end_jiffies);
|
||||
i++) {
|
||||
if (!func(test_specific_state))
|
||||
state.task_func_reported_failure = 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, state.hardirq_func_calls, 0,
|
||||
"Timer function was not called");
|
||||
KUNIT_EXPECT_GT_MSG(test, state.softirq_func_calls, 0,
|
||||
"BH work function was not called");
|
||||
|
||||
/* Check for incorrect hash values reported from any context. */
|
||||
KUNIT_EXPECT_FALSE_MSG(
|
||||
test, state.task_func_reported_failure,
|
||||
"Incorrect hash values reported from task context");
|
||||
KUNIT_EXPECT_FALSE_MSG(
|
||||
test, state.hardirq_func_reported_failure,
|
||||
"Incorrect hash values reported from hardirq context");
|
||||
KUNIT_EXPECT_FALSE_MSG(
|
||||
test, state.softirq_func_reported_failure,
|
||||
"Incorrect hash values reported from softirq context");
|
||||
}
|
||||
|
||||
#define IRQ_TEST_DATA_LEN 256
|
||||
#define IRQ_TEST_NUM_BUFFERS 3 /* matches max concurrency level */
|
||||
|
||||
struct hash_irq_test1_state {
|
||||
u8 expected_hashes[IRQ_TEST_NUM_BUFFERS][HASH_SIZE];
|
||||
atomic_t seqno;
|
||||
};
|
||||
|
||||
/*
|
||||
* Compute the hash of one of the test messages and verify that it matches the
|
||||
* expected hash from @state->expected_hashes. To increase the chance of
|
||||
* detecting problems, cycle through multiple messages.
|
||||
*/
|
||||
static bool hash_irq_test1_func(void *state_)
|
||||
{
|
||||
struct hash_irq_test1_state *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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test that if hashes are computed in task, softirq, and hardirq context
|
||||
* concurrently, then all results are as expected.
|
||||
*/
|
||||
static void test_hash_interrupt_context_1(struct kunit *test)
|
||||
{
|
||||
struct hash_irq_test1_state state = {};
|
||||
|
||||
/* Prepare some test messages and compute the expected hash of each. */
|
||||
rand_bytes(test_buf, IRQ_TEST_NUM_BUFFERS * IRQ_TEST_DATA_LEN);
|
||||
for (int i = 0; i < IRQ_TEST_NUM_BUFFERS; i++)
|
||||
HASH(&test_buf[i * IRQ_TEST_DATA_LEN], IRQ_TEST_DATA_LEN,
|
||||
state.expected_hashes[i]);
|
||||
|
||||
run_irq_test(test, hash_irq_test1_func, 100000, &state);
|
||||
}
|
||||
|
||||
struct hash_irq_test2_hash_ctx {
|
||||
struct HASH_CTX hash_ctx;
|
||||
atomic_t in_use;
|
||||
int offset;
|
||||
int step;
|
||||
};
|
||||
|
||||
struct hash_irq_test2_state {
|
||||
struct hash_irq_test2_hash_ctx ctxs[IRQ_TEST_NUM_BUFFERS];
|
||||
u8 expected_hash[HASH_SIZE];
|
||||
u16 update_lens[32];
|
||||
int num_steps;
|
||||
};
|
||||
|
||||
static bool hash_irq_test2_func(void *state_)
|
||||
{
|
||||
struct hash_irq_test2_state *state = state_;
|
||||
struct hash_irq_test2_hash_ctx *ctx;
|
||||
bool ret = true;
|
||||
|
||||
for (ctx = &state->ctxs[0]; ctx < &state->ctxs[ARRAY_SIZE(state->ctxs)];
|
||||
ctx++) {
|
||||
if (atomic_cmpxchg(&ctx->in_use, 0, 1) == 0)
|
||||
break;
|
||||
}
|
||||
if (WARN_ON_ONCE(ctx == &state->ctxs[ARRAY_SIZE(state->ctxs)])) {
|
||||
/*
|
||||
* This should never happen, as the number of contexts is equal
|
||||
* to the maximum concurrency level of run_irq_test().
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctx->step == 0) {
|
||||
/* Init step */
|
||||
HASH_INIT(&ctx->hash_ctx);
|
||||
ctx->offset = 0;
|
||||
ctx->step++;
|
||||
} else if (ctx->step < state->num_steps - 1) {
|
||||
/* Update step */
|
||||
HASH_UPDATE(&ctx->hash_ctx, &test_buf[ctx->offset],
|
||||
state->update_lens[ctx->step - 1]);
|
||||
ctx->offset += state->update_lens[ctx->step - 1];
|
||||
ctx->step++;
|
||||
} else {
|
||||
/* Final step */
|
||||
u8 actual_hash[HASH_SIZE];
|
||||
|
||||
if (WARN_ON_ONCE(ctx->offset != TEST_BUF_LEN))
|
||||
ret = false;
|
||||
HASH_FINAL(&ctx->hash_ctx, actual_hash);
|
||||
if (memcmp(actual_hash, state->expected_hash, HASH_SIZE) != 0)
|
||||
ret = false;
|
||||
ctx->step = 0;
|
||||
}
|
||||
atomic_set_release(&ctx->in_use, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test that if hashes are computed in task, softirq, and hardirq context
|
||||
* concurrently, *including doing different parts of the same incremental
|
||||
* computation in different contexts*, then all results are as expected.
|
||||
* Besides detecting bugs similar to those that test_hash_interrupt_context_1
|
||||
* can detect, this test case can also detect bugs where hash function
|
||||
* implementations don't correctly handle these mixed incremental computations.
|
||||
*/
|
||||
static void test_hash_interrupt_context_2(struct kunit *test)
|
||||
{
|
||||
struct hash_irq_test2_state *state;
|
||||
int remaining = TEST_BUF_LEN;
|
||||
|
||||
state = kunit_kzalloc(test, sizeof(*state), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, state);
|
||||
|
||||
rand_bytes(test_buf, TEST_BUF_LEN);
|
||||
HASH(test_buf, TEST_BUF_LEN, state->expected_hash);
|
||||
|
||||
/*
|
||||
* Generate a list of update lengths to use. Ensure that it contains
|
||||
* multiple entries but is limited to a maximum length.
|
||||
*/
|
||||
static_assert(TEST_BUF_LEN / 4096 > 1);
|
||||
for (state->num_steps = 0;
|
||||
state->num_steps < ARRAY_SIZE(state->update_lens) - 1 && remaining;
|
||||
state->num_steps++) {
|
||||
state->update_lens[state->num_steps] =
|
||||
rand_length(min(remaining, 4096));
|
||||
remaining -= state->update_lens[state->num_steps];
|
||||
}
|
||||
if (remaining)
|
||||
state->update_lens[state->num_steps++] = remaining;
|
||||
state->num_steps += 2; /* for init and final */
|
||||
|
||||
run_irq_test(test, hash_irq_test2_func, 250000, state);
|
||||
}
|
||||
|
||||
#define UNKEYED_HASH_KUNIT_CASES \
|
||||
KUNIT_CASE(test_hash_test_vectors), \
|
||||
KUNIT_CASE(test_hash_all_lens_up_to_4096), \
|
||||
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_ctx_zeroization), \
|
||||
KUNIT_CASE(test_hash_interrupt_context_1), \
|
||||
KUNIT_CASE(test_hash_interrupt_context_2)
|
||||
/* benchmark_hash is omitted so that the suites can put it last. */
|
||||
|
||||
#ifdef HMAC
|
||||
/*
|
||||
* Test the corresponding HMAC variant.
|
||||
*
|
||||
* This test case is fairly short, since HMAC is just a simple C wrapper around
|
||||
* the underlying unkeyed hash function, which is already well-tested by the
|
||||
* other test cases. It's not useful to test things like data alignment or
|
||||
* interrupt context again for HMAC, nor to have a long list of test vectors.
|
||||
*
|
||||
* Thus, just do a single consolidated test, which covers all data lengths up to
|
||||
* 4096 bytes and all key lengths up to 292 bytes. For each data length, select
|
||||
* a key length, generate the inputs from a seed, and compute the HMAC value.
|
||||
* Concatenate all these HMAC values together, and compute the HMAC of that.
|
||||
* Verify that value. If this fails, then the HMAC implementation is wrong.
|
||||
* This won't show which specific input failed, but that should be fine. Any
|
||||
* failure would likely be non-input-specific or also show in the unkeyed tests.
|
||||
*/
|
||||
static void test_hmac(struct kunit *test)
|
||||
{
|
||||
static const u8 zeroes[sizeof(struct HMAC_CTX)];
|
||||
u8 *raw_key;
|
||||
struct HMAC_KEY key;
|
||||
struct HMAC_CTX ctx;
|
||||
u8 mac[HASH_SIZE];
|
||||
u8 mac2[HASH_SIZE];
|
||||
|
||||
static_assert(TEST_BUF_LEN >= 4096 + 293);
|
||||
rand_bytes_seeded_from_len(test_buf, 4096);
|
||||
raw_key = &test_buf[4096];
|
||||
|
||||
rand_bytes_seeded_from_len(raw_key, 32);
|
||||
HMAC_PREPAREKEY(&key, raw_key, 32);
|
||||
HMAC_INIT(&ctx, &key);
|
||||
for (size_t data_len = 0; data_len <= 4096; data_len++) {
|
||||
/*
|
||||
* Cycle through key lengths as well. Somewhat arbitrarily go
|
||||
* up to 293, which is somewhat larger than the largest hash
|
||||
* block size (which is the size at which the key starts being
|
||||
* hashed down to one block); going higher would not be useful.
|
||||
* To reduce correlation with data_len, use a prime number here.
|
||||
*/
|
||||
size_t key_len = data_len % 293;
|
||||
|
||||
HMAC_UPDATE(&ctx, test_buf, data_len);
|
||||
|
||||
rand_bytes_seeded_from_len(raw_key, key_len);
|
||||
HMAC_USINGRAWKEY(raw_key, key_len, test_buf, data_len, mac);
|
||||
HMAC_UPDATE(&ctx, mac, HASH_SIZE);
|
||||
|
||||
/* Verify that HMAC() is consistent with HMAC_USINGRAWKEY(). */
|
||||
HMAC_PREPAREKEY(&key, raw_key, key_len);
|
||||
HMAC(&key, test_buf, data_len, mac2);
|
||||
KUNIT_ASSERT_MEMEQ_MSG(
|
||||
test, mac, mac2, HASH_SIZE,
|
||||
"HMAC gave different results with raw and prepared keys");
|
||||
}
|
||||
HMAC_FINAL(&ctx, mac);
|
||||
KUNIT_EXPECT_MEMEQ_MSG(test, mac, hmac_testvec_consolidated, HASH_SIZE,
|
||||
"HMAC gave wrong result");
|
||||
KUNIT_EXPECT_MEMEQ_MSG(test, &ctx, zeroes, sizeof(ctx),
|
||||
"HMAC context was not zeroized by finalization");
|
||||
}
|
||||
#define HASH_KUNIT_CASES UNKEYED_HASH_KUNIT_CASES, KUNIT_CASE(test_hmac)
|
||||
#else
|
||||
#define HASH_KUNIT_CASES UNKEYED_HASH_KUNIT_CASES
|
||||
#endif
|
||||
|
||||
/* 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,
|
||||
};
|
||||
u8 hash[HASH_SIZE];
|
||||
|
||||
if (!IS_ENABLED(CONFIG_CRYPTO_LIB_BENCHMARK))
|
||||
kunit_skip(test, "not enabled");
|
||||
|
||||
/* Warm-up */
|
||||
for (size_t i = 0; i < 10000000; i += TEST_BUF_LEN)
|
||||
HASH(test_buf, TEST_BUF_LEN, hash);
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(lens_to_test); i++) {
|
||||
size_t len = lens_to_test[i];
|
||||
/* The '+ 128' tries to account for per-message overhead. */
|
||||
size_t num_iters = 10000000 / (len + 128);
|
||||
u64 t;
|
||||
|
||||
KUNIT_ASSERT_LE(test, len, TEST_BUF_LEN);
|
||||
preempt_disable();
|
||||
t = ktime_get_ns();
|
||||
for (size_t 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", len,
|
||||
div64_u64((u64)len * num_iters * 1000, t ?: 1));
|
||||
}
|
||||
}
|
||||
186
lib/crypto/tests/poly1305-testvecs.h
Normal file
186
lib/crypto/tests/poly1305-testvecs.h
Normal file
@@ -0,0 +1,186 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/* This file was generated by: ./scripts/crypto/gen-hash-testvecs.py poly1305 */
|
||||
|
||||
static const struct {
|
||||
size_t data_len;
|
||||
u8 digest[POLY1305_DIGEST_SIZE];
|
||||
} hash_testvecs[] = {
|
||||
{
|
||||
.data_len = 0,
|
||||
.digest = {
|
||||
0xe8, 0x2d, 0x67, 0x2c, 0x01, 0x48, 0xf9, 0xb7,
|
||||
0x87, 0x85, 0x3f, 0xcf, 0x18, 0x66, 0x8c, 0xd3,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 1,
|
||||
.digest = {
|
||||
0xb8, 0xad, 0xca, 0x6b, 0x32, 0xba, 0x34, 0x42,
|
||||
0x54, 0x10, 0x28, 0xf5, 0x0f, 0x7e, 0x8e, 0xe3,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 2,
|
||||
.digest = {
|
||||
0xb8, 0xf7, 0xf4, 0xc2, 0x85, 0x33, 0x80, 0x63,
|
||||
0xd1, 0x45, 0xda, 0xf8, 0x7c, 0x79, 0x42, 0xd1,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 3,
|
||||
.digest = {
|
||||
0xf3, 0x73, 0x7b, 0x60, 0x24, 0xcc, 0x5d, 0x3e,
|
||||
0xd1, 0x95, 0x86, 0xce, 0x89, 0x0a, 0x33, 0xba,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 16,
|
||||
.digest = {
|
||||
0x0a, 0x1a, 0x2d, 0x39, 0xea, 0x49, 0x8f, 0xb7,
|
||||
0x90, 0xb6, 0x74, 0x3b, 0x41, 0x3b, 0x96, 0x11,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 32,
|
||||
.digest = {
|
||||
0x99, 0x05, 0xe3, 0xa7, 0x9e, 0x2a, 0xd2, 0x42,
|
||||
0xb9, 0x45, 0x0c, 0x08, 0xe7, 0x10, 0xe4, 0xe1,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 48,
|
||||
.digest = {
|
||||
0xe1, 0xb2, 0x15, 0xee, 0xa2, 0xf3, 0x04, 0xac,
|
||||
0xdd, 0x27, 0x57, 0x95, 0x2f, 0x45, 0xa8, 0xd3,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 49,
|
||||
.digest = {
|
||||
0x1c, 0xf3, 0xab, 0x39, 0xc0, 0x69, 0x49, 0x69,
|
||||
0x89, 0x6f, 0x1f, 0x03, 0x16, 0xe7, 0xc0, 0xf0,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 63,
|
||||
.digest = {
|
||||
0x30, 0xb0, 0x32, 0x87, 0x51, 0x55, 0x9c, 0x39,
|
||||
0x38, 0x42, 0x06, 0xe9, 0x2a, 0x3e, 0x2c, 0x92,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 64,
|
||||
.digest = {
|
||||
0x2c, 0x04, 0x16, 0x36, 0x55, 0x25, 0x2d, 0xc6,
|
||||
0x3d, 0x70, 0x5b, 0x88, 0x46, 0xb6, 0x71, 0x77,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 65,
|
||||
.digest = {
|
||||
0x03, 0x87, 0xdd, 0xbe, 0xe8, 0x30, 0xf2, 0x15,
|
||||
0x40, 0x44, 0x29, 0x7b, 0xb1, 0xe9, 0x9d, 0xe7,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 127,
|
||||
.digest = {
|
||||
0x29, 0x83, 0x4f, 0xcb, 0x5a, 0x93, 0x25, 0xad,
|
||||
0x05, 0xa4, 0xb3, 0x24, 0x77, 0x62, 0x2d, 0x3d,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 128,
|
||||
.digest = {
|
||||
0x20, 0x0e, 0x2c, 0x05, 0xe2, 0x0b, 0x85, 0xa0,
|
||||
0x24, 0x73, 0x7f, 0x65, 0x70, 0x6c, 0x3e, 0xb0,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 129,
|
||||
.digest = {
|
||||
0xef, 0x2f, 0x98, 0x42, 0xc2, 0x90, 0x55, 0xea,
|
||||
0xba, 0x28, 0x76, 0xfd, 0x9e, 0x3e, 0x4d, 0x53,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 256,
|
||||
.digest = {
|
||||
0x9e, 0x75, 0x4b, 0xc7, 0x69, 0x68, 0x51, 0x90,
|
||||
0xdc, 0x29, 0xc8, 0xfa, 0x86, 0xf1, 0xc9, 0xb3,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 511,
|
||||
.digest = {
|
||||
0x9d, 0x13, 0xf5, 0x54, 0xe6, 0xe3, 0x45, 0x38,
|
||||
0x8b, 0x6d, 0x5c, 0xc4, 0x50, 0xeb, 0x90, 0xcb,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 513,
|
||||
.digest = {
|
||||
0xaa, 0xb2, 0x3e, 0x3c, 0x2a, 0xfc, 0x62, 0x0e,
|
||||
0xd4, 0xe6, 0xe5, 0x5c, 0x6b, 0x9f, 0x3d, 0xc7,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 1000,
|
||||
.digest = {
|
||||
0xd6, 0x8c, 0xea, 0x8a, 0x0f, 0x68, 0xa9, 0xa8,
|
||||
0x67, 0x86, 0xf9, 0xc1, 0x4c, 0x26, 0x10, 0x6d,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 3333,
|
||||
.digest = {
|
||||
0xdc, 0xc1, 0x54, 0xe7, 0x38, 0xc6, 0xdb, 0x24,
|
||||
0xa7, 0x0b, 0xff, 0xd3, 0x1b, 0x93, 0x01, 0xa6,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 4096,
|
||||
.digest = {
|
||||
0x8f, 0x88, 0x3e, 0x9c, 0x7b, 0x2e, 0x82, 0x5a,
|
||||
0x1d, 0x31, 0x82, 0xcc, 0x69, 0xb4, 0x16, 0x26,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 4128,
|
||||
.digest = {
|
||||
0x23, 0x45, 0x94, 0xa8, 0x11, 0x54, 0x9d, 0xf2,
|
||||
0xa1, 0x9a, 0xca, 0xf9, 0x3e, 0x65, 0x52, 0xfd,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 4160,
|
||||
.digest = {
|
||||
0x7b, 0xfc, 0xa9, 0x1e, 0x03, 0xad, 0xef, 0x03,
|
||||
0xe2, 0x20, 0x92, 0xc7, 0x54, 0x83, 0xfa, 0x37,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 4224,
|
||||
.digest = {
|
||||
0x46, 0xab, 0x8c, 0x75, 0xb3, 0x10, 0xa6, 0x3f,
|
||||
0x74, 0x55, 0x42, 0x6d, 0x69, 0x35, 0xd2, 0xf5,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 16384,
|
||||
.digest = {
|
||||
0xd0, 0xfe, 0x26, 0xc2, 0xca, 0x94, 0x2d, 0x52,
|
||||
0x2d, 0xe1, 0x11, 0xdd, 0x42, 0x28, 0x83, 0xa6,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const u8 hash_testvec_consolidated[POLY1305_DIGEST_SIZE] = {
|
||||
0x9d, 0x07, 0x5d, 0xc9, 0x6c, 0xeb, 0x62, 0x5d,
|
||||
0x02, 0x5f, 0xe1, 0xe3, 0xd1, 0x71, 0x69, 0x34,
|
||||
};
|
||||
|
||||
static const u8 poly1305_allones_macofmacs[POLY1305_DIGEST_SIZE] = {
|
||||
0x0c, 0x26, 0x6b, 0x45, 0x87, 0x06, 0xcf, 0xc4,
|
||||
0x3f, 0x70, 0x7d, 0xb3, 0x50, 0xdd, 0x81, 0x25,
|
||||
};
|
||||
165
lib/crypto/tests/poly1305_kunit.c
Normal file
165
lib/crypto/tests/poly1305_kunit.c
Normal file
@@ -0,0 +1,165 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright 2025 Google LLC
|
||||
*/
|
||||
#include <crypto/poly1305.h>
|
||||
#include "poly1305-testvecs.h"
|
||||
|
||||
/*
|
||||
* A fixed key used when presenting Poly1305 as an unkeyed hash function in
|
||||
* order to reuse hash-test-template.h. At the beginning of the test suite,
|
||||
* this is initialized to bytes generated from a fixed seed.
|
||||
*/
|
||||
static u8 test_key[POLY1305_KEY_SIZE];
|
||||
|
||||
/* This probably should be in the actual API, but just define it here for now */
|
||||
static void poly1305(const u8 key[POLY1305_KEY_SIZE], const u8 *data,
|
||||
size_t len, u8 out[POLY1305_DIGEST_SIZE])
|
||||
{
|
||||
struct poly1305_desc_ctx ctx;
|
||||
|
||||
poly1305_init(&ctx, key);
|
||||
poly1305_update(&ctx, data, len);
|
||||
poly1305_final(&ctx, out);
|
||||
}
|
||||
|
||||
static void poly1305_init_withtestkey(struct poly1305_desc_ctx *ctx)
|
||||
{
|
||||
poly1305_init(ctx, test_key);
|
||||
}
|
||||
|
||||
static void poly1305_withtestkey(const u8 *data, size_t len,
|
||||
u8 out[POLY1305_DIGEST_SIZE])
|
||||
{
|
||||
poly1305(test_key, data, len, out);
|
||||
}
|
||||
|
||||
/* Generate the HASH_KUNIT_CASES using hash-test-template.h. */
|
||||
#define HASH poly1305_withtestkey
|
||||
#define HASH_CTX poly1305_desc_ctx
|
||||
#define HASH_SIZE POLY1305_DIGEST_SIZE
|
||||
#define HASH_INIT poly1305_init_withtestkey
|
||||
#define HASH_UPDATE poly1305_update
|
||||
#define HASH_FINAL poly1305_final
|
||||
#include "hash-test-template.h"
|
||||
|
||||
static int poly1305_suite_init(struct kunit_suite *suite)
|
||||
{
|
||||
rand_bytes_seeded_from_len(test_key, POLY1305_KEY_SIZE);
|
||||
return hash_suite_init(suite);
|
||||
}
|
||||
|
||||
static void poly1305_suite_exit(struct kunit_suite *suite)
|
||||
{
|
||||
hash_suite_exit(suite);
|
||||
}
|
||||
|
||||
/*
|
||||
* Poly1305 test case which uses a key and message consisting only of one bits:
|
||||
*
|
||||
* - Using an all-one-bits r_key tests the key clamping.
|
||||
* - Using an all-one-bits s_key tests carries in implementations of the
|
||||
* addition mod 2**128 during finalization.
|
||||
* - Using all-one-bits message, and to a lesser extent r_key, tends to maximize
|
||||
* any intermediate accumulator values. This increases the chance of
|
||||
* detecting bugs that occur only in rare cases where the accumulator values
|
||||
* get very large, for example the bug fixed by commit 678cce4019d746da
|
||||
* ("crypto: x86/poly1305 - fix overflow during partial reduction").
|
||||
*
|
||||
* Accumulator overflow bugs may be specific to particular update lengths (in
|
||||
* blocks) and/or particular values of the previous acculumator. Note that the
|
||||
* accumulator starts at 0 which gives the lowest chance of an overflow. Thus,
|
||||
* a single all-one-bits test vector may be insufficient.
|
||||
*
|
||||
* Considering that, do the following test: continuously update a single
|
||||
* Poly1305 context with all-one-bits data of varying lengths (0, 16, 32, ...,
|
||||
* 4096 bytes). After each update, generate the MAC from the current context,
|
||||
* and feed that MAC into a separate Poly1305 context. Repeat that entire
|
||||
* sequence of updates 32 times without re-initializing either context,
|
||||
* resulting in a total of 8224 MAC computations from a long-running, cumulative
|
||||
* context. Finally, generate and verify the MAC of all the MACs.
|
||||
*/
|
||||
static void test_poly1305_allones_keys_and_message(struct kunit *test)
|
||||
{
|
||||
struct poly1305_desc_ctx mac_ctx, macofmacs_ctx;
|
||||
u8 mac[POLY1305_DIGEST_SIZE];
|
||||
|
||||
static_assert(TEST_BUF_LEN >= 4096);
|
||||
memset(test_buf, 0xff, 4096);
|
||||
|
||||
poly1305_init(&mac_ctx, test_buf);
|
||||
poly1305_init(&macofmacs_ctx, test_buf);
|
||||
for (int i = 0; i < 32; i++) {
|
||||
for (size_t len = 0; len <= 4096; len += 16) {
|
||||
struct poly1305_desc_ctx tmp_ctx;
|
||||
|
||||
poly1305_update(&mac_ctx, test_buf, len);
|
||||
tmp_ctx = mac_ctx;
|
||||
poly1305_final(&tmp_ctx, mac);
|
||||
poly1305_update(&macofmacs_ctx, mac,
|
||||
POLY1305_DIGEST_SIZE);
|
||||
}
|
||||
}
|
||||
poly1305_final(&macofmacs_ctx, mac);
|
||||
KUNIT_ASSERT_MEMEQ(test, mac, poly1305_allones_macofmacs,
|
||||
POLY1305_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Poly1305 test case which uses r_key=1, s_key=0, and a 48-byte message
|
||||
* consisting of three blocks with integer values [2**128 - i, 0, 0]. In this
|
||||
* case, the result of the polynomial evaluation is 2**130 - i. For small
|
||||
* values of i, this is very close to the modulus 2**130 - 5, which helps catch
|
||||
* edge case bugs in the modular reduction logic.
|
||||
*/
|
||||
static void test_poly1305_reduction_edge_cases(struct kunit *test)
|
||||
{
|
||||
static const u8 key[POLY1305_KEY_SIZE] = { 1 }; /* r_key=1, s_key=0 */
|
||||
u8 data[3 * POLY1305_BLOCK_SIZE] = {};
|
||||
u8 expected_mac[POLY1305_DIGEST_SIZE];
|
||||
u8 actual_mac[POLY1305_DIGEST_SIZE];
|
||||
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
/* Set the first data block to 2**128 - i. */
|
||||
data[0] = -i;
|
||||
memset(&data[1], 0xff, POLY1305_BLOCK_SIZE - 1);
|
||||
|
||||
/*
|
||||
* Assuming s_key=0, the expected MAC as an integer is
|
||||
* (2**130 - i mod 2**130 - 5) + 0 mod 2**128. If 1 <= i <= 5,
|
||||
* that's 5 - i. If 6 <= i <= 10, that's 2**128 - i.
|
||||
*/
|
||||
if (i <= 5) {
|
||||
expected_mac[0] = 5 - i;
|
||||
memset(&expected_mac[1], 0, POLY1305_DIGEST_SIZE - 1);
|
||||
} else {
|
||||
expected_mac[0] = -i;
|
||||
memset(&expected_mac[1], 0xff,
|
||||
POLY1305_DIGEST_SIZE - 1);
|
||||
}
|
||||
|
||||
/* Compute and verify the MAC. */
|
||||
poly1305(key, data, sizeof(data), actual_mac);
|
||||
KUNIT_ASSERT_MEMEQ(test, actual_mac, expected_mac,
|
||||
POLY1305_DIGEST_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
static struct kunit_case poly1305_test_cases[] = {
|
||||
HASH_KUNIT_CASES,
|
||||
KUNIT_CASE(test_poly1305_allones_keys_and_message),
|
||||
KUNIT_CASE(test_poly1305_reduction_edge_cases),
|
||||
KUNIT_CASE(benchmark_hash),
|
||||
{},
|
||||
};
|
||||
|
||||
static struct kunit_suite poly1305_test_suite = {
|
||||
.name = "poly1305",
|
||||
.test_cases = poly1305_test_cases,
|
||||
.suite_init = poly1305_suite_init,
|
||||
.suite_exit = poly1305_suite_exit,
|
||||
};
|
||||
kunit_test_suite(poly1305_test_suite);
|
||||
|
||||
MODULE_DESCRIPTION("KUnit tests and benchmark for Poly1305");
|
||||
MODULE_LICENSE("GPL");
|
||||
212
lib/crypto/tests/sha1-testvecs.h
Normal file
212
lib/crypto/tests/sha1-testvecs.h
Normal file
@@ -0,0 +1,212 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/* This file was generated by: ./scripts/crypto/gen-hash-testvecs.py sha1 */
|
||||
|
||||
static const struct {
|
||||
size_t data_len;
|
||||
u8 digest[SHA1_DIGEST_SIZE];
|
||||
} hash_testvecs[] = {
|
||||
{
|
||||
.data_len = 0,
|
||||
.digest = {
|
||||
0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d,
|
||||
0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90,
|
||||
0xaf, 0xd8, 0x07, 0x09,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 1,
|
||||
.digest = {
|
||||
0x0a, 0xd0, 0x52, 0xdd, 0x9f, 0x32, 0x40, 0x55,
|
||||
0x21, 0xe4, 0x3c, 0x6e, 0xbd, 0xc5, 0x2f, 0x5a,
|
||||
0x02, 0x54, 0x93, 0xb2,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 2,
|
||||
.digest = {
|
||||
0x13, 0x83, 0x82, 0x03, 0x23, 0xff, 0x46, 0xd6,
|
||||
0x12, 0x7f, 0xad, 0x05, 0x2b, 0xc3, 0x4a, 0x42,
|
||||
0x49, 0x6a, 0xf8, 0x84,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 3,
|
||||
.digest = {
|
||||
0xe4, 0xdf, 0x7b, 0xdc, 0xe8, 0x6e, 0x81, 0x97,
|
||||
0x1e, 0x0f, 0xe8, 0x8b, 0x76, 0xa8, 0x59, 0x04,
|
||||
0xae, 0x92, 0x1a, 0x7c,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 16,
|
||||
.digest = {
|
||||
0x8c, 0x1c, 0x30, 0xd8, 0xbc, 0xc4, 0xc3, 0xf5,
|
||||
0xf8, 0x83, 0x0d, 0x1e, 0x04, 0x5d, 0x29, 0xb5,
|
||||
0x68, 0x89, 0xc1, 0xe9,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 32,
|
||||
.digest = {
|
||||
0x6c, 0x1d, 0x72, 0x31, 0xa5, 0x03, 0x4f, 0xdc,
|
||||
0xff, 0x2d, 0x06, 0x3e, 0x24, 0x26, 0x34, 0x8d,
|
||||
0x60, 0xa4, 0x67, 0x16,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 48,
|
||||
.digest = {
|
||||
0x37, 0x53, 0x33, 0xfa, 0xd0, 0x21, 0xad, 0xe7,
|
||||
0xa5, 0x43, 0xf1, 0x94, 0x64, 0x11, 0x47, 0x9c,
|
||||
0x72, 0xb5, 0x78, 0xb4,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 49,
|
||||
.digest = {
|
||||
0x51, 0x5c, 0xd8, 0x5a, 0xa9, 0xde, 0x7b, 0x2a,
|
||||
0xa2, 0xff, 0x70, 0x09, 0x56, 0x88, 0x40, 0x2b,
|
||||
0x50, 0x93, 0x82, 0x47,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 63,
|
||||
.digest = {
|
||||
0xbc, 0x9c, 0xab, 0x93, 0x06, 0xd5, 0xdb, 0xac,
|
||||
0x2c, 0x33, 0x15, 0x83, 0x56, 0xf6, 0x91, 0x20,
|
||||
0x09, 0xc7, 0xb2, 0x6b,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 64,
|
||||
.digest = {
|
||||
0x26, 0x90, 0x3b, 0x47, 0xe1, 0x92, 0x42, 0xd0,
|
||||
0x85, 0x63, 0x2e, 0x6b, 0x68, 0xa4, 0xc4, 0x4c,
|
||||
0xe6, 0xf4, 0xb0, 0x52,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 65,
|
||||
.digest = {
|
||||
0x55, 0x6f, 0x87, 0xdc, 0x34, 0x3d, 0xe2, 0x4f,
|
||||
0xc3, 0x81, 0xa4, 0x82, 0x79, 0x84, 0x64, 0x01,
|
||||
0x55, 0xa0, 0x1e, 0x36,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 127,
|
||||
.digest = {
|
||||
0xb7, 0xd5, 0x5f, 0xa4, 0xef, 0xbf, 0x4f, 0x96,
|
||||
0x01, 0xc1, 0x06, 0xe3, 0x75, 0xa8, 0x90, 0x92,
|
||||
0x4c, 0x5f, 0xf1, 0x21,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 128,
|
||||
.digest = {
|
||||
0x70, 0x0c, 0xea, 0xa4, 0x93, 0xd0, 0x56, 0xf0,
|
||||
0x6f, 0xbb, 0x53, 0x42, 0x5b, 0xe3, 0xf2, 0xb0,
|
||||
0x30, 0x66, 0x8e, 0x75,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 129,
|
||||
.digest = {
|
||||
0x15, 0x01, 0xbc, 0xb0, 0xee, 0xd8, 0xeb, 0xa8,
|
||||
0x7d, 0xd9, 0x4d, 0x50, 0x2e, 0x41, 0x30, 0xba,
|
||||
0x41, 0xaa, 0x7b, 0x02,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 256,
|
||||
.digest = {
|
||||
0x98, 0x05, 0x52, 0xf5, 0x0f, 0xf0, 0xd3, 0x97,
|
||||
0x15, 0x8c, 0xa3, 0x9a, 0x2b, 0x4d, 0x67, 0x57,
|
||||
0x29, 0xa0, 0xac, 0x61,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 511,
|
||||
.digest = {
|
||||
0x1f, 0x47, 0xf0, 0xcc, 0xd7, 0xda, 0xa5, 0x3b,
|
||||
0x39, 0xb4, 0x5b, 0xa8, 0x33, 0xd4, 0xca, 0x2f,
|
||||
0xdd, 0xf2, 0x39, 0x89,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 513,
|
||||
.digest = {
|
||||
0xb9, 0x75, 0xe6, 0x57, 0x42, 0x7f, 0x8b, 0x0a,
|
||||
0xcc, 0x53, 0x10, 0x69, 0x45, 0xac, 0xfd, 0x11,
|
||||
0xf7, 0x1f, 0x4e, 0x6f,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 1000,
|
||||
.digest = {
|
||||
0x63, 0x66, 0xcb, 0x44, 0xc1, 0x2c, 0xa2, 0x06,
|
||||
0x5d, 0xb9, 0x8e, 0x31, 0xcb, 0x4f, 0x4e, 0x49,
|
||||
0xe0, 0xfb, 0x3c, 0x4e,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 3333,
|
||||
.digest = {
|
||||
0x35, 0xbc, 0x74, 0xfb, 0x31, 0x9c, 0xd4, 0xdd,
|
||||
0xe8, 0x87, 0xa7, 0x56, 0x3b, 0x08, 0xe5, 0x49,
|
||||
0xe1, 0xe9, 0xc9, 0xa8,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 4096,
|
||||
.digest = {
|
||||
0x43, 0x00, 0xea, 0xcd, 0x4e, 0x7c, 0xe9, 0xe4,
|
||||
0x32, 0xce, 0x25, 0xa8, 0xcd, 0x20, 0xa8, 0xaa,
|
||||
0x7b, 0x63, 0x2c, 0x3c,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 4128,
|
||||
.digest = {
|
||||
0xd0, 0x67, 0x26, 0x0e, 0x22, 0x72, 0xaa, 0x63,
|
||||
0xfc, 0x34, 0x55, 0x07, 0xab, 0xc8, 0x64, 0xb6,
|
||||
0xc4, 0xea, 0xd5, 0x7c,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 4160,
|
||||
.digest = {
|
||||
0x6b, 0xc9, 0x5e, 0xb9, 0x41, 0x19, 0x50, 0x35,
|
||||
0xf1, 0x39, 0xfe, 0xd9, 0x72, 0x6d, 0xd0, 0x55,
|
||||
0xb8, 0x1f, 0x1a, 0x95,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 4224,
|
||||
.digest = {
|
||||
0x70, 0x5d, 0x10, 0x2e, 0x4e, 0x44, 0xc9, 0x80,
|
||||
0x8f, 0xba, 0x13, 0xbc, 0xd0, 0x77, 0x78, 0xc7,
|
||||
0x84, 0xe3, 0x24, 0x43,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 16384,
|
||||
.digest = {
|
||||
0xa8, 0x82, 0xca, 0x08, 0xb4, 0x84, 0x09, 0x13,
|
||||
0xc0, 0x9c, 0x26, 0x18, 0xcf, 0x0f, 0xf3, 0x08,
|
||||
0xff, 0xa1, 0xe4, 0x5d,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const u8 hash_testvec_consolidated[SHA1_DIGEST_SIZE] = {
|
||||
0xe1, 0x72, 0xa5, 0x3c, 0xda, 0xf2, 0xe5, 0x56,
|
||||
0xb8, 0xb5, 0x35, 0x6e, 0xce, 0xc8, 0x37, 0x57,
|
||||
0x31, 0xb4, 0x05, 0xdd,
|
||||
};
|
||||
|
||||
static const u8 hmac_testvec_consolidated[SHA1_DIGEST_SIZE] = {
|
||||
0x9d, 0xe5, 0xb1, 0x43, 0x97, 0x95, 0x16, 0x52,
|
||||
0xa0, 0x7a, 0xc0, 0xe2, 0xc1, 0x60, 0x64, 0x7c,
|
||||
0x24, 0xf9, 0x34, 0xd7,
|
||||
};
|
||||
39
lib/crypto/tests/sha1_kunit.c
Normal file
39
lib/crypto/tests/sha1_kunit.c
Normal file
@@ -0,0 +1,39 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright 2025 Google LLC
|
||||
*/
|
||||
#include <crypto/sha1.h>
|
||||
#include "sha1-testvecs.h"
|
||||
|
||||
#define HASH sha1
|
||||
#define HASH_CTX sha1_ctx
|
||||
#define HASH_SIZE SHA1_DIGEST_SIZE
|
||||
#define HASH_INIT sha1_init
|
||||
#define HASH_UPDATE sha1_update
|
||||
#define HASH_FINAL sha1_final
|
||||
#define HMAC_KEY hmac_sha1_key
|
||||
#define HMAC_CTX hmac_sha1_ctx
|
||||
#define HMAC_PREPAREKEY hmac_sha1_preparekey
|
||||
#define HMAC_INIT hmac_sha1_init
|
||||
#define HMAC_UPDATE hmac_sha1_update
|
||||
#define HMAC_FINAL hmac_sha1_final
|
||||
#define HMAC hmac_sha1
|
||||
#define HMAC_USINGRAWKEY hmac_sha1_usingrawkey
|
||||
#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 = "sha1",
|
||||
.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-1 and HMAC-SHA1");
|
||||
MODULE_LICENSE("GPL");
|
||||
238
lib/crypto/tests/sha224-testvecs.h
Normal file
238
lib/crypto/tests/sha224-testvecs.h
Normal file
@@ -0,0 +1,238 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/* This file was generated by: ./scripts/crypto/gen-hash-testvecs.py sha224 */
|
||||
|
||||
static const struct {
|
||||
size_t data_len;
|
||||
u8 digest[SHA224_DIGEST_SIZE];
|
||||
} hash_testvecs[] = {
|
||||
{
|
||||
.data_len = 0,
|
||||
.digest = {
|
||||
0xd1, 0x4a, 0x02, 0x8c, 0x2a, 0x3a, 0x2b, 0xc9,
|
||||
0x47, 0x61, 0x02, 0xbb, 0x28, 0x82, 0x34, 0xc4,
|
||||
0x15, 0xa2, 0xb0, 0x1f, 0x82, 0x8e, 0xa6, 0x2a,
|
||||
0xc5, 0xb3, 0xe4, 0x2f,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 1,
|
||||
.digest = {
|
||||
0xe3, 0x4d, 0x79, 0x17, 0x75, 0x35, 0xdc, 0xd2,
|
||||
0x27, 0xc9, 0x9d, 0x0b, 0x90, 0x0f, 0x21, 0x5d,
|
||||
0x95, 0xfb, 0x9c, 0x6d, 0xa8, 0xec, 0x19, 0x15,
|
||||
0x12, 0xef, 0xf5, 0x0f,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 2,
|
||||
.digest = {
|
||||
0x81, 0xc7, 0x60, 0x0d, 0x6d, 0x13, 0x75, 0x70,
|
||||
0x4b, 0xc0, 0xab, 0xea, 0x04, 0xe3, 0x78, 0x7e,
|
||||
0x73, 0xb9, 0x0f, 0xb6, 0xae, 0x90, 0xf3, 0x94,
|
||||
0xb2, 0x56, 0xda, 0xc8,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 3,
|
||||
.digest = {
|
||||
0x24, 0xf0, 0x8c, 0x6e, 0x9d, 0xd6, 0x06, 0x80,
|
||||
0x0a, 0x03, 0xee, 0x9b, 0x33, 0xec, 0x83, 0x42,
|
||||
0x2c, 0x8b, 0xe7, 0xc7, 0xc6, 0x04, 0xfb, 0xc6,
|
||||
0xa3, 0x3a, 0x4d, 0xc9,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 16,
|
||||
.digest = {
|
||||
0x1c, 0x08, 0xa8, 0x55, 0x8f, 0xc6, 0x0a, 0xea,
|
||||
0x2f, 0x1b, 0x54, 0xff, 0x8d, 0xd2, 0xa3, 0xc7,
|
||||
0x42, 0xc2, 0x93, 0x3d, 0x73, 0x18, 0x84, 0xba,
|
||||
0x75, 0x49, 0x34, 0xfd,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 32,
|
||||
.digest = {
|
||||
0x45, 0xdd, 0xb5, 0xf0, 0x3c, 0xda, 0xe6, 0xd4,
|
||||
0x6c, 0x86, 0x91, 0x29, 0x11, 0x2f, 0x88, 0x7d,
|
||||
0xd8, 0x3c, 0xa3, 0xd6, 0xdd, 0x1e, 0xac, 0x98,
|
||||
0xff, 0xf0, 0x14, 0x69,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 48,
|
||||
.digest = {
|
||||
0x0b, 0xfb, 0x71, 0x4c, 0x06, 0x7a, 0xd5, 0x89,
|
||||
0x76, 0x0a, 0x43, 0x8b, 0x2b, 0x47, 0x12, 0x56,
|
||||
0xa7, 0x64, 0x33, 0x1d, 0xd3, 0x44, 0x17, 0x95,
|
||||
0x23, 0xe7, 0x53, 0x01,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 49,
|
||||
.digest = {
|
||||
0xc4, 0xae, 0x9c, 0x33, 0xd5, 0x1d, 0xf4, 0xa7,
|
||||
0xfd, 0xb7, 0xd4, 0x6b, 0xc3, 0xeb, 0xa8, 0xbf,
|
||||
0xfb, 0x07, 0x89, 0x4b, 0x07, 0x15, 0x22, 0xec,
|
||||
0xe1, 0x45, 0x84, 0xba,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 63,
|
||||
.digest = {
|
||||
0xad, 0x01, 0x34, 0x2a, 0xe2, 0x3b, 0x58, 0x06,
|
||||
0x9f, 0x20, 0xc8, 0xfb, 0xf3, 0x20, 0x82, 0xa6,
|
||||
0x9f, 0xee, 0x7a, 0xbe, 0xdf, 0xf3, 0x5d, 0x57,
|
||||
0x9b, 0xce, 0x79, 0x96,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 64,
|
||||
.digest = {
|
||||
0xa7, 0xa6, 0x47, 0xf7, 0xed, 0x2a, 0xe5, 0xe3,
|
||||
0xc0, 0x1e, 0x7b, 0x40, 0xe4, 0xf7, 0x40, 0x65,
|
||||
0x42, 0xc1, 0x6f, 0x7d, 0x8d, 0x0d, 0x17, 0x4f,
|
||||
0xd3, 0xbc, 0x0d, 0x85,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 65,
|
||||
.digest = {
|
||||
0xc4, 0x9c, 0xb5, 0x6a, 0x01, 0x2d, 0x10, 0xa9,
|
||||
0x5f, 0xa4, 0x5a, 0xe1, 0xba, 0x40, 0x12, 0x09,
|
||||
0x7b, 0xea, 0xdb, 0xa6, 0x7b, 0xcb, 0x56, 0xf0,
|
||||
0xfd, 0x5b, 0xe2, 0xe7,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 127,
|
||||
.digest = {
|
||||
0x14, 0xda, 0x0e, 0x01, 0xca, 0x78, 0x7d, 0x2d,
|
||||
0x85, 0xa3, 0xca, 0x0e, 0x80, 0xf9, 0x95, 0x10,
|
||||
0xa1, 0x7b, 0xa5, 0xaa, 0xfc, 0x95, 0x05, 0x08,
|
||||
0x53, 0xda, 0x52, 0xee,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 128,
|
||||
.digest = {
|
||||
0xa5, 0x24, 0xc4, 0x54, 0xe1, 0x50, 0xab, 0xee,
|
||||
0x22, 0xc1, 0xa7, 0x27, 0x15, 0x2c, 0x6f, 0xf7,
|
||||
0x4c, 0x31, 0xe5, 0x15, 0x25, 0x4e, 0x71, 0xc6,
|
||||
0x7e, 0xa0, 0x11, 0x5d,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 129,
|
||||
.digest = {
|
||||
0x73, 0xd0, 0x8c, 0xce, 0xed, 0xed, 0x9f, 0xaa,
|
||||
0x21, 0xaf, 0xa2, 0x08, 0x80, 0x16, 0x15, 0x59,
|
||||
0x3f, 0x1d, 0x7f, 0x0a, 0x79, 0x3d, 0x7b, 0x58,
|
||||
0xf8, 0xc8, 0x5c, 0x27,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 256,
|
||||
.digest = {
|
||||
0x31, 0xa7, 0xa1, 0xca, 0x49, 0x72, 0x75, 0xcc,
|
||||
0x6e, 0x02, 0x9e, 0xad, 0xea, 0x86, 0x5c, 0x91,
|
||||
0x02, 0xe4, 0xc9, 0xf9, 0xd3, 0x9e, 0x74, 0x50,
|
||||
0xd8, 0x43, 0x6b, 0x85,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 511,
|
||||
.digest = {
|
||||
0x40, 0x60, 0x8b, 0xb0, 0x03, 0xa9, 0x75, 0xab,
|
||||
0x2d, 0x5b, 0x20, 0x9a, 0x05, 0x72, 0xb7, 0xa8,
|
||||
0xce, 0xf2, 0x4f, 0x66, 0x62, 0xe3, 0x7e, 0x24,
|
||||
0xd6, 0xe2, 0xea, 0xfa,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 513,
|
||||
.digest = {
|
||||
0x4f, 0x5f, 0x9f, 0x1e, 0xb3, 0x66, 0x81, 0xdb,
|
||||
0x41, 0x5d, 0x65, 0x97, 0x00, 0x8d, 0xdc, 0x62,
|
||||
0x03, 0xb0, 0x4d, 0x6b, 0x5c, 0x7f, 0x1e, 0xa0,
|
||||
0xfe, 0xfc, 0x0e, 0xb8,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 1000,
|
||||
.digest = {
|
||||
0x08, 0xa8, 0xa1, 0xc0, 0xd8, 0xf9, 0xb4, 0xaa,
|
||||
0x53, 0x22, 0xa1, 0x73, 0x0b, 0x45, 0xa0, 0x20,
|
||||
0x72, 0xf3, 0xa9, 0xbc, 0x51, 0xd0, 0x20, 0x79,
|
||||
0x69, 0x97, 0xf7, 0xe3,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 3333,
|
||||
.digest = {
|
||||
0xe8, 0x60, 0x5f, 0xb9, 0x12, 0xe1, 0x6b, 0x24,
|
||||
0xc5, 0xe8, 0x43, 0xa9, 0x5c, 0x3f, 0x65, 0xed,
|
||||
0xbe, 0xfd, 0x77, 0xf5, 0x47, 0xf2, 0x75, 0x21,
|
||||
0xc2, 0x8f, 0x54, 0x8f,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 4096,
|
||||
.digest = {
|
||||
0xc7, 0xdf, 0x50, 0x16, 0x10, 0x01, 0xb7, 0xdf,
|
||||
0x34, 0x1d, 0x18, 0xa2, 0xd5, 0xad, 0x1f, 0x50,
|
||||
0xf7, 0xa8, 0x9a, 0x72, 0xfb, 0xfd, 0xd9, 0x1c,
|
||||
0x57, 0xac, 0x08, 0x97,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 4128,
|
||||
.digest = {
|
||||
0xdf, 0x16, 0x76, 0x7f, 0xc0, 0x16, 0x84, 0x63,
|
||||
0xac, 0xcf, 0xd0, 0x78, 0x1e, 0x96, 0x67, 0xc5,
|
||||
0x3c, 0x06, 0xe9, 0xdb, 0x6e, 0x7d, 0xd0, 0x07,
|
||||
0xaa, 0xb1, 0x56, 0xc9,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 4160,
|
||||
.digest = {
|
||||
0x49, 0xec, 0x5c, 0x18, 0xd7, 0x5b, 0xda, 0xed,
|
||||
0x5b, 0x59, 0xde, 0x09, 0x34, 0xb2, 0x49, 0x43,
|
||||
0x62, 0x6a, 0x0a, 0x63, 0x6a, 0x51, 0x08, 0x37,
|
||||
0x8c, 0xb6, 0x29, 0x84,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 4224,
|
||||
.digest = {
|
||||
0x3d, 0xc2, 0xc8, 0x43, 0xcf, 0xb7, 0x33, 0x14,
|
||||
0x04, 0x93, 0xed, 0xe2, 0xcd, 0x8a, 0x69, 0x5c,
|
||||
0x5a, 0xd5, 0x9b, 0x52, 0xdf, 0x48, 0xa7, 0xaa,
|
||||
0x28, 0x2b, 0x5d, 0x27,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 16384,
|
||||
.digest = {
|
||||
0xa7, 0xaf, 0xda, 0x92, 0xe2, 0xe7, 0x61, 0xdc,
|
||||
0xa1, 0x32, 0x53, 0x2a, 0x3f, 0x41, 0x5c, 0x7e,
|
||||
0xc9, 0x89, 0xda, 0x1c, 0xf7, 0x8d, 0x00, 0xbd,
|
||||
0x21, 0x73, 0xb1, 0x69,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const u8 hash_testvec_consolidated[SHA224_DIGEST_SIZE] = {
|
||||
0x9e, 0xb8, 0x82, 0xab, 0x83, 0x37, 0xe4, 0x63,
|
||||
0x84, 0xee, 0x21, 0x15, 0xc2, 0xbb, 0xa3, 0x17,
|
||||
0x8f, 0xc4, 0x99, 0x33, 0xa0, 0x2c, 0x9f, 0xec,
|
||||
0xca, 0xd0, 0xf3, 0x73,
|
||||
};
|
||||
|
||||
static const u8 hmac_testvec_consolidated[SHA224_DIGEST_SIZE] = {
|
||||
0x66, 0x34, 0x79, 0x92, 0x47, 0x0e, 0xcd, 0x70,
|
||||
0xb0, 0x8b, 0x91, 0xcb, 0x94, 0x2f, 0x67, 0x65,
|
||||
0x2f, 0xc9, 0xd2, 0x91, 0x32, 0xaf, 0xf7, 0x5f,
|
||||
0xb6, 0x01, 0x5b, 0xf2,
|
||||
};
|
||||
39
lib/crypto/tests/sha224_kunit.c
Normal file
39
lib/crypto/tests/sha224_kunit.c
Normal file
@@ -0,0 +1,39 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright 2025 Google LLC
|
||||
*/
|
||||
#include <crypto/sha2.h>
|
||||
#include "sha224-testvecs.h"
|
||||
|
||||
#define HASH sha224
|
||||
#define HASH_CTX sha224_ctx
|
||||
#define HASH_SIZE SHA224_DIGEST_SIZE
|
||||
#define HASH_INIT sha224_init
|
||||
#define HASH_UPDATE sha224_update
|
||||
#define HASH_FINAL sha224_final
|
||||
#define HMAC_KEY hmac_sha224_key
|
||||
#define HMAC_CTX hmac_sha224_ctx
|
||||
#define HMAC_PREPAREKEY hmac_sha224_preparekey
|
||||
#define HMAC_INIT hmac_sha224_init
|
||||
#define HMAC_UPDATE hmac_sha224_update
|
||||
#define HMAC_FINAL hmac_sha224_final
|
||||
#define HMAC hmac_sha224
|
||||
#define HMAC_USINGRAWKEY hmac_sha224_usingrawkey
|
||||
#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 = "sha224",
|
||||
.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-224 and HMAC-SHA224");
|
||||
MODULE_LICENSE("GPL");
|
||||
238
lib/crypto/tests/sha256-testvecs.h
Normal file
238
lib/crypto/tests/sha256-testvecs.h
Normal file
@@ -0,0 +1,238 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/* This file was generated by: ./scripts/crypto/gen-hash-testvecs.py sha256 */
|
||||
|
||||
static const struct {
|
||||
size_t data_len;
|
||||
u8 digest[SHA256_DIGEST_SIZE];
|
||||
} hash_testvecs[] = {
|
||||
{
|
||||
.data_len = 0,
|
||||
.digest = {
|
||||
0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
|
||||
0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
|
||||
0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
|
||||
0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 1,
|
||||
.digest = {
|
||||
0x45, 0xf8, 0x3d, 0x17, 0xe1, 0x0b, 0x34, 0xfc,
|
||||
0xa0, 0x1e, 0xb8, 0xf4, 0x45, 0x4d, 0xac, 0x34,
|
||||
0xa7, 0x77, 0xd9, 0x40, 0x4a, 0x46, 0x4e, 0x73,
|
||||
0x2c, 0xf4, 0xab, 0xf2, 0xc0, 0xda, 0x94, 0xc4,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 2,
|
||||
.digest = {
|
||||
0xf9, 0xd3, 0x52, 0x2f, 0xd5, 0xe0, 0x99, 0x15,
|
||||
0x1c, 0xd6, 0xa9, 0x24, 0x4f, 0x40, 0xba, 0x25,
|
||||
0x33, 0x43, 0x3e, 0xe1, 0x78, 0x6a, 0xfe, 0x7d,
|
||||
0x07, 0xe2, 0x29, 0x7b, 0x6d, 0xc5, 0x73, 0xf5,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 3,
|
||||
.digest = {
|
||||
0x71, 0xf7, 0xa1, 0xef, 0x69, 0x86, 0x0e, 0xe4,
|
||||
0x87, 0x25, 0x58, 0x4c, 0x07, 0x2c, 0xfc, 0x60,
|
||||
0xc5, 0xf6, 0xe2, 0x44, 0xaa, 0xfb, 0x41, 0xc7,
|
||||
0x2b, 0xc5, 0x01, 0x8c, 0x39, 0x98, 0x30, 0x37,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 16,
|
||||
.digest = {
|
||||
0x09, 0x95, 0x9a, 0xfa, 0x25, 0x18, 0x86, 0x06,
|
||||
0xfe, 0x65, 0xc9, 0x2f, 0x91, 0x15, 0x74, 0x06,
|
||||
0x6c, 0xbf, 0xef, 0x7b, 0x0b, 0xc7, 0x2c, 0x05,
|
||||
0xdd, 0x17, 0x5d, 0x6f, 0x8a, 0xa5, 0xde, 0x3c,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 32,
|
||||
.digest = {
|
||||
0xe5, 0x52, 0x3c, 0x85, 0xea, 0x1b, 0xe1, 0x6c,
|
||||
0xe0, 0xdb, 0xc3, 0xef, 0xf0, 0xca, 0xc2, 0xe1,
|
||||
0xb9, 0x36, 0xa1, 0x28, 0xb6, 0x9e, 0xf5, 0x6e,
|
||||
0x70, 0xf7, 0xf9, 0xa7, 0x1c, 0xd3, 0x22, 0xd0,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 48,
|
||||
.digest = {
|
||||
0x5f, 0x84, 0xd4, 0xd7, 0x2e, 0x80, 0x09, 0xef,
|
||||
0x1c, 0x77, 0x7c, 0x25, 0x59, 0x63, 0x88, 0x64,
|
||||
0xfd, 0x56, 0xea, 0x23, 0xf4, 0x4f, 0x2e, 0x49,
|
||||
0xcd, 0xb4, 0xaa, 0xc7, 0x5c, 0x8b, 0x75, 0x84,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 49,
|
||||
.digest = {
|
||||
0x22, 0x6e, 0xca, 0xda, 0x00, 0x2d, 0x90, 0x96,
|
||||
0x24, 0xf8, 0x55, 0x17, 0x11, 0xda, 0x42, 0x1c,
|
||||
0x78, 0x4e, 0xbf, 0xd9, 0xc5, 0xcf, 0xf3, 0xe3,
|
||||
0xaf, 0xd3, 0x60, 0xcd, 0xaa, 0xe2, 0xc7, 0x22,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 63,
|
||||
.digest = {
|
||||
0x97, 0xe2, 0x74, 0xdc, 0x6b, 0xa4, 0xaf, 0x32,
|
||||
0x3b, 0x50, 0x6d, 0x80, 0xb5, 0xd3, 0x0c, 0x36,
|
||||
0xea, 0x3f, 0x5d, 0x36, 0xa7, 0x49, 0x51, 0xf3,
|
||||
0xbd, 0x69, 0x68, 0x60, 0x9b, 0xde, 0x73, 0xf5,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 64,
|
||||
.digest = {
|
||||
0x13, 0x74, 0xb1, 0x72, 0xd6, 0x53, 0x48, 0x28,
|
||||
0x42, 0xd8, 0xba, 0x64, 0x20, 0x60, 0xb6, 0x4c,
|
||||
0xc3, 0xac, 0x5d, 0x93, 0x8c, 0xb9, 0xd4, 0xcc,
|
||||
0xb4, 0x9f, 0x31, 0x1f, 0xeb, 0x68, 0x35, 0x58,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 65,
|
||||
.digest = {
|
||||
0xda, 0xbe, 0xd7, 0xbc, 0x6e, 0xe6, 0x5a, 0x57,
|
||||
0xeb, 0x9a, 0x93, 0xaa, 0x66, 0xd0, 0xe0, 0xc4,
|
||||
0x29, 0x7f, 0xe9, 0x3b, 0x8e, 0xdf, 0x81, 0x82,
|
||||
0x8d, 0x15, 0x11, 0x59, 0x4e, 0x13, 0xa5, 0x58,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 127,
|
||||
.digest = {
|
||||
0x8c, 0x1a, 0xba, 0x40, 0x66, 0x94, 0x19, 0xf4,
|
||||
0x2e, 0xa2, 0xae, 0x94, 0x53, 0x18, 0xb6, 0xfd,
|
||||
0xa0, 0x12, 0xc5, 0xef, 0xd5, 0xd6, 0x1b, 0xa1,
|
||||
0x37, 0xea, 0x19, 0x44, 0x35, 0x54, 0x85, 0x74,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 128,
|
||||
.digest = {
|
||||
0xfd, 0x07, 0xd8, 0x77, 0x7d, 0x8b, 0x4f, 0xee,
|
||||
0x60, 0x60, 0x26, 0xef, 0x2a, 0x86, 0xfb, 0x67,
|
||||
0xeb, 0x31, 0x27, 0x03, 0x99, 0x3c, 0xde, 0xe5,
|
||||
0x84, 0x72, 0x71, 0x4c, 0x33, 0x7b, 0x87, 0x13,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 129,
|
||||
.digest = {
|
||||
0x97, 0xc5, 0x58, 0x38, 0x20, 0xc7, 0xde, 0xfa,
|
||||
0xdd, 0x9b, 0x10, 0xc6, 0xc2, 0x2f, 0x94, 0xb5,
|
||||
0xc0, 0x33, 0xc0, 0x20, 0x1c, 0x2f, 0xb4, 0x28,
|
||||
0x5e, 0x36, 0xfa, 0x8c, 0x24, 0x1c, 0x18, 0x27,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 256,
|
||||
.digest = {
|
||||
0x62, 0x17, 0x84, 0x26, 0x98, 0x30, 0x57, 0xca,
|
||||
0x4f, 0x32, 0xd9, 0x09, 0x09, 0x34, 0xe2, 0xcb,
|
||||
0x92, 0x45, 0xd5, 0xeb, 0x8b, 0x9b, 0x3c, 0xd8,
|
||||
0xaa, 0xc7, 0xd2, 0x2b, 0x04, 0xab, 0xb3, 0x35,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 511,
|
||||
.digest = {
|
||||
0x7f, 0xe1, 0x09, 0x78, 0x5d, 0x61, 0xfa, 0x5e,
|
||||
0x9b, 0x8c, 0xb1, 0xa9, 0x09, 0x69, 0xb4, 0x24,
|
||||
0x54, 0xf2, 0x1c, 0xc9, 0x5f, 0xfb, 0x59, 0x9d,
|
||||
0x36, 0x1b, 0x37, 0x44, 0xfc, 0x64, 0x79, 0xb6,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 513,
|
||||
.digest = {
|
||||
0xd2, 0x3b, 0x3a, 0xe7, 0x13, 0x4f, 0xbd, 0x29,
|
||||
0x6b, 0xd2, 0x79, 0x26, 0x6c, 0xd2, 0x22, 0x43,
|
||||
0x25, 0x34, 0x9b, 0x9b, 0x22, 0xb0, 0x9f, 0x61,
|
||||
0x1d, 0xf4, 0xe2, 0x65, 0x68, 0x95, 0x02, 0x6c,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 1000,
|
||||
.digest = {
|
||||
0x0c, 0x34, 0x53, 0x3f, 0x0f, 0x8a, 0x39, 0x8d,
|
||||
0x63, 0xe4, 0x83, 0x6e, 0x11, 0x7d, 0x14, 0x8e,
|
||||
0x5b, 0xf0, 0x4d, 0xca, 0x23, 0x24, 0xb5, 0xd2,
|
||||
0x13, 0x3f, 0xd9, 0xde, 0x84, 0x74, 0x26, 0x59,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 3333,
|
||||
.digest = {
|
||||
0xa8, 0xb8, 0x83, 0x01, 0x1b, 0x38, 0x7a, 0xca,
|
||||
0x59, 0xe9, 0x5b, 0x37, 0x6a, 0xab, 0xb4, 0x85,
|
||||
0x94, 0x73, 0x26, 0x04, 0xef, 0xed, 0xf4, 0x0d,
|
||||
0xd6, 0x09, 0x21, 0x09, 0x96, 0x78, 0xe3, 0xcf,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 4096,
|
||||
.digest = {
|
||||
0x0b, 0x12, 0x66, 0x96, 0x78, 0x4f, 0x2c, 0x35,
|
||||
0xa4, 0xed, 0xbc, 0xb8, 0x30, 0xa6, 0x37, 0x9b,
|
||||
0x94, 0x13, 0xae, 0x86, 0xf0, 0x20, 0xfb, 0x49,
|
||||
0x8f, 0x5d, 0x20, 0x70, 0x60, 0x2b, 0x02, 0x70,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 4128,
|
||||
.digest = {
|
||||
0xe4, 0xbd, 0xe4, 0x3b, 0x85, 0xf4, 0x6f, 0x11,
|
||||
0xad, 0xc4, 0x79, 0xcc, 0x8e, 0x6d, 0x8b, 0x15,
|
||||
0xbb, 0xf9, 0xd3, 0x65, 0xe1, 0xf8, 0x8d, 0x22,
|
||||
0x65, 0x66, 0x66, 0xb3, 0xf5, 0xd0, 0x9c, 0xaf,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 4160,
|
||||
.digest = {
|
||||
0x90, 0x5f, 0xe0, 0xfc, 0xb1, 0xdc, 0x38, 0x1b,
|
||||
0xe5, 0x37, 0x3f, 0xd2, 0xcc, 0x48, 0xc4, 0xbc,
|
||||
0xb4, 0xfd, 0xf7, 0x71, 0x5f, 0x6b, 0xf4, 0xc4,
|
||||
0xa6, 0x08, 0x7e, 0xfc, 0x4e, 0x96, 0xf7, 0xc2,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 4224,
|
||||
.digest = {
|
||||
0x1f, 0x34, 0x0a, 0x3b, 0xdb, 0xf7, 0x7a, 0xdb,
|
||||
0x3d, 0x89, 0x85, 0x0c, 0xd2, 0xf0, 0x0c, 0xbd,
|
||||
0x25, 0x39, 0x14, 0x06, 0x28, 0x0f, 0x6b, 0x5f,
|
||||
0xe3, 0x1f, 0x2a, 0xb6, 0xca, 0x56, 0x41, 0xa1,
|
||||
},
|
||||
},
|
||||
{
|
||||
.data_len = 16384,
|
||||
.digest = {
|
||||
0x7b, 0x01, 0x2d, 0x84, 0x70, 0xee, 0xe0, 0x77,
|
||||
0x3c, 0x17, 0x63, 0xfe, 0x40, 0xd7, 0xfd, 0xa1,
|
||||
0x75, 0x90, 0xb8, 0x3e, 0x50, 0xcd, 0x06, 0xb7,
|
||||
0xb9, 0xb9, 0x2b, 0x91, 0x4f, 0xba, 0xe4, 0x4c,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const u8 hash_testvec_consolidated[SHA256_DIGEST_SIZE] = {
|
||||
0x78, 0x1c, 0xb1, 0x9f, 0xe5, 0xe1, 0xcb, 0x41,
|
||||
0x8b, 0x34, 0x00, 0x33, 0x57, 0xc3, 0x1c, 0x8f,
|
||||
0x5c, 0x84, 0xc7, 0x8b, 0x87, 0x6a, 0x13, 0x29,
|
||||
0x2f, 0xc4, 0x1a, 0x70, 0x5e, 0x40, 0xf2, 0xfe,
|
||||
};
|
||||
|
||||
static const u8 hmac_testvec_consolidated[SHA256_DIGEST_SIZE] = {
|
||||
0x56, 0x96, 0x2e, 0x23, 0x3f, 0x94, 0x89, 0x0d,
|
||||
0x0f, 0x24, 0x36, 0x2e, 0x19, 0x3d, 0xb5, 0xac,
|
||||
0xb8, 0xcd, 0xf1, 0xc9, 0xca, 0xac, 0xee, 0x9d,
|
||||
0x62, 0xe6, 0x81, 0xe5, 0x96, 0xf9, 0x38, 0xf5,
|
||||
};
|
||||
39
lib/crypto/tests/sha256_kunit.c
Normal file
39
lib/crypto/tests/sha256_kunit.c
Normal file
@@ -0,0 +1,39 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright 2025 Google LLC
|
||||
*/
|
||||
#include <crypto/sha2.h>
|
||||
#include "sha256-testvecs.h"
|
||||
|
||||
#define HASH sha256
|
||||
#define HASH_CTX sha256_ctx
|
||||
#define HASH_SIZE SHA256_DIGEST_SIZE
|
||||
#define HASH_INIT sha256_init
|
||||
#define HASH_UPDATE sha256_update
|
||||
#define HASH_FINAL sha256_final
|
||||
#define HMAC_KEY hmac_sha256_key
|
||||
#define HMAC_CTX hmac_sha256_ctx
|
||||
#define HMAC_PREPAREKEY hmac_sha256_preparekey
|
||||
#define HMAC_INIT hmac_sha256_init
|
||||
#define HMAC_UPDATE hmac_sha256_update
|
||||
#define HMAC_FINAL hmac_sha256_final
|
||||
#define HMAC hmac_sha256
|
||||
#define HMAC_USINGRAWKEY hmac_sha256_usingrawkey
|
||||
#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 = "sha256",
|
||||
.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-256 and HMAC-SHA256");
|
||||
MODULE_LICENSE("GPL");
|
||||
290
lib/crypto/tests/sha384-testvecs.h
Normal file
290
lib/crypto/tests/sha384-testvecs.h
Normal file
@@ -0,0 +1,290 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/* This file was generated by: ./scripts/crypto/gen-hash-testvecs.py sha384 */
|
||||
|
||||
static const struct {
|
||||
size_t data_len;
|
||||
u8 digest[SHA384_DIGEST_SIZE];
|
||||
} hash_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 u8 hash_testvec_consolidated[SHA384_DIGEST_SIZE] = {
|
||||
0xfc, 0xcb, 0xe6, 0x42, 0xf0, 0x9e, 0x2b, 0x77,
|
||||
0x7b, 0x62, 0xe8, 0x70, 0x86, 0xbf, 0xaf, 0x3c,
|
||||
0xbb, 0x02, 0xd9, 0x86, 0xdc, 0xba, 0xd3, 0xa4,
|
||||
0x0d, 0x8d, 0xb3, 0x2d, 0x0b, 0xa3, 0x84, 0x04,
|
||||
0x7c, 0x16, 0x37, 0xaf, 0xba, 0x1e, 0xd4, 0x2f,
|
||||
0x4c, 0x57, 0x55, 0x86, 0x52, 0x47, 0x9a, 0xec,
|
||||
};
|
||||
|
||||
static const u8 hmac_testvec_consolidated[SHA384_DIGEST_SIZE] = {
|
||||
0x82, 0xcf, 0x7d, 0x80, 0x71, 0xdb, 0x91, 0x09,
|
||||
0x67, 0xe8, 0x44, 0x4a, 0x0d, 0x03, 0xb1, 0xf9,
|
||||
0x62, 0xde, 0x4e, 0xbb, 0x1f, 0x41, 0xcd, 0x62,
|
||||
0x39, 0x6b, 0x2d, 0x44, 0x0e, 0xde, 0x98, 0x73,
|
||||
0xdd, 0xeb, 0x9d, 0x53, 0xfb, 0xee, 0xd1, 0xc3,
|
||||
0x96, 0xdb, 0xfc, 0x2a, 0x38, 0x90, 0x02, 0x53,
|
||||
};
|
||||
39
lib/crypto/tests/sha384_kunit.c
Normal file
39
lib/crypto/tests/sha384_kunit.c
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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 HMAC_KEY hmac_sha384_key
|
||||
#define HMAC_CTX hmac_sha384_ctx
|
||||
#define HMAC_PREPAREKEY 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
|
||||
#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 = "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");
|
||||
342
lib/crypto/tests/sha512-testvecs.h
Normal file
342
lib/crypto/tests/sha512-testvecs.h
Normal file
@@ -0,0 +1,342 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/* This file was generated by: ./scripts/crypto/gen-hash-testvecs.py sha512 */
|
||||
|
||||
static const struct {
|
||||
size_t data_len;
|
||||
u8 digest[SHA512_DIGEST_SIZE];
|
||||
} hash_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 u8 hash_testvec_consolidated[SHA512_DIGEST_SIZE] = {
|
||||
0x5b, 0x9d, 0xf9, 0xab, 0x8c, 0x8e, 0x52, 0xdb,
|
||||
0x02, 0xa0, 0x4c, 0x24, 0x2d, 0xc4, 0xa8, 0x4e,
|
||||
0x9c, 0x93, 0x2f, 0x72, 0xa8, 0x75, 0xfb, 0xb5,
|
||||
0xdb, 0xef, 0x52, 0xc6, 0xa3, 0xfe, 0xeb, 0x6b,
|
||||
0x92, 0x79, 0x18, 0x05, 0xf6, 0xd7, 0xaf, 0x7b,
|
||||
0x36, 0xfc, 0x83, 0x2c, 0x7e, 0x7b, 0x59, 0x8b,
|
||||
0xf9, 0x81, 0xaa, 0x98, 0x38, 0x11, 0x97, 0x56,
|
||||
0x34, 0xe5, 0x2a, 0x4b, 0xf2, 0x9e, 0xf3, 0xdb,
|
||||
};
|
||||
|
||||
static const u8 hmac_testvec_consolidated[SHA512_DIGEST_SIZE] = {
|
||||
0x40, 0xe7, 0xbc, 0x03, 0xdf, 0x22, 0xd4, 0x76,
|
||||
0x66, 0x45, 0xf8, 0x1d, 0x25, 0xdf, 0xbe, 0xa2,
|
||||
0x93, 0x06, 0x8c, 0x1d, 0x14, 0x23, 0x9b, 0x5c,
|
||||
0xfa, 0xac, 0xdf, 0xbd, 0xa2, 0x24, 0xe5, 0xf7,
|
||||
0xdc, 0xf7, 0xae, 0x96, 0xc1, 0x34, 0xe5, 0x24,
|
||||
0x16, 0x24, 0xdc, 0xee, 0x4f, 0x62, 0x1c, 0x67,
|
||||
0x4e, 0x02, 0x31, 0x4b, 0x9b, 0x65, 0x25, 0xeb,
|
||||
0x32, 0x2e, 0x24, 0xfb, 0xcd, 0x2b, 0x59, 0xd8,
|
||||
};
|
||||
39
lib/crypto/tests/sha512_kunit.c
Normal file
39
lib/crypto/tests/sha512_kunit.c
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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 HMAC_KEY hmac_sha512_key
|
||||
#define HMAC_CTX hmac_sha512_ctx
|
||||
#define HMAC_PREPAREKEY 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
|
||||
#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 = "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");
|
||||
147
scripts/crypto/gen-hash-testvecs.py
Executable file
147
scripts/crypto/gen-hash-testvecs.py
Executable file
@@ -0,0 +1,147 @@
|
||||
#!/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]
|
||||
|
||||
# Generate the given number of random bytes, using the length itself as the seed
|
||||
# for a simple linear congruential generator (LCG). The C test code uses the
|
||||
# same LCG with the same seeding strategy to reconstruct the data, ensuring
|
||||
# reproducibility without explicitly storing the data in the test vectors.
|
||||
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)
|
||||
|
||||
POLY1305_KEY_SIZE = 32
|
||||
|
||||
# A straightforward, unoptimized implementation of Poly1305.
|
||||
# Reference: https://cr.yp.to/mac/poly1305-20050329.pdf
|
||||
class Poly1305:
|
||||
def __init__(self, key):
|
||||
assert len(key) == POLY1305_KEY_SIZE
|
||||
self.h = 0
|
||||
rclamp = 0x0ffffffc0ffffffc0ffffffc0fffffff
|
||||
self.r = int.from_bytes(key[:16], byteorder='little') & rclamp
|
||||
self.s = int.from_bytes(key[16:], byteorder='little')
|
||||
|
||||
# Note: this supports partial blocks only at the end.
|
||||
def update(self, data):
|
||||
for i in range(0, len(data), 16):
|
||||
chunk = data[i:i+16]
|
||||
c = int.from_bytes(chunk, byteorder='little') + 2**(8 * len(chunk))
|
||||
self.h = ((self.h + c) * self.r) % (2**130 - 5)
|
||||
return self
|
||||
|
||||
# Note: gen_additional_poly1305_testvecs() relies on this being
|
||||
# nondestructive, i.e. not changing any field of self.
|
||||
def digest(self):
|
||||
m = (self.h + self.s) % 2**128
|
||||
return m.to_bytes(16, byteorder='little')
|
||||
|
||||
def hash_init(alg):
|
||||
if alg == 'poly1305':
|
||||
# Use a fixed random key here, to present Poly1305 as an unkeyed hash.
|
||||
# This allows all the test cases for unkeyed hashes to work on Poly1305.
|
||||
return Poly1305(rand_bytes(POLY1305_KEY_SIZE))
|
||||
return hashlib.new(alg)
|
||||
|
||||
def hash_update(ctx, data):
|
||||
ctx.update(data)
|
||||
|
||||
def hash_final(ctx):
|
||||
return ctx.digest()
|
||||
|
||||
def compute_hash(alg, data):
|
||||
ctx = hash_init(alg)
|
||||
hash_update(ctx, data)
|
||||
return hash_final(ctx)
|
||||
|
||||
def print_bytes(prefix, value, bytes_per_line):
|
||||
for i in range(0, len(value), bytes_per_line):
|
||||
line = prefix + ''.join(f'0x{b:02x}, ' for b in value[i:i+bytes_per_line])
|
||||
print(f'{line.rstrip()}')
|
||||
|
||||
def print_static_u8_array_definition(name, value):
|
||||
print('')
|
||||
print(f'static const u8 {name} = {{')
|
||||
print_bytes('\t', value, 8)
|
||||
print('};')
|
||||
|
||||
def print_c_struct_u8_array_field(name, value):
|
||||
print(f'\t\t.{name} = {{')
|
||||
print_bytes('\t\t\t', value, 8)
|
||||
print('\t\t},')
|
||||
|
||||
def gen_unkeyed_testvecs(alg):
|
||||
print('')
|
||||
print('static const struct {')
|
||||
print('\tsize_t data_len;')
|
||||
print(f'\tu8 digest[{alg.upper()}_DIGEST_SIZE];')
|
||||
print('} hash_testvecs[] = {')
|
||||
for data_len in DATA_LENS:
|
||||
data = rand_bytes(data_len)
|
||||
print('\t{')
|
||||
print(f'\t\t.data_len = {data_len},')
|
||||
print_c_struct_u8_array_field('digest', compute_hash(alg, data))
|
||||
print('\t},')
|
||||
print('};')
|
||||
|
||||
data = rand_bytes(4096)
|
||||
ctx = hash_init(alg)
|
||||
for data_len in range(len(data) + 1):
|
||||
hash_update(ctx, compute_hash(alg, data[:data_len]))
|
||||
print_static_u8_array_definition(
|
||||
f'hash_testvec_consolidated[{alg.upper()}_DIGEST_SIZE]',
|
||||
hash_final(ctx))
|
||||
|
||||
def gen_hmac_testvecs(alg):
|
||||
ctx = hmac.new(rand_bytes(32), digestmod=alg)
|
||||
data = rand_bytes(4096)
|
||||
for data_len in range(len(data) + 1):
|
||||
ctx.update(data[:data_len])
|
||||
key_len = data_len % 293
|
||||
key = rand_bytes(key_len)
|
||||
mac = hmac.digest(key, data[:data_len], alg)
|
||||
ctx.update(mac)
|
||||
print_static_u8_array_definition(
|
||||
f'hmac_testvec_consolidated[{alg.upper()}_DIGEST_SIZE]',
|
||||
ctx.digest())
|
||||
|
||||
def gen_additional_poly1305_testvecs():
|
||||
key = b'\xff' * POLY1305_KEY_SIZE
|
||||
data = b''
|
||||
ctx = Poly1305(key)
|
||||
for _ in range(32):
|
||||
for j in range(0, 4097, 16):
|
||||
ctx.update(b'\xff' * j)
|
||||
data += ctx.digest()
|
||||
print_static_u8_array_definition(
|
||||
'poly1305_allones_macofmacs[POLY1305_DIGEST_SIZE]',
|
||||
Poly1305(key).update(data).digest())
|
||||
|
||||
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, or poly1305.\n')
|
||||
sys.stderr.write('Example: gen-hash-testvecs.py sha512\n')
|
||||
sys.exit(1)
|
||||
|
||||
alg = sys.argv[1]
|
||||
print('/* SPDX-License-Identifier: GPL-2.0-or-later */')
|
||||
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:
|
||||
gen_hmac_testvecs(alg)
|
||||
Reference in New Issue
Block a user