Annotation of embedaddon/php/ext/hash/hash_md.c, revision 1.1
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: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>