md5.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /*
  2. EQ2Emulator: Everquest II Server Emulator
  3. Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net)
  4. This file is part of EQ2Emulator.
  5. EQ2Emulator is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. EQ2Emulator is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with EQ2Emulator. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include <string.h> /* for memcpy() */
  17. #include "../common/md5.h"
  18. #include "../common/MiscFunctions.h"
  19. #include "../common/seperator.h"
  20. MD5::MD5() {
  21. memset(pMD5, 0, 16);
  22. }
  23. MD5::MD5(const uchar* buf, uint32 len) {
  24. Generate(buf, len, pMD5);
  25. }
  26. MD5::MD5(const char* buf, uint32 len) {
  27. Generate((const uchar*) buf, len, pMD5);
  28. }
  29. MD5::MD5(const int8 buf[16]) {
  30. Set(buf);
  31. }
  32. MD5::MD5(const char* iMD5String) {
  33. Set(iMD5String);
  34. }
  35. void MD5::Generate(const char* iString) {
  36. Generate((const uchar*) iString, strlen(iString));
  37. }
  38. void MD5::Generate(const int8* buf, uint32 len) {
  39. Generate(buf, len, pMD5);
  40. }
  41. bool MD5::Set(const int8 buf[16]) {
  42. memcpy(pMD5, buf, 16);
  43. return true;
  44. }
  45. bool MD5::Set(const char* iMD5String) {
  46. char tmp[5] = { '0', 'x', 0, 0, 0 };
  47. for (int i=0; i<16; i++) {
  48. tmp[2] = iMD5String[i*2];
  49. tmp[3] = iMD5String[(i*2) + 1];
  50. if (!Seperator::IsHexNumber(tmp))
  51. return false;
  52. pMD5[i] = hextoi(tmp);
  53. }
  54. return true;
  55. }
  56. MD5::operator const char* () {
  57. snprintf(pMD5String, sizeof(pMD5String), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", pMD5[0], pMD5[1], pMD5[2], pMD5[3], pMD5[4], pMD5[5], pMD5[6], pMD5[7], pMD5[8], pMD5[9], pMD5[10], pMD5[11], pMD5[12], pMD5[13], pMD5[14], pMD5[15]);
  58. return pMD5String;
  59. }
  60. bool MD5::operator== (const MD5& iMD5) {
  61. if (memcmp(pMD5, iMD5.pMD5, 16) == 0)
  62. return true;
  63. else
  64. return false;
  65. }
  66. bool MD5::operator== (const int8* iMD5) {
  67. if (memcmp(pMD5, iMD5, 16) == 0)
  68. return true;
  69. else
  70. return false;
  71. }
  72. bool MD5::operator== (const char* iMD5String) {
  73. char tmp[5] = { '0', 'x', 0, 0, 0 };
  74. for (int i=0; i<16; i++) {
  75. tmp[2] = iMD5String[i*2];
  76. tmp[3] = iMD5String[(i*2) + 1];
  77. if (pMD5[i] != hextoi(tmp))
  78. return false;
  79. }
  80. return true;
  81. }
  82. MD5& MD5::operator= (const MD5& iMD5) {
  83. memcpy(pMD5, iMD5.pMD5, 16);
  84. return *this;
  85. }
  86. MD5* MD5::operator= (const MD5* iMD5) {
  87. memcpy(pMD5, iMD5->pMD5, 16);
  88. return this;
  89. }
  90. /* Byte-swap an array of words to little-endian. (Byte-sex independent) */
  91. void MD5::byteSwap(uint32 *buf, uint32 words) {
  92. int8 *p = (int8 *)buf;
  93. do {
  94. *buf++ = (uint32)((uint32)p[3]<<8 | p[2]) << 16 |
  95. ((uint32)p[1]<<8 | p[0]);
  96. p += 4;
  97. } while (--words);
  98. }
  99. void MD5::Generate(const int8* buf, uint32 len, int8 digest[16]) {
  100. MD5Context ctx;
  101. Init(&ctx);
  102. Update(&ctx, buf, len);
  103. Final(digest, &ctx);
  104. }
  105. /* Start MD5 accumulation. */
  106. void MD5::Init(struct MD5Context *ctx) {
  107. ctx->hash[0] = 0x67452301;
  108. ctx->hash[1] = 0xefcdab89;
  109. ctx->hash[2] = 0x98badcfe;
  110. ctx->hash[3] = 0x10325476;
  111. ctx->bytes[1] = ctx->bytes[0] = 0;
  112. }
  113. /* Update ctx to reflect the addition of another buffer full of bytes. */
  114. void MD5::Update(struct MD5Context *ctx, int8 const *buf, uint32 len) {
  115. uint32 t = ctx->bytes[0];
  116. if ((ctx->bytes[0] = t + len) < t) /* Update 64-bit byte count */
  117. ctx->bytes[1]++; /* Carry from low to high */
  118. t = 64 - (t & 0x3f); /* Bytes available in ctx->input (>= 1) */
  119. if (t > len) {
  120. memcpy((int8*)ctx->input+64-t, buf, len);
  121. return;
  122. }
  123. /* First chunk is an odd size */
  124. memcpy((int8*)ctx->input+64-t, buf, t);
  125. byteSwap(ctx->input, 16);
  126. Transform(ctx->hash, ctx->input);
  127. buf += t;
  128. len -= t;
  129. /* Process data in 64-byte chunks */
  130. while (len >= 64) {
  131. memcpy(ctx->input, buf, 64);
  132. byteSwap(ctx->input, 16);
  133. Transform(ctx->hash, ctx->input);
  134. buf += 64;
  135. len -= 64;
  136. }
  137. /* Buffer any remaining bytes of data */
  138. memcpy(ctx->input, buf, len);
  139. }
  140. /* Final wrapup - pad to 64-byte boundary with the bit pattern
  141. * 1 0* (64-bit count of bits processed, LSB-first) */
  142. void MD5::Final(int8 digest[16], MD5Context *ctx) {
  143. int count = ctx->bytes[0] & 0x3F; /* Bytes mod 64 */
  144. int8 *p = (int8*)ctx->input + count;
  145. /* Set the first byte of padding to 0x80. There is always room. */
  146. *p++ = 0x80;
  147. /* Bytes of zero padding needed to make 56 bytes (-8..55) */
  148. count = 56 - 1 - count;
  149. if (count < 0) { /* Padding forces an extra block */
  150. memset(p, 0, count+8);
  151. byteSwap(ctx->input, 16);
  152. Transform(ctx->hash, ctx->input);
  153. p = (int8*)ctx->input;
  154. count = 56;
  155. }
  156. memset(p, 0, count);
  157. byteSwap(ctx->input, 14);
  158. /* Append 8 bytes of length in *bits* and transform */
  159. ctx->input[14] = ctx->bytes[0] << 3;
  160. ctx->input[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
  161. Transform(ctx->hash, ctx->input);
  162. byteSwap(ctx->hash, 4);
  163. memcpy(digest, ctx->hash, 16);
  164. memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
  165. }
  166. /* The four core functions */
  167. #define F1(x, y, z) (z ^ (x & (y ^ z)))
  168. #define F2(x, y, z) F1(z, x, y)
  169. #define F3(x, y, z) (x ^ y ^ z)
  170. #define F4(x, y, z) (y ^ (x | ~z))
  171. /* This is the central step in the MD5 algorithm. */
  172. #define MD5STEP(f,w,x,y,z,in,s) (w += f(x,y,z)+in, w = (w<<s | w>>(32-s)) + x)
  173. /* The heart of the MD5 algorithm. */
  174. void MD5::Transform(uint32 hash[4], const uint32 input[16]) {
  175. uint32 a = hash[0], b = hash[1], c = hash[2], d = hash[3];
  176. MD5STEP(F1, a, b, c, d, input[ 0]+0xd76aa478, 7);
  177. MD5STEP(F1, d, a, b, c, input[ 1]+0xe8c7b756, 12);
  178. MD5STEP(F1, c, d, a, b, input[ 2]+0x242070db, 17);
  179. MD5STEP(F1, b, c, d, a, input[ 3]+0xc1bdceee, 22);
  180. MD5STEP(F1, a, b, c, d, input[ 4]+0xf57c0faf, 7);
  181. MD5STEP(F1, d, a, b, c, input[ 5]+0x4787c62a, 12);
  182. MD5STEP(F1, c, d, a, b, input[ 6]+0xa8304613, 17);
  183. MD5STEP(F1, b, c, d, a, input[ 7]+0xfd469501, 22);
  184. MD5STEP(F1, a, b, c, d, input[ 8]+0x698098d8, 7);
  185. MD5STEP(F1, d, a, b, c, input[ 9]+0x8b44f7af, 12);
  186. MD5STEP(F1, c, d, a, b, input[10]+0xffff5bb1, 17);
  187. MD5STEP(F1, b, c, d, a, input[11]+0x895cd7be, 22);
  188. MD5STEP(F1, a, b, c, d, input[12]+0x6b901122, 7);
  189. MD5STEP(F1, d, a, b, c, input[13]+0xfd987193, 12);
  190. MD5STEP(F1, c, d, a, b, input[14]+0xa679438e, 17);
  191. MD5STEP(F1, b, c, d, a, input[15]+0x49b40821, 22);
  192. MD5STEP(F2, a, b, c, d, input[ 1]+0xf61e2562, 5);
  193. MD5STEP(F2, d, a, b, c, input[ 6]+0xc040b340, 9);
  194. MD5STEP(F2, c, d, a, b, input[11]+0x265e5a51, 14);
  195. MD5STEP(F2, b, c, d, a, input[ 0]+0xe9b6c7aa, 20);
  196. MD5STEP(F2, a, b, c, d, input[ 5]+0xd62f105d, 5);
  197. MD5STEP(F2, d, a, b, c, input[10]+0x02441453, 9);
  198. MD5STEP(F2, c, d, a, b, input[15]+0xd8a1e681, 14);
  199. MD5STEP(F2, b, c, d, a, input[ 4]+0xe7d3fbc8, 20);
  200. MD5STEP(F2, a, b, c, d, input[ 9]+0x21e1cde6, 5);
  201. MD5STEP(F2, d, a, b, c, input[14]+0xc33707d6, 9);
  202. MD5STEP(F2, c, d, a, b, input[ 3]+0xf4d50d87, 14);
  203. MD5STEP(F2, b, c, d, a, input[ 8]+0x455a14ed, 20);
  204. MD5STEP(F2, a, b, c, d, input[13]+0xa9e3e905, 5);
  205. MD5STEP(F2, d, a, b, c, input[ 2]+0xfcefa3f8, 9);
  206. MD5STEP(F2, c, d, a, b, input[ 7]+0x676f02d9, 14);
  207. MD5STEP(F2, b, c, d, a, input[12]+0x8d2a4c8a, 20);
  208. MD5STEP(F3, a, b, c, d, input[ 5]+0xfffa3942, 4);
  209. MD5STEP(F3, d, a, b, c, input[ 8]+0x8771f681, 11);
  210. MD5STEP(F3, c, d, a, b, input[11]+0x6d9d6122, 16);
  211. MD5STEP(F3, b, c, d, a, input[14]+0xfde5380c, 23);
  212. MD5STEP(F3, a, b, c, d, input[ 1]+0xa4beea44, 4);
  213. MD5STEP(F3, d, a, b, c, input[ 4]+0x4bdecfa9, 11);
  214. MD5STEP(F3, c, d, a, b, input[ 7]+0xf6bb4b60, 16);
  215. MD5STEP(F3, b, c, d, a, input[10]+0xbebfbc70, 23);
  216. MD5STEP(F3, a, b, c, d, input[13]+0x289b7ec6, 4);
  217. MD5STEP(F3, d, a, b, c, input[ 0]+0xeaa127fa, 11);
  218. MD5STEP(F3, c, d, a, b, input[ 3]+0xd4ef3085, 16);
  219. MD5STEP(F3, b, c, d, a, input[ 6]+0x04881d05, 23);
  220. MD5STEP(F3, a, b, c, d, input[ 9]+0xd9d4d039, 4);
  221. MD5STEP(F3, d, a, b, c, input[12]+0xe6db99e5, 11);
  222. MD5STEP(F3, c, d, a, b, input[15]+0x1fa27cf8, 16);
  223. MD5STEP(F3, b, c, d, a, input[ 2]+0xc4ac5665, 23);
  224. MD5STEP(F4, a, b, c, d, input[ 0]+0xf4292244, 6);
  225. MD5STEP(F4, d, a, b, c, input[ 7]+0x432aff97, 10);
  226. MD5STEP(F4, c, d, a, b, input[14]+0xab9423a7, 15);
  227. MD5STEP(F4, b, c, d, a, input[ 5]+0xfc93a039, 21);
  228. MD5STEP(F4, a, b, c, d, input[12]+0x655b59c3, 6);
  229. MD5STEP(F4, d, a, b, c, input[ 3]+0x8f0ccc92, 10);
  230. MD5STEP(F4, c, d, a, b, input[10]+0xffeff47d, 15);
  231. MD5STEP(F4, b, c, d, a, input[ 1]+0x85845dd1, 21);
  232. MD5STEP(F4, a, b, c, d, input[ 8]+0x6fa87e4f, 6);
  233. MD5STEP(F4, d, a, b, c, input[15]+0xfe2ce6e0, 10);
  234. MD5STEP(F4, c, d, a, b, input[ 6]+0xa3014314, 15);
  235. MD5STEP(F4, b, c, d, a, input[13]+0x4e0811a1, 21);
  236. MD5STEP(F4, a, b, c, d, input[ 4]+0xf7537e82, 6);
  237. MD5STEP(F4, d, a, b, c, input[11]+0xbd3af235, 10);
  238. MD5STEP(F4, c, d, a, b, input[ 2]+0x2ad7d2bb, 15);
  239. MD5STEP(F4, b, c, d, a, input[ 9]+0xeb86d391, 21);
  240. hash[0] += a; hash[1] += b; hash[2] += c; hash[3] += d;
  241. }