2 * RFC 1321 compliant MD5 implementation
4 * Copyright (C) 2006-2007 Christophe Devine
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.
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.
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,
21 * The MD5 algorithm was designed by Ron Rivest in 1991.
22 * From the XYSSL project.
24 * http://www.ietf.org/rfc/rfc1321.txt
32 * 32-bit integer manipulation macros (little endian)
35 #define GET_ULONG_LE(n,b,i) \
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 ); \
45 #define PUT_ULONG_LE(n,b,i) \
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 ); \
57 void md5_starts(md5_context
* ctx
)
62 ctx
->state
[0] = 0x67452301;
63 ctx
->state
[1] = 0xEFCDAB89;
64 ctx
->state
[2] = 0x98BADCFE;
65 ctx
->state
[3] = 0x10325476;
68 static void md5_process(md5_context
* ctx
, unsigned char data
[64])
70 unsigned long X
[16], A
, B
, C
, D
;
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);
89 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
91 #define P(a,b,c,d,k,s,t) \
93 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
101 #define F(x,y,z) (z ^ (x & (y ^ z)))
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);
122 #define F(x,y,z) (y ^ (z & (x ^ y)))
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);
143 #define F(x,y,z) (x ^ y ^ z)
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);
164 #define F(x,y,z) (y ^ (x | ~z))
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);
194 void md5_update(md5_context
* ctx
, unsigned char *input
, int ilen
)
202 left
= ctx
->total
[0] & 0x3F;
205 ctx
->total
[0] += ilen
;
206 ctx
->total
[0] &= 0xFFFFFFFF;
208 if (ctx
->total
[0] < (unsigned long) ilen
)
211 if (left
&& ilen
>= fill
) {
212 memcpy((void *) (ctx
->buffer
+ left
), (void *) input
, fill
);
213 md5_process(ctx
, ctx
->buffer
);
220 md5_process(ctx
, input
);
226 memcpy((void *) (ctx
->buffer
+ left
), (void *) input
, ilen
);
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
240 void md5_finish(md5_context
* ctx
, unsigned char output
[16])
242 unsigned long last
, padn
;
243 unsigned long high
, low
;
244 unsigned char msglen
[8];
246 high
= (ctx
->total
[0] >> 29)
247 | (ctx
->total
[1] << 3);
248 low
= (ctx
->total
[0] << 3);
250 PUT_ULONG_LE(low
, msglen
, 0);
251 PUT_ULONG_LE(high
, msglen
, 4);
253 last
= ctx
->total
[0] & 0x3F;
254 padn
= (last
< 56) ? (56 - last
) : (120 - last
);
256 md5_update(ctx
, (unsigned char *) md5_padding
, padn
);
257 md5_update(ctx
, msglen
, 8);
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);
266 * output = MD5( input buffer )
268 void md5(unsigned char *input
, int ilen
, unsigned char output
[16])
273 md5_update(&ctx
, input
, ilen
);
274 md5_finish(&ctx
, output
);
276 memset(&ctx
, 0, sizeof(md5_context
));
280 * output = MD5( file contents )
282 int md5_file(char *path
, unsigned char output
[16])
287 unsigned char buf
[1024];
289 if ((f
= fopen(path
, "rb")) == NULL
)
294 while ((n
= fread(buf
, 1, sizeof(buf
), f
)) > 0)
295 md5_update(&ctx
, buf
, (int) n
);
297 md5_finish(&ctx
, output
);
299 memset(&ctx
, 0, sizeof(md5_context
));
301 if (ferror(f
) != 0) {
311 * MD5 HMAC context setup
313 void md5_hmac_starts(md5_context
* ctx
, unsigned char *key
, int keylen
)
316 unsigned char sum
[16];
319 md5(key
, keylen
, sum
);
324 memset(ctx
->ipad
, 0x36, 64);
325 memset(ctx
->opad
, 0x5C, 64);
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
]);
333 md5_update(ctx
, ctx
->ipad
, 64);
335 memset(sum
, 0, sizeof(sum
));
339 * MD5 HMAC process buffer
341 void md5_hmac_update(md5_context
* ctx
, unsigned char *input
, int ilen
)
343 md5_update(ctx
, input
, ilen
);
347 * MD5 HMAC final digest
349 void md5_hmac_finish(md5_context
* ctx
, unsigned char output
[16])
351 unsigned char tmpbuf
[16];
353 md5_finish(ctx
, tmpbuf
);
355 md5_update(ctx
, ctx
->opad
, 64);
356 md5_update(ctx
, tmpbuf
, 16);
357 md5_finish(ctx
, output
);
359 memset(tmpbuf
, 0, sizeof(tmpbuf
));
363 * output = HMAC-MD5( hmac key, input buffer )
365 void md5_hmac(unsigned char *key
, int keylen
, unsigned char *input
,
366 int ilen
, unsigned char output
[16])
370 md5_hmac_starts(&ctx
, key
, keylen
);
371 md5_hmac_update(&ctx
, input
, ilen
);
372 md5_hmac_finish(&ctx
, output
);
374 memset(&ctx
, 0, sizeof(md5_context
));
377 #if defined(XYSSL_SELF_TEST)
380 * RFC 1321 test vectors
382 static const char md5_test_str
[7][81] = {
387 {"abcdefghijklmnopqrstuvwxyz"},
388 {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"},
389 {"12345678901234567890123456789012345678901234567890123456789012"
390 "345678901234567890"}
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}
413 int md5_self_test(int verbose
)
416 unsigned char md5sum
[16];
418 for (i
= 0; i
< 7; i
++) {
420 printf(" MD5 test #%d: ", i
+ 1);
422 md5((unsigned char *) md5_test_str
[i
],
423 strlen(md5_test_str
[i
]), md5sum
);
425 if (memcmp(md5sum
, md5_test_sum
[i
], 16) != 0) {