1 // SPDX-License-Identifier: GPL-2.0-only 1 2 /* Glue code for SHA1 hashing optimized for sp 3 * 4 * This is based largely upon arch/x86/crypto/ 5 * 6 * Copyright (c) Alan Smithee. 7 * Copyright (c) Andrew McDonald <andrew@mcdon 8 * Copyright (c) Jean-Francois Dive <jef@linux 9 * Copyright (c) Mathias Krause <minipli@googl 10 */ 11 12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fm 13 14 #include <crypto/internal/hash.h> 15 #include <linux/init.h> 16 #include <linux/module.h> 17 #include <linux/mm.h> 18 #include <linux/types.h> 19 #include <crypto/sha1.h> 20 #include <crypto/sha1_base.h> 21 22 #include <asm/pstate.h> 23 #include <asm/elf.h> 24 25 #include "opcodes.h" 26 27 asmlinkage void sha1_sparc64_transform(u32 *di 28 unsigne 29 30 static void __sha1_sparc64_update(struct sha1_ 31 unsigned int 32 { 33 unsigned int done = 0; 34 35 sctx->count += len; 36 if (partial) { 37 done = SHA1_BLOCK_SIZE - parti 38 memcpy(sctx->buffer + partial, 39 sha1_sparc64_transform(sctx->s 40 } 41 if (len - done >= SHA1_BLOCK_SIZE) { 42 const unsigned int rounds = (l 43 44 sha1_sparc64_transform(sctx->s 45 done += rounds * SHA1_BLOCK_SI 46 } 47 48 memcpy(sctx->buffer, data + done, len 49 } 50 51 static int sha1_sparc64_update(struct shash_de 52 unsigned int le 53 { 54 struct sha1_state *sctx = shash_desc_c 55 unsigned int partial = sctx->count % S 56 57 /* Handle the fast case right here */ 58 if (partial + len < SHA1_BLOCK_SIZE) { 59 sctx->count += len; 60 memcpy(sctx->buffer + partial, 61 } else 62 __sha1_sparc64_update(sctx, da 63 64 return 0; 65 } 66 67 /* Add padding and return the message digest. 68 static int sha1_sparc64_final(struct shash_des 69 { 70 struct sha1_state *sctx = shash_desc_c 71 unsigned int i, index, padlen; 72 __be32 *dst = (__be32 *)out; 73 __be64 bits; 74 static const u8 padding[SHA1_BLOCK_SIZ 75 76 bits = cpu_to_be64(sctx->count << 3); 77 78 /* Pad out to 56 mod 64 and append len 79 index = sctx->count % SHA1_BLOCK_SIZE; 80 padlen = (index < 56) ? (56 - index) : 81 82 /* We need to fill a whole block for _ 83 if (padlen <= 56) { 84 sctx->count += padlen; 85 memcpy(sctx->buffer + index, p 86 } else { 87 __sha1_sparc64_update(sctx, pa 88 } 89 __sha1_sparc64_update(sctx, (const u8 90 91 /* Store state in digest */ 92 for (i = 0; i < 5; i++) 93 dst[i] = cpu_to_be32(sctx->sta 94 95 /* Wipe context */ 96 memset(sctx, 0, sizeof(*sctx)); 97 98 return 0; 99 } 100 101 static int sha1_sparc64_export(struct shash_de 102 { 103 struct sha1_state *sctx = shash_desc_c 104 105 memcpy(out, sctx, sizeof(*sctx)); 106 107 return 0; 108 } 109 110 static int sha1_sparc64_import(struct shash_de 111 { 112 struct sha1_state *sctx = shash_desc_c 113 114 memcpy(sctx, in, sizeof(*sctx)); 115 116 return 0; 117 } 118 119 static struct shash_alg alg = { 120 .digestsize = SHA1_DIGEST_SI 121 .init = sha1_base_init 122 .update = sha1_sparc64_u 123 .final = sha1_sparc64_f 124 .export = sha1_sparc64_e 125 .import = sha1_sparc64_i 126 .descsize = sizeof(struct 127 .statesize = sizeof(struct 128 .base = { 129 .cra_name = "sha1" 130 .cra_driver_name= "sha1- 131 .cra_priority = SPARC_ 132 .cra_blocksize = SHA1_B 133 .cra_module = THIS_M 134 } 135 }; 136 137 static bool __init sparc64_has_sha1_opcode(voi 138 { 139 unsigned long cfr; 140 141 if (!(sparc64_elf_hwcap & HWCAP_SPARC_ 142 return false; 143 144 __asm__ __volatile__("rd %%asr26, %0" 145 if (!(cfr & CFR_SHA1)) 146 return false; 147 148 return true; 149 } 150 151 static int __init sha1_sparc64_mod_init(void) 152 { 153 if (sparc64_has_sha1_opcode()) { 154 pr_info("Using sparc64 sha1 op 155 return crypto_register_shash(& 156 } 157 pr_info("sparc64 sha1 opcode not avail 158 return -ENODEV; 159 } 160 161 static void __exit sha1_sparc64_mod_fini(void) 162 { 163 crypto_unregister_shash(&alg); 164 } 165 166 module_init(sha1_sparc64_mod_init); 167 module_exit(sha1_sparc64_mod_fini); 168 169 MODULE_LICENSE("GPL"); 170 MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm 171 172 MODULE_ALIAS_CRYPTO("sha1"); 173 174 #include "crop_devid.c" 175
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.