1 /* 2 * Cryptographic API. 3 * 4 * SHA-512 and SHA-384 Secure Hash Algorithm. 5 * 6 * Adapted for OCTEON by Aaro Koskinen <aaro.koskinen@iki.fi>. 7 * 8 * Based on crypto/sha512_generic.c, which is: 9 * 10 * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com> 11 * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk> 12 * Copyright (c) 2003 Kyle McMartin <kyle@debian.org> 13 * 14 * This program is free software; you can redistribute it and/or modify it 15 * under the terms of the GNU General Public License as published by the 16 * Free Software Foundation; either version 2, or (at your option) any 17 * later version. 18 */ 19 20 #include <linux/mm.h> 21 #include <crypto/sha.h> 22 #include <linux/init.h> 23 #include <linux/types.h> 24 #include <linux/module.h> 25 #include <asm/byteorder.h> 26 #include <asm/octeon/octeon.h> 27 #include <crypto/internal/hash.h> 28 29 #include "octeon-crypto.h" 30 31 /* 32 * We pass everything as 64-bit. OCTEON can handle misaligned data. 33 */ 34 35 static void octeon_sha512_store_hash(struct sha512_state *sctx) 36 { 37 write_octeon_64bit_hash_sha512(sctx->state[0], 0); 38 write_octeon_64bit_hash_sha512(sctx->state[1], 1); 39 write_octeon_64bit_hash_sha512(sctx->state[2], 2); 40 write_octeon_64bit_hash_sha512(sctx->state[3], 3); 41 write_octeon_64bit_hash_sha512(sctx->state[4], 4); 42 write_octeon_64bit_hash_sha512(sctx->state[5], 5); 43 write_octeon_64bit_hash_sha512(sctx->state[6], 6); 44 write_octeon_64bit_hash_sha512(sctx->state[7], 7); 45 } 46 47 static void octeon_sha512_read_hash(struct sha512_state *sctx) 48 { 49 sctx->state[0] = read_octeon_64bit_hash_sha512(0); 50 sctx->state[1] = read_octeon_64bit_hash_sha512(1); 51 sctx->state[2] = read_octeon_64bit_hash_sha512(2); 52 sctx->state[3] = read_octeon_64bit_hash_sha512(3); 53 sctx->state[4] = read_octeon_64bit_hash_sha512(4); 54 sctx->state[5] = read_octeon_64bit_hash_sha512(5); 55 sctx->state[6] = read_octeon_64bit_hash_sha512(6); 56 sctx->state[7] = read_octeon_64bit_hash_sha512(7); 57 } 58 59 static void octeon_sha512_transform(const void *_block) 60 { 61 const u64 *block = _block; 62 63 write_octeon_64bit_block_sha512(block[0], 0); 64 write_octeon_64bit_block_sha512(block[1], 1); 65 write_octeon_64bit_block_sha512(block[2], 2); 66 write_octeon_64bit_block_sha512(block[3], 3); 67 write_octeon_64bit_block_sha512(block[4], 4); 68 write_octeon_64bit_block_sha512(block[5], 5); 69 write_octeon_64bit_block_sha512(block[6], 6); 70 write_octeon_64bit_block_sha512(block[7], 7); 71 write_octeon_64bit_block_sha512(block[8], 8); 72 write_octeon_64bit_block_sha512(block[9], 9); 73 write_octeon_64bit_block_sha512(block[10], 10); 74 write_octeon_64bit_block_sha512(block[11], 11); 75 write_octeon_64bit_block_sha512(block[12], 12); 76 write_octeon_64bit_block_sha512(block[13], 13); 77 write_octeon_64bit_block_sha512(block[14], 14); 78 octeon_sha512_start(block[15]); 79 } 80 81 static int octeon_sha512_init(struct shash_desc *desc) 82 { 83 struct sha512_state *sctx = shash_desc_ctx(desc); 84 85 sctx->state[0] = SHA512_H0; 86 sctx->state[1] = SHA512_H1; 87 sctx->state[2] = SHA512_H2; 88 sctx->state[3] = SHA512_H3; 89 sctx->state[4] = SHA512_H4; 90 sctx->state[5] = SHA512_H5; 91 sctx->state[6] = SHA512_H6; 92 sctx->state[7] = SHA512_H7; 93 sctx->count[0] = sctx->count[1] = 0; 94 95 return 0; 96 } 97 98 static int octeon_sha384_init(struct shash_desc *desc) 99 { 100 struct sha512_state *sctx = shash_desc_ctx(desc); 101 102 sctx->state[0] = SHA384_H0; 103 sctx->state[1] = SHA384_H1; 104 sctx->state[2] = SHA384_H2; 105 sctx->state[3] = SHA384_H3; 106 sctx->state[4] = SHA384_H4; 107 sctx->state[5] = SHA384_H5; 108 sctx->state[6] = SHA384_H6; 109 sctx->state[7] = SHA384_H7; 110 sctx->count[0] = sctx->count[1] = 0; 111 112 return 0; 113 } 114 115 static void __octeon_sha512_update(struct sha512_state *sctx, const u8 *data, 116 unsigned int len) 117 { 118 unsigned int part_len; 119 unsigned int index; 120 unsigned int i; 121 122 /* Compute number of bytes mod 128. */ 123 index = sctx->count[0] % SHA512_BLOCK_SIZE; 124 125 /* Update number of bytes. */ 126 if ((sctx->count[0] += len) < len) 127 sctx->count[1]++; 128 129 part_len = SHA512_BLOCK_SIZE - index; 130 131 /* Transform as many times as possible. */ 132 if (len >= part_len) { 133 memcpy(&sctx->buf[index], data, part_len); 134 octeon_sha512_transform(sctx->buf); 135 136 for (i = part_len; i + SHA512_BLOCK_SIZE <= len; 137 i += SHA512_BLOCK_SIZE) 138 octeon_sha512_transform(&data[i]); 139 140 index = 0; 141 } else { 142 i = 0; 143 } 144 145 /* Buffer remaining input. */ 146 memcpy(&sctx->buf[index], &data[i], len - i); 147 } 148 149 static int octeon_sha512_update(struct shash_desc *desc, const u8 *data, 150 unsigned int len) 151 { 152 struct sha512_state *sctx = shash_desc_ctx(desc); 153 struct octeon_cop2_state state; 154 unsigned long flags; 155 156 /* 157 * Small updates never reach the crypto engine, so the generic sha512 is 158 * faster because of the heavyweight octeon_crypto_enable() / 159 * octeon_crypto_disable(). 160 */ 161 if ((sctx->count[0] % SHA512_BLOCK_SIZE) + len < SHA512_BLOCK_SIZE) 162 return crypto_sha512_update(desc, data, len); 163 164 flags = octeon_crypto_enable(&state); 165 octeon_sha512_store_hash(sctx); 166 167 __octeon_sha512_update(sctx, data, len); 168 169 octeon_sha512_read_hash(sctx); 170 octeon_crypto_disable(&state, flags); 171 172 return 0; 173 } 174 175 static int octeon_sha512_final(struct shash_desc *desc, u8 *hash) 176 { 177 struct sha512_state *sctx = shash_desc_ctx(desc); 178 static u8 padding[128] = { 0x80, }; 179 struct octeon_cop2_state state; 180 __be64 *dst = (__be64 *)hash; 181 unsigned int pad_len; 182 unsigned long flags; 183 unsigned int index; 184 __be64 bits[2]; 185 int i; 186 187 /* Save number of bits. */ 188 bits[1] = cpu_to_be64(sctx->count[0] << 3); 189 bits[0] = cpu_to_be64(sctx->count[1] << 3 | sctx->count[0] >> 61); 190 191 /* Pad out to 112 mod 128. */ 192 index = sctx->count[0] & 0x7f; 193 pad_len = (index < 112) ? (112 - index) : ((128+112) - index); 194 195 flags = octeon_crypto_enable(&state); 196 octeon_sha512_store_hash(sctx); 197 198 __octeon_sha512_update(sctx, padding, pad_len); 199 200 /* Append length (before padding). */ 201 __octeon_sha512_update(sctx, (const u8 *)bits, sizeof(bits)); 202 203 octeon_sha512_read_hash(sctx); 204 octeon_crypto_disable(&state, flags); 205 206 /* Store state in digest. */ 207 for (i = 0; i < 8; i++) 208 dst[i] = cpu_to_be64(sctx->state[i]); 209 210 /* Zeroize sensitive information. */ 211 memset(sctx, 0, sizeof(struct sha512_state)); 212 213 return 0; 214 } 215 216 static int octeon_sha384_final(struct shash_desc *desc, u8 *hash) 217 { 218 u8 D[64]; 219 220 octeon_sha512_final(desc, D); 221 222 memcpy(hash, D, 48); 223 memzero_explicit(D, 64); 224 225 return 0; 226 } 227 228 static struct shash_alg octeon_sha512_algs[2] = { { 229 .digestsize = SHA512_DIGEST_SIZE, 230 .init = octeon_sha512_init, 231 .update = octeon_sha512_update, 232 .final = octeon_sha512_final, 233 .descsize = sizeof(struct sha512_state), 234 .base = { 235 .cra_name = "sha512", 236 .cra_driver_name= "octeon-sha512", 237 .cra_priority = OCTEON_CR_OPCODE_PRIORITY, 238 .cra_blocksize = SHA512_BLOCK_SIZE, 239 .cra_module = THIS_MODULE, 240 } 241 }, { 242 .digestsize = SHA384_DIGEST_SIZE, 243 .init = octeon_sha384_init, 244 .update = octeon_sha512_update, 245 .final = octeon_sha384_final, 246 .descsize = sizeof(struct sha512_state), 247 .base = { 248 .cra_name = "sha384", 249 .cra_driver_name= "octeon-sha384", 250 .cra_priority = OCTEON_CR_OPCODE_PRIORITY, 251 .cra_blocksize = SHA384_BLOCK_SIZE, 252 .cra_module = THIS_MODULE, 253 } 254 } }; 255 256 static int __init octeon_sha512_mod_init(void) 257 { 258 if (!octeon_has_crypto()) 259 return -ENOTSUPP; 260 return crypto_register_shashes(octeon_sha512_algs, 261 ARRAY_SIZE(octeon_sha512_algs)); 262 } 263 264 static void __exit octeon_sha512_mod_fini(void) 265 { 266 crypto_unregister_shashes(octeon_sha512_algs, 267 ARRAY_SIZE(octeon_sha512_algs)); 268 } 269 270 module_init(octeon_sha512_mod_init); 271 module_exit(octeon_sha512_mod_fini); 272 273 MODULE_LICENSE("GPL"); 274 MODULE_DESCRIPTION("SHA-512 and SHA-384 Secure Hash Algorithms (OCTEON)"); 275 MODULE_AUTHOR("Aaro Koskinen <aaro.koskinen@iki.fi>"); 276