1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Cryptographic API. 4 * 5 * SHA1 Secure Hash Algorithm. 6 * 7 * Adapted for OCTEON by Aaro Koskinen <aaro.koskinen@iki.fi>. 8 * 9 * Based on crypto/sha1_generic.c, which is: 10 * 11 * Copyright (c) Alan Smithee. 12 * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk> 13 * Copyright (c) Jean-Francois Dive <jef@linuxbe.org> 14 */ 15 16 #include <linux/mm.h> 17 #include <crypto/sha1.h> 18 #include <linux/init.h> 19 #include <linux/types.h> 20 #include <linux/module.h> 21 #include <asm/byteorder.h> 22 #include <asm/octeon/octeon.h> 23 #include <crypto/internal/hash.h> 24 25 #include "octeon-crypto.h" 26 27 /* 28 * We pass everything as 64-bit. OCTEON can handle misaligned data. 29 */ 30 31 static void octeon_sha1_store_hash(struct sha1_state *sctx) 32 { 33 u64 *hash = (u64 *)sctx->state; 34 union { 35 u32 word[2]; 36 u64 dword; 37 } hash_tail = { { sctx->state[4], } }; 38 39 write_octeon_64bit_hash_dword(hash[0], 0); 40 write_octeon_64bit_hash_dword(hash[1], 1); 41 write_octeon_64bit_hash_dword(hash_tail.dword, 2); 42 memzero_explicit(&hash_tail.word[0], sizeof(hash_tail.word[0])); 43 } 44 45 static void octeon_sha1_read_hash(struct sha1_state *sctx) 46 { 47 u64 *hash = (u64 *)sctx->state; 48 union { 49 u32 word[2]; 50 u64 dword; 51 } hash_tail; 52 53 hash[0] = read_octeon_64bit_hash_dword(0); 54 hash[1] = read_octeon_64bit_hash_dword(1); 55 hash_tail.dword = read_octeon_64bit_hash_dword(2); 56 sctx->state[4] = hash_tail.word[0]; 57 memzero_explicit(&hash_tail.dword, sizeof(hash_tail.dword)); 58 } 59 60 static void octeon_sha1_transform(const void *_block) 61 { 62 const u64 *block = _block; 63 64 write_octeon_64bit_block_dword(block[0], 0); 65 write_octeon_64bit_block_dword(block[1], 1); 66 write_octeon_64bit_block_dword(block[2], 2); 67 write_octeon_64bit_block_dword(block[3], 3); 68 write_octeon_64bit_block_dword(block[4], 4); 69 write_octeon_64bit_block_dword(block[5], 5); 70 write_octeon_64bit_block_dword(block[6], 6); 71 octeon_sha1_start(block[7]); 72 } 73 74 static int octeon_sha1_init(struct shash_desc *desc) 75 { 76 struct sha1_state *sctx = shash_desc_ctx(desc); 77 78 sctx->state[0] = SHA1_H0; 79 sctx->state[1] = SHA1_H1; 80 sctx->state[2] = SHA1_H2; 81 sctx->state[3] = SHA1_H3; 82 sctx->state[4] = SHA1_H4; 83 sctx->count = 0; 84 85 return 0; 86 } 87 88 static void __octeon_sha1_update(struct sha1_state *sctx, const u8 *data, 89 unsigned int len) 90 { 91 unsigned int partial; 92 unsigned int done; 93 const u8 *src; 94 95 partial = sctx->count % SHA1_BLOCK_SIZE; 96 sctx->count += len; 97 done = 0; 98 src = data; 99 100 if ((partial + len) >= SHA1_BLOCK_SIZE) { 101 if (partial) { 102 done = -partial; 103 memcpy(sctx->buffer + partial, data, 104 done + SHA1_BLOCK_SIZE); 105 src = sctx->buffer; 106 } 107 108 do { 109 octeon_sha1_transform(src); 110 done += SHA1_BLOCK_SIZE; 111 src = data + done; 112 } while (done + SHA1_BLOCK_SIZE <= len); 113 114 partial = 0; 115 } 116 memcpy(sctx->buffer + partial, src, len - done); 117 } 118 119 static int octeon_sha1_update(struct shash_desc *desc, const u8 *data, 120 unsigned int len) 121 { 122 struct sha1_state *sctx = shash_desc_ctx(desc); 123 struct octeon_cop2_state state; 124 unsigned long flags; 125 126 /* 127 * Small updates never reach the crypto engine, so the generic sha1 is 128 * faster because of the heavyweight octeon_crypto_enable() / 129 * octeon_crypto_disable(). 130 */ 131 if ((sctx->count % SHA1_BLOCK_SIZE) + len < SHA1_BLOCK_SIZE) 132 return crypto_sha1_update(desc, data, len); 133 134 flags = octeon_crypto_enable(&state); 135 octeon_sha1_store_hash(sctx); 136 137 __octeon_sha1_update(sctx, data, len); 138 139 octeon_sha1_read_hash(sctx); 140 octeon_crypto_disable(&state, flags); 141 142 return 0; 143 } 144 145 static int octeon_sha1_final(struct shash_desc *desc, u8 *out) 146 { 147 struct sha1_state *sctx = shash_desc_ctx(desc); 148 static const u8 padding[64] = { 0x80, }; 149 struct octeon_cop2_state state; 150 __be32 *dst = (__be32 *)out; 151 unsigned int pad_len; 152 unsigned long flags; 153 unsigned int index; 154 __be64 bits; 155 int i; 156 157 /* Save number of bits. */ 158 bits = cpu_to_be64(sctx->count << 3); 159 160 /* Pad out to 56 mod 64. */ 161 index = sctx->count & 0x3f; 162 pad_len = (index < 56) ? (56 - index) : ((64+56) - index); 163 164 flags = octeon_crypto_enable(&state); 165 octeon_sha1_store_hash(sctx); 166 167 __octeon_sha1_update(sctx, padding, pad_len); 168 169 /* Append length (before padding). */ 170 __octeon_sha1_update(sctx, (const u8 *)&bits, sizeof(bits)); 171 172 octeon_sha1_read_hash(sctx); 173 octeon_crypto_disable(&state, flags); 174 175 /* Store state in digest */ 176 for (i = 0; i < 5; i++) 177 dst[i] = cpu_to_be32(sctx->state[i]); 178 179 /* Zeroize sensitive information. */ 180 memset(sctx, 0, sizeof(*sctx)); 181 182 return 0; 183 } 184 185 static int octeon_sha1_export(struct shash_desc *desc, void *out) 186 { 187 struct sha1_state *sctx = shash_desc_ctx(desc); 188 189 memcpy(out, sctx, sizeof(*sctx)); 190 return 0; 191 } 192 193 static int octeon_sha1_import(struct shash_desc *desc, const void *in) 194 { 195 struct sha1_state *sctx = shash_desc_ctx(desc); 196 197 memcpy(sctx, in, sizeof(*sctx)); 198 return 0; 199 } 200 201 static struct shash_alg octeon_sha1_alg = { 202 .digestsize = SHA1_DIGEST_SIZE, 203 .init = octeon_sha1_init, 204 .update = octeon_sha1_update, 205 .final = octeon_sha1_final, 206 .export = octeon_sha1_export, 207 .import = octeon_sha1_import, 208 .descsize = sizeof(struct sha1_state), 209 .statesize = sizeof(struct sha1_state), 210 .base = { 211 .cra_name = "sha1", 212 .cra_driver_name= "octeon-sha1", 213 .cra_priority = OCTEON_CR_OPCODE_PRIORITY, 214 .cra_blocksize = SHA1_BLOCK_SIZE, 215 .cra_module = THIS_MODULE, 216 } 217 }; 218 219 static int __init octeon_sha1_mod_init(void) 220 { 221 if (!octeon_has_crypto()) 222 return -ENOTSUPP; 223 return crypto_register_shash(&octeon_sha1_alg); 224 } 225 226 static void __exit octeon_sha1_mod_fini(void) 227 { 228 crypto_unregister_shash(&octeon_sha1_alg); 229 } 230 231 module_init(octeon_sha1_mod_init); 232 module_exit(octeon_sha1_mod_fini); 233 234 MODULE_LICENSE("GPL"); 235 MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm (OCTEON)"); 236 MODULE_AUTHOR("Aaro Koskinen <aaro.koskinen@iki.fi>"); 237