// SPDX-License-Identifier: GPL-2.0-only /* * GHASH: hash function for GCM (Galois/Counter Mode). * * Copyright (c) 2007 Nokia Siemens Networks - Mikko Herranen <[email protected]> * Copyright (c) 2009 Intel Corp. * Author: Huang Ying <[email protected]> */ /* * GHASH is a keyed hash function used in GCM authentication tag generation. * * The original GCM paper [1] presents GHASH as a function GHASH(H, A, C) which * takes a 16-byte hash key H, additional authenticated data A, and a ciphertext * C. It formats A and C into a single byte string X, interprets X as a * polynomial over GF(2^128), and evaluates this polynomial at the point H. * * However, the NIST standard for GCM [2] presents GHASH as GHASH(H, X) where X * is the already-formatted byte string containing both A and C. * * "ghash" in the Linux crypto API uses the 'X' (pre-formatted) convention, * since the API supports only a single data stream per hash. Thus, the * formatting of 'A' and 'C' is done in the "gcm" template, not in "ghash". * * The reason "ghash" is separate from "gcm" is to allow "gcm" to use an * accelerated "ghash" when a standalone accelerated "gcm(aes)" is unavailable. * It is generally inappropriate to use "ghash" for other purposes, since it is * an "ε-almost-XOR-universal hash function", not a cryptographic hash function. * It can only be used securely in crypto modes specially designed to use it. * * [1] The Galois/Counter Mode of Operation (GCM) * (http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.694.695&rep=rep1&type=pdf) * [2] Recommendation for Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC * (https://csrc.nist.gov/publications/detail/sp/800-38d/final) */ #include <crypto/algapi.h> #include <crypto/gf128mul.h> #include <crypto/ghash.h> #include <crypto/internal/hash.h> #include <linux/crypto.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> static int ghash_init(struct shash_desc *desc) { … } static int ghash_setkey(struct crypto_shash *tfm, const u8 *key, unsigned int keylen) { … } static int ghash_update(struct shash_desc *desc, const u8 *src, unsigned int srclen) { … } static void ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx) { … } static int ghash_final(struct shash_desc *desc, u8 *dst) { … } static void ghash_exit_tfm(struct crypto_tfm *tfm) { … } static struct shash_alg ghash_alg = …; static int __init ghash_mod_init(void) { … } static void __exit ghash_mod_exit(void) { … } subsys_initcall(ghash_mod_init); module_exit(ghash_mod_exit); MODULE_LICENSE(…) …; MODULE_DESCRIPTION(…) …; MODULE_ALIAS_CRYPTO(…) …; MODULE_ALIAS_CRYPTO(…) …;