]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
lib/crypto: powerpc/sha1: Migrate optimized code into library
authorEric Biggers <ebiggers@kernel.org>
Sat, 12 Jul 2025 23:23:01 +0000 (16:23 -0700)
committerEric Biggers <ebiggers@kernel.org>
Mon, 14 Jul 2025 18:11:49 +0000 (11:11 -0700)
Instead of exposing the powerpc-optimized SHA-1 code via
powerpc-specific crypto_shash algorithms, instead just implement the
sha1_blocks() library function.  This is much simpler, it makes the
SHA-1 library functions be powerpc-optimized, and it fixes the
longstanding issue where the powerpc-optimized SHA-1 code was disabled
by default.  SHA-1 still remains available through crypto_shash, but
individual architectures no longer need to handle it.

Note: to see the diff from arch/powerpc/crypto/sha1-spe-glue.c to
lib/crypto/powerpc/sha1.h, view this commit with 'git show -M10'.

Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20250712232329.818226-11-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
12 files changed:
arch/powerpc/configs/44x/akebono_defconfig
arch/powerpc/configs/powernv_defconfig
arch/powerpc/configs/ppc64_defconfig
arch/powerpc/crypto/Kconfig
arch/powerpc/crypto/Makefile
arch/powerpc/crypto/sha1-spe-glue.c [deleted file]
arch/powerpc/crypto/sha1.c [deleted file]
lib/crypto/Kconfig
lib/crypto/Makefile
lib/crypto/powerpc/sha1-powerpc-asm.S [moved from arch/powerpc/crypto/sha1-powerpc-asm.S with 100% similarity]
lib/crypto/powerpc/sha1-spe-asm.S [moved from arch/powerpc/crypto/sha1-spe-asm.S with 100% similarity]
lib/crypto/powerpc/sha1.h [new file with mode: 0644]

index fde4824f235efba835d48c30af6825c4c0ea5e24..1882eb2da354a721a6f67f901a134d7fbfee89e9 100644 (file)
@@ -128,6 +128,5 @@ CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0x00010000
 CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x33f
 CONFIG_CRYPTO_PCBC=y
 CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1_PPC=y
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_HW is not set
index 379229c982a493e3fdfad942fd4cc9f3b3effa7c..98f56e63ad21cb7ba5c3ef33f6d6b1190506ef42 100644 (file)
@@ -322,7 +322,6 @@ CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_MD5_PPC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_SHA1_PPC=m
 CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_ANUBIS=m
index 3423c405cad4b777a9d2ff543cb548a0defa3a29..dca67aae5da3c4278bb2bc2e54260648dcd02477 100644 (file)
@@ -388,7 +388,6 @@ CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_LZO=m
 CONFIG_CRYPTO_MD5_PPC=m
-CONFIG_CRYPTO_SHA1_PPC=m
 CONFIG_CRYPTO_AES_GCM_P10=m
 CONFIG_CRYPTO_DEV_NX=y
 CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
index caaa359f4742039f2cf52a10efb4aed8d325f0b7..cfe39fc221cf81fe54dec028ec445a973bf72929 100644 (file)
@@ -23,22 +23,6 @@ config CRYPTO_MD5_PPC
 
          Architecture: powerpc
 
-config CRYPTO_SHA1_PPC
-       tristate "Hash functions: SHA-1"
-       help
-         SHA-1 secure hash algorithm (FIPS 180)
-
-         Architecture: powerpc
-
-config CRYPTO_SHA1_PPC_SPE
-       tristate "Hash functions: SHA-1 (SPE)"
-       depends on SPE
-       help
-         SHA-1 secure hash algorithm (FIPS 180)
-
-         Architecture: powerpc using
-         - SPE (Signal Processing Engine) extensions
-
 config CRYPTO_AES_PPC_SPE
        tristate "Ciphers: AES, modes: ECB/CBC/CTR/XTS (SPE)"
        depends on SPE
