Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lib/crypto: sparc/sha1: Migrate optimized code into library

Instead of exposing the sparc-optimized SHA-1 code via sparc-specific
crypto_shash algorithms, instead just implement the sha1_blocks()
library function. This is much simpler, it makes the SHA-1 library
functions be sparc-optimized, and it fixes the longstanding issue where
the sparc-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/sparc/crypto/sha1_glue.c to
lib/crypto/sparc/sha1.h, view this commit with 'git show -M10'.

Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20250712232329.818226-13-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>

+45 -106
-10
arch/sparc/crypto/Kconfig
··· 26 26 27 27 Architecture: sparc64 using crypto instructions, when available 28 28 29 - config CRYPTO_SHA1_SPARC64 30 - tristate "Hash functions: SHA-1" 31 - depends on SPARC64 32 - select CRYPTO_SHA1 33 - select CRYPTO_HASH 34 - help 35 - SHA-1 secure hash algorithm (FIPS 180) 36 - 37 - Architecture: sparc64 38 - 39 29 config CRYPTO_AES_SPARC64 40 30 tristate "Ciphers: AES, modes: ECB, CBC, CTR" 41 31 depends on SPARC64
-2
arch/sparc/crypto/Makefile
··· 3 3 # Arch-specific CryptoAPI modules. 4 4 # 5 5 6 - obj-$(CONFIG_CRYPTO_SHA1_SPARC64) += sha1-sparc64.o 7 6 obj-$(CONFIG_CRYPTO_MD5_SPARC64) += md5-sparc64.o 8 7 9 8 obj-$(CONFIG_CRYPTO_AES_SPARC64) += aes-sparc64.o 10 9 obj-$(CONFIG_CRYPTO_DES_SPARC64) += des-sparc64.o 11 10 obj-$(CONFIG_CRYPTO_CAMELLIA_SPARC64) += camellia-sparc64.o 12 11 13 - sha1-sparc64-y := sha1_asm.o sha1_glue.o 14 12 md5-sparc64-y := md5_asm.o md5_glue.o 15 13 16 14 aes-sparc64-y := aes_asm.o aes_glue.o
arch/sparc/crypto/sha1_asm.S lib/crypto/sparc/sha1_asm.S
-94
arch/sparc/crypto/sha1_glue.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* Glue code for SHA1 hashing optimized for sparc64 crypto opcodes. 3 - * 4 - * This is based largely upon arch/x86/crypto/sha1_ssse3_glue.c 5 - * 6 - * Copyright (c) Alan Smithee. 7 - * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk> 8 - * Copyright (c) Jean-Francois Dive <jef@linuxbe.org> 9 - * Copyright (c) Mathias Krause <minipli@googlemail.com> 10 - */ 11 - 12 - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 13 - 14 - #include <asm/elf.h> 15 - #include <asm/opcodes.h> 16 - #include <asm/pstate.h> 17 - #include <crypto/internal/hash.h> 18 - #include <crypto/sha1.h> 19 - #include <crypto/sha1_base.h> 20 - #include <linux/kernel.h> 21 - #include <linux/module.h> 22 - 23 - asmlinkage void sha1_sparc64_transform(struct sha1_state *digest, 24 - const u8 *data, int rounds); 25 - 26 - static int sha1_sparc64_update(struct shash_desc *desc, const u8 *data, 27 - unsigned int len) 28 - { 29 - return sha1_base_do_update_blocks(desc, data, len, 30 - sha1_sparc64_transform); 31 - } 32 - 33 - /* Add padding and return the message digest. */ 34 - static int sha1_sparc64_finup(struct shash_desc *desc, const u8 *src, 35 - unsigned int len, u8 *out) 36 - { 37 - sha1_base_do_finup(desc, src, len, sha1_sparc64_transform); 38 - return sha1_base_finish(desc, out); 39 - } 40 - 41 - static struct shash_alg alg = { 42 - .digestsize = SHA1_DIGEST_SIZE, 43 - .init = sha1_base_init, 44 - .update = sha1_sparc64_update, 45 - .finup = sha1_sparc64_finup, 46 - .descsize = SHA1_STATE_SIZE, 47 - .base = { 48 - .cra_name = "sha1", 49 - .cra_driver_name= "sha1-sparc64", 50 - .cra_priority = SPARC_CR_OPCODE_PRIORITY, 51 - .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY, 52 - .cra_blocksize = SHA1_BLOCK_SIZE, 53 - .cra_module = THIS_MODULE, 54 - } 55 - }; 56 - 57 - static bool __init sparc64_has_sha1_opcode(void) 58 - { 59 - unsigned long cfr; 60 - 61 - if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO)) 62 - return false; 63 - 64 - __asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr)); 65 - if (!(cfr & CFR_SHA1)) 66 - return false; 67 - 68 - return true; 69 - } 70 - 71 - static int __init sha1_sparc64_mod_init(void) 72 - { 73 - if (sparc64_has_sha1_opcode()) { 74 - pr_info("Using sparc64 sha1 opcode optimized SHA-1 implementation\n"); 75 - return crypto_register_shash(&alg); 76 - } 77 - pr_info("sparc64 sha1 opcode not available.\n"); 78 - return -ENODEV; 79 - } 80 - 81 - static void __exit sha1_sparc64_mod_fini(void) 82 - { 83 - crypto_unregister_shash(&alg); 84 - } 85 - 86 - module_init(sha1_sparc64_mod_init); 87 - module_exit(sha1_sparc64_mod_fini); 88 - 89 - MODULE_LICENSE("GPL"); 90 - MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, sparc64 sha1 opcode accelerated"); 91 - 92 - MODULE_ALIAS_CRYPTO("sha1"); 93 - 94 - #include "crop_devid.c"
+1
lib/crypto/Kconfig
··· 151 151 default y if MIPS && CPU_CAVIUM_OCTEON 152 152 default y if PPC 153 153 default y if S390 154 + default y if SPARC64 154 155 155 156 config CRYPTO_LIB_SHA256 156 157 tristate
+1
lib/crypto/Makefile
··· 81 81 libsha1-y += powerpc/sha1-powerpc-asm.o 82 82 libsha1-$(CONFIG_SPE) += powerpc/sha1-spe-asm.o 83 83 endif 84 + libsha1-$(CONFIG_SPARC) += sparc/sha1_asm.o 84 85 endif # CONFIG_CRYPTO_LIB_SHA1_ARCH 85 86 86 87 ################################################################################
+43
lib/crypto/sparc/sha1.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * SHA-1 accelerated using the sparc64 crypto opcodes 4 + * 5 + * Copyright (c) Alan Smithee. 6 + * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk> 7 + * Copyright (c) Jean-Francois Dive <jef@linuxbe.org> 8 + * Copyright (c) Mathias Krause <minipli@googlemail.com> 9 + */ 10 + 11 + #include <asm/elf.h> 12 + #include <asm/opcodes.h> 13 + #include <asm/pstate.h> 14 + 15 + static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_sha1_opcodes); 16 + 17 + asmlinkage void sha1_sparc64_transform(struct sha1_block_state *state, 18 + const u8 *data, size_t nblocks); 19 + 20 + static void sha1_blocks(struct sha1_block_state *state, 21 + const u8 *data, size_t nblocks) 22 + { 23 + if (static_branch_likely(&have_sha1_opcodes)) 24 + sha1_sparc64_transform(state, data, nblocks); 25 + else 26 + sha1_blocks_generic(state, data, nblocks); 27 + } 28 + 29 + #define sha1_mod_init_arch sha1_mod_init_arch 30 + static inline void sha1_mod_init_arch(void) 31 + { 32 + unsigned long cfr; 33 + 34 + if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO)) 35 + return; 36 + 37 + __asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr)); 38 + if (!(cfr & CFR_SHA1)) 39 + return; 40 + 41 + static_branch_enable(&have_sha1_opcodes); 42 + pr_info("Using sparc64 sha1 opcode optimized SHA-1 implementation\n"); 43 + }