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