[PATCH 16/19] crypto: ghash - Remove ghash from crypto_shash API

Eric Biggers
2026-03-19T06:19:22Z

Now that there are no users of the "ghash" crypto_shash algorithm,
remove it. GHASH remains supported via the library API.

Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
crypto/Kconfig | 7 --
crypto/Makefile | 1 -
crypto/ghash-generic.c | 162 -----------------------------------------
crypto/tcrypt.c | 9 ---
crypto/testmgr.c | 6 --
crypto/testmgr.h | 109 ---------------------------
6 files changed, 294 deletions(-)
delete mode 100644 crypto/ghash-generic.c

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 13ccf5ac2f1a..efb482ea192d 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -886,17 +886,10 @@ config CRYPTO_CMAC
select CRYPTO_MANAGER
help
CMAC (Cipher-based Message Authentication Code) authentication
mode (NIST SP800-38B and IETF RFC4493)

-config CRYPTO_GHASH
- tristate "GHASH"
- select CRYPTO_HASH
- select CRYPTO_LIB_GF128MUL
- help
- GCM GHASH function (NIST SP800-38D)
-
config CRYPTO_HMAC
tristate "HMAC (Keyed-Hash MAC)"
select CRYPTO_HASH
select CRYPTO_MANAGER
help
diff --git a/crypto/Makefile b/crypto/Makefile
index 04e269117589..17f4fca9b9e5 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -169,11 +169,10 @@ CFLAGS_jitterentropy.o = -O0
KASAN_SANITIZE_jitterentropy.o = n
UBSAN_SANITIZE_jitterentropy.o = n
jitterentropy_rng-y := jitterentropy.o jitterentropy-kcapi.o
obj-$(CONFIG_CRYPTO_JITTERENTROPY_TESTINTERFACE) += jitterentropy-testing.o
obj-$(CONFIG_CRYPTO_BENCHMARK) += tcrypt.o
-obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o
obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o
obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o
obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o
obj-$(CONFIG_CRYPTO_USER_API_RNG) += algif_rng.o
obj-$(CONFIG_CRYPTO_USER_API_AEAD) += algif_aead.o
diff --git a/crypto/ghash-generic.c b/crypto/ghash-generic.c
deleted file mode 100644
index e5803c249c12..000000000000
--- a/crypto/ghash-generic.c
+++ /dev/null
@@ -1,162 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * GHASH: hash function for GCM (Galois/Counter Mode).
- *
- * Copyright (c) 2007 Nokia Siemens Networks - Mikko Herranen <mh1@iki.fi>
- * Copyright (c) 2009 Intel Corp.
- * Author: Huang Ying <ying.huang@intel.com>
- */
-
-/*
- * 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/gf128mul.h>
-#include <crypto/ghash.h>
-#include <crypto/internal/hash.h>
-#include <crypto/utils.h>
-#include <linux/err.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-
-static int ghash_init(struct shash_desc *desc)
-{
- struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
-
- memset(dctx, 0, sizeof(*dctx));
-
- return 0;
-}
-
-static int ghash_setkey(struct crypto_shash *tfm,
- const u8 *key, unsigned int keylen)
-{
- struct ghash_ctx *ctx = crypto_shash_ctx(tfm);
- be128 k;
-
- if (keylen != GHASH_BLOCK_SIZE)
- return -EINVAL;
-
- if (ctx->gf128)
- gf128mul_free_4k(ctx->gf128);
-
- BUILD_BUG_ON(sizeof(k) != GHASH_BLOCK_SIZE);
- memcpy(&k, key, GHASH_BLOCK_SIZE); /* avoid violating alignment rules */
- ctx->gf128 = gf128mul_init_4k_lle(&k);
- memzero_explicit(&k, GHASH_BLOCK_SIZE);
-
- if (!ctx->gf128)
- return -ENOMEM;
-
- return 0;
-}
-
-static int ghash_update(struct shash_desc *desc,
- const u8 *src, unsigned int srclen)
-{
- struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
- struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
- u8 *dst = dctx->buffer;
-
- do {
- crypto_xor(dst, src, GHASH_BLOCK_SIZE);
- gf128mul_4k_lle((be128 *)dst, ctx->gf128);
- src += GHASH_BLOCK_SIZE;
- srclen -= GHASH_BLOCK_SIZE;
- } while (srclen >= GHASH_BLOCK_SIZE);
-
- return srclen;
-}
-
-static void ghash_flush(struct shash_desc *desc, const u8 *src,
- unsigned int len)
-{
- struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
- struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
- u8 *dst = dctx->buffer;
-
- if (len) {
- crypto_xor(dst, src, len);
- gf128mul_4k_lle((be128 *)dst, ctx->gf128);
- }
-}
-
-static int ghash_finup(struct shash_desc *desc, const u8 *src,
- unsigned int len, u8 *dst)
-{
- struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
- u8 *buf = dctx->buffer;
-
- ghash_flush(desc, src, len);
- memcpy(dst, buf, GHASH_BLOCK_SIZE);
-
- return 0;
-}
-
-static void ghash_exit_tfm(struct crypto_tfm *tfm)
-{
- struct ghash_ctx *ctx = crypto_tfm_ctx(tfm);
- if (ctx->gf128)
- gf128mul_free_4k(ctx->gf128);
-}
-
-static struct shash_alg ghash_alg = {
- .digestsize = GHASH_DIGEST_SIZE,
- .init = ghash_init,
- .update = ghash_update,
- .finup = ghash_finup,
- .setkey = ghash_setkey,
- .descsize = sizeof(struct ghash_desc_ctx),
- .base = {
- .cra_name = "ghash",
- .cra_driver_name = "ghash-generic",
- .cra_priority = 100,
- .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY,
- .cra_blocksize = GHASH_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct ghash_ctx),
- .cra_module = THIS_MODULE,
- .cra_exit = ghash_exit_tfm,
- },
-};
-
-static int __init ghash_mod_init(void)
-{
- return crypto_register_shash(&ghash_alg);
-}
-
-static void __exit ghash_mod_exit(void)
-{
- crypto_unregister_shash(&ghash_alg);
-}
-
-module_init(ghash_mod_init);
-module_exit(ghash_mod_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("GHASH hash function");
-MODULE_ALIAS_CRYPTO("ghash");
-MODULE_ALIAS_CRYPTO("ghash-generic");
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index aded37546137..1773f5f71351 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -1648,14 +1648,10 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)

