Return to hash_md.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / hash |
1.1 ! misho 1: /* ! 2: +----------------------------------------------------------------------+ ! 3: | PHP Version 5 | ! 4: +----------------------------------------------------------------------+ ! 5: | Copyright (c) 1997-2012 The PHP Group | ! 6: +----------------------------------------------------------------------+ ! 7: | This source file is subject to version 3.01 of the PHP license, | ! 8: | that is bundled with this package in the file LICENSE, and is | ! 9: | available through the world-wide-web at the following url: | ! 10: | http://www.php.net/license/3_01.txt | ! 11: | If you did not receive a copy of the PHP license and are unable to | ! 12: | obtain it through the world-wide-web, please send a note to | ! 13: | license@php.net so we can mail you a copy immediately. | ! 14: +----------------------------------------------------------------------+ ! 15: | Taken from: ext/standard/md5.c | ! 16: +----------------------------------------------------------------------+ ! 17: */ ! 18: ! 19: /* $Id: hash_md.c 321634 2012-01-01 13:15:04Z felipe $ */ ! 20: ! 21: #include "php_hash.h" ! 22: #include "php_hash_md.h" ! 23: ! 24: const php_hash_ops php_hash_md5_ops = { ! 25: (php_hash_init_func_t) PHP_MD5Init, ! 26: (php_hash_update_func_t) PHP_MD5Update, ! 27: (php_hash_final_func_t) PHP_MD5Final, ! 28: (php_hash_copy_func_t) php_hash_copy, ! 29: 16, ! 30: 64, ! 31: sizeof(PHP_MD5_CTX) ! 32: }; ! 33: ! 34: const php_hash_ops php_hash_md4_ops = { ! 35: (php_hash_init_func_t) PHP_MD4Init, ! 36: (php_hash_update_func_t) PHP_MD4Update, ! 37: (php_hash_final_func_t) PHP_MD4Final, ! 38: (php_hash_copy_func_t) php_hash_copy, ! 39: 16, ! 40: 64, ! 41: sizeof(PHP_MD4_CTX) ! 42: }; ! 43: ! 44: const php_hash_ops php_hash_md2_ops = { ! 45: (php_hash_init_func_t) PHP_MD2Init, ! 46: (php_hash_update_func_t) PHP_MD2Update, ! 47: (php_hash_final_func_t) PHP_MD2Final, ! 48: (php_hash_copy_func_t) php_hash_copy, ! 49: 16, ! 50: 16, ! 51: sizeof(PHP_MD2_CTX) ! 52: }; ! 53: ! 54: /* MD common stuff */ ! 55: ! 56: static const unsigned char PADDING[64] = ! 57: { ! 58: 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 59: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 60: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ! 61: }; ! 62: ! 63: /* {{{ Encode ! 64: Encodes input (php_hash_uint32) into output (unsigned char). Assumes len is ! 65: a multiple of 4. ! 66: */ ! 67: static void Encode(unsigned char *output, php_hash_uint32 *input, unsigned int len) ! 68: { ! 69: unsigned int i, j; ! 70: ! 71: for (i = 0, j = 0; j < len; i++, j += 4) { ! 72: output[j] = (unsigned char) (input[i] & 0xff); ! 73: output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff); ! 74: output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff); ! 75: output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff); ! 76: } ! 77: } ! 78: /* }}} */ ! 79: ! 80: /* {{{ Decode ! 81: Decodes input (unsigned char) into output (php_hash_uint32). Assumes len is ! 82: a multiple of 4. ! 83: */ ! 84: static void Decode(php_hash_uint32 *output, const unsigned char *input, unsigned int len) ! 85: { ! 86: unsigned int i, j; ! 87: ! 88: for (i = 0, j = 0; j < len; i++, j += 4) ! 89: output[i] = ((php_hash_uint32) input[j]) | (((php_hash_uint32) input[j + 1]) << 8) | ! 90: (((php_hash_uint32) input[j + 2]) << 16) | (((php_hash_uint32) input[j + 3]) << 24); ! 91: } ! 92: /* }}} */ ! 93: ! 94: #ifdef PHP_HASH_MD5_NOT_IN_CORE ! 95: ! 96: /* MD5 */ ! 97: ! 98: PHP_HASH_API void make_digest(char *md5str, unsigned char *digest) ! 99: { ! 100: php_hash_bin2hex(md5str, digest, 16); ! 101: md5str[32] = '\0'; ! 102: } ! 103: ! 104: /* {{{ proto string md5(string str, [ bool raw_output]) ! 105: Calculate the md5 hash of a string */ ! 106: PHP_NAMED_FUNCTION(php_if_md5) ! 107: { ! 108: char *arg; ! 109: int arg_len; ! 110: zend_bool raw_output = 0; ! 111: char md5str[33]; ! 112: PHP_MD5_CTX context; ! 113: unsigned char digest[16]; ! 114: ! 115: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { ! 116: return; ! 117: } ! 118: ! 119: md5str[0] = '\0'; ! 120: PHP_MD5Init(&context); ! 121: PHP_MD5Update(&context, arg, arg_len); ! 122: PHP_MD5Final(digest, &context); ! 123: if (raw_output) { ! 124: RETURN_STRINGL(digest, 16, 1); ! 125: } else { ! 126: make_digest(md5str, digest); ! 127: RETVAL_STRING(md5str, 1); ! 128: } ! 129: ! 130: } ! 131: /* }}} */ ! 132: ! 133: /* {{{ proto string md5_file(string filename [, bool raw_output]) ! 134: Calculate the md5 hash of given filename */ ! 135: PHP_NAMED_FUNCTION(php_if_md5_file) ! 136: { ! 137: char *arg; ! 138: int arg_len; ! 139: zend_bool raw_output = 0; ! 140: char md5str[33]; ! 141: unsigned char buf[1024]; ! 142: unsigned char digest[16]; ! 143: PHP_MD5_CTX context; ! 144: int n; ! 145: php_stream *stream; ! 146: ! 147: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) { ! 148: return; ! 149: } ! 150: ! 151: stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL); ! 152: if (!stream) { ! 153: RETURN_FALSE; ! 154: } ! 155: ! 156: PHP_MD5Init(&context); ! 157: ! 158: while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) { ! 159: PHP_MD5Update(&context, buf, n); ! 160: } ! 161: ! 162: PHP_MD5Final(digest, &context); ! 163: ! 164: php_stream_close(stream); ! 165: ! 166: if (n<0) { ! 167: RETURN_FALSE; ! 168: } ! 169: ! 170: if (raw_output) { ! 171: RETURN_STRINGL(digest, 16, 1); ! 172: } else { ! 173: make_digest(md5str, digest); ! 174: RETVAL_STRING(md5str, 1); ! 175: } ! 176: } ! 177: /* }}} */ ! 178: ! 179: /* ! 180: * The remaining code is the reference MD5 code (md5c.c) from rfc1321 ! 181: */ ! 182: /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm ! 183: */ ! 184: ! 185: /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All ! 186: rights reserved. ! 187: ! 188: License to copy and use this software is granted provided that it ! 189: is identified as the "RSA Data Security, Inc. MD5 Message-Digest ! 190: Algorithm" in all material mentioning or referencing this software ! 191: or this function. ! 192: ! 193: License is also granted to make and use derivative works provided ! 194: that such works are identified as "derived from the RSA Data ! 195: Security, Inc. MD5 Message-Digest Algorithm" in all material ! 196: mentioning or referencing the derived work. ! 197: ! 198: RSA Data Security, Inc. makes no representations concerning either ! 199: the merchantability of this software or the suitability of this ! 200: software for any particular purpose. It is provided "as is" ! 201: without express or implied warranty of any kind. ! 202: ! 203: These notices must be retained in any copies of any part of this ! 204: documentation and/or software. ! 205: */ ! 206: ! 207: /* Constants for MD5Transform routine. ! 208: */ ! 209: ! 210: #define S11 7 ! 211: #define S12 12 ! 212: #define S13 17 ! 213: #define S14 22 ! 214: #define S21 5 ! 215: #define S22 9 ! 216: #define S23 14 ! 217: #define S24 20 ! 218: #define S31 4 ! 219: #define S32 11 ! 220: #define S33 16 ! 221: #define S34 23 ! 222: #define S41 6 ! 223: #define S42 10 ! 224: #define S43 15 ! 225: #define S44 21 ! 226: ! 227: static void MD5Transform(php_hash_uint32[4], const unsigned char[64]); ! 228: ! 229: /* F, G, H and I are basic MD5 functions. ! 230: */ ! 231: #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) ! 232: #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) ! 233: #define H(x, y, z) ((x) ^ (y) ^ (z)) ! 234: #define I(x, y, z) ((y) ^ ((x) | (~z))) ! 235: ! 236: /* ROTATE_LEFT rotates x left n bits. ! 237: */ ! 238: #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) ! 239: ! 240: /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. ! 241: Rotation is separate from addition to prevent recomputation. ! 242: */ ! 243: #define FF(a, b, c, d, x, s, ac) { \ ! 244: (a) += F ((b), (c), (d)) + (x) + (php_hash_uint32)(ac); \ ! 245: (a) = ROTATE_LEFT ((a), (s)); \ ! 246: (a) += (b); \ ! 247: } ! 248: #define GG(a, b, c, d, x, s, ac) { \ ! 249: (a) += G ((b), (c), (d)) + (x) + (php_hash_uint32)(ac); \ ! 250: (a) = ROTATE_LEFT ((a), (s)); \ ! 251: (a) += (b); \ ! 252: } ! 253: #define HH(a, b, c, d, x, s, ac) { \ ! 254: (a) += H ((b), (c), (d)) + (x) + (php_hash_uint32)(ac); \ ! 255: (a) = ROTATE_LEFT ((a), (s)); \ ! 256: (a) += (b); \ ! 257: } ! 258: #define II(a, b, c, d, x, s, ac) { \ ! 259: (a) += I ((b), (c), (d)) + (x) + (php_hash_uint32)(ac); \ ! 260: (a) = ROTATE_LEFT ((a), (s)); \ ! 261: (a) += (b); \ ! 262: } ! 263: ! 264: /* {{{ PHP_MD5Init ! 265: * MD5 initialization. Begins an MD5 operation, writing a new context. ! 266: */ ! 267: PHP_HASH_API void PHP_MD5Init(PHP_MD5_CTX * context) ! 268: { ! 269: context->count[0] = context->count[1] = 0; ! 270: /* Load magic initialization constants. ! 271: */ ! 272: context->state[0] = 0x67452301; ! 273: context->state[1] = 0xefcdab89; ! 274: context->state[2] = 0x98badcfe; ! 275: context->state[3] = 0x10325476; ! 276: } ! 277: /* }}} */ ! 278: ! 279: /* {{{ PHP_MD5Update ! 280: MD5 block update operation. Continues an MD5 message-digest ! 281: operation, processing another message block, and updating the ! 282: context. ! 283: */ ! 284: PHP_HASH_API void PHP_MD5Update(PHP_MD5_CTX * context, const unsigned char *input, ! 285: unsigned int inputLen) ! 286: { ! 287: unsigned int i, index, partLen; ! 288: ! 289: /* Compute number of bytes mod 64 */ ! 290: index = (unsigned int) ((context->count[0] >> 3) & 0x3F); ! 291: ! 292: /* Update number of bits */ ! 293: if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) ! 294: < ((php_hash_uint32) inputLen << 3)) ! 295: context->count[1]++; ! 296: context->count[1] += ((php_hash_uint32) inputLen >> 29); ! 297: ! 298: partLen = 64 - index; ! 299: ! 300: /* Transform as many times as possible. ! 301: */ ! 302: if (inputLen >= partLen) { ! 303: memcpy ! 304: ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); ! 305: MD5Transform(context->state, context->buffer); ! 306: ! 307: for (i = partLen; i + 63 < inputLen; i += 64) ! 308: MD5Transform(context->state, &input[i]); ! 309: ! 310: index = 0; ! 311: } else ! 312: i = 0; ! 313: ! 314: /* Buffer remaining input */ ! 315: memcpy ! 316: ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], ! 317: inputLen - i); ! 318: } ! 319: /* }}} */ ! 320: ! 321: /* {{{ PHP_MD5Final ! 322: MD5 finalization. Ends an MD5 message-digest operation, writing the ! 323: the message digest and zeroizing the context. ! 324: */ ! 325: PHP_HASH_API void PHP_MD5Final(unsigned char digest[16], PHP_MD5_CTX * context) ! 326: { ! 327: unsigned char bits[8]; ! 328: unsigned int index, padLen; ! 329: ! 330: /* Save number of bits */ ! 331: Encode(bits, context->count, 8); ! 332: ! 333: /* Pad out to 56 mod 64. ! 334: */ ! 335: index = (unsigned int) ((context->count[0] >> 3) & 0x3f); ! 336: padLen = (index < 56) ? (56 - index) : (120 - index); ! 337: PHP_MD5Update(context, PADDING, padLen); ! 338: ! 339: /* Append length (before padding) */ ! 340: PHP_MD5Update(context, bits, 8); ! 341: ! 342: /* Store state in digest */ ! 343: Encode(digest, context->state, 16); ! 344: ! 345: /* Zeroize sensitive information. ! 346: */ ! 347: memset((unsigned char*) context, 0, sizeof(*context)); ! 348: } ! 349: /* }}} */ ! 350: ! 351: /* {{{ MD5Transform ! 352: * MD5 basic transformation. Transforms state based on block. ! 353: */ ! 354: static void MD5Transform(state, block) ! 355: php_hash_uint32 state[4]; ! 356: const unsigned char block[64]; ! 357: { ! 358: php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; ! 359: ! 360: Decode(x, block, 64); ! 361: ! 362: /* Round 1 */ ! 363: FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */ ! 364: FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */ ! 365: FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */ ! 366: FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */ ! 367: FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */ ! 368: FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */ ! 369: FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */ ! 370: FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */ ! 371: FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */ ! 372: FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */ ! 373: FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ ! 374: FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ ! 375: FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ ! 376: FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ ! 377: FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ ! 378: FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ ! 379: ! 380: /* Round 2 */ ! 381: GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */ ! 382: GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */ ! 383: GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ ! 384: GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */ ! 385: GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */ ! 386: GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */ ! 387: GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ ! 388: GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */ ! 389: GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */ ! 390: GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ ! 391: GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */ ! 392: GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */ ! 393: GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ ! 394: GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */ ! 395: GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */ ! 396: GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ ! 397: ! 398: /* Round 3 */ ! 399: HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */ ! 400: HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */ ! 401: HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ ! 402: HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ ! 403: HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */ ! 404: HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */ ! 405: HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */ ! 406: HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ ! 407: HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ ! 408: HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */ ! 409: HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */ ! 410: HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */ ! 411: HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */ ! 412: HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ ! 413: HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ ! 414: HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */ ! 415: ! 416: /* Round 4 */ ! 417: II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */ ! 418: II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */ ! 419: II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ ! 420: II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */ ! 421: II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ ! 422: II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */ ! 423: II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ ! 424: II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */ ! 425: II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */ ! 426: II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ ! 427: II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */ ! 428: II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ ! 429: II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */ ! 430: II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ ! 431: II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */ ! 432: II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */ ! 433: ! 434: state[0] += a; ! 435: state[1] += b; ! 436: state[2] += c; ! 437: state[3] += d; ! 438: ! 439: /* Zeroize sensitive information. */ ! 440: memset((unsigned char*) x, 0, sizeof(x)); ! 441: } ! 442: /* }}} */ ! 443: ! 444: #endif /* PHP_HASH_MD5_NOT_IN_CORE */ ! 445: ! 446: /* MD4 */ ! 447: ! 448: #define MD4_F(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) ! 449: #define MD4_G(x,y,z) (((x) & ((y) | (z))) | ((y) & (z))) ! 450: #define MD4_H(x,y,z) ((x) ^ (y) ^ (z)) ! 451: ! 452: #define ROTL32(s,v) (((v) << (s)) | ((v) >> (32 - (s)))) ! 453: ! 454: #define MD4_R1(a,b,c,d,k,s) a = ROTL32(s, a + MD4_F(b,c,d) + x[k]) ! 455: #define MD4_R2(a,b,c,d,k,s) a = ROTL32(s, a + MD4_G(b,c,d) + x[k] + 0x5A827999) ! 456: #define MD4_R3(a,b,c,d,k,s) a = ROTL32(s, a + MD4_H(b,c,d) + x[k] + 0x6ED9EBA1) ! 457: ! 458: static void MD4Transform(php_hash_uint32 state[4], const unsigned char block[64]) ! 459: { ! 460: php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; ! 461: ! 462: Decode(x, block, 64); ! 463: ! 464: /* Round 1 */ ! 465: MD4_R1(a,b,c,d, 0, 3); ! 466: MD4_R1(d,a,b,c, 1, 7); ! 467: MD4_R1(c,d,a,b, 2,11); ! 468: MD4_R1(b,c,d,a, 3,19); ! 469: MD4_R1(a,b,c,d, 4, 3); ! 470: MD4_R1(d,a,b,c, 5, 7); ! 471: MD4_R1(c,d,a,b, 6,11); ! 472: MD4_R1(b,c,d,a, 7,19); ! 473: MD4_R1(a,b,c,d, 8, 3); ! 474: MD4_R1(d,a,b,c, 9, 7); ! 475: MD4_R1(c,d,a,b,10,11); ! 476: MD4_R1(b,c,d,a,11,19); ! 477: MD4_R1(a,b,c,d,12, 3); ! 478: MD4_R1(d,a,b,c,13, 7); ! 479: MD4_R1(c,d,a,b,14,11); ! 480: MD4_R1(b,c,d,a,15,19); ! 481: ! 482: /* Round 2 */ ! 483: MD4_R2(a,b,c,d, 0, 3); ! 484: MD4_R2(d,a,b,c, 4, 5); ! 485: MD4_R2(c,d,a,b, 8, 9); ! 486: MD4_R2(b,c,d,a,12,13); ! 487: MD4_R2(a,b,c,d, 1, 3); ! 488: MD4_R2(d,a,b,c, 5, 5); ! 489: MD4_R2(c,d,a,b, 9, 9); ! 490: MD4_R2(b,c,d,a,13,13); ! 491: MD4_R2(a,b,c,d, 2, 3); ! 492: MD4_R2(d,a,b,c, 6, 5); ! 493: MD4_R2(c,d,a,b,10, 9); ! 494: MD4_R2(b,c,d,a,14,13); ! 495: MD4_R2(a,b,c,d, 3, 3); ! 496: MD4_R2(d,a,b,c, 7, 5); ! 497: MD4_R2(c,d,a,b,11, 9); ! 498: MD4_R2(b,c,d,a,15,13); ! 499: ! 500: /* Round 3 */ ! 501: MD4_R3(a,b,c,d, 0, 3); ! 502: MD4_R3(d,a,b,c, 8, 9); ! 503: MD4_R3(c,d,a,b, 4,11); ! 504: MD4_R3(b,c,d,a,12,15); ! 505: MD4_R3(a,b,c,d, 2, 3); ! 506: MD4_R3(d,a,b,c,10, 9); ! 507: MD4_R3(c,d,a,b, 6,11); ! 508: MD4_R3(b,c,d,a,14,15); ! 509: MD4_R3(a,b,c,d, 1, 3); ! 510: MD4_R3(d,a,b,c, 9, 9); ! 511: MD4_R3(c,d,a,b, 5,11); ! 512: MD4_R3(b,c,d,a,13,15); ! 513: MD4_R3(a,b,c,d, 3, 3); ! 514: MD4_R3(d,a,b,c,11, 9); ! 515: MD4_R3(c,d,a,b, 7,11); ! 516: MD4_R3(b,c,d,a,15,15); ! 517: ! 518: state[0] += a; ! 519: state[1] += b; ! 520: state[2] += c; ! 521: state[3] += d; ! 522: } ! 523: ! 524: /* {{{ PHP_MD4Init ! 525: * MD4 initialization. Begins an MD4 operation, writing a new context. ! 526: */ ! 527: PHP_HASH_API void PHP_MD4Init(PHP_MD4_CTX * context) ! 528: { ! 529: context->count[0] = context->count[1] = 0; ! 530: /* Load magic initialization constants. ! 531: */ ! 532: context->state[0] = 0x67452301; ! 533: context->state[1] = 0xefcdab89; ! 534: context->state[2] = 0x98badcfe; ! 535: context->state[3] = 0x10325476; ! 536: } ! 537: /* }}} */ ! 538: ! 539: /* {{{ PHP_MD4Update ! 540: MD4 block update operation. Continues an MD4 message-digest ! 541: operation, processing another message block, and updating the ! 542: context. ! 543: */ ! 544: PHP_HASH_API void PHP_MD4Update(PHP_MD4_CTX * context, const unsigned char *input, unsigned int inputLen) ! 545: { ! 546: unsigned int i, index, partLen; ! 547: ! 548: /* Compute number of bytes mod 64 */ ! 549: index = (unsigned int) ((context->count[0] >> 3) & 0x3F); ! 550: ! 551: /* Update number of bits */ ! 552: if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) ! 553: < ((php_hash_uint32) inputLen << 3)) ! 554: context->count[1]++; ! 555: context->count[1] += ((php_hash_uint32) inputLen >> 29); ! 556: ! 557: partLen = 64 - index; ! 558: ! 559: /* Transform as many times as possible. ! 560: */ ! 561: if (inputLen >= partLen) { ! 562: memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); ! 563: MD4Transform(context->state, context->buffer); ! 564: ! 565: for (i = partLen; i + 63 < inputLen; i += 64) { ! 566: MD4Transform(context->state, &input[i]); ! 567: } ! 568: ! 569: index = 0; ! 570: } else { ! 571: i = 0; ! 572: } ! 573: ! 574: /* Buffer remaining input */ ! 575: memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i); ! 576: } ! 577: /* }}} */ ! 578: ! 579: /* {{{ PHP_MD4Final ! 580: MD4 finalization. Ends an MD4 message-digest operation, writing the ! 581: the message digest and zeroizing the context. ! 582: */ ! 583: PHP_HASH_API void PHP_MD4Final(unsigned char digest[16], PHP_MD4_CTX * context) ! 584: { ! 585: unsigned char bits[8]; ! 586: unsigned int index, padLen; ! 587: ! 588: /* Save number of bits */ ! 589: Encode(bits, context->count, 8); ! 590: ! 591: /* Pad out to 56 mod 64. ! 592: */ ! 593: index = (unsigned int) ((context->count[0] >> 3) & 0x3f); ! 594: padLen = (index < 56) ? (56 - index) : (120 - index); ! 595: PHP_MD4Update(context, PADDING, padLen); ! 596: ! 597: /* Append length (before padding) */ ! 598: PHP_MD4Update(context, bits, 8); ! 599: ! 600: /* Store state in digest */ ! 601: Encode(digest, context->state, 16); ! 602: ! 603: /* Zeroize sensitive information. ! 604: */ ! 605: memset((unsigned char*) context, 0, sizeof(*context)); ! 606: } ! 607: /* }}} */ ! 608: ! 609: /* MD2 */ ! 610: ! 611: static const unsigned char MD2_S[256] = { ! 612: 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, 19, ! 613: 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, 76, 130, 202, ! 614: 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, 138, 23, 229, 18, ! 615: 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, 245, 142, 187, 47, 238, 122, ! 616: 169, 104, 121, 145, 21, 178, 7, 63, 148, 194, 16, 137, 11, 34, 95, 33, ! 617: 128, 127, 93, 154, 90, 144, 50, 39, 53, 62, 204, 231, 191, 247, 151, 3, ! 618: 255, 25, 48, 179, 72, 165, 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, ! 619: 79, 184, 56, 210, 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, ! 620: 69, 157, 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, ! 621: 27, 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, ! 622: 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, 234, 38, ! 623: 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, 129, 77, 82, ! 624: 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, 8, 12, 189, 177, 74, ! 625: 120, 136, 149, 139, 227, 99, 232, 109, 233, 203, 213, 254, 59, 0, 29, 57, ! 626: 242, 239, 183, 14, 102, 88, 208, 228, 166, 119, 114, 248, 235, 117, 75, 10, ! 627: 49, 68, 80, 180, 143, 237, 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 }; ! 628: ! 629: PHP_HASH_API void PHP_MD2Init(PHP_MD2_CTX *context) ! 630: { ! 631: memset(context, 0, sizeof(PHP_MD2_CTX)); ! 632: } ! 633: ! 634: static void MD2_Transform(PHP_MD2_CTX *context, const unsigned char *block) ! 635: { ! 636: unsigned char i,j,t = 0; ! 637: ! 638: for(i = 0; i < 16; i++) { ! 639: context->state[16+i] = block[i]; ! 640: context->state[32+i] = (context->state[16+i] ^ context->state[i]); ! 641: } ! 642: ! 643: for(i = 0; i < 18; i++) { ! 644: for(j = 0; j < 48; j++) { ! 645: t = context->state[j] = context->state[j] ^ MD2_S[t]; ! 646: } ! 647: t += i; ! 648: } ! 649: ! 650: /* Update checksum -- must be after transform to avoid fouling up last message block */ ! 651: t = context->checksum[15]; ! 652: for(i = 0; i < 16; i++) { ! 653: t = context->checksum[i] ^= MD2_S[block[i] ^ t]; ! 654: } ! 655: } ! 656: ! 657: PHP_HASH_API void PHP_MD2Update(PHP_MD2_CTX *context, const unsigned char *buf, unsigned int len) ! 658: { ! 659: const unsigned char *p = buf, *e = buf + len; ! 660: ! 661: if (context->in_buffer) { ! 662: if (context->in_buffer + len < 16) { ! 663: /* Not enough for block, just pass into buffer */ ! 664: memcpy(context->buffer + context->in_buffer, p, len); ! 665: context->in_buffer += len; ! 666: return; ! 667: } ! 668: /* Put buffered data together with inbound for a single block */ ! 669: memcpy(context->buffer + context->in_buffer, p, 16 - context->in_buffer); ! 670: MD2_Transform(context, context->buffer); ! 671: p += 16 - context->in_buffer; ! 672: context->in_buffer = 0; ! 673: } ! 674: ! 675: /* Process as many whole blocks as remain */ ! 676: while ((p + 16) <= e) { ! 677: MD2_Transform(context, p); ! 678: p += 16; ! 679: } ! 680: ! 681: /* Copy remaining data to buffer */ ! 682: if (p < e) { ! 683: memcpy(context->buffer, p, e - p); ! 684: context->in_buffer = e - p; ! 685: } ! 686: } ! 687: ! 688: PHP_HASH_API void PHP_MD2Final(unsigned char output[16], PHP_MD2_CTX *context) ! 689: { ! 690: memset(context->buffer + context->in_buffer, 16 - context->in_buffer, 16 - context->in_buffer); ! 691: MD2_Transform(context, context->buffer); ! 692: MD2_Transform(context, context->checksum); ! 693: ! 694: memcpy(output, context->state, 16); ! 695: } ! 696: ! 697: /* ! 698: * Local variables: ! 699: * tab-width: 4 ! 700: * c-basic-offset: 4 ! 701: * End: ! 702: * vim600: sw=4 ts=4 fdm=marker ! 703: * vim<600: sw=4 ts=4 ! 704: */