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

Note: to see the diff from
arch/mips/cavium-octeon/crypto/octeon-sha512.c to
lib/crypto/mips/sha512.h, view this commit with 'git show -M10'.

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

index db26c73fa0edaf794de7ab4c7df140ba8d63ad0b..168b19ef7ce89ff12c13046e707353e9f923b053 100644 (file)
@@ -8,4 +8,3 @@ obj-y += octeon-crypto.o
 obj-$(CONFIG_CRYPTO_MD5_OCTEON)                += octeon-md5.o
 obj-$(CONFIG_CRYPTO_SHA1_OCTEON)       += octeon-sha1.o
 obj-$(CONFIG_CRYPTO_SHA256_OCTEON)     += octeon-sha256.o
-obj-$(CONFIG_CRYPTO_SHA512_OCTEON)     += octeon-sha512.o
diff --git a/arch/mips/cavium-octeon/crypto/octeon-sha512.c b/arch/mips/cavium-octeon/crypto/octeon-sha512.c
deleted file mode 100644 (file)
index 53de74f..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Cryptographic API.
- *
- * SHA-512 and SHA-384 Secure Hash Algorithm.
- *
- * Adapted for OCTEON by Aaro Koskinen <aaro.koskinen@iki.fi>.
- *
- * Based on crypto/sha512_generic.c, which is:
- *
- * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
- * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
- * Copyright (c) 2003 Kyle McMartin <kyle@debian.org>
- */
-
-#include <asm/octeon/crypto.h>
-#include <asm/octeon/octeon.h>
-#include <crypto/internal/hash.h>
-#include <crypto/sha2.h>
-#include <crypto/sha512_base.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-/*
- * We pass everything as 64-bit. OCTEON can handle misaligned data.
- */
-
-static void octeon_sha512_store_hash(struct sha512_state *sctx)
-{
-       write_octeon_64bit_hash_sha512(sctx->state[0], 0);
-       write_octeon_64bit_hash_sha512(sctx->state[1], 1);
-       write_octeon_64bit_hash_sha512(sctx->state[2], 2);
-       write_octeon_64bit_hash_sha512(sctx->state[3], 3);
-       write_octeon_64bit_hash_sha512(sctx->state[4], 4);
-       write_octeon_64bit_hash_sha512(sctx->state[5], 5);
-       write_octeon_64bit_hash_sha512(sctx->state[6], 6);
-       write_octeon_64bit_hash_sha512(sctx->state[7], 7);
-}
-
-static void octeon_sha512_read_hash(struct sha512_state *sctx)
-{
-       sctx->state[0] = read_octeon_64bit_hash_sha512(0);
-       sctx->state[1] = read_octeon_64bit_hash_sha512(1);
-       sctx->state[2] = read_octeon_64bit_hash_sha512(2);
-       sctx->state[3] = read_octeon_64bit_hash_sha512(3);
-       sctx->state[4] = read_octeon_64bit_hash_sha512(4);
-       sctx->state[5] = read_octeon_64bit_hash_sha512(5);
-       sctx->state[6] = read_octeon_64bit_hash_sha512(6);
-       sctx->state[7] = read_octeon_64bit_hash_sha512(7);
-}
-
-static void octeon_sha512_transform(struct sha512_state *sctx,
-                                   const u8 *src, int blocks)
-{
-       do {
-               const u64 *block = (const u64 *)src;
-
-               write_octeon_64bit_block_sha512(block[0], 0);
-               write_octeon_64bit_block_sha512(block[1], 1);
-               write_octeon_64bit_block_sha512(block[2], 2);
-               write_octeon_64bit_block_sha512(block[3], 3);
-               write_octeon_64bit_block_sha512(block[4], 4);
-               write_octeon_64bit_block_sha512(block[5], 5);
-               write_octeon_64bit_block_sha512(block[6], 6);
-               write_octeon_64bit_block_sha512(block[7], 7);
-               write_octeon_64bit_block_sha512(block[8], 8);
-               write_octeon_64bit_block_sha512(block[9], 9);
-               write_octeon_64bit_block_sha512(block[10], 10);
-               write_octeon_64bit_block_sha512(block[11], 11);
-               write_octeon_64bit_block_sha512(block[12], 12);
-               write_octeon_64bit_block_sha512(block[13], 13);
-               write_octeon_64bit_block_sha512(block[14], 14);
-               octeon_sha512_start(block[15]);
-
-               src += SHA512_BLOCK_SIZE;
-       } while (--blocks);
-}
-
-static int octeon_sha512_update(struct shash_desc *desc, const u8 *data,
-                               unsigned int len)
-{
-       struct sha512_state *sctx = shash_desc_ctx(desc);
-       struct octeon_cop2_state state;
-       unsigned long flags;
-       int remain;
-
-       flags = octeon_crypto_enable(&state);
-       octeon_sha512_store_hash(sctx);
-
-       remain = sha512_base_do_update_blocks(desc, data, len,
-                                             octeon_sha512_transform);
-
-       octeon_sha512_read_hash(sctx);
-       octeon_crypto_disable(&state, flags);
-       return remain;
-}
-
-static int octeon_sha512_finup(struct shash_desc *desc, const u8 *src,
-                              unsigned int len, u8 *hash)
-{
-       struct sha512_state *sctx = shash_desc_ctx(desc);
-       struct octeon_cop2_state state;
-       unsigned long flags;
-
-       flags = octeon_crypto_enable(&state);
-       octeon_sha512_store_hash(sctx);
-
-       sha512_base_do_finup(desc, src, len, octeon_sha512_transform);
-
-       octeon_sha512_read_hash(sctx);
-       octeon_crypto_disable(&state, flags);
-       return sha512_base_finish(desc, hash);
-}
-
-static struct shash_alg octeon_sha512_algs[2] = { {
-       .digestsize     =       SHA512_DIGEST_SIZE,
-       .init           =       sha512_base_init,
-       .update         =       octeon_sha512_update,
-       .finup          =       octeon_sha512_finup,
-       .descsize       =       SHA512_STATE_SIZE,
-       .base           =       {
-               .cra_name       =       "sha512",
-               .cra_driver_name=       "octeon-sha512",
-               .cra_priority   =       OCTEON_CR_OPCODE_PRIORITY,
-               .cra_flags      =       CRYPTO_AHASH_ALG_BLOCK_ONLY |
-                                       CRYPTO_AHASH_ALG_FINUP_MAX,
-               .cra_blocksize  =       SHA512_BLOCK_SIZE,
-               .cra_module     =       THIS_MODULE,
-       }
-}, {
-       .digestsize     =       SHA384_DIGEST_SIZE,
-       .init           =       sha384_base_init,
-       .update         =       octeon_sha512_update,
-       .finup          =       octeon_sha512_finup,
-       .descsize       =       SHA512_STATE_SIZE,
-       .base           =       {
-               .cra_name       =       "sha384",
-               .cra_driver_name=       "octeon-sha384",
-               .cra_priority   =       OCTEON_CR_OPCODE_PRIORITY,
-               .cra_flags      =       CRYPTO_AHASH_ALG_BLOCK_ONLY |
-                                       CRYPTO_AHASH_ALG_FINUP_MAX,
-               .cra_blocksize  =       SHA384_BLOCK_SIZE,
-               .cra_module     =       THIS_MODULE,
-       }
-} };
-
-static int __init octeon_sha512_mod_init(void)
-{
-       if (!octeon_has_crypto())
-               return -ENOTSUPP;
-       return crypto_register_shashes(octeon_sha512_algs,
-                                      ARRAY_SIZE(octeon_sha512_algs));
-}
-
-static void __exit octeon_sha512_mod_fini(void)
-{
-       crypto_unregister_shashes(octeon_sha512_algs,
-                                 ARRAY_SIZE(octeon_sha512_algs));
-}
-
-module_init(octeon_sha512_mod_init);
-module_exit(octeon_sha512_mod_fini);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("SHA-512 and SHA-384 Secure Hash Algorithms (OCTEON)");
-MODULE_AUTHOR("Aaro Koskinen <aaro.koskinen@iki.fi>");
index 88ae0aa85364b10970da00c7bdb0d91d87d77cb6..effdfb2bb738b40fe053c6c37ee78d0e53127ec8 100644 (file)
@@ -157,7 +157,6 @@ CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_MD5_OCTEON=y
 CONFIG_CRYPTO_SHA1_OCTEON=m
