blob: ab2db4890ae7eb4bc432320bb2a044a0d56aa518 [file] [log] [blame]
Jean-Christophe PLAGNIOL-VILLARDb571afd2008-06-07 12:29:52 +02001/*
2 * FIPS-180-2 compliant SHA-256 implementation
3 *
4 * Copyright (C) 2001-2003 Christophe Devine
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef USE_HOSTCC
22#include <common.h>
23#endif /* USE_HOSTCC */
24#include <watchdog.h>
25#include <linux/string.h>
26#include <sha256.h>
27
28/*
29 * 32-bit integer manipulation macros (big endian)
30 */
31#ifndef GET_UINT32_BE
32#define GET_UINT32_BE(n,b,i) { \
33 (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
34 | ( (unsigned long) (b)[(i) + 1] << 16 ) \
35 | ( (unsigned long) (b)[(i) + 2] << 8 ) \
36 | ( (unsigned long) (b)[(i) + 3] ); \
37}
38#endif
39#ifndef PUT_UINT32_BE
40#define PUT_UINT32_BE(n,b,i) { \
41 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
42 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
43 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
44 (b)[(i) + 3] = (unsigned char) ( (n) ); \
45}
46#endif
47
48void sha256_starts(sha256_context * ctx)
49{
50 ctx->total[0] = 0;
51 ctx->total[1] = 0;
52
53 ctx->state[0] = 0x6A09E667;
54 ctx->state[1] = 0xBB67AE85;
55 ctx->state[2] = 0x3C6EF372;
56 ctx->state[3] = 0xA54FF53A;
57 ctx->state[4] = 0x510E527F;
58 ctx->state[5] = 0x9B05688C;
59 ctx->state[6] = 0x1F83D9AB;
60 ctx->state[7] = 0x5BE0CD19;
61}
62
Simon Glassec7381f2012-12-05 14:46:34 +000063static void sha256_process(sha256_context *ctx, const uint8_t data[64])
Jean-Christophe PLAGNIOL-VILLARDb571afd2008-06-07 12:29:52 +020064{
65 uint32_t temp1, temp2;
66 uint32_t W[64];
67 uint32_t A, B, C, D, E, F, G, H;
68
69 GET_UINT32_BE(W[0], data, 0);
70 GET_UINT32_BE(W[1], data, 4);
71 GET_UINT32_BE(W[2], data, 8);
72 GET_UINT32_BE(W[3], data, 12);
73 GET_UINT32_BE(W[4], data, 16);
74 GET_UINT32_BE(W[5], data, 20);
75 GET_UINT32_BE(W[6], data, 24);
76 GET_UINT32_BE(W[7], data, 28);
77 GET_UINT32_BE(W[8], data, 32);
78 GET_UINT32_BE(W[9], data, 36);
79 GET_UINT32_BE(W[10], data, 40);
80 GET_UINT32_BE(W[11], data, 44);
81 GET_UINT32_BE(W[12], data, 48);
82 GET_UINT32_BE(W[13], data, 52);
83 GET_UINT32_BE(W[14], data, 56);
84 GET_UINT32_BE(W[15], data, 60);
85
86#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
87#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
88
89#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
90#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
91
92#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
93#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
94
95#define F0(x,y,z) ((x & y) | (z & (x | y)))
96#define F1(x,y,z) (z ^ (x & (y ^ z)))
97
98#define R(t) \
99( \
100 W[t] = S1(W[t - 2]) + W[t - 7] + \
101 S0(W[t - 15]) + W[t - 16] \
102)
103
104#define P(a,b,c,d,e,f,g,h,x,K) { \
105 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
106 temp2 = S2(a) + F0(a,b,c); \
107 d += temp1; h = temp1 + temp2; \
108}
109
110 A = ctx->state[0];
111 B = ctx->state[1];
112 C = ctx->state[2];
113 D = ctx->state[3];
114 E = ctx->state[4];
115 F = ctx->state[5];
116 G = ctx->state[6];
117 H = ctx->state[7];
118
119 P(A, B, C, D, E, F, G, H, W[0], 0x428A2F98);
120 P(H, A, B, C, D, E, F, G, W[1], 0x71374491);
121 P(G, H, A, B, C, D, E, F, W[2], 0xB5C0FBCF);
122 P(F, G, H, A, B, C, D, E, W[3], 0xE9B5DBA5);
123 P(E, F, G, H, A, B, C, D, W[4], 0x3956C25B);
124 P(D, E, F, G, H, A, B, C, W[5], 0x59F111F1);
125 P(C, D, E, F, G, H, A, B, W[6], 0x923F82A4);
126 P(B, C, D, E, F, G, H, A, W[7], 0xAB1C5ED5);
127 P(A, B, C, D, E, F, G, H, W[8], 0xD807AA98);
128 P(H, A, B, C, D, E, F, G, W[9], 0x12835B01);
129 P(G, H, A, B, C, D, E, F, W[10], 0x243185BE);
130 P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
131 P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
132 P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
133 P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
134 P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
135 P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
136 P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
137 P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
138 P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
139 P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
140 P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
141 P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
142 P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
143 P(A, B, C, D, E, F, G, H, R(24), 0x983E5152);
144 P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
145 P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
146 P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
147 P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
148 P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
149 P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
150 P(B, C, D, E, F, G, H, A, R(31), 0x14292967);
151 P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
152 P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
153 P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
154 P(F, G, H, A, B, C, D, E, R(35), 0x53380D13);
155 P(E, F, G, H, A, B, C, D, R(36), 0x650A7354);
156 P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
157 P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
158 P(B, C, D, E, F, G, H, A, R(39), 0x92722C85);
159 P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
160 P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
161 P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
162 P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
163 P(E, F, G, H, A, B, C, D, R(44), 0xD192E819);
164 P(D, E, F, G, H, A, B, C, R(45), 0xD6990624);
165 P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
166 P(B, C, D, E, F, G, H, A, R(47), 0x106AA070);
167 P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
168 P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
169 P(G, H, A, B, C, D, E, F, R(50), 0x2748774C);
170 P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
171 P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
172 P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
173 P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
174 P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
175 P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
176 P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
177 P(G, H, A, B, C, D, E, F, R(58), 0x84C87814);
178 P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
179 P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
180 P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
181 P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
182 P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
183
184 ctx->state[0] += A;
185 ctx->state[1] += B;
186 ctx->state[2] += C;
187 ctx->state[3] += D;
188 ctx->state[4] += E;
189 ctx->state[5] += F;
190 ctx->state[6] += G;
191 ctx->state[7] += H;
192}
193
Simon Glassec7381f2012-12-05 14:46:34 +0000194void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length)
Jean-Christophe PLAGNIOL-VILLARDb571afd2008-06-07 12:29:52 +0200195{
196 uint32_t left, fill;
197
198 if (!length)
199 return;
200
201 left = ctx->total[0] & 0x3F;
202 fill = 64 - left;
203
204 ctx->total[0] += length;
205 ctx->total[0] &= 0xFFFFFFFF;
206
207 if (ctx->total[0] < length)
208 ctx->total[1]++;
209
210 if (left && length >= fill) {
211 memcpy((void *) (ctx->buffer + left), (void *) input, fill);
212 sha256_process(ctx, ctx->buffer);
213 length -= fill;
214 input += fill;
215 left = 0;
216 }
217
218 while (length >= 64) {
219 sha256_process(ctx, input);
220 length -= 64;
221 input += 64;
222 }
223
224 if (length)
225 memcpy((void *) (ctx->buffer + left), (void *) input, length);
226}
227
228static uint8_t sha256_padding[64] = {
229 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
230 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
231 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
232 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
233};
234
235void sha256_finish(sha256_context * ctx, uint8_t digest[32])
236{
237 uint32_t last, padn;
238 uint32_t high, low;
239 uint8_t msglen[8];
240
241 high = ((ctx->total[0] >> 29)
242 | (ctx->total[1] << 3));
243 low = (ctx->total[0] << 3);
244
245 PUT_UINT32_BE(high, msglen, 0);
246 PUT_UINT32_BE(low, msglen, 4);
247
248 last = ctx->total[0] & 0x3F;
249 padn = (last < 56) ? (56 - last) : (120 - last);
250
251 sha256_update(ctx, sha256_padding, padn);
252 sha256_update(ctx, msglen, 8);
253
254 PUT_UINT32_BE(ctx->state[0], digest, 0);
255 PUT_UINT32_BE(ctx->state[1], digest, 4);
256 PUT_UINT32_BE(ctx->state[2], digest, 8);
257 PUT_UINT32_BE(ctx->state[3], digest, 12);
258 PUT_UINT32_BE(ctx->state[4], digest, 16);
259 PUT_UINT32_BE(ctx->state[5], digest, 20);
260 PUT_UINT32_BE(ctx->state[6], digest, 24);
261 PUT_UINT32_BE(ctx->state[7], digest, 28);
262}
Simon Glassec7381f2012-12-05 14:46:34 +0000263
264/*
265 * Output = SHA-256( input buffer ). Trigger the watchdog every 'chunk_sz'
266 * bytes of input processed.
267 */
268void sha256_csum_wd(const unsigned char *input, unsigned int ilen,
269 unsigned char *output, unsigned int chunk_sz)
270{
271 sha256_context ctx;
272#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
273 unsigned char *end, *curr;
274 int chunk;
275#endif
276
277 sha256_starts(&ctx);
278
279#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
280 curr = input;
281 end = input + ilen;
282 while (curr < end) {
283 chunk = end - curr;
284 if (chunk > chunk_sz)
285 chunk = chunk_sz;
286 sha256_update(&ctx, curr, chunk);
287 curr += chunk;
288 WATCHDOG_RESET();
289 }
290#else
291 sha256_update(&ctx, input, ilen);
292#endif
293
294 sha256_finish(&ctx, output);
295}