]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
lib/crypto: arm/sha512: Migrate optimized SHA-512 code to library
authorEric Biggers <ebiggers@kernel.org>
Mon, 30 Jun 2025 16:03:11 +0000 (09:03 -0700)
committerEric Biggers <ebiggers@kernel.org>
Mon, 30 Jun 2025 16:26:19 +0000 (09:26 -0700)
Instead of exposing the arm-optimized SHA-512 code via arm-specific
crypto_shash algorithms, instead just implement the sha512_blocks()
library function.  This is much simpler, it makes the SHA-512 (and
SHA-384) library functions be arm-optimized, and it fixes the
longstanding issue where the arm-optimized SHA-512 code was disabled by
default.  SHA-512 still remains available through crypto_shash, but
individual architectures no longer need to handle it.

To match sha512_blocks(), change the type of the nblocks parameter of
the assembly functions from int to size_t.  The assembly functions
actually already treated it as size_t.

Acked-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20250630160320.2888-8-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
15 files changed:
arch/arm/configs/exynos_defconfig
arch/arm/configs/milbeaut_m10v_defconfig
arch/arm/configs/multi_v7_defconfig
arch/arm/configs/omap2plus_defconfig
arch/arm/configs/pxa_defconfig
arch/arm/crypto/Kconfig
arch/arm/crypto/Makefile
arch/arm/crypto/sha512-glue.c [deleted file]
arch/arm/crypto/sha512-neon-glue.c [deleted file]
arch/arm/crypto/sha512.h [deleted file]
lib/crypto/Kconfig
lib/crypto/Makefile
lib/crypto/arm/.gitignore [new file with mode: 0644]
lib/crypto/arm/sha512-armv4.pl [moved from arch/arm/crypto/sha512-armv4.pl with 100% similarity]
lib/crypto/arm/sha512.h [new file with mode: 0644]

index f71af368674cf13609635e7c37165bab8116320f..d58e300693045ad96d5236e5141da3ec417e4fd5 100644 (file)
@@ -364,7 +364,6 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
 CONFIG_CRYPTO_SHA1_ARM_NEON=m
-CONFIG_CRYPTO_SHA512_ARM=m
 CONFIG_CRYPTO_AES_ARM_BS=m
 CONFIG_CRYPTO_CHACHA20_NEON=m
 CONFIG_CRYPTO_DEV_EXYNOS_RNG=y
index 242e7d5a3f6820405d1dc5be0ce1baf3420bdb0d..8ebf8bd872fe8a3693ccd507eb52a4cdb91eedab 100644 (file)
@@ -100,7 +100,6 @@ CONFIG_CRYPTO_SEQIV=m
 CONFIG_CRYPTO_GHASH_ARM_CE=m
 CONFIG_CRYPTO_SHA1_ARM_NEON=m
 CONFIG_CRYPTO_SHA1_ARM_CE=m
-CONFIG_CRYPTO_SHA512_ARM=m
 CONFIG_CRYPTO_AES_ARM=m
 CONFIG_CRYPTO_AES_ARM_BS=m
 CONFIG_CRYPTO_AES_ARM_CE=m
index 50c170b4619f72db1933f7b692c4655e2a9130f0..3fd07e864ca8554e29c11e8e86bb320c8b8e3afc 100644 (file)
@@ -1282,7 +1282,6 @@ CONFIG_CRYPTO_USER_API_AEAD=m
 CONFIG_CRYPTO_GHASH_ARM_CE=m
 CONFIG_CRYPTO_SHA1_ARM_NEON=m
 CONFIG_CRYPTO_SHA1_ARM_CE=m
-CONFIG_CRYPTO_SHA512_ARM=m
 CONFIG_CRYPTO_AES_ARM=m
 CONFIG_CRYPTO_AES_ARM_BS=m
 CONFIG_CRYPTO_AES_ARM_CE=m
