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