TI's CC3100 websocket camera demo with Arducam mini ov5642 and freertos. Should work with other M3's. Work in progress test demo.

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