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