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