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