25 /* |
25 /* |
26 Independent implementation of MD5 (RFC 1321). |
26 Independent implementation of MD5 (RFC 1321). |
27 |
27 |
28 This code implements the MD5 Algorithm defined in RFC 1321, whose |
28 This code implements the MD5 Algorithm defined in RFC 1321, whose |
29 text is available at |
29 text is available at |
30 http://www.ietf.org/rfc/rfc1321.txt |
30 http://www.ietf.org/rfc/rfc1321.txt |
31 The code is derived from the text of the RFC, including the test suite |
31 The code is derived from the text of the RFC, including the test suite |
32 (section A.5) but excluding the rest of Appendix A. It does not include |
32 (section A.5) but excluding the rest of Appendix A. It does not include |
33 any code or documentation that is identified in the RFC as being |
33 any code or documentation that is identified in the RFC as being |
34 copyrighted. |
34 copyrighted. |
35 |
35 |
36 The original and principal author of md5.c is L. Peter Deutsch |
36 The original and principal author of md5.c is L. Peter Deutsch |
37 <ghost@aladdin.com>. Other authors are noted in the change history |
37 <ghost@aladdin.com>. Other authors are noted in the change history |
38 that follows (in reverse chronological order): |
38 that follows (in reverse chronological order): |
39 |
39 |
40 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order |
40 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order |
41 either statically or dynamically; added missing #include <string.h> |
41 either statically or dynamically; added missing #include <string.h> |
42 in library. |
42 in library. |
43 2002-03-11 lpd Corrected argument list for main(), and added int return |
43 2002-03-11 lpd Corrected argument list for main(), and added int return |
44 type, in test program and T value program. |
44 type, in test program and T value program. |
45 2002-02-21 lpd Added missing #include <stdio.h> in test program. |
45 2002-02-21 lpd Added missing #include <stdio.h> in test program. |
46 2000-07-03 lpd Patched to eliminate warnings about "constant is |
46 2000-07-03 lpd Patched to eliminate warnings about "constant is |
47 unsigned in ANSI C, signed in traditional"; made test program |
47 unsigned in ANSI C, signed in traditional"; made test program |
48 self-checking. |
48 self-checking. |
49 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. |
49 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. |
50 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). |
50 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). |
51 1999-05-03 lpd Original version. |
51 1999-05-03 lpd Original version. |
52 */ |
52 */ |
53 |
53 |
54 #include "md5.h" |
54 #include "md5.h" |
55 #include <string.h> |
55 #include <string.h> |
56 |
56 |
57 #undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ |
57 #undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ |
58 #ifdef ARCH_IS_BIG_ENDIAN |
58 #ifdef ARCH_IS_BIG_ENDIAN |
59 # define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) |
59 # define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) |
60 #else |
60 #else |
61 # define BYTE_ORDER 0 |
61 # define BYTE_ORDER 0 |
62 #endif |
62 #endif |
144 const md5_word_t *X; |
144 const md5_word_t *X; |
145 #endif |
145 #endif |
146 |
146 |
147 { |
147 { |
148 #if BYTE_ORDER == 0 |
148 #if BYTE_ORDER == 0 |
149 /* |
149 /* |
150 * Determine dynamically whether this is a big-endian or |
150 * Determine dynamically whether this is a big-endian or |
151 * little-endian machine, since we can use a more efficient |
151 * little-endian machine, since we can use a more efficient |
152 * algorithm on the latter. |
152 * algorithm on the latter. |
153 */ |
153 */ |
154 static const int w = 1; |
154 static const int w = 1; |
155 |
155 |
156 if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ |
156 if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ |
157 #endif |
157 #endif |
158 #if BYTE_ORDER <= 0 /* little-endian */ |
158 #if BYTE_ORDER <= 0 /* little-endian */ |
159 { |
159 { |
160 /* |
160 /* |
161 * On little-endian machines, we can process properly aligned |
161 * On little-endian machines, we can process properly aligned |
162 * data without copying it. |
162 * data without copying it. |
163 */ |
163 */ |
164 if (!((data - (const md5_byte_t *)0) & 3)) { |
164 if (!((data - (const md5_byte_t *)0) & 3)) { |
165 /* data are properly aligned */ |
165 /* data are properly aligned */ |
166 X = (const md5_word_t *)data; |
166 X = (const md5_word_t *)data; |
167 } else { |
167 } else { |
168 /* not aligned */ |
168 /* not aligned */ |
169 memcpy(xbuf, data, 64); |
169 memcpy(xbuf, data, 64); |
170 X = xbuf; |
170 X = xbuf; |
171 } |
171 } |
172 } |
172 } |
173 #endif |
173 #endif |
174 #if BYTE_ORDER == 0 |
174 #if BYTE_ORDER == 0 |
175 else /* dynamic big-endian */ |
175 else /* dynamic big-endian */ |
176 #endif |
176 #endif |
177 #if BYTE_ORDER >= 0 /* big-endian */ |
177 #if BYTE_ORDER >= 0 /* big-endian */ |
178 { |
178 { |
179 /* |
179 /* |
180 * On big-endian machines, we must arrange the bytes in the |
180 * On big-endian machines, we must arrange the bytes in the |
181 * right order. |
181 * right order. |
182 */ |
182 */ |
183 const md5_byte_t *xp = data; |
183 const md5_byte_t *xp = data; |
184 int i; |
184 int i; |
185 |
185 |
186 # if BYTE_ORDER == 0 |
186 # if BYTE_ORDER == 0 |
187 X = xbuf; /* (dynamic only) */ |
187 X = xbuf; /* (dynamic only) */ |
188 # else |
188 # else |
189 # define xbuf X /* (static only) */ |
189 # define xbuf X /* (static only) */ |
190 # endif |
190 # endif |
191 for (i = 0; i < 16; ++i, xp += 4) |
191 for (i = 0; i < 16; ++i, xp += 4) |
192 xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); |
192 xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); |
193 } |
193 } |
194 #endif |
194 #endif |
195 } |
195 } |
196 |
196 |
197 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) |
197 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) |
198 |
198 |
326 int left = nbytes; |
326 int left = nbytes; |
327 int offset = (pms->count[0] >> 3) & 63; |
327 int offset = (pms->count[0] >> 3) & 63; |
328 md5_word_t nbits = (md5_word_t)(nbytes << 3); |
328 md5_word_t nbits = (md5_word_t)(nbytes << 3); |
329 |
329 |
330 if (nbytes <= 0) |
330 if (nbytes <= 0) |
331 return; |
331 return; |
332 |
332 |
333 /* Update the message length. */ |
333 /* Update the message length. */ |
334 pms->count[1] += nbytes >> 29; |
334 pms->count[1] += nbytes >> 29; |
335 pms->count[0] += nbits; |
335 pms->count[0] += nbits; |
336 if (pms->count[0] < nbits) |
336 if (pms->count[0] < nbits) |
337 pms->count[1]++; |
337 pms->count[1]++; |
338 |
338 |
339 /* Process an initial partial block. */ |
339 /* Process an initial partial block. */ |
340 if (offset) { |
340 if (offset) { |
341 int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); |
341 int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); |
342 |
342 |
343 memcpy(pms->buf + offset, p, copy); |
343 memcpy(pms->buf + offset, p, copy); |
344 if (offset + copy < 64) |
344 if (offset + copy < 64) |
345 return; |
345 return; |
346 p += copy; |
346 p += copy; |
347 left -= copy; |
347 left -= copy; |
348 md5_process(pms, pms->buf); |
348 md5_process(pms, pms->buf); |
349 } |
349 } |
350 |
350 |
351 /* Process full blocks. */ |
351 /* Process full blocks. */ |
352 for (; left >= 64; p += 64, left -= 64) |
352 for (; left >= 64; p += 64, left -= 64) |
353 md5_process(pms, p); |
353 md5_process(pms, p); |
354 |
354 |
355 /* Process a final partial block. */ |
355 /* Process a final partial block. */ |
356 if (left) |
356 if (left) |
357 memcpy(pms->buf, p, left); |
357 memcpy(pms->buf, p, left); |
358 } |
358 } |
359 |
359 |
360 void |
360 void |
361 md5_finish(md5_state_t *pms, md5_byte_t digest[16]) |
361 md5_finish(md5_state_t *pms, md5_byte_t digest[16]) |
362 { |
362 { |
363 static const md5_byte_t pad[64] = { |
363 static const md5_byte_t pad[64] = { |
364 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
364 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
365 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
365 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
366 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
366 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
367 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
367 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
368 }; |
368 }; |
369 md5_byte_t data[8]; |
369 md5_byte_t data[8]; |
370 int i; |
370 int i; |
371 |
371 |
372 /* Save the length before padding. */ |
372 /* Save the length before padding. */ |
373 for (i = 0; i < 8; ++i) |
373 for (i = 0; i < 8; ++i) |
374 data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); |
374 data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); |
375 /* Pad to 56 bytes mod 64. */ |
375 /* Pad to 56 bytes mod 64. */ |
376 md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); |
376 md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); |
377 /* Append the length. */ |
377 /* Append the length. */ |
378 md5_append(pms, data, 8); |
378 md5_append(pms, data, 8); |
379 for (i = 0; i < 16; ++i) |
379 for (i = 0; i < 16; ++i) |
380 digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); |
380 digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); |
381 } |
381 } |