root/ext/hash/hash_md.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. Encode
  2. Decode
  3. make_digest
  4. PHP_NAMED_FUNCTION
  5. PHP_NAMED_FUNCTION
  6. PHP_MD5Init
  7. PHP_MD5Update
  8. PHP_MD5Final
  9. MD5Transform
  10. MD4Transform
  11. PHP_MD4Init
  12. PHP_MD4Update
  13. PHP_MD4Final
  14. PHP_MD2Init
  15. MD2_Transform
  16. PHP_MD2Update
  17. PHP_MD2Final

   1 /*
   2   +----------------------------------------------------------------------+
   3   | PHP Version 7                                                        |
   4   +----------------------------------------------------------------------+
   5   | Copyright (c) 1997-2016 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$ */
  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         size_t 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(), "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);
 125         } else {
 126                 make_digest(md5str, digest);
 127                 RETVAL_STRING(md5str);
 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         size_t        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(), "p|b", &arg, &arg_len, &raw_output) == FAILURE) {
 148                 return;
 149         }
 150 
 151         stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS, 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);
 172         } else {
 173                 make_digest(md5str, digest);
 174                 RETVAL_STRING(md5str);
 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         ZEND_SECURE_ZERO((unsigned char*) context, 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         ZEND_SECURE_ZERO((unsigned char*) x, 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         ZEND_SECURE_ZERO((unsigned char*) context, 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  */

/* [<][>][^][v][top][bottom][index][help] */