00001 /* 00002 * FIPS-180-2 compliant SHA-256 implementation 00003 * 00004 * Copyright (C) 2006-2007 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 along 00017 * with this program; if not, write to the Free Software Foundation, Inc., 00018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00019 */ 00020 /* 00021 * The SHA-256 Secure Hash Standard was published by NIST in 2002. 00022 * 00023 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf 00024 */ 00025 00026 #include "xyssl/config.h" 00027 00028 #if defined(XYSSL_SHA2_C) 00029 00030 #include "xyssl/sha2.h" 00031 00032 #include <string.h> 00033 #include <stdio.h> 00034 00035 /* 00036 * 32-bit integer manipulation macros (big endian) 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 * SHA-256 context setup 00060 */ 00061 void sha2_starts( sha2_context *ctx, int is224 ) 00062 { 00063 ctx->total[0] = 0; 00064 ctx->total[1] = 0; 00065 00066 if( is224 == 0 ) 00067 { 00068 /* SHA-256 */ 00069 ctx->state[0] = 0x6A09E667; 00070 ctx->state[1] = 0xBB67AE85; 00071 ctx->state[2] = 0x3C6EF372; 00072 ctx->state[3] = 0xA54FF53A; 00073 ctx->state[4] = 0x510E527F; 00074 ctx->state[5] = 0x9B05688C; 00075 ctx->state[6] = 0x1F83D9AB; 00076 ctx->state[7] = 0x5BE0CD19; 00077 } 00078 else 00079 { 00080 /* SHA-224 */ 00081 ctx->state[0] = 0xC1059ED8; 00082 ctx->state[1] = 0x367CD507; 00083 ctx->state[2] = 0x3070DD17; 00084 ctx->state[3] = 0xF70E5939; 00085 ctx->state[4] = 0xFFC00B31; 00086 ctx->state[5] = 0x68581511; 00087 ctx->state[6] = 0x64F98FA7; 00088 ctx->state[7] = 0xBEFA4FA4; 00089 } 00090 00091 ctx->is224 = is224; 00092 } 00093 00094 static void sha2_process( sha2_context *ctx, unsigned char data[64] ) 00095 { 00096 unsigned long temp1, temp2, W[64]; 00097 unsigned long A, B, C, D, E, F, G, H; 00098 00099 GET_ULONG_BE( W[ 0], data, 0 ); 00100 GET_ULONG_BE( W[ 1], data, 4 ); 00101 GET_ULONG_BE( W[ 2], data, 8 ); 00102 GET_ULONG_BE( W[ 3], data, 12 ); 00103 GET_ULONG_BE( W[ 4], data, 16 ); 00104 GET_ULONG_BE( W[ 5], data, 20 ); 00105 GET_ULONG_BE( W[ 6], data, 24 ); 00106 GET_ULONG_BE( W[ 7], data, 28 ); 00107 GET_ULONG_BE( W[ 8], data, 32 ); 00108 GET_ULONG_BE( W[ 9], data, 36 ); 00109 GET_ULONG_BE( W[10], data, 40 ); 00110 GET_ULONG_BE( W[11], data, 44 ); 00111 GET_ULONG_BE( W[12], data, 48 ); 00112 GET_ULONG_BE( W[13], data, 52 ); 00113 GET_ULONG_BE( W[14], data, 56 ); 00114 GET_ULONG_BE( W[15], data, 60 ); 00115 00116 #define SHR(x,n) ((x & 0xFFFFFFFF) >> n) 00117 #define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) 00118 00119 #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) 00120 #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) 00121 00122 #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) 00123 #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) 00124 00125 #define F0(x,y,z) ((x & y) | (z & (x | y))) 00126 #define F1(x,y,z) (z ^ (x & (y ^ z))) 00127 00128 #define R(t) \ 00129 ( \ 00130 W[t] = S1(W[t - 2]) + W[t - 7] + \ 00131 S0(W[t - 15]) + W[t - 16] \ 00132 ) 00133 00134 #define P(a,b,c,d,e,f,g,h,x,K) \ 00135 { \ 00136 temp1 = h + S3(e) + F1(e,f,g) + K + x; \ 00137 temp2 = S2(a) + F0(a,b,c); \ 00138 d += temp1; h = temp1 + temp2; \ 00139 } 00140 00141 A = ctx->state[0]; 00142 B = ctx->state[1]; 00143 C = ctx->state[2]; 00144 D = ctx->state[3]; 00145 E = ctx->state[4]; 00146 F = ctx->state[5]; 00147 G = ctx->state[6]; 00148 H = ctx->state[7]; 00149 00150 P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 ); 00151 P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 ); 00152 P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF ); 00153 P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 ); 00154 P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B ); 00155 P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 ); 00156 P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 ); 00157 P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 ); 00158 P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 ); 00159 P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 ); 00160 P( G, H, A, B, C, D, E, F, W[10], 0x243185BE ); 00161 P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 ); 00162 P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 ); 00163 P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE ); 00164 P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 ); 00165 P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 ); 00166 P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 ); 00167 P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 ); 00168 P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 ); 00169 P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC ); 00170 P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F ); 00171 P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA ); 00172 P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC ); 00173 P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA ); 00174 P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 ); 00175 P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D ); 00176 P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 ); 00177 P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 ); 00178 P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 ); 00179 P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 ); 00180 P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 ); 00181 P( B, C, D, E, F, G, H, A, R(31), 0x14292967 ); 00182 P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 ); 00183 P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 ); 00184 P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC ); 00185 P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 ); 00186 P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 ); 00187 P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB ); 00188 P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E ); 00189 P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 ); 00190 P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 ); 00191 P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B ); 00192 P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 ); 00193 P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 ); 00194 P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 ); 00195 P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 ); 00196 P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 ); 00197 P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 ); 00198 P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 ); 00199 P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 ); 00200 P( G, H, A, B, C, D, E, F, R(50), 0x2748774C ); 00201 P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 ); 00202 P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 ); 00203 P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A ); 00204 P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F ); 00205 P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 ); 00206 P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE ); 00207 P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F ); 00208 P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 ); 00209 P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 ); 00210 P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA ); 00211 P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB ); 00212 P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 ); 00213 P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 ); 00214 00215 ctx->state[0] += A; 00216 ctx->state[1] += B; 00217 ctx->state[2] += C; 00218 ctx->state[3] += D; 00219 ctx->state[4] += E; 00220 ctx->state[5] += F; 00221 ctx->state[6] += G; 00222 ctx->state[7] += H; 00223 } 00224 00225 /* 00226 * SHA-256 process buffer 00227 */ 00228 void sha2_update( sha2_context *ctx, unsigned char *input, int ilen ) 00229 { 00230 int fill; 00231 unsigned long left; 00232 00233 if( ilen <= 0 ) 00234 return; 00235 00236 left = ctx->total[0] & 0x3F; 00237 fill = 64 - left; 00238 00239 ctx->total[0] += ilen; 00240 ctx->total[0] &= 0xFFFFFFFF; 00241 00242 if( ctx->total[0] < (unsigned long) ilen ) 00243 ctx->total[1]++; 00244 00245 if( left && ilen >= fill ) 00246 { 00247 memcpy( (void *) (ctx->buffer + left), 00248 (void *) input, fill ); 00249 sha2_process( ctx, ctx->buffer ); 00250 input += fill; 00251 ilen -= fill; 00252 left = 0; 00253 } 00254 00255 while( ilen >= 64 ) 00256 { 00257 sha2_process( ctx, input ); 00258 input += 64; 00259 ilen -= 64; 00260 } 00261 00262 if( ilen > 0 ) 00263 { 00264 memcpy( (void *) (ctx->buffer + left), 00265 (void *) input, ilen ); 00266 } 00267 } 00268 00269 static const unsigned char sha2_padding[64] = 00270 { 00271 0x80, 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 }; 00276 00277 /* 00278 * SHA-256 final digest 00279 */ 00280 void sha2_finish( sha2_context *ctx, unsigned char output[32] ) 00281 { 00282 unsigned long last, padn; 00283 unsigned long high, low; 00284 unsigned char msglen[8]; 00285 00286 high = ( ctx->total[0] >> 29 ) 00287 | ( ctx->total[1] << 3 ); 00288 low = ( ctx->total[0] << 3 ); 00289 00290 PUT_ULONG_BE( high, msglen, 0 ); 00291 PUT_ULONG_BE( low, msglen, 4 ); 00292 00293 last = ctx->total[0] & 0x3F; 00294 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); 00295 00296 sha2_update( ctx, (unsigned char *) sha2_padding, padn ); 00297 sha2_update( ctx, msglen, 8 ); 00298 00299 PUT_ULONG_BE( ctx->state[0], output, 0 ); 00300 PUT_ULONG_BE( ctx->state[1], output, 4 ); 00301 PUT_ULONG_BE( ctx->state[2], output, 8 ); 00302 PUT_ULONG_BE( ctx->state[3], output, 12 ); 00303 PUT_ULONG_BE( ctx->state[4], output, 16 ); 00304 PUT_ULONG_BE( ctx->state[5], output, 20 ); 00305 PUT_ULONG_BE( ctx->state[6], output, 24 ); 00306 00307 if( ctx->is224 == 0 ) 00308 PUT_ULONG_BE( ctx->state[7], output, 28 ); 00309 } 00310 00311 /* 00312 * output = SHA-256( input buffer ) 00313 */ 00314 void sha2( unsigned char *input, int ilen, 00315 unsigned char output[32], int is224 ) 00316 { 00317 sha2_context ctx; 00318 00319 sha2_starts( &ctx, is224 ); 00320 sha2_update( &ctx, input, ilen ); 00321 sha2_finish( &ctx, output ); 00322 00323 memset( &ctx, 0, sizeof( sha2_context ) ); 00324 } 00325 00326 /* 00327 * output = SHA-256( file contents ) 00328 */ 00329 int sha2_file( char *path, unsigned char output[32], int is224 ) 00330 { 00331 FILE *f; 00332 size_t n; 00333 sha2_context ctx; 00334 unsigned char buf[1024]; 00335 00336 if( ( f = fopen( path, "rb" ) ) == NULL ) 00337 return( 1 ); 00338 00339 sha2_starts( &ctx, is224 ); 00340 00341 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) 00342 sha2_update( &ctx, buf, (int) n ); 00343 00344 sha2_finish( &ctx, output ); 00345 00346 memset( &ctx, 0, sizeof( sha2_context ) ); 00347 00348 if( ferror( f ) != 0 ) 00349 { 00350 fclose( f ); 00351 return( 2 ); 00352 } 00353 00354 fclose( f ); 00355 return( 0 ); 00356 } 00357 00358 /* 00359 * SHA-256 HMAC context setup 00360 */ 00361 void sha2_hmac_starts( sha2_context *ctx, unsigned char *key, int keylen, 00362 int is224 ) 00363 { 00364 int i; 00365 unsigned char sum[32]; 00366 00367 if( keylen > 64 ) 00368 { 00369 sha2( key, keylen, sum, is224 ); 00370 keylen = ( is224 ) ? 28 : 32; 00371 key = sum; 00372 } 00373 00374 memset( ctx->ipad, 0x36, 64 ); 00375 memset( ctx->opad, 0x5C, 64 ); 00376 00377 for( i = 0; i < keylen; i++ ) 00378 { 00379 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); 00380 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); 00381 } 00382 00383 sha2_starts( ctx, is224 ); 00384 sha2_update( ctx, ctx->ipad, 64 ); 00385 00386 memset( sum, 0, sizeof( sum ) ); 00387 } 00388 00389 /* 00390 * SHA-256 HMAC process buffer 00391 */ 00392 void sha2_hmac_update( sha2_context *ctx, unsigned char *input, int ilen ) 00393 { 00394 sha2_update( ctx, input, ilen ); 00395 } 00396 00397 /* 00398 * SHA-256 HMAC final digest 00399 */ 00400 void sha2_hmac_finish( sha2_context *ctx, unsigned char output[32] ) 00401 { 00402 int is224, hlen; 00403 unsigned char tmpbuf[32]; 00404 00405 is224 = ctx->is224; 00406 hlen = ( is224 == 0 ) ? 32 : 28; 00407 00408 sha2_finish( ctx, tmpbuf ); 00409 sha2_starts( ctx, is224 ); 00410 sha2_update( ctx, ctx->opad, 64 ); 00411 sha2_update( ctx, tmpbuf, hlen ); 00412 sha2_finish( ctx, output ); 00413 00414 memset( tmpbuf, 0, sizeof( tmpbuf ) ); 00415 } 00416 00417 /* 00418 * output = HMAC-SHA-256( hmac key, input buffer ) 00419 */ 00420 void sha2_hmac( unsigned char *key, int keylen, 00421 unsigned char *input, int ilen, 00422 unsigned char output[32], int is224 ) 00423 { 00424 sha2_context ctx; 00425 00426 sha2_hmac_starts( &ctx, key, keylen, is224 ); 00427 sha2_hmac_update( &ctx, input, ilen ); 00428 sha2_hmac_finish( &ctx, output ); 00429 00430 memset( &ctx, 0, sizeof( sha2_context ) ); 00431 } 00432 00433 #if defined(XYSSL_SELF_TEST) 00434 /* 00435 * FIPS-180-2 test vectors 00436 */ 00437 static unsigned char sha2_test_buf[3][57] = 00438 { 00439 { "abc" }, 00440 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, 00441 { "" } 00442 }; 00443 00444 static const int sha2_test_buflen[3] = 00445 { 00446 3, 56, 1000 00447 }; 00448 00449 static const unsigned char sha2_test_sum[6][32] = 00450 { 00451 /* 00452 * SHA-224 test vectors 00453 */ 00454 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22, 00455 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3, 00456 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7, 00457 0xE3, 0x6C, 0x9D, 0xA7 }, 00458 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC, 00459 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50, 00460 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19, 00461 0x52, 0x52, 0x25, 0x25 }, 00462 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8, 00463 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B, 00464 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE, 00465 0x4E, 0xE7, 0xAD, 0x67 }, 00466 00467 /* 00468 * SHA-256 test vectors 00469 */ 00470 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, 00471 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, 00472 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, 00473 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD }, 00474 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, 00475 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, 00476 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, 00477 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 }, 00478 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92, 00479 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67, 00480 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E, 00481 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 } 00482 }; 00483 00484 /* 00485 * RFC 4231 test vectors 00486 */ 00487 static unsigned char sha2_hmac_test_key[7][26] = 00488 { 00489 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" 00490 "\x0B\x0B\x0B\x0B" }, 00491 { "Jefe" }, 00492 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" 00493 "\xAA\xAA\xAA\xAA" }, 00494 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" 00495 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, 00496 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" 00497 "\x0C\x0C\x0C\x0C" }, 00498 { "" }, /* 0xAA 131 times */ 00499 { "" } 00500 }; 00501 00502 static const int sha2_hmac_test_keylen[7] = 00503 { 00504 20, 4, 20, 25, 20, 131, 131 00505 }; 00506 00507 static unsigned char sha2_hmac_test_buf[7][153] = 00508 { 00509 { "Hi There" }, 00510 { "what do ya want for nothing?" }, 00511 { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" 00512 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" 00513 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" 00514 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" 00515 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, 00516 { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" 00517 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" 00518 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" 00519 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" 00520 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, 00521 { "Test With Truncation" }, 00522 { "Test Using Larger Than Block-Size Key - Hash Key First" }, 00523 { "This is a test using a larger than block-size key " 00524 "and a larger than block-size data. The key needs to " 00525 "be hashed before being used by the HMAC algorithm." } 00526 }; 00527 00528 static const int sha2_hmac_test_buflen[7] = 00529 { 00530 8, 28, 50, 50, 20, 54, 152 00531 }; 00532 00533 static const unsigned char sha2_hmac_test_sum[14][32] = 00534 { 00535 /* 00536 * HMAC-SHA-224 test vectors 00537 */ 00538 { 0x89, 0x6F, 0xB1, 0x12, 0x8A, 0xBB, 0xDF, 0x19, 00539 0x68, 0x32, 0x10, 0x7C, 0xD4, 0x9D, 0xF3, 0x3F, 00540 0x47, 0xB4, 0xB1, 0x16, 0x99, 0x12, 0xBA, 0x4F, 00541 0x53, 0x68, 0x4B, 0x22 }, 00542 { 0xA3, 0x0E, 0x01, 0x09, 0x8B, 0xC6, 0xDB, 0xBF, 00543 0x45, 0x69, 0x0F, 0x3A, 0x7E, 0x9E, 0x6D, 0x0F, 00544 0x8B, 0xBE, 0xA2, 0xA3, 0x9E, 0x61, 0x48, 0x00, 00545 0x8F, 0xD0, 0x5E, 0x44 }, 00546 { 0x7F, 0xB3, 0xCB, 0x35, 0x88, 0xC6, 0xC1, 0xF6, 00547 0xFF, 0xA9, 0x69, 0x4D, 0x7D, 0x6A, 0xD2, 0x64, 00548 0x93, 0x65, 0xB0, 0xC1, 0xF6, 0x5D, 0x69, 0xD1, 00549 0xEC, 0x83, 0x33, 0xEA }, 00550 { 0x6C, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3C, 0xAC, 00551 0x6A, 0x2A, 0xBC, 0x1B, 0xB3, 0x82, 0x62, 0x7C, 00552 0xEC, 0x6A, 0x90, 0xD8, 0x6E, 0xFC, 0x01, 0x2D, 00553 0xE7, 0xAF, 0xEC, 0x5A }, 00554 { 0x0E, 0x2A, 0xEA, 0x68, 0xA9, 0x0C, 0x8D, 0x37, 00555 0xC9, 0x88, 0xBC, 0xDB, 0x9F, 0xCA, 0x6F, 0xA8 }, 00556 { 0x95, 0xE9, 0xA0, 0xDB, 0x96, 0x20, 0x95, 0xAD, 00557 0xAE, 0xBE, 0x9B, 0x2D, 0x6F, 0x0D, 0xBC, 0xE2, 00558 0xD4, 0x99, 0xF1, 0x12, 0xF2, 0xD2, 0xB7, 0x27, 00559 0x3F, 0xA6, 0x87, 0x0E }, 00560 { 0x3A, 0x85, 0x41, 0x66, 0xAC, 0x5D, 0x9F, 0x02, 00561 0x3F, 0x54, 0xD5, 0x17, 0xD0, 0xB3, 0x9D, 0xBD, 00562 0x94, 0x67, 0x70, 0xDB, 0x9C, 0x2B, 0x95, 0xC9, 00563 0xF6, 0xF5, 0x65, 0xD1 }, 00564 00565 /* 00566 * HMAC-SHA-256 test vectors 00567 */ 00568 { 0xB0, 0x34, 0x4C, 0x61, 0xD8, 0xDB, 0x38, 0x53, 00569 0x5C, 0xA8, 0xAF, 0xCE, 0xAF, 0x0B, 0xF1, 0x2B, 00570 0x88, 0x1D, 0xC2, 0x00, 0xC9, 0x83, 0x3D, 0xA7, 00571 0x26, 0xE9, 0x37, 0x6C, 0x2E, 0x32, 0xCF, 0xF7 }, 00572 { 0x5B, 0xDC, 0xC1, 0x46, 0xBF, 0x60, 0x75, 0x4E, 00573 0x6A, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xC7, 00574 0x5A, 0x00, 0x3F, 0x08, 0x9D, 0x27, 0x39, 0x83, 00575 0x9D, 0xEC, 0x58, 0xB9, 0x64, 0xEC, 0x38, 0x43 }, 00576 { 0x77, 0x3E, 0xA9, 0x1E, 0x36, 0x80, 0x0E, 0x46, 00577 0x85, 0x4D, 0xB8, 0xEB, 0xD0, 0x91, 0x81, 0xA7, 00578 0x29, 0x59, 0x09, 0x8B, 0x3E, 0xF8, 0xC1, 0x22, 00579 0xD9, 0x63, 0x55, 0x14, 0xCE, 0xD5, 0x65, 0xFE }, 00580 { 0x82, 0x55, 0x8A, 0x38, 0x9A, 0x44, 0x3C, 0x0E, 00581 0xA4, 0xCC, 0x81, 0x98, 0x99, 0xF2, 0x08, 0x3A, 00582 0x85, 0xF0, 0xFA, 0xA3, 0xE5, 0x78, 0xF8, 0x07, 00583 0x7A, 0x2E, 0x3F, 0xF4, 0x67, 0x29, 0x66, 0x5B }, 00584 { 0xA3, 0xB6, 0x16, 0x74, 0x73, 0x10, 0x0E, 0xE0, 00585 0x6E, 0x0C, 0x79, 0x6C, 0x29, 0x55, 0x55, 0x2B }, 00586 { 0x60, 0xE4, 0x31, 0x59, 0x1E, 0xE0, 0xB6, 0x7F, 00587 0x0D, 0x8A, 0x26, 0xAA, 0xCB, 0xF5, 0xB7, 0x7F, 00588 0x8E, 0x0B, 0xC6, 0x21, 0x37, 0x28, 0xC5, 0x14, 00589 0x05, 0x46, 0x04, 0x0F, 0x0E, 0xE3, 0x7F, 0x54 }, 00590 { 0x9B, 0x09, 0xFF, 0xA7, 0x1B, 0x94, 0x2F, 0xCB, 00591 0x27, 0x63, 0x5F, 0xBC, 0xD5, 0xB0, 0xE9, 0x44, 00592 0xBF, 0xDC, 0x63, 0x64, 0x4F, 0x07, 0x13, 0x93, 00593 0x8A, 0x7F, 0x51, 0x53, 0x5C, 0x3A, 0x35, 0xE2 } 00594 }; 00595 00596 /* 00597 * Checkup routine 00598 */ 00599 int sha2_self_test( int verbose ) 00600 { 00601 int i, j, k, buflen; 00602 unsigned char buf[1024]; 00603 unsigned char sha2sum[32]; 00604 sha2_context ctx; 00605 00606 for( i = 0; i < 6; i++ ) 00607 { 00608 j = i % 3; 00609 k = i < 3; 00610 00611 if( verbose != 0 ) 00612 printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 ); 00613 00614 sha2_starts( &ctx, k ); 00615 00616 if( j == 2 ) 00617 { 00618 memset( buf, 'a', buflen = 1000 ); 00619 00620 for( j = 0; j < 1000; j++ ) 00621 sha2_update( &ctx, buf, buflen ); 00622 } 00623 else 00624 sha2_update( &ctx, sha2_test_buf[j], 00625 sha2_test_buflen[j] ); 00626 00627 sha2_finish( &ctx, sha2sum ); 00628 00629 if( memcmp( sha2sum, sha2_test_sum[i], 32 - k * 4 ) != 0 ) 00630 { 00631 if( verbose != 0 ) 00632 printf( "failed\n" ); 00633 00634 return( 1 ); 00635 } 00636 00637 if( verbose != 0 ) 00638 printf( "passed\n" ); 00639 } 00640 00641 if( verbose != 0 ) 00642 printf( "\n" ); 00643 00644 for( i = 0; i < 14; i++ ) 00645 { 00646 j = i % 7; 00647 k = i < 7; 00648 00649 if( verbose != 0 ) 00650 printf( " HMAC-SHA-%d test #%d: ", 256 - k * 32, j + 1 ); 00651 00652 if( j == 5 || j == 6 ) 00653 { 00654 memset( buf, '\xAA', buflen = 131 ); 00655 sha2_hmac_starts( &ctx, buf, buflen, k ); 00656 } 00657 else 00658 sha2_hmac_starts( &ctx, sha2_hmac_test_key[j], 00659 sha2_hmac_test_keylen[j], k ); 00660 00661 sha2_hmac_update( &ctx, sha2_hmac_test_buf[j], 00662 sha2_hmac_test_buflen[j] ); 00663 00664 sha2_hmac_finish( &ctx, sha2sum ); 00665 00666 buflen = ( j == 4 ) ? 16 : 32 - k * 4; 00667 00668 if( memcmp( sha2sum, sha2_hmac_test_sum[i], buflen ) != 0 ) 00669 { 00670 if( verbose != 0 ) 00671 printf( "failed\n" ); 00672 00673 return( 1 ); 00674 } 00675 00676 if( verbose != 0 ) 00677 printf( "passed\n" ); 00678 } 00679 00680 if( verbose != 0 ) 00681 printf( "\n" ); 00682 00683 return( 0 ); 00684 } 00685 00686 #endif 00687 00688 #endif