[PATCH 02/13] crypto/crc32c: register only one shash_alg

Eric Biggers
2025-06-01T22:45:54Z

Stop unnecessarily registering a "crc32c-generic" shash_alg when a
"crc32c-$(ARCH)" shash_alg is registered too.

While every algorithm does need to have a generic implementation to
ensure uniformity of support across platforms, that doesn't mean that we
need to make the generic implementation available through crypto_shash
when an optimized implementation is also available.

Registering the generic shash_alg did allow users of the crypto_shash or
crypto_ahash APIs to request the generic implementation specifically,
instead of an optimized one. However, the only known use case for that
was the differential fuzz tests in crypto/testmgr.c. Equivalent test
coverage is now provided by crc_kunit.

Besides simplifying crypto/crc32c.c, this change eliminates the need for
the library to provide crc32c_base() as part of its interface. Later
patches will make crc32c_base() be internal to the library.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
crypto/crc32c.c | 70 +++++++------------------------------------------
1 file changed, 10 insertions(+), 60 deletions(-)

diff --git a/crypto/crc32c.c b/crypto/crc32c.c
index e5377898414a2..e160695682f16 100644
--- a/crypto/crc32c.c
+++ b/crypto/crc32c.c
@@ -83,19 +83,10 @@ static int chksum_setkey(struct crypto_shash *tfm, const u8 *key,
static int chksum_update(struct shash_desc *desc, const u8 *data,
unsigned int length)
{
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);

- ctx->crc = crc32c_base(ctx->crc, data, length);
- return 0;
-}
-
-static int chksum_update_arch(struct shash_desc *desc, const u8 *data,
- unsigned int length)
-{
- struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
ctx->crc = crc32c(ctx->crc, data, length);
return 0;
}

static int chksum_final(struct shash_desc *desc, u8 *out)
@@ -105,17 +96,10 @@ static int chksum_final(struct shash_desc *desc, u8 *out)
put_unaligned_le32(~ctx->crc, out);
return 0;
}

static int __chksum_finup(u32 *crcp, const u8 *data, unsigned int len, u8 *out)
-{
- put_unaligned_le32(~crc32c_base(*crcp, data, len), out);
- return 0;
-}
-
-static int __chksum_finup_arch(u32 *crcp, const u8 *data, unsigned int len,
- u8 *out)
{
put_unaligned_le32(~crc32c(*crcp, data, len), out);
return 0;
}

@@ -125,98 +109,64 @@ static int chksum_finup(struct shash_desc *desc, const u8 *data,
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);

return __chksum_finup(&ctx->crc, data, len, out);
}

-static int chksum_finup_arch(struct shash_desc *desc, const u8 *data,
- unsigned int len, u8 *out)
-{
- struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
- return __chksum_finup_arch(&ctx->crc, data, len, out);
-}
-
static int chksum_digest(struct shash_desc *desc, const u8 *data,
unsigned int length, u8 *out)
{
struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);

return __chksum_finup(&mctx->key, data, length, out);
}

-static int chksum_digest_arch(struct shash_desc *desc, const u8 *data,
- unsigned int length, u8 *out)
-{
- struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
-
- return __chksum_finup_arch(&mctx->key, data, length, out);
-}
-
static int crc32c_cra_init(struct crypto_tfm *tfm)
{
struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);

mctx->key = ~0;
return 0;
}

-static struct shash_alg algs[] = {{
+static struct shash_alg alg = {
.digestsize = CHKSUM_DIGEST_SIZE,
.setkey = chksum_setkey,
.init = chksum_init,
.update = chksum_update,
.final = chksum_final,
.finup = chksum_finup,
.digest = chksum_digest,
.descsize = sizeof(struct chksum_desc_ctx),

.base.cra_name = "crc32c",
- .base.cra_driver_name = "crc32c-generic",
.base.cra_priority = 100,
.base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
.base.cra_blocksize = CHKSUM_BLOCK_SIZE,
.base.cra_ctxsize = sizeof(struct chksum_ctx),
.base.cra_module = THIS_MODULE,
.base.cra_init = crc32c_cra_init,
-}, {
- .digestsize = CHKSUM_DIGEST_SIZE,
- .setkey = chksum_setkey,
- .init = chksum_init,
- .update = chksum_update_arch,
- .final = chksum_final,
- .finup = chksum_finup_arch,
- .digest = chksum_digest_arch,
- .descsize = sizeof(struct chksum_desc_ctx),
-
- .base.cra_name = "crc32c",
- .base.cra_driver_name = "crc32c-" __stringify(ARCH),
- .base.cra_priority = 150,
- .base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
- .base.cra_blocksize = CHKSUM_BLOCK_SIZE,
- .base.cra_ctxsize = sizeof(struct chksum_ctx),
- .base.cra_module = THIS_MODULE,
- .base.cra_init = crc32c_cra_init,
-}};
-
-static int num_algs;
+};

static int __init crc32c_mod_init(void)
{
- /* register the arch flavor only if it differs from the generic one */
- num_algs = 1 + ((crc32_optimizations() & CRC32C_OPTIMIZATION) != 0);
+ const char *driver_name =
+ (crc32_optimizations() & CRC32C_OPTIMIZATION) ?
+ "crc32c-" __stringify(ARCH) :
+ "crc32c-generic";
+
+ strscpy(alg.base.cra_driver_name, driver_name, CRYPTO_MAX_ALG_NAME);

- return crypto_register_shashes(algs, num_algs);
+ return crypto_register_shash(&alg);
}

static void __exit crc32c_mod_fini(void)
{
- crypto_unregister_shashes(algs, num_algs);
+ crypto_unregister_shash(&alg);
}

module_init(crc32c_mod_init);
module_exit(crc32c_mod_fini);

MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c");
MODULE_LICENSE("GPL");
MODULE_ALIAS_CRYPTO("crc32c");
-MODULE_ALIAS_CRYPTO("crc32c-generic");
--
2.49.0