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