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