/home/dko/projects/mobilec/tags/MobileC-v1.10.2/MobileC-v1.10.2/src/security/xyssl-0.9/library/sha2.c

Go to the documentation of this file.
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

Generated on Fri Jul 11 17:59:46 2008 for Mobile-C by  doxygen 1.5.4