aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/sha256_generic.c
diff options
context:
space:
mode:
authorSebastian Siewior <sebastian@breakpoint.cc>2007-10-07 23:45:10 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:55:50 -0400
commitad5d27899fdbe7a66e57fdf1af883dbd7ff88dac (patch)
tree666a5809fd9a01e0798411b94962903c3431400c /crypto/sha256_generic.c
parentf8246af005d56b73f4f04304fc5b6fd9878af4ef (diff)
[CRYPTO] sha: Load the SHA[1|256] module by an alias
Loading the crypto algorithm by the alias instead of by module directly has the advantage that all possible implementations of this algorithm are loaded automatically and the crypto API can choose the best one depending on its priority. Additionally it ensures that the generic implementation as well as the HW driver (if available) is loaded in case the HW driver needs the generic version as fallback in corner cases. Also remove the probe for sha1 in padlock's init code. Quote from Herbert: The probe is actually pointless since we can always probe when the algorithm is actually used which does not lead to dead-locks like this. Signed-off-by: Sebastian Siewior <sebastian@breakpoint.cc> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/sha256_generic.c')
-rw-r--r--crypto/sha256_generic.c342
1 files changed, 342 insertions, 0 deletions
diff --git a/crypto/sha256_generic.c b/crypto/sha256_generic.c
new file mode 100644
index 000000000000..74bf2f95f4e5
--- /dev/null
+++ b/crypto/sha256_generic.c
@@ -0,0 +1,342 @@
1/*
2 * Cryptographic API.
3 *
4 * SHA-256, as specified in
5 * http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf
6 *
7 * SHA-256 code by Jean-Luc Cooke <jlcooke@certainkey.com>.
8 *
9 * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
10 * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
11 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the Free
15 * Software Foundation; either version 2 of the License, or (at your option)
16 * any later version.
17 *
18 */
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/mm.h>
22#include <linux/crypto.h>
23#include <linux/types.h>
24#include <asm/scatterlist.h>
25#include <asm/byteorder.h>
26
27#define SHA256_DIGEST_SIZE 32
28#define SHA256_HMAC_BLOCK_SIZE 64
29
30struct sha256_ctx {
31 u32 count[2];
32 u32 state[8];
33 u8 buf[128];
34};
35
36static inline u32 Ch(u32 x, u32 y, u32 z)
37{
38 return z ^ (x & (y ^ z));
39}
40
41static inline u32 Maj(u32 x, u32 y, u32 z)
42{
43 return (x & y) | (z & (x | y));
44}
45
46#define e0(x) (ror32(x, 2) ^ ror32(x,13) ^ ror32(x,22))
47#define e1(x) (ror32(x, 6) ^ ror32(x,11) ^ ror32(x,25))
48#define s0(x) (ror32(x, 7) ^ ror32(x,18) ^ (x >> 3))
49#define s1(x) (ror32(x,17) ^ ror32(x,19) ^ (x >> 10))
50
51#define H0 0x6a09e667
52#define H1 0xbb67ae85
53#define H2 0x3c6ef372
54#define H3 0xa54ff53a
55#define H4 0x510e527f
56#define H5 0x9b05688c
57#define H6 0x1f83d9ab
58#define H7 0x5be0cd19
59
60static inline void LOAD_OP(int I, u32 *W, const u8 *input)
61{
62 W[I] = __be32_to_cpu( ((__be32*)(input))[I] );
63}
64
65static inline void BLEND_OP(int I, u32 *W)
66{
67 W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
68}
69
70static void sha256_transform(u32 *state, const u8 *input)
71{
72 u32 a, b, c, d, e, f, g, h, t1, t2;
73 u32 W[64];
74 int i;
75
76 /* load the input */
77 for (i = 0; i < 16; i++)
78 LOAD_OP(i, W, input);
79
80 /* now blend */
81 for (i = 16; i < 64; i++)
82 BLEND_OP(i, W);
83
84 /* load the state into our registers */
85 a=state[0]; b=state[1]; c=state[2]; d=state[3];
86 e=state[4]; f=state[5]; g=state[6]; h=state[7];
87
88 /* now iterate */
89 t1 = h + e1(e) + Ch(e,f,g) + 0x428a2f98 + W[ 0];
90 t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
91 t1 = g + e1(d) + Ch(d,e,f) + 0x71374491 + W[ 1];
92 t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
93 t1 = f + e1(c) + Ch(c,d,e) + 0xb5c0fbcf + W[ 2];
94 t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
95 t1 = e + e1(b) + Ch(b,c,d) + 0xe9b5dba5 + W[ 3];
96 t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
97 t1 = d + e1(a) + Ch(a,b,c) + 0x3956c25b + W[ 4];
98 t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
99 t1 = c + e1(h) + Ch(h,a,b) + 0x59f111f1 + W[ 5];
100 t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
101 t1 = b + e1(g) + Ch(g,h,a) + 0x923f82a4 + W[ 6];
102 t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
103 t1 = a + e1(f) + Ch(f,g,h) + 0xab1c5ed5 + W[ 7];
104 t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
105
106 t1 = h + e1(e) + Ch(e,f,g) + 0xd807aa98 + W[ 8];
107 t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
108 t1 = g + e1(d) + Ch(d,e,f) + 0x12835b01 + W[ 9];
109 t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
110 t1 = f + e1(c) + Ch(c,d,e) + 0x243185be + W[10];
111 t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
112 t1 = e + e1(b) + Ch(b,c,d) + 0x550c7dc3 + W[11];
113 t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
114 t1 = d + e1(a) + Ch(a,b,c) + 0x72be5d74 + W[12];
115 t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
116 t1 = c + e1(h) + Ch(h,a,b) + 0x80deb1fe + W[13];
117 t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
118 t1 = b + e1(g) + Ch(g,h,a) + 0x9bdc06a7 + W[14];
119 t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
120 t1 = a + e1(f) + Ch(f,g,h) + 0xc19bf174 + W[15];
121 t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
122
123 t1 = h + e1(e) + Ch(e,f,g) + 0xe49b69c1 + W[16];
124 t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
125 t1 = g + e1(d) + Ch(d,e,f) + 0xefbe4786 + W[17];
126 t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
127 t1 = f + e1(c) + Ch(c,d,e) + 0x0fc19dc6 + W[18];
128 t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
129 t1 = e + e1(b) + Ch(b,c,d) + 0x240ca1cc + W[19];
130 t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
131 t1 = d + e1(a) + Ch(a,b,c) + 0x2de92c6f + W[20];
132 t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
133 t1 = c + e1(h) + Ch(h,a,b) + 0x4a7484aa + W[21];
134 t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
135 t1 = b + e1(g) + Ch(g,h,a) + 0x5cb0a9dc + W[22];
136 t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
137 t1 = a + e1(f) + Ch(f,g,h) + 0x76f988da + W[23];
138 t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
139
140 t1 = h + e1(e) + Ch(e,f,g) + 0x983e5152 + W[24];
141 t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
142 t1 = g + e1(d) + Ch(d,e,f) + 0xa831c66d + W[25];
143 t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
144 t1 = f + e1(c) + Ch(c,d,e) + 0xb00327c8 + W[26];
145 t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
146 t1 = e + e1(b) + Ch(b,c,d) + 0xbf597fc7 + W[27];
147 t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
148 t1 = d + e1(a) + Ch(a,b,c) + 0xc6e00bf3 + W[28];
149 t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
150 t1 = c + e1(h) + Ch(h,a,b) + 0xd5a79147 + W[29];
151 t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
152 t1 = b + e1(g) + Ch(g,h,a) + 0x06ca6351 + W[30];
153 t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
154 t1 = a + e1(f) + Ch(f,g,h) + 0x14292967 + W[31];
155 t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
156
157 t1 = h + e1(e) + Ch(e,f,g) + 0x27b70a85 + W[32];
158 t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
159 t1 = g + e1(d) + Ch(d,e,f) + 0x2e1b2138 + W[33];
160 t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
161 t1 = f + e1(c) + Ch(c,d,e) + 0x4d2c6dfc + W[34];
162 t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
163 t1 = e + e1(b) + Ch(b,c,d) + 0x53380d13 + W[35];
164 t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
165 t1 = d + e1(a) + Ch(a,b,c) + 0x650a7354 + W[36];
166 t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
167 t1 = c + e1(h) + Ch(h,a,b) + 0x766a0abb + W[37];
168 t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
169 t1 = b + e1(g) + Ch(g,h,a) + 0x81c2c92e + W[38];
170 t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
171 t1 = a + e1(f) + Ch(f,g,h) + 0x92722c85 + W[39];
172 t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
173
174 t1 = h + e1(e) + Ch(e,f,g) + 0xa2bfe8a1 + W[40];
175 t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
176 t1 = g + e1(d) + Ch(d,e,f) + 0xa81a664b + W[41];
177 t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
178 t1 = f + e1(c) + Ch(c,d,e) + 0xc24b8b70 + W[42];
179 t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
180 t1 = e + e1(b) + Ch(b,c,d) + 0xc76c51a3 + W[43];
181 t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
182 t1 = d + e1(a) + Ch(a,b,c) + 0xd192e819 + W[44];
183 t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
184 t1 = c + e1(h) + Ch(h,a,b) + 0xd6990624 + W[45];
185 t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
186 t1 = b + e1(g) + Ch(g,h,a) + 0xf40e3585 + W[46];
187 t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
188 t1 = a + e1(f) + Ch(f,g,h) + 0x106aa070 + W[47];
189 t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
190
191 t1 = h + e1(e) + Ch(e,f,g) + 0x19a4c116 + W[48];
192 t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
193 t1 = g + e1(d) + Ch(d,e,f) + 0x1e376c08 + W[49];
194 t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
195 t1 = f + e1(c) + Ch(c,d,e) + 0x2748774c + W[50];
196 t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
197 t1 = e + e1(b) + Ch(b,c,d) + 0x34b0bcb5 + W[51];
198 t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
199 t1 = d + e1(a) + Ch(a,b,c) + 0x391c0cb3 + W[52];
200 t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
201 t1 = c + e1(h) + Ch(h,a,b) + 0x4ed8aa4a + W[53];
202 t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
203 t1 = b + e1(g) + Ch(g,h,a) + 0x5b9cca4f + W[54];
204 t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
205 t1 = a + e1(f) + Ch(f,g,h) + 0x682e6ff3 + W[55];
206 t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
207
208 t1 = h + e1(e) + Ch(e,f,g) + 0x748f82ee + W[56];
209 t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
210 t1 = g + e1(d) + Ch(d,e,f) + 0x78a5636f + W[57];
211 t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
212 t1 = f + e1(c) + Ch(c,d,e) + 0x84c87814 + W[58];
213 t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
214 t1 = e + e1(b) + Ch(b,c,d) + 0x8cc70208 + W[59];
215 t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
216 t1 = d + e1(a) + Ch(a,b,c) + 0x90befffa + W[60];
217 t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
218 t1 = c + e1(h) + Ch(h,a,b) + 0xa4506ceb + W[61];
219 t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
220 t1 = b + e1(g) + Ch(g,h,a) + 0xbef9a3f7 + W[62];
221 t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
222 t1 = a + e1(f) + Ch(f,g,h) + 0xc67178f2 + W[63];
223 t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
224
225 state[0] += a; state[1] += b; state[2] += c; state[3] += d;
226 state[4] += e; state[5] += f; state[6] += g; state[7] += h;
227
228 /* clear any sensitive info... */
229 a = b = c = d = e = f = g = h = t1 = t2 = 0;
230 memset(W, 0, 64 * sizeof(u32));
231}
232
233static void sha256_init(struct crypto_tfm *tfm)
234{
235 struct sha256_ctx *sctx = crypto_tfm_ctx(tfm);
236 sctx->state[0] = H0;
237 sctx->state[1] = H1;
238 sctx->state[2] = H2;
239 sctx->state[3] = H3;
240 sctx->state[4] = H4;
241 sctx->state[5] = H5;
242 sctx->state[6] = H6;
243 sctx->state[7] = H7;
244 sctx->count[0] = sctx->count[1] = 0;
245}
246
247static void sha256_update(struct crypto_tfm *tfm, const u8 *data,
248 unsigned int len)
249{
250 struct sha256_ctx *sctx = crypto_tfm_ctx(tfm);
251 unsigned int i, index, part_len;
252
253 /* Compute number of bytes mod 128 */
254 index = (unsigned int)((sctx->count[0] >> 3) & 0x3f);
255
256 /* Update number of bits */
257 if ((sctx->count[0] += (len << 3)) < (len << 3)) {
258 sctx->count[1]++;
259 sctx->count[1] += (len >> 29);
260 }
261
262 part_len = 64 - index;
263
264 /* Transform as many times as possible. */
265 if (len >= part_len) {
266 memcpy(&sctx->buf[index], data, part_len);
267 sha256_transform(sctx->state, sctx->buf);
268
269 for (i = part_len; i + 63 < len; i += 64)
270 sha256_transform(sctx->state, &data[i]);
271 index = 0;
272 } else {
273 i = 0;
274 }
275
276 /* Buffer remaining input */
277 memcpy(&sctx->buf[index], &data[i], len-i);
278}
279
280static void sha256_final(struct crypto_tfm *tfm, u8 *out)
281{
282 struct sha256_ctx *sctx = crypto_tfm_ctx(tfm);
283 __be32 *dst = (__be32 *)out;
284 __be32 bits[2];
285 unsigned int index, pad_len;
286 int i;
287 static const u8 padding[64] = { 0x80, };
288
289 /* Save number of bits */
290 bits[1] = cpu_to_be32(sctx->count[0]);
291 bits[0] = cpu_to_be32(sctx->count[1]);
292
293 /* Pad out to 56 mod 64. */
294 index = (sctx->count[0] >> 3) & 0x3f;
295 pad_len = (index < 56) ? (56 - index) : ((64+56) - index);
296 sha256_update(tfm, padding, pad_len);
297
298 /* Append length (before padding) */
299 sha256_update(tfm, (const u8 *)bits, sizeof(bits));
300
301 /* Store state in digest */
302 for (i = 0; i < 8; i++)
303 dst[i] = cpu_to_be32(sctx->state[i]);
304
305 /* Zeroize sensitive information. */
306 memset(sctx, 0, sizeof(*sctx));
307}
308
309
310static struct crypto_alg alg = {
311 .cra_name = "sha256",
312 .cra_driver_name= "sha256-generic",
313 .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
314 .cra_blocksize = SHA256_HMAC_BLOCK_SIZE,
315 .cra_ctxsize = sizeof(struct sha256_ctx),
316 .cra_module = THIS_MODULE,
317 .cra_alignmask = 3,
318 .cra_list = LIST_HEAD_INIT(alg.cra_list),
319 .cra_u = { .digest = {
320 .dia_digestsize = SHA256_DIGEST_SIZE,
321 .dia_init = sha256_init,
322 .dia_update = sha256_update,
323 .dia_final = sha256_final } }
324};
325
326static int __init init(void)
327{
328 return crypto_register_alg(&alg);
329}
330
331static void __exit fini(void)
332{
333 crypto_unregister_alg(&alg);
334}
335
336module_init(init);
337module_exit(fini);
338
339MODULE_LICENSE("GPL");
340MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm");
341
342MODULE_ALIAS("sha256");