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