]> git.ipfire.org Git - people/ms/u-boot.git/blame - lib/sha1.c
stdio: remove useless strncpy
[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>
566a494f
HS
39#include "sha1.h"
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
4ef218f6 76static void sha1_process (sha1_context * ctx, 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 */
4ef218f6 233void sha1_update (sha1_context * ctx, unsigned char *input, int ilen)
566a494f 234{
4ef218f6
WD
235 int fill;
236 unsigned long left;
237
238 if (ilen <= 0)
239 return;
240
241 left = ctx->total[0] & 0x3F;
242 fill = 64 - left;
243
244 ctx->total[0] += ilen;
245 ctx->total[0] &= 0xFFFFFFFF;
246
247 if (ctx->total[0] < (unsigned long) ilen)
248 ctx->total[1]++;
249
250 if (left && ilen >= fill) {
251 memcpy ((void *) (ctx->buffer + left), (void *) input, fill);
252 sha1_process (ctx, ctx->buffer);
253 input += fill;
254 ilen -= fill;
255 left = 0;
256 }
257
258 while (ilen >= 64) {
259 sha1_process (ctx, input);
260 input += 64;
261 ilen -= 64;
262 }
263
264 if (ilen > 0) {
265 memcpy ((void *) (ctx->buffer + left), (void *) input, ilen);
266 }
566a494f
HS
267}
268
4ef218f6
WD
269static const unsigned char sha1_padding[64] = {
270 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
271 0, 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
566a494f
HS
274};
275
276/*
277 * SHA-1 final digest
278 */
4ef218f6 279void sha1_finish (sha1_context * ctx, unsigned char output[20])
566a494f 280{
4ef218f6
WD
281 unsigned long last, padn;
282 unsigned long high, low;
283 unsigned char msglen[8];
566a494f 284
4ef218f6
WD
285 high = (ctx->total[0] >> 29)
286 | (ctx->total[1] << 3);
287 low = (ctx->total[0] << 3);
566a494f 288
4ef218f6
WD
289 PUT_UINT32_BE (high, msglen, 0);
290 PUT_UINT32_BE (low, msglen, 4);
566a494f 291
4ef218f6
WD
292 last = ctx->total[0] & 0x3F;
293 padn = (last < 56) ? (56 - last) : (120 - last);
566a494f 294
4ef218f6
WD
295 sha1_update (ctx, (unsigned char *) sha1_padding, padn);
296 sha1_update (ctx, msglen, 8);
566a494f 297
4ef218f6
WD
298 PUT_UINT32_BE (ctx->state[0], output, 0);
299 PUT_UINT32_BE (ctx->state[1], output, 4);
300 PUT_UINT32_BE (ctx->state[2], output, 8);
301 PUT_UINT32_BE (ctx->state[3], output, 12);
302 PUT_UINT32_BE (ctx->state[4], output, 16);
566a494f
HS
303}
304
305/*
306 * Output = SHA-1( input buffer )
307 */
4ef218f6 308void sha1_csum (unsigned char *input, int ilen, unsigned char output[20])
566a494f 309{
4ef218f6 310 sha1_context ctx;
566a494f 311
4ef218f6
WD
312 sha1_starts (&ctx);
313 sha1_update (&ctx, input, ilen);
314 sha1_finish (&ctx, output);
566a494f
HS
315}
316
215b01bb
BS
317/*
318 * Output = SHA-1( input buffer ). Trigger the watchdog every 'chunk_sz'
319 * bytes of input processed.
320 */
321void sha1_csum_wd (unsigned char *input, int ilen, unsigned char output[20],
322 unsigned int chunk_sz)
323{
324 sha1_context ctx;
325#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
326 unsigned char *end, *curr;
327 int chunk;
328#endif
329
330 sha1_starts (&ctx);
331
332#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
333 curr = input;
334 end = input + ilen;
335 while (curr < end) {
336 chunk = end - curr;
337 if (chunk > chunk_sz)
338 chunk = chunk_sz;
339 sha1_update (&ctx, curr, chunk);
340 curr += chunk;
341 WATCHDOG_RESET ();
342 }
343#else
344 sha1_update (&ctx, input, ilen);
345#endif
346
347 sha1_finish (&ctx, output);
348}
349
566a494f
HS
350/*
351 * Output = HMAC-SHA-1( input buffer, hmac key )
352 */
4ef218f6
WD
353void sha1_hmac (unsigned char *key, int keylen,
354 unsigned char *input, int ilen, unsigned char output[20])
566a494f 355{
4ef218f6
WD
356 int i;
357 sha1_context ctx;
358 unsigned char k_ipad[64];
359 unsigned char k_opad[64];
360 unsigned char tmpbuf[20];
361
362 memset (k_ipad, 0x36, 64);
363 memset (k_opad, 0x5C, 64);
364
365 for (i = 0; i < keylen; i++) {
366 if (i >= 64)
367 break;
368
369 k_ipad[i] ^= key[i];
370 k_opad[i] ^= key[i];
371 }
372
373 sha1_starts (&ctx);
374 sha1_update (&ctx, k_ipad, 64);
375 sha1_update (&ctx, input, ilen);
376 sha1_finish (&ctx, tmpbuf);
377
378 sha1_starts (&ctx);
379 sha1_update (&ctx, k_opad, 64);
380 sha1_update (&ctx, tmpbuf, 20);
381 sha1_finish (&ctx, output);
382
383 memset (k_ipad, 0, 64);
384 memset (k_opad, 0, 64);
385 memset (tmpbuf, 0, 20);
386 memset (&ctx, 0, sizeof (sha1_context));
566a494f
HS
387}
388
389static const char _sha1_src[] = "_sha1_src";
390
391#ifdef SELF_TEST
392/*
393 * FIPS-180-1 test vectors
394 */
4ef218f6
WD
395static const char sha1_test_str[3][57] = {
396 {"abc"},
397 {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
398 {""}
566a494f
HS
399};
400
4ef218f6
WD
401static const unsigned char sha1_test_sum[3][20] = {
402 {0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
403 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D},
404 {0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
405 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1},
406 {0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
407 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F}
566a494f
HS
408};
409
410/*
411 * Checkup routine
412 */
4ef218f6 413int sha1_self_test (void)
566a494f 414{
4ef218f6
WD
415 int i, j;
416 unsigned char buf[1000];
417 unsigned char sha1sum[20];
418 sha1_context ctx;
419
420 for (i = 0; i < 3; i++) {
421 printf (" SHA-1 test #%d: ", i + 1);
422
423 sha1_starts (&ctx);
424
425 if (i < 2)
426 sha1_update (&ctx, (unsigned char *) sha1_test_str[i],
427 strlen (sha1_test_str[i]));
428 else {
429 memset (buf, 'a', 1000);
430 for (j = 0; j < 1000; j++)
431 sha1_update (&ctx, buf, 1000);
432 }
433
434 sha1_finish (&ctx, sha1sum);
435
436 if (memcmp (sha1sum, sha1_test_sum[i], 20) != 0) {
437 printf ("failed\n");
438 return (1);
439 }
440
441 printf ("passed\n");
442 }
443
444 printf ("\n");
445 return (0);
566a494f
HS
446}
447#else
4ef218f6 448int sha1_self_test (void)
566a494f 449{
4ef218f6 450 return (0);
566a494f
HS
451}
452#endif