// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * GF(2^128) polynomial hashing: GHASH and POLYVAL
 *
 * Copyright 2025 Google LLC
 */

#include <crypto/gf128hash.h>
#include <linux/export.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/unaligned.h>

/*
 * GHASH and POLYVAL are almost-XOR-universal hash functions.  They interpret
 * the message as the coefficients of a polynomial in the finite field GF(2^128)
 * and evaluate that polynomial at a secret point.
 *
 * Neither GHASH nor POLYVAL is a cryptographic hash function.  They should be
 * used only by algorithms that are specifically designed to use them.
 *
 * GHASH is the older variant, defined as part of GCM in NIST SP 800-38D
 * (https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-38d.pdf).
 * GHASH is hard to implement directly, due to its backwards mapping between
 * bits and polynomial coefficients.  GHASH implementations typically pre and
 * post-process the inputs and outputs (mainly by byte-swapping) to convert the
 * GHASH computation into an equivalent computation over a different,
 * easier-to-use representation of GF(2^128).
 *
 * POLYVAL is a newer GF(2^128) polynomial hash, originally defined as part of
 * AES-GCM-SIV (https://datatracker.ietf.org/doc/html/rfc8452) and also used by
 * HCTR2 (https://eprint.iacr.org/2021/1441.pdf).  It uses that easier-to-use
 * field representation directly, eliminating the data conversion steps.
 *
 * This file provides library APIs for GHASH and POLYVAL.  These APIs can
 * delegate to either a generic implementation or an architecture-optimized
 * implementation.  Due to the mathematical relationship between GHASH and
 * POLYVAL, in some cases code for one is reused with the other.
 *
 * For the generic implementation, we don't use the traditional table approach
 * to GF(2^128) multiplication.  That approach is not constant-time and requires
 * a lot of memory.  Instead, we use a different approach which emulates
 * carryless multiplication using standard multiplications by spreading the data
 * bits apart using "holes".  This allows the carries to spill harmlessly.  This
 * approach is borrowed from BoringSSL, which in turn credits BearSSL's
 * documentation (https://bearssl.org/constanttime.html#ghash-for-gcm) for the
 * "holes" trick and a presentation by Shay Gueron
 * (https://crypto.stanford.edu/RealWorldCrypto/slides/gueron.pdf) for the
 * 256-bit => 128-bit reduction algorithm.
 */

#ifdef CONFIG_ARCH_SUPPORTS_INT128

/* Do a 64 x 64 => 128 bit carryless multiplication. */
static void clmul64(u64 a, u64 b, u64 *out_lo, u64 *out_hi)
{
	/*
	 * With 64-bit multiplicands and one term every 4 bits, there would be
	 * up to 64 / 4 = 16 one bits per column when each multiplication is
	 * written out as a series of additions in the schoolbook manner.
	 * Unfortunately, that doesn't work since the value 16 is 1 too large to
	 * fit in 4 bits.  Carries would sometimes overflow into the next term.
	 *
	 * Using one term every 5 bits would work.  However, that would cost
	 * 5 x 5 = 25 multiplications instead of 4 x 4 = 16.
	 *
	 * Instead, mask off 4 bits from one multiplicand, giving a max of 15
	 * one bits per column.  Then handle those 4 bits separately.
	 */
	u64 a0 = a & 0x1111111111111110;
	u64 a1 = a & 0x2222222222222220;
	u64 a2 = a & 0x4444444444444440;
	u64 a3 = a & 0x8888888888888880;

	u64 b0 = b & 0x1111111111111111;
	u64 b1 = b & 0x2222222222222222;
	u64 b2 = b & 0x4444444444444444;
	u64 b3 = b & 0x8888888888888888;

	/* Multiply the high 60 bits of @a by @b. */
	u128 c0 = (a0 * (u128)b0) ^ (a1 * (u128)b3) ^
		  (a2 * (u128)b2) ^ (a3 * (u128)b1);
	u128 c1 = (a0 * (u128)b1) ^ (a1 * (u128)b0) ^
		  (a2 * (u128)b3) ^ (a3 * (u128)b2);
	u128 c2 = (a0 * (u128)b2) ^ (a1 * (u128)b1) ^
		  (a2 * (u128)b0) ^ (a3 * (u128)b3);
	u128 c3 = (a0 * (u128)b3) ^ (a1 * (u128)b2) ^
		  (a2 * (u128)b1) ^ (a3 * (u128)b0);

	/* Multiply the low 4 bits of @a by @b. */
	u64 e0 = -(a & 1) & b;
	u64 e1 = -((a >> 1) & 1) & b;
	u64 e2 = -((a >> 2) & 1) & b;
	u64 e3 = -((a >> 3) & 1) & b;
	u64 extra_lo = e0 ^ (e1 << 1) ^ (e2 << 2) ^ (e3 << 3);
	u64 extra_hi = (e1 >> 63) ^ (e2 >> 62) ^ (e3 >> 61);

	/* Add all the intermediate products together. */
	*out_lo = (((u64)c0) & 0x1111111111111111) ^
		  (((u64)c1) & 0x2222222222222222) ^
		  (((u64)c2) & 0x4444444444444444) ^
		  (((u64)c3) & 0x8888888888888888) ^ extra_lo;
	*out_hi = (((u64)(c0 >> 64)) & 0x1111111111111111) ^
		  (((u64)(c1 >> 64)) & 0x2222222222222222) ^
		  (((u64)(c2 >> 64)) & 0x4444444444444444) ^
		  (((u64)(c3 >> 64)) & 0x8888888888888888) ^ extra_hi;
}

#else /* CONFIG_ARCH_SUPPORTS_INT128 */

/* Do a 32 x 32 => 64 bit carryless multiplication. */
static noinline_for_stack u64 clmul32(u32 a, u32 b)
{
	/*
	 * With 32-bit multiplicands and one term every 4 bits, there are up to
	 * 32 / 4 = 8 one bits per column when each multiplication is written
	 * out as a series of additions in the schoolbook manner.  The value 8
	 * fits in 4 bits, so the carries don't overflow into the next term.
	 */
	u32 a0 = a & 0x11111111;
	u32 a1 = a & 0x22222222;
	u32 a2 = a & 0x44444444;
	u32 a3 = a & 0x88888888;

	u32 b0 = b & 0x11111111;
	u32 b1 = b & 0x22222222;
	u32 b2 = b & 0x44444444;
	u32 b3 = b & 0x88888888;

	u64 c0 = (a0 * (u64)b0) ^ (a1 * (u64)b3) ^
		 (a2 * (u64)b2) ^ (a3 * (u64)b1);
	u64 c1 = (a0 * (u64)b1) ^ (a1 * (u64)b0) ^
		 (a2 * (u64)b3) ^ (a3 * (u64)b2);
	u64 c2 = (a0 * (u64)b2) ^ (a1 * (u64)b1) ^
		 (a2 * (u64)b0) ^ (a3 * (u64)b3);
	u64 c3 = (a0 * (u64)b3) ^ (a1 * (u64)b2) ^
		 (a2 * (u64)b1) ^ (a3 * (u64)b0);

	/* Add all the intermediate products together. */
	return (c0 & 0x1111111111111111) ^
	       (c1 & 0x2222222222222222) ^
	       (c2 & 0x4444444444444444) ^
	       (c3 & 0x8888888888888888);
}