index 9f9780c8e62aadea51de9546805ae5d7c28f8cde..530dfb8338c98e6d2eb4936fb533f21cb56d8298 100644 (file)
@@ -705,7 +705,6 @@ CONFIG_SECURITY=y
 CONFIG_CRYPTO_MICHAEL_MIC=y
 CONFIG_CRYPTO_GHASH_ARM_CE=m
 CONFIG_CRYPTO_SHA1_ARM_NEON=m
-CONFIG_CRYPTO_SHA512_ARM=m
 CONFIG_CRYPTO_AES_ARM=m
 CONFIG_CRYPTO_AES_ARM_BS=m
 CONFIG_CRYPTO_CHACHA20_NEON=m
index ff29c5b0e9c93670dda5f13481dac08f26ed3b5e..eaa44574d4a64603811f5983e509a4a7bd44c19e 100644 (file)
@@ -659,7 +659,6 @@ CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_LZO=y
 CONFIG_CRYPTO_SHA1_ARM=m
-CONFIG_CRYPTO_SHA512_ARM=m
 CONFIG_CRYPTO_AES_ARM=m
 CONFIG_FONTS=y
 CONFIG_FONT_8x8=y
index 7efb9a8596e4e58302144c4b16cfa90f9afac465..a18f97f1597cbe7b46bfa9aed92b755862d65561 100644 (file)
@@ -93,16 +93,6 @@ config CRYPTO_SHA1_ARM_CE
 
          Architecture: arm using ARMv8 Crypto Extensions
 
-config CRYPTO_SHA512_ARM
-       tristate "Hash functions: SHA-384 and SHA-512 (NEON)"
-       select CRYPTO_HASH
-       depends on !CPU_V7M
-       help
-         SHA-384 and SHA-512 secure hash algorithms (FIPS 180)
-
-         Architecture: arm using
-         - NEON (Advanced SIMD) extensions
-
 config CRYPTO_AES_ARM
        tristate "Ciphers: AES"
        select CRYPTO_ALGAPI
index 8479137c6e80022766342694d4ee9dbca12205f4..78a4042d8761c14baf0fbfa85560e8262b35cd0c 100644 (file)
@@ -7,7 +7,6 @@ obj-$(CONFIG_CRYPTO_AES_ARM) += aes-arm.o
 obj-$(CONFIG_CRYPTO_AES_ARM_BS) += aes-arm-bs.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM) += sha1-arm.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM_NEON) += sha1-arm-neon.o
-obj-$(CONFIG_CRYPTO_SHA512_ARM) += sha512-arm.o
 obj-$(CONFIG_CRYPTO_BLAKE2B_NEON) += blake2b-neon.o
 obj-$(CONFIG_CRYPTO_NHPOLY1305_NEON) += nhpoly1305-neon.o
 obj-$(CONFIG_CRYPTO_CURVE25519_NEON) += curve25519-neon.o
@@ -20,23 +19,9 @@ aes-arm-y    := aes-cipher-core.o aes-cipher-glue.o
 aes-arm-bs-y   := aes-neonbs-core.o aes-neonbs-glue.o
 sha1-arm-y     := sha1-armv4-large.o sha1_glue.o
 sha1-arm-neon-y        := sha1-armv7-neon.o sha1_neon_glue.o
-sha512-arm-neon-$(CONFIG_KERNEL_MODE_NEON) := sha512-neon-glue.o
-sha512-arm-y   := sha512-core.o sha512-glue.o $(sha512-arm-neon-y)
 blake2b-neon-y  := blake2b-neon-core.o blake2b-neon-glue.o
 sha1-arm-ce-y  := sha1-ce-core.o sha1-ce-glue.o
 aes-arm-ce-y   := aes-ce-core.o aes-ce-glue.o
 ghash-arm-ce-y := ghash-ce-core.o ghash-ce-glue.o
 nhpoly1305-neon-y := nh-neon-core.o nhpoly1305-neon-glue.o
 curve25519-neon-y := curve25519-core.o curve25519-glue.o
