00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 #include "xyssl/config.h"
00027 
00028 #if defined(XYSSL_SHA1_C)
00029 
00030 #include "xyssl/sha1.h"
00031 
00032 #include <string.h>
00033 #include <stdio.h>
00034 
00035 
00036 
00037 
00038 #ifndef GET_ULONG_BE
00039 #define GET_ULONG_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_ULONG_BE
00049 #define PUT_ULONG_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 
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_ULONG_BE( W[ 0], data,  0 );
00078     GET_ULONG_BE( W[ 1], data,  4 );
00079     GET_ULONG_BE( W[ 2], data,  8 );
00080     GET_ULONG_BE( W[ 3], data, 12 );
00081     GET_ULONG_BE( W[ 4], data, 16 );
00082     GET_ULONG_BE( W[ 5], data, 20 );
00083     GET_ULONG_BE( W[ 6], data, 24 );
00084     GET_ULONG_BE( W[ 7], data, 28 );
00085     GET_ULONG_BE( W[ 8], data, 32 );
00086     GET_ULONG_BE( W[ 9], data, 36 );
00087     GET_ULONG_BE( W[10], data, 40 );
00088     GET_ULONG_BE( W[11], data, 44 );
00089     GET_ULONG_BE( W[12], data, 48 );
00090     GET_ULONG_BE( W[13], data, 52 );
00091     GET_ULONG_BE( W[14], data, 56 );
00092     GET_ULONG_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 
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 
00283 
00284 void sha1_finish( sha1_context *ctx, unsigned char output[20] )
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_ULONG_BE( high, msglen, 0 );
00295     PUT_ULONG_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_ULONG_BE( ctx->state[0], output,  0 );
00304     PUT_ULONG_BE( ctx->state[1], output,  4 );
00305     PUT_ULONG_BE( ctx->state[2], output,  8 );
00306     PUT_ULONG_BE( ctx->state[3], output, 12 );
00307     PUT_ULONG_BE( ctx->state[4], output, 16 );
00308 }
00309 
00310 
00311 
00312 
00313 void sha1( unsigned char *input, int ilen, unsigned char output[20] )
00314 {
00315     sha1_context ctx;
00316 
00317     sha1_starts( &ctx );
00318     sha1_update( &ctx, input, ilen );
00319     sha1_finish( &ctx, output );
00320 
00321     memset( &ctx, 0, sizeof( sha1_context ) );
00322 }
00323 
00324 
00325 
00326 
00327 int sha1_file( char *path, unsigned char output[20] )
00328 {
00329     FILE *f;
00330     size_t n;
00331     sha1_context ctx;
00332     unsigned char buf[1024];
00333 
00334     if( ( f = fopen( path, "rb" ) ) == NULL )
00335         return( 1 );
00336 
00337     sha1_starts( &ctx );
00338 
00339     while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
00340         sha1_update( &ctx, buf, (int) n );
00341 
00342     sha1_finish( &ctx, output );
00343 
00344     memset( &ctx, 0, sizeof( sha1_context ) );
00345 
00346     if( ferror( f ) != 0 )
00347     {
00348         fclose( f );
00349         return( 2 );
00350     }
00351 
00352     fclose( f );
00353     return( 0 );
00354 }
00355 
00356 
00357 
00358 
00359 void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen )
00360 {
00361     int i;
00362     unsigned char sum[20];
00363 
00364     if( keylen > 64 )
00365     {
00366         sha1( key, keylen, sum );
00367         keylen = 20;
00368         key = sum;
00369     }
00370 
00371     memset( ctx->ipad, 0x36, 64 );
00372     memset( ctx->opad, 0x5C, 64 );
00373 
00374     for( i = 0; i < keylen; i++ )
00375     {
00376         ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
00377         ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
00378     }
00379 
00380     sha1_starts( ctx );
00381     sha1_update( ctx, ctx->ipad, 64 );
00382 
00383     memset( sum, 0, sizeof( sum ) );
00384 }
00385 
00386 
00387 
00388 
00389 void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen )
00390 {
00391     sha1_update( ctx, input, ilen );
00392 }
00393 
00394 
00395 
00396 
00397 void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] )
00398 {
00399     unsigned char tmpbuf[20];
00400 
00401     sha1_finish( ctx, tmpbuf );
00402     sha1_starts( ctx );
00403     sha1_update( ctx, ctx->opad, 64 );
00404     sha1_update( ctx, tmpbuf, 20 );
00405     sha1_finish( ctx, output );
00406 
00407     memset( tmpbuf, 0, sizeof( tmpbuf ) );
00408 }
00409 
00410 
00411 
00412 
00413 void sha1_hmac( unsigned char *key, int keylen,
00414                 unsigned char *input, int ilen,
00415                 unsigned char output[20] )
00416 {
00417     sha1_context ctx;
00418 
00419     sha1_hmac_starts( &ctx, key, keylen );
00420     sha1_hmac_update( &ctx, input, ilen );
00421     sha1_hmac_finish( &ctx, output );
00422 
00423     memset( &ctx, 0, sizeof( sha1_context ) );
00424 }
00425 
00426 #if defined(XYSSL_SELF_TEST)
00427 
00428 
00429 
00430 static unsigned char sha1_test_buf[3][57] = 
00431 {
00432     { "abc" },
00433     { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
00434     { "" }
00435 };
00436 
00437 static const int sha1_test_buflen[3] =
00438 {
00439     3, 56, 1000
00440 };
00441 
00442 static const unsigned char sha1_test_sum[3][20] =
00443 {
00444     { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
00445       0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D },
00446     { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
00447       0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 },
00448     { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
00449       0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }
00450 };
00451 
00452 
00453 
00454 
00455 static unsigned char sha1_hmac_test_key[7][26] =
00456 {
00457     { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
00458       "\x0B\x0B\x0B\x0B" },
00459     { "Jefe" },
00460     { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
00461       "\xAA\xAA\xAA\xAA" },
00462     { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
00463       "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
00464     { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
00465       "\x0C\x0C\x0C\x0C" },
00466     { "" }, 
00467     { "" }
00468 };
00469 
00470 static const int sha1_hmac_test_keylen[7] =
00471 {
00472     20, 4, 20, 25, 20, 80, 80
00473 };
00474 
00475 static unsigned char sha1_hmac_test_buf[7][74] =
00476 {
00477     { "Hi There" },
00478     { "what do ya want for nothing?" },
00479     { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
00480       "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
00481       "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
00482       "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
00483       "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
00484     { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
00485       "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
00486       "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
00487       "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
00488       "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
00489     { "Test With Truncation" },
00490     { "Test Using Larger Than Block-Size Key - Hash Key First" },
00491     { "Test Using Larger Than Block-Size Key and Larger"
00492       " Than One Block-Size Data" }
00493 };
00494 
00495 static const int sha1_hmac_test_buflen[7] =
00496 {
00497     8, 28, 50, 50, 20, 54, 73
00498 };
00499 
00500 static const unsigned char sha1_hmac_test_sum[7][20] =
00501 {
00502     { 0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B,
00503       0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00 },
00504     { 0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74,
00505       0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79 },
00506     { 0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3,
00507       0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3 },
00508     { 0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84,
00509       0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA },
00510     { 0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2,
00511       0x7B, 0xE1 },
00512     { 0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70,
00513       0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12 },
00514     { 0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B,
00515       0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91 }
00516 };
00517 
00518 
00519 
00520 
00521 int sha1_self_test( int verbose )
00522 {
00523     int i, j, buflen;
00524     unsigned char buf[1024];
00525     unsigned char sha1sum[20];
00526     sha1_context ctx;
00527 
00528     
00529 
00530 
00531     for( i = 0; i < 3; i++ )
00532     {
00533         if( verbose != 0 )
00534             printf( "  SHA-1 test #%d: ", i + 1 );
00535 
00536         sha1_starts( &ctx );
00537 
00538         if( i == 2 )
00539         {
00540             memset( buf, 'a', buflen = 1000 );
00541 
00542             for( j = 0; j < 1000; j++ )
00543                 sha1_update( &ctx, buf, buflen );
00544         }
00545         else
00546             sha1_update( &ctx, sha1_test_buf[i],
00547                                sha1_test_buflen[i] );
00548 
00549         sha1_finish( &ctx, sha1sum );
00550 
00551         if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
00552         {
00553             if( verbose != 0 )
00554                 printf( "failed\n" );
00555 
00556             return( 1 );
00557         }
00558 
00559         if( verbose != 0 )
00560             printf( "passed\n" );
00561     }
00562 
00563     if( verbose != 0 )
00564         printf( "\n" );
00565 
00566     for( i = 0; i < 7; i++ )
00567     {
00568         if( verbose != 0 )
00569             printf( "  HMAC-SHA-1 test #%d: ", i + 1 );
00570 
00571         if( i == 5 || i == 6 )
00572         {
00573             memset( buf, '\xAA', buflen = 80 );
00574             sha1_hmac_starts( &ctx, buf, buflen );
00575         }
00576         else
00577             sha1_hmac_starts( &ctx, sha1_hmac_test_key[i],
00578                                     sha1_hmac_test_keylen[i] );
00579 
00580         sha1_hmac_update( &ctx, sha1_hmac_test_buf[i],
00581                                 sha1_hmac_test_buflen[i] );
00582 
00583         sha1_hmac_finish( &ctx, sha1sum );
00584 
00585         buflen = ( i == 4 ) ? 12 : 20;
00586 
00587         if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 )
00588         {
00589             if( verbose != 0 )
00590                 printf( "failed\n" );
00591 
00592             return( 1 );
00593         }
00594 
00595         if( verbose != 0 )
00596             printf( "passed\n" );
00597     }
00598 
00599     if( verbose != 0 )
00600         printf( "\n" );
00601 
00602     return( 0 );
00603 }
00604 
00605 #endif
00606 
00607 #endif