sha1.cc

Go to the documentation of this file.
00001 /*
00002  *  FIPS-180-1 compliant SHA-1 implementation
00003  *
00004  *  Copyright (C) 2001-2003  Christophe Devine
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 #include <string.h>
00022 
00023 #include "sha1.h"
00024 
00025 #define GET_UINT32(n,b,i)                       \
00026 {                                               \
00027     (n) = ( (uint32) (b)[(i)    ] << 24 )       \
00028         | ( (uint32) (b)[(i) + 1] << 16 )       \
00029         | ( (uint32) (b)[(i) + 2] <<  8 )       \
00030         | ( (uint32) (b)[(i) + 3]       );      \
00031 }
00032 
00033 #define PUT_UINT32(n,b,i)                       \
00034 {                                               \
00035     (b)[(i)    ] = (uint8) ( (n) >> 24 );       \
00036     (b)[(i) + 1] = (uint8) ( (n) >> 16 );       \
00037     (b)[(i) + 2] = (uint8) ( (n) >>  8 );       \
00038     (b)[(i) + 3] = (uint8) ( (n)       );       \
00039 }
00040 
00041 void sha1_starts( sha1_context *ctx )
00042 {
00043     ctx->total[0] = 0;
00044     ctx->total[1] = 0;
00045 
00046     ctx->state[0] = 0x67452301;
00047     ctx->state[1] = 0xEFCDAB89;
00048     ctx->state[2] = 0x98BADCFE;
00049     ctx->state[3] = 0x10325476;
00050     ctx->state[4] = 0xC3D2E1F0;
00051 }
00052 
00053 void sha1_process( sha1_context *ctx, uint8 data[64] )
00054 {
00055     uint32 temp, W[16], A, B, C, D, E;
00056 
00057     GET_UINT32( W[0],  data,  0 );
00058     GET_UINT32( W[1],  data,  4 );
00059     GET_UINT32( W[2],  data,  8 );
00060     GET_UINT32( W[3],  data, 12 );
00061     GET_UINT32( W[4],  data, 16 );
00062     GET_UINT32( W[5],  data, 20 );
00063     GET_UINT32( W[6],  data, 24 );
00064     GET_UINT32( W[7],  data, 28 );
00065     GET_UINT32( W[8],  data, 32 );
00066     GET_UINT32( W[9],  data, 36 );
00067     GET_UINT32( W[10], data, 40 );
00068     GET_UINT32( W[11], data, 44 );
00069     GET_UINT32( W[12], data, 48 );
00070     GET_UINT32( W[13], data, 52 );
00071     GET_UINT32( W[14], data, 56 );
00072     GET_UINT32( W[15], data, 60 );
00073 
00074 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
00075 
00076 #define R(t)                                            \
00077 (                                                       \
00078     temp = W[(t -  3) & 0x0F] ^ W[(t - 8) & 0x0F] ^     \
00079            W[(t - 14) & 0x0F] ^ W[ t      & 0x0F],      \
00080     ( W[t & 0x0F] = S(temp,1) )                         \
00081 )
00082 
00083 #define P(a,b,c,d,e,x)                                  \
00084 {                                                       \
00085     e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);        \
00086 }
00087 
00088     A = ctx->state[0];
00089     B = ctx->state[1];
00090     C = ctx->state[2];
00091     D = ctx->state[3];
00092     E = ctx->state[4];
00093 
00094 #define F(x,y,z) (z ^ (x & (y ^ z)))
00095 #define K 0x5A827999
00096 
00097     P( A, B, C, D, E, W[0]  );
00098     P( E, A, B, C, D, W[1]  );
00099     P( D, E, A, B, C, W[2]  );
00100     P( C, D, E, A, B, W[3]  );
00101     P( B, C, D, E, A, W[4]  );
00102     P( A, B, C, D, E, W[5]  );
00103     P( E, A, B, C, D, W[6]  );
00104     P( D, E, A, B, C, W[7]  );
00105     P( C, D, E, A, B, W[8]  );
00106     P( B, C, D, E, A, W[9]  );
00107     P( A, B, C, D, E, W[10] );
00108     P( E, A, B, C, D, W[11] );
00109     P( D, E, A, B, C, W[12] );
00110     P( C, D, E, A, B, W[13] );
00111     P( B, C, D, E, A, W[14] );
00112     P( A, B, C, D, E, W[15] );
00113     P( E, A, B, C, D, R(16) );
00114     P( D, E, A, B, C, R(17) );
00115     P( C, D, E, A, B, R(18) );
00116     P( B, C, D, E, A, R(19) );
00117 
00118 #undef K
00119 #undef F
00120 
00121 #define F(x,y,z) (x ^ y ^ z)
00122 #define K 0x6ED9EBA1
00123 
00124     P( A, B, C, D, E, R(20) );
00125     P( E, A, B, C, D, R(21) );
00126     P( D, E, A, B, C, R(22) );
00127     P( C, D, E, A, B, R(23) );
00128     P( B, C, D, E, A, R(24) );
00129     P( A, B, C, D, E, R(25) );
00130     P( E, A, B, C, D, R(26) );
00131     P( D, E, A, B, C, R(27) );
00132     P( C, D, E, A, B, R(28) );
00133     P( B, C, D, E, A, R(29) );
00134     P( A, B, C, D, E, R(30) );
00135     P( E, A, B, C, D, R(31) );
00136     P( D, E, A, B, C, R(32) );
00137     P( C, D, E, A, B, R(33) );
00138     P( B, C, D, E, A, R(34) );
00139     P( A, B, C, D, E, R(35) );
00140     P( E, A, B, C, D, R(36) );
00141     P( D, E, A, B, C, R(37) );
00142     P( C, D, E, A, B, R(38) );
00143     P( B, C, D, E, A, R(39) );
00144 
00145 #undef K
00146 #undef F
00147 
00148 #define F(x,y,z) ((x & y) | (z & (x | y)))
00149 #define K 0x8F1BBCDC
00150 
00151     P( A, B, C, D, E, R(40) );
00152     P( E, A, B, C, D, R(41) );
00153     P( D, E, A, B, C, R(42) );
00154     P( C, D, E, A, B, R(43) );
00155     P( B, C, D, E, A, R(44) );
00156     P( A, B, C, D, E, R(45) );
00157     P( E, A, B, C, D, R(46) );
00158     P( D, E, A, B, C, R(47) );
00159     P( C, D, E, A, B, R(48) );
00160     P( B, C, D, E, A, R(49) );
00161     P( A, B, C, D, E, R(50) );
00162     P( E, A, B, C, D, R(51) );
00163     P( D, E, A, B, C, R(52) );
00164     P( C, D, E, A, B, R(53) );
00165     P( B, C, D, E, A, R(54) );
00166     P( A, B, C, D, E, R(55) );
00167     P( E, A, B, C, D, R(56) );
00168     P( D, E, A, B, C, R(57) );
00169     P( C, D, E, A, B, R(58) );
00170     P( B, C, D, E, A, R(59) );
00171 
00172 #undef K
00173 #undef F
00174 
00175 #define F(x,y,z) (x ^ y ^ z)
00176 #define K 0xCA62C1D6
00177 
00178     P( A, B, C, D, E, R(60) );
00179     P( E, A, B, C, D, R(61) );
00180     P( D, E, A, B, C, R(62) );
00181     P( C, D, E, A, B, R(63) );
00182     P( B, C, D, E, A, R(64) );
00183     P( A, B, C, D, E, R(65) );
00184     P( E, A, B, C, D, R(66) );
00185     P( D, E, A, B, C, R(67) );
00186     P( C, D, E, A, B, R(68) );
00187     P( B, C, D, E, A, R(69) );
00188     P( A, B, C, D, E, R(70) );
00189     P( E, A, B, C, D, R(71) );
00190     P( D, E, A, B, C, R(72) );
00191     P( C, D, E, A, B, R(73) );
00192     P( B, C, D, E, A, R(74) );
00193     P( A, B, C, D, E, R(75) );
00194     P( E, A, B, C, D, R(76) );
00195     P( D, E, A, B, C, R(77) );
00196     P( C, D, E, A, B, R(78) );
00197     P( B, C, D, E, A, R(79) );
00198 
00199 #undef K
00200 #undef F
00201 
00202     ctx->state[0] += A;
00203     ctx->state[1] += B;
00204     ctx->state[2] += C;
00205     ctx->state[3] += D;
00206     ctx->state[4] += E;
00207 }
00208 
00209 void sha1_update( sha1_context *ctx, uint8 *input, uint32 length )
00210 {
00211     uint32 left, fill;
00212 
00213     if( ! length ) return;
00214 
00215     left = ctx->total[0] & 0x3F;
00216     fill = 64 - left;
00217 
00218     ctx->total[0] += length;
00219     ctx->total[0] &= 0xFFFFFFFF;
00220 
00221     if( ctx->total[0] < length )
00222         ctx->total[1]++;
00223 
00224     if( left && length >= fill )
00225     {
00226         memcpy( (void *) (ctx->buffer + left),
00227                 (void *) input, fill );
00228         sha1_process( ctx, ctx->buffer );
00229         length -= fill;
00230         input  += fill;
00231         left = 0;
00232     }
00233 
00234     while( length >= 64 )
00235     {
00236         sha1_process( ctx, input );
00237         length -= 64;
00238         input  += 64;
00239     }
00240 
00241     if( length )
00242     {
00243         memcpy( (void *) (ctx->buffer + left),
00244                 (void *) input, length );
00245     }
00246 }
00247 
00248 static uint8 sha1_padding[64] =
00249 {
00250  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00251     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00252     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00253     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00254 };
00255 
00256 void sha1_finish( sha1_context *ctx, uint8 digest[20] )
00257 {
00258     uint32 last, padn;
00259     uint32 high, low;
00260     uint8 msglen[8];
00261 
00262     high = ( ctx->total[0] >> 29 )
00263          | ( ctx->total[1] <<  3 );
00264     low  = ( ctx->total[0] <<  3 );
00265 
00266     PUT_UINT32( high, msglen, 0 );
00267     PUT_UINT32( low,  msglen, 4 );
00268 
00269     last = ctx->total[0] & 0x3F;
00270     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
00271 
00272     sha1_update( ctx, sha1_padding, padn );
00273     sha1_update( ctx, msglen, 8 );
00274 
00275     PUT_UINT32( ctx->state[0], digest,  0 );
00276     PUT_UINT32( ctx->state[1], digest,  4 );
00277     PUT_UINT32( ctx->state[2], digest,  8 );
00278     PUT_UINT32( ctx->state[3], digest, 12 );
00279     PUT_UINT32( ctx->state[4], digest, 16 );
00280 }
00281 
00282 #ifdef TEST
00283 
00284 #include <stdlib.h>
00285 #include <stdio.h>
00286 
00287 /*
00288  * those are the standard FIPS-180-1 test vectors
00289  */
00290 
00291 static char *msg[] = 
00292 {
00293     "abc",
00294     "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
00295     NULL
00296 };
00297 
00298 static char *val[] =
00299 {
00300     "a9993e364706816aba3e25717850c26c9cd0d89d",
00301     "84983e441c3bd26ebaae4aa1f95129e5e54670f1",
00302     "34aa973cd4c4daa4f61eeb2bdbad27316534016f"
00303 };
00304 
00305 int main( int argc, char *argv[] )
00306 {
00307     FILE *f;
00308     int i, j;
00309     char output[41];
00310     sha1_context ctx;
00311     unsigned char buf[1000];
00312     unsigned char sha1sum[20];
00313 
00314     if( argc < 2 )
00315     {
00316         printf( "\n SHA-1 Validation Tests:\n\n" );
00317 
00318         for( i = 0; i < 3; i++ )
00319         {
00320             printf( " Test %d ", i + 1 );
00321 
00322             sha1_starts( &ctx );
00323 
00324             if( i < 2 )
00325             {
00326                 sha1_update( &ctx, (uint8 *) msg[i],
00327                              strlen( msg[i] ) );
00328             }
00329             else
00330             {
00331                 memset( buf, 'a', 1000 );
00332 
00333                 for( j = 0; j < 1000; j++ )
00334                 {
00335                     sha1_update( &ctx, (uint8 *) buf, 1000 );
00336                 }
00337             }
00338 
00339             sha1_finish( &ctx, sha1sum );
00340 
00341             for( j = 0; j < 20; j++ )
00342             {
00343                 sprintf( output + j * 2, "%02x", sha1sum[j] );
00344             }
00345 
00346             if( memcmp( output, val[i], 40 ) )
00347             {
00348                 printf( "failed!\n" );
00349                 return( 1 );
00350             }
00351 
00352             printf( "passed.\n" );
00353         }
00354 
00355         printf( "\n" );
00356     }
00357     else
00358     {
00359         if( ! ( f = fopen( argv[1], "rb" ) ) )
00360         {
00361             perror( "fopen" );
00362             return( 1 );
00363         }
00364 
00365         sha1_starts( &ctx );
00366 
00367         while( ( i = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
00368         {
00369             sha1_update( &ctx, buf, i );
00370         }
00371 
00372         sha1_finish( &ctx, sha1sum );
00373 
00374         for( j = 0; j < 20; j++ )
00375         {
00376             printf( "%02x", sha1sum[j] );
00377         }
00378 
00379         printf( "  %s\n", argv[1] );
00380     }
00381 
00382     return( 0 );
00383 }
00384 
00385 #endif
00386 

Generated on Thu Jun 7 12:54:29 2007 for DTN Reference Implementation by  doxygen 1.5.1