linux/crypto/polyval-generic.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * POLYVAL: hash function for HCTR2.
 *
 * Copyright (c) 2007 Nokia Siemens Networks - Mikko Herranen <[email protected]>
 * Copyright (c) 2009 Intel Corp.
 *   Author: Huang Ying <[email protected]>
 * Copyright 2021 Google LLC
 */

/*
 * Code based on crypto/ghash-generic.c
 *
 * POLYVAL is a keyed hash function similar to GHASH. POLYVAL uses a different
 * modulus for finite field multiplication which makes hardware accelerated
 * implementations on little-endian machines faster. POLYVAL is used in the
 * kernel to implement HCTR2, but was originally specified for AES-GCM-SIV
 * (RFC 8452).
 *
 * For more information see:
 * Length-preserving encryption with HCTR2:
 *   https://eprint.iacr.org/2021/1441.pdf
 * AES-GCM-SIV: Nonce Misuse-Resistant Authenticated Encryption:
 *   https://datatracker.ietf.org/doc/html/rfc8452
 *
 * Like GHASH, POLYVAL is not a cryptographic hash function and should
 * not be used outside of crypto modes explicitly designed to use POLYVAL.
 *
 * This implementation uses a convenient trick involving the GHASH and POLYVAL
 * fields. This trick allows multiplication in the POLYVAL field to be
 * implemented by using multiplication in the GHASH field as a subroutine. An
 * element of the POLYVAL field can be converted to an element of the GHASH
 * field by computing x*REVERSE(a), where REVERSE reverses the byte-ordering of
 * a. Similarly, an element of the GHASH field can be converted back to the
 * POLYVAL field by computing REVERSE(x^{-1}*a). For more information, see:
 * https://datatracker.ietf.org/doc/html/rfc8452#appendix-A
 *
 * By using this trick, we do not need to implement the POLYVAL field for the
 * generic implementation.
 *
 * Warning: this generic implementation is not intended to be used in practice
 * and is not constant time. For practical use, a hardware accelerated
 * implementation of POLYVAL should be used instead.
 *
 */

#include <asm/unaligned.h>
#include <crypto/algapi.h>
#include <crypto/gf128mul.h>
#include <crypto/polyval.h>
#include <crypto/internal/hash.h>
#include <linux/crypto.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

struct polyval_tfm_ctx {};

struct polyval_desc_ctx {};

static void copy_and_reverse(u8 dst[POLYVAL_BLOCK_SIZE],
			     const u8 src[POLYVAL_BLOCK_SIZE])
{}

/*
 * Performs multiplication in the POLYVAL field using the GHASH field as a
 * subroutine.  This function is used as a fallback for hardware accelerated
 * implementations when simd registers are unavailable.
 *
 * Note: This function is not used for polyval-generic, instead we use the 4k
 * lookup table implementation for finite field multiplication.
 */
void polyval_mul_non4k(u8 *op1, const u8 *op2)
{}
EXPORT_SYMBOL_GPL();

/*
 * Perform a POLYVAL update using non4k multiplication.  This function is used
 * as a fallback for hardware accelerated implementations when simd registers
 * are unavailable.
 *
 * Note: This function is not used for polyval-generic, instead we use the 4k
 * lookup table implementation of finite field multiplication.
 */
void polyval_update_non4k(const u8 *key, const u8 *in,
			  size_t nblocks, u8 *accumulator)
{}
EXPORT_SYMBOL_GPL();

static int polyval_setkey(struct crypto_shash *tfm,
			  const u8 *key, unsigned int keylen)
{}

static int polyval_init(struct shash_desc *desc)
{}

static int polyval_update(struct shash_desc *desc,
			 const u8 *src, unsigned int srclen)
{}

static int polyval_final(struct shash_desc *desc, u8 *dst)
{}

static void polyval_exit_tfm(struct crypto_tfm *tfm)
{}

static struct shash_alg polyval_alg =;

static int __init polyval_mod_init(void)
{}

static void __exit polyval_mod_exit(void)
{}

subsys_initcall(polyval_mod_init);
module_exit(polyval_mod_exit);

MODULE_LICENSE();
MODULE_DESCRIPTION();
MODULE_ALIAS_CRYPTO();
MODULE_ALIAS_CRYPTO();