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
00027
00028
00029 #include "polarssl/config.h"
00030
00031 #if defined(POLARSSL_SHA4_C)
00032
00033 #include "polarssl/sha4.h"
00034
00035 #include <string.h>
00036 #include <stdio.h>
00037
00038
00039
00040
00041 #ifndef GET_UINT64_BE
00042 #define GET_UINT64_BE(n,b,i) \
00043 { \
00044 (n) = ( (unsigned int64) (b)[(i) ] << 56 ) \
00045 | ( (unsigned int64) (b)[(i) + 1] << 48 ) \
00046 | ( (unsigned int64) (b)[(i) + 2] << 40 ) \
00047 | ( (unsigned int64) (b)[(i) + 3] << 32 ) \
00048 | ( (unsigned int64) (b)[(i) + 4] << 24 ) \
00049 | ( (unsigned int64) (b)[(i) + 5] << 16 ) \
00050 | ( (unsigned int64) (b)[(i) + 6] << 8 ) \
00051 | ( (unsigned int64) (b)[(i) + 7] ); \
00052 }
00053 #endif
00054
00055 #ifndef PUT_UINT64_BE
00056 #define PUT_UINT64_BE(n,b,i) \
00057 { \
00058 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
00059 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
00060 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
00061 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
00062 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
00063 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
00064 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
00065 (b)[(i) + 7] = (unsigned char) ( (n) ); \
00066 }
00067 #endif
00068
00069
00070
00071
00072 static const unsigned int64 K[80] =
00073 {
00074 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
00075 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
00076 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
00077 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
00078 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
00079 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
00080 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
00081 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
00082 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
00083 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
00084 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
00085 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
00086 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
00087 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
00088 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
00089 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
00090 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
00091 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
00092 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
00093 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
00094 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
00095 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
00096 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
00097 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
00098 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
00099 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
00100 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
00101 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
00102 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
00103 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
00104 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
00105 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
00106 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
00107 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
00108 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
00109 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
00110 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
00111 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
00112 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
00113 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
00114 };
00115
00116
00117
00118
00119 void sha4_starts( sha4_context *ctx, int is384 )
00120 {
00121 ctx->total[0] = 0;
00122 ctx->total[1] = 0;
00123
00124 if( is384 == 0 )
00125 {
00126
00127 ctx->state[0] = UL64(0x6A09E667F3BCC908);
00128 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
00129 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
00130 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
00131 ctx->state[4] = UL64(0x510E527FADE682D1);
00132 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
00133 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
00134 ctx->state[7] = UL64(0x5BE0CD19137E2179);
00135 }
00136 else
00137 {
00138
00139 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
00140 ctx->state[1] = UL64(0x629A292A367CD507);
00141 ctx->state[2] = UL64(0x9159015A3070DD17);
00142 ctx->state[3] = UL64(0x152FECD8F70E5939);
00143 ctx->state[4] = UL64(0x67332667FFC00B31);
00144 ctx->state[5] = UL64(0x8EB44A8768581511);
00145 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
00146 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
00147 }
00148
00149 ctx->is384 = is384;
00150 }
00151
00152 static void sha4_process( sha4_context *ctx, unsigned char data[128] )
00153 {
00154 int i;
00155 unsigned int64 temp1, temp2, W[80];
00156 unsigned int64 A, B, C, D, E, F, G, H;
00157
00158 #define SHR(x,n) (x >> n)
00159 #define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
00160
00161 #define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
00162 #define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
00163
00164 #define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
00165 #define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
00166
00167 #define F0(x,y,z) ((x & y) | (z & (x | y)))
00168 #define F1(x,y,z) (z ^ (x & (y ^ z)))
00169
00170 #define P(a,b,c,d,e,f,g,h,x,K) \
00171 { \
00172 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
00173 temp2 = S2(a) + F0(a,b,c); \
00174 d += temp1; h = temp1 + temp2; \
00175 }
00176
00177 for( i = 0; i < 16; i++ )
00178 {
00179 GET_UINT64_BE( W[i], data, i << 3 );
00180 }
00181
00182 for( ; i < 80; i++ )
00183 {
00184 W[i] = S1(W[i - 2]) + W[i - 7] +
00185 S0(W[i - 15]) + W[i - 16];
00186 }
00187
00188 A = ctx->state[0];
00189 B = ctx->state[1];
00190 C = ctx->state[2];
00191 D = ctx->state[3];
00192 E = ctx->state[4];
00193 F = ctx->state[5];
00194 G = ctx->state[6];
00195 H = ctx->state[7];
00196 i = 0;
00197
00198 do
00199 {
00200 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
00201 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
00202 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
00203 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
00204 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
00205 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
00206 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
00207 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
00208 }
00209 while( i < 80 );
00210
00211 ctx->state[0] += A;
00212 ctx->state[1] += B;
00213 ctx->state[2] += C;
00214 ctx->state[3] += D;
00215 ctx->state[4] += E;
00216 ctx->state[5] += F;
00217 ctx->state[6] += G;
00218 ctx->state[7] += H;
00219 }
00220
00221
00222
00223
00224 void sha4_update( sha4_context *ctx, unsigned char *input, int ilen )
00225 {
00226 int fill;
00227 unsigned int64 left;
00228
00229 if( ilen <= 0 )
00230 return;
00231
00232 left = ctx->total[0] & 0x7F;
00233 fill = (int)( 128 - left );
00234
00235 ctx->total[0] += ilen;
00236
00237 if( ctx->total[0] < (unsigned int64) ilen )
00238 ctx->total[1]++;
00239
00240 if( left && ilen >= fill )
00241 {
00242 memcpy( (void *) (ctx->buffer + left),
00243 (void *) input, fill );
00244 sha4_process( ctx, ctx->buffer );
00245 input += fill;
00246 ilen -= fill;
00247 left = 0;
00248 }
00249
00250 while( ilen >= 128 )
00251 {
00252 sha4_process( ctx, input );
00253 input += 128;
00254 ilen -= 128;
00255 }
00256
00257 if( ilen > 0 )
00258 {
00259 memcpy( (void *) (ctx->buffer + left),
00260 (void *) input, ilen );
00261 }
00262 }
00263
00264 static const unsigned char sha4_padding[128] =
00265 {
00266 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00267 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00268 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00269 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00270 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00271 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00272 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00273 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00274 };
00275
00276
00277
00278
00279 void sha4_finish( sha4_context *ctx, unsigned char output[64] )
00280 {
00281 int last, padn;
00282 unsigned int64 high, low;
00283 unsigned char msglen[16];
00284
00285 high = ( ctx->total[0] >> 61 )
00286 | ( ctx->total[1] << 3 );
00287 low = ( ctx->total[0] << 3 );
00288
00289 PUT_UINT64_BE( high, msglen, 0 );
00290 PUT_UINT64_BE( low, msglen, 8 );
00291
00292 last = (int)( ctx->total[0] & 0x7F );
00293 padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
00294
00295 sha4_update( ctx, (unsigned char *) sha4_padding, padn );
00296 sha4_update( ctx, msglen, 16 );
00297
00298 PUT_UINT64_BE( ctx->state[0], output, 0 );
00299 PUT_UINT64_BE( ctx->state[1], output, 8 );
00300 PUT_UINT64_BE( ctx->state[2], output, 16 );
00301 PUT_UINT64_BE( ctx->state[3], output, 24 );
00302 PUT_UINT64_BE( ctx->state[4], output, 32 );
00303 PUT_UINT64_BE( ctx->state[5], output, 40 );
00304
00305 if( ctx->is384 == 0 )
00306 {
00307 PUT_UINT64_BE( ctx->state[6], output, 48 );
00308 PUT_UINT64_BE( ctx->state[7], output, 56 );
00309 }
00310 }
00311
00312
00313
00314
00315 void sha4( unsigned char *input, int ilen,
00316 unsigned char output[64], int is384 )
00317 {
00318 sha4_context ctx;
00319
00320 sha4_starts( &ctx, is384 );
00321 sha4_update( &ctx, input, ilen );
00322 sha4_finish( &ctx, output );
00323
00324 memset( &ctx, 0, sizeof( sha4_context ) );
00325 }
00326
00327
00328
00329
00330 int sha4_file( char *path, unsigned char output[64], int is384 )
00331 {
00332 FILE *f;
00333 size_t n;
00334 sha4_context ctx;
00335 unsigned char buf[1024];
00336
00337 if( ( f = fopen( path, "rb" ) ) == NULL )
00338 return( 1 );
00339
00340 sha4_starts( &ctx, is384 );
00341
00342 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
00343 sha4_update( &ctx, buf, (int) n );
00344
00345 sha4_finish( &ctx, output );
00346
00347 memset( &ctx, 0, sizeof( sha4_context ) );
00348
00349 if( ferror( f ) != 0 )
00350 {
00351 fclose( f );
00352 return( 2 );
00353 }
00354
00355 fclose( f );
00356 return( 0 );
00357 }
00358
00359
00360
00361
00362 void sha4_hmac_starts( sha4_context *ctx, unsigned char *key, int keylen,
00363 int is384 )
00364 {
00365 int i;
00366 unsigned char sum[64];
00367
00368 if( keylen > 128 )
00369 {
00370 sha4( key, keylen, sum, is384 );
00371 keylen = ( is384 ) ? 48 : 64;
00372 key = sum;
00373 }
00374
00375 memset( ctx->ipad, 0x36, 128 );
00376 memset( ctx->opad, 0x5C, 128 );
00377
00378 for( i = 0; i < keylen; i++ )
00379 {
00380 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
00381 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
00382 }
00383
00384 sha4_starts( ctx, is384 );
00385 sha4_update( ctx, ctx->ipad, 128 );
00386
00387 memset( sum, 0, sizeof( sum ) );
00388 }
00389
00390
00391
00392
00393 void sha4_hmac_update( sha4_context *ctx,
00394 unsigned char *input, int ilen )
00395 {
00396 sha4_update( ctx, input, ilen );
00397 }
00398
00399
00400
00401
00402 void sha4_hmac_finish( sha4_context *ctx, unsigned char output[64] )
00403 {
00404 int is384, hlen;
00405 unsigned char tmpbuf[64];
00406
00407 is384 = ctx->is384;
00408 hlen = ( is384 == 0 ) ? 64 : 48;
00409
00410 sha4_finish( ctx, tmpbuf );
00411 sha4_starts( ctx, is384 );
00412 sha4_update( ctx, ctx->opad, 128 );
00413 sha4_update( ctx, tmpbuf, hlen );
00414 sha4_finish( ctx, output );
00415
00416 memset( tmpbuf, 0, sizeof( tmpbuf ) );
00417 }
00418
00419
00420
00421
00422 void sha4_hmac( unsigned char *key, int keylen,
00423 unsigned char *input, int ilen,
00424 unsigned char output[64], int is384 )
00425 {
00426 sha4_context ctx;
00427
00428 sha4_hmac_starts( &ctx, key, keylen, is384 );
00429 sha4_hmac_update( &ctx, input, ilen );
00430 sha4_hmac_finish( &ctx, output );
00431
00432 memset( &ctx, 0, sizeof( sha4_context ) );
00433 }
00434
00435 #if defined(POLARSSL_SELF_TEST)
00436
00437
00438
00439
00440 static unsigned char sha4_test_buf[3][113] =
00441 {
00442 { "abc" },
00443 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
00444 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
00445 { "" }
00446 };
00447
00448 static const int sha4_test_buflen[3] =
00449 {
00450 3, 112, 1000
00451 };
00452
00453 static const unsigned char sha4_test_sum[6][64] =
00454 {
00455
00456
00457
00458 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
00459 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
00460 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
00461 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
00462 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
00463 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
00464 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
00465 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
00466 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
00467 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
00468 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
00469 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
00470 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
00471 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
00472 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
00473 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
00474 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
00475 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
00476
00477
00478
00479
00480 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
00481 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
00482 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
00483 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
00484 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
00485 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
00486 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
00487 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
00488 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
00489 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
00490 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
00491 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
00492 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
00493 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
00494 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
00495 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
00496 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
00497 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
00498 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
00499 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
00500 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
00501 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
00502 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
00503 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
00504 };
00505
00506
00507
00508
00509 static unsigned char sha4_hmac_test_key[7][26] =
00510 {
00511 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
00512 "\x0B\x0B\x0B\x0B" },
00513 { "Jefe" },
00514 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
00515 "\xAA\xAA\xAA\xAA" },
00516 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
00517 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
00518 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
00519 "\x0C\x0C\x0C\x0C" },
00520 { "" },
00521 { "" }
00522 };
00523
00524 static const int sha4_hmac_test_keylen[7] =
00525 {
00526 20, 4, 20, 25, 20, 131, 131
00527 };
00528
00529 static unsigned char sha4_hmac_test_buf[7][153] =
00530 {
00531 { "Hi There" },
00532 { "what do ya want for nothing?" },
00533 { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
00534 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
00535 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
00536 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
00537 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
00538 { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
00539 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
00540 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
00541 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
00542 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
00543 { "Test With Truncation" },
00544 { "Test Using Larger Than Block-Size Key - Hash Key First" },
00545 { "This is a test using a larger than block-size key "
00546 "and a larger than block-size data. The key needs to "
00547 "be hashed before being used by the HMAC algorithm." }
00548 };
00549
00550 static const int sha4_hmac_test_buflen[7] =
00551 {
00552 8, 28, 50, 50, 20, 54, 152
00553 };
00554
00555 static const unsigned char sha4_hmac_test_sum[14][64] =
00556 {
00557
00558
00559
00560 { 0xAF, 0xD0, 0x39, 0x44, 0xD8, 0x48, 0x95, 0x62,
00561 0x6B, 0x08, 0x25, 0xF4, 0xAB, 0x46, 0x90, 0x7F,
00562 0x15, 0xF9, 0xDA, 0xDB, 0xE4, 0x10, 0x1E, 0xC6,
00563 0x82, 0xAA, 0x03, 0x4C, 0x7C, 0xEB, 0xC5, 0x9C,
00564 0xFA, 0xEA, 0x9E, 0xA9, 0x07, 0x6E, 0xDE, 0x7F,
00565 0x4A, 0xF1, 0x52, 0xE8, 0xB2, 0xFA, 0x9C, 0xB6 },
00566 { 0xAF, 0x45, 0xD2, 0xE3, 0x76, 0x48, 0x40, 0x31,
00567 0x61, 0x7F, 0x78, 0xD2, 0xB5, 0x8A, 0x6B, 0x1B,
00568 0x9C, 0x7E, 0xF4, 0x64, 0xF5, 0xA0, 0x1B, 0x47,
00569 0xE4, 0x2E, 0xC3, 0x73, 0x63, 0x22, 0x44, 0x5E,
00570 0x8E, 0x22, 0x40, 0xCA, 0x5E, 0x69, 0xE2, 0xC7,
00571 0x8B, 0x32, 0x39, 0xEC, 0xFA, 0xB2, 0x16, 0x49 },
00572 { 0x88, 0x06, 0x26, 0x08, 0xD3, 0xE6, 0xAD, 0x8A,
00573 0x0A, 0xA2, 0xAC, 0xE0, 0x14, 0xC8, 0xA8, 0x6F,
00574 0x0A, 0xA6, 0x35, 0xD9, 0x47, 0xAC, 0x9F, 0xEB,
00575 0xE8, 0x3E, 0xF4, 0xE5, 0x59, 0x66, 0x14, 0x4B,
00576 0x2A, 0x5A, 0xB3, 0x9D, 0xC1, 0x38, 0x14, 0xB9,
00577 0x4E, 0x3A, 0xB6, 0xE1, 0x01, 0xA3, 0x4F, 0x27 },
00578 { 0x3E, 0x8A, 0x69, 0xB7, 0x78, 0x3C, 0x25, 0x85,
00579 0x19, 0x33, 0xAB, 0x62, 0x90, 0xAF, 0x6C, 0xA7,
00580 0x7A, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9C,
00581 0xC5, 0x57, 0x7C, 0x6E, 0x1F, 0x57, 0x3B, 0x4E,
00582 0x68, 0x01, 0xDD, 0x23, 0xC4, 0xA7, 0xD6, 0x79,
00583 0xCC, 0xF8, 0xA3, 0x86, 0xC6, 0x74, 0xCF, 0xFB },
00584 { 0x3A, 0xBF, 0x34, 0xC3, 0x50, 0x3B, 0x2A, 0x23,
00585 0xA4, 0x6E, 0xFC, 0x61, 0x9B, 0xAE, 0xF8, 0x97 },
00586 { 0x4E, 0xCE, 0x08, 0x44, 0x85, 0x81, 0x3E, 0x90,
00587 0x88, 0xD2, 0xC6, 0x3A, 0x04, 0x1B, 0xC5, 0xB4,
00588 0x4F, 0x9E, 0xF1, 0x01, 0x2A, 0x2B, 0x58, 0x8F,
00589 0x3C, 0xD1, 0x1F, 0x05, 0x03, 0x3A, 0xC4, 0xC6,
00590 0x0C, 0x2E, 0xF6, 0xAB, 0x40, 0x30, 0xFE, 0x82,
00591 0x96, 0x24, 0x8D, 0xF1, 0x63, 0xF4, 0x49, 0x52 },
00592 { 0x66, 0x17, 0x17, 0x8E, 0x94, 0x1F, 0x02, 0x0D,
00593 0x35, 0x1E, 0x2F, 0x25, 0x4E, 0x8F, 0xD3, 0x2C,
00594 0x60, 0x24, 0x20, 0xFE, 0xB0, 0xB8, 0xFB, 0x9A,
00595 0xDC, 0xCE, 0xBB, 0x82, 0x46, 0x1E, 0x99, 0xC5,
00596 0xA6, 0x78, 0xCC, 0x31, 0xE7, 0x99, 0x17, 0x6D,
00597 0x38, 0x60, 0xE6, 0x11, 0x0C, 0x46, 0x52, 0x3E },
00598
00599
00600
00601
00602 { 0x87, 0xAA, 0x7C, 0xDE, 0xA5, 0xEF, 0x61, 0x9D,
00603 0x4F, 0xF0, 0xB4, 0x24, 0x1A, 0x1D, 0x6C, 0xB0,
00604 0x23, 0x79, 0xF4, 0xE2, 0xCE, 0x4E, 0xC2, 0x78,
00605 0x7A, 0xD0, 0xB3, 0x05, 0x45, 0xE1, 0x7C, 0xDE,
00606 0xDA, 0xA8, 0x33, 0xB7, 0xD6, 0xB8, 0xA7, 0x02,
00607 0x03, 0x8B, 0x27, 0x4E, 0xAE, 0xA3, 0xF4, 0xE4,
00608 0xBE, 0x9D, 0x91, 0x4E, 0xEB, 0x61, 0xF1, 0x70,
00609 0x2E, 0x69, 0x6C, 0x20, 0x3A, 0x12, 0x68, 0x54 },
00610 { 0x16, 0x4B, 0x7A, 0x7B, 0xFC, 0xF8, 0x19, 0xE2,
00611 0xE3, 0x95, 0xFB, 0xE7, 0x3B, 0x56, 0xE0, 0xA3,
00612 0x87, 0xBD, 0x64, 0x22, 0x2E, 0x83, 0x1F, 0xD6,
00613 0x10, 0x27, 0x0C, 0xD7, 0xEA, 0x25, 0x05, 0x54,
00614 0x97, 0x58, 0xBF, 0x75, 0xC0, 0x5A, 0x99, 0x4A,
00615 0x6D, 0x03, 0x4F, 0x65, 0xF8, 0xF0, 0xE6, 0xFD,
00616 0xCA, 0xEA, 0xB1, 0xA3, 0x4D, 0x4A, 0x6B, 0x4B,
00617 0x63, 0x6E, 0x07, 0x0A, 0x38, 0xBC, 0xE7, 0x37 },
00618 { 0xFA, 0x73, 0xB0, 0x08, 0x9D, 0x56, 0xA2, 0x84,
00619 0xEF, 0xB0, 0xF0, 0x75, 0x6C, 0x89, 0x0B, 0xE9,
00620 0xB1, 0xB5, 0xDB, 0xDD, 0x8E, 0xE8, 0x1A, 0x36,
00621 0x55, 0xF8, 0x3E, 0x33, 0xB2, 0x27, 0x9D, 0x39,
00622 0xBF, 0x3E, 0x84, 0x82, 0x79, 0xA7, 0x22, 0xC8,
00623 0x06, 0xB4, 0x85, 0xA4, 0x7E, 0x67, 0xC8, 0x07,
00624 0xB9, 0x46, 0xA3, 0x37, 0xBE, 0xE8, 0x94, 0x26,
00625 0x74, 0x27, 0x88, 0x59, 0xE1, 0x32, 0x92, 0xFB },
00626 { 0xB0, 0xBA, 0x46, 0x56, 0x37, 0x45, 0x8C, 0x69,
00627 0x90, 0xE5, 0xA8, 0xC5, 0xF6, 0x1D, 0x4A, 0xF7,
00628 0xE5, 0x76, 0xD9, 0x7F, 0xF9, 0x4B, 0x87, 0x2D,
00629 0xE7, 0x6F, 0x80, 0x50, 0x36, 0x1E, 0xE3, 0xDB,
00630 0xA9, 0x1C, 0xA5, 0xC1, 0x1A, 0xA2, 0x5E, 0xB4,
00631 0xD6, 0x79, 0x27, 0x5C, 0xC5, 0x78, 0x80, 0x63,
00632 0xA5, 0xF1, 0x97, 0x41, 0x12, 0x0C, 0x4F, 0x2D,
00633 0xE2, 0xAD, 0xEB, 0xEB, 0x10, 0xA2, 0x98, 0xDD },
00634 { 0x41, 0x5F, 0xAD, 0x62, 0x71, 0x58, 0x0A, 0x53,
00635 0x1D, 0x41, 0x79, 0xBC, 0x89, 0x1D, 0x87, 0xA6 },
00636 { 0x80, 0xB2, 0x42, 0x63, 0xC7, 0xC1, 0xA3, 0xEB,
00637 0xB7, 0x14, 0x93, 0xC1, 0xDD, 0x7B, 0xE8, 0xB4,
00638 0x9B, 0x46, 0xD1, 0xF4, 0x1B, 0x4A, 0xEE, 0xC1,
00639 0x12, 0x1B, 0x01, 0x37, 0x83, 0xF8, 0xF3, 0x52,
00640 0x6B, 0x56, 0xD0, 0x37, 0xE0, 0x5F, 0x25, 0x98,
00641 0xBD, 0x0F, 0xD2, 0x21, 0x5D, 0x6A, 0x1E, 0x52,
00642 0x95, 0xE6, 0x4F, 0x73, 0xF6, 0x3F, 0x0A, 0xEC,
00643 0x8B, 0x91, 0x5A, 0x98, 0x5D, 0x78, 0x65, 0x98 },
00644 { 0xE3, 0x7B, 0x6A, 0x77, 0x5D, 0xC8, 0x7D, 0xBA,
00645 0xA4, 0xDF, 0xA9, 0xF9, 0x6E, 0x5E, 0x3F, 0xFD,
00646 0xDE, 0xBD, 0x71, 0xF8, 0x86, 0x72, 0x89, 0x86,
00647 0x5D, 0xF5, 0xA3, 0x2D, 0x20, 0xCD, 0xC9, 0x44,
00648 0xB6, 0x02, 0x2C, 0xAC, 0x3C, 0x49, 0x82, 0xB1,
00649 0x0D, 0x5E, 0xEB, 0x55, 0xC3, 0xE4, 0xDE, 0x15,
00650 0x13, 0x46, 0x76, 0xFB, 0x6D, 0xE0, 0x44, 0x60,
00651 0x65, 0xC9, 0x74, 0x40, 0xFA, 0x8C, 0x6A, 0x58 }
00652 };
00653
00654
00655
00656
00657 int sha4_self_test( int verbose )
00658 {
00659 int i, j, k, buflen;
00660 unsigned char buf[1024];
00661 unsigned char sha4sum[64];
00662 sha4_context ctx;
00663
00664 for( i = 0; i < 6; i++ )
00665 {
00666 j = i % 3;
00667 k = i < 3;
00668
00669 if( verbose != 0 )
00670 printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
00671
00672 sha4_starts( &ctx, k );
00673
00674 if( j == 2 )
00675 {
00676 memset( buf, 'a', buflen = 1000 );
00677
00678 for( j = 0; j < 1000; j++ )
00679 sha4_update( &ctx, buf, buflen );
00680 }
00681 else
00682 sha4_update( &ctx, sha4_test_buf[j],
00683 sha4_test_buflen[j] );
00684
00685 sha4_finish( &ctx, sha4sum );
00686
00687 if( memcmp( sha4sum, sha4_test_sum[i], 64 - k * 16 ) != 0 )
00688 {
00689 if( verbose != 0 )
00690 printf( "failed\n" );
00691
00692 return( 1 );
00693 }
00694
00695 if( verbose != 0 )
00696 printf( "passed\n" );
00697 }
00698
00699 if( verbose != 0 )
00700 printf( "\n" );
00701
00702 for( i = 0; i < 14; i++ )
00703 {
00704 j = i % 7;
00705 k = i < 7;
00706
00707 if( verbose != 0 )
00708 printf( " HMAC-SHA-%d test #%d: ", 512 - k * 128, j + 1 );
00709
00710 if( j == 5 || j == 6 )
00711 {
00712 memset( buf, '\xAA', buflen = 131 );
00713 sha4_hmac_starts( &ctx, buf, buflen, k );
00714 }
00715 else
00716 sha4_hmac_starts( &ctx, sha4_hmac_test_key[j],
00717 sha4_hmac_test_keylen[j], k );
00718
00719 sha4_hmac_update( &ctx, sha4_hmac_test_buf[j],
00720 sha4_hmac_test_buflen[j] );
00721
00722 sha4_hmac_finish( &ctx, sha4sum );
00723
00724 buflen = ( j == 4 ) ? 16 : 64 - k * 16;
00725
00726 if( memcmp( sha4sum, sha4_hmac_test_sum[i], buflen ) != 0 )
00727 {
00728 if( verbose != 0 )
00729 printf( "failed\n" );
00730
00731 return( 1 );
00732 }
00733
00734 if( verbose != 0 )
00735 printf( "passed\n" );
00736 }
00737
00738 if( verbose != 0 )
00739 printf( "\n" );
00740
00741 return( 0 );
00742 }
00743
00744 #endif
00745
00746 #endif