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