Port of TI's CC3100 Websock camera demo. Using FreeRTOS, mbedTLS, also parts of Arducam for cams ov5642 and 0v2640. Can also use MT9D111. Work in progress. Be warned some parts maybe a bit flacky. This is for Seeed Arch max only, for an M3, see the demo for CM3 using the 0v5642 aducam mini.

Dependencies:   mbed

Committer:
dflet
Date:
Tue Sep 15 16:45:04 2015 +0000
Revision:
22:f9b5e0b80bf2
Parent:
0:50cedd586816
Removed some debug.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dflet 0:50cedd586816 1 /*
dflet 0:50cedd586816 2 * RFC 1321 compliant MD5 implementation
dflet 0:50cedd586816 3 *
dflet 0:50cedd586816 4 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
dflet 0:50cedd586816 5 *
dflet 0:50cedd586816 6 * This file is part of mbed TLS (https://tls.mbed.org)
dflet 0:50cedd586816 7 *
dflet 0:50cedd586816 8 * This program is free software; you can redistribute it and/or modify
dflet 0:50cedd586816 9 * it under the terms of the GNU General Public License as published by
dflet 0:50cedd586816 10 * the Free Software Foundation; either version 2 of the License, or
dflet 0:50cedd586816 11 * (at your option) any later version.
dflet 0:50cedd586816 12 *
dflet 0:50cedd586816 13 * This program is distributed in the hope that it will be useful,
dflet 0:50cedd586816 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
dflet 0:50cedd586816 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
dflet 0:50cedd586816 16 * GNU General Public License for more details.
dflet 0:50cedd586816 17 *
dflet 0:50cedd586816 18 * You should have received a copy of the GNU General Public License along
dflet 0:50cedd586816 19 * with this program; if not, write to the Free Software Foundation, Inc.,
dflet 0:50cedd586816 20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
dflet 0:50cedd586816 21 */
dflet 0:50cedd586816 22 /*
dflet 0:50cedd586816 23 * The MD5 algorithm was designed by Ron Rivest in 1991.
dflet 0:50cedd586816 24 *
dflet 0:50cedd586816 25 * http://www.ietf.org/rfc/rfc1321.txt
dflet 0:50cedd586816 26 */
dflet 0:50cedd586816 27
dflet 0:50cedd586816 28 #if !defined(POLARSSL_CONFIG_FILE)
dflet 0:50cedd586816 29 #include "polarssl/config.h"
dflet 0:50cedd586816 30 #else
dflet 0:50cedd586816 31 #include POLARSSL_CONFIG_FILE
dflet 0:50cedd586816 32 #endif
dflet 0:50cedd586816 33
dflet 0:50cedd586816 34 #if defined(POLARSSL_MD5_C)
dflet 0:50cedd586816 35
dflet 0:50cedd586816 36 #include "polarssl/md5.h"
dflet 0:50cedd586816 37
dflet 0:50cedd586816 38 #include <string.h>
dflet 0:50cedd586816 39
dflet 0:50cedd586816 40 #if defined(POLARSSL_FS_IO)
dflet 0:50cedd586816 41 #include <stdio.h>
dflet 0:50cedd586816 42 #endif
dflet 0:50cedd586816 43
dflet 0:50cedd586816 44 #if defined(POLARSSL_SELF_TEST)
dflet 0:50cedd586816 45 #if defined(POLARSSL_PLATFORM_C)
dflet 0:50cedd586816 46 #include "polarssl/platform.h"
dflet 0:50cedd586816 47 #else
dflet 0:50cedd586816 48 #include <stdio.h>
dflet 0:50cedd586816 49 #define polarssl_printf printf
dflet 0:50cedd586816 50 #endif /* POLARSSL_PLATFORM_C */
dflet 0:50cedd586816 51 #endif /* POLARSSL_SELF_TEST */
dflet 0:50cedd586816 52
dflet 0:50cedd586816 53 /* Implementation that should never be optimized out by the compiler */
dflet 0:50cedd586816 54 static void polarssl_zeroize( void *v, size_t n ) {
dflet 0:50cedd586816 55 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
dflet 0:50cedd586816 56 }
dflet 0:50cedd586816 57
dflet 0:50cedd586816 58 #if !defined(POLARSSL_MD5_ALT)
dflet 0:50cedd586816 59
dflet 0:50cedd586816 60 /*
dflet 0:50cedd586816 61 * 32-bit integer manipulation macros (little endian)
dflet 0:50cedd586816 62 */
dflet 0:50cedd586816 63 #ifndef GET_UINT32_LE
dflet 0:50cedd586816 64 #define GET_UINT32_LE(n,b,i) \
dflet 0:50cedd586816 65 { \
dflet 0:50cedd586816 66 (n) = ( (uint32_t) (b)[(i) ] ) \
dflet 0:50cedd586816 67 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
dflet 0:50cedd586816 68 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
dflet 0:50cedd586816 69 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
dflet 0:50cedd586816 70 }
dflet 0:50cedd586816 71 #endif
dflet 0:50cedd586816 72
dflet 0:50cedd586816 73 #ifndef PUT_UINT32_LE
dflet 0:50cedd586816 74 #define PUT_UINT32_LE(n,b,i) \
dflet 0:50cedd586816 75 { \
dflet 0:50cedd586816 76 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
dflet 0:50cedd586816 77 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
dflet 0:50cedd586816 78 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
dflet 0:50cedd586816 79 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
dflet 0:50cedd586816 80 }
dflet 0:50cedd586816 81 #endif
dflet 0:50cedd586816 82
dflet 0:50cedd586816 83 void md5_init( md5_context *ctx )
dflet 0:50cedd586816 84 {
dflet 0:50cedd586816 85 memset( ctx, 0, sizeof( md5_context ) );
dflet 0:50cedd586816 86 }
dflet 0:50cedd586816 87
dflet 0:50cedd586816 88 void md5_free( md5_context *ctx )
dflet 0:50cedd586816 89 {
dflet 0:50cedd586816 90 if( ctx == NULL )
dflet 0:50cedd586816 91 return;
dflet 0:50cedd586816 92
dflet 0:50cedd586816 93 polarssl_zeroize( ctx, sizeof( md5_context ) );
dflet 0:50cedd586816 94 }
dflet 0:50cedd586816 95
dflet 0:50cedd586816 96 /*
dflet 0:50cedd586816 97 * MD5 context setup
dflet 0:50cedd586816 98 */
dflet 0:50cedd586816 99 void md5_starts( md5_context *ctx )
dflet 0:50cedd586816 100 {
dflet 0:50cedd586816 101 ctx->total[0] = 0;
dflet 0:50cedd586816 102 ctx->total[1] = 0;
dflet 0:50cedd586816 103
dflet 0:50cedd586816 104 ctx->state[0] = 0x67452301;
dflet 0:50cedd586816 105 ctx->state[1] = 0xEFCDAB89;
dflet 0:50cedd586816 106 ctx->state[2] = 0x98BADCFE;
dflet 0:50cedd586816 107 ctx->state[3] = 0x10325476;
dflet 0:50cedd586816 108 }
dflet 0:50cedd586816 109
dflet 0:50cedd586816 110 void md5_process( md5_context *ctx, const unsigned char data[64] )
dflet 0:50cedd586816 111 {
dflet 0:50cedd586816 112 uint32_t X[16], A, B, C, D;
dflet 0:50cedd586816 113
dflet 0:50cedd586816 114 GET_UINT32_LE( X[ 0], data, 0 );
dflet 0:50cedd586816 115 GET_UINT32_LE( X[ 1], data, 4 );
dflet 0:50cedd586816 116 GET_UINT32_LE( X[ 2], data, 8 );
dflet 0:50cedd586816 117 GET_UINT32_LE( X[ 3], data, 12 );
dflet 0:50cedd586816 118 GET_UINT32_LE( X[ 4], data, 16 );
dflet 0:50cedd586816 119 GET_UINT32_LE( X[ 5], data, 20 );
dflet 0:50cedd586816 120 GET_UINT32_LE( X[ 6], data, 24 );
dflet 0:50cedd586816 121 GET_UINT32_LE( X[ 7], data, 28 );
dflet 0:50cedd586816 122 GET_UINT32_LE( X[ 8], data, 32 );
dflet 0:50cedd586816 123 GET_UINT32_LE( X[ 9], data, 36 );
dflet 0:50cedd586816 124 GET_UINT32_LE( X[10], data, 40 );
dflet 0:50cedd586816 125 GET_UINT32_LE( X[11], data, 44 );
dflet 0:50cedd586816 126 GET_UINT32_LE( X[12], data, 48 );
dflet 0:50cedd586816 127 GET_UINT32_LE( X[13], data, 52 );
dflet 0:50cedd586816 128 GET_UINT32_LE( X[14], data, 56 );
dflet 0:50cedd586816 129 GET_UINT32_LE( X[15], data, 60 );
dflet 0:50cedd586816 130
dflet 0:50cedd586816 131 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
dflet 0:50cedd586816 132
dflet 0:50cedd586816 133 #define P(a,b,c,d,k,s,t) \
dflet 0:50cedd586816 134 { \
dflet 0:50cedd586816 135 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
dflet 0:50cedd586816 136 }
dflet 0:50cedd586816 137
dflet 0:50cedd586816 138 A = ctx->state[0];
dflet 0:50cedd586816 139 B = ctx->state[1];
dflet 0:50cedd586816 140 C = ctx->state[2];
dflet 0:50cedd586816 141 D = ctx->state[3];
dflet 0:50cedd586816 142
dflet 0:50cedd586816 143 #define F(x,y,z) (z ^ (x & (y ^ z)))
dflet 0:50cedd586816 144
dflet 0:50cedd586816 145 P( A, B, C, D, 0, 7, 0xD76AA478 );
dflet 0:50cedd586816 146 P( D, A, B, C, 1, 12, 0xE8C7B756 );
dflet 0:50cedd586816 147 P( C, D, A, B, 2, 17, 0x242070DB );
dflet 0:50cedd586816 148 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
dflet 0:50cedd586816 149 P( A, B, C, D, 4, 7, 0xF57C0FAF );
dflet 0:50cedd586816 150 P( D, A, B, C, 5, 12, 0x4787C62A );
dflet 0:50cedd586816 151 P( C, D, A, B, 6, 17, 0xA8304613 );
dflet 0:50cedd586816 152 P( B, C, D, A, 7, 22, 0xFD469501 );
dflet 0:50cedd586816 153 P( A, B, C, D, 8, 7, 0x698098D8 );
dflet 0:50cedd586816 154 P( D, A, B, C, 9, 12, 0x8B44F7AF );
dflet 0:50cedd586816 155 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
dflet 0:50cedd586816 156 P( B, C, D, A, 11, 22, 0x895CD7BE );
dflet 0:50cedd586816 157 P( A, B, C, D, 12, 7, 0x6B901122 );
dflet 0:50cedd586816 158 P( D, A, B, C, 13, 12, 0xFD987193 );
dflet 0:50cedd586816 159 P( C, D, A, B, 14, 17, 0xA679438E );
dflet 0:50cedd586816 160 P( B, C, D, A, 15, 22, 0x49B40821 );
dflet 0:50cedd586816 161
dflet 0:50cedd586816 162 #undef F
dflet 0:50cedd586816 163
dflet 0:50cedd586816 164 #define F(x,y,z) (y ^ (z & (x ^ y)))
dflet 0:50cedd586816 165
dflet 0:50cedd586816 166 P( A, B, C, D, 1, 5, 0xF61E2562 );
dflet 0:50cedd586816 167 P( D, A, B, C, 6, 9, 0xC040B340 );
dflet 0:50cedd586816 168 P( C, D, A, B, 11, 14, 0x265E5A51 );
dflet 0:50cedd586816 169 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
dflet 0:50cedd586816 170 P( A, B, C, D, 5, 5, 0xD62F105D );
dflet 0:50cedd586816 171 P( D, A, B, C, 10, 9, 0x02441453 );
dflet 0:50cedd586816 172 P( C, D, A, B, 15, 14, 0xD8A1E681 );
dflet 0:50cedd586816 173 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
dflet 0:50cedd586816 174 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
dflet 0:50cedd586816 175 P( D, A, B, C, 14, 9, 0xC33707D6 );
dflet 0:50cedd586816 176 P( C, D, A, B, 3, 14, 0xF4D50D87 );
dflet 0:50cedd586816 177 P( B, C, D, A, 8, 20, 0x455A14ED );
dflet 0:50cedd586816 178 P( A, B, C, D, 13, 5, 0xA9E3E905 );
dflet 0:50cedd586816 179 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
dflet 0:50cedd586816 180 P( C, D, A, B, 7, 14, 0x676F02D9 );
dflet 0:50cedd586816 181 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
dflet 0:50cedd586816 182
dflet 0:50cedd586816 183 #undef F
dflet 0:50cedd586816 184
dflet 0:50cedd586816 185 #define F(x,y,z) (x ^ y ^ z)
dflet 0:50cedd586816 186
dflet 0:50cedd586816 187 P( A, B, C, D, 5, 4, 0xFFFA3942 );
dflet 0:50cedd586816 188 P( D, A, B, C, 8, 11, 0x8771F681 );
dflet 0:50cedd586816 189 P( C, D, A, B, 11, 16, 0x6D9D6122 );
dflet 0:50cedd586816 190 P( B, C, D, A, 14, 23, 0xFDE5380C );
dflet 0:50cedd586816 191 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
dflet 0:50cedd586816 192 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
dflet 0:50cedd586816 193 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
dflet 0:50cedd586816 194 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
dflet 0:50cedd586816 195 P( A, B, C, D, 13, 4, 0x289B7EC6 );
dflet 0:50cedd586816 196 P( D, A, B, C, 0, 11, 0xEAA127FA );
dflet 0:50cedd586816 197 P( C, D, A, B, 3, 16, 0xD4EF3085 );
dflet 0:50cedd586816 198 P( B, C, D, A, 6, 23, 0x04881D05 );
dflet 0:50cedd586816 199 P( A, B, C, D, 9, 4, 0xD9D4D039 );
dflet 0:50cedd586816 200 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
dflet 0:50cedd586816 201 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
dflet 0:50cedd586816 202 P( B, C, D, A, 2, 23, 0xC4AC5665 );
dflet 0:50cedd586816 203
dflet 0:50cedd586816 204 #undef F
dflet 0:50cedd586816 205
dflet 0:50cedd586816 206 #define F(x,y,z) (y ^ (x | ~z))
dflet 0:50cedd586816 207
dflet 0:50cedd586816 208 P( A, B, C, D, 0, 6, 0xF4292244 );
dflet 0:50cedd586816 209 P( D, A, B, C, 7, 10, 0x432AFF97 );
dflet 0:50cedd586816 210 P( C, D, A, B, 14, 15, 0xAB9423A7 );
dflet 0:50cedd586816 211 P( B, C, D, A, 5, 21, 0xFC93A039 );
dflet 0:50cedd586816 212 P( A, B, C, D, 12, 6, 0x655B59C3 );
dflet 0:50cedd586816 213 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
dflet 0:50cedd586816 214 P( C, D, A, B, 10, 15, 0xFFEFF47D );
dflet 0:50cedd586816 215 P( B, C, D, A, 1, 21, 0x85845DD1 );
dflet 0:50cedd586816 216 P( A, B, C, D, 8, 6, 0x6FA87E4F );
dflet 0:50cedd586816 217 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
dflet 0:50cedd586816 218 P( C, D, A, B, 6, 15, 0xA3014314 );
dflet 0:50cedd586816 219 P( B, C, D, A, 13, 21, 0x4E0811A1 );
dflet 0:50cedd586816 220 P( A, B, C, D, 4, 6, 0xF7537E82 );
dflet 0:50cedd586816 221 P( D, A, B, C, 11, 10, 0xBD3AF235 );
dflet 0:50cedd586816 222 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
dflet 0:50cedd586816 223 P( B, C, D, A, 9, 21, 0xEB86D391 );
dflet 0:50cedd586816 224
dflet 0:50cedd586816 225 #undef F
dflet 0:50cedd586816 226
dflet 0:50cedd586816 227 ctx->state[0] += A;
dflet 0:50cedd586816 228 ctx->state[1] += B;
dflet 0:50cedd586816 229 ctx->state[2] += C;
dflet 0:50cedd586816 230 ctx->state[3] += D;
dflet 0:50cedd586816 231 }
dflet 0:50cedd586816 232
dflet 0:50cedd586816 233 /*
dflet 0:50cedd586816 234 * MD5 process buffer
dflet 0:50cedd586816 235 */
dflet 0:50cedd586816 236 void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen )
dflet 0:50cedd586816 237 {
dflet 0:50cedd586816 238 size_t fill;
dflet 0:50cedd586816 239 uint32_t left;
dflet 0:50cedd586816 240
dflet 0:50cedd586816 241 if( ilen == 0 )
dflet 0:50cedd586816 242 return;
dflet 0:50cedd586816 243
dflet 0:50cedd586816 244 left = ctx->total[0] & 0x3F;
dflet 0:50cedd586816 245 fill = 64 - left;
dflet 0:50cedd586816 246
dflet 0:50cedd586816 247 ctx->total[0] += (uint32_t) ilen;
dflet 0:50cedd586816 248 ctx->total[0] &= 0xFFFFFFFF;
dflet 0:50cedd586816 249
dflet 0:50cedd586816 250 if( ctx->total[0] < (uint32_t) ilen )
dflet 0:50cedd586816 251 ctx->total[1]++;
dflet 0:50cedd586816 252
dflet 0:50cedd586816 253 if( left && ilen >= fill )
dflet 0:50cedd586816 254 {
dflet 0:50cedd586816 255 memcpy( (void *) (ctx->buffer + left), input, fill );
dflet 0:50cedd586816 256 md5_process( ctx, ctx->buffer );
dflet 0:50cedd586816 257 input += fill;
dflet 0:50cedd586816 258 ilen -= fill;
dflet 0:50cedd586816 259 left = 0;
dflet 0:50cedd586816 260 }
dflet 0:50cedd586816 261
dflet 0:50cedd586816 262 while( ilen >= 64 )
dflet 0:50cedd586816 263 {
dflet 0:50cedd586816 264 md5_process( ctx, input );
dflet 0:50cedd586816 265 input += 64;
dflet 0:50cedd586816 266 ilen -= 64;
dflet 0:50cedd586816 267 }
dflet 0:50cedd586816 268
dflet 0:50cedd586816 269 if( ilen > 0 )
dflet 0:50cedd586816 270 {
dflet 0:50cedd586816 271 memcpy( (void *) (ctx->buffer + left), input, ilen );
dflet 0:50cedd586816 272 }
dflet 0:50cedd586816 273 }
dflet 0:50cedd586816 274
dflet 0:50cedd586816 275 static const unsigned char md5_padding[64] =
dflet 0:50cedd586816 276 {
dflet 0:50cedd586816 277 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
dflet 0:50cedd586816 278 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
dflet 0:50cedd586816 279 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
dflet 0:50cedd586816 280 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
dflet 0:50cedd586816 281 };
dflet 0:50cedd586816 282
dflet 0:50cedd586816 283 /*
dflet 0:50cedd586816 284 * MD5 final digest
dflet 0:50cedd586816 285 */
dflet 0:50cedd586816 286 void md5_finish( md5_context *ctx, unsigned char output[16] )
dflet 0:50cedd586816 287 {
dflet 0:50cedd586816 288 uint32_t last, padn;
dflet 0:50cedd586816 289 uint32_t high, low;
dflet 0:50cedd586816 290 unsigned char msglen[8];
dflet 0:50cedd586816 291
dflet 0:50cedd586816 292 high = ( ctx->total[0] >> 29 )
dflet 0:50cedd586816 293 | ( ctx->total[1] << 3 );
dflet 0:50cedd586816 294 low = ( ctx->total[0] << 3 );
dflet 0:50cedd586816 295
dflet 0:50cedd586816 296 PUT_UINT32_LE( low, msglen, 0 );
dflet 0:50cedd586816 297 PUT_UINT32_LE( high, msglen, 4 );
dflet 0:50cedd586816 298
dflet 0:50cedd586816 299 last = ctx->total[0] & 0x3F;
dflet 0:50cedd586816 300 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
dflet 0:50cedd586816 301
dflet 0:50cedd586816 302 md5_update( ctx, md5_padding, padn );
dflet 0:50cedd586816 303 md5_update( ctx, msglen, 8 );
dflet 0:50cedd586816 304
dflet 0:50cedd586816 305 PUT_UINT32_LE( ctx->state[0], output, 0 );
dflet 0:50cedd586816 306 PUT_UINT32_LE( ctx->state[1], output, 4 );
dflet 0:50cedd586816 307 PUT_UINT32_LE( ctx->state[2], output, 8 );
dflet 0:50cedd586816 308 PUT_UINT32_LE( ctx->state[3], output, 12 );
dflet 0:50cedd586816 309 }
dflet 0:50cedd586816 310
dflet 0:50cedd586816 311 #endif /* !POLARSSL_MD5_ALT */
dflet 0:50cedd586816 312
dflet 0:50cedd586816 313 /*
dflet 0:50cedd586816 314 * output = MD5( input buffer )
dflet 0:50cedd586816 315 */
dflet 0:50cedd586816 316 void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
dflet 0:50cedd586816 317 {
dflet 0:50cedd586816 318 md5_context ctx;
dflet 0:50cedd586816 319
dflet 0:50cedd586816 320 md5_init( &ctx );
dflet 0:50cedd586816 321 md5_starts( &ctx );
dflet 0:50cedd586816 322 md5_update( &ctx, input, ilen );
dflet 0:50cedd586816 323 md5_finish( &ctx, output );
dflet 0:50cedd586816 324 md5_free( &ctx );
dflet 0:50cedd586816 325 }
dflet 0:50cedd586816 326
dflet 0:50cedd586816 327 #if defined(POLARSSL_FS_IO)
dflet 0:50cedd586816 328 /*
dflet 0:50cedd586816 329 * output = MD5( file contents )
dflet 0:50cedd586816 330 */
dflet 0:50cedd586816 331 int md5_file( const char *path, unsigned char output[16] )
dflet 0:50cedd586816 332 {
dflet 0:50cedd586816 333 FILE *f;
dflet 0:50cedd586816 334 size_t n;
dflet 0:50cedd586816 335 md5_context ctx;
dflet 0:50cedd586816 336 unsigned char buf[1024];
dflet 0:50cedd586816 337
dflet 0:50cedd586816 338 if( ( f = fopen( path, "rb" ) ) == NULL )
dflet 0:50cedd586816 339 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
dflet 0:50cedd586816 340
dflet 0:50cedd586816 341 md5_init( &ctx );
dflet 0:50cedd586816 342 md5_starts( &ctx );
dflet 0:50cedd586816 343
dflet 0:50cedd586816 344 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
dflet 0:50cedd586816 345 md5_update( &ctx, buf, n );
dflet 0:50cedd586816 346
dflet 0:50cedd586816 347 md5_finish( &ctx, output );
dflet 0:50cedd586816 348 md5_free( &ctx );
dflet 0:50cedd586816 349
dflet 0:50cedd586816 350 if( ferror( f ) != 0 )
dflet 0:50cedd586816 351 {
dflet 0:50cedd586816 352 fclose( f );
dflet 0:50cedd586816 353 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
dflet 0:50cedd586816 354 }
dflet 0:50cedd586816 355
dflet 0:50cedd586816 356 fclose( f );
dflet 0:50cedd586816 357 return( 0 );
dflet 0:50cedd586816 358 }
dflet 0:50cedd586816 359 #endif /* POLARSSL_FS_IO */
dflet 0:50cedd586816 360
dflet 0:50cedd586816 361 /*
dflet 0:50cedd586816 362 * MD5 HMAC context setup
dflet 0:50cedd586816 363 */
dflet 0:50cedd586816 364 void md5_hmac_starts( md5_context *ctx, const unsigned char *key,
dflet 0:50cedd586816 365 size_t keylen )
dflet 0:50cedd586816 366 {
dflet 0:50cedd586816 367 size_t i;
dflet 0:50cedd586816 368 unsigned char sum[16];
dflet 0:50cedd586816 369
dflet 0:50cedd586816 370 if( keylen > 64 )
dflet 0:50cedd586816 371 {
dflet 0:50cedd586816 372 md5( key, keylen, sum );
dflet 0:50cedd586816 373 keylen = 16;
dflet 0:50cedd586816 374 key = sum;
dflet 0:50cedd586816 375 }
dflet 0:50cedd586816 376
dflet 0:50cedd586816 377 memset( ctx->ipad, 0x36, 64 );
dflet 0:50cedd586816 378 memset( ctx->opad, 0x5C, 64 );
dflet 0:50cedd586816 379
dflet 0:50cedd586816 380 for( i = 0; i < keylen; i++ )
dflet 0:50cedd586816 381 {
dflet 0:50cedd586816 382 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
dflet 0:50cedd586816 383 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
dflet 0:50cedd586816 384 }
dflet 0:50cedd586816 385
dflet 0:50cedd586816 386 md5_starts( ctx );
dflet 0:50cedd586816 387 md5_update( ctx, ctx->ipad, 64 );
dflet 0:50cedd586816 388
dflet 0:50cedd586816 389 polarssl_zeroize( sum, sizeof( sum ) );
dflet 0:50cedd586816 390 }
dflet 0:50cedd586816 391
dflet 0:50cedd586816 392 /*
dflet 0:50cedd586816 393 * MD5 HMAC process buffer
dflet 0:50cedd586816 394 */
dflet 0:50cedd586816 395 void md5_hmac_update( md5_context *ctx, const unsigned char *input,
dflet 0:50cedd586816 396 size_t ilen )
dflet 0:50cedd586816 397 {
dflet 0:50cedd586816 398 md5_update( ctx, input, ilen );
dflet 0:50cedd586816 399 }
dflet 0:50cedd586816 400
dflet 0:50cedd586816 401 /*
dflet 0:50cedd586816 402 * MD5 HMAC final digest
dflet 0:50cedd586816 403 */
dflet 0:50cedd586816 404 void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
dflet 0:50cedd586816 405 {
dflet 0:50cedd586816 406 unsigned char tmpbuf[16];
dflet 0:50cedd586816 407
dflet 0:50cedd586816 408 md5_finish( ctx, tmpbuf );
dflet 0:50cedd586816 409 md5_starts( ctx );
dflet 0:50cedd586816 410 md5_update( ctx, ctx->opad, 64 );
dflet 0:50cedd586816 411 md5_update( ctx, tmpbuf, 16 );
dflet 0:50cedd586816 412 md5_finish( ctx, output );
dflet 0:50cedd586816 413
dflet 0:50cedd586816 414 polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
dflet 0:50cedd586816 415 }
dflet 0:50cedd586816 416
dflet 0:50cedd586816 417 /*
dflet 0:50cedd586816 418 * MD5 HMAC context reset
dflet 0:50cedd586816 419 */
dflet 0:50cedd586816 420 void md5_hmac_reset( md5_context *ctx )
dflet 0:50cedd586816 421 {
dflet 0:50cedd586816 422 md5_starts( ctx );
dflet 0:50cedd586816 423 md5_update( ctx, ctx->ipad, 64 );
dflet 0:50cedd586816 424 }
dflet 0:50cedd586816 425
dflet 0:50cedd586816 426 /*
dflet 0:50cedd586816 427 * output = HMAC-MD5( hmac key, input buffer )
dflet 0:50cedd586816 428 */
dflet 0:50cedd586816 429 void md5_hmac( const unsigned char *key, size_t keylen,
dflet 0:50cedd586816 430 const unsigned char *input, size_t ilen,
dflet 0:50cedd586816 431 unsigned char output[16] )
dflet 0:50cedd586816 432 {
dflet 0:50cedd586816 433 md5_context ctx;
dflet 0:50cedd586816 434
dflet 0:50cedd586816 435 md5_init( &ctx );
dflet 0:50cedd586816 436 md5_hmac_starts( &ctx, key, keylen );
dflet 0:50cedd586816 437 md5_hmac_update( &ctx, input, ilen );
dflet 0:50cedd586816 438 md5_hmac_finish( &ctx, output );
dflet 0:50cedd586816 439 md5_free( &ctx );
dflet 0:50cedd586816 440 }
dflet 0:50cedd586816 441
dflet 0:50cedd586816 442 #if defined(POLARSSL_SELF_TEST)
dflet 0:50cedd586816 443 /*
dflet 0:50cedd586816 444 * RFC 1321 test vectors
dflet 0:50cedd586816 445 */
dflet 0:50cedd586816 446 static const unsigned char md5_test_buf[7][81] =
dflet 0:50cedd586816 447 {
dflet 0:50cedd586816 448 { "" },
dflet 0:50cedd586816 449 { "a" },
dflet 0:50cedd586816 450 { "abc" },
dflet 0:50cedd586816 451 { "message digest" },
dflet 0:50cedd586816 452 { "abcdefghijklmnopqrstuvwxyz" },
dflet 0:50cedd586816 453 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
dflet 0:50cedd586816 454 { "12345678901234567890123456789012345678901234567890123456789012" \
dflet 0:50cedd586816 455 "345678901234567890" }
dflet 0:50cedd586816 456 };
dflet 0:50cedd586816 457
dflet 0:50cedd586816 458 static const int md5_test_buflen[7] =
dflet 0:50cedd586816 459 {
dflet 0:50cedd586816 460 0, 1, 3, 14, 26, 62, 80
dflet 0:50cedd586816 461 };
dflet 0:50cedd586816 462
dflet 0:50cedd586816 463 static const unsigned char md5_test_sum[7][16] =
dflet 0:50cedd586816 464 {
dflet 0:50cedd586816 465 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
dflet 0:50cedd586816 466 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
dflet 0:50cedd586816 467 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
dflet 0:50cedd586816 468 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
dflet 0:50cedd586816 469 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
dflet 0:50cedd586816 470 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
dflet 0:50cedd586816 471 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
dflet 0:50cedd586816 472 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
dflet 0:50cedd586816 473 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
dflet 0:50cedd586816 474 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
dflet 0:50cedd586816 475 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
dflet 0:50cedd586816 476 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
dflet 0:50cedd586816 477 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
dflet 0:50cedd586816 478 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
dflet 0:50cedd586816 479 };
dflet 0:50cedd586816 480
dflet 0:50cedd586816 481 /*
dflet 0:50cedd586816 482 * RFC 2202 test vectors
dflet 0:50cedd586816 483 */
dflet 0:50cedd586816 484 static const unsigned char md5_hmac_test_key[7][26] =
dflet 0:50cedd586816 485 {
dflet 0:50cedd586816 486 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
dflet 0:50cedd586816 487 { "Jefe" },
dflet 0:50cedd586816 488 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
dflet 0:50cedd586816 489 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
dflet 0:50cedd586816 490 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
dflet 0:50cedd586816 491 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
dflet 0:50cedd586816 492 { "" }, /* 0xAA 80 times */
dflet 0:50cedd586816 493 { "" }
dflet 0:50cedd586816 494 };
dflet 0:50cedd586816 495
dflet 0:50cedd586816 496 static const int md5_hmac_test_keylen[7] =
dflet 0:50cedd586816 497 {
dflet 0:50cedd586816 498 16, 4, 16, 25, 16, 80, 80
dflet 0:50cedd586816 499 };
dflet 0:50cedd586816 500
dflet 0:50cedd586816 501 static const unsigned char md5_hmac_test_buf[7][74] =
dflet 0:50cedd586816 502 {
dflet 0:50cedd586816 503 { "Hi There" },
dflet 0:50cedd586816 504 { "what do ya want for nothing?" },
dflet 0:50cedd586816 505 { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
dflet 0:50cedd586816 506 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
dflet 0:50cedd586816 507 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
dflet 0:50cedd586816 508 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
dflet 0:50cedd586816 509 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
dflet 0:50cedd586816 510 { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
dflet 0:50cedd586816 511 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
dflet 0:50cedd586816 512 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
dflet 0:50cedd586816 513 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
dflet 0:50cedd586816 514 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
dflet 0:50cedd586816 515 { "Test With Truncation" },
dflet 0:50cedd586816 516 { "Test Using Larger Than Block-Size Key - Hash Key First" },
dflet 0:50cedd586816 517 { "Test Using Larger Than Block-Size Key and Larger"
dflet 0:50cedd586816 518 " Than One Block-Size Data" }
dflet 0:50cedd586816 519 };
dflet 0:50cedd586816 520
dflet 0:50cedd586816 521 static const int md5_hmac_test_buflen[7] =
dflet 0:50cedd586816 522 {
dflet 0:50cedd586816 523 8, 28, 50, 50, 20, 54, 73
dflet 0:50cedd586816 524 };
dflet 0:50cedd586816 525
dflet 0:50cedd586816 526 static const unsigned char md5_hmac_test_sum[7][16] =
dflet 0:50cedd586816 527 {
dflet 0:50cedd586816 528 { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
dflet 0:50cedd586816 529 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
dflet 0:50cedd586816 530 { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
dflet 0:50cedd586816 531 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
dflet 0:50cedd586816 532 { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
dflet 0:50cedd586816 533 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
dflet 0:50cedd586816 534 { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
dflet 0:50cedd586816 535 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
dflet 0:50cedd586816 536 { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
dflet 0:50cedd586816 537 0xF9, 0xBA, 0xB9, 0x95 },
dflet 0:50cedd586816 538 { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
dflet 0:50cedd586816 539 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
dflet 0:50cedd586816 540 { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
dflet 0:50cedd586816 541 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
dflet 0:50cedd586816 542 };
dflet 0:50cedd586816 543
dflet 0:50cedd586816 544 /*
dflet 0:50cedd586816 545 * Checkup routine
dflet 0:50cedd586816 546 */
dflet 0:50cedd586816 547 int md5_self_test( int verbose )
dflet 0:50cedd586816 548 {
dflet 0:50cedd586816 549 int i, buflen;
dflet 0:50cedd586816 550 unsigned char buf[1024];
dflet 0:50cedd586816 551 unsigned char md5sum[16];
dflet 0:50cedd586816 552 md5_context ctx;
dflet 0:50cedd586816 553
dflet 0:50cedd586816 554 for( i = 0; i < 7; i++ )
dflet 0:50cedd586816 555 {
dflet 0:50cedd586816 556 if( verbose != 0 )
dflet 0:50cedd586816 557 polarssl_printf( " MD5 test #%d: ", i + 1 );
dflet 0:50cedd586816 558
dflet 0:50cedd586816 559 md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
dflet 0:50cedd586816 560
dflet 0:50cedd586816 561 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
dflet 0:50cedd586816 562 {
dflet 0:50cedd586816 563 if( verbose != 0 )
dflet 0:50cedd586816 564 polarssl_printf( "failed\n" );
dflet 0:50cedd586816 565
dflet 0:50cedd586816 566 return( 1 );
dflet 0:50cedd586816 567 }
dflet 0:50cedd586816 568
dflet 0:50cedd586816 569 if( verbose != 0 )
dflet 0:50cedd586816 570 polarssl_printf( "passed\n" );
dflet 0:50cedd586816 571 }
dflet 0:50cedd586816 572
dflet 0:50cedd586816 573 if( verbose != 0 )
dflet 0:50cedd586816 574 polarssl_printf( "\n" );
dflet 0:50cedd586816 575
dflet 0:50cedd586816 576 for( i = 0; i < 7; i++ )
dflet 0:50cedd586816 577 {
dflet 0:50cedd586816 578 if( verbose != 0 )
dflet 0:50cedd586816 579 polarssl_printf( " HMAC-MD5 test #%d: ", i + 1 );
dflet 0:50cedd586816 580
dflet 0:50cedd586816 581 if( i == 5 || i == 6 )
dflet 0:50cedd586816 582 {
dflet 0:50cedd586816 583 memset( buf, 0xAA, buflen = 80 );
dflet 0:50cedd586816 584 md5_hmac_starts( &ctx, buf, buflen );
dflet 0:50cedd586816 585 }
dflet 0:50cedd586816 586 else
dflet 0:50cedd586816 587 md5_hmac_starts( &ctx, md5_hmac_test_key[i],
dflet 0:50cedd586816 588 md5_hmac_test_keylen[i] );
dflet 0:50cedd586816 589
dflet 0:50cedd586816 590 md5_hmac_update( &ctx, md5_hmac_test_buf[i],
dflet 0:50cedd586816 591 md5_hmac_test_buflen[i] );
dflet 0:50cedd586816 592
dflet 0:50cedd586816 593 md5_hmac_finish( &ctx, md5sum );
dflet 0:50cedd586816 594
dflet 0:50cedd586816 595 buflen = ( i == 4 ) ? 12 : 16;
dflet 0:50cedd586816 596
dflet 0:50cedd586816 597 if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
dflet 0:50cedd586816 598 {
dflet 0:50cedd586816 599 if( verbose != 0 )
dflet 0:50cedd586816 600 polarssl_printf( "failed\n" );
dflet 0:50cedd586816 601
dflet 0:50cedd586816 602 return( 1 );
dflet 0:50cedd586816 603 }
dflet 0:50cedd586816 604
dflet 0:50cedd586816 605 if( verbose != 0 )
dflet 0:50cedd586816 606 polarssl_printf( "passed\n" );
dflet 0:50cedd586816 607 }
dflet 0:50cedd586816 608
dflet 0:50cedd586816 609 if( verbose != 0 )
dflet 0:50cedd586816 610 polarssl_printf( "\n" );
dflet 0:50cedd586816 611
dflet 0:50cedd586816 612 return( 0 );
dflet 0:50cedd586816 613 }
dflet 0:50cedd586816 614
dflet 0:50cedd586816 615 #endif /* POLARSSL_SELF_TEST */
dflet 0:50cedd586816 616
dflet 0:50cedd586816 617 #endif /* POLARSSL_MD5_C */
dflet 0:50cedd586816 618