index 8c2936ae466fcb8788a885a4594ad46238d064a5..bc8fd27344b8bbe0a1992416c3b850c98fa26bdb 100644 (file)
@@ -7,16 +7,12 @@
 
 obj-$(CONFIG_CRYPTO_AES_PPC_SPE) += aes-ppc-spe.o
 obj-$(CONFIG_CRYPTO_MD5_PPC) += md5-ppc.o
-obj-$(CONFIG_CRYPTO_SHA1_PPC) += sha1-powerpc.o
-obj-$(CONFIG_CRYPTO_SHA1_PPC_SPE) += sha1-ppc-spe.o
 obj-$(CONFIG_CRYPTO_AES_GCM_P10) += aes-gcm-p10-crypto.o
 obj-$(CONFIG_CRYPTO_DEV_VMX_ENCRYPT) += vmx-crypto.o
 obj-$(CONFIG_CRYPTO_CURVE25519_PPC64) += curve25519-ppc64le.o
 
 aes-ppc-spe-y := aes-spe-core.o aes-spe-keys.o aes-tab-4k.o aes-spe-modes.o aes-spe-glue.o
 md5-ppc-y := md5-asm.o md5-glue.o
-sha1-powerpc-y := sha1-powerpc-asm.o sha1.o
-sha1-ppc-spe-y := sha1-spe-asm.o sha1-spe-glue.o
 aes-gcm-p10-crypto-y := aes-gcm-p10-glue.o aes-gcm-p10.o ghashp10-ppc.o aesp10-ppc.o
 vmx-crypto-objs := vmx.o aesp8-ppc.o ghashp8-ppc.o aes.o aes_cbc.o aes_ctr.o aes_xts.o ghash.o
 curve25519-ppc64le-y := curve25519-ppc64le-core.o curve25519-ppc64le_asm.o