-CONFIG_CRYPTO_SHA512_OCTEON=m
 CONFIG_CRYPTO_DES=y
 CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
 CONFIG_DEBUG_FS=y
index 6bf073ae7613f544ac73bd098fa1c2b64aed357f..51a76a5ee3b16802a6aa3f720156731f1c7a51c0 100644 (file)
@@ -22,14 +22,4 @@ config CRYPTO_SHA1_OCTEON
 
          Architecture: mips OCTEON
 
-config CRYPTO_SHA512_OCTEON
-       tristate "Hash functions: SHA-384 and SHA-512 (OCTEON)"
-       depends on CPU_CAVIUM_OCTEON
-       select CRYPTO_SHA512
-       select CRYPTO_HASH
-       help
-         SHA-384 and SHA-512 secure hash algorithms (FIPS 180)
-
-         Architecture: mips OCTEON using crypto instructions, when available
-
 endmenu
index 26413f679fab279298d5fc2f09730a38669f6c36..303ea15e3e900993acafa2bfb7a13ca4824cac93 100644 (file)
@@ -179,6 +179,7 @@ config CRYPTO_LIB_SHA512_ARCH
        depends on CRYPTO_LIB_SHA512 && !UML
        default y if ARM && !CPU_V7M
        default y if ARM64
