1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * SHA-256 accelerated using the sparc64 sha256 opcodes 4 * 5 * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com> 6 * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk> 7 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> 8 * SHA224 Support Copyright 2007 Intel Corporation <jonathan.lynch@intel.com> 9 */ 10 11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 12 13 #include <asm/elf.h> 14 #include <asm/opcodes.h> 15 #include <asm/pstate.h> 16 #include <crypto/internal/sha2.h> 17 #include <linux/kernel.h> 18 #include <linux/module.h> 19 20 static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_sha256_opcodes); 21 22 asmlinkage void sha256_sparc64_transform(u32 state[SHA256_STATE_WORDS], 23 const u8 *data, size_t nblocks); 24 25 void sha256_blocks_arch(u32 state[SHA256_STATE_WORDS], 26 const u8 *data, size_t nblocks) 27 { 28 if (static_branch_likely(&have_sha256_opcodes)) 29 sha256_sparc64_transform(state, data, nblocks); 30 else 31 sha256_blocks_generic(state, data, nblocks); 32 } 33 EXPORT_SYMBOL_GPL(sha256_blocks_arch); 34 35 bool sha256_is_arch_optimized(void) 36 { 37 return static_key_enabled(&have_sha256_opcodes); 38 } 39 EXPORT_SYMBOL_GPL(sha256_is_arch_optimized); 40 41 static int __init sha256_sparc64_mod_init(void) 42 { 43 unsigned long cfr; 44 45 if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO)) 46 return 0; 47 48 __asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr)); 49 if (!(cfr & CFR_SHA256)) 50 return 0; 51 52 static_branch_enable(&have_sha256_opcodes); 53 pr_info("Using sparc64 sha256 opcode optimized SHA-256/SHA-224 implementation\n"); 54 return 0; 55 } 56 subsys_initcall(sha256_sparc64_mod_init); 57 58 static void __exit sha256_sparc64_mod_exit(void) 59 { 60 } 61 module_exit(sha256_sparc64_mod_exit); 62 63 MODULE_LICENSE("GPL"); 64 MODULE_DESCRIPTION("SHA-256 accelerated using the sparc64 sha256 opcodes"); 65