1 // SPDX-License-Identifier: GPL-2.0-only 1 2 /* Glue code for SHA256 hashing optimized for 3 * 4 * This is based largely upon crypto/sha256_ge 5 * 6 * Copyright (c) Jean-Luc Cooke <jlcooke@certa 7 * Copyright (c) Andrew McDonald <andrew@mcdon 8 * Copyright (c) 2002 James Morris <jmorris@in 9 * SHA224 Support Copyright 2007 Intel Corpora 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/sha2.h> 20 #include <crypto/sha256_base.h> 21 22 #include <asm/pstate.h> 23 #include <asm/elf.h> 24 25 #include "opcodes.h" 26 27 asmlinkage void sha256_sparc64_transform(u32 * 28 unsig 29 30 static void __sha256_sparc64_update(struct sha 31 unsigned i 32 { 33 unsigned int done = 0; 34 35 sctx->count += len; 36 if (partial) { 37 done = SHA256_BLOCK_SIZE - par 38 memcpy(sctx->buf + partial, da 39 sha256_sparc64_transform(sctx- 40 } 41 if (len - done >= SHA256_BLOCK_SIZE) { 42 const unsigned int rounds = (l 43 44 sha256_sparc64_transform(sctx- 45 done += rounds * SHA256_BLOCK_ 46 } 47 48 memcpy(sctx->buf, data + done, len - d 49 } 50 51 static int sha256_sparc64_update(struct shash_ 52 unsigned int 53 { 54 struct sha256_state *sctx = shash_desc 55 unsigned int partial = sctx->count % S 56 57 /* Handle the fast case right here */ 58 if (partial + len < SHA256_BLOCK_SIZE) 59 sctx->count += len; 60 memcpy(sctx->buf + partial, da 61 } else 62 __sha256_sparc64_update(sctx, 63 64 return 0; 65 } 66 67 static int sha256_sparc64_final(struct shash_d 68 { 69 struct sha256_state *sctx = shash_desc 70 unsigned int i, index, padlen; 71 __be32 *dst = (__be32 *)out; 72 __be64 bits; 73 static const u8 padding[SHA256_BLOCK_S 74 75 bits = cpu_to_be64(sctx->count << 3); 76 77 /* Pad out to 56 mod 64 and append len 78 index = sctx->count % SHA256_BLOCK_SIZ 79 padlen = (index < 56) ? (56 - index) : 80 81 /* We need to fill a whole block for _ 82 if (padlen <= 56) { 83 sctx->count += padlen; 84 memcpy(sctx->buf + index, padd 85 } else { 86 __sha256_sparc64_update(sctx, 87 } 88 __sha256_sparc64_update(sctx, (const u 89 90 /* Store state in digest */ 91 for (i = 0; i < 8; i++) 92 dst[i] = cpu_to_be32(sctx->sta 93 94 /* Wipe context */ 95 memset(sctx, 0, sizeof(*sctx)); 96 97 return 0; 98 } 99 100 static int sha224_sparc64_final(struct shash_d 101 { 102 u8 D[SHA256_DIGEST_SIZE]; 103 104 sha256_sparc64_final(desc, D); 105 106 memcpy(hash, D, SHA224_DIGEST_SIZE); 107 memzero_explicit(D, SHA256_DIGEST_SIZE 108 109 return 0; 110 } 111 112 static int sha256_sparc64_export(struct shash_ 113 { 114 struct sha256_state *sctx = shash_desc 115 116 memcpy(out, sctx, sizeof(*sctx)); 117 return 0; 118 } 119 120 static int sha256_sparc64_import(struct shash_ 121 { 122 struct sha256_state *sctx = shash_desc 123 124 memcpy(sctx, in, sizeof(*sctx)); 125 return 0; 126 } 127 128 static struct shash_alg sha256_alg = { 129 .digestsize = SHA256_DIGEST_ 130 .init = sha256_base_in 131 .update = sha256_sparc64 132 .final = sha256_sparc64 133 .export = sha256_sparc64 134 .import = sha256_sparc64 135 .descsize = sizeof(struct 136 .statesize = sizeof(struct 137 .base = { 138 .cra_name = "sha25 139 .cra_driver_name= "sha25 140 .cra_priority = SPARC_ 141 .cra_blocksize = SHA256 142 .cra_module = THIS_M 143 } 144 }; 145 146 static struct shash_alg sha224_alg = { 147 .digestsize = SHA224_DIGEST_ 148 .init = sha224_base_in 149 .update = sha256_sparc64 150 .final = sha224_sparc64 151 .descsize = sizeof(struct 152 .base = { 153 .cra_name = "sha22 154 .cra_driver_name= "sha22 155 .cra_priority = SPARC_ 156 .cra_blocksize = SHA224 157 .cra_module = THIS_M 158 } 159 }; 160 161 static bool __init sparc64_has_sha256_opcode(v 162 { 163 unsigned long cfr; 164 165 if (!(sparc64_elf_hwcap & HWCAP_SPARC_ 166 return false; 167 168 __asm__ __volatile__("rd %%asr26, %0" 169 if (!(cfr & CFR_SHA256)) 170 return false; 171 172 return true; 173 } 174 175 static int __init sha256_sparc64_mod_init(void 176 { 177 if (sparc64_has_sha256_opcode()) { 178 int ret = crypto_register_shas 179 if (ret < 0) 180 return ret; 181 182 ret = crypto_register_shash(&s 183 if (ret < 0) { 184 crypto_unregister_shas 185 return ret; 186 } 187 188 pr_info("Using sparc64 sha256 189 return 0; 190 } 191 pr_info("sparc64 sha256 opcode not ava 192 return -ENODEV; 193 } 194 195 static void __exit sha256_sparc64_mod_fini(voi 196 { 197 crypto_unregister_shash(&sha224_alg); 198 crypto_unregister_shash(&sha256_alg); 199 } 200 201 module_init(sha256_sparc64_mod_init); 202 module_exit(sha256_sparc64_mod_fini); 203 204 MODULE_LICENSE("GPL"); 205 MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure 206 207 MODULE_ALIAS_CRYPTO("sha224"); 208 MODULE_ALIAS_CRYPTO("sha256"); 209 210 #include "crop_devid.c" 211
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.