|
|
1.1.1.8 ! root 1: /* ! 2: * This code implements the MD5 message-digest algorithm. ! 3: * The algorithm is due to Ron Rivest. This code was ! 4: * written by Colin Plumb in 1993, no copyright is claimed. ! 5: * This code is in the public domain; do with it what you wish. ! 6: * ! 7: * Equivalent code is available from RSA Data Security, Inc. ! 8: * This code has been tested against that, and is equivalent, ! 9: * except that you don't need to include two pages of legalese ! 10: * with every copy. ! 11: * ! 12: * To compute the message digest of a chunk of bytes, declare an ! 13: * MD5Context structure, pass it to MD5Init, call MD5Update as ! 14: * needed on buffers full of bytes, and then call MD5Final, which ! 15: * will fill a supplied 16-byte array with the digest. ! 16: */ ! 17: #include <string.h> /* for memcpy() */ ! 18: #include "md5.h" ! 19: ! 20: #ifndef HIGHFIRST ! 21: #define byteReverse(buf, len) /* Nothing */ ! 22: #else ! 23: void byteReverse(unsigned char *buf, unsigned longs); ! 24: ! 25: #ifndef ASM_MD5 ! 26: /* ! 27: * Note: this code is harmless on little-endian machines. ! 28: */ ! 29: void byteReverse(unsigned char *buf, unsigned longs) ! 30: { ! 31: uint32 t; ! 32: do { ! 33: t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | ! 34: ((unsigned) buf[1] << 8 | buf[0]); ! 35: *(uint32 *) buf = t; ! 36: buf += 4; ! 37: } while (--longs); ! 38: } ! 39: #endif ! 40: #endif ! 41: ! 42: /* ! 43: * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious ! 44: * initialization constants. ! 45: */ ! 46: void MD5Init(struct MD5Context *ctx) ! 47: { ! 48: ctx->buf[0] = 0x67452301; ! 49: ctx->buf[1] = 0xefcdab89; ! 50: ctx->buf[2] = 0x98badcfe; ! 51: ctx->buf[3] = 0x10325476; ! 52: ! 53: ctx->bits[0] = 0; ! 54: ctx->bits[1] = 0; ! 55: } ! 56: ! 57: /* ! 58: * Update context to reflect the concatenation of another buffer full ! 59: * of bytes. ! 60: */ ! 61: void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) ! 62: { ! 63: uint32 t; ! 64: ! 65: /* Update bitcount */ ! 66: ! 67: t = ctx->bits[0]; ! 68: if ((ctx->bits[0] = t + ((uint32) len << 3)) < t) ! 69: ctx->bits[1]++; /* Carry from low to high */ ! 70: ctx->bits[1] += len >> 29; ! 71: ! 72: t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ ! 73: ! 74: /* Handle any leading odd-sized chunks */ ! 75: ! 76: if (t) { ! 77: unsigned char *p = (unsigned char *) ctx->in + t; ! 78: ! 79: t = 64 - t; ! 80: if (len < t) { ! 81: memcpy(p, buf, len); ! 82: return; ! 83: } ! 84: memcpy(p, buf, t); ! 85: byteReverse(ctx->in, 16); ! 86: MD5Transform(ctx->buf, (uint32 *) ctx->in); ! 87: buf += t; ! 88: len -= t; ! 89: } ! 90: /* Process data in 64-byte chunks */ ! 91: ! 92: while (len >= 64) { ! 93: memcpy(ctx->in, buf, 64); ! 94: byteReverse(ctx->in, 16); ! 95: MD5Transform(ctx->buf, (uint32 *) ctx->in); ! 96: buf += 64; ! 97: len -= 64; ! 98: } ! 99: ! 100: /* Handle any remaining bytes of data. */ ! 101: ! 102: memcpy(ctx->in, buf, len); ! 103: } ! 104: ! 105: /* ! 106: * Final wrapup - pad to 64-byte boundary with the bit pattern ! 107: * 1 0* (64-bit count of bits processed, MSB-first) ! 108: */ ! 109: void MD5Final(unsigned char digest[16], struct MD5Context *ctx) ! 110: { ! 111: unsigned count; ! 112: unsigned char *p; ! 113: ! 114: /* Compute number of bytes mod 64 */ ! 115: count = (ctx->bits[0] >> 3) & 0x3F; ! 116: ! 117: /* Set the first char of padding to 0x80. This is safe since there is ! 118: always at least one byte free */ ! 119: p = ctx->in + count; ! 120: *p++ = 0x80; ! 121: ! 122: /* Bytes of padding needed to make 64 bytes */ ! 123: count = 64 - 1 - count; ! 124: ! 125: /* Pad out to 56 mod 64 */ ! 126: if (count < 8) { ! 127: /* Two lots of padding: Pad the first block to 64 bytes */ ! 128: memset(p, 0, count); ! 129: byteReverse(ctx->in, 16); ! 130: MD5Transform(ctx->buf, (uint32 *) ctx->in); ! 131: ! 132: /* Now fill the next block with 56 bytes */ ! 133: memset(ctx->in, 0, 56); ! 134: } else { ! 135: /* Pad block to 56 bytes */ ! 136: memset(p, 0, count - 8); ! 137: } ! 138: byteReverse(ctx->in, 14); ! 139: ! 140: /* Append length in bits and transform */ ! 141: ((uint32 *) ctx->in)[14] = ctx->bits[0]; ! 142: ((uint32 *) ctx->in)[15] = ctx->bits[1]; ! 143: ! 144: MD5Transform(ctx->buf, (uint32 *) ctx->in); ! 145: byteReverse((unsigned char *) ctx->buf, 4); ! 146: memcpy(digest, ctx->buf, 16); ! 147: memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ ! 148: } ! 149: ! 150: #ifndef ASM_MD5 ! 151: ! 152: /* The four core functions - F1 is optimized somewhat */ ! 153: ! 154: /* #define F1(x, y, z) (x & y | ~x & z) */ ! 155: #define F1(x, y, z) (z ^ (x & (y ^ z))) ! 156: #define F2(x, y, z) F1(z, x, y) ! 157: #define F3(x, y, z) (x ^ y ^ z) ! 158: #define F4(x, y, z) (y ^ (x | ~z)) ! 159: ! 160: /* This is the central step in the MD5 algorithm. */ ! 161: #ifdef __PUREC__ ! 162: #define MD5STEP(f, w, x, y, z, data, s) \ ! 163: ( w += f /*(x, y, z)*/ + data, w = w<<s | w>>(32-s), w += x ) ! 164: #else ! 165: #define MD5STEP(f, w, x, y, z, data, s) \ ! 166: ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) ! 167: #endif ! 168: ! 169: /* ! 170: * The core of the MD5 algorithm, this alters an existing MD5 hash to ! 171: * reflect the addition of 16 longwords of new data. MD5Update blocks ! 172: * the data and converts bytes into longwords for this routine. ! 173: */ ! 174: void MD5Transform(uint32 buf[4], uint32 const in[16]) ! 175: { ! 176: register uint32 a, b, c, d; ! 177: ! 178: a = buf[0]; ! 179: b = buf[1]; ! 180: c = buf[2]; ! 181: d = buf[3]; ! 182: ! 183: #ifdef __PUREC__ /* PureC Weirdness... (GG) */ ! 184: MD5STEP(F1(b,c,d), a, b, c, d, in[0] + 0xd76aa478L, 7); ! 185: MD5STEP(F1(a,b,c), d, a, b, c, in[1] + 0xe8c7b756L, 12); ! 186: MD5STEP(F1(d,a,b), c, d, a, b, in[2] + 0x242070dbL, 17); ! 187: MD5STEP(F1(c,d,a), b, c, d, a, in[3] + 0xc1bdceeeL, 22); ! 188: MD5STEP(F1(b,c,d), a, b, c, d, in[4] + 0xf57c0fafL, 7); ! 189: MD5STEP(F1(a,b,c), d, a, b, c, in[5] + 0x4787c62aL, 12); ! 190: MD5STEP(F1(d,a,b), c, d, a, b, in[6] + 0xa8304613L, 17); ! 191: MD5STEP(F1(c,d,a), b, c, d, a, in[7] + 0xfd469501L, 22); ! 192: MD5STEP(F1(b,c,d), a, b, c, d, in[8] + 0x698098d8L, 7); ! 193: MD5STEP(F1(a,b,c), d, a, b, c, in[9] + 0x8b44f7afL, 12); ! 194: MD5STEP(F1(d,a,b), c, d, a, b, in[10] + 0xffff5bb1L, 17); ! 195: MD5STEP(F1(c,d,a), b, c, d, a, in[11] + 0x895cd7beL, 22); ! 196: MD5STEP(F1(b,c,d), a, b, c, d, in[12] + 0x6b901122L, 7); ! 197: MD5STEP(F1(a,b,c), d, a, b, c, in[13] + 0xfd987193L, 12); ! 198: MD5STEP(F1(d,a,b), c, d, a, b, in[14] + 0xa679438eL, 17); ! 199: MD5STEP(F1(c,d,a), b, c, d, a, in[15] + 0x49b40821L, 22); ! 200: ! 201: MD5STEP(F2(b,c,d), a, b, c, d, in[1] + 0xf61e2562L, 5); ! 202: MD5STEP(F2(a,b,c), d, a, b, c, in[6] + 0xc040b340L, 9); ! 203: MD5STEP(F2(d,a,b), c, d, a, b, in[11] + 0x265e5a51L, 14); ! 204: MD5STEP(F2(c,d,a), b, c, d, a, in[0] + 0xe9b6c7aaL, 20); ! 205: MD5STEP(F2(b,c,d), a, b, c, d, in[5] + 0xd62f105dL, 5); ! 206: MD5STEP(F2(a,b,c), d, a, b, c, in[10] + 0x02441453L, 9); ! 207: MD5STEP(F2(d,a,b), c, d, a, b, in[15] + 0xd8a1e681L, 14); ! 208: MD5STEP(F2(c,d,a), b, c, d, a, in[4] + 0xe7d3fbc8L, 20); ! 209: MD5STEP(F2(b,c,d), a, b, c, d, in[9] + 0x21e1cde6L, 5); ! 210: MD5STEP(F2(a,b,c), d, a, b, c, in[14] + 0xc33707d6L, 9); ! 211: MD5STEP(F2(d,a,b), c, d, a, b, in[3] + 0xf4d50d87L, 14); ! 212: MD5STEP(F2(c,d,a), b, c, d, a, in[8] + 0x455a14edL, 20); ! 213: MD5STEP(F2(b,c,d), a, b, c, d, in[13] + 0xa9e3e905L, 5); ! 214: MD5STEP(F2(a,b,c), d, a, b, c, in[2] + 0xfcefa3f8L, 9); ! 215: MD5STEP(F2(d,a,b), c, d, a, b, in[7] + 0x676f02d9L, 14); ! 216: MD5STEP(F2(c,d,a), b, c, d, a, in[12] + 0x8d2a4c8aL, 20); ! 217: ! 218: MD5STEP(F3(b,c,d), a, b, c, d, in[5] + 0xfffa3942L, 4); ! 219: MD5STEP(F3(a,b,c), d, a, b, c, in[8] + 0x8771f681L, 11); ! 220: MD5STEP(F3(d,a,b), c, d, a, b, in[11] + 0x6d9d6122L, 16); ! 221: MD5STEP(F3(c,d,a), b, c, d, a, in[14] + 0xfde5380cL, 23); ! 222: MD5STEP(F3(b,c,d), a, b, c, d, in[1] + 0xa4beea44L, 4); ! 223: MD5STEP(F3(a,b,c), d, a, b, c, in[4] + 0x4bdecfa9L, 11); ! 224: MD5STEP(F3(d,a,b), c, d, a, b, in[7] + 0xf6bb4b60L, 16); ! 225: MD5STEP(F3(c,d,a), b, c, d, a, in[10] + 0xbebfbc70L, 23); ! 226: MD5STEP(F3(b,c,d), a, b, c, d, in[13] + 0x289b7ec6L, 4); ! 227: MD5STEP(F3(a,b,c), d, a, b, c, in[0] + 0xeaa127faL, 11); ! 228: MD5STEP(F3(d,a,b), c, d, a, b, in[3] + 0xd4ef3085L, 16); ! 229: MD5STEP(F3(c,d,a), b, c, d, a, in[6] + 0x04881d05L, 23); ! 230: MD5STEP(F3(b,c,d), a, b, c, d, in[9] + 0xd9d4d039L, 4); ! 231: MD5STEP(F3(a,b,c), d, a, b, c, in[12] + 0xe6db99e5L, 11); ! 232: MD5STEP(F3(d,a,b), c, d, a, b, in[15] + 0x1fa27cf8L, 16); ! 233: MD5STEP(F3(c,d,a), b, c, d, a, in[2] + 0xc4ac5665L, 23); ! 234: ! 235: MD5STEP(F4(b,c,d), a, b, c, d, in[0] + 0xf4292244L, 6); ! 236: MD5STEP(F4(a,b,c), d, a, b, c, in[7] + 0x432aff97L, 10); ! 237: MD5STEP(F4(d,a,b), c, d, a, b, in[14] + 0xab9423a7L, 15); ! 238: MD5STEP(F4(c,d,a), b, c, d, a, in[5] + 0xfc93a039L, 21); ! 239: MD5STEP(F4(b,c,d), a, b, c, d, in[12] + 0x655b59c3L, 6); ! 240: MD5STEP(F4(a,b,c), d, a, b, c, in[3] + 0x8f0ccc92L, 10); ! 241: MD5STEP(F4(d,a,b), c, d, a, b, in[10] + 0xffeff47dL, 15); ! 242: MD5STEP(F4(c,d,a), b, c, d, a, in[1] + 0x85845dd1L, 21); ! 243: MD5STEP(F4(b,c,d), a, b, c, d, in[8] + 0x6fa87e4fL, 6); ! 244: MD5STEP(F4(a,b,c), d, a, b, c, in[15] + 0xfe2ce6e0L, 10); ! 245: MD5STEP(F4(d,a,b), c, d, a, b, in[6] + 0xa3014314L, 15); ! 246: MD5STEP(F4(c,d,a), b, c, d, a, in[13] + 0x4e0811a1L, 21); ! 247: MD5STEP(F4(b,c,d), a, b, c, d, in[4] + 0xf7537e82L, 6); ! 248: MD5STEP(F4(a,b,c), d, a, b, c, in[11] + 0xbd3af235L, 10); ! 249: MD5STEP(F4(d,a,b), c, d, a, b, in[2] + 0x2ad7d2bbL, 15); ! 250: MD5STEP(F4(c,d,a), b, c, d, a, in[9] + 0xeb86d391L, 21); ! 251: #else ! 252: MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); ! 253: MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); ! 254: MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); ! 255: MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); ! 256: MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); ! 257: MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); ! 258: MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); ! 259: MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); ! 260: MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); ! 261: MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); ! 262: MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); ! 263: MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); ! 264: MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); ! 265: MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); ! 266: MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); ! 267: MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); ! 268: ! 269: MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); ! 270: MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); ! 271: MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); ! 272: MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); ! 273: MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); ! 274: MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); ! 275: MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); ! 276: MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); ! 277: MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); ! 278: MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); ! 279: MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); ! 280: MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); ! 281: MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); ! 282: MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); ! 283: MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); ! 284: MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); ! 285: ! 286: MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); ! 287: MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); ! 288: MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); ! 289: MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); ! 290: MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); ! 291: MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); ! 292: MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); ! 293: MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); ! 294: MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); ! 295: MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); ! 296: MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); ! 297: MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); ! 298: MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); ! 299: MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); ! 300: MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); ! 301: MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); ! 302: ! 303: MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); ! 304: MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); ! 305: MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); ! 306: MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); ! 307: MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); ! 308: MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); ! 309: MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); ! 310: MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); ! 311: MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); ! 312: MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); ! 313: MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); ! 314: MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); ! 315: MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); ! 316: MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); ! 317: MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); ! 318: MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); ! 319: #endif ! 320: ! 321: buf[0] += a; ! 322: buf[1] += b; ! 323: buf[2] += c; ! 324: buf[3] += d; ! 325: } ! 326: ! 327: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.