• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/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
445 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt