]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
crypto: crct10dif - expose arch-optimized lib function
authorEric Biggers <ebiggers@google.com>
Mon, 2 Dec 2024 01:20:47 +0000 (17:20 -0800)
committerEric Biggers <ebiggers@google.com>
Mon, 2 Dec 2024 01:23:13 +0000 (17:23 -0800)
Now that crc_t10dif_update() may be directly optimized for each
architecture, make the shash driver for crct10dif register a
crct10dif-$arch algorithm that uses it, instead of only
crct10dif-generic which uses crc_t10dif_generic().

The result is that architecture-optimized crct10dif will remain
available through the shash API once the architectures implement
crc_t10dif_arch() instead of the shash API.

Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Link: https://lore.kernel.org/r/20241202012056.209768-4-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>
crypto/Makefile
crypto/crct10dif_generic.c

index 0537df1719d3606e236f76e0a0fc89ab60fe0203..ffd94c7f2643fa53aa572a26c6139bdcdcfb47b1 100644 (file)
@@ -158,6 +158,7 @@ obj-$(CONFIG_CRYPTO_CRC32) += crc32_generic.o
 CFLAGS_crc32c_generic.o += -DARCH=$(ARCH)
 CFLAGS_crc32_generic.o += -DARCH=$(ARCH)
 obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_generic.o
+CFLAGS_crct10dif_generic.o += -DARCH=$(ARCH)
 obj-$(CONFIG_CRYPTO_CRC64_ROCKSOFT) += crc64_rocksoft_generic.o
 obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o
 obj-$(CONFIG_CRYPTO_LZO) += lzo.o lzo-rle.o
index e843982073bb5836d84ccd34d464ae4877a8984a..259cb01932cb5e970c5dd91f13d025882651d061 100644 (file)
@@ -57,6 +57,15 @@ static int chksum_update(struct shash_desc *desc, const u8 *data,
        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 = crc_t10dif_update(ctx->crc, data, length);
+       return 0;
+}
+
 static int chksum_final(struct shash_desc *desc, u8 *out)
 {
        struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
@@ -71,6 +80,13 @@ static int __chksum_finup(__u16 crc, const u8 *data, unsigned int len, u8 *out)
        return 0;
 }
 
+static int __chksum_finup_arch(__u16 crc, const u8 *data, unsigned int len,
+                              u8 *out)
+{
+       *(__u16 *)out = crc_t10dif_update(crc, data, len);
+       return 0;
+}
+
 static int chksum_finup(struct shash_desc *desc, const u8 *data,
                        unsigned int len, u8 *out)
 {
@@ -79,37 +95,67 @@ static int chksum_finup(struct shash_desc *desc, const u8 *data,
        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)
 {
        return __chksum_finup(0, data, length, out);
 }
 
-static struct shash_alg alg = {
-       .digestsize             =       CRC_T10DIF_DIGEST_SIZE,
-       .init           =       chksum_init,
-       .update         =       chksum_update,
-       .final          =       chksum_final,
-       .finup          =       chksum_finup,
-       .digest         =       chksum_digest,
-       .descsize               =       sizeof(struct chksum_desc_ctx),
-       .base                   =       {
-               .cra_name               =       "crct10dif",
-               .cra_driver_name        =       "crct10dif-generic",
-               .cra_priority           =       100,
-               .cra_blocksize          =       CRC_T10DIF_BLOCK_SIZE,
-               .cra_module             =       THIS_MODULE,
-       }
-};
+static int chksum_digest_arch(struct shash_desc *desc, const u8 *data,
+                             unsigned int length, u8 *out)
+{
+       return __chksum_finup_arch(0, data, length, out);
+}
+
+static struct shash_alg algs[] = {{
+       .digestsize             = CRC_T10DIF_DIGEST_SIZE,
+       .init                   = chksum_init,
+       .update                 = chksum_update,
+       .final                  = chksum_final,
+       .finup                  = chksum_finup,
+       .digest                 = chksum_digest,
+       .descsize               = sizeof(struct chksum_desc_ctx),
+       .base.cra_name          = "crct10dif",
+       .base.cra_driver_name   = "crct10dif-generic",
+       .base.cra_priority      = 100,
+       .base.cra_blocksize     = CRC_T10DIF_BLOCK_SIZE,
+       .base.cra_module        = THIS_MODULE,
+}, {
+       .digestsize             = CRC_T10DIF_DIGEST_SIZE,
+       .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          = "crct10dif",
+       .base.cra_driver_name   = "crct10dif-" __stringify(ARCH),
+       .base.cra_priority      = 150,
+       .base.cra_blocksize     = CRC_T10DIF_BLOCK_SIZE,
+       .base.cra_module        = THIS_MODULE,
+}};
+
+static int num_algs;
 
 static int __init crct10dif_mod_init(void)
 {
-       return crypto_register_shash(&alg);
+       /* register the arch flavor only if it differs from the generic one */
+       num_algs = 1 + crc_t10dif_is_optimized();
+
+       return crypto_register_shashes(algs, num_algs);
 }
 
 static void __exit crct10dif_mod_fini(void)
 {
-       crypto_unregister_shash(&alg);
+       crypto_unregister_shashes(algs, num_algs);
 }
 
 subsys_initcall(crct10dif_mod_init);