/* Do a 64 x 64 => 128 bit carryless multiplication. */
static void clmul64(u64 a, u64 b, u64 *out_lo, u64 *out_hi)
{
	u32 a_lo = (u32)a;
	u32 a_hi = a >> 32;
	u32 b_lo = (u32)b;
	u32 b_hi = b >> 32;

	/* Karatsuba multiplication */
	u64 lo = clmul32(a_lo, b_lo);
	u64 hi = clmul32(a_hi, b_hi);
	u64 mi = clmul32(a_lo ^ a_hi, b_lo ^ b_hi) ^ lo ^ hi;

	*out_lo = lo ^ (mi << 32);
	*out_hi = hi ^ (mi >> 32);
}
#endif /* !CONFIG_ARCH_SUPPORTS_INT128 */

/* Compute @a = @a * @b * x^-128 in the POLYVAL field. */
static void __maybe_unused
polyval_mul_generic(struct polyval_elem *a, const struct polyval_elem *b)
{
	u64 c0, c1, c2, c3, mi0, mi1;

	/*
	 * Carryless-multiply @a by @b using Karatsuba multiplication.  Store
	 * the 256-bit product in @c0 (low) through @c3 (high).
	 */
	clmul64(le64_to_cpu(a->lo), le64_to_cpu(b->lo), &c0, &c1);
	clmul64(le64_to_cpu(a->hi), le64_to_cpu(b->hi), &c2, &c3);
	clmul64(le64_to_cpu(a->lo ^ a->hi), le64_to_cpu(b->lo ^ b->hi),
		&mi0, &mi1);
	mi0 ^= c0 ^ c2;
	mi1 ^= c1 ^ c3;
	c1 ^= mi0;
	c2 ^= mi1;

	/*
	 * Cancel out the low 128 bits of the product by adding multiples of
	 * G(x) = x^128 + x^127 + x^126 + x^121 + 1.  Do this in two steps, each
	 * of which cancels out 64 bits.  Note that we break G(x) into three
	 * parts: 1, x^64 * (x^63 + x^62 + x^57), and x^128 * 1.
	 */

	/*
	 * First, add G(x) times c0 as follows:
	 *
	 * (c0, c1, c2) = (0,
	 *                 c1 + (c0 * (x^63 + x^62 + x^57) mod x^64),
	 *		   c2 + c0 + floor((c0 * (x^63 + x^62 + x^57)) / x^64))
	 */
	c1 ^= (c0 << 63) ^ (c0 << 62) ^ (c0 << 57);
	c2 ^= c0 ^ (c0 >> 1) ^ (c0 >> 2) ^ (c0 >> 7);

	/*
	 * Second, add G(x) times the new c1:
	 *
	 * (c1, c2, c3) = (0,
	 *                 c2 + (c1 * (x^63 + x^62 + x^57) mod x^64),
	 *		   c3 + c1 + floor((c1 * (x^63 + x^62 + x^57)) / x^64))
	 */
	c2 ^= (c1 << 63) ^ (c1 << 62) ^ (c1 << 57);
	c3 ^= c1 ^ (c1 >> 1) ^ (c1 >> 2) ^ (c1 >> 7);

	/* Return (c2, c3).  This implicitly multiplies by x^-128. */
	a->lo = cpu_to_le64(c2);
	a->hi = cpu_to_le64(c3);
}

static void __maybe_unused ghash_blocks_generic(struct polyval_elem *acc,
						const struct polyval_elem *key,
						const u8 *data, size_t nblocks)
{
	do {
		acc->lo ^=
			cpu_to_le64(get_unaligned_be64((__be64 *)(data + 8)));
		acc->hi ^= cpu_to_le64(get_unaligned_be64((__be64 *)data));
		polyval_mul_generic(acc, key);
		data += GHASH_BLOCK_SIZE;
	} while (--nblocks);
}

static void __maybe_unused
polyval_blocks_generic(struct polyval_elem *acc, const struct polyval_elem *key,
		       const u8 *data, size_t nblocks)
{
	do {
		acc->lo ^= get_unaligned((__le64 *)data);
		acc->hi ^= get_unaligned((__le64 *)(data + 8));
		polyval_mul_generic(acc, key);
		data += POLYVAL_BLOCK_SIZE;
	} while (--nblocks);
}