diff --git a/arch/powerpc/crypto/sha1-spe-glue.c b/arch/powerpc/crypto/sha1-spe-glue.c
deleted file mode 100644 (file)
index 04c88e1..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Glue code for SHA-1 implementation for SPE instructions (PPC)
- *
- * Based on generic implementation.
- *
- * Copyright (c) 2015 Markus Stockhausen <stockhausen@collogia.de>
- */
-
-#include <asm/switch_to.h>
-#include <crypto/internal/hash.h>
-#include <crypto/sha1.h>
-#include <crypto/sha1_base.h>
-#include <linux/kernel.h>
-#include <linux/preempt.h>
-#include <linux/module.h>
-
-/*
- * MAX_BYTES defines the number of bytes that are allowed to be processed
- * between preempt_disable() and preempt_enable(). SHA1 takes ~1000
- * operations per 64 bytes. e500 cores can issue two arithmetic instructions
- * per clock cycle using one 32/64 bit unit (SU1) and one 32 bit unit (SU2).
- * Thus 2KB of input data will need an estimated maximum of 18,000 cycles.
- * Headroom for cache misses included. Even with the low end model clocked
- * at 667 MHz this equals to a critical time window of less than 27us.
- *
- */
-#define MAX_BYTES 2048
-
-asmlinkage void ppc_spe_sha1_transform(u32 *state, const u8 *src, u32 blocks);
-
-static void spe_begin(void)
-{
-       /* We just start SPE operations and will save SPE registers later. */
-       preempt_disable();
-       enable_kernel_spe();
-}
-
-static void spe_end(void)
-{
-       disable_kernel_spe();
-       /* reenable preemption */
-       preempt_enable();
-}
-
-static void ppc_spe_sha1_block(struct sha1_state *sctx, const u8 *src,
-                              int blocks)
-{
-       do {
-               int unit = min(blocks, MAX_BYTES / SHA1_BLOCK_SIZE);
-
-               spe_begin();
-               ppc_spe_sha1_transform(sctx->state, src, unit);
-               spe_end();
-
-               src += unit * SHA1_BLOCK_SIZE;
-               blocks -= unit;
-       } while (blocks);
-}
-
-static int ppc_spe_sha1_update(struct shash_desc *desc, const u8 *data,
-                       unsigned int len)
-{
-       return sha1_base_do_update_blocks(desc, data, len, ppc_spe_sha1_block);
-}
-
-static int ppc_spe_sha1_finup(struct shash_desc *desc, const u8 *src,
-                             unsigned int len, u8 *out)
-{
-       sha1_base_do_finup(desc, src, len, ppc_spe_sha1_block);
-       return sha1_base_finish(desc, out);
-}
-
-static struct shash_alg alg = {
-       .digestsize     =       SHA1_DIGEST_SIZE,
-       .init           =       sha1_base_init,
-       .update         =       ppc_spe_sha1_update,
-       .finup          =       ppc_spe_sha1_finup,
-       .descsize       =       SHA1_STATE_SIZE,
-       .base           =       {
-               .cra_name       =       "sha1",
-               .cra_driver_name=       "sha1-ppc-spe",
-               .cra_priority   =       300,
-               .cra_flags      =       CRYPTO_AHASH_ALG_BLOCK_ONLY,
-               .cra_blocksize  =       SHA1_BLOCK_SIZE,
-               .cra_module     =       THIS_MODULE,
-       }
-};
-
-static int __init ppc_spe_sha1_mod_init(void)
-{
-       return crypto_register_shash(&alg);
-}
-
-static void __exit ppc_spe_sha1_mod_fini(void)
-{
-       crypto_unregister_shash(&alg);
-}
-
-module_init(ppc_spe_sha1_mod_init);
-module_exit(ppc_spe_sha1_mod_fini);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, SPE optimized");
-
-MODULE_ALIAS_CRYPTO("sha1");
-MODULE_ALIAS_CRYPTO("sha1-ppc-spe");
diff --git a/arch/powerpc/crypto/sha1.c b/arch/powerpc/crypto/sha1.c
deleted file mode 100644 (file)
index 4593946..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Cryptographic API.
- *
- * powerpc implementation of the SHA1 Secure Hash Algorithm.
- *
- * Derived from cryptoapi implementation, adapted for in-place
- * scatterlist interface.
- *
- * Derived from "crypto/sha1.c"
- * Copyright (c) Alan Smithee.
- * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
- * Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
- */
-#include <crypto/internal/hash.h>
-#include <crypto/sha1.h>
-#include <crypto/sha1_base.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-asmlinkage void powerpc_sha_transform(u32 *state, const u8 *src);
-
-static void powerpc_sha_block(struct sha1_state *sctx, const u8 *data,
-                             int blocks)
-{
-       do {
-               powerpc_sha_transform(sctx->state, data);
-               data += 64;
-       } while (--blocks);
-}
-
-static int powerpc_sha1_update(struct shash_desc *desc, const u8 *data,
-                              unsigned int len)
-{
-       return sha1_base_do_update_blocks(desc, data, len, powerpc_sha_block);
-}
-
-/* Add padding and return the message digest. */
-static int powerpc_sha1_finup(struct shash_desc *desc, const u8 *src,
-                             unsigned int len, u8 *out)
-{
-       sha1_base_do_finup(desc, src, len, powerpc_sha_block);
-       return sha1_base_finish(desc, out);
-}
-
-static struct shash_alg alg = {
-       .digestsize     =       SHA1_DIGEST_SIZE,
-       .init           =       sha1_base_init,
-       .update         =       powerpc_sha1_update,
-       .finup          =       powerpc_sha1_finup,
-       .descsize       =       SHA1_STATE_SIZE,
-       .base           =       {
-               .cra_name       =       "sha1",
-               .cra_driver_name=       "sha1-powerpc",
-               .cra_flags      =       CRYPTO_AHASH_ALG_BLOCK_ONLY,
-               .cra_blocksize  =       SHA1_BLOCK_SIZE,
-               .cra_module     =       THIS_MODULE,
-       }
-};
-
-static int __init sha1_powerpc_mod_init(void)
-{
-       return crypto_register_shash(&alg);
-}
-
-static void __exit sha1_powerpc_mod_fini(void)
-{
-       crypto_unregister_shash(&alg);
-}
-
-module_init(sha1_powerpc_mod_init);
-module_exit(sha1_powerpc_mod_fini);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm");
-
-MODULE_ALIAS_CRYPTO("sha1");
-MODULE_ALIAS_CRYPTO("sha1-powerpc");
index 7c9dc432fb4216fc4a110b324b8068791eed95d8..22ffbdab82d6ecd0be66434be88dbe6a2f9d933b 100644 (file)
@@ -149,6 +149,7 @@ config CRYPTO_LIB_SHA1_ARCH
        default y if ARM
        default y if ARM64 && KERNEL_MODE_NEON
        default y if MIPS && CPU_CAVIUM_OCTEON