-
-quiet_cmd_perl = PERL    $@
-      cmd_perl = $(PERL) $(<) > $(@)
-
-$(obj)/%-core.S: $(src)/%-armv4.pl
-       $(call cmd,perl)
-
-clean-files += sha512-core.S
-
-aflags-thumb2-$(CONFIG_THUMB2_KERNEL)  := -U__thumb2__ -D__thumb2__=1
-
-AFLAGS_sha512-core.o += $(aflags-thumb2-y)
diff --git a/arch/arm/crypto/sha512-glue.c b/arch/arm/crypto/sha512-glue.c
deleted file mode 100644 (file)
index f8a6480..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * sha512-glue.c - accelerated SHA-384/512 for ARM
- *
- * Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@linaro.org>
- */
-
-#include <asm/hwcap.h>
-#include <asm/neon.h>
-#include <crypto/internal/hash.h>
-#include <crypto/sha2.h>
-#include <crypto/sha512_base.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include "sha512.h"
-
-MODULE_DESCRIPTION("Accelerated SHA-384/SHA-512 secure hash for ARM");
-MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
-MODULE_LICENSE("GPL v2");
-
-MODULE_ALIAS_CRYPTO("sha384");
-MODULE_ALIAS_CRYPTO("sha512");
-MODULE_ALIAS_CRYPTO("sha384-arm");
-MODULE_ALIAS_CRYPTO("sha512-arm");
-
-asmlinkage void sha512_block_data_order(struct sha512_state *state,
-                                       u8 const *src, int blocks);
-
-static int sha512_arm_update(struct shash_desc *desc, const u8 *data,
-                            unsigned int len)
-{
-       return sha512_base_do_update_blocks(desc, data, len,
-                                           sha512_block_data_order);
-}
-
-static int sha512_arm_finup(struct shash_desc *desc, const u8 *data,
-                           unsigned int len, u8 *out)
-{
-       sha512_base_do_finup(desc, data, len, sha512_block_data_order);
-       return sha512_base_finish(desc, out);
-}
-
-static struct shash_alg sha512_arm_algs[] = { {
-       .init                   = sha384_base_init,
-       .update                 = sha512_arm_update,
-       .finup                  = sha512_arm_finup,
-       .descsize               = SHA512_STATE_SIZE,
-       .digestsize             = SHA384_DIGEST_SIZE,
-       .base                   = {
-               .cra_name               = "sha384",
-               .cra_driver_name        = "sha384-arm",
-               .cra_priority           = 250,
-               .cra_flags              = CRYPTO_AHASH_ALG_BLOCK_ONLY |
-                                         CRYPTO_AHASH_ALG_FINUP_MAX,
-               .cra_blocksize          = SHA512_BLOCK_SIZE,
-               .cra_module             = THIS_MODULE,
-       }
-},  {
-       .init                   = sha512_base_init,
-       .update                 = sha512_arm_update,
-       .finup                  = sha512_arm_finup,
-       .descsize               = SHA512_STATE_SIZE,
-       .digestsize             = SHA512_DIGEST_SIZE,
-       .base                   = {
-               .cra_name               = "sha512",
-               .cra_driver_name        = "sha512-arm",
-               .cra_priority           = 250,
-               .cra_flags              = CRYPTO_AHASH_ALG_BLOCK_ONLY |
-                                         CRYPTO_AHASH_ALG_FINUP_MAX,
-               .cra_blocksize          = SHA512_BLOCK_SIZE,
-               .cra_module             = THIS_MODULE,
-       }
-} };
-
-static int __init sha512_arm_mod_init(void)
-{
-       int err;
-
-       err = crypto_register_shashes(sha512_arm_algs,
-                                     ARRAY_SIZE(sha512_arm_algs));
-       if (err)
-               return err;
-
-       if (IS_ENABLED(CONFIG_KERNEL_MODE_NEON) && cpu_has_neon()) {
-               err = crypto_register_shashes(sha512_neon_algs,
-                                             ARRAY_SIZE(sha512_neon_algs));
-               if (err)
-                       goto err_unregister;
-       }
-       return 0;
-
-err_unregister:
-       crypto_unregister_shashes(sha512_arm_algs,
-                                 ARRAY_SIZE(sha512_arm_algs));
-
-       return err;
-}
-
-static void __exit sha512_arm_mod_fini(void)
-{
-       crypto_unregister_shashes(sha512_arm_algs,
-                                 ARRAY_SIZE(sha512_arm_algs));
-       if (IS_ENABLED(CONFIG_KERNEL_MODE_NEON) && cpu_has_neon())
-               crypto_unregister_shashes(sha512_neon_algs,
-                                         ARRAY_SIZE(sha512_neon_algs));
-}
-
-module_init(sha512_arm_mod_init);
-module_exit(sha512_arm_mod_fini);
diff --git a/arch/arm/crypto/sha512-neon-glue.c b/arch/arm/crypto/sha512-neon-glue.c
deleted file mode 100644 (file)
index bd52807..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * sha512-neon-glue.c - accelerated SHA-384/512 for ARM NEON
- *
- * Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@linaro.org>
- */
-
-#include <asm/neon.h>
-#include <crypto/internal/hash.h>
-#include <crypto/sha2.h>
-#include <crypto/sha512_base.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include "sha512.h"
-
-MODULE_ALIAS_CRYPTO("sha384-neon");
-MODULE_ALIAS_CRYPTO("sha512-neon");
-
-asmlinkage void sha512_block_data_order_neon(struct sha512_state *state,
-                                            const u8 *src, int blocks);
-
-static int sha512_neon_update(struct shash_desc *desc, const u8 *data,
-                             unsigned int len)
-{
-       int remain;
-
-       kernel_neon_begin();
-       remain = sha512_base_do_update_blocks(desc, data, len,
-                                             sha512_block_data_order_neon);
-       kernel_neon_end();
-       return remain;
-}
-
-static int sha512_neon_finup(struct shash_desc *desc, const u8 *data,
-                            unsigned int len, u8 *out)
-{
-       kernel_neon_begin();
-       sha512_base_do_finup(desc, data, len, sha512_block_data_order_neon);
-       kernel_neon_end();
-       return sha512_base_finish(desc, out);
-}
-
-struct shash_alg sha512_neon_algs[] = { {
-       .init                   = sha384_base_init,
-       .update                 = sha512_neon_update,
-       .finup                  = sha512_neon_finup,
-       .descsize               = SHA512_STATE_SIZE,
-       .digestsize             = SHA384_DIGEST_SIZE,
-       .base                   = {
-               .cra_name               = "sha384",
-               .cra_driver_name        = "sha384-neon",
-               .cra_priority           = 300,
-               .cra_flags              = CRYPTO_AHASH_ALG_BLOCK_ONLY |
-                                         CRYPTO_AHASH_ALG_FINUP_MAX,
-               .cra_blocksize          = SHA384_BLOCK_SIZE,
-               .cra_module             = THIS_MODULE,
-
-       }
-},  {
-       .init                   = sha512_base_init,
-       .update                 = sha512_neon_update,
-       .finup                  = sha512_neon_finup,
-       .descsize               = SHA512_STATE_SIZE,
-       .digestsize             = SHA512_DIGEST_SIZE,
-       .base                   = {
-               .cra_name               = "sha512",
-               .cra_driver_name        = "sha512-neon",
-               .cra_priority           = 300,
-               .cra_flags              = CRYPTO_AHASH_ALG_BLOCK_ONLY |
-                                         CRYPTO_AHASH_ALG_FINUP_MAX,
-               .cra_blocksize          = SHA512_BLOCK_SIZE,
-               .cra_module             = THIS_MODULE,
-       }
-} };
diff --git a/arch/arm/crypto/sha512.h b/arch/arm/crypto/sha512.h
deleted file mode 100644 (file)
index eeaee52..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-extern struct shash_alg sha512_neon_algs[2];
index d1bee3787eb3cea03d77b30628f57d46d93cb8d2..dac6356ba0aace355879f1781885c7f9db5c2cd2 100644 (file)
@@ -177,6 +177,7 @@ config CRYPTO_LIB_SHA512
 config CRYPTO_LIB_SHA512_ARCH
        bool
        depends on CRYPTO_LIB_SHA512 && !UML
