Hannes Tschofenig / Mbed 2 deprecated aes-gcm-test-program

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers md5.c Source File

md5.c

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