+       default y if MIPS && CPU_CAVIUM_OCTEON
 
 config CRYPTO_LIB_SM3
        tristate
diff --git a/lib/crypto/mips/sha512.h b/lib/crypto/mips/sha512.h
new file mode 100644 (file)
index 0000000..b3ffbc1
--- /dev/null
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Cryptographic API.
+ *
+ * SHA-512 and SHA-384 Secure Hash Algorithm.
+ *
+ * Adapted for OCTEON by Aaro Koskinen <aaro.koskinen@iki.fi>.
+ *
+ * Based on crypto/sha512_generic.c, which is:
+ *
+ * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
+ * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
+ * Copyright (c) 2003 Kyle McMartin <kyle@debian.org>
+ */
+
+#include <asm/octeon/crypto.h>
+#include <asm/octeon/octeon.h>
+
+/*
+ * We pass everything as 64-bit. OCTEON can handle misaligned data.
+ */
+
+static void sha512_blocks(struct sha512_block_state *state,
+                         const u8 *data, size_t nblocks)
+{
+       struct octeon_cop2_state cop2_state;
+       unsigned long flags;
+
+       if (!octeon_has_crypto())
+               return sha512_blocks_generic(state, data, nblocks);
+
+       flags = octeon_crypto_enable(&cop2_state);
+       write_octeon_64bit_hash_sha512(state->h[0], 0);
+       write_octeon_64bit_hash_sha512(state->h[1], 1);
+       write_octeon_64bit_hash_sha512(state->h[2], 2);
+       write_octeon_64bit_hash_sha512(state->h[3], 3);
+       write_octeon_64bit_hash_sha512(state->h[4], 4);
+       write_octeon_64bit_hash_sha512(state->h[5], 5);
+       write_octeon_64bit_hash_sha512(state->h[6], 6);
+       write_octeon_64bit_hash_sha512(state->h[7], 7);
+
+       do {
+               const u64 *block = (const u64 *)data;
+
+               write_octeon_64bit_block_sha512(block[0], 0);
+               write_octeon_64bit_block_sha512(block[1], 1);
+               write_octeon_64bit_block_sha512(block[2], 2);
+               write_octeon_64bit_block_sha512(block[3], 3);
+               write_octeon_64bit_block_sha512(block[4], 4);
+               write_octeon_64bit_block_sha512(block[5], 5);
+               write_octeon_64bit_block_sha512(block[6], 6);
+               write_octeon_64bit_block_sha512(block[7], 7);
+               write_octeon_64bit_block_sha512(block[8], 8);
+               write_octeon_64bit_block_sha512(block[9], 9);
+               write_octeon_64bit_block_sha512(block[10], 10);
+               write_octeon_64bit_block_sha512(block[11], 11);
+               write_octeon_64bit_block_sha512(block[12], 12);
+               write_octeon_64bit_block_sha512(block[13], 13);
+               write_octeon_64bit_block_sha512(block[14], 14);
+               octeon_sha512_start(block[15]);
+
+               data += SHA512_BLOCK_SIZE;
+       } while (--nblocks);
+
+       state->h[0] = read_octeon_64bit_hash_sha512(0);
+       state->h[1] = read_octeon_64bit_hash_sha512(1);
+       state->h[2] = read_octeon_64bit_hash_sha512(2);
+       state->h[3] = read_octeon_64bit_hash_sha512(3);
+       state->h[4] = read_octeon_64bit_hash_sha512(4);
+       state->h[5] = read_octeon_64bit_hash_sha512(5);
+       state->h[6] = read_octeon_64bit_hash_sha512(6);
+       state->h[7] = read_octeon_64bit_hash_sha512(7);
+       octeon_crypto_disable(&cop2_state, flags);
+}