+       default y if ARM && !CPU_V7M
 
 config CRYPTO_LIB_SM3
        tristate
index f6b6f370451ecc5926c9520a29df692948c47e55..67008a1612c6f68c0795e53c4570e9a23c459778 100644 (file)
@@ -1,5 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0
 
+aflags-thumb2-$(CONFIG_THUMB2_KERNEL)  := -U__thumb2__ -D__thumb2__=1
+
+quiet_cmd_perlasm = PERLASM $@
+      cmd_perlasm = $(PERL) $(<) > $(@)
+
 obj-$(CONFIG_CRYPTO_LIB_UTILS)                 += libcryptoutils.o
 libcryptoutils-y                               := memneq.o utils.o
 
@@ -68,6 +73,15 @@ obj-$(CONFIG_CRYPTO_LIB_SHA512) += libsha512.o
 libsha512-y := sha512.o
 ifeq ($(CONFIG_CRYPTO_LIB_SHA512_ARCH),y)
 CFLAGS_sha512.o += -I$(src)/$(SRCARCH)
+
+ifeq ($(CONFIG_ARM),y)
+libsha512-y += arm/sha512-core.o
+$(obj)/arm/sha512-core.S: $(src)/arm/sha512-armv4.pl
+       $(call cmd,perlasm)
+clean-files += arm/sha512-core.S
+AFLAGS_arm/sha512-core.o += $(aflags-thumb2-y)
+endif
+
 endif # CONFIG_CRYPTO_LIB_SHA512_ARCH
 
 obj-$(CONFIG_MPILIB) += mpi/
