// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright 2025 Google LLC
 */
#include <crypto/gf128hash.h>
#include "polyval-testvecs.h"

/*
 * A fixed key used when presenting POLYVAL as an unkeyed hash function in order
 * to reuse hash-test-template.h.  At the beginning of the test suite, this is
 * initialized to a key prepared from bytes generated from a fixed seed.
 */
static struct polyval_key test_key;

static void polyval_init_withtestkey(struct polyval_ctx *ctx)
{
	polyval_init(ctx, &test_key);
}

static void polyval_withtestkey(const u8 *data, size_t len,
				u8 out[POLYVAL_BLOCK_SIZE])
{
	polyval(&test_key, data, len, out);
}

/* Generate the HASH_KUNIT_CASES using hash-test-template.h. */
#define HASH polyval_withtestkey
#define HASH_CTX polyval_ctx
#define HASH_SIZE POLYVAL_BLOCK_SIZE
#define HASH_INIT polyval_init_withtestkey
#define HASH_UPDATE polyval_update
#define HASH_FINAL polyval_final
#include "hash-test-template.h"

/*
 * Test an example from RFC8452 ("AES-GCM-SIV: Nonce Misuse-Resistant
 * Authenticated Encryption") to ensure compatibility with that.
 */
static void test_polyval_rfc8452_testvec(struct kunit *test)
{
	static const u8 raw_key[POLYVAL_BLOCK_SIZE] =
		"\x31\x07\x28\xd9\x91\x1f\x1f\x38"
		"\x37\xb2\x43\x16\xc3\xfa\xb9\xa0";
	static const u8 data[48] =
		"\x65\x78\x61\x6d\x70\x6c\x65\x00"
		"\x00\x00\x00\x00\x00\x00\x00\x00"
		"\x48\x65\x6c\x6c\x6f\x20\x77\x6f"
		"\x72\x6c\x64\x00\x00\x00\x00\x00"
		"\x38\x00\x00\x00\x00\x00\x00\x00"
		"\x58\x00\x00\x00\x00\x00\x00\x00";
	static const u8 expected_hash[POLYVAL_BLOCK_SIZE] =
		"\xad\x7f\xcf\x0b\x51\x69\x85\x16"
		"\x62\x67\x2f\x3c\x5f\x95\x13\x8f";
	u8 hash[POLYVAL_BLOCK_SIZE];
	struct polyval_key key;

	polyval_preparekey(&key, raw_key);
	polyval(&key, data, sizeof(data), hash);
	KUNIT_ASSERT_MEMEQ(test, hash, expected_hash, sizeof(hash));
}

/*
 * Test a key and messages containing all one bits.  This is useful to detect
 * overflow bugs in implementations that emulate carryless multiplication using
 * a series of standard multiplications with the bits spread out.
 */
static void test_polyval_allones_key_and_message(struct kunit *test)
{
	const size_t max_len = 4096;
	u8 *data = alloc_buf(test, max_len);
	struct polyval_key key;
	struct polyval_ctx hashofhashes_ctx;
	u8 hash[POLYVAL_BLOCK_SIZE];

	memset(data, 0xff, max_len);

	polyval_preparekey(&key, data);
	polyval_init(&hashofhashes_ctx, &key);
	for (size_t len = 0; len <= max_len; len += 16) {
		polyval(&key, data, len, hash);
		polyval_update(&hashofhashes_ctx, hash, sizeof(hash));
	}
	polyval_final(&hashofhashes_ctx, hash);
	KUNIT_ASSERT_MEMEQ(test, hash, polyval_allones_hashofhashes,
			   sizeof(hash));
}

#define MAX_LEN_FOR_KEY_CHECK 1024

/*
 * Given two prepared keys which should be identical (but may differ in
 * alignment and/or whether they are followed by a guard page or not), verify
 * that they produce consistent results on various data lengths.
 */
static void check_key_consistency(struct kunit *test,
				  const struct polyval_key *key1,
				  const struct polyval_key *key2)
{
	u8 *data = alloc_buf(test, MAX_LEN_FOR_KEY_CHECK);
	u8 hash1[POLYVAL_BLOCK_SIZE];
	u8 hash2[POLYVAL_BLOCK_SIZE];

	rand_bytes(data, MAX_LEN_FOR_KEY_CHECK);
	KUNIT_ASSERT_MEMEQ(test, key1, key2, sizeof(*key1));

	for (int i = 0; i < 100; i++) {
		size_t len = rand_length(MAX_LEN_FOR_KEY_CHECK);

		polyval(key1, data, len, hash1);
		polyval(key2, data, len, hash2);
		KUNIT_ASSERT_MEMEQ(test, hash1, hash2, sizeof(hash1));
	}
}

