/home/dko/projects/mobilec/trunk/src/security/xyssl-0.7/library/sha1.c

Go to the documentation of this file.
00001 /*
00002  *  FIPS-180-1 compliant SHA-1 implementation
00003  *
00004  *  Copyright (C) 2006-2007  Christophe Devine
00005  *
00006  *  This library is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU Lesser General Public
00008  *  License, version 2.1 as published by the Free Software Foundation.
00009  *
00010  *  This library is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *  Lesser General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU Lesser General Public
00016  *  License along with this library; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00018  *  MA  02110-1301  USA
00019  */
00020 /*
00021  *  The SHA-1 standard was published by NIST in 1993.
00022  *
00023  *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
00024  */
00025 
00026 #ifndef _CRT_SECURE_NO_DEPRECATE
00027 #define _CRT_SECURE_NO_DEPRECATE 1
00028 #endif
00029 
00030 #include <string.h>
00031 #include <stdio.h>
00032 
00033 #include "xyssl/sha1.h"
00034 
00035 /*
00036  * 32-bit integer manipulation macros (big endian)
00037  */
00038 #ifndef GET_UINT32_BE
00039 #define GET_UINT32_BE(n,b,i)                            \
00040 {                                                       \
00041     (n) = ( (unsigned long) (b)[(i)    ] << 24 )        \
00042         | ( (unsigned long) (b)[(i) + 1] << 16 )        \
00043         | ( (unsigned long) (b)[(i) + 2] <<  8 )        \
00044         | ( (unsigned long) (b)[(i) + 3]       );       \
00045 }
00046 #endif
00047 
00048 #ifndef PUT_UINT32_BE
00049 #define PUT_UINT32_BE(n,b,i)                            \
00050 {                                                       \
00051     (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
00052     (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
00053     (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
00054     (b)[(i) + 3] = (unsigned char) ( (n)       );       \
00055 }
00056 #endif
00057 
00058 /*
00059  * SHA-1 context setup
00060  */
00061 void sha1_starts( sha1_context *ctx )
00062 {
00063     ctx->total[0] = 0;
00064     ctx->total[1] = 0;
00065 
00066     ctx->state[0] = 0x67452301;
00067     ctx->state[1] = 0xEFCDAB89;
00068     ctx->state[2] = 0x98BADCFE;
00069     ctx->state[3] = 0x10325476;
00070     ctx->state[4] = 0xC3D2E1F0;
00071 }
00072 
00073 static void sha1_process( sha1_context *ctx, unsigned char data[64] )
00074 {
00075     unsigned long temp, W[16], A, B, C, D, E;
00076 
00077     GET_UINT32_BE( W[ 0], data,  0 );
00078     GET_UINT32_BE( W[ 1], data,  4 );
00079     GET_UINT32_BE( W[ 2], data,  8 );
00080     GET_UINT32_BE( W[ 3], data, 12 );
00081     GET_UINT32_BE( W[ 4], data, 16 );
00082     GET_UINT32_BE( W[ 5], data, 20 );
00083     GET_UINT32_BE( W[ 6], data, 24 );
00084     GET_UINT32_BE( W[ 7], data, 28 );
00085     GET_UINT32_BE( W[ 8], data, 32 );
00086     GET_UINT32_BE( W[ 9], data, 36 );
00087     GET_UINT32_BE( W[10], data, 40 );
00088     GET_UINT32_BE( W[11], data, 44 );
00089     GET_UINT32_BE( W[12], data, 48 );
00090     GET_UINT32_BE( W[13], data, 52 );
00091     GET_UINT32_BE( W[14], data, 56 );
00092     GET_UINT32_BE( W[15], data, 60 );
00093 
00094 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
00095 
00096 #define R(t)                                            \
00097 (                                                       \
00098     temp = W[(t -  3) & 0x0F] ^ W[(t - 8) & 0x0F] ^     \
00099            W[(t - 14) & 0x0F] ^ W[ t      & 0x0F],      \
00100     ( W[t & 0x0F] = S(temp,1) )                         \
00101 )
00102 
00103 #define P(a,b,c,d,e,x)                                  \
00104 {                                                       \
00105     e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);        \
00106 }
00107 
00108     A = ctx->state[0];
00109     B = ctx->state[1];
00110     C = ctx->state[2];
00111     D = ctx->state[3];
00112     E = ctx->state[4];
00113 
00114 #define F(x,y,z) (z ^ (x & (y ^ z)))
00115 #define K 0x5A827999
00116 
00117     P( A, B, C, D, E, W[0]  );
00118     P( E, A, B, C, D, W[1]  );
00119     P( D, E, A, B, C, W[2]  );
00120     P( C, D, E, A, B, W[3]  );
00121     P( B, C, D, E, A, W[4]  );
00122     P( A, B, C, D, E, W[5]  );
00123     P( E, A, B, C, D, W[6]  );
00124     P( D, E, A, B, C, W[7]  );
00125     P( C, D, E, A, B, W[8]  );
00126     P( B, C, D, E, A, W[9]  );
00127     P( A, B, C, D, E, W[10] );
00128     P( E, A, B, C, D, W[11] );
00129     P( D, E, A, B, C, W[12] );
00130     P( C, D, E, A, B, W[13] );
00131     P( B, C, D, E, A, W[14] );
00132     P( A, B, C, D, E, W[15] );
00133     P( E, A, B, C, D, R(16) );
00134     P( D, E, A, B, C, R(17) );
00135     P( C, D, E, A, B, R(18) );
00136     P( B, C, D, E, A, R(19) );
00137 
00138 #undef K
00139 #undef F
00140 
00141 #define F(x,y,z) (x ^ y ^ z)
00142 #define K 0x6ED9EBA1
00143 
00144     P( A, B, C, D, E, R(20) );
00145     P( E, A, B, C, D, R(21) );
00146     P( D, E, A, B, C, R(22) );
00147     P( C, D, E, A, B, R(23) );
00148     P( B, C, D, E, A, R(24) );
00149     P( A, B, C, D, E, R(25) );
00150     P( E, A, B, C, D, R(26) );
00151     P( D, E, A, B, C, R(27) );
00152     P( C, D, E, A, B, R(28) );
00153     P( B, C, D, E, A, R(29) );
00154     P( A, B, C, D, E, R(30) );
00155     P( E, A, B, C, D, R(31) );
00156     P( D, E, A, B, C, R(32) );
00157     P( C, D, E, A, B, R(33) );
00158     P( B, C, D, E, A, R(34) );
00159     P( A, B, C, D, E, R(35) );
00160     P( E, A, B, C, D, R(36) );
00161     P( D, E, A, B, C, R(37) );
00162     P( C, D, E, A, B, R(38) );
00163     P( B, C, D, E, A, R(39) );
00164 
00165 #undef K
00166 #undef F
00167 
00168 #define F(x,y,z) ((x & y) | (z & (x | y)))
00169 #define K 0x8F1BBCDC
00170 
00171     P( A, B, C, D, E, R(40) );
00172     P( E, A, B, C, D, R(41) );
00173     P( D, E, A, B, C, R(42) );
00174     P( C, D, E, A, B, R(43) );
00175     P( B, C, D, E, A, R(44) );
00176     P( A, B, C, D, E, R(45) );
00177     P( E, A, B, C, D, R(46) );
00178     P( D, E, A, B, C, R(47) );
00179     P( C, D, E, A, B, R(48) );
00180     P( B, C, D, E, A, R(49) );
00181     P( A, B, C, D, E, R(50) );
00182     P( E, A, B, C, D, R(51) );
00183     P( D, E, A, B, C, R(52) );
00184     P( C, D, E, A, B, R(53) );
00185     P( B, C, D, E, A, R(54) );
00186     P( A, B, C, D, E, R(55) );
00187     P( E, A, B, C, D, R(56) );
00188     P( D, E, A, B, C, R(57) );
00189     P( C, D, E, A, B, R(58) );
00190     P( B, C, D, E, A, R(59) );
00191 
00192 #undef K
00193 #undef F
00194 
00195 #define F(x,y,z) (x ^ y ^ z)
00196 #define K 0xCA62C1D6
00197 
00198     P( A, B, C, D, E, R(60) );
00199     P( E, A, B, C, D, R(61) );
00200     P( D, E, A, B, C, R(62) );
00201     P( C, D, E, A, B, R(63) );
00202     P( B, C, D, E, A, R(64) );
00203     P( A, B, C, D, E, R(65) );
00204     P( E, A, B, C, D, R(66) );
00205     P( D, E, A, B, C, R(67) );
00206     P( C, D, E, A, B, R(68) );
00207     P( B, C, D, E, A, R(69) );
00208     P( A, B, C, D, E, R(70) );
00209     P( E, A, B, C, D, R(71) );
00210     P( D, E, A, B, C, R(72) );
00211     P( C, D, E, A, B, R(73) );
00212     P( B, C, D, E, A, R(74) );
00213     P( A, B, C, D, E, R(75) );
00214     P( E, A, B, C, D, R(76) );
00215     P( D, E, A, B, C, R(77) );
00216     P( C, D, E, A, B, R(78) );
00217     P( B, C, D, E, A, R(79) );
00218 
00219 #undef K
00220 #undef F
00221 
00222     ctx->state[0] += A;
00223     ctx->state[1] += B;
00224     ctx->state[2] += C;
00225     ctx->state[3] += D;
00226     ctx->state[4] += E;
00227 }
00228 
00229 /*
00230  * SHA-1 process buffer
00231  */
00232 void sha1_update( sha1_context *ctx, unsigned char *input, int ilen )
00233 {
00234     int fill;
00235     unsigned long left;
00236 
00237     if( ilen <= 0 )
00238         return;
00239 
00240     left = ctx->total[0] & 0x3F;
00241     fill = 64 - left;
00242 
00243     ctx->total[0] += ilen;
00244     ctx->total[0] &= 0xFFFFFFFF;
00245 
00246     if( ctx->total[0] < (unsigned long) ilen )
00247         ctx->total[1]++;
00248 
00249     if( left && ilen >= fill )
00250     {
00251         memcpy( (void *) (ctx->buffer + left),
00252                 (void *) input, fill );
00253         sha1_process( ctx, ctx->buffer );
00254         input += fill;
00255         ilen  -= fill;
00256         left = 0;
00257     }
00258 
00259     while( ilen >= 64 )
00260     {
00261         sha1_process( ctx, input );
00262         input += 64;
00263         ilen  -= 64;
00264     }
00265 
00266     if( ilen > 0 )
00267     {
00268         memcpy( (void *) (ctx->buffer + left),
00269                 (void *) input, ilen );
00270     }
00271 }
00272 
00273 static const unsigned char sha1_padding[64] =
00274 {
00275  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00276     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00277     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00278     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00279 };
00280 
00281 /*
00282  * SHA-1 final digest
00283  */
00284 void sha1_finish( sha1_context *ctx, unsigned char *output )
00285 {
00286     unsigned long last, padn;
00287     unsigned long high, low;
00288     unsigned char msglen[8];
00289 
00290     high = ( ctx->total[0] >> 29 )
00291          | ( ctx->total[1] <<  3 );
00292     low  = ( ctx->total[0] <<  3 );
00293 
00294     PUT_UINT32_BE( high, msglen, 0 );
00295     PUT_UINT32_BE( low,  msglen, 4 );
00296 
00297     last = ctx->total[0] & 0x3F;
00298     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
00299 
00300     sha1_update( ctx, (unsigned char *) sha1_padding, padn );
00301     sha1_update( ctx, msglen, 8 );
00302 
00303     PUT_UINT32_BE( ctx->state[0], output,  0 );
00304     PUT_UINT32_BE( ctx->state[1], output,  4 );
00305     PUT_UINT32_BE( ctx->state[2], output,  8 );
00306     PUT_UINT32_BE( ctx->state[3], output, 12 );
00307     PUT_UINT32_BE( ctx->state[4], output, 16 );
00308 }
00309 
00310 /*
00311  * Output = SHA-1( input buffer )
00312  */
00313 void sha1( unsigned char *input, int ilen,
00314            unsigned char *output )
00315 {
00316     sha1_context ctx;
00317 
00318     sha1_starts( &ctx );
00319     sha1_update( &ctx, input, ilen );
00320     sha1_finish( &ctx, output );
00321 
00322     memset( &ctx, 0, sizeof( sha1_context ) );
00323 }
00324 
00325 /*
00326  * Output = SHA-1( file contents )
00327  */
00328 int sha1_file( char *path, unsigned char *output )
00329 {
00330     FILE *f;
00331     size_t n;
00332     sha1_context ctx;
00333     unsigned char buf[1024];
00334 
00335     if( ( f = fopen( path, "rb" ) ) == NULL )
00336         return( 1 );
00337 
00338     sha1_starts( &ctx );
00339 
00340     while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
00341         sha1_update( &ctx, buf, (int) n );
00342 
00343     sha1_finish( &ctx, output );
00344 
00345     memset( &ctx, 0, sizeof( sha1_context ) );
00346 
00347     if( ferror( f ) != 0 )
00348     {
00349         fclose( f );
00350         return( 2 );
00351     }
00352 
00353     fclose( f );
00354     return( 0 );
00355 }
00356 
00357 /*
00358  * SHA-1 HMAC context setup
00359  */
00360 void sha1_hmac_starts( sha1_context *ctx,
00361                        unsigned char *key, int keylen )
00362 {
00363     int i;
00364 
00365     memset( ctx->ipad, 0x36, 64 );
00366     memset( ctx->opad, 0x5C, 64 );
00367 
00368     for( i = 0; i < keylen; i++ )
00369     {
00370         if( i >= 64 ) break;
00371 
00372         ctx->ipad[i] ^= key[i];
00373         ctx->opad[i] ^= key[i];
00374     }
00375 
00376     sha1_starts( ctx );
00377     sha1_update( ctx, ctx->ipad, 64 );
00378 }
00379 
00380 /*
00381  * SHA-1 HMAC process buffer
00382  */
00383 void sha1_hmac_update( sha1_context *ctx,
00384                        unsigned char *input, int ilen )
00385 {
00386     sha1_update( ctx, input, ilen );
00387 }
00388 
00389 /*
00390  * SHA-1 HMAC final digest
00391  */
00392 void sha1_hmac_finish( sha1_context *ctx, unsigned char *output )
00393 {
00394     unsigned char tmpbuf[20];
00395 
00396     sha1_finish( ctx, tmpbuf );
00397     sha1_starts( ctx );
00398     sha1_update( ctx, ctx->opad, 64 );
00399     sha1_update( ctx, tmpbuf, 20 );
00400     sha1_finish( ctx, output );
00401 
00402     memset( tmpbuf, 0, sizeof( tmpbuf ) );
00403 }
00404 
00405 /*
00406  * Output = HMAC-SHA-1( hmac key, input buffer )
00407  */
00408 void sha1_hmac( unsigned char *key, int keylen,
00409                 unsigned char *input, int ilen,
00410                 unsigned char *output )
00411 {
00412     sha1_context ctx;
00413 
00414     sha1_hmac_starts( &ctx, key, keylen );
00415     sha1_hmac_update( &ctx, input, ilen );
00416     sha1_hmac_finish( &ctx, output );
00417 
00418     memset( &ctx, 0, sizeof( sha1_context ) );
00419 }
00420 
00421 static const char _sha1_src[] = "_sha1_src";
00422 
00423 #if defined(SELF_TEST)
00424 /*
00425  * FIPS-180-1 test vectors
00426  */
00427 static const char sha1_test_str[3][57] = 
00428 {
00429     { "abc" },
00430     { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
00431     { "" }
00432 };
00433 
00434 static const unsigned char sha1_test_sum[3][20] =
00435 {
00436     { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
00437       0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D },
00438     { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
00439       0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 },
00440     { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
00441       0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }
00442 };
00443 
00444 /*
00445  * Checkup routine
00446  */
00447 int sha1_self_test( int verbose )
00448 {
00449     int i, j;
00450     unsigned char buf[1000];
00451     unsigned char sha1sum[20];
00452     sha1_context ctx;
00453 
00454     for( i = 0; i < 3; i++ )
00455     {
00456         if( verbose != 0 )
00457             printf( "  SHA-1 test #%d: ", i + 1 );
00458 
00459         sha1_starts( &ctx );
00460 
00461         if( i < 2 )
00462             sha1_update( &ctx, (unsigned char *) sha1_test_str[i],
00463                          strlen( sha1_test_str[i] ) );
00464         else
00465         {
00466             memset( buf, 'a', 1000 );
00467             for( j = 0; j < 1000; j++ )
00468                 sha1_update( &ctx, buf, 1000 );
00469         }
00470 
00471         sha1_finish( &ctx, sha1sum );
00472 
00473         if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
00474         {
00475             if( verbose != 0 )
00476                 printf( "failed\n" );
00477 
00478             return( 1 );
00479         }
00480 
00481         if( verbose != 0 )
00482             printf( "passed\n" );
00483     }
00484 
00485     if( verbose != 0 )
00486         printf( "\n" );
00487 
00488     return( 0 );
00489 }
00490 #else
00491 int sha1_self_test( int verbose )
00492 {
00493     return( 0 );
00494 }
00495 #endif

Generated on Fri May 16 14:49:55 2008 for Mobile-C by  doxygen 1.5.4