Blame view
crypto/sha512_generic.c
7.74 KB
8d7c56d08
|
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
1da177e4c
|
2 3 4 5 6 |
/* SHA-512 code by Jean-Luc Cooke <jlcooke@certainkey.com> * * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com> * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk> * Copyright (c) 2003 Kyle McMartin <kyle@debian.org> |
1da177e4c
|
7 |
*/ |
bd9d20dba
|
8 |
#include <crypto/internal/hash.h> |
1da177e4c
|
9 10 |
#include <linux/kernel.h> #include <linux/module.h> |
1da177e4c
|
11 12 13 |
#include <linux/mm.h> #include <linux/init.h> #include <linux/crypto.h> |
06ace7a9b
|
14 |
#include <linux/types.h> |
a24d22b22
|
15 |
#include <crypto/sha2.h> |
ca142584b
|
16 |
#include <crypto/sha512_base.h> |
f9e2bca6c
|
17 |
#include <linux/percpu.h> |
1da177e4c
|
18 |
#include <asm/byteorder.h> |
be34c4ef6
|
19 |
#include <asm/unaligned.h> |
1da177e4c
|
20 |
|
26f7120b8
|
21 22 23 24 25 26 27 28 29 |
const u8 sha384_zero_message_hash[SHA384_DIGEST_SIZE] = { 0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38, 0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a, 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43, 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda, 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb, 0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b }; EXPORT_SYMBOL_GPL(sha384_zero_message_hash); |
30c217ef6
|
30 31 32 33 34 35 36 37 38 39 40 |
const u8 sha512_zero_message_hash[SHA512_DIGEST_SIZE] = { 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd, 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07, 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc, 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce, 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0, 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f, 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81, 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e }; EXPORT_SYMBOL_GPL(sha512_zero_message_hash); |
1da177e4c
|
41 42 43 44 45 46 47 48 49 |
static inline u64 Ch(u64 x, u64 y, u64 z) { return z ^ (x & (y ^ z)); } static inline u64 Maj(u64 x, u64 y, u64 z) { return (x & y) | (z & (x | y)); } |
1da177e4c
|
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
static const u64 sha512_K[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL, }; |
f2ea0f5f0
|
79 80 81 82 |
#define e0(x) (ror64(x,28) ^ ror64(x,34) ^ ror64(x,39)) #define e1(x) (ror64(x,14) ^ ror64(x,18) ^ ror64(x,41)) #define s0(x) (ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7)) #define s1(x) (ror64(x,19) ^ ror64(x,61) ^ (x >> 6)) |
1da177e4c
|
83 |
|
1da177e4c
|
84 85 |
static inline void LOAD_OP(int I, u64 *W, const u8 *input) { |
be34c4ef6
|
86 |
W[I] = get_unaligned_be64((__u64 *)input + I); |
1da177e4c
|
87 88 89 90 |
} static inline void BLEND_OP(int I, u64 *W) { |
58d7d18b5
|
91 |
W[I & 15] += s1(W[(I-2) & 15]) + W[(I-7) & 15] + s0(W[(I-15) & 15]); |
1da177e4c
|
92 93 94 |
} static void |
f9e2bca6c
|
95 |
sha512_transform(u64 *state, const u8 *input) |
1da177e4c
|
96 97 98 99 |
{ u64 a, b, c, d, e, f, g, h, t1, t2; int i; |
51fc6dc8f
|
100 |
u64 W[16]; |
1da177e4c
|
101 |
|
1da177e4c
|
102 |
/* load the state into our registers */ |
78f8b3a24
|
103 104 |
a=state[0]; b=state[1]; c=state[2]; d=state[3]; e=state[4]; f=state[5]; g=state[6]; h=state[7]; |
3a92d687c
|
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
/* now iterate */ for (i=0; i<80; i+=8) { if (!(i & 8)) { int j; if (i < 16) { /* load the input */ for (j = 0; j < 16; j++) LOAD_OP(i + j, W, input); } else { for (j = 0; j < 16; j++) { BLEND_OP(i + j, W); } } } t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i ] + W[(i & 15)]; t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[(i & 15) + 1]; t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[(i & 15) + 2]; t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[(i & 15) + 3]; t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[(i & 15) + 4]; t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[(i & 15) + 5]; t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[(i & 15) + 6]; t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[(i & 15) + 7]; t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; |
1da177e4c
|
137 |
} |
78f8b3a24
|
138 139 140 |
state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; state[5] += f; state[6] += g; state[7] += h; |
1da177e4c
|
141 |
} |
ca142584b
|
142 143 |
static void sha512_generic_block_fn(struct sha512_state *sst, u8 const *src, int blocks) |
1da177e4c
|
144 |
{ |
ca142584b
|
145 146 147 148 |
while (blocks--) { sha512_transform(sst->state, src); src += SHA512_BLOCK_SIZE; } |
1da177e4c
|
149 |
} |
bf70fa9d9
|
150 151 |
int crypto_sha512_update(struct shash_desc *desc, const u8 *data, unsigned int len) |
1da177e4c
|
152 |
{ |
ca142584b
|
153 |
return sha512_base_do_update(desc, data, len, sha512_generic_block_fn); |
1da177e4c
|
154 |
} |
bf70fa9d9
|
155 |
EXPORT_SYMBOL(crypto_sha512_update); |
1da177e4c
|
156 |
|
ca142584b
|
157 |
static int sha512_final(struct shash_desc *desc, u8 *hash) |
1da177e4c
|
158 |
{ |
ca142584b
|
159 160 |
sha512_base_do_finalize(desc, sha512_generic_block_fn); return sha512_base_finish(desc, hash); |
1da177e4c
|
161 |
} |
ca142584b
|
162 163 |
int crypto_sha512_finup(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *hash) |
1da177e4c
|
164 |
{ |
ca142584b
|
165 166 |
sha512_base_do_update(desc, data, len, sha512_generic_block_fn); return sha512_final(desc, hash); |
1da177e4c
|
167 |
} |
ca142584b
|
168 |
EXPORT_SYMBOL(crypto_sha512_finup); |
1da177e4c
|
169 |
|
648b2a102
|
170 |
static struct shash_alg sha512_algs[2] = { { |
bd9d20dba
|
171 |
.digestsize = SHA512_DIGEST_SIZE, |
ca142584b
|
172 |
.init = sha512_base_init, |
bf70fa9d9
|
173 |
.update = crypto_sha512_update, |
bd9d20dba
|
174 |
.final = sha512_final, |
ca142584b
|
175 |
.finup = crypto_sha512_finup, |
1f38ad838
|
176 |
.descsize = sizeof(struct sha512_state), |
bd9d20dba
|
177 178 |
.base = { .cra_name = "sha512", |
d32958149
|
179 |
.cra_driver_name = "sha512-generic", |
e47890163
|
180 |
.cra_priority = 100, |
bd9d20dba
|
181 182 183 |
.cra_blocksize = SHA512_BLOCK_SIZE, .cra_module = THIS_MODULE, } |
648b2a102
|
184 |
}, { |
bd9d20dba
|
185 |
.digestsize = SHA384_DIGEST_SIZE, |
ca142584b
|
186 |
.init = sha384_base_init, |
bf70fa9d9
|
187 |
.update = crypto_sha512_update, |
ca142584b
|
188 189 |
.final = sha512_final, .finup = crypto_sha512_finup, |
1f38ad838
|
190 |
.descsize = sizeof(struct sha512_state), |
bd9d20dba
|
191 192 |
.base = { .cra_name = "sha384", |
d32958149
|
193 |
.cra_driver_name = "sha384-generic", |
e47890163
|
194 |
.cra_priority = 100, |
bd9d20dba
|
195 196 197 |
.cra_blocksize = SHA384_BLOCK_SIZE, .cra_module = THIS_MODULE, } |
648b2a102
|
198 |
} }; |
1da177e4c
|
199 |
|
3af5b90bd
|
200 |
static int __init sha512_generic_mod_init(void) |
1da177e4c
|
201 |
{ |
648b2a102
|
202 |
return crypto_register_shashes(sha512_algs, ARRAY_SIZE(sha512_algs)); |
1da177e4c
|
203 |
} |
3af5b90bd
|
204 |
static void __exit sha512_generic_mod_fini(void) |
1da177e4c
|
205 |
{ |
648b2a102
|
206 |
crypto_unregister_shashes(sha512_algs, ARRAY_SIZE(sha512_algs)); |
1da177e4c
|
207 |
} |
c4741b230
|
208 |
subsys_initcall(sha512_generic_mod_init); |
3af5b90bd
|
209 |
module_exit(sha512_generic_mod_fini); |
1da177e4c
|
210 211 212 |
MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA-512 and SHA-384 Secure Hash Algorithms"); |
78f8b3a24
|
213 |
|
5d26a105b
|
214 |
MODULE_ALIAS_CRYPTO("sha384"); |
3e14dcf7c
|
215 |
MODULE_ALIAS_CRYPTO("sha384-generic"); |
5d26a105b
|
216 |
MODULE_ALIAS_CRYPTO("sha512"); |
3e14dcf7c
|
217 |
MODULE_ALIAS_CRYPTO("sha512-generic"); |