/home/dko/projects/mobilec/trunk/src/security/xyssl-0.7/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 library is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU Lesser General Public
00008  *  License, version 2.1 as published by the Free Software Foundation.
00009  *
00010  *  This library is distributed in the hope that it will be usefu),
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *  Lesser General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU Lesser General Public
00016  *  License along with this library; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00018  *  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 #ifndef _CRT_SECURE_NO_DEPRECATE
00027 #define _CRT_SECURE_NO_DEPRECATE 1
00028 #endif
00029 
00030 #include <string.h>
00031 #include <stdio.h>
00032 
00033 #include "xyssl/sha4.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) = ( (uint64) (b)[(i)    ] << 56 )               \
00042         | ( (uint64) (b)[(i) + 1] << 48 )               \
00043         | ( (uint64) (b)[(i) + 2] << 40 )               \
00044         | ( (uint64) (b)[(i) + 3] << 32 )               \
00045         | ( (uint64) (b)[(i) + 4] << 24 )               \
00046         | ( (uint64) (b)[(i) + 5] << 16 )               \
00047         | ( (uint64) (b)[(i) + 6] <<  8 )               \
00048         | ( (uint64) (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 uint64 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     uint64 temp1, temp2, W[80];
00153     uint64 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     uint64 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] < (uint64) 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 )
00277 {
00278         int last, padn;
00279     uint64 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, 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, 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,  int is384,
00360                        unsigned char *key, int keylen )
00361 {
00362     int i;
00363 
00364     memset( ctx->ipad, 0x36, 64 );
00365     memset( ctx->opad, 0x5C, 64 );
00366 
00367     for( i = 0; i < keylen; i++ )
00368     {
00369         if( i >= 64 ) break;
00370 
00371         ctx->ipad[i] ^= key[i];
00372         ctx->opad[i] ^= key[i];
00373     }
00374 
00375     sha4_starts( ctx, is384 );
00376     sha4_update( ctx, ctx->ipad, 64 );
00377 }
00378 
00379 /*
00380  * SHA-512 HMAC process buffer
00381  */
00382 void sha4_hmac_update( sha4_context *ctx,
00383                        unsigned char *input, int ilen )
00384 {
00385     sha4_update( ctx, input, ilen );
00386 }
00387 
00388 /*
00389  * SHA-512 HMAC final digest
00390  */
00391 void sha4_hmac_finish( sha4_context *ctx, unsigned char *output )
00392 {
00393     int is384, hlen;
00394     unsigned char tmpbuf[64];
00395 
00396     is384 = ctx->is384;
00397     hlen = ( is384 == 0 ) ? 64 : 48;
00398 
00399     sha4_finish( ctx, tmpbuf );
00400     sha4_starts( ctx, is384 );
00401     sha4_update( ctx, ctx->opad, 64 );
00402     sha4_update( ctx, tmpbuf, hlen );
00403     sha4_finish( ctx, output );
00404 
00405     memset( tmpbuf, 0, sizeof( tmpbuf ) );
00406 }
00407 
00408 /*
00409  * Output = HMAC-SHA-512( hmac key, input buffer )
00410  */
00411 void sha4_hmac( unsigned char *key,  int keylen,
00412                 unsigned char *input,  int ilen,
00413                 unsigned char *output, int is384 )
00414 {
00415     sha4_context ctx;
00416 
00417     sha4_hmac_starts( &ctx, is384, key, keylen );
00418     sha4_hmac_update( &ctx, input, ilen );
00419     sha4_hmac_finish( &ctx, output );
00420 
00421     memset( &ctx, 0, sizeof( sha4_context ) );
00422 }
00423 
00424 static const char _sha4_src[] = "_sha4_src";
00425 
00426 #if defined(SELF_TEST)
00427 /*
00428  * FIPS-180-2 test vectors
00429  */
00430 static const char sha4_test_str[3][112] = 
00431 {
00432     { "abc" },
00433     { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
00434       "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
00435     { "" }
00436 };
00437 
00438 static const unsigned char sha4_test_sum[6][64] =
00439 {
00440     /*
00441      * SHA-384 test vectors
00442      */
00443     { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
00444       0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
00445       0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
00446       0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
00447       0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
00448       0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
00449     { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
00450       0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
00451       0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
00452       0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
00453       0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
00454       0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
00455     { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
00456       0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
00457       0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
00458       0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
00459       0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
00460       0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
00461 
00462     /*
00463      * SHA-512 test vectors
00464      */
00465     { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
00466       0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
00467       0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
00468       0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
00469       0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
00470       0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
00471       0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
00472       0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
00473     { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
00474       0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
00475       0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
00476       0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
00477       0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
00478       0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
00479       0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
00480       0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
00481     { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
00482       0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
00483       0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
00484       0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
00485       0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
00486       0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
00487       0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
00488       0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
00489 };
00490 
00491 /*
00492  * Checkup routine
00493  */
00494 int sha4_self_test( int verbose )
00495 {
00496     int i, j, k;
00497     unsigned char buf[1000];
00498     unsigned char sha4sum[64];
00499     sha4_context ctx;
00500 
00501     memset( buf, 'a', 1000 );
00502 
00503     for( i = 0; i < 6; i++ )
00504     {
00505         j = i % 3;
00506         k = i < 3;
00507 
00508         if( verbose != 0 )
00509             printf( "  SHA-%d test #%d: ", 512 - k * 128, j + 1 );
00510 
00511         sha4_starts( &ctx, k );
00512 
00513         if( j < 2 )
00514             sha4_update( &ctx,
00515                          (unsigned char *) sha4_test_str[j],
00516                          strlen( sha4_test_str[j] ) );
00517         else
00518         {
00519             for( j = 0; j < 1000; j++ )
00520                 sha4_update( &ctx, buf, 1000 );
00521         }
00522 
00523         sha4_finish( &ctx, sha4sum );
00524 
00525         if( memcmp( sha4sum, sha4_test_sum[i], 64 - k * 16 ) != 0 )
00526         {
00527             if( verbose != 0 )
00528                 printf( "failed\n" );
00529 
00530             return( 1 );
00531         }
00532 
00533         if( verbose != 0 )
00534             printf( "passed\n" );
00535     }
00536 
00537     if( verbose != 0 )
00538         printf( "\n" );
00539 
00540     return( 0 );
00541 }
00542 #else
00543 int sha4_self_test( int verbose )
00544 {
00545     return( 0 );
00546 }
00547 #endif

Generated on Fri May 16 14:49:55 2008 for Mobile-C by  doxygen 1.5.4