mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 03:35:32 -04:00
lib/crypto: tests: Create test-utils.h
Move hash-test-template's test RNG code and the buffer allocation code from various test suites into a header test-utils.h. This allows them to be shared by other test suites. Reviewed-by: Ard Biesheuvel <ardb@kernel.org> Link: https://patch.msgid.link/20260802233005.161467-2-ebiggers@kernel.org Signed-off-by: Eric Biggers <ebiggers@kernel.org>
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include "test-utils.h"
|
||||
|
||||
struct chacha20poly1305_testvec {
|
||||
const u8 *input, *output, *assoc, *nonce, *key;
|
||||
@@ -8890,11 +8890,8 @@ static void test_chacha20poly1305(struct kunit *test)
|
||||
bool ret;
|
||||
struct scatterlist sg_src[3];
|
||||
|
||||
computed_output = kunit_kmalloc(test, MAXIMUM_TEST_BUFFER_LEN,
|
||||
GFP_KERNEL);
|
||||
input = kunit_kmalloc(test, MAXIMUM_TEST_BUFFER_LEN, GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, computed_output);
|
||||
KUNIT_ASSERT_NOT_NULL(test, input);
|
||||
computed_output = alloc_buf(test, MAXIMUM_TEST_BUFFER_LEN);
|
||||
input = alloc_buf(test, MAXIMUM_TEST_BUFFER_LEN);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(chacha20poly1305_enc_vectors); ++i) {
|
||||
memset(computed_output, 0, MAXIMUM_TEST_BUFFER_LEN);
|
||||
|
||||
@@ -8,69 +8,13 @@
|
||||
#include <kunit/run-in-irq-context.h>
|
||||
#include <kunit/test.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include "test-utils.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)
|
||||
{
|
||||
/*
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <kunit/test.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/unaligned.h>
|
||||
#include "test-utils.h"
|
||||
|
||||
#define Q 8380417 /* The prime q = 2^23 - 2^13 + 1 */
|
||||
|
||||
@@ -60,14 +61,6 @@ static void do_mldsa_and_assert_success(struct kunit *test,
|
||||
KUNIT_ASSERT_EQ(test, err, 0);
|
||||
}
|
||||
|
||||
static u8 *kunit_kmemdup_or_fail(struct kunit *test, const u8 *src, size_t len)
|
||||
{
|
||||
u8 *dst = kunit_kmalloc(test, len, GFP_KERNEL);
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, dst);
|
||||
return memcpy(dst, src, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test that changing coefficients in a valid signature's z vector results in
|
||||
* the following behavior from mldsa_verify():
|
||||
@@ -83,7 +76,7 @@ static u8 *kunit_kmemdup_or_fail(struct kunit *test, const u8 *src, size_t len)
|
||||
static void test_mldsa_z_range(struct kunit *test,
|
||||
const struct mldsa_testvector *tv)
|
||||
{
|
||||
u8 *sig = kunit_kmemdup_or_fail(test, tv->sig, tv->sig_len);
|
||||
u8 *sig = memdup_buf(test, tv->sig, tv->sig_len);
|
||||
const int lambda = params[tv->alg].lambda;
|
||||
const s32 gamma1 = params[tv->alg].gamma1;
|
||||
const int beta = params[tv->alg].beta;
|
||||
@@ -146,7 +139,7 @@ static void test_mldsa_bad_hints(struct kunit *test,
|
||||
{
|
||||
const int omega = params[tv->alg].omega;
|
||||
const int k = params[tv->alg].k;
|
||||
u8 *sig = kunit_kmemdup_or_fail(test, tv->sig, tv->sig_len);
|
||||
u8 *sig = memdup_buf(test, tv->sig, tv->sig_len);
|
||||
/* Pointer to the encoded hint vector in the signature */
|
||||
u8 *hintvec = &sig[tv->sig_len - omega - k];
|
||||
u8 h;
|
||||
@@ -202,9 +195,9 @@ static void test_mldsa_mutation(struct kunit *test,
|
||||
const int msg_len = tv->msg_len;
|
||||
const int pk_len = tv->pk_len;
|
||||
const int num_iter = 200;
|
||||
u8 *sig = kunit_kmemdup_or_fail(test, tv->sig, sig_len);
|
||||
u8 *msg = kunit_kmemdup_or_fail(test, tv->msg, msg_len);
|
||||
u8 *pk = kunit_kmemdup_or_fail(test, tv->pk, pk_len);
|
||||
u8 *sig = memdup_buf(test, tv->sig, sig_len);
|
||||
u8 *msg = memdup_buf(test, tv->msg, msg_len);
|
||||
u8 *pk = memdup_buf(test, tv->pk, pk_len);
|
||||
|
||||
/* Initially the signature is valid. */
|
||||
do_mldsa_and_assert_success(test, tv);
|
||||
|
||||
@@ -5,14 +5,13 @@
|
||||
#include <crypto/nh.h>
|
||||
#include <kunit/test.h>
|
||||
#include "nh-testvecs.h"
|
||||
#include "test-utils.h"
|
||||
|
||||
static void test_nh(struct kunit *test)
|
||||
{
|
||||
u32 *key = kunit_kmalloc(test, NH_KEY_BYTES, GFP_KERNEL);
|
||||
u32 *key = memdup_buf(test, nh_test_key, NH_KEY_BYTES);
|
||||
__le64 hash[NH_NUM_PASSES];
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, key);
|
||||
memcpy(key, nh_test_key, NH_KEY_BYTES);
|
||||
le32_to_cpu_array(key, NH_KEY_WORDS);
|
||||
|
||||
nh(key, nh_test_msg, 16, hash);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
#include <crypto/sha2.h>
|
||||
#include "sha256-testvecs.h"
|
||||
#include "test-utils.h"
|
||||
|
||||
/* Generate the HASH_KUNIT_CASES using hash-test-template.h. */
|
||||
#define HASH sha256
|
||||
@@ -22,26 +23,6 @@
|
||||
#define HMAC_USINGRAWKEY hmac_sha256_usingrawkey
|
||||
#include "hash-test-template.h"
|
||||
|
||||
static void free_guarded_buf(void *buf)
|
||||
{
|
||||
vfree(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a KUnit-managed buffer that has length @len bytes immediately
|
||||
* followed by an unmapped page, and assert that the allocation succeeds.
|
||||
*/
|
||||
static void *alloc_guarded_buf(struct kunit *test, size_t len)
|
||||
{
|
||||
size_t full_len = round_up(len, PAGE_SIZE);
|
||||
void *buf = vmalloc(full_len);
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, buf);
|
||||
KUNIT_ASSERT_EQ(test, 0,
|
||||
kunit_add_action_or_reset(test, free_guarded_buf, buf));
|
||||
return buf + full_len - len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test for sha256_finup_2x(). Specifically, choose various data lengths and
|
||||
* salt lengths, and for each one, verify that sha256_finup_2x() produces the
|
||||
|
||||
111
lib/crypto/tests/test-utils.h
Normal file
111
lib/crypto/tests/test-utils.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Test utility functions shared by the crypto library tests.
|
||||
*
|
||||
* For now this is simply a header that's included into the KUnit test suites
|
||||
* that need it. If this gets too large it could be made its own translation
|
||||
* unit and libcrypto_test_utils module, but that seems overkill for now.
|
||||
*/
|
||||
#ifndef LIB_CRYPTO_TEST_UTILS_H
|
||||
#define LIB_CRYPTO_TEST_UTILS_H
|
||||
|
||||
#include <kunit/test.h>
|
||||
#include <linux/math.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
static u64 random_seed;
|
||||
|
||||
static __maybe_unused void action_free_guarded_buf(void *buf)
|
||||
{
|
||||
vfree(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a KUnit-managed buffer that has length @size bytes (> 0) immediately
|
||||
* followed by an unmapped page, and assert that the allocation succeeds.
|
||||
*/
|
||||
static __maybe_unused void *alloc_guarded_buf(struct kunit *test, size_t size)
|
||||
{
|
||||
size_t full_size = round_up(size, PAGE_SIZE);
|
||||
void *buf = vmalloc(full_size);
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, buf);
|
||||
KUNIT_ASSERT_EQ(test, 0,
|
||||
kunit_add_action_or_reset(test, action_free_guarded_buf,
|
||||
buf));
|
||||
return buf + full_size - size;
|
||||
}
|
||||
|
||||
static __maybe_unused void *alloc_buf(struct kunit *test, size_t size)
|
||||
{
|
||||
void *buf = kunit_kmalloc(test, size, GFP_KERNEL);
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static __maybe_unused void *memdup_buf(struct kunit *test, const void *src,
|
||||
size_t size)
|
||||
{
|
||||
void *dst = alloc_buf(test, size);
|
||||
|
||||
return memcpy(dst, src, size);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 __maybe_unused u32 rand32(void)
|
||||
{
|
||||
random_seed = (random_seed * 25214903917 + 11) & ((1ULL << 48) - 1);
|
||||
return random_seed >> 16;
|
||||
}
|
||||
|
||||
static __maybe_unused void rand_bytes(u8 *out, size_t len)
|
||||
{
|
||||
for (size_t i = 0; i < len; i++)
|
||||
out[i] = rand32();
|
||||
}
|
||||
|
||||
static __maybe_unused void rand_bytes_seeded_from_len(u8 *out, size_t len)
|
||||
{
|
||||
random_seed = len;
|
||||
rand_bytes(out, len);
|
||||
}
|
||||
|
||||
static __maybe_unused bool rand_bool(void)
|
||||
{
|
||||
return rand32() % 2;
|
||||
}
|
||||
|
||||
/* Generate a random length, preferring small lengths. */
|
||||
static __maybe_unused 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 __maybe_unused size_t rand_offset(size_t max_offset)
|
||||
{
|
||||
return min(rand32() % 128, max_offset);
|
||||
}
|
||||
|
||||
#endif /* LIB_CRYPTO_TEST_UTILS_H */
|
||||
Reference in New Issue
Block a user