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