/* Convert the key from GHASH format to POLYVAL format. */
static void __maybe_unused ghash_key_to_polyval(const u8 in[GHASH_BLOCK_SIZE],
						struct polyval_elem *out)
{
	u64 hi = get_unaligned_be64(&in[0]);
	u64 lo = get_unaligned_be64(&in[8]);
	u64 mask = (s64)hi >> 63;

	hi = (hi << 1) ^ (lo >> 63) ^ (mask & ((u64)0xc2 << 56));
	lo = (lo << 1) ^ (mask & 1);
	out->lo = cpu_to_le64(lo);
	out->hi = cpu_to_le64(hi);
}

/* Convert the accumulator from POLYVAL format to GHASH format. */
static void polyval_acc_to_ghash(const struct polyval_elem *in,
				 u8 out[GHASH_BLOCK_SIZE])
{
	put_unaligned_be64(le64_to_cpu(in->hi), &out[0]);
	put_unaligned_be64(le64_to_cpu(in->lo), &out[8]);
}

/* Convert the accumulator from GHASH format to POLYVAL format. */
static void __maybe_unused ghash_acc_to_polyval(const u8 in[GHASH_BLOCK_SIZE],
						struct polyval_elem *out)
{
	out->lo = cpu_to_le64(get_unaligned_be64(&in[8]));
	out->hi = cpu_to_le64(get_unaligned_be64(&in[0]));
}

#ifdef CONFIG_CRYPTO_LIB_GF128HASH_ARCH
#include "gf128hash.h" /* $(SRCARCH)/gf128hash.h */
#endif

void ghash_preparekey(struct ghash_key *key, const u8 raw_key[GHASH_BLOCK_SIZE])
{
#ifdef ghash_preparekey_arch
	ghash_preparekey_arch(key, raw_key);
#else
	ghash_key_to_polyval(raw_key, &key->h);
#endif
}
EXPORT_SYMBOL_GPL(ghash_preparekey);

static void ghash_mul(struct ghash_ctx *ctx)
{
#ifdef ghash_mul_arch
	ghash_mul_arch(&ctx->acc, ctx->key);
#elif defined(ghash_blocks_arch)
	static const u8 zeroes[GHASH_BLOCK_SIZE];

	ghash_blocks_arch(&ctx->acc, ctx->key, zeroes, 1);
#else
	polyval_mul_generic(&ctx->acc, &ctx->key->h);
#endif
}

/* nblocks is always >= 1. */
static void ghash_blocks(struct ghash_ctx *ctx, const u8 *data, size_t nblocks)
{
#ifdef ghash_blocks_arch
	ghash_blocks_arch(&ctx->acc, ctx->key, data, nblocks);
#else
	ghash_blocks_generic(&ctx->acc, &ctx->key->h, data, nblocks);
#endif
}

void ghash_update(struct ghash_ctx *ctx, const u8 *data, size_t len)
{
	if (unlikely(ctx->partial)) {
		size_t n = min(len, GHASH_BLOCK_SIZE - ctx->partial);

		len -= n;
		while (n--)
			ctx->acc.bytes[GHASH_BLOCK_SIZE - 1 - ctx->partial++] ^=
				*data++;
		if (ctx->partial < GHASH_BLOCK_SIZE)
			return;
		ghash_mul(ctx);
	}
	if (len >= GHASH_BLOCK_SIZE) {
		size_t nblocks = len / GHASH_BLOCK_SIZE;

		ghash_blocks(ctx, data, nblocks);
		data += len & ~(GHASH_BLOCK_SIZE - 1);
		len &= GHASH_BLOCK_SIZE - 1;
	}
	for (size_t i = 0; i < len; i++)
		ctx->acc.bytes[GHASH_BLOCK_SIZE - 1 - i] ^= data[i];
	ctx->partial = len;
}
EXPORT_SYMBOL_GPL(ghash_update);

