rpcd: iwinfo plugin fixes
[openwrt.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