case 45:
ret = min(ret, tcrypt_test("rfc4309(ccm(aes))"));
break;

- case 46:
- ret = min(ret, tcrypt_test("ghash"));
- break;
-
case 48:
ret = min(ret, tcrypt_test("sha3-224"));
break;

case 49:
@@ -2249,15 +2245,10 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
fallthrough;
case 317:
test_hash_speed("blake2b-512", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
fallthrough;
- case 318:
- klen = 16;
- test_hash_speed("ghash", sec, generic_hash_speed_template);
- if (mode > 300 && mode < 400) break;
- fallthrough;
case 319:
test_hash_speed("crc32c", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
fallthrough;
case 322:
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 0b0ad358e091..dd01f86dd6fe 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -4983,16 +4983,10 @@ static const struct alg_test_desc alg_test_descs[] = {
.generic_driver = "gcm_base(ctr(sm4-generic),ghash-lib)",
.test = alg_test_aead,
.suite = {
.aead = __VECS(sm4_gcm_tv_template)
}
- }, {
- .alg = "ghash",
- .test = alg_test_hash,
- .suite = {
- .hash = __VECS(ghash_tv_template)
- }
}, {
.alg = "hctr2(aes)",
.generic_driver = "hctr2_base(xctr(aes-lib),polyval-lib)",
.test = alg_test_skcipher,
.suite = {
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 1c69c11c0cdb..a3274abacfde 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -6181,119 +6181,10 @@ static const struct hash_testvec wp256_tv_template[] = {
"\x8A\x7A\x5A\x52\xDE\xEE\x65\x62"
"\x07\xC5\x62\xF9\x88\xE9\x5C\x69",
},
};

-static const struct hash_testvec ghash_tv_template[] =
-{
- {
- .key = "\xdf\xa6\xbf\x4d\xed\x81\xdb\x03"
- "\xff\xca\xff\x95\xf8\x30\xf0\x61",
- .ksize = 16,
- .plaintext = "\x95\x2b\x2a\x56\xa5\x60\x04a\xc0"
- "\xb3\x2b\x66\x56\xa0\x5b\x40\xb6",
- .psize = 16,
- .digest = "\xda\x53\xeb\x0a\xd2\xc5\x5b\xb6"
- "\x4f\xc4\x80\x2c\xc3\xfe\xda\x60",
- }, {
- .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
- "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
- .ksize = 16,
- .plaintext = "what do ya want for nothing?",
- .psize = 28,
- .digest = "\x3e\x1f\x5c\x4d\x65\xf0\xef\xce"
- "\x0d\x61\x06\x27\x66\x51\xd5\xe2",
- }, {
- .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
- "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
- .ksize = 16,
- .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
- "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
- "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
- "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
- .psize = 50,
- .digest = "\xfb\x49\x8a\x36\xe1\x96\xe1\x96"
- "\xe1\x96\xe1\x96\xe1\x96\xe1\x96",
- }, {
- .key = "\xda\x53\xeb\x0a\xd2\xc5\x5b\xb6"
- "\x4f\xc4\x80\x2c\xc3\xfe\xda\x60",
- .ksize = 16,
- .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
- "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
- "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
- "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
- .psize = 50,
- .digest = "\x2b\x5c\x0c\x7f\x52\xd1\x60\xc2"
- "\x49\xed\x6e\x32\x7a\xa9\xbe\x08",
- }, {
- .key = "\x95\x2b\x2a\x56\xa5\x60\x04a\xc0"
- "\xb3\x2b\x66\x56\xa0\x5b\x40\xb6",
- .ksize = 16,
- .plaintext = "Test With Truncation",
- .psize = 20,
- .digest = "\xf8\x94\x87\x2a\x4b\x63\x99\x28"
- "\x23\xf7\x93\xf7\x19\xf5\x96\xd9",
- }, {
- .key = "\x0a\x1b\x2c\x3d\x4e\x5f\x64\x71"
- "\x82\x93\xa4\xb5\xc6\xd7\xe8\xf9",
- .ksize = 16,
- .plaintext = "\x56\x6f\x72\x20\x6c\x61\x75\x74"
- "\x65\x72\x20\x4c\x61\x75\x73\x63"
- "\x68\x65\x6e\x20\x75\x6e\x64\x20"
- "\x53\x74\x61\x75\x6e\x65\x6e\x20"
- "\x73\x65\x69\x20\x73\x74\x69\x6c"
- "\x6c\x2c\x0a\x64\x75\x20\x6d\x65"
- "\x69\x6e\x20\x74\x69\x65\x66\x74"
- "\x69\x65\x66\x65\x73\x20\x4c\x65"
- "\x62\x65\x6e\x3b\x0a\x64\x61\x73"
- "\x73\x20\x64\x75\x20\x77\x65\x69"
- "\xc3\x9f\x74\x20\x77\x61\x73\x20"
- "\x64\x65\x72\x20\x57\x69\x6e\x64"
- "\x20\x64\x69\x72\x20\x77\x69\x6c"
- "\x6c\x2c\x0a\x65\x68\x20\x6e\x6f"
- "\x63\x68\x20\x64\x69\x65\x20\x42"
- "\x69\x72\x6b\x65\x6e\x20\x62\x65"
- "\x62\x65\x6e\x2e\x0a\x0a\x55\x6e"
- "\x64\x20\x77\x65\x6e\x6e\x20\x64"
- "\x69\x72\x20\x65\x69\x6e\x6d\x61"
- "\x6c\x20\x64\x61\x73\x20\x53\x63"
- "\x68\x77\x65\x69\x67\x65\x6e\x20"
- "\x73\x70\x72\x61\x63\x68\x2c\x0a"
- "\x6c\x61\x73\x73\x20\x64\x65\x69"
- "\x6e\x65\x20\x53\x69\x6e\x6e\x65"
- "\x20\x62\x65\x73\x69\x65\x67\x65"
- "\x6e\x2e\x0a\x4a\x65\x64\x65\x6d"
- "\x20\x48\x61\x75\x63\x68\x65\x20"
- "\x67\x69\x62\x74\x20\x64\x69\x63"
- "\x68\x2c\x20\x67\x69\x62\x20\x6e"
- "\x61\x63\x68\x2c\x0a\x65\x72\x20"
- "\x77\x69\x72\x64\x20\x64\x69\x63"
- "\x68\x20\x6c\x69\x65\x62\x65\x6e"
- "\x20\x75\x6e\x64\x20\x77\x69\x65"
- "\x67\x65\x6e\x2e\x0a\x0a\x55\x6e"
- "\x64\x20\x64\x61\x6e\x6e\x20\x6d"
- "\x65\x69\x6e\x65\x20\x53\x65\x65"
- "\x6c\x65\x20\x73\x65\x69\x74\x20"
- "\x77\x65\x69\x74\x2c\x20\x73\x65"
- "\x69\x20\x77\x65\x69\x74\x2c\x0a"
- "\x64\x61\x73\x73\x20\x64\x69\x72"
- "\x20\x64\x61\x73\x20\x4c\x65\x62"
- "\x65\x6e\x20\x67\x65\x6c\x69\x6e"
- "\x67\x65\x2c\x0a\x62\x72\x65\x69"
- "\x74\x65\x20\x64\x69\x63\x68\x20"
- "\x77\x69\x65\x20\x65\x69\x6e\x20"
- "\x46\x65\x69\x65\x72\x6b\x6c\x65"
- "\x69\x64\x0a\xc3\xbc\x62\x65\x72"
- "\x20\x64\x69\x65\x20\x73\x69\x6e"
- "\x6e\x65\x6e\x64\x65\x6e\x20\x44"
- "\x69\x6e\x67\x65\x2e\x2e\x2e\x0a",
- .psize = 400,
- .digest = "\xad\xb1\xc1\xe9\x56\x70\x31\x1d"
- "\xbb\x5b\xdf\x5e\x70\x72\x1a\x57",
- },
-};
-
/*
* HMAC-MD5 test vectors from RFC2202
* (These need to be fixed to not use strlen).
*/
static const struct hash_testvec hmac_md5_tv_template[] =
--
2.53.0