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

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

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