00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 #include "md5.h"
00078
00079 #include <string>
00080 #include <memory>
00081 #include <string.h>
00082
00083 #ifdef TEST
00084
00085
00086
00087
00088
00089
00090 main()
00091 {
00092 static const char *const test[7*2] = {
00093 "", "d41d8cd98f00b204e9800998ecf8427e",
00094 "a", "0cc175b9c0f1b6a831c399e269772661",
00095 "abc", "900150983cd24fb0d6963f7d28e17f72",
00096 "message digest", "f96b697d7cb7938d525a2f31aaf161d0",
00097 "abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b",
00098 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
00099 "d174ab98d277d9f5a5611c2c9f419d9f",
00100 "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "57edf4a22be3c955ac49da2e2107b67a"
00101 };
00102 int i;
00103
00104 for (i = 0; i < 7*2; i += 2) {
00105 md5_state_t state;
00106 md5_byte_t digest[16];
00107 char hex_output[16*2 + 1];
00108 int di;
00109
00110 md5_init(&state);
00111 md5_append(&state, (const md5_byte_t *)test[i], strlen(test[i]));
00112 md5_finish(&state, digest);
00113 printf("MD5 (\"%s\") = ", test[i]);
00114 for (di = 0; di < 16; ++di)
00115 sprintf(hex_output + di * 2, "%02x", digest[di]);
00116 puts(hex_output);
00117 if (strcmp(hex_output, test[i + 1]))
00118 printf("**** ERROR, should be: %s\n", test[i + 1]);
00119 }
00120 return 0;
00121 }
00122 #endif
00123
00124
00125
00126
00127
00128 #ifdef COMPUTE_T_VALUES
00129 #include <math>
00130 main()
00131 {
00132 int i;
00133 for (i = 1; i <= 64; ++i) {
00134 unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i)));
00135
00136
00137
00138
00139
00140 if (v >> 31) {
00141 printf("#define T%d /* 0x%08lx */ (T_MASK ^ 0x%08lx)\n", i,
00142 v, (unsigned long)(unsigned int)(~v));
00143 } else {
00144 printf("#define T%d 0x%08lx\n", i, v);
00145 }
00146 }
00147 return 0;
00148 }
00149 #endif
00150
00151
00152
00153 #define T_MASK ((md5_word_t)~0)
00154 #define T1 (T_MASK ^ 0x28955b87)
00155 #define T2 (T_MASK ^ 0x173848a9)
00156 #define T3 0x242070db
00157 #define T4 (T_MASK ^ 0x3e423111)
00158 #define T5 (T_MASK ^ 0x0a83f050)
00159 #define T6 0x4787c62a
00160 #define T7 (T_MASK ^ 0x57cfb9ec)
00161 #define T8 (T_MASK ^ 0x02b96afe)
00162 #define T9 0x698098d8
00163 #define T10 (T_MASK ^ 0x74bb0850)
00164 #define T11 (T_MASK ^ 0x0000a44e)
00165 #define T12 (T_MASK ^ 0x76a32841)
00166 #define T13 0x6b901122
00167 #define T14 (T_MASK ^ 0x02678e6c)
00168 #define T15 (T_MASK ^ 0x5986bc71)
00169 #define T16 0x49b40821
00170 #define T17 (T_MASK ^ 0x09e1da9d)
00171 #define T18 (T_MASK ^ 0x3fbf4cbf)
00172 #define T19 0x265e5a51
00173 #define T20 (T_MASK ^ 0x16493855)
00174 #define T21 (T_MASK ^ 0x29d0efa2)
00175 #define T22 0x02441453
00176 #define T23 (T_MASK ^ 0x275e197e)
00177 #define T24 (T_MASK ^ 0x182c0437)
00178 #define T25 0x21e1cde6
00179 #define T26 (T_MASK ^ 0x3cc8f829)
00180 #define T27 (T_MASK ^ 0x0b2af278)
00181 #define T28 0x455a14ed
00182 #define T29 (T_MASK ^ 0x561c16fa)
00183 #define T30 (T_MASK ^ 0x03105c07)
00184 #define T31 0x676f02d9
00185 #define T32 (T_MASK ^ 0x72d5b375)
00186 #define T33 (T_MASK ^ 0x0005c6bd)
00187 #define T34 (T_MASK ^ 0x788e097e)
00188 #define T35 0x6d9d6122
00189 #define T36 (T_MASK ^ 0x021ac7f3)
00190 #define T37 (T_MASK ^ 0x5b4115bb)
00191 #define T38 0x4bdecfa9
00192 #define T39 (T_MASK ^ 0x0944b49f)
00193 #define T40 (T_MASK ^ 0x4140438f)
00194 #define T41 0x289b7ec6
00195 #define T42 (T_MASK ^ 0x155ed805)
00196 #define T43 (T_MASK ^ 0x2b10cf7a)
00197 #define T44 0x04881d05
00198 #define T45 (T_MASK ^ 0x262b2fc6)
00199 #define T46 (T_MASK ^ 0x1924661a)
00200 #define T47 0x1fa27cf8
00201 #define T48 (T_MASK ^ 0x3b53a99a)
00202 #define T49 (T_MASK ^ 0x0bd6ddbb)
00203 #define T50 0x432aff97
00204 #define T51 (T_MASK ^ 0x546bdc58)
00205 #define T52 (T_MASK ^ 0x036c5fc6)
00206 #define T53 0x655b59c3
00207 #define T54 (T_MASK ^ 0x70f3336d)
00208 #define T55 (T_MASK ^ 0x00100b82)
00209 #define T56 (T_MASK ^ 0x7a7ba22e)
00210 #define T57 0x6fa87e4f
00211 #define T58 (T_MASK ^ 0x01d3191f)
00212 #define T59 (T_MASK ^ 0x5cfebceb)
00213 #define T60 0x4e0811a1
00214 #define T61 (T_MASK ^ 0x08ac817d)
00215 #define T62 (T_MASK ^ 0x42c50dca)
00216 #define T63 0x2ad7d2bb
00217 #define T64 (T_MASK ^ 0x14792c6e)
00218
00219
00220 static void
00221 md5_process(md5_state_t *pms, const md5_byte_t *data )
00222 {
00223 md5_word_t
00224 a = pms->abcd[0], b = pms->abcd[1],
00225 c = pms->abcd[2], d = pms->abcd[3];
00226 md5_word_t t;
00227
00228 #ifndef ARCH_IS_BIG_ENDIAN
00229 # define ARCH_IS_BIG_ENDIAN 1
00230 #endif
00231 #if ARCH_IS_BIG_ENDIAN
00232
00233
00234
00235
00236
00237 md5_word_t X[16];
00238 const md5_byte_t *xp = data;
00239 int i;
00240
00241 for (i = 0; i < 16; ++i, xp += 4)
00242 X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
00243
00244 #else
00245
00246
00247
00248
00249
00250 md5_word_t xbuf[16];
00251 const md5_word_t *X;
00252
00253 if (!((data - (const md5_byte_t *)0) & 3)) {
00254
00255 X = (const md5_word_t *)data;
00256 } else {
00257
00258 memcpy(xbuf, data, 64);
00259 X = xbuf;
00260 }
00261 #endif
00262
00263 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
00264
00265
00266
00267
00268 #define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
00269 #define SET(a, b, c, d, k, s, Ti)\
00270 t = a + F(b,c,d) + X[k] + Ti;\
00271 a = ROTATE_LEFT(t, s) + b
00272
00273 SET(a, b, c, d, 0, 7, T1);
00274 SET(d, a, b, c, 1, 12, T2);
00275 SET(c, d, a, b, 2, 17, T3);
00276 SET(b, c, d, a, 3, 22, T4);
00277 SET(a, b, c, d, 4, 7, T5);
00278 SET(d, a, b, c, 5, 12, T6);
00279 SET(c, d, a, b, 6, 17, T7);
00280 SET(b, c, d, a, 7, 22, T8);
00281 SET(a, b, c, d, 8, 7, T9);
00282 SET(d, a, b, c, 9, 12, T10);
00283 SET(c, d, a, b, 10, 17, T11);
00284 SET(b, c, d, a, 11, 22, T12);
00285 SET(a, b, c, d, 12, 7, T13);
00286 SET(d, a, b, c, 13, 12, T14);
00287 SET(c, d, a, b, 14, 17, T15);
00288 SET(b, c, d, a, 15, 22, T16);
00289 #undef SET
00290
00291
00292
00293
00294 #define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
00295 #define SET(a, b, c, d, k, s, Ti)\
00296 t = a + G(b,c,d) + X[k] + Ti;\
00297 a = ROTATE_LEFT(t, s) + b
00298
00299 SET(a, b, c, d, 1, 5, T17);
00300 SET(d, a, b, c, 6, 9, T18);
00301 SET(c, d, a, b, 11, 14, T19);
00302 SET(b, c, d, a, 0, 20, T20);
00303 SET(a, b, c, d, 5, 5, T21);
00304 SET(d, a, b, c, 10, 9, T22);
00305 SET(c, d, a, b, 15, 14, T23);
00306 SET(b, c, d, a, 4, 20, T24);
00307 SET(a, b, c, d, 9, 5, T25);
00308 SET(d, a, b, c, 14, 9, T26);
00309 SET(c, d, a, b, 3, 14, T27);
00310 SET(b, c, d, a, 8, 20, T28);
00311 SET(a, b, c, d, 13, 5, T29);
00312 SET(d, a, b, c, 2, 9, T30);
00313 SET(c, d, a, b, 7, 14, T31);
00314 SET(b, c, d, a, 12, 20, T32);
00315 #undef SET
00316
00317
00318
00319
00320 #define H(x, y, z) ((x) ^ (y) ^ (z))
00321 #define SET(a, b, c, d, k, s, Ti)\
00322 t = a + H(b,c,d) + X[k] + Ti;\
00323 a = ROTATE_LEFT(t, s) + b
00324
00325 SET(a, b, c, d, 5, 4, T33);
00326 SET(d, a, b, c, 8, 11, T34);
00327 SET(c, d, a, b, 11, 16, T35);
00328 SET(b, c, d, a, 14, 23, T36);
00329 SET(a, b, c, d, 1, 4, T37);
00330 SET(d, a, b, c, 4, 11, T38);
00331 SET(c, d, a, b, 7, 16, T39);
00332 SET(b, c, d, a, 10, 23, T40);
00333 SET(a, b, c, d, 13, 4, T41);
00334 SET(d, a, b, c, 0, 11, T42);
00335 SET(c, d, a, b, 3, 16, T43);
00336 SET(b, c, d, a, 6, 23, T44);
00337 SET(a, b, c, d, 9, 4, T45);
00338 SET(d, a, b, c, 12, 11, T46);
00339 SET(c, d, a, b, 15, 16, T47);
00340 SET(b, c, d, a, 2, 23, T48);
00341 #undef SET
00342
00343
00344
00345
00346 #define I(x, y, z) ((y) ^ ((x) | ~(z)))
00347 #define SET(a, b, c, d, k, s, Ti)\
00348 t = a + I(b,c,d) + X[k] + Ti;\
00349 a = ROTATE_LEFT(t, s) + b
00350
00351 SET(a, b, c, d, 0, 6, T49);
00352 SET(d, a, b, c, 7, 10, T50);
00353 SET(c, d, a, b, 14, 15, T51);
00354 SET(b, c, d, a, 5, 21, T52);
00355 SET(a, b, c, d, 12, 6, T53);
00356 SET(d, a, b, c, 3, 10, T54);
00357 SET(c, d, a, b, 10, 15, T55);
00358 SET(b, c, d, a, 1, 21, T56);
00359 SET(a, b, c, d, 8, 6, T57);
00360 SET(d, a, b, c, 15, 10, T58);
00361 SET(c, d, a, b, 6, 15, T59);
00362 SET(b, c, d, a, 13, 21, T60);
00363 SET(a, b, c, d, 4, 6, T61);
00364 SET(d, a, b, c, 11, 10, T62);
00365 SET(c, d, a, b, 2, 15, T63);
00366 SET(b, c, d, a, 9, 21, T64);
00367 #undef SET
00368
00369
00370
00371
00372 pms->abcd[0] += a;
00373 pms->abcd[1] += b;
00374 pms->abcd[2] += c;
00375 pms->abcd[3] += d;
00376 }
00377
00378 void
00379 md5_init(md5_state_t *pms)
00380 {
00381 pms->count[0] = pms->count[1] = 0;
00382 pms->abcd[0] = 0x67452301;
00383 pms->abcd[1] = T_MASK ^ 0x10325476;
00384 pms->abcd[2] = T_MASK ^ 0x67452301;
00385 pms->abcd[3] = 0x10325476;
00386 }
00387
00388 void
00389 md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
00390 {
00391 const md5_byte_t *p = data;
00392 int left = nbytes;
00393 int offset = (pms->count[0] >> 3) & 63;
00394 md5_word_t nbits = (md5_word_t)(nbytes << 3);
00395
00396 if (nbytes <= 0)
00397 return;
00398
00399
00400 pms->count[1] += nbytes >> 29;
00401 pms->count[0] += nbits;
00402 if (pms->count[0] < nbits)
00403 pms->count[1]++;
00404
00405
00406 if (offset) {
00407 int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
00408
00409 memcpy(pms->buf + offset, p, copy);
00410 if (offset + copy < 64)
00411 return;
00412 p += copy;
00413 left -= copy;
00414 md5_process(pms, pms->buf);
00415 }
00416
00417
00418 for (; left >= 64; p += 64, left -= 64)
00419 md5_process(pms, p);
00420
00421
00422 if (left)
00423 memcpy(pms->buf, p, left);
00424 }
00425
00426 void
00427 md5_finish(md5_state_t *pms, md5_byte_t digest[16])
00428 {
00429 static const md5_byte_t pad[64] = {
00430 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00431 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00432 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00433 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00434 };
00435 md5_byte_t data[8];
00436 int i;
00437
00438
00439 for (i = 0; i < 8; ++i)
00440 data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
00441
00442 md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
00443
00444 md5_append(pms, data, 8);
00445 for (i = 0; i < 16; ++i)
00446 digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
00447 }