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