+       default y if PPC
 
 config CRYPTO_LIB_SHA256
        tristate
index 1da13c9e2f711c4af74b3904767da2706860822d..02f672562928e1993fb2050fa4f02f69a3bdd892 100644 (file)
@@ -77,6 +77,10 @@ libsha1-$(CONFIG_KERNEL_MODE_NEON) += arm/sha1-armv7-neon.o \
                                      arm/sha1-ce-core.o
 endif
 libsha1-$(CONFIG_ARM64) += arm64/sha1-ce-core.o
+ifeq ($(CONFIG_PPC),y)
+libsha1-y += powerpc/sha1-powerpc-asm.o
+libsha1-$(CONFIG_SPE) += powerpc/sha1-spe-asm.o
+endif
 endif # CONFIG_CRYPTO_LIB_SHA1_ARCH
 
 ################################################################################
diff --git a/lib/crypto/powerpc/sha1.h b/lib/crypto/powerpc/sha1.h
new file mode 100644 (file)
index 0000000..e2c010f
--- /dev/null
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * SHA-1 optimized for PowerPC
+ *
+ * Copyright (c) 2015 Markus Stockhausen <stockhausen@collogia.de>
+ */
+
+#include <asm/switch_to.h>
+#include <linux/preempt.h>
+
+#ifdef CONFIG_SPE
+/*
+ * MAX_BYTES defines the number of bytes that are allowed to be processed
+ * between preempt_disable() and preempt_enable(). SHA1 takes ~1000
+ * operations per 64 bytes. e500 cores can issue two arithmetic instructions
+ * per clock cycle using one 32/64 bit unit (SU1) and one 32 bit unit (SU2).
+ * Thus 2KB of input data will need an estimated maximum of 18,000 cycles.
+ * Headroom for cache misses included. Even with the low end model clocked
+ * at 667 MHz this equals to a critical time window of less than 27us.
+ *
+ */
+#define MAX_BYTES 2048
+
+asmlinkage void ppc_spe_sha1_transform(struct sha1_block_state *state,
+                                      const u8 *data, u32 nblocks);
+
+static void spe_begin(void)
+{
+       /* We just start SPE operations and will save SPE registers later. */
+       preempt_disable();
+       enable_kernel_spe();
+}
+
+static void spe_end(void)
+{
+       disable_kernel_spe();
+       /* reenable preemption */
+       preempt_enable();
+}
+
+static void sha1_blocks(struct sha1_block_state *state,
+                       const u8 *data, size_t nblocks)
+{
+       do {
+               u32 unit = min_t(size_t, nblocks, MAX_BYTES / SHA1_BLOCK_SIZE);
+
+               spe_begin();
+               ppc_spe_sha1_transform(state, data, unit);
+               spe_end();
+
+               data += unit * SHA1_BLOCK_SIZE;
+               nblocks -= unit;
+       } while (nblocks);
+}
+#else /* CONFIG_SPE */
+asmlinkage void powerpc_sha_transform(struct sha1_block_state *state,
+                                     const u8 data[SHA1_BLOCK_SIZE]);
+
+static void sha1_blocks(struct sha1_block_state *state,
+                       const u8 *data, size_t nblocks)
+{
+       do {
+               powerpc_sha_transform(state, data);
+               data += SHA1_BLOCK_SIZE;
+       } while (--nblocks);
+}
+#endif /* !CONFIG_SPE */