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