]> git.ipfire.org Git - people/ms/u-boot.git/blame - lib/sha1.c
Add more SPDX-License-Identifier tags
[people/ms/u-boot.git] / lib / sha1.c
CommitLineData
566a494f
HS
1/*
2 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
3 * based on:
4 * FIPS-180-1 compliant SHA-1 implementation
5 *
6 * Copyright (C) 2003-2006 Christophe Devine
7 *
5b8031cc 8 * SPDX-License-Identifier: LGPL-2.1
566a494f
HS
9 */
10/*
11 * The SHA-1 standard was published by NIST in 1993.
12 *
13 * http://www.itl.nist.gov/fipspubs/fip180-1.htm
14 */
15
16#ifndef _CRT_SECURE_NO_DEPRECATE
17#define _CRT_SECURE_NO_DEPRECATE 1
18#endif
19
7590378f
BS
20#ifndef USE_HOSTCC
21#include <common.h>
a94f22f0 22#include <linux/string.h>
338cc038
WD
23#else
24#include <string.h>
7590378f
BS
25#endif /* USE_HOSTCC */
26#include <watchdog.h>
2b9912e6 27#include <u-boot/sha1.h>
566a494f
HS
28
29/*
30 * 32-bit integer manipulation macros (big endian)
31 */
32#ifndef GET_UINT32_BE
4ef218f6
WD
33#define GET_UINT32_BE(n,b,i) { \
34 (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
35 | ( (unsigned long) (b)[(i) + 1] << 16 ) \
36 | ( (unsigned long) (b)[(i) + 2] << 8 ) \
37 | ( (unsigned long) (b)[(i) + 3] ); \
566a494f
HS
38}
39#endif
40#ifndef PUT_UINT32_BE
4ef218f6
WD
41#define PUT_UINT32_BE(n,b,i) { \
42 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
43 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
44 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
45 (b)[(i) + 3] = (unsigned char) ( (n) ); \
566a494f
HS
46}
47#endif
48
49/*
50 * SHA-1 context setup
51 */
4ef218f6 52void sha1_starts (sha1_context * ctx)
566a494f 53{
4ef218f6
WD
54 ctx->total[0] = 0;
55 ctx->total[1] = 0;
56
57 ctx->state[0] = 0x67452301;
58 ctx->state[1] = 0xEFCDAB89;
59 ctx->state[2] = 0x98BADCFE;
60 ctx->state[3] = 0x10325476;
61 ctx->state[4] = 0xC3D2E1F0;
566a494f
HS
62}
63
a7d1d765 64static void sha1_process(sha1_context *ctx, const unsigned char data[64])
566a494f 65{
4ef218f6
WD
66 unsigned long temp, W[16], A, B, C, D, E;
67
68 GET_UINT32_BE (W[0], data, 0);
69 GET_UINT32_BE (W[1], data, 4);
70 GET_UINT32_BE (W[2], data, 8);
71 GET_UINT32_BE (W[3], data, 12);
72 GET_UINT32_BE (W[4], data, 16);
73 GET_UINT32_BE (W[5], data, 20);
74 GET_UINT32_BE (W[6], data, 24);
75 GET_UINT32_BE (W[7], data, 28);
76 GET_UINT32_BE (W[8], data, 32);
77 GET_UINT32_BE (W[9], data, 36);
78 GET_UINT32_BE (W[10], data, 40);
79 GET_UINT32_BE (W[11], data, 44);
80 GET_UINT32_BE (W[12], data, 48);
81 GET_UINT32_BE (W[13], data, 52);
82 GET_UINT32_BE (W[14], data, 56);
83 GET_UINT32_BE (W[15], data, 60);
84
85#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
86
87#define R(t) ( \
88 temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
89 W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
90 ( W[t & 0x0F] = S(temp,1) ) \
566a494f
HS
91)
92
4ef218f6
WD
93#define P(a,b,c,d,e,x) { \
94 e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
566a494f
HS
95}
96
4ef218f6
WD
97 A = ctx->state[0];
98 B = ctx->state[1];
99 C = ctx->state[2];
100 D = ctx->state[3];
101 E = ctx->state[4];
566a494f
HS
102
103#define F(x,y,z) (z ^ (x & (y ^ z)))
104#define K 0x5A827999
105
4ef218f6
WD
106 P (A, B, C, D, E, W[0]);
107 P (E, A, B, C, D, W[1]);
108 P (D, E, A, B, C, W[2]);
109 P (C, D, E, A, B, W[3]);
110 P (B, C, D, E, A, W[4]);
111 P (A, B, C, D, E, W[5]);
112 P (E, A, B, C, D, W[6]);
113 P (D, E, A, B, C, W[7]);
114 P (C, D, E, A, B, W[8]);
115 P (B, C, D, E, A, W[9]);
116 P (A, B, C, D, E, W[10]);
117 P (E, A, B, C, D, W[11]);
118 P (D, E, A, B, C, W[12]);
119 P (C, D, E, A, B, W[13]);
120 P (B, C, D, E, A, W[14]);
121 P (A, B, C, D, E, W[15]);
122 P (E, A, B, C, D, R (16));
123 P (D, E, A, B, C, R (17));
124 P (C, D, E, A, B, R (18));
125 P (B, C, D, E, A, R (19));
566a494f
HS
126
127#undef K
128#undef F
129
130#define F(x,y,z) (x ^ y ^ z)
131#define K 0x6ED9EBA1
132
4ef218f6
WD
133 P (A, B, C, D, E, R (20));
134 P (E, A, B, C, D, R (21));
135 P (D, E, A, B, C, R (22));
136 P (C, D, E, A, B, R (23));
137 P (B, C, D, E, A, R (24));
138 P (A, B, C, D, E, R (25));
139 P (E, A, B, C, D, R (26));
140 P (D, E, A, B, C, R (27));
141 P (C, D, E, A, B, R (28));
142 P (B, C, D, E, A, R (29));
143 P (A, B, C, D, E, R (30));
144 P (E, A, B, C, D, R (31));
145 P (D, E, A, B, C, R (32));
146 P (C, D, E, A, B, R (33));
147 P (B, C, D, E, A, R (34));
148 P (A, B, C, D, E, R (35));
149 P (E, A, B, C, D, R (36));
150 P (D, E, A, B, C, R (37));
151 P (C, D, E, A, B, R (38));
152 P (B, C, D, E, A, R (39));
566a494f
HS
153
154#undef K
155#undef F
156
157#define F(x,y,z) ((x & y) | (z & (x | y)))
158#define K 0x8F1BBCDC
159
4ef218f6
WD
160 P (A, B, C, D, E, R (40));
161 P (E, A, B, C, D, R (41));
162 P (D, E, A, B, C, R (42));
163 P (C, D, E, A, B, R (43));
164 P (B, C, D, E, A, R (44));
165 P (A, B, C, D, E, R (45));
166 P (E, A, B, C, D, R (46));
167 P (D, E, A, B, C, R (47));
168 P (C, D, E, A, B, R (48));
169 P (B, C, D, E, A, R (49));
170 P (A, B, C, D, E, R (50));
171 P (E, A, B, C, D, R (51));
172 P (D, E, A, B, C, R (52));
173 P (C, D, E, A, B, R (53));
174 P (B, C, D, E, A, R (54));
175 P (A, B, C, D, E, R (55));
176 P (E, A, B, C, D, R (56));
177 P (D, E, A, B, C, R (57));
178 P (C, D, E, A, B, R (58));
179 P (B, C, D, E, A, R (59));
566a494f
HS
180
181#undef K
182#undef F
183
184#define F(x,y,z) (x ^ y ^ z)
185#define K 0xCA62C1D6
186
4ef218f6
WD
187 P (A, B, C, D, E, R (60));
188 P (E, A, B, C, D, R (61));
189 P (D, E, A, B, C, R (62));
190 P (C, D, E, A, B, R (63));
191 P (B, C, D, E, A, R (64));
192 P (A, B, C, D, E, R (65));
193 P (E, A, B, C, D, R (66));
194 P (D, E, A, B, C, R (67));
195 P (C, D, E, A, B, R (68));
196 P (B, C, D, E, A, R (69));
197 P (A, B, C, D, E, R (70));
198 P (E, A, B, C, D, R (71));
199 P (D, E, A, B, C, R (72));
200 P (C, D, E, A, B, R (73));
201 P (B, C, D, E, A, R (74));
202 P (A, B, C, D, E, R (75));
203 P (E, A, B, C, D, R (76));
204 P (D, E, A, B, C, R (77));
205 P (C, D, E, A, B, R (78));
206 P (B, C, D, E, A, R (79));
566a494f
HS
207
208#undef K
209#undef F
210
4ef218f6
WD
211 ctx->state[0] += A;
212 ctx->state[1] += B;
213 ctx->state[2] += C;
214 ctx->state[3] += D;
215 ctx->state[4] += E;
566a494f
HS
216}
217
218/*
219 * SHA-1 process buffer
220 */
a7d1d765
SG
221void sha1_update(sha1_context *ctx, const unsigned char *input,
222 unsigned int ilen)
566a494f 223{
4ef218f6
WD
224 int fill;
225 unsigned long left;
226
227 if (ilen <= 0)
228 return;
229
230 left = ctx->total[0] & 0x3F;
231 fill = 64 - left;
232
233 ctx->total[0] += ilen;
234 ctx->total[0] &= 0xFFFFFFFF;
235
236 if (ctx->total[0] < (unsigned long) ilen)
237 ctx->total[1]++;
238
239 if (left && ilen >= fill) {
240 memcpy ((void *) (ctx->buffer + left), (void *) input, fill);
241 sha1_process (ctx, ctx->buffer);
242 input += fill;
243 ilen -= fill;
244 left = 0;
245 }
246
247 while (ilen >= 64) {
248 sha1_process (ctx, input);
249 input += 64;
250 ilen -= 64;
251 }
252
253 if (ilen > 0) {
254 memcpy ((void *) (ctx->buffer + left), (void *) input, ilen);
255 }
566a494f
HS
256}
257
4ef218f6
WD
258static const unsigned char sha1_padding[64] = {
259 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
260 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
261 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
262 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
566a494f
HS
263};
264
265/*
266 * SHA-1 final digest
267 */
4ef218f6 268void sha1_finish (sha1_context * ctx, unsigned char output[20])
566a494f 269{
4ef218f6
WD
270 unsigned long last, padn;
271 unsigned long high, low;
272 unsigned char msglen[8];
566a494f 273
4ef218f6
WD
274 high = (ctx->total[0] >> 29)
275 | (ctx->total[1] << 3);
276 low = (ctx->total[0] << 3);
566a494f 277
4ef218f6
WD
278 PUT_UINT32_BE (high, msglen, 0);
279 PUT_UINT32_BE (low, msglen, 4);
566a494f 280
4ef218f6
WD
281 last = ctx->total[0] & 0x3F;
282 padn = (last < 56) ? (56 - last) : (120 - last);
566a494f 283
4ef218f6
WD
284 sha1_update (ctx, (unsigned char *) sha1_padding, padn);
285 sha1_update (ctx, msglen, 8);
566a494f 286
4ef218f6
WD
287 PUT_UINT32_BE (ctx->state[0], output, 0);
288 PUT_UINT32_BE (ctx->state[1], output, 4);
289 PUT_UINT32_BE (ctx->state[2], output, 8);
290 PUT_UINT32_BE (ctx->state[3], output, 12);
291 PUT_UINT32_BE (ctx->state[4], output, 16);
566a494f
HS
292}
293
294/*
295 * Output = SHA-1( input buffer )
296 */
a7d1d765
SG
297void sha1_csum(const unsigned char *input, unsigned int ilen,
298 unsigned char *output)
566a494f 299{
4ef218f6 300 sha1_context ctx;
566a494f 301
4ef218f6
WD
302 sha1_starts (&ctx);
303 sha1_update (&ctx, input, ilen);
304 sha1_finish (&ctx, output);
566a494f
HS
305}
306
215b01bb
BS
307/*
308 * Output = SHA-1( input buffer ). Trigger the watchdog every 'chunk_sz'
309 * bytes of input processed.
310 */
a7d1d765
SG
311void sha1_csum_wd(const unsigned char *input, unsigned int ilen,
312 unsigned char *output, unsigned int chunk_sz)
215b01bb
BS
313{
314 sha1_context ctx;
315#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
a7d1d765 316 const unsigned char *end, *curr;
215b01bb
BS
317 int chunk;
318#endif
319
320 sha1_starts (&ctx);
321
322#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
323 curr = input;
324 end = input + ilen;
325 while (curr < end) {
326 chunk = end - curr;
327 if (chunk > chunk_sz)
328 chunk = chunk_sz;
329 sha1_update (&ctx, curr, chunk);
330 curr += chunk;
331 WATCHDOG_RESET ();
332 }
333#else
334 sha1_update (&ctx, input, ilen);
335#endif
336
337 sha1_finish (&ctx, output);
338}
339
566a494f
HS
340/*
341 * Output = HMAC-SHA-1( input buffer, hmac key )
342 */
a7d1d765
SG
343void sha1_hmac(const unsigned char *key, int keylen,
344 const unsigned char *input, unsigned int ilen,
345 unsigned char *output)
566a494f 346{
4ef218f6
WD
347 int i;
348 sha1_context ctx;
349 unsigned char k_ipad[64];
350 unsigned char k_opad[64];
351 unsigned char tmpbuf[20];
352
353 memset (k_ipad, 0x36, 64);
354 memset (k_opad, 0x5C, 64);
355
356 for (i = 0; i < keylen; i++) {
357 if (i >= 64)
358 break;
359
360 k_ipad[i] ^= key[i];
361 k_opad[i] ^= key[i];
362 }
363
364 sha1_starts (&ctx);
365 sha1_update (&ctx, k_ipad, 64);
366 sha1_update (&ctx, input, ilen);
367 sha1_finish (&ctx, tmpbuf);
368
369 sha1_starts (&ctx);
370 sha1_update (&ctx, k_opad, 64);
371 sha1_update (&ctx, tmpbuf, 20);
372 sha1_finish (&ctx, output);
373
374 memset (k_ipad, 0, 64);
375 memset (k_opad, 0, 64);
376 memset (tmpbuf, 0, 20);
377 memset (&ctx, 0, sizeof (sha1_context));
566a494f
HS
378}
379
566a494f
HS
380#ifdef SELF_TEST
381/*
382 * FIPS-180-1 test vectors
383 */
4ef218f6
WD
384static const char sha1_test_str[3][57] = {
385 {"abc"},
386 {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
387 {""}
566a494f
HS
388};
389
4ef218f6
WD
390static const unsigned char sha1_test_sum[3][20] = {
391 {0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
392 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D},
393 {0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
394 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1},
395 {0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
396 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F}
566a494f
HS
397};
398
399/*
400 * Checkup routine
401 */
4ef218f6 402int sha1_self_test (void)
566a494f 403{
4ef218f6
WD
404 int i, j;
405 unsigned char buf[1000];
406 unsigned char sha1sum[20];
407 sha1_context ctx;
408
409 for (i = 0; i < 3; i++) {
410 printf (" SHA-1 test #%d: ", i + 1);
411
412 sha1_starts (&ctx);
413
414 if (i < 2)
415 sha1_update (&ctx, (unsigned char *) sha1_test_str[i],
416 strlen (sha1_test_str[i]));
417 else {
418 memset (buf, 'a', 1000);
419 for (j = 0; j < 1000; j++)
420 sha1_update (&ctx, buf, 1000);
421 }
422
423 sha1_finish (&ctx, sha1sum);
424
425 if (memcmp (sha1sum, sha1_test_sum[i], 20) != 0) {
426 printf ("failed\n");
427 return (1);
428 }
429
430 printf ("passed\n");
431 }
432
433 printf ("\n");
434 return (0);
566a494f
HS
435}
436#else
4ef218f6 437int sha1_self_test (void)
566a494f 438{
4ef218f6 439 return (0);
566a494f
HS
440}
441#endif