1 /*
2  *  RFC 1321 compliant MD5 implementation
3  *
4  *  Copyright (C) 2006-2007  Christophe Devine
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Lesser General Public
8  *  License, version 2.1 as published by the Free Software Foundation.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public
16  *  License along with this library; if not, write to the Free Software
17  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18  *  MA  02110-1301  USA
19  */
20 /*
21  *  The MD5 algorithm was designed by Ron Rivest in 1991.
22  *  From the XYSSL project.
23  *
24  *  http://www.ietf.org/rfc/rfc1321.txt
25  */
26 #include "md5.h"
27 
28 #include <string.h>
29 #include <stdio.h>
30 
31 /*
32  * 32-bit integer manipulation macros (little endian)
33  */
34 #ifndef GET_ULONG_LE
35 #define GET_ULONG_LE(n,b,i)                             \
36 {                                                       \
37     (n) = ( (unsigned long) (b)[(i)    ]       )        \
38         | ( (unsigned long) (b)[(i) + 1] <<  8 )        \
39         | ( (unsigned long) (b)[(i) + 2] << 16 )        \
40         | ( (unsigned long) (b)[(i) + 3] << 24 );       \
41 }
42 #endif
43 
44 #ifndef PUT_ULONG_LE
45 #define PUT_ULONG_LE(n,b,i)                             \
46 {                                                       \
47     (b)[(i)    ] = (unsigned char) ( (n)       );       \
48     (b)[(i) + 1] = (unsigned char) ( (n) >>  8 );       \
49     (b)[(i) + 2] = (unsigned char) ( (n) >> 16 );       \
50     (b)[(i) + 3] = (unsigned char) ( (n) >> 24 );       \
51 }
52 #endif
53 
54 /*
55  * MD5 context setup
56  */
md5_starts(md5_context * ctx)57 void md5_starts(md5_context * ctx)
58 {
59 	ctx->total[0] = 0;
60 	ctx->total[1] = 0;
61 
62 	ctx->state[0] = 0x67452301;
63 	ctx->state[1] = 0xEFCDAB89;
64 	ctx->state[2] = 0x98BADCFE;
65 	ctx->state[3] = 0x10325476;
66 }
67 
md5_process(md5_context * ctx,unsigned char data[64])68 static void md5_process(md5_context * ctx, unsigned char data[64])
69 {
70 	unsigned long X[16], A, B, C, D;
71 
72 	GET_ULONG_LE(X[0], data, 0);
73 	GET_ULONG_LE(X[1], data, 4);
74 	GET_ULONG_LE(X[2], data, 8);
75 	GET_ULONG_LE(X[3], data, 12);
76 	GET_ULONG_LE(X[4], data, 16);
77 	GET_ULONG_LE(X[5], data, 20);
78 	GET_ULONG_LE(X[6], data, 24);
79 	GET_ULONG_LE(X[7], data, 28);
80 	GET_ULONG_LE(X[8], data, 32);
81 	GET_ULONG_LE(X[9], data, 36);
82 	GET_ULONG_LE(X[10], data, 40);
83 	GET_ULONG_LE(X[11], data, 44);
84 	GET_ULONG_LE(X[12], data, 48);
85 	GET_ULONG_LE(X[13], data, 52);
86 	GET_ULONG_LE(X[14], data, 56);
87 	GET_ULONG_LE(X[15], data, 60);
88 
89 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
90 
91 #define P(a,b,c,d,k,s,t)                                \
92 {                                                       \
93     a += F(b,c,d) + X[k] + t; a = S(a,s) + b;           \
94 }
95 
96 	A = ctx->state[0];
97 	B = ctx->state[1];
98 	C = ctx->state[2];
99 	D = ctx->state[3];
100 
101 #define F(x,y,z) (z ^ (x & (y ^ z)))
102 
103 	P(A, B, C, D, 0, 7, 0xD76AA478);
104 	P(D, A, B, C, 1, 12, 0xE8C7B756);
105 	P(C, D, A, B, 2, 17, 0x242070DB);
106 	P(B, C, D, A, 3, 22, 0xC1BDCEEE);
107 	P(A, B, C, D, 4, 7, 0xF57C0FAF);
108 	P(D, A, B, C, 5, 12, 0x4787C62A);
109 	P(C, D, A, B, 6, 17, 0xA8304613);
110 	P(B, C, D, A, 7, 22, 0xFD469501);
111 	P(A, B, C, D, 8, 7, 0x698098D8);
112 	P(D, A, B, C, 9, 12, 0x8B44F7AF);
113 	P(C, D, A, B, 10, 17, 0xFFFF5BB1);
114 	P(B, C, D, A, 11, 22, 0x895CD7BE);
115 	P(A, B, C, D, 12, 7, 0x6B901122);
116 	P(D, A, B, C, 13, 12, 0xFD987193);
117 	P(C, D, A, B, 14, 17, 0xA679438E);
118 	P(B, C, D, A, 15, 22, 0x49B40821);
119 
120 #undef F
121 
122 #define F(x,y,z) (y ^ (z & (x ^ y)))
123 
124 	P(A, B, C, D, 1, 5, 0xF61E2562);
125 	P(D, A, B, C, 6, 9, 0xC040B340);
126 	P(C, D, A, B, 11, 14, 0x265E5A51);
127 	P(B, C, D, A, 0, 20, 0xE9B6C7AA);
128 	P(A, B, C, D, 5, 5, 0xD62F105D);
129 	P(D, A, B, C, 10, 9, 0x02441453);
130 	P(C, D, A, B, 15, 14, 0xD8A1E681);
131 	P(B, C, D, A, 4, 20, 0xE7D3FBC8);
132 	P(A, B, C, D, 9, 5, 0x21E1CDE6);
133 	P(D, A, B, C, 14, 9, 0xC33707D6);
134 	P(C, D, A, B, 3, 14, 0xF4D50D87);
135 	P(B, C, D, A, 8, 20, 0x455A14ED);
136 	P(A, B, C, D, 13, 5, 0xA9E3E905);
137 	P(D, A, B, C, 2, 9, 0xFCEFA3F8);
138 	P(C, D, A, B, 7, 14, 0x676F02D9);
139 	P(B, C, D, A, 12, 20, 0x8D2A4C8A);
140 
141 #undef F
142 
143 #define F(x,y,z) (x ^ y ^ z)
144 
145 	P(A, B, C, D, 5, 4, 0xFFFA3942);
146 	P(D, A, B, C, 8, 11, 0x8771F681);
147 	P(C, D, A, B, 11, 16, 0x6D9D6122);
148 	P(B, C, D, A, 14, 23, 0xFDE5380C);
149 	P(A, B, C, D, 1, 4, 0xA4BEEA44);
150 	P(D, A, B, C, 4, 11, 0x4BDECFA9);
151 	P(C, D, A, B, 7, 16, 0xF6BB4B60);
152 	P(B, C, D, A, 10, 23, 0xBEBFBC70);
153 	P(A, B, C, D, 13, 4, 0x289B7EC6);
154 	P(D, A, B, C, 0, 11, 0xEAA127FA);
155 	P(C, D, A, B, 3, 16, 0xD4EF3085);
156 	P(B, C, D, A, 6, 23, 0x04881D05);
157 	P(A, B, C, D, 9, 4, 0xD9D4D039);
158 	P(D, A, B, C, 12, 11, 0xE6DB99E5);
159 	P(C, D, A, B, 15, 16, 0x1FA27CF8);
160 	P(B, C, D, A, 2, 23, 0xC4AC5665);
161 
162 #undef F
163 
164 #define F(x,y,z) (y ^ (x | ~z))
165 
166 	P(A, B, C, D, 0, 6, 0xF4292244);
167 	P(D, A, B, C, 7, 10, 0x432AFF97);
168 	P(C, D, A, B, 14, 15, 0xAB9423A7);
169 	P(B, C, D, A, 5, 21, 0xFC93A039);
170 	P(A, B, C, D, 12, 6, 0x655B59C3);
171 	P(D, A, B, C, 3, 10, 0x8F0CCC92);
172 	P(C, D, A, B, 10, 15, 0xFFEFF47D);
173 	P(B, C, D, A, 1, 21, 0x85845DD1);
174 	P(A, B, C, D, 8, 6, 0x6FA87E4F);
175 	P(D, A, B, C, 15, 10, 0xFE2CE6E0);
176 	P(C, D, A, B, 6, 15, 0xA3014314);
177 	P(B, C, D, A, 13, 21, 0x4E0811A1);
178 	P(A, B, C, D, 4, 6, 0xF7537E82);
179 	P(D, A, B, C, 11, 10, 0xBD3AF235);
180 	P(C, D, A, B, 2, 15, 0x2AD7D2BB);
181 	P(B, C, D, A, 9, 21, 0xEB86D391);
182 
183 #undef F
184 
185 	ctx->state[0] += A;
186 	ctx->state[1] += B;
187 	ctx->state[2] += C;
188 	ctx->state[3] += D;
189 }
190 
191 /*
192  * MD5 process buffer
193  */
md5_update(md5_context * ctx,unsigned char * input,int ilen)194 void md5_update(md5_context * ctx, unsigned char *input, int ilen)
195 {
196 	int fill;
197 	unsigned long left;
198 
199 	if (ilen <= 0)
200 		return;
201 
202 	left = ctx->total[0] & 0x3F;
203 	fill = 64 - left;
204 
205 	ctx->total[0] += ilen;
206 	ctx->total[0] &= 0xFFFFFFFF;
207 
208 	if (ctx->total[0] < (unsigned long) ilen)
209 		ctx->total[1]++;
210 
211 	if (left && ilen >= fill) {
212 		memcpy((void *) (ctx->buffer + left), (void *) input, fill);
213 		md5_process(ctx, ctx->buffer);
214 		input += fill;
215 		ilen -= fill;
216 		left = 0;
217 	}
218 
219 	while (ilen >= 64) {
220 		md5_process(ctx, input);
221 		input += 64;
222 		ilen -= 64;
223 	}
224 
225 	if (ilen > 0) {
226 		memcpy((void *) (ctx->buffer + left), (void *) input, ilen);
227 	}
228 }
229 
230 static const unsigned char md5_padding[64] = {
231 	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
232 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
233 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
234 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
235 };
236 
237 /*
238  * MD5 final digest
239  */
md5_finish(md5_context * ctx,unsigned char output[16])240 void md5_finish(md5_context * ctx, unsigned char output[16])
241 {
242 	unsigned long last, padn;
243 	unsigned long high, low;
244 	unsigned char msglen[8];
245 
246 	high = (ctx->total[0] >> 29)
247 		| (ctx->total[1] << 3);
248 	low = (ctx->total[0] << 3);
249 
250 	PUT_ULONG_LE(low, msglen, 0);
251 	PUT_ULONG_LE(high, msglen, 4);
252 
253 	last = ctx->total[0] & 0x3F;
254 	padn = (last < 56) ? (56 - last) : (120 - last);
255 
256 	md5_update(ctx, (unsigned char *) md5_padding, padn);
257 	md5_update(ctx, msglen, 8);
258 
259 	PUT_ULONG_LE(ctx->state[0], output, 0);
260 	PUT_ULONG_LE(ctx->state[1], output, 4);
261 	PUT_ULONG_LE(ctx->state[2], output, 8);
262 	PUT_ULONG_LE(ctx->state[3], output, 12);
263 }
264 
265 /*
266  * output = MD5( input buffer )
267  */
md5(unsigned char * input,int ilen,unsigned char output[16])268 void md5(unsigned char *input, int ilen, unsigned char output[16])
269 {
270 	md5_context ctx;
271 
272 	md5_starts(&ctx);
273 	md5_update(&ctx, input, ilen);
274 	md5_finish(&ctx, output);
275 
276 	memset(&ctx, 0, sizeof(md5_context));
277 }
278 
279 /*
280  * output = MD5( file contents )
281  */
md5_file(char * path,unsigned char output[16])282 int md5_file(char *path, unsigned char output[16])
283 {
284 	FILE *f;
285 	size_t n;
286 	md5_context ctx;
287 	unsigned char buf[1024];
288 
289 	if ((f = fopen(path, "rb")) == NULL)
290 		return (1);
291 
292 	md5_starts(&ctx);
293 
294 	while ((n = fread(buf, 1, sizeof(buf), f)) > 0)
295 		md5_update(&ctx, buf, (int) n);
296 
297 	md5_finish(&ctx, output);
298 
299 	memset(&ctx, 0, sizeof(md5_context));
300 
301 	if (ferror(f) != 0) {
302 		fclose(f);
303 		return (2);
304 	}
305 
306 	fclose(f);
307 	return (0);
308 }
309 
310 /*
311  * MD5 HMAC context setup
312  */
md5_hmac_starts(md5_context * ctx,unsigned char * key,int keylen)313 void md5_hmac_starts(md5_context * ctx, unsigned char *key, int keylen)
314 {
315 	int i;
316 	unsigned char sum[16];
317 
318 	if (keylen > 64) {
319 		md5(key, keylen, sum);
320 		keylen = 16;
321 		key = sum;
322 	}
323 
324 	memset(ctx->ipad, 0x36, 64);
325 	memset(ctx->opad, 0x5C, 64);
326 
327 	for (i = 0; i < keylen; i++) {
328 		ctx->ipad[i] = (unsigned char) (ctx->ipad[i] ^ key[i]);
329 		ctx->opad[i] = (unsigned char) (ctx->opad[i] ^ key[i]);
330 	}
331 
332 	md5_starts(ctx);
333 	md5_update(ctx, ctx->ipad, 64);
334 
335 	memset(sum, 0, sizeof(sum));
336 }
337 
338 /*
339  * MD5 HMAC process buffer
340  */
md5_hmac_update(md5_context * ctx,unsigned char * input,int ilen)341 void md5_hmac_update(md5_context * ctx, unsigned char *input, int ilen)
342 {
343 	md5_update(ctx, input, ilen);
344 }
345 
346 /*
347  * MD5 HMAC final digest
348  */
md5_hmac_finish(md5_context * ctx,unsigned char output[16])349 void md5_hmac_finish(md5_context * ctx, unsigned char output[16])
350 {
351 	unsigned char tmpbuf[16];
352 
353 	md5_finish(ctx, tmpbuf);
354 	md5_starts(ctx);
355 	md5_update(ctx, ctx->opad, 64);
356 	md5_update(ctx, tmpbuf, 16);
357 	md5_finish(ctx, output);
358 
359 	memset(tmpbuf, 0, sizeof(tmpbuf));
360 }
361 
362 /*
363  * output = HMAC-MD5( hmac key, input buffer )
364  */
md5_hmac(unsigned char * key,int keylen,unsigned char * input,int ilen,unsigned char output[16])365 void md5_hmac(unsigned char *key, int keylen, unsigned char *input,
366 			  int ilen, unsigned char output[16])
367 {
368 	md5_context ctx;
369 
370 	md5_hmac_starts(&ctx, key, keylen);
371 	md5_hmac_update(&ctx, input, ilen);
372 	md5_hmac_finish(&ctx, output);
373 
374 	memset(&ctx, 0, sizeof(md5_context));
375 }
376 
377 #if defined(XYSSL_SELF_TEST)
378 
379 /*
380  * RFC 1321 test vectors
381  */
382 static const char md5_test_str[7][81] = {
383 	{""},
384 	{"a"},
385 	{"abc"},
386 	{"message digest"},
387 	{"abcdefghijklmnopqrstuvwxyz"},
388 	{"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"},
389 	{"12345678901234567890123456789012345678901234567890123456789012"
390 	 "345678901234567890"}
391 };
392 
393 static const unsigned char md5_test_sum[7][16] = {
394 	{0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
395 	 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E},
396 	{0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
397 	 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61},
398 	{0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
399 	 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72},
400 	{0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
401 	 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0},
402 	{0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
403 	 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B},
404 	{0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
405 	 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F},
406 	{0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
407 	 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A}
408 };
409 
410 /*
411  * Checkup routine
412  */
md5_self_test(int verbose)413 int md5_self_test(int verbose)
414 {
415 	int i;
416 	unsigned char md5sum[16];
417 
418 	for (i = 0; i < 7; i++) {
419 		if (verbose != 0)
420 			printf("  MD5 test #%d: ", i + 1);
421 
422 		md5((unsigned char *) md5_test_str[i],
423 			strlen(md5_test_str[i]), md5sum);
424 
425 		if (memcmp(md5sum, md5_test_sum[i], 16) != 0) {
426 			if (verbose != 0)
427 				printf("failed\n");
428 
429 			return (1);
430 		}
431 
432 		if (verbose != 0)
433 			printf("passed\n");
434 	}
435 
436 	if (verbose != 0)
437 		printf("\n");
438 
439 	return (0);
440 }
441 
442 #endif
443