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

Go to the documentation of this file.
00001 /*
00002  *  RFC 1321 compliant MD5 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 MD5 algorithm was designed by Ron Rivest in 1991.
00022  *
00023  *  http://www.ietf.org/rfc/rfc1321.txt
00024  */
00025 
00026 #include "xyssl/config.h"
00027 
00028 #if defined(XYSSL_MD5_C)
00029 
00030 #include "xyssl/md5.h"
00031 
00032 #include <string.h>
00033 #include <stdio.h>
00034 
00035 /*
00036  * 32-bit integer manipulation macros (little endian)
00037  */
00038 #ifndef GET_ULONG_LE
00039 #define GET_ULONG_LE(n,b,i)                             \
00040 {                                                       \
00041     (n) = ( (unsigned long) (b)[(i)    ]       )        \
00042         | ( (unsigned long) (b)[(i) + 1] <<  8 )        \
00043         | ( (unsigned long) (b)[(i) + 2] << 16 )        \
00044         | ( (unsigned long) (b)[(i) + 3] << 24 );       \
00045 }
00046 #endif
00047 
00048 #ifndef PUT_ULONG_LE
00049 #define PUT_ULONG_LE(n,b,i)                             \
00050 {                                                       \
00051     (b)[(i)    ] = (unsigned char) ( (n)       );       \
00052     (b)[(i) + 1] = (unsigned char) ( (n) >>  8 );       \
00053     (b)[(i) + 2] = (unsigned char) ( (n) >> 16 );       \
00054     (b)[(i) + 3] = (unsigned char) ( (n) >> 24 );       \
00055 }
00056 #endif
00057 
00058 /*
00059  * MD5 context setup
00060  */
00061 void md5_starts( md5_context *ctx )
00062 {
00063     ctx->total[0] = 0;
00064     ctx->total[1] = 0;
00065 
00066     ctx->state[0] = 0x67452301;
00067     ctx->state[1] = 0xEFCDAB89;
00068     ctx->state[2] = 0x98BADCFE;
00069     ctx->state[3] = 0x10325476;
00070 }
00071 
00072 static void md5_process( md5_context *ctx, unsigned char data[64] )
00073 {
00074     unsigned long X[16], A, B, C, D;
00075 
00076     GET_ULONG_LE( X[ 0], data,  0 );
00077     GET_ULONG_LE( X[ 1], data,  4 );
00078     GET_ULONG_LE( X[ 2], data,  8 );
00079     GET_ULONG_LE( X[ 3], data, 12 );
00080     GET_ULONG_LE( X[ 4], data, 16 );
00081     GET_ULONG_LE( X[ 5], data, 20 );
00082     GET_ULONG_LE( X[ 6], data, 24 );
00083     GET_ULONG_LE( X[ 7], data, 28 );
00084     GET_ULONG_LE( X[ 8], data, 32 );
00085     GET_ULONG_LE( X[ 9], data, 36 );
00086     GET_ULONG_LE( X[10], data, 40 );
00087     GET_ULONG_LE( X[11], data, 44 );
00088     GET_ULONG_LE( X[12], data, 48 );
00089     GET_ULONG_LE( X[13], data, 52 );
00090     GET_ULONG_LE( X[14], data, 56 );
00091     GET_ULONG_LE( X[15], data, 60 );
00092 
00093 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
00094 
00095 #define P(a,b,c,d,k,s,t)                                \
00096 {                                                       \
00097     a += F(b,c,d) + X[k] + t; a = S(a,s) + b;           \
00098 }
00099 
00100     A = ctx->state[0];
00101     B = ctx->state[1];
00102     C = ctx->state[2];
00103     D = ctx->state[3];
00104 
00105 #define F(x,y,z) (z ^ (x & (y ^ z)))
00106 
00107     P( A, B, C, D,  0,  7, 0xD76AA478 );
00108     P( D, A, B, C,  1, 12, 0xE8C7B756 );
00109     P( C, D, A, B,  2, 17, 0x242070DB );
00110     P( B, C, D, A,  3, 22, 0xC1BDCEEE );
00111     P( A, B, C, D,  4,  7, 0xF57C0FAF );
00112     P( D, A, B, C,  5, 12, 0x4787C62A );
00113     P( C, D, A, B,  6, 17, 0xA8304613 );
00114     P( B, C, D, A,  7, 22, 0xFD469501 );
00115     P( A, B, C, D,  8,  7, 0x698098D8 );
00116     P( D, A, B, C,  9, 12, 0x8B44F7AF );
00117     P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
00118     P( B, C, D, A, 11, 22, 0x895CD7BE );
00119     P( A, B, C, D, 12,  7, 0x6B901122 );
00120     P( D, A, B, C, 13, 12, 0xFD987193 );
00121     P( C, D, A, B, 14, 17, 0xA679438E );
00122     P( B, C, D, A, 15, 22, 0x49B40821 );
00123 
00124 #undef F
00125 
00126 #define F(x,y,z) (y ^ (z & (x ^ y)))
00127 
00128     P( A, B, C, D,  1,  5, 0xF61E2562 );
00129     P( D, A, B, C,  6,  9, 0xC040B340 );
00130     P( C, D, A, B, 11, 14, 0x265E5A51 );
00131     P( B, C, D, A,  0, 20, 0xE9B6C7AA );
00132     P( A, B, C, D,  5,  5, 0xD62F105D );
00133     P( D, A, B, C, 10,  9, 0x02441453 );
00134     P( C, D, A, B, 15, 14, 0xD8A1E681 );
00135     P( B, C, D, A,  4, 20, 0xE7D3FBC8 );
00136     P( A, B, C, D,  9,  5, 0x21E1CDE6 );
00137     P( D, A, B, C, 14,  9, 0xC33707D6 );
00138     P( C, D, A, B,  3, 14, 0xF4D50D87 );
00139     P( B, C, D, A,  8, 20, 0x455A14ED );
00140     P( A, B, C, D, 13,  5, 0xA9E3E905 );
00141     P( D, A, B, C,  2,  9, 0xFCEFA3F8 );
00142     P( C, D, A, B,  7, 14, 0x676F02D9 );
00143     P( B, C, D, A, 12, 20, 0x8D2A4C8A );
00144 
00145 #undef F
00146     
00147 #define F(x,y,z) (x ^ y ^ z)
00148 
00149     P( A, B, C, D,  5,  4, 0xFFFA3942 );
00150     P( D, A, B, C,  8, 11, 0x8771F681 );
00151     P( C, D, A, B, 11, 16, 0x6D9D6122 );
00152     P( B, C, D, A, 14, 23, 0xFDE5380C );
00153     P( A, B, C, D,  1,  4, 0xA4BEEA44 );
00154     P( D, A, B, C,  4, 11, 0x4BDECFA9 );
00155     P( C, D, A, B,  7, 16, 0xF6BB4B60 );
00156     P( B, C, D, A, 10, 23, 0xBEBFBC70 );
00157     P( A, B, C, D, 13,  4, 0x289B7EC6 );
00158     P( D, A, B, C,  0, 11, 0xEAA127FA );
00159     P( C, D, A, B,  3, 16, 0xD4EF3085 );
00160     P( B, C, D, A,  6, 23, 0x04881D05 );
00161     P( A, B, C, D,  9,  4, 0xD9D4D039 );
00162     P( D, A, B, C, 12, 11, 0xE6DB99E5 );
00163     P( C, D, A, B, 15, 16, 0x1FA27CF8 );
00164     P( B, C, D, A,  2, 23, 0xC4AC5665 );
00165 
00166 #undef F
00167 
00168 #define F(x,y,z) (y ^ (x | ~z))
00169 
00170     P( A, B, C, D,  0,  6, 0xF4292244 );
00171     P( D, A, B, C,  7, 10, 0x432AFF97 );
00172     P( C, D, A, B, 14, 15, 0xAB9423A7 );
00173     P( B, C, D, A,  5, 21, 0xFC93A039 );
00174     P( A, B, C, D, 12,  6, 0x655B59C3 );
00175     P( D, A, B, C,  3, 10, 0x8F0CCC92 );
00176     P( C, D, A, B, 10, 15, 0xFFEFF47D );
00177     P( B, C, D, A,  1, 21, 0x85845DD1 );
00178     P( A, B, C, D,  8,  6, 0x6FA87E4F );
00179     P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
00180     P( C, D, A, B,  6, 15, 0xA3014314 );
00181     P( B, C, D, A, 13, 21, 0x4E0811A1 );
00182     P( A, B, C, D,  4,  6, 0xF7537E82 );
00183     P( D, A, B, C, 11, 10, 0xBD3AF235 );
00184     P( C, D, A, B,  2, 15, 0x2AD7D2BB );
00185     P( B, C, D, A,  9, 21, 0xEB86D391 );
00186 
00187 #undef F
00188 
00189     ctx->state[0] += A;
00190     ctx->state[1] += B;
00191     ctx->state[2] += C;
00192     ctx->state[3] += D;
00193 }
00194 
00195 /*
00196  * MD5 process buffer
00197  */
00198 void md5_update( md5_context *ctx, unsigned char *input, int ilen )
00199 {
00200     int fill;
00201     unsigned long left;
00202 
00203     if( ilen <= 0 )
00204         return;
00205 
00206     left = ctx->total[0] & 0x3F;
00207     fill = 64 - left;
00208 
00209     ctx->total[0] += ilen;
00210     ctx->total[0] &= 0xFFFFFFFF;
00211 
00212     if( ctx->total[0] < (unsigned long) ilen )
00213         ctx->total[1]++;
00214 
00215     if( left && ilen >= fill )
00216     {
00217         memcpy( (void *) (ctx->buffer + left),
00218                 (void *) input, fill );
00219         md5_process( ctx, ctx->buffer );
00220         input += fill;
00221         ilen  -= fill;
00222         left = 0;
00223     }
00224 
00225     while( ilen >= 64 )
00226     {
00227         md5_process( ctx, input );
00228         input += 64;
00229         ilen  -= 64;
00230     }
00231 
00232     if( ilen > 0 )
00233     {
00234         memcpy( (void *) (ctx->buffer + left),
00235                 (void *) input, ilen );
00236     }
00237 }
00238 
00239 static const unsigned char md5_padding[64] =
00240 {
00241  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00242     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00243     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00244     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00245 };
00246 
00247 /*
00248  * MD5 final digest
00249  */
00250 void md5_finish( md5_context *ctx, unsigned char output[16] )
00251 {
00252     unsigned long last, padn;
00253     unsigned long high, low;
00254     unsigned char msglen[8];
00255 
00256     high = ( ctx->total[0] >> 29 )
00257          | ( ctx->total[1] <<  3 );
00258     low  = ( ctx->total[0] <<  3 );
00259 
00260     PUT_ULONG_LE( low,  msglen, 0 );
00261     PUT_ULONG_LE( high, msglen, 4 );
00262 
00263     last = ctx->total[0] & 0x3F;
00264     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
00265 
00266     md5_update( ctx, (unsigned char *) md5_padding, padn );
00267     md5_update( ctx, msglen, 8 );
00268 
00269     PUT_ULONG_LE( ctx->state[0], output,  0 );
00270     PUT_ULONG_LE( ctx->state[1], output,  4 );
00271     PUT_ULONG_LE( ctx->state[2], output,  8 );
00272     PUT_ULONG_LE( ctx->state[3], output, 12 );
00273 }
00274 
00275 /*
00276  * output = MD5( input buffer )
00277  */
00278 void md5( unsigned char *input, int ilen, unsigned char output[16] )
00279 {
00280     md5_context ctx;
00281 
00282     md5_starts( &ctx );
00283     md5_update( &ctx, input, ilen );
00284     md5_finish( &ctx, output );
00285 
00286     memset( &ctx, 0, sizeof( md5_context ) );
00287 }
00288 
00289 /*
00290  * output = MD5( file contents )
00291  */
00292 int md5_file( char *path, unsigned char output[16] )
00293 {
00294     FILE *f;
00295     size_t n;
00296     md5_context ctx;
00297     unsigned char buf[1024];
00298 
00299     if( ( f = fopen( path, "rb" ) ) == NULL )
00300         return( 1 );
00301 
00302     md5_starts( &ctx );
00303 
00304     while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
00305         md5_update( &ctx, buf, (int) n );
00306 
00307     md5_finish( &ctx, output );
00308 
00309     memset( &ctx, 0, sizeof( md5_context ) );
00310 
00311     if( ferror( f ) != 0 )
00312     {
00313         fclose( f );
00314         return( 2 );
00315     }
00316 
00317     fclose( f );
00318     return( 0 );
00319 }
00320 
00321 /*
00322  * MD5 HMAC context setup
00323  */
00324 void md5_hmac_starts( md5_context *ctx, unsigned char *key, int keylen )
00325 {
00326     int i;
00327     unsigned char sum[16];
00328 
00329     if( keylen > 64 )
00330     {
00331         md5( key, keylen, sum );
00332         keylen = 16;
00333         key = sum;
00334     }
00335 
00336     memset( ctx->ipad, 0x36, 64 );
00337     memset( ctx->opad, 0x5C, 64 );
00338 
00339     for( i = 0; i < keylen; i++ )
00340     {
00341         ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
00342         ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
00343     }
00344 
00345     md5_starts( ctx );
00346     md5_update( ctx, ctx->ipad, 64 );
00347 
00348     memset( sum, 0, sizeof( sum ) );
00349 }
00350 
00351 /*
00352  * MD5 HMAC process buffer
00353  */
00354 void md5_hmac_update( md5_context *ctx, unsigned char *input, int ilen )
00355 {
00356     md5_update( ctx, input, ilen );
00357 }
00358 
00359 /*
00360  * MD5 HMAC final digest
00361  */
00362 void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
00363 {
00364     unsigned char tmpbuf[16];
00365 
00366     md5_finish( ctx, tmpbuf );
00367     md5_starts( ctx );
00368     md5_update( ctx, ctx->opad, 64 );
00369     md5_update( ctx, tmpbuf, 16 );
00370     md5_finish( ctx, output );
00371 
00372     memset( tmpbuf, 0, sizeof( tmpbuf ) );
00373 }
00374 
00375 /*
00376  * output = HMAC-MD5( hmac key, input buffer )
00377  */
00378 void md5_hmac( unsigned char *key, int keylen, unsigned char *input, int ilen,
00379                unsigned char output[16] )
00380 {
00381     md5_context ctx;
00382 
00383     md5_hmac_starts( &ctx, key, keylen );
00384     md5_hmac_update( &ctx, input, ilen );
00385     md5_hmac_finish( &ctx, output );
00386 
00387     memset( &ctx, 0, sizeof( md5_context ) );
00388 }
00389 
00390 #if defined(XYSSL_SELF_TEST)
00391 /*
00392  * RFC 1321 test vectors
00393  */
00394 static unsigned char md5_test_buf[7][81] =
00395 {
00396     { "" }, 
00397     { "a" },
00398     { "abc" },
00399     { "message digest" },
00400     { "abcdefghijklmnopqrstuvwxyz" },
00401     { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
00402     { "12345678901234567890123456789012345678901234567890123456789012" \
00403       "345678901234567890" }
00404 };
00405 
00406 static const int md5_test_buflen[7] =
00407 {
00408     0, 1, 3, 14, 26, 62, 80
00409 };
00410 
00411 static const unsigned char md5_test_sum[7][16] =
00412 {
00413     { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
00414       0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
00415     { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
00416       0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
00417     { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
00418       0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
00419     { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
00420       0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
00421     { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
00422       0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
00423     { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
00424       0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
00425     { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
00426       0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
00427 };
00428 
00429 /*
00430  * RFC 2202 test vectors
00431  */
00432 static unsigned char md5_hmac_test_key[7][26] =
00433 {
00434     { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
00435     { "Jefe" },
00436     { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
00437     { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
00438       "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
00439     { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
00440     { "" }, /* 0xAA 80 times */
00441     { "" }
00442 };
00443 
00444 static const int md5_hmac_test_keylen[7] =
00445 {
00446     16, 4, 16, 25, 16, 80, 80
00447 };
00448 
00449 static unsigned char md5_hmac_test_buf[7][74] =
00450 {
00451     { "Hi There" },
00452     { "what do ya want for nothing?" },
00453     { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
00454       "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
00455       "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
00456       "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
00457       "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
00458     { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
00459       "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
00460       "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
00461       "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
00462       "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
00463     { "Test With Truncation" },
00464     { "Test Using Larger Than Block-Size Key - Hash Key First" },
00465     { "Test Using Larger Than Block-Size Key and Larger"
00466       " Than One Block-Size Data" }
00467 };
00468 
00469 static const int md5_hmac_test_buflen[7] =
00470 {
00471     8, 28, 50, 50, 20, 54, 73
00472 };
00473 
00474 static const unsigned char md5_hmac_test_sum[7][16] =
00475 {
00476     { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
00477       0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
00478     { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
00479       0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
00480     { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
00481       0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
00482     { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
00483       0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
00484     { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
00485       0xF9, 0xBA, 0xB9, 0x95 },
00486     { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
00487       0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
00488     { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
00489       0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
00490 };
00491 
00492 /*
00493  * Checkup routine
00494  */
00495 int md5_self_test( int verbose )
00496 {
00497     int i, buflen;
00498     unsigned char buf[1024];
00499     unsigned char md5sum[16];
00500     md5_context ctx;
00501 
00502     for( i = 0; i < 7; i++ )
00503     {
00504         if( verbose != 0 )
00505             printf( "  MD5 test #%d: ", i + 1 );
00506 
00507         md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
00508 
00509         if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
00510         {
00511             if( verbose != 0 )
00512                 printf( "failed\n" );
00513 
00514             return( 1 );
00515         }
00516 
00517         if( verbose != 0 )
00518             printf( "passed\n" );
00519     }
00520 
00521     if( verbose != 0 )
00522         printf( "\n" );
00523 
00524     for( i = 0; i < 7; i++ )
00525     {
00526         if( verbose != 0 )
00527             printf( "  HMAC-MD5 test #%d: ", i + 1 );
00528 
00529         if( i == 5 || i == 6 )
00530         {
00531             memset( buf, '\xAA', buflen = 80 );
00532             md5_hmac_starts( &ctx, buf, buflen );
00533         }
00534         else
00535             md5_hmac_starts( &ctx, md5_hmac_test_key[i],
00536                                    md5_hmac_test_keylen[i] );
00537 
00538         md5_hmac_update( &ctx, md5_hmac_test_buf[i],
00539                                md5_hmac_test_buflen[i] );
00540 
00541         md5_hmac_finish( &ctx, md5sum );
00542 
00543         buflen = ( i == 4 ) ? 12 : 16;
00544 
00545         if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
00546         {
00547             if( verbose != 0 )
00548                 printf( "failed\n" );
00549 
00550             return( 1 );
00551         }
00552 
00553         if( verbose != 0 )
00554             printf( "passed\n" );
00555     }
00556 
00557     if( verbose != 0 )
00558         printf( "\n" );
00559 
00560     return( 0 );
00561 }
00562 
00563 #endif
00564 
00565 #endif

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