40cc78ca089137ebd7ab69d41af79453d2967274
[openwrt/staging/mkresin.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, void *data, uint length )
229 {
230 uchar *input = data;
231 ulong left, fill;
232
233 if( ! length ) return;
234
235 left = ctx->total[0] & 0x3F;
236 fill = 64 - left;
237
238 ctx->total[0] += length;
239 ctx->total[0] &= 0xFFFFFFFF;
240
241 if( ctx->total[0] < length )
242 ctx->total[1]++;
243
244 if( left && length >= fill )
245 {
246 memcpy( (void *) (ctx->buffer + left),
247 (void *) input, fill );
248 sha1_process( ctx, ctx->buffer );
249 length -= fill;
250 input += fill;
251 left = 0;
252 }
253
254 while( length >= 64 )
255 {
256 sha1_process( ctx, input );
257 length -= 64;
258 input += 64;
259 }
260
261 if( length )
262 {
263 memcpy( (void *) (ctx->buffer + left),
264 (void *) input, length );
265 }
266 }
267
268 static uchar sha1_padding[64] =
269 {
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
274 };
275
276 void sha1_finish( sha1_context *ctx, uchar digest[20] )
277 {
278 ulong last, padn;
279 ulong high, low;
280 uchar msglen[8];
281
282 high = ( ctx->total[0] >> 29 )
283 | ( ctx->total[1] << 3 );
284 low = ( ctx->total[0] << 3 );
285
286 PUT_UINT32_BE( high, msglen, 0 );
287 PUT_UINT32_BE( low, msglen, 4 );
288
289 last = ctx->total[0] & 0x3F;
290 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
291
292 sha1_update( ctx, sha1_padding, padn );
293 sha1_update( ctx, msglen, 8 );
294
295 PUT_UINT32_BE( ctx->state[0], digest, 0 );
296 PUT_UINT32_BE( ctx->state[1], digest, 4 );
297 PUT_UINT32_BE( ctx->state[2], digest, 8 );
298 PUT_UINT32_BE( ctx->state[3], digest, 12 );
299 PUT_UINT32_BE( ctx->state[4], digest, 16 );
300 }
301
302 /*
303 * Output SHA-1(file contents), returns 0 if successful.
304 */
305 int sha1_file( char *filename, uchar digest[20] )
306 {
307 FILE *f;
308 size_t n;
309 sha1_context ctx;
310 uchar buf[1024];
311
312 if( ( f = fopen( filename, "rb" ) ) == NULL )
313 return( 1 );
314
315 sha1_starts( &ctx );
316
317 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
318 sha1_update( &ctx, buf, (uint) n );
319
320 sha1_finish( &ctx, digest );
321
322 fclose( f );
323 return( 0 );
324 }
325
326 /*
327 * Output SHA-1(buf)
328 */
329 void sha1_csum( uchar *buf, uint buflen, uchar digest[20] )
330 {
331 sha1_context ctx;
332
333 sha1_starts( &ctx );
334 sha1_update( &ctx, buf, buflen );
335 sha1_finish( &ctx, digest );
336 }
337
338 /*
339 * Output HMAC-SHA-1(key,buf)
340 */
341 void sha1_hmac( uchar *key, uint keylen, uchar *buf, uint buflen,
342 uchar digest[20] )
343 {
344 uint i;
345 sha1_context ctx;
346 uchar k_ipad[64];
347 uchar k_opad[64];
348 uchar tmpbuf[20];
349
350 memset( k_ipad, 0x36, 64 );
351 memset( k_opad, 0x5C, 64 );
352
353 for( i = 0; i < keylen; i++ )
354 {
355 if( i >= 64 ) break;
356
357 k_ipad[i] ^= key[i];
358 k_opad[i] ^= key[i];
359 }
360
361 sha1_starts( &ctx );
362 sha1_update( &ctx, k_ipad, 64 );
363 sha1_update( &ctx, buf, buflen );
364 sha1_finish( &ctx, tmpbuf );
365
366 sha1_starts( &ctx );
367 sha1_update( &ctx, k_opad, 64 );
368 sha1_update( &ctx, tmpbuf, 20 );
369 sha1_finish( &ctx, digest );
370
371 memset( k_ipad, 0, 64 );
372 memset( k_opad, 0, 64 );
373 memset( tmpbuf, 0, 20 );
374 memset( &ctx, 0, sizeof( sha1_context ) );
375 }
376
377 #ifdef SELF_TEST
378 /*
379 * FIPS-180-1 test vectors
380 */
381 static char *sha1_test_str[3] =
382 {
383 "abc",
384 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
385 NULL
386 };
387
388 static uchar sha1_test_sum[3][20] =
389 {
390 { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
391 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D },
392 { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
393 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 },
394 { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
395 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }
396 };
397
398 /*
399 * Checkup routine
400 */
401 int sha1_self_test( void )
402 {
403 int i, j;
404 uchar buf[1000];
405 uchar sha1sum[20];
406 sha1_context ctx;
407
408 for( i = 0; i < 3; i++ )
409 {
410 printf( " SHA-1 test #%d: ", i + 1 );
411
412 sha1_starts( &ctx );
413
414 if( i < 2 )
415 sha1_update( &ctx, (uchar *) sha1_test_str[i],
416 strlen( sha1_test_str[i] ) );
417 else
418 {
419 memset( buf, 'a', 1000 );
420 for( j = 0; j < 1000; j++ )
421 sha1_update( &ctx, (uchar *) buf, 1000 );
422 }
423
424 sha1_finish( &ctx, sha1sum );
425
426 if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
427 {
428 printf( "failed\n" );
429 return( 1 );
430 }
431
432 printf( "passed\n" );
433 }
434
435 printf( "\n" );
436 return( 0 );
437 }
438 #else
439 int sha1_self_test( void )
440 {
441 printf( "SHA-1 self-test not available\n\n" );
442 return( 1 );
443 }
444 #endif