blob: 7348162575ceaccda1fa0100298e47e2f0e25af9 [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)
261 unsigned char *end, *curr;
262 int chunk;
263#endif
264
265 sha256_starts(&ctx);
266
267#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
268 curr = input;
269 end = input + ilen;
270 while (curr < end) {
271 chunk = end - curr;
272 if (chunk > chunk_sz)
273 chunk = chunk_sz;
274 sha256_update(&ctx, curr, chunk);
275 curr += chunk;
276 WATCHDOG_RESET();
277 }
278#else
279 sha256_update(&ctx, input, ilen);
280#endif
281
282 sha256_finish(&ctx, output);
283}