00001
00002
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 #include "stdafx.h"
00060 #include "core/bitmath_func.hpp"
00061 #include "core/endian_func.hpp"
00062 #include "md5.h"
00063
00064 #define T_MASK ((uint32)~0)
00065 #define T1 (T_MASK ^ 0x28955b87)
00066 #define T2 (T_MASK ^ 0x173848a9)
00067 #define T3 0x242070db
00068 #define T4 (T_MASK ^ 0x3e423111)
00069 #define T5 (T_MASK ^ 0x0a83f050)
00070 #define T6 0x4787c62a
00071 #define T7 (T_MASK ^ 0x57cfb9ec)
00072 #define T8 (T_MASK ^ 0x02b96afe)
00073 #define T9 0x698098d8
00074 #define T10 (T_MASK ^ 0x74bb0850)
00075 #define T11 (T_MASK ^ 0x0000a44e)
00076 #define T12 (T_MASK ^ 0x76a32841)
00077 #define T13 0x6b901122
00078 #define T14 (T_MASK ^ 0x02678e6c)
00079 #define T15 (T_MASK ^ 0x5986bc71)
00080 #define T16 0x49b40821
00081 #define T17 (T_MASK ^ 0x09e1da9d)
00082 #define T18 (T_MASK ^ 0x3fbf4cbf)
00083 #define T19 0x265e5a51
00084 #define T20 (T_MASK ^ 0x16493855)
00085 #define T21 (T_MASK ^ 0x29d0efa2)
00086 #define T22 0x02441453
00087 #define T23 (T_MASK ^ 0x275e197e)
00088 #define T24 (T_MASK ^ 0x182c0437)
00089 #define T25 0x21e1cde6
00090 #define T26 (T_MASK ^ 0x3cc8f829)
00091 #define T27 (T_MASK ^ 0x0b2af278)
00092 #define T28 0x455a14ed
00093 #define T29 (T_MASK ^ 0x561c16fa)
00094 #define T30 (T_MASK ^ 0x03105c07)
00095 #define T31 0x676f02d9
00096 #define T32 (T_MASK ^ 0x72d5b375)
00097 #define T33 (T_MASK ^ 0x0005c6bd)
00098 #define T34 (T_MASK ^ 0x788e097e)
00099 #define T35 0x6d9d6122
00100 #define T36 (T_MASK ^ 0x021ac7f3)
00101 #define T37 (T_MASK ^ 0x5b4115bb)
00102 #define T38 0x4bdecfa9
00103 #define T39 (T_MASK ^ 0x0944b49f)
00104 #define T40 (T_MASK ^ 0x4140438f)
00105 #define T41 0x289b7ec6
00106 #define T42 (T_MASK ^ 0x155ed805)
00107 #define T43 (T_MASK ^ 0x2b10cf7a)
00108 #define T44 0x04881d05
00109 #define T45 (T_MASK ^ 0x262b2fc6)
00110 #define T46 (T_MASK ^ 0x1924661a)
00111 #define T47 0x1fa27cf8
00112 #define T48 (T_MASK ^ 0x3b53a99a)
00113 #define T49 (T_MASK ^ 0x0bd6ddbb)
00114 #define T50 0x432aff97
00115 #define T51 (T_MASK ^ 0x546bdc58)
00116 #define T52 (T_MASK ^ 0x036c5fc6)
00117 #define T53 0x655b59c3
00118 #define T54 (T_MASK ^ 0x70f3336d)
00119 #define T55 (T_MASK ^ 0x00100b82)
00120 #define T56 (T_MASK ^ 0x7a7ba22e)
00121 #define T57 0x6fa87e4f
00122 #define T58 (T_MASK ^ 0x01d3191f)
00123 #define T59 (T_MASK ^ 0x5cfebceb)
00124 #define T60 0x4e0811a1
00125 #define T61 (T_MASK ^ 0x08ac817d)
00126 #define T62 (T_MASK ^ 0x42c50dca)
00127 #define T63 0x2ad7d2bb
00128 #define T64 (T_MASK ^ 0x14792c6e)
00129
00130 static inline void Md5Set1(const uint32 *X, uint32 *a, const uint32 *b, const uint32 *c, const uint32 *d, const uint8 k, const uint8 s, const uint32 Ti)
00131 {
00132 uint32 t = (*b & *c) | (~*b & *d);
00133 t += *a + X[k] + Ti;
00134 *a = ROL(t, s) + *b;
00135 }
00136
00137 static inline void Md5Set2(const uint32 *X, uint32 *a, const uint32 *b, const uint32 *c, const uint32 *d, const uint8 k, const uint8 s, const uint32 Ti)
00138 {
00139 uint32 t = (*b & *d) | (*c & ~*d);
00140 t += *a + X[k] + Ti;
00141 *a = ROL(t, s) + *b;
00142 }
00143
00144
00145 static inline void Md5Set3(const uint32 *X, uint32 *a, const uint32 *b, const uint32 *c, const uint32 *d, const uint8 k, const uint8 s, const uint32 Ti)
00146 {
00147 uint32 t = *b ^ *c ^ *d;
00148 t += *a + X[k] + Ti;
00149 *a = ROL(t, s) + *b;
00150 }
00151
00152 static inline void Md5Set4(const uint32 *X, uint32 *a, const uint32 *b, const uint32 *c, const uint32 *d, const uint8 k, const uint8 s, const uint32 Ti)
00153 {
00154 uint32 t = *c ^ (*b | ~*d);
00155 t += *a + X[k] + Ti;
00156 *a = ROL(t, s) + *b;
00157 }
00158
00159 Md5::Md5()
00160 {
00161 count[0] = 0;
00162 count[1] = 0;
00163 abcd[0] = 0x67452301;
00164 abcd[1] = T_MASK ^ 0x10325476;
00165 abcd[2] = T_MASK ^ 0x67452301;
00166 abcd[3] = 0x10325476;
00167 }
00168
00169 void Md5::Process(const uint8 *data )
00170 {
00171 uint32 a = this->abcd[0];
00172 uint32 b = this->abcd[1];
00173 uint32 c = this->abcd[2];
00174 uint32 d = this->abcd[3];
00175
00176 uint32 X[16];
00177
00178
00179 uint32 *px = (uint32 *)data;
00180 for (uint i = 0; i < 16; i++) {
00181 X[i] = TO_LE32(*px);
00182 px++;
00183 }
00184
00185
00186 Md5Set1(X, &a, &b, &c, &d, 0, 7, T1);
00187 Md5Set1(X, &d, &a, &b, &c, 1, 12, T2);
00188 Md5Set1(X, &c, &d, &a, &b, 2, 17, T3);
00189 Md5Set1(X, &b, &c, &d, &a, 3, 22, T4);
00190 Md5Set1(X, &a, &b, &c, &d, 4, 7, T5);
00191 Md5Set1(X, &d, &a, &b, &c, 5, 12, T6);
00192 Md5Set1(X, &c, &d, &a, &b, 6, 17, T7);
00193 Md5Set1(X, &b, &c, &d, &a, 7, 22, T8);
00194 Md5Set1(X, &a, &b, &c, &d, 8, 7, T9);
00195 Md5Set1(X, &d, &a, &b, &c, 9, 12, T10);
00196 Md5Set1(X, &c, &d, &a, &b, 10, 17, T11);
00197 Md5Set1(X, &b, &c, &d, &a, 11, 22, T12);
00198 Md5Set1(X, &a, &b, &c, &d, 12, 7, T13);
00199 Md5Set1(X, &d, &a, &b, &c, 13, 12, T14);
00200 Md5Set1(X, &c, &d, &a, &b, 14, 17, T15);
00201 Md5Set1(X, &b, &c, &d, &a, 15, 22, T16);
00202
00203
00204 Md5Set2(X, &a, &b, &c, &d, 1, 5, T17);
00205 Md5Set2(X, &d, &a, &b, &c, 6, 9, T18);
00206 Md5Set2(X, &c, &d, &a, &b, 11, 14, T19);
00207 Md5Set2(X, &b, &c, &d, &a, 0, 20, T20);
00208 Md5Set2(X, &a, &b, &c, &d, 5, 5, T21);
00209 Md5Set2(X, &d, &a, &b, &c, 10, 9, T22);
00210 Md5Set2(X, &c, &d, &a, &b, 15, 14, T23);
00211 Md5Set2(X, &b, &c, &d, &a, 4, 20, T24);
00212 Md5Set2(X, &a, &b, &c, &d, 9, 5, T25);
00213 Md5Set2(X, &d, &a, &b, &c, 14, 9, T26);
00214 Md5Set2(X, &c, &d, &a, &b, 3, 14, T27);
00215 Md5Set2(X, &b, &c, &d, &a, 8, 20, T28);
00216 Md5Set2(X, &a, &b, &c, &d, 13, 5, T29);
00217 Md5Set2(X, &d, &a, &b, &c, 2, 9, T30);
00218 Md5Set2(X, &c, &d, &a, &b, 7, 14, T31);
00219 Md5Set2(X, &b, &c, &d, &a, 12, 20, T32);
00220
00221
00222 Md5Set3(X, &a, &b, &c, &d, 5, 4, T33);
00223 Md5Set3(X, &d, &a, &b, &c, 8, 11, T34);
00224 Md5Set3(X, &c, &d, &a, &b, 11, 16, T35);
00225 Md5Set3(X, &b, &c, &d, &a, 14, 23, T36);
00226 Md5Set3(X, &a, &b, &c, &d, 1, 4, T37);
00227 Md5Set3(X, &d, &a, &b, &c, 4, 11, T38);
00228 Md5Set3(X, &c, &d, &a, &b, 7, 16, T39);
00229 Md5Set3(X, &b, &c, &d, &a, 10, 23, T40);
00230 Md5Set3(X, &a, &b, &c, &d, 13, 4, T41);
00231 Md5Set3(X, &d, &a, &b, &c, 0, 11, T42);
00232 Md5Set3(X, &c, &d, &a, &b, 3, 16, T43);
00233 Md5Set3(X, &b, &c, &d, &a, 6, 23, T44);
00234 Md5Set3(X, &a, &b, &c, &d, 9, 4, T45);
00235 Md5Set3(X, &d, &a, &b, &c, 12, 11, T46);
00236 Md5Set3(X, &c, &d, &a, &b, 15, 16, T47);
00237 Md5Set3(X, &b, &c, &d, &a, 2, 23, T48);
00238
00239
00240 Md5Set4(X, &a, &b, &c, &d, 0, 6, T49);
00241 Md5Set4(X, &d, &a, &b, &c, 7, 10, T50);
00242 Md5Set4(X, &c, &d, &a, &b, 14, 15, T51);
00243 Md5Set4(X, &b, &c, &d, &a, 5, 21, T52);
00244 Md5Set4(X, &a, &b, &c, &d, 12, 6, T53);
00245 Md5Set4(X, &d, &a, &b, &c, 3, 10, T54);
00246 Md5Set4(X, &c, &d, &a, &b, 10, 15, T55);
00247 Md5Set4(X, &b, &c, &d, &a, 1, 21, T56);
00248 Md5Set4(X, &a, &b, &c, &d, 8, 6, T57);
00249 Md5Set4(X, &d, &a, &b, &c, 15, 10, T58);
00250 Md5Set4(X, &c, &d, &a, &b, 6, 15, T59);
00251 Md5Set4(X, &b, &c, &d, &a, 13, 21, T60);
00252 Md5Set4(X, &a, &b, &c, &d, 4, 6, T61);
00253 Md5Set4(X, &d, &a, &b, &c, 11, 10, T62);
00254 Md5Set4(X, &c, &d, &a, &b, 2, 15, T63);
00255 Md5Set4(X, &b, &c, &d, &a, 9, 21, T64);
00256
00257
00258
00259
00260 this->abcd[0] += a;
00261 this->abcd[1] += b;
00262 this->abcd[2] += c;
00263 this->abcd[3] += d;
00264 }
00265
00266 void Md5::Append(const void *data, const size_t nbytes)
00267 {
00268 const uint8 *p = (const uint8 *)data;
00269 size_t left = nbytes;
00270 const size_t offset = (this->count[0] >> 3) & 63;
00271 const uint32 nbits = (uint32)(nbytes << 3);
00272
00273 if (nbytes <= 0) return;
00274
00275
00276 this->count[1] += (uint32)(nbytes >> 29);
00277 this->count[0] += nbits;
00278
00279 if (this->count[0] < nbits) this->count[1]++;
00280
00281
00282 if (offset) {
00283 size_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
00284
00285 memcpy(this->buf + offset, p, copy);
00286
00287 if (offset + copy < 64) return;
00288
00289 p += copy;
00290 left -= copy;
00291 this->Process(this->buf);
00292 }
00293
00294
00295 for (; left >= 64; p += 64, left -= 64) this->Process(p);
00296
00297
00298 if (left) memcpy(this->buf, p, left);
00299 }
00300
00301 void Md5::Finish(uint8 digest[16])
00302 {
00303 static const uint8 pad[64] = {
00304 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00305 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00306 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00307 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00308 };
00309 uint8 data[8];
00310 uint i;
00311
00312
00313 for (i = 0; i < 8; ++i)
00314 data[i] = (uint8)(this->count[i >> 2] >> ((i & 3) << 3));
00315
00316
00317 this->Append(pad, ((55 - (this->count[0] >> 3)) & 63) + 1);
00318
00319 this->Append(data, 8);
00320
00321 for (i = 0; i < 16; ++i)
00322 digest[i] = (uint8)(this->abcd[i >> 2] >> ((i & 3) << 3));
00323 }