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