void ghash_final(struct ghash_ctx *ctx, u8 out[GHASH_BLOCK_SIZE])
{
	if (unlikely(ctx->partial))
		ghash_mul(ctx);
	polyval_acc_to_ghash(&ctx->acc, out);
	memzero_explicit(ctx, sizeof(*ctx));
}
EXPORT_SYMBOL_GPL(ghash_final);

void polyval_preparekey(struct polyval_key *key,
			const u8 raw_key[POLYVAL_BLOCK_SIZE])
{
#ifdef polyval_preparekey_arch
	polyval_preparekey_arch(key, raw_key);
#else
	memcpy(key->h.bytes, raw_key, POLYVAL_BLOCK_SIZE);
#endif
}
EXPORT_SYMBOL_GPL(polyval_preparekey);

/*
 * polyval_mul_generic() and polyval_blocks_generic() take the key as a
 * polyval_elem rather than a polyval_key, so that arch-optimized
 * implementations with a different key format can use it as a fallback (if they
 * have H^1 stored somewhere in their struct).  Thus, the following dispatch
 * code is needed to pass the appropriate key argument.
 */

static void polyval_mul(struct polyval_ctx *ctx)
{
#ifdef polyval_mul_arch
	polyval_mul_arch(&ctx->acc, ctx->key);
#elif defined(polyval_blocks_arch)
	static const u8 zeroes[POLYVAL_BLOCK_SIZE];

	polyval_blocks_arch(&ctx->acc, ctx->key, zeroes, 1);
#else
	polyval_mul_generic(&ctx->acc, &ctx->key->h);
#endif
}

/* nblocks is always >= 1. */
static void polyval_blocks(struct polyval_ctx *ctx,
			   const u8 *data, size_t nblocks)
{
#ifdef polyval_blocks_arch
	polyval_blocks_arch(&ctx->acc, ctx->key, data, nblocks);
#else
	polyval_blocks_generic(&ctx->acc, &ctx->key->h, data, nblocks);
#endif
}

void polyval_update(struct polyval_ctx *ctx, const u8 *data, size_t len)
{
	if (unlikely(ctx->partial)) {
		size_t n = min(len, POLYVAL_BLOCK_SIZE - ctx->partial);

		len -= n;
		while (n--)
			ctx->acc.bytes[ctx->partial++] ^= *data++;
		if (ctx->partial < POLYVAL_BLOCK_SIZE)
			return;
		polyval_mul(ctx);
	}
	if (len >= POLYVAL_BLOCK_SIZE) {
		size_t nblocks = len / POLYVAL_BLOCK_SIZE;

		polyval_blocks(ctx, data, nblocks);
		data += len & ~(POLYVAL_BLOCK_SIZE - 1);
		len &= POLYVAL_BLOCK_SIZE - 1;
	}
	for (size_t i = 0; i < len; i++)
		ctx->acc.bytes[i] ^= data[i];
	ctx->partial = len;
}
EXPORT_SYMBOL_GPL(polyval_update);

void polyval_final(struct polyval_ctx *ctx, u8 out[POLYVAL_BLOCK_SIZE])
{
	if (unlikely(ctx->partial))
		polyval_mul(ctx);
	memcpy(out, &ctx->acc, POLYVAL_BLOCK_SIZE);
	memzero_explicit(ctx, sizeof(*ctx));
}
EXPORT_SYMBOL_GPL(polyval_final);

#ifdef gf128hash_mod_init_arch
static int __init gf128hash_mod_init(void)
{
	gf128hash_mod_init_arch();
	return 0;
}
subsys_initcall(gf128hash_mod_init);

static void __exit gf128hash_mod_exit(void)
{
}
module_exit(gf128hash_mod_exit);
#endif

MODULE_DESCRIPTION("GF(2^128) polynomial hashing: GHASH and POLYVAL");
MODULE_LICENSE("GPL");