diff --git a/lib/crypto/arm/.gitignore b/lib/crypto/arm/.gitignore
new file mode 100644 (file)
index 0000000..670a4d9
--- /dev/null
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+sha512-core.S
diff --git a/lib/crypto/arm/sha512.h b/lib/crypto/arm/sha512.h
new file mode 100644 (file)
index 0000000..f147b64
--- /dev/null
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * arm32-optimized SHA-512 block function
+ *
+ * Copyright 2025 Google LLC
+ */
+
+#include <asm/neon.h>
+#include <crypto/internal/simd.h>
+
+static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_neon);
+
+asmlinkage void sha512_block_data_order(struct sha512_block_state *state,
+                                       const u8 *data, size_t nblocks);
+asmlinkage void sha512_block_data_order_neon(struct sha512_block_state *state,
+                                            const u8 *data, size_t nblocks);
+
+static void sha512_blocks(struct sha512_block_state *state,
+                         const u8 *data, size_t nblocks)
+{
+       if (IS_ENABLED(CONFIG_KERNEL_MODE_NEON) &&
+           static_branch_likely(&have_neon) && likely(crypto_simd_usable())) {
+               kernel_neon_begin();
+               sha512_block_data_order_neon(state, data, nblocks);
+               kernel_neon_end();
+       } else {
+               sha512_block_data_order(state, data, nblocks);
+       }
+}
+
+#ifdef CONFIG_KERNEL_MODE_NEON
+#define sha512_mod_init_arch sha512_mod_init_arch
+static inline void sha512_mod_init_arch(void)
+{
+       if (cpu_has_neon())
+               static_branch_enable(&have_neon);
+}
+#endif /* CONFIG_KERNEL_MODE_NEON */