DEFINITIONS
This source file includes following functions.
- main
- main
- md5_process
- MD5_Init
- MD5_Update
- MD5_Final
- MD5_End
- MD5_Equal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 #include "md5.h"
49
50 #ifdef TEST
51
52
53
54
55
56 #include <string.h>
57 main()
58 {
59 static const char *const test[7*2] = {
60 "", "d41d8cd98f00b204e9800998ecf8427e",
61 "a", "0cc175b9c0f1b6a831c399e269772661",
62 "abc", "900150983cd24fb0d6963f7d28e17f72",
63 "message digest", "f96b697d7cb7938d525a2f31aaf161d0",
64 "abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b",
65 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
66 "d174ab98d277d9f5a5611c2c9f419d9f",
67 "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "57edf4a22be3c955ac49da2e2107b67a"
68 };
69 int i;
70
71 for (i = 0; i < 7*2; i += 2) {
72 MD5_CTX state;
73 uint8_t digest[16];
74 char hex_output[16*2 + 1];
75 int di;
76
77 MD5_Init(&state);
78 MD5_Update(&state, (const uint8_t *)test[i], strlen(test[i]));
79 MD5_Final(digest, &state);
80 printf("MD5 (\"%s\") = ", test[i]);
81 for (di = 0; di < 16; ++di)
82 sprintf(hex_output + di * 2, "%02x", digest[di]);
83 puts(hex_output);
84 if (strcmp(hex_output, test[i + 1]))
85 printf("**** ERROR, should be: %s\n", test[i + 1]);
86 }
87 return 0;
88 }
89 #endif
90
91
92
93
94
95 #ifdef COMPUTE_T_VALUES
96 #include <math.h>
97 main()
98 {
99 int i;
100 for (i = 1; i <= 64; ++i) {
101 unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i)));
102
103
104
105
106
107 if (v >> 31) {
108 printf("#define T%d /* 0x%08lx */ (T_MASK ^ 0x%08lx)\n", i,
109 v, (unsigned long)(unsigned int)(~v));
110 } else {
111 printf("#define T%d 0x%08lx\n", i, v);
112 }
113 }
114 return 0;
115 }
116 #endif
117
118
119
120 #ifdef T_MASK
121 #undef T_MASK
122 #endif
123 #define T_MASK ((uint32_t)~0)
124 #define T1 (T_MASK ^ 0x28955b87)
125 #define T2 (T_MASK ^ 0x173848a9)
126 #define T3 0x242070db
127 #define T4 (T_MASK ^ 0x3e423111)
128 #define T5 (T_MASK ^ 0x0a83f050)
129 #define T6 0x4787c62a
130 #define T7 (T_MASK ^ 0x57cfb9ec)
131 #define T8 (T_MASK ^ 0x02b96afe)
132 #define T9 0x698098d8
133 #define T10 (T_MASK ^ 0x74bb0850)
134 #define T11 (T_MASK ^ 0x0000a44e)
135 #define T12 (T_MASK ^ 0x76a32841)
136 #define T13 0x6b901122
137 #define T14 (T_MASK ^ 0x02678e6c)
138 #define T15 (T_MASK ^ 0x5986bc71)
139 #define T16 0x49b40821
140 #define T17 (T_MASK ^ 0x09e1da9d)
141 #define T18 (T_MASK ^ 0x3fbf4cbf)
142 #define T19 0x265e5a51
143 #define T20 (T_MASK ^ 0x16493855)
144 #define T21 (T_MASK ^ 0x29d0efa2)
145 #define T22 0x02441453
146 #define T23 (T_MASK ^ 0x275e197e)
147 #define T24 (T_MASK ^ 0x182c0437)
148 #define T25 0x21e1cde6
149 #define T26 (T_MASK ^ 0x3cc8f829)
150 #define T27 (T_MASK ^ 0x0b2af278)
151 #define T28 0x455a14ed
152 #define T29 (T_MASK ^ 0x561c16fa)
153 #define T30 (T_MASK ^ 0x03105c07)
154 #define T31 0x676f02d9
155 #define T32 (T_MASK ^ 0x72d5b375)
156 #define T33 (T_MASK ^ 0x0005c6bd)
157 #define T34 (T_MASK ^ 0x788e097e)
158 #define T35 0x6d9d6122
159 #define T36 (T_MASK ^ 0x021ac7f3)
160 #define T37 (T_MASK ^ 0x5b4115bb)
161 #define T38 0x4bdecfa9
162 #define T39 (T_MASK ^ 0x0944b49f)
163 #define T40 (T_MASK ^ 0x4140438f)
164 #define T41 0x289b7ec6
165 #define T42 (T_MASK ^ 0x155ed805)
166 #define T43 (T_MASK ^ 0x2b10cf7a)
167 #define T44 0x04881d05
168 #define T45 (T_MASK ^ 0x262b2fc6)
169 #define T46 (T_MASK ^ 0x1924661a)
170 #define T47 0x1fa27cf8
171 #define T48 (T_MASK ^ 0x3b53a99a)
172 #define T49 (T_MASK ^ 0x0bd6ddbb)
173 #define T50 0x432aff97
174 #define T51 (T_MASK ^ 0x546bdc58)
175 #define T52 (T_MASK ^ 0x036c5fc6)
176 #define T53 0x655b59c3
177 #define T54 (T_MASK ^ 0x70f3336d)
178 #define T55 (T_MASK ^ 0x00100b82)
179 #define T56 (T_MASK ^ 0x7a7ba22e)
180 #define T57 0x6fa87e4f
181 #define T58 (T_MASK ^ 0x01d3191f)
182 #define T59 (T_MASK ^ 0x5cfebceb)
183 #define T60 0x4e0811a1
184 #define T61 (T_MASK ^ 0x08ac817d)
185 #define T62 (T_MASK ^ 0x42c50dca)
186 #define T63 0x2ad7d2bb
187 #define T64 (T_MASK ^ 0x14792c6e)
188
189
190 static void
191 md5_process(MD5_CTX *pms, const uint8_t *data )
192 {
193 uint32_t
194 a = pms->state[0], b = pms->state[1],
195 c = pms->state[2], d = pms->state[3];
196 uint32_t t;
197
198 #ifdef WORDS_BIGENDIAN
199
200
201
202
203
204 uint32_t X[16];
205 const uint8_t *xp = data;
206 int i;
207
208 for (i = 0; i < 16; ++i, xp += 4)
209 X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
210
211 #else
212
213
214
215
216
217 uint32_t xbuf[16];
218 const uint32_t *X;
219
220 if (!((data - (const uint8_t *)0) & 3)) {
221
222 X = (const uint32_t *)data;
223 } else {
224
225 memcpy(xbuf, data, 64);
226 X = xbuf;
227 }
228 #endif
229
230 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
231
232
233
234
235 #define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
236 #define SET(a, b, c, d, k, s, Ti)\
237 t = a + F(b,c,d) + X[k] + Ti;\
238 a = ROTATE_LEFT(t, s) + b
239
240 SET(a, b, c, d, 0, 7, T1);
241 SET(d, a, b, c, 1, 12, T2);
242 SET(c, d, a, b, 2, 17, T3);
243 SET(b, c, d, a, 3, 22, T4);
244 SET(a, b, c, d, 4, 7, T5);
245 SET(d, a, b, c, 5, 12, T6);
246 SET(c, d, a, b, 6, 17, T7);
247 SET(b, c, d, a, 7, 22, T8);
248 SET(a, b, c, d, 8, 7, T9);
249 SET(d, a, b, c, 9, 12, T10);
250 SET(c, d, a, b, 10, 17, T11);
251 SET(b, c, d, a, 11, 22, T12);
252 SET(a, b, c, d, 12, 7, T13);
253 SET(d, a, b, c, 13, 12, T14);
254 SET(c, d, a, b, 14, 17, T15);
255 SET(b, c, d, a, 15, 22, T16);
256 #undef SET
257
258
259
260
261 #define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
262 #define SET(a, b, c, d, k, s, Ti)\
263 t = a + G(b,c,d) + X[k] + Ti;\
264 a = ROTATE_LEFT(t, s) + b
265
266 SET(a, b, c, d, 1, 5, T17);
267 SET(d, a, b, c, 6, 9, T18);
268 SET(c, d, a, b, 11, 14, T19);
269 SET(b, c, d, a, 0, 20, T20);
270 SET(a, b, c, d, 5, 5, T21);
271 SET(d, a, b, c, 10, 9, T22);
272 SET(c, d, a, b, 15, 14, T23);
273 SET(b, c, d, a, 4, 20, T24);
274 SET(a, b, c, d, 9, 5, T25);
275 SET(d, a, b, c, 14, 9, T26);
276 SET(c, d, a, b, 3, 14, T27);
277 SET(b, c, d, a, 8, 20, T28);
278 SET(a, b, c, d, 13, 5, T29);
279 SET(d, a, b, c, 2, 9, T30);
280 SET(c, d, a, b, 7, 14, T31);
281 SET(b, c, d, a, 12, 20, T32);
282 #undef SET
283
284
285
286
287 #define H(x, y, z) ((x) ^ (y) ^ (z))
288 #define SET(a, b, c, d, k, s, Ti)\
289 t = a + H(b,c,d) + X[k] + Ti;\
290 a = ROTATE_LEFT(t, s) + b
291
292 SET(a, b, c, d, 5, 4, T33);
293 SET(d, a, b, c, 8, 11, T34);
294 SET(c, d, a, b, 11, 16, T35);
295 SET(b, c, d, a, 14, 23, T36);
296 SET(a, b, c, d, 1, 4, T37);
297 SET(d, a, b, c, 4, 11, T38);
298 SET(c, d, a, b, 7, 16, T39);
299 SET(b, c, d, a, 10, 23, T40);
300 SET(a, b, c, d, 13, 4, T41);
301 SET(d, a, b, c, 0, 11, T42);
302 SET(c, d, a, b, 3, 16, T43);
303 SET(b, c, d, a, 6, 23, T44);
304 SET(a, b, c, d, 9, 4, T45);
305 SET(d, a, b, c, 12, 11, T46);
306 SET(c, d, a, b, 15, 16, T47);
307 SET(b, c, d, a, 2, 23, T48);
308 #undef SET
309
310
311
312
313 #define I(x, y, z) ((y) ^ ((x) | ~(z)))
314 #define SET(a, b, c, d, k, s, Ti)\
315 t = a + I(b,c,d) + X[k] + Ti;\
316 a = ROTATE_LEFT(t, s) + b
317
318 SET(a, b, c, d, 0, 6, T49);
319 SET(d, a, b, c, 7, 10, T50);
320 SET(c, d, a, b, 14, 15, T51);
321 SET(b, c, d, a, 5, 21, T52);
322 SET(a, b, c, d, 12, 6, T53);
323 SET(d, a, b, c, 3, 10, T54);
324 SET(c, d, a, b, 10, 15, T55);
325 SET(b, c, d, a, 1, 21, T56);
326 SET(a, b, c, d, 8, 6, T57);
327 SET(d, a, b, c, 15, 10, T58);
328 SET(c, d, a, b, 6, 15, T59);
329 SET(b, c, d, a, 13, 21, T60);
330 SET(a, b, c, d, 4, 6, T61);
331 SET(d, a, b, c, 11, 10, T62);
332 SET(c, d, a, b, 2, 15, T63);
333 SET(b, c, d, a, 9, 21, T64);
334 #undef SET
335
336
337
338
339 pms->state[0] += a;
340 pms->state[1] += b;
341 pms->state[2] += c;
342 pms->state[3] += d;
343 }
344
345 void
346 MD5_Init(MD5_CTX *pms)
347 {
348 pms->count[0] = pms->count[1] = 0;
349 pms->state[0] = 0x67452301;
350 pms->state[1] = T_MASK ^ 0x10325476;
351 pms->state[2] = T_MASK ^ 0x67452301;
352 pms->state[3] = 0x10325476;
353 }
354
355 void
356 MD5_Update(MD5_CTX *pms, const uint8_t *data, size_t nbytes)
357 {
358 const uint8_t *p = data;
359 size_t left = nbytes;
360 size_t offset = (pms->count[0] >> 3) & 63;
361 uint32_t nbits = (uint32_t)(nbytes << 3);
362
363 if (nbytes <= 0)
364 return;
365
366
367 pms->count[1] += nbytes >> 29;
368 pms->count[0] += nbits;
369 if (pms->count[0] < nbits)
370 pms->count[1]++;
371
372
373 if (offset) {
374 size_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
375
376 memcpy(pms->buffer + offset, p, copy);
377 if (offset + copy < 64)
378 return;
379 p += copy;
380 left -= copy;
381 md5_process(pms, pms->buffer);
382 }
383
384
385 for (; left >= 64; p += 64, left -= 64)
386 md5_process(pms, p);
387
388
389 if (left)
390 memcpy(pms->buffer, p, left);
391 }
392
393 void
394 MD5_Final(uint8_t *digest, MD5_CTX *pms)
395 {
396 static const uint8_t pad[64] = {
397 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
398 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
399 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
400 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
401 };
402 uint8_t data[8];
403 size_t i;
404
405
406 for (i = 0; i < 8; ++i)
407 data[i] = (uint8_t)(pms->count[i >> 2] >> ((i & 3) << 3));
408
409 MD5_Update(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
410
411 MD5_Update(pms, data, 8);
412 for (i = 0; i < 16; ++i)
413 digest[i] = (uint8_t)(pms->state[i >> 2] >> ((i & 3) << 3));
414 }
415
416 void
417 MD5_End(MD5_CTX *pctx, uint8_t *hexdigest)
418 {
419 unsigned char digest[16];
420 size_t i;
421
422 MD5_Final(digest, pctx);
423
424 for (i = 0; i < 16; i++)
425 sprintf(hexdigest + i * 2, "%02x", digest[i]);
426 }
427
428 int MD5_Equal(MD5_CTX* pctx1, MD5_CTX* pctx2) {
429 return memcmp(pctx1->count, pctx2->count, sizeof(pctx1->count)) == 0
430 && memcmp(pctx1->state, pctx2->state, sizeof(pctx1->state)) == 0
431 && memcmp(pctx1->buffer, pctx2->buffer, sizeof(pctx1->buffer)) == 0;
432 }