|
|
1.1.1.5 ! 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 ! 47: MD5Init(struct MD5Context *ctx) ! 48: { ! 49: ctx->buf[0] = 0x67452301; ! 50: ctx->buf[1] = 0xefcdab89; ! 51: ctx->buf[2] = 0x98badcfe; ! 52: ctx->buf[3] = 0x10325476; ! 53: ! 54: ctx->bits[0] = 0; ! 55: ctx->bits[1] = 0; ! 56: } ! 57: ! 58: /* ! 59: * Update context to reflect the concatenation of another buffer full ! 60: * of bytes. ! 61: */ ! 62: void ! 63: MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) ! 64: { ! 65: uint32 t; ! 66: ! 67: /* Update bitcount */ ! 68: ! 69: t = ctx->bits[0]; ! 70: if ((ctx->bits[0] = t + ((uint32)len << 3)) < t) ! 71: ctx->bits[1]++; /* Carry from low to high */ ! 72: ctx->bits[1] += len >> 29; ! 73: ! 74: t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ ! 75: ! 76: /* Handle any leading odd-sized chunks */ ! 77: ! 78: if ( t ) { ! 79: unsigned char *p = (unsigned char *)ctx->in + t; ! 80: ! 81: t = 64-t; ! 82: if (len < t) { ! 83: memcpy(p, buf, len); ! 84: return; ! 85: } ! 86: memcpy(p, buf, t); ! 87: byteReverse(ctx->in, 16); ! 88: MD5Transform(ctx->buf, (uint32 *)ctx->in); ! 89: buf += t; ! 90: len -= t; ! 91: } ! 92: ! 93: /* Process data in 64-byte chunks */ ! 94: ! 95: while (len >= 64) { ! 96: memcpy(ctx->in, buf, 64); ! 97: byteReverse(ctx->in, 16); ! 98: MD5Transform(ctx->buf, (uint32 *)ctx->in); ! 99: buf += 64; ! 100: len -= 64; ! 101: } ! 102: ! 103: /* Handle any remaining bytes of data. */ ! 104: ! 105: memcpy(ctx->in, buf, len); ! 106: } ! 107: ! 108: /* ! 109: * Final wrapup - pad to 64-byte boundary with the bit pattern ! 110: * 1 0* (64-bit count of bits processed, MSB-first) ! 111: */ ! 112: void ! 113: MD5Final(unsigned char digest[16], struct MD5Context *ctx) ! 114: { ! 115: unsigned count; ! 116: unsigned char *p; ! 117: ! 118: /* Compute number of bytes mod 64 */ ! 119: count = (ctx->bits[0] >> 3) & 0x3F; ! 120: ! 121: /* Set the first char of padding to 0x80. This is safe since there is ! 122: always at least one byte free */ ! 123: p = ctx->in + count; ! 124: *p++ = 0x80; ! 125: ! 126: /* Bytes of padding needed to make 64 bytes */ ! 127: count = 64 - 1 - count; ! 128: ! 129: /* Pad out to 56 mod 64 */ ! 130: if (count < 8) { ! 131: /* Two lots of padding: Pad the first block to 64 bytes */ ! 132: memset(p, 0, count); ! 133: byteReverse(ctx->in, 16); ! 134: MD5Transform(ctx->buf, (uint32 *)ctx->in); ! 135: ! 136: /* Now fill the next block with 56 bytes */ ! 137: memset(ctx->in, 0, 56); ! 138: } else { ! 139: /* Pad block to 56 bytes */ ! 140: memset(p, 0, count-8); ! 141: } ! 142: byteReverse(ctx->in, 14); ! 143: ! 144: /* Append length in bits and transform */ ! 145: ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0]; ! 146: ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1]; ! 147: ! 148: MD5Transform(ctx->buf, (uint32 *)ctx->in); ! 149: byteReverse((unsigned char *)ctx->buf, 4); ! 150: memcpy(digest, ctx->buf, 16); ! 151: memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ ! 152: } ! 153: ! 154: #ifndef ASM_MD5 ! 155: ! 156: /* The four core functions - F1 is optimized somewhat */ ! 157: ! 158: /* #define F1(x, y, z) (x & y | ~x & z) */ ! 159: #define F1(x, y, z) (z ^ (x & (y ^ z))) ! 160: #define F2(x, y, z) F1(z, x, y) ! 161: #define F3(x, y, z) (x ^ y ^ z) ! 162: #define F4(x, y, z) (y ^ (x | ~z)) ! 163: ! 164: /* This is the central step in the MD5 algorithm. */ ! 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: ! 168: /* ! 169: * The core of the MD5 algorithm, this alters an existing MD5 hash to ! 170: * reflect the addition of 16 longwords of new data. MD5Update blocks ! 171: * the data and converts bytes into longwords for this routine. ! 172: */ ! 173: void ! 174: 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: MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7); ! 184: MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12); ! 185: MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17); ! 186: MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22); ! 187: MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7); ! 188: MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12); ! 189: MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17); ! 190: MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22); ! 191: MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7); ! 192: MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12); ! 193: MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17); ! 194: MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22); ! 195: MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7); ! 196: MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12); ! 197: MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17); ! 198: MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22); ! 199: ! 200: MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5); ! 201: MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9); ! 202: MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14); ! 203: MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20); ! 204: MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5); ! 205: MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9); ! 206: MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14); ! 207: MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20); ! 208: MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5); ! 209: MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9); ! 210: MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14); ! 211: MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20); ! 212: MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5); ! 213: MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9); ! 214: MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14); ! 215: MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20); ! 216: ! 217: MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4); ! 218: MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11); ! 219: MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16); ! 220: MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23); ! 221: MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4); ! 222: MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11); ! 223: MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16); ! 224: MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23); ! 225: MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4); ! 226: MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11); ! 227: MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16); ! 228: MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23); ! 229: MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4); ! 230: MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11); ! 231: MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16); ! 232: MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23); ! 233: ! 234: MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6); ! 235: MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10); ! 236: MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15); ! 237: MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21); ! 238: MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6); ! 239: MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10); ! 240: MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15); ! 241: MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21); ! 242: MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6); ! 243: MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10); ! 244: MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15); ! 245: MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21); ! 246: MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6); ! 247: MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10); ! 248: MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15); ! 249: MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21); ! 250: ! 251: buf[0] += a; ! 252: buf[1] += b; ! 253: buf[2] += c; ! 254: buf[3] += d; ! 255: } ! 256: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.