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