/* Test that no buffer overreads occur on either raw_key or polyval_key. */
static void test_polyval_with_guarded_key(struct kunit *test)
{
	u8 raw_key[POLYVAL_BLOCK_SIZE];
	u8 *guarded_raw_key = alloc_guarded_buf(test, sizeof(raw_key));
	struct polyval_key key1, key2;
	struct polyval_key *guarded_key =
		alloc_guarded_buf(test, sizeof(*guarded_key));

	/* Prepare with regular buffers. */
	rand_bytes(raw_key, sizeof(raw_key));
	polyval_preparekey(&key1, raw_key);

	/* Prepare with guarded raw_key, then check that it works. */
	memcpy(guarded_raw_key, raw_key, sizeof(raw_key));
	polyval_preparekey(&key2, guarded_raw_key);
	check_key_consistency(test, &key1, &key2);

	/* Prepare guarded polyval_key, then check that it works. */
	polyval_preparekey(guarded_key, raw_key);
	check_key_consistency(test, &key1, guarded_key);
}

/*
 * Test that polyval_key only needs to be aligned to
 * __alignof__(struct polyval_key), i.e. 8 bytes.  The assembly code may prefer
 * 16-byte or higher alignment, but it mustn't require it.
 */
static void test_polyval_with_minimally_aligned_key(struct kunit *test)
{
	u8 raw_key[POLYVAL_BLOCK_SIZE];
	struct polyval_key key;
	const size_t align = __alignof__(struct polyval_key);
	u8 *key_buf = alloc_buf(test, sizeof(struct polyval_key) + 3 * align);
	struct polyval_key *minaligned_key =
		(struct polyval_key *)(PTR_ALIGN(key_buf, 2 * align) + align);

	KUNIT_ASSERT_TRUE(test, IS_ALIGNED((uintptr_t)minaligned_key, align));
	KUNIT_ASSERT_TRUE(test,
			  !IS_ALIGNED((uintptr_t)minaligned_key, 2 * align));

	rand_bytes(raw_key, sizeof(raw_key));
	polyval_preparekey(&key, raw_key);
	polyval_preparekey(minaligned_key, raw_key);
	check_key_consistency(test, &key, minaligned_key);
}

struct polyval_irq_test_state {
	struct polyval_key expected_key;
	u8 raw_key[POLYVAL_BLOCK_SIZE];
};

static bool polyval_irq_test_func(void *state_)
{
	struct polyval_irq_test_state *state = state_;
	struct polyval_key key;

	polyval_preparekey(&key, state->raw_key);
	return memcmp(&key, &state->expected_key, sizeof(key)) == 0;
}

/*
 * Test that polyval_preparekey() produces the same output regardless of whether
 * FPU or vector registers are usable when it is called.
 */
static void test_polyval_preparekey_in_irqs(struct kunit *test)
{
	struct polyval_irq_test_state state;

	rand_bytes(state.raw_key, sizeof(state.raw_key));
	polyval_preparekey(&state.expected_key, state.raw_key);
	kunit_run_irq_test(test, polyval_irq_test_func, 200000, &state);
}

static int polyval_suite_init(struct kunit_suite *suite)
{
	u8 raw_key[POLYVAL_BLOCK_SIZE];

	rand_bytes_seeded_from_len(raw_key, sizeof(raw_key));
	polyval_preparekey(&test_key, raw_key);
	return 0;
}

static struct kunit_case polyval_test_cases[] = {
	HASH_KUNIT_CASES,
	KUNIT_CASE(test_polyval_rfc8452_testvec),
	KUNIT_CASE(test_polyval_allones_key_and_message),
	KUNIT_CASE(test_polyval_with_guarded_key),
	KUNIT_CASE(test_polyval_with_minimally_aligned_key),
	KUNIT_CASE(test_polyval_preparekey_in_irqs),
	KUNIT_CASE(benchmark_hash),
	{},
};

static struct kunit_suite polyval_test_suite = {
	.name = "polyval",
	.test_cases = polyval_test_cases,
	.suite_init = polyval_suite_init,
};
kunit_test_suite(polyval_test_suite);

MODULE_DESCRIPTION("KUnit tests and benchmark for POLYVAL");
MODULE_LICENSE("GPL");
