]> git.ipfire.org Git - thirdparty/u-boot.git/blame - lib/sha256.c
efi_loader: variable: attributes may not be changed if a variable exists
[thirdparty/u-boot.git] / lib / sha256.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
b571afde
JCPV
2/*
3 * FIPS-180-2 compliant SHA-256 implementation
4 *
5 * Copyright (C) 2001-2003 Christophe Devine
b571afde
JCPV
6 */
7
8#ifndef USE_HOSTCC
9#include <common.h>
822ef00e
AB
10#include <linux/string.h>
11#else
12#include <string.h>
b571afde
JCPV
13#endif /* USE_HOSTCC */
14#include <watchdog.h>
2b9912e6 15#include <u-boot/sha256.h>
b571afde 16
da29f299
AD
17const 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
b571afde
JCPV
23/*
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
ec7381fb 58static void sha256_process(sha256_context *ctx, const uint8_t data[64])
b571afde
JCPV
59{
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
ec7381fb 189void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length)
b571afde
JCPV
190{
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}
ec7381fb
SG
258
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)
2842c1c2
HS
268 const unsigned char *end;
269 unsigned char *curr;
ec7381fb
SG
270 int chunk;
271#endif
272
273 sha256_starts(&ctx);
274
275#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
2842c1c2 276 curr = (unsigned char *)input;
ec7381fb
SG
277 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}