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