]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
lib/crypto: s390/sha512: Migrate optimized SHA-512 code to library
authorEric Biggers <ebiggers@kernel.org>
Mon, 30 Jun 2025 16:03:16 +0000 (09:03 -0700)
committerEric Biggers <ebiggers@kernel.org>
Mon, 30 Jun 2025 16:26:20 +0000 (09:26 -0700)
Instead of exposing the s390-optimized SHA-512 code via s390-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 s390-optimized, and it fixes the
longstanding issue where the s390-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.

Acked-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20250630160320.2888-13-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
arch/s390/configs/debug_defconfig
arch/s390/configs/defconfig
arch/s390/crypto/Kconfig
arch/s390/crypto/Makefile
arch/s390/crypto/sha512_s390.c [deleted file]
lib/crypto/Kconfig
lib/crypto/s390/sha512.h [new file with mode: 0644]

index 8ecad727497e1351dc66cc3f0f571143e1479ed8..ef313c30b375c2317a42975c64f110ef14390526 100644 (file)
@@ -804,7 +804,6 @@ CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
-CONFIG_CRYPTO_SHA512_S390=m
 CONFIG_CRYPTO_SHA1_S390=m
 CONFIG_CRYPTO_SHA3_256_S390=m
 CONFIG_CRYPTO_SHA3_512_S390=m
index c13a77765162a0493b54c991ef432f518894ac41..b6fa341bb03b60de2a844af673ad5aca7c7d2ab5 100644 (file)
@@ -791,7 +791,6 @@ CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
-CONFIG_CRYPTO_SHA512_S390=m
 CONFIG_CRYPTO_SHA1_S390=m
 CONFIG_CRYPTO_SHA3_256_S390=m
 CONFIG_CRYPTO_SHA3_512_S390=m
index e2c27588b21a9640a2d5d101c3e2a4a10a6ecd61..4557514fbac35481521a851da73688b606c427d1 100644 (file)
@@ -2,16 +2,6 @@
 
 menu "Accelerated Cryptographic Algorithms for CPU (s390)"
 
-config CRYPTO_SHA512_S390
-       tristate "Hash functions: SHA-384 and SHA-512"
-       select CRYPTO_HASH
-       help
-         SHA-384 and SHA-512 secure hash algorithms (FIPS 180)
-
-         Architecture: s390
-
-         It is available as of z10.
-
 config CRYPTO_SHA1_S390
        tristate "Hash functions: SHA-1"
        select CRYPTO_HASH
index 21757d86cd4995ea42c57c4fd4019d347ad1a5fc..473d64c0982af084730bddbf7816aa04f3230052 100644 (file)
@@ -4,7 +4,6 @@
 #
 
 obj-$(CONFIG_CRYPTO_SHA1_S390) += sha1_s390.o sha_common.o
-obj-$(CONFIG_CRYPTO_SHA512_S390) += sha512_s390.o sha_common.o
 obj-$(CONFIG_CRYPTO_SHA3_256_S390) += sha3_256_s390.o sha_common.o
 obj-$(CONFIG_CRYPTO_SHA3_512_S390) += sha3_512_s390.o sha_common.o
 obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o
diff --git a/arch/s390/crypto/sha512_s390.c b/arch/s390/crypto/sha512_s390.c
deleted file mode 100644 (file)
index e8bb172..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Cryptographic API.
- *
- * s390 implementation of the SHA512 and SHA38 Secure Hash Algorithm.
- *
- * Copyright IBM Corp. 2007
- * Author(s): Jan Glauber (jang@de.ibm.com)
- */
-#include <asm/cpacf.h>
-#include <crypto/internal/hash.h>
-#include <crypto/sha2.h>
-#include <linux/cpufeature.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include "sha.h"
-
-static int sha512_init_s390(struct shash_desc *desc)
-{
-       struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
-
-       ctx->sha512.state[0] = SHA512_H0;
-       ctx->sha512.state[1] = SHA512_H1;
-       ctx->sha512.state[2] = SHA512_H2;
-       ctx->sha512.state[3] = SHA512_H3;
-       ctx->sha512.state[4] = SHA512_H4;
-       ctx->sha512.state[5] = SHA512_H5;
-       ctx->sha512.state[6] = SHA512_H6;
-       ctx->sha512.state[7] = SHA512_H7;
-       ctx->count = 0;
-       ctx->sha512.count_hi = 0;
-       ctx->func = CPACF_KIMD_SHA_512;
-
-       return 0;
-}
-
-static int sha512_export(struct shash_desc *desc, void *out)
-{
-       struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
-       struct sha512_state *octx = out;
-
-       octx->count[0] = sctx->count;
-       octx->count[1] = sctx->sha512.count_hi;
-       memcpy(octx->state, sctx->state, sizeof(octx->state));
-       return 0;
-}
-
-static int sha512_import(struct shash_desc *desc, const void *in)
-{
-       struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
-       const struct sha512_state *ictx = in;
-
-       sctx->count = ictx->count[0];
-       sctx->sha512.count_hi = ictx->count[1];
-
-       memcpy(sctx->state, ictx->state, sizeof(ictx->state));
-       sctx->func = CPACF_KIMD_SHA_512;
-       return 0;
-}
-
-static struct shash_alg sha512_alg = {
-       .digestsize     =       SHA512_DIGEST_SIZE,
-       .init           =       sha512_init_s390,
-       .update         =       s390_sha_update_blocks,
-       .finup          =       s390_sha_finup,
-       .export         =       sha512_export,
-       .import         =       sha512_import,
-       .descsize       =       sizeof(struct s390_sha_ctx),
-       .statesize      =       SHA512_STATE_SIZE,
-       .base           =       {
-               .cra_name       =       "sha512",
-               .cra_driver_name=       "sha512-s390",
-               .cra_priority   =       300,
-               .cra_flags      =       CRYPTO_AHASH_ALG_BLOCK_ONLY |
-                                       CRYPTO_AHASH_ALG_FINUP_MAX,
-               .cra_blocksize  =       SHA512_BLOCK_SIZE,
-               .cra_module     =       THIS_MODULE,
-       }
-};
-
-MODULE_ALIAS_CRYPTO("sha512");
-
-static int sha384_init_s390(struct shash_desc *desc)
-{
-       struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
-
-       ctx->sha512.state[0] = SHA384_H0;
-       ctx->sha512.state[1] = SHA384_H1;
-       ctx->sha512.state[2] = SHA384_H2;
-       ctx->sha512.state[3] = SHA384_H3;
-       ctx->sha512.state[4] = SHA384_H4;
-       ctx->sha512.state[5] = SHA384_H5;
-       ctx->sha512.state[6] = SHA384_H6;
-       ctx->sha512.state[7] = SHA384_H7;
-       ctx->count = 0;
-       ctx->sha512.count_hi = 0;
-       ctx->func = CPACF_KIMD_SHA_512;
-
-       return 0;
-}
-
-static struct shash_alg sha384_alg = {
-       .digestsize     =       SHA384_DIGEST_SIZE,
-       .init           =       sha384_init_s390,
-       .update         =       s390_sha_update_blocks,
-       .finup          =       s390_sha_finup,
-       .export         =       sha512_export,
-       .import         =       sha512_import,
-       .descsize       =       sizeof(struct s390_sha_ctx),
-       .statesize      =       SHA512_STATE_SIZE,
-       .base           =       {
-               .cra_name       =       "sha384",
-               .cra_driver_name=       "sha384-s390",
-               .cra_priority   =       300,
-               .cra_blocksize  =       SHA384_BLOCK_SIZE,
-               .cra_flags      =       CRYPTO_AHASH_ALG_BLOCK_ONLY |
-                                       CRYPTO_AHASH_ALG_FINUP_MAX,
-               .cra_ctxsize    =       sizeof(struct s390_sha_ctx),
-               .cra_module     =       THIS_MODULE,
-       }
-};
-
-MODULE_ALIAS_CRYPTO("sha384");
-
-static int __init init(void)
-{
-       int ret;
-
-       if (!cpacf_query_func(CPACF_KIMD, CPACF_KIMD_SHA_512))
-               return -ENODEV;
-       if ((ret = crypto_register_shash(&sha512_alg)) < 0)
-               goto out;
-       if ((ret = crypto_register_shash(&sha384_alg)) < 0)
-               crypto_unregister_shash(&sha512_alg);
-out:
-       return ret;
-}
-
-static void __exit fini(void)
-{
-       crypto_unregister_shash(&sha512_alg);
-       crypto_unregister_shash(&sha384_alg);
-}
-
-module_cpu_feature_match(S390_CPU_FEATURE_MSA, init);
-module_exit(fini);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("SHA512 and SHA-384 Secure Hash Algorithm");
index 656f2c08c46cd189f4bd8c85ceaf3fc8348ad785..6f1386b8d79d0e86186fb7dd253a3bf906970a62 100644 (file)
@@ -181,6 +181,7 @@ config CRYPTO_LIB_SHA512_ARCH
        default y if ARM64
        default y if MIPS && CPU_CAVIUM_OCTEON
        default y if RISCV && 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+       default y if S390
 
 config CRYPTO_LIB_SM3
        tristate
diff --git a/lib/crypto/s390/sha512.h b/lib/crypto/s390/sha512.h
new file mode 100644 (file)
index 0000000..2474465
--- /dev/null
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * SHA-512 optimized using the CP Assist for Cryptographic Functions (CPACF)
+ *
+ * Copyright 2025 Google LLC
+ */
+#include <asm/cpacf.h>
+#include <linux/cpufeature.h>
+
+static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_cpacf_sha512);
+
+static void sha512_blocks(struct sha512_block_state *state,
+                         const u8 *data, size_t nblocks)
+{
+       if (static_branch_likely(&have_cpacf_sha512))
+               cpacf_kimd(CPACF_KIMD_SHA_512, state, data,
+                          nblocks * SHA512_BLOCK_SIZE);
+       else
+               sha512_blocks_generic(state, data, nblocks);
+}
+
+#define sha512_mod_init_arch sha512_mod_init_arch
+static inline void sha512_mod_init_arch(void)
+{
+       if (cpu_have_feature(S390_CPU_FEATURE_MSA) &&
+           cpacf_query_func(CPACF_KIMD, CPACF_KIMD_SHA_512))
+               static_branch_enable(&have_cpacf_sha512);
+}