root/ext/hash/hash.c

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

DEFINITIONS

This source file includes following definitions.
  1. php_hash_fetch_ops
  2. php_hash_register_algo
  3. php_hash_copy
  4. php_hash_do_hash
  5. PHP_FUNCTION
  6. PHP_FUNCTION
  7. php_hash_string_xor_char
  8. php_hash_string_xor
  9. php_hash_hmac_prep_key
  10. php_hash_hmac_round
  11. php_hash_do_hash_hmac
  12. PHP_FUNCTION
  13. PHP_FUNCTION
  14. PHP_FUNCTION
  15. PHP_FUNCTION
  16. PHP_FUNCTION
  17. PHP_FUNCTION
  18. PHP_FUNCTION
  19. PHP_FUNCTION
  20. PHP_FUNCTION
  21. PHP_FUNCTION
  22. PHP_FUNCTION
  23. php_hash_dtor
  24. PHP_MINFO_FUNCTION
  25. mhash_init
  26. PHP_FUNCTION
  27. PHP_FUNCTION
  28. PHP_FUNCTION
  29. PHP_FUNCTION
  30. PHP_FUNCTION
  31. PHP_MINIT_FUNCTION
  32. PHP_MSHUTDOWN_FUNCTION
  33. PHP_MINFO_FUNCTION

   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   | Author: Sara Golemon <pollita@php.net>                               |
  16   |         Scott MacVicar <scottmac@php.net>                            |
  17   +----------------------------------------------------------------------+
  18 */
  19 
  20 /* $Id$ */
  21 
  22 #ifdef HAVE_CONFIG_H
  23 #include "config.h"
  24 #endif
  25 
  26 #include <math.h>
  27 #include "php_hash.h"
  28 #include "ext/standard/info.h"
  29 #include "ext/standard/file.h"
  30 
  31 static int php_hash_le_hash;
  32 HashTable php_hash_hashtable;
  33 
  34 #if (PHP_MAJOR_VERSION >= 5)
  35 # define DEFAULT_CONTEXT FG(default_context)
  36 #else
  37 # define DEFAULT_CONTEXT NULL
  38 #endif
  39 
  40 #ifdef PHP_MHASH_BC
  41 struct mhash_bc_entry {
  42         char *mhash_name;
  43         char *hash_name;
  44         int value;
  45 };
  46 
  47 #define MHASH_NUM_ALGOS 34
  48 
  49 static struct mhash_bc_entry mhash_to_hash[MHASH_NUM_ALGOS] = {
  50         {"CRC32", "crc32", 0},
  51         {"MD5", "md5", 1},
  52         {"SHA1", "sha1", 2},
  53         {"HAVAL256", "haval256,3", 3},
  54         {NULL, NULL, 4},
  55         {"RIPEMD160", "ripemd160", 5},
  56         {NULL, NULL, 6},
  57         {"TIGER", "tiger192,3", 7},
  58         {"GOST", "gost", 8},
  59         {"CRC32B", "crc32b", 9},
  60         {"HAVAL224", "haval224,3", 10},
  61         {"HAVAL192", "haval192,3", 11},
  62         {"HAVAL160", "haval160,3", 12},
  63         {"HAVAL128", "haval128,3", 13},
  64         {"TIGER128", "tiger128,3", 14},
  65         {"TIGER160", "tiger160,3", 15},
  66         {"MD4", "md4", 16},
  67         {"SHA256", "sha256", 17},
  68         {"ADLER32", "adler32", 18},
  69         {"SHA224", "sha224", 19},
  70         {"SHA512", "sha512", 20},
  71         {"SHA384", "sha384", 21},
  72         {"WHIRLPOOL", "whirlpool", 22},
  73         {"RIPEMD128", "ripemd128", 23},
  74         {"RIPEMD256", "ripemd256", 24},
  75         {"RIPEMD320", "ripemd320", 25},
  76         {NULL, NULL, 26}, /* support needs to be added for snefru 128 */
  77         {"SNEFRU256", "snefru256", 27},
  78         {"MD2", "md2", 28},
  79         {"FNV132", "fnv132", 29},
  80         {"FNV1A32", "fnv1a32", 30},
  81         {"FNV164", "fnv164", 31},
  82         {"FNV1A64", "fnv1a64", 32},
  83         {"JOAAT", "joaat", 33},
  84 };
  85 #endif
  86 
  87 /* Hash Registry Access */
  88 
  89 PHP_HASH_API const php_hash_ops *php_hash_fetch_ops(const char *algo, size_t algo_len) /* {{{ */
  90 {
  91         char *lower = zend_str_tolower_dup(algo, algo_len);
  92         php_hash_ops *ops = zend_hash_str_find_ptr(&php_hash_hashtable, lower, algo_len);
  93         efree(lower);
  94 
  95         return ops;
  96 }
  97 /* }}} */
  98 
  99 PHP_HASH_API void php_hash_register_algo(const char *algo, const php_hash_ops *ops) /* {{{ */
 100 {
 101         size_t algo_len = strlen(algo);
 102         char *lower = zend_str_tolower_dup(algo, algo_len);
 103         zend_hash_str_add_ptr(&php_hash_hashtable, lower, algo_len, (void *) ops);
 104         efree(lower);
 105 }
 106 /* }}} */
 107 
 108 PHP_HASH_API int php_hash_copy(const void *ops, void *orig_context, void *dest_context) /* {{{ */
 109 {
 110         php_hash_ops *hash_ops = (php_hash_ops *)ops;
 111 
 112         memcpy(dest_context, orig_context, hash_ops->context_size);
 113         return SUCCESS;
 114 }
 115 /* }}} */
 116 
 117 /* Userspace */
 118 
 119 static void php_hash_do_hash(INTERNAL_FUNCTION_PARAMETERS, int isfilename, zend_bool raw_output_default) /* {{{ */
 120 {
 121         zend_string *digest;
 122         char *algo, *data;
 123         size_t algo_len, data_len;
 124         zend_bool raw_output = raw_output_default;
 125         const php_hash_ops *ops;
 126         void *context;
 127         php_stream *stream = NULL;
 128 
 129         if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|b", &algo, &algo_len, &data, &data_len, &raw_output) == FAILURE) {
 130                 return;
 131         }
 132 
 133         ops = php_hash_fetch_ops(algo, algo_len);
 134         if (!ops) {
 135                 php_error_docref(NULL, E_WARNING, "Unknown hashing algorithm: %s", algo);
 136                 RETURN_FALSE;
 137         }
 138         if (isfilename) {
 139                 if (CHECK_NULL_PATH(data, data_len)) {
 140                         php_error_docref(NULL, E_WARNING, "Invalid path");
 141                         RETURN_FALSE;
 142                 }
 143                 stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, DEFAULT_CONTEXT);
 144                 if (!stream) {
 145                         /* Stream will report errors opening file */
 146                         RETURN_FALSE;
 147                 }
 148         }
 149 
 150         context = emalloc(ops->context_size);
 151         ops->hash_init(context);
 152 
 153         if (isfilename) {
 154                 char buf[1024];
 155                 size_t n;
 156 
 157                 while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
 158                         ops->hash_update(context, (unsigned char *) buf, n);
 159                 }
 160                 php_stream_close(stream);
 161         } else {
 162                 ops->hash_update(context, (unsigned char *) data, data_len);
 163         }
 164 
 165         digest = zend_string_alloc(ops->digest_size, 0);
 166         ops->hash_final((unsigned char *) ZSTR_VAL(digest), context);
 167         efree(context);
 168 
 169         if (raw_output) {
 170                 ZSTR_VAL(digest)[ops->digest_size] = 0;
 171                 RETURN_NEW_STR(digest);
 172         } else {
 173                 zend_string *hex_digest = zend_string_safe_alloc(ops->digest_size, 2, 0, 0);
 174 
 175                 php_hash_bin2hex(ZSTR_VAL(hex_digest), (unsigned char *) ZSTR_VAL(digest), ops->digest_size);
 176                 ZSTR_VAL(hex_digest)[2 * ops->digest_size] = 0;
 177                 zend_string_release(digest);
 178                 RETURN_NEW_STR(hex_digest);
 179         }
 180 }
 181 /* }}} */
 182 
 183 /* {{{ proto string hash(string algo, string data[, bool raw_output = false])
 184 Generate a hash of a given input string
 185 Returns lowercase hexits by default */
 186 PHP_FUNCTION(hash)
 187 {
 188         php_hash_do_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0);
 189 }
 190 /* }}} */
 191 
 192 /* {{{ proto string hash_file(string algo, string filename[, bool raw_output = false])
 193 Generate a hash of a given file
 194 Returns lowercase hexits by default */
 195 PHP_FUNCTION(hash_file)
 196 {
 197         php_hash_do_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1, 0);
 198 }
 199 /* }}} */
 200 
 201 static inline void php_hash_string_xor_char(unsigned char *out, const unsigned char *in, const unsigned char xor_with, const int length) {
 202         int i;
 203         for (i=0; i < length; i++) {
 204                 out[i] = in[i] ^ xor_with;
 205         }
 206 }
 207 
 208 static inline void php_hash_string_xor(unsigned char *out, const unsigned char *in, const unsigned char *xor_with, const int length) {
 209         int i;
 210         for (i=0; i < length; i++) {
 211                 out[i] = in[i] ^ xor_with[i];
 212         }
 213 }
 214 
 215 static inline void php_hash_hmac_prep_key(unsigned char *K, const php_hash_ops *ops, void *context, const unsigned char *key, const size_t key_len) {
 216         memset(K, 0, ops->block_size);
 217         if (key_len > ops->block_size) {
 218                 /* Reduce the key first */
 219                 ops->hash_init(context);
 220                 ops->hash_update(context, key, key_len);
 221                 ops->hash_final(K, context);
 222         } else {
 223                 memcpy(K, key, key_len);
 224         }
 225         /* XOR the key with 0x36 to get the ipad) */
 226         php_hash_string_xor_char(K, K, 0x36, ops->block_size);
 227 }
 228 
 229 static inline void php_hash_hmac_round(unsigned char *final, const php_hash_ops *ops, void *context, const unsigned char *key, const unsigned char *data, const zend_long data_size) {
 230         ops->hash_init(context);
 231         ops->hash_update(context, key, ops->block_size);
 232         ops->hash_update(context, data, data_size);
 233         ops->hash_final(final, context);
 234 }
 235 
 236 static void php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAMETERS, int isfilename, zend_bool raw_output_default) /* {{{ */
 237 {
 238         zend_string *digest;
 239         char *algo, *data, *key;
 240         unsigned char *K;
 241         size_t algo_len, data_len, key_len;
 242         zend_bool raw_output = raw_output_default;
 243         const php_hash_ops *ops;
 244         void *context;
 245         php_stream *stream = NULL;
 246 
 247         if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|b", &algo, &algo_len, &data, &data_len,
 248                                                                                                                                   &key, &key_len, &raw_output) == FAILURE) {
 249                 return;
 250         }
 251 
 252         ops = php_hash_fetch_ops(algo, algo_len);
 253         if (!ops) {
 254                 php_error_docref(NULL, E_WARNING, "Unknown hashing algorithm: %s", algo);
 255                 RETURN_FALSE;
 256         }
 257         if (isfilename) {
 258                 if (CHECK_NULL_PATH(data, data_len)) {
 259                         php_error_docref(NULL, E_WARNING, "Invalid path");
 260                         RETURN_FALSE;
 261                 }
 262                 stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, DEFAULT_CONTEXT);
 263                 if (!stream) {
 264                         /* Stream will report errors opening file */
 265                         RETURN_FALSE;
 266                 }
 267         }
 268 
 269         context = emalloc(ops->context_size);
 270 
 271         K = emalloc(ops->block_size);
 272         digest = zend_string_alloc(ops->digest_size, 0);
 273 
 274         php_hash_hmac_prep_key(K, ops, context, (unsigned char *) key, key_len);
 275 
 276         if (isfilename) {
 277                 char buf[1024];
 278                 int n;
 279                 ops->hash_init(context);
 280                 ops->hash_update(context, K, ops->block_size);
 281                 while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
 282                         ops->hash_update(context, (unsigned char *) buf, n);
 283                 }
 284                 php_stream_close(stream);
 285                 ops->hash_final((unsigned char *) ZSTR_VAL(digest), context);
 286         } else {
 287                 php_hash_hmac_round((unsigned char *) ZSTR_VAL(digest), ops, context, K, (unsigned char *) data, data_len);
 288         }
 289 
 290         php_hash_string_xor_char(K, K, 0x6A, ops->block_size);
 291 
 292         php_hash_hmac_round((unsigned char *) ZSTR_VAL(digest), ops, context, K, (unsigned char *) ZSTR_VAL(digest), ops->digest_size);
 293 
 294         /* Zero the key */
 295         ZEND_SECURE_ZERO(K, ops->block_size);
 296         efree(K);
 297         efree(context);
 298 
 299         if (raw_output) {
 300                 ZSTR_VAL(digest)[ops->digest_size] = 0;
 301                 RETURN_NEW_STR(digest);
 302         } else {
 303                 zend_string *hex_digest = zend_string_safe_alloc(ops->digest_size, 2, 0, 0);
 304 
 305                 php_hash_bin2hex(ZSTR_VAL(hex_digest), (unsigned char *) ZSTR_VAL(digest), ops->digest_size);
 306                 ZSTR_VAL(hex_digest)[2 * ops->digest_size] = 0;
 307                 zend_string_release(digest);
 308                 RETURN_NEW_STR(hex_digest);
 309         }
 310 }
 311 /* }}} */
 312 
 313 /* {{{ proto string hash_hmac(string algo, string data, string key[, bool raw_output = false])
 314 Generate a hash of a given input string with a key using HMAC
 315 Returns lowercase hexits by default */
 316 PHP_FUNCTION(hash_hmac)
 317 {
 318         php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0);
 319 }
 320 /* }}} */
 321 
 322 /* {{{ proto string hash_hmac_file(string algo, string filename, string key[, bool raw_output = false])
 323 Generate a hash of a given file with a key using HMAC
 324 Returns lowercase hexits by default */
 325 PHP_FUNCTION(hash_hmac_file)
 326 {
 327         php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1, 0);
 328 }
 329 /* }}} */
 330 
 331 
 332 /* {{{ proto resource hash_init(string algo[, int options, string key])
 333 Initialize a hashing context */
 334 PHP_FUNCTION(hash_init)
 335 {
 336         char *algo, *key = NULL;
 337         size_t algo_len, key_len = 0;
 338         int argc = ZEND_NUM_ARGS();
 339         zend_long options = 0;
 340         void *context;
 341         const php_hash_ops *ops;
 342         php_hash_data *hash;
 343 
 344         if (zend_parse_parameters(argc, "s|ls", &algo, &algo_len, &options, &key, &key_len) == FAILURE) {
 345                 return;
 346         }
 347 
 348         ops = php_hash_fetch_ops(algo, algo_len);
 349         if (!ops) {
 350                 php_error_docref(NULL, E_WARNING, "Unknown hashing algorithm: %s", algo);
 351                 RETURN_FALSE;
 352         }
 353 
 354         if (options & PHP_HASH_HMAC &&
 355                 key_len <= 0) {
 356                 /* Note: a zero length key is no key at all */
 357                 php_error_docref(NULL, E_WARNING, "HMAC requested without a key");
 358                 RETURN_FALSE;
 359         }
 360 
 361         context = emalloc(ops->context_size);
 362         ops->hash_init(context);
 363 
 364         hash = emalloc(sizeof(php_hash_data));
 365         hash->ops = ops;
 366         hash->context = context;
 367         hash->options = options;
 368         hash->key = NULL;
 369 
 370         if (options & PHP_HASH_HMAC) {
 371                 char *K = emalloc(ops->block_size);
 372                 int i;
 373 
 374                 memset(K, 0, ops->block_size);
 375 
 376                 if (key_len > ops->block_size) {
 377                         /* Reduce the key first */
 378                         ops->hash_update(context, (unsigned char *) key, key_len);
 379                         ops->hash_final((unsigned char *) K, context);
 380                         /* Make the context ready to start over */
 381                         ops->hash_init(context);
 382                 } else {
 383                         memcpy(K, key, key_len);
 384                 }
 385 
 386                 /* XOR ipad */
 387                 for(i=0; i < ops->block_size; i++) {
 388                         K[i] ^= 0x36;
 389                 }
 390                 ops->hash_update(context, (unsigned char *) K, ops->block_size);
 391                 hash->key = (unsigned char *) K;
 392         }
 393 
 394         RETURN_RES(zend_register_resource(hash, php_hash_le_hash));
 395 }
 396 /* }}} */
 397 
 398 /* {{{ proto bool hash_update(resource context, string data)
 399 Pump data into the hashing algorithm */
 400 PHP_FUNCTION(hash_update)
 401 {
 402         zval *zhash;
 403         php_hash_data *hash;
 404         char *data;
 405         size_t data_len;
 406 
 407         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &zhash, &data, &data_len) == FAILURE) {
 408                 return;
 409         }
 410 
 411         if ((hash = (php_hash_data *)zend_fetch_resource(Z_RES_P(zhash), PHP_HASH_RESNAME, php_hash_le_hash)) == NULL) {
 412                 RETURN_FALSE;
 413         }
 414 
 415         hash->ops->hash_update(hash->context, (unsigned char *) data, data_len);
 416 
 417         RETURN_TRUE;
 418 }
 419 /* }}} */
 420 
 421 /* {{{ proto int hash_update_stream(resource context, resource handle[, integer length])
 422 Pump data into the hashing algorithm from an open stream */
 423 PHP_FUNCTION(hash_update_stream)
 424 {
 425         zval *zhash, *zstream;
 426         php_hash_data *hash;
 427         php_stream *stream = NULL;
 428         zend_long length = -1, didread = 0;
 429 
 430         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr|l", &zhash, &zstream, &length) == FAILURE) {
 431                 return;
 432         }
 433 
 434         if ((hash = (php_hash_data *)zend_fetch_resource(Z_RES_P(zhash), PHP_HASH_RESNAME, php_hash_le_hash)) == NULL) {
 435                 RETURN_FALSE;
 436         }
 437 
 438         php_stream_from_zval(stream, zstream);
 439 
 440         while (length) {
 441                 char buf[1024];
 442                 zend_long n, toread = 1024;
 443 
 444                 if (length > 0 && toread > length) {
 445                         toread = length;
 446                 }
 447 
 448                 if ((n = php_stream_read(stream, buf, toread)) <= 0) {
 449                         /* Nada mas */
 450                         RETURN_LONG(didread);
 451                 }
 452                 hash->ops->hash_update(hash->context, (unsigned char *) buf, n);
 453                 length -= n;
 454                 didread += n;
 455         }
 456 
 457         RETURN_LONG(didread);
 458 }
 459 /* }}} */
 460 
 461 /* {{{ proto bool hash_update_file(resource context, string filename[, resource context])
 462 Pump data into the hashing algorithm from a file */
 463 PHP_FUNCTION(hash_update_file)
 464 {
 465         zval *zhash, *zcontext = NULL;
 466         php_hash_data *hash;
 467         php_stream_context *context;
 468         php_stream *stream;
 469         char *filename, buf[1024];
 470         size_t filename_len, n;
 471 
 472         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rp|r", &zhash, &filename, &filename_len, &zcontext) == FAILURE) {
 473                 return;
 474         }
 475 
 476         if ((hash = (php_hash_data *)zend_fetch_resource(Z_RES_P(zhash), PHP_HASH_RESNAME, php_hash_le_hash)) == NULL) {
 477                 RETURN_FALSE;
 478         }
 479         context = php_stream_context_from_zval(zcontext, 0);
 480 
 481         stream = php_stream_open_wrapper_ex(filename, "rb", REPORT_ERRORS, NULL, context);
 482         if (!stream) {
 483                 /* Stream will report errors opening file */
 484                 RETURN_FALSE;
 485         }
 486 
 487         while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
 488                 hash->ops->hash_update(hash->context, (unsigned char *) buf, n);
 489         }
 490         php_stream_close(stream);
 491 
 492         RETURN_TRUE;
 493 }
 494 /* }}} */
 495 
 496 /* {{{ proto string hash_final(resource context[, bool raw_output=false])
 497 Output resulting digest */
 498 PHP_FUNCTION(hash_final)
 499 {
 500         zval *zhash;
 501         php_hash_data *hash;
 502         zend_bool raw_output = 0;
 503         zend_string *digest;
 504         int digest_len;
 505 
 506         if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|b", &zhash, &raw_output) == FAILURE) {
 507                 return;
 508         }
 509 
 510         if ((hash = (php_hash_data *)zend_fetch_resource(Z_RES_P(zhash), PHP_HASH_RESNAME, php_hash_le_hash)) == NULL) {
 511                 RETURN_FALSE;
 512         }
 513 
 514         digest_len = hash->ops->digest_size;
 515         digest = zend_string_alloc(digest_len, 0);
 516         hash->ops->hash_final((unsigned char *) ZSTR_VAL(digest), hash->context);
 517         if (hash->options & PHP_HASH_HMAC) {
 518                 int i;
 519 
 520                 /* Convert K to opad -- 0x6A = 0x36 ^ 0x5C */
 521                 for(i=0; i < hash->ops->block_size; i++) {
 522                         hash->key[i] ^= 0x6A;
 523                 }
 524 
 525                 /* Feed this result into the outter hash */
 526                 hash->ops->hash_init(hash->context);
 527                 hash->ops->hash_update(hash->context, hash->key, hash->ops->block_size);
 528                 hash->ops->hash_update(hash->context, (unsigned char *) ZSTR_VAL(digest), hash->ops->digest_size);
 529                 hash->ops->hash_final((unsigned char *) ZSTR_VAL(digest), hash->context);
 530 
 531                 /* Zero the key */
 532                 ZEND_SECURE_ZERO(hash->key, hash->ops->block_size);
 533                 efree(hash->key);
 534                 hash->key = NULL;
 535         }
 536         ZSTR_VAL(digest)[digest_len] = 0;
 537         efree(hash->context);
 538         hash->context = NULL;
 539         zend_list_close(Z_RES_P(zhash));
 540 
 541         if (raw_output) {
 542                 RETURN_NEW_STR(digest);
 543         } else {
 544                 zend_string *hex_digest = zend_string_safe_alloc(digest_len, 2, 0, 0);
 545 
 546                 php_hash_bin2hex(ZSTR_VAL(hex_digest), (unsigned char *) ZSTR_VAL(digest), digest_len);
 547                 ZSTR_VAL(hex_digest)[2 * digest_len] = 0;
 548                 zend_string_release(digest);
 549                 RETURN_NEW_STR(hex_digest);
 550         }
 551 }
 552 /* }}} */
 553 
 554 /* {{{ proto resource hash_copy(resource context)
 555 Copy hash resource */
 556 PHP_FUNCTION(hash_copy)
 557 {
 558         zval *zhash;
 559         php_hash_data *hash, *copy_hash;
 560         void *context;
 561         int res;
 562 
 563         if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zhash) == FAILURE) {
 564                 return;
 565         }
 566 
 567         if ((hash = (php_hash_data *)zend_fetch_resource(Z_RES_P(zhash), PHP_HASH_RESNAME, php_hash_le_hash)) == NULL) {
 568                 RETURN_FALSE;
 569         }
 570 
 571 
 572         context = emalloc(hash->ops->context_size);
 573         hash->ops->hash_init(context);
 574 
 575         res = hash->ops->hash_copy(hash->ops, hash->context, context);
 576         if (res != SUCCESS) {
 577                 efree(context);
 578                 RETURN_FALSE;
 579         }
 580 
 581         copy_hash = emalloc(sizeof(php_hash_data));
 582         copy_hash->ops = hash->ops;
 583         copy_hash->context = context;
 584         copy_hash->options = hash->options;
 585         copy_hash->key = ecalloc(1, hash->ops->block_size);
 586         if (hash->key) {
 587                 memcpy(copy_hash->key, hash->key, hash->ops->block_size);
 588         }
 589         RETURN_RES(zend_register_resource(copy_hash, php_hash_le_hash));
 590 }
 591 /* }}} */
 592 
 593 /* {{{ proto array hash_algos(void)
 594 Return a list of registered hashing algorithms */
 595 PHP_FUNCTION(hash_algos)
 596 {
 597         zend_string *str;
 598 
 599         array_init(return_value);
 600         ZEND_HASH_FOREACH_STR_KEY(&php_hash_hashtable, str) {
 601                 add_next_index_str(return_value, zend_string_copy(str));
 602         } ZEND_HASH_FOREACH_END();
 603 }
 604 /* }}} */
 605 
 606 /* {{{ proto string hash_pbkdf2(string algo, string password, string salt, int iterations [, int length = 0, bool raw_output = false])
 607 Generate a PBKDF2 hash of the given password and salt
 608 Returns lowercase hexits by default */
 609 PHP_FUNCTION(hash_pbkdf2)
 610 {
 611         zend_string *returnval;
 612         char *algo, *salt, *pass = NULL;
 613         unsigned char *computed_salt, *digest, *temp, *result, *K1, *K2 = NULL;
 614         zend_long loops, i, j, iterations, digest_length = 0, length = 0;
 615         size_t algo_len, pass_len, salt_len = 0;
 616         zend_bool raw_output = 0;
 617         const php_hash_ops *ops;
 618         void *context;
 619 
 620         if (zend_parse_parameters(ZEND_NUM_ARGS(), "sssl|lb", &algo, &algo_len, &pass, &pass_len, &salt, &salt_len, &iterations, &length, &raw_output) == FAILURE) {
 621                 return;
 622         }
 623 
 624         ops = php_hash_fetch_ops(algo, algo_len);
 625         if (!ops) {
 626                 php_error_docref(NULL, E_WARNING, "Unknown hashing algorithm: %s", algo);
 627                 RETURN_FALSE;
 628         }
 629 
 630         if (iterations <= 0) {
 631                 php_error_docref(NULL, E_WARNING, "Iterations must be a positive integer: " ZEND_LONG_FMT, iterations);
 632                 RETURN_FALSE;
 633         }
 634 
 635         if (length < 0) {
 636                 php_error_docref(NULL, E_WARNING, "Length must be greater than or equal to 0: " ZEND_LONG_FMT, length);
 637                 RETURN_FALSE;
 638         }
 639 
 640         if (salt_len > INT_MAX - 4) {
 641                 php_error_docref(NULL, E_WARNING, "Supplied salt is too long, max of INT_MAX - 4 bytes: %zd supplied", salt_len);
 642                 RETURN_FALSE;
 643         }
 644 
 645         context = emalloc(ops->context_size);
 646         ops->hash_init(context);
 647 
 648         K1 = emalloc(ops->block_size);
 649         K2 = emalloc(ops->block_size);
 650         digest = emalloc(ops->digest_size);
 651         temp = emalloc(ops->digest_size);
 652 
 653         /* Setup Keys that will be used for all hmac rounds */
 654         php_hash_hmac_prep_key(K1, ops, context, (unsigned char *) pass, pass_len);
 655         /* Convert K1 to opad -- 0x6A = 0x36 ^ 0x5C */
 656         php_hash_string_xor_char(K2, K1, 0x6A, ops->block_size);
 657 
 658         /* Setup Main Loop to build a long enough result */
 659         if (length == 0) {
 660                 length = ops->digest_size;
 661                 if (!raw_output) {
 662                         length = length * 2;
 663                 }
 664         }
 665         digest_length = length;
 666         if (!raw_output) {
 667                 digest_length = (zend_long) ceil((float) length / 2.0);
 668         }
 669 
 670         loops = (zend_long) ceil((float) digest_length / (float) ops->digest_size);
 671 
 672         result = safe_emalloc(loops, ops->digest_size, 0);
 673 
 674         computed_salt = safe_emalloc(salt_len, 1, 4);
 675         memcpy(computed_salt, (unsigned char *) salt, salt_len);
 676 
 677         for (i = 1; i <= loops; i++) {
 678                 /* digest = hash_hmac(salt + pack('N', i), password) { */
 679 
 680                 /* pack("N", i) */
 681                 computed_salt[salt_len] = (unsigned char) (i >> 24);
 682                 computed_salt[salt_len + 1] = (unsigned char) ((i & 0xFF0000) >> 16);
 683                 computed_salt[salt_len + 2] = (unsigned char) ((i & 0xFF00) >> 8);
 684                 computed_salt[salt_len + 3] = (unsigned char) (i & 0xFF);
 685 
 686                 php_hash_hmac_round(digest, ops, context, K1, computed_salt, (zend_long) salt_len + 4);
 687                 php_hash_hmac_round(digest, ops, context, K2, digest, ops->digest_size);
 688                 /* } */
 689 
 690                 /* temp = digest */
 691                 memcpy(temp, digest, ops->digest_size);
 692 
 693                 /*
 694                  * Note that the loop starting at 1 is intentional, since we've already done
 695                  * the first round of the algorithm.
 696                  */
 697                 for (j = 1; j < iterations; j++) {
 698                         /* digest = hash_hmac(digest, password) { */
 699                         php_hash_hmac_round(digest, ops, context, K1, digest, ops->digest_size);
 700                         php_hash_hmac_round(digest, ops, context, K2, digest, ops->digest_size);
 701                         /* } */
 702                         /* temp ^= digest */
 703                         php_hash_string_xor(temp, temp, digest, ops->digest_size);
 704                 }
 705                 /* result += temp */
 706                 memcpy(result + ((i - 1) * ops->digest_size), temp, ops->digest_size);
 707         }
 708         /* Zero potentially sensitive variables */
 709         ZEND_SECURE_ZERO(K1, ops->block_size);
 710         ZEND_SECURE_ZERO(K2, ops->block_size);
 711         ZEND_SECURE_ZERO(computed_salt, salt_len + 4);
 712         efree(K1);
 713         efree(K2);
 714         efree(computed_salt);
 715         efree(context);
 716         efree(digest);
 717         efree(temp);
 718 
 719         returnval = zend_string_alloc(length, 0);
 720         if (raw_output) {
 721                 memcpy(ZSTR_VAL(returnval), result, length);
 722         } else {
 723                 php_hash_bin2hex(ZSTR_VAL(returnval), result, digest_length);
 724         }
 725         ZSTR_VAL(returnval)[length] = 0;
 726         efree(result);
 727         RETURN_NEW_STR(returnval);
 728 }
 729 /* }}} */
 730 
 731 /* {{{ proto bool hash_equals(string known_string, string user_string)
 732    Compares two strings using the same time whether they're equal or not.
 733    A difference in length will leak */
 734 PHP_FUNCTION(hash_equals)
 735 {
 736         zval *known_zval, *user_zval;
 737         char *known_str, *user_str;
 738         int result = 0, j;
 739 
 740         if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &known_zval, &user_zval) == FAILURE) {
 741                 return;
 742         }
 743 
 744         /* We only allow comparing string to prevent unexpected results. */
 745         if (Z_TYPE_P(known_zval) != IS_STRING) {
 746                 php_error_docref(NULL, E_WARNING, "Expected known_string to be a string, %s given", zend_zval_type_name(known_zval));
 747                 RETURN_FALSE;
 748         }
 749 
 750         if (Z_TYPE_P(user_zval) != IS_STRING) {
 751                 php_error_docref(NULL, E_WARNING, "Expected user_string to be a string, %s given", zend_zval_type_name(user_zval));
 752                 RETURN_FALSE;
 753         }
 754 
 755         if (Z_STRLEN_P(known_zval) != Z_STRLEN_P(user_zval)) {
 756                 RETURN_FALSE;
 757         }
 758 
 759         known_str = Z_STRVAL_P(known_zval);
 760         user_str = Z_STRVAL_P(user_zval);
 761 
 762         /* This is security sensitive code. Do not optimize this for speed. */
 763         for (j = 0; j < Z_STRLEN_P(known_zval); j++) {
 764                 result |= known_str[j] ^ user_str[j];
 765         }
 766 
 767         RETURN_BOOL(0 == result);
 768 }
 769 /* }}} */
 770 
 771 /* Module Housekeeping */
 772 
 773 static void php_hash_dtor(zend_resource *rsrc) /* {{{ */
 774 {
 775         php_hash_data *hash = (php_hash_data*)rsrc->ptr;
 776 
 777         /* Just in case the algo has internally allocated resources */
 778         if (hash->context) {
 779                 unsigned char *dummy = emalloc(hash->ops->digest_size);
 780                 hash->ops->hash_final(dummy, hash->context);
 781                 efree(dummy);
 782                 efree(hash->context);
 783         }
 784 
 785         if (hash->key) {
 786                 memset(hash->key, 0, hash->ops->block_size);
 787                 efree(hash->key);
 788         }
 789         efree(hash);
 790 }
 791 /* }}} */
 792 
 793 #define PHP_HASH_HAVAL_REGISTER(p,b)    php_hash_register_algo("haval" #b "," #p , &php_hash_##p##haval##b##_ops);
 794 
 795 #ifdef PHP_MHASH_BC
 796 
 797 #if 0
 798 /* See #69823, we should not insert module into module_registry while doing startup */
 799 
 800 PHP_MINFO_FUNCTION(mhash)
 801 {
 802         php_info_print_table_start();
 803         php_info_print_table_row(2, "MHASH support", "Enabled");
 804         php_info_print_table_row(2, "MHASH API Version", "Emulated Support");
 805         php_info_print_table_end();
 806 }
 807 
 808 zend_module_entry mhash_module_entry = {
 809         STANDARD_MODULE_HEADER,
 810         "mhash",
 811         NULL,
 812         NULL,
 813         NULL,
 814         NULL,
 815         NULL,
 816         PHP_MINFO(mhash),
 817         PHP_MHASH_VERSION,
 818         STANDARD_MODULE_PROPERTIES,
 819 };
 820 #endif
 821 
 822 static void mhash_init(INIT_FUNC_ARGS)
 823 {
 824         char buf[128];
 825         int len;
 826         int algo_number = 0;
 827 
 828         for (algo_number = 0; algo_number < MHASH_NUM_ALGOS; algo_number++) {
 829                 struct mhash_bc_entry algorithm = mhash_to_hash[algo_number];
 830                 if (algorithm.mhash_name == NULL) {
 831                         continue;
 832                 }
 833 
 834                 len = slprintf(buf, 127, "MHASH_%s", algorithm.mhash_name, strlen(algorithm.mhash_name));
 835                 zend_register_long_constant(buf, len, algorithm.value, CONST_CS | CONST_PERSISTENT, module_number);
 836         }
 837 
 838         /* TODO: this cause #69823 zend_register_internal_module(&mhash_module_entry); */
 839 }
 840 
 841 /* {{{ proto string mhash(int hash, string data [, string key])
 842    Hash data with hash */
 843 PHP_FUNCTION(mhash)
 844 {
 845         zval *z_algorithm;
 846         zend_long algorithm;
 847 
 848         if (zend_parse_parameters(1, "z", &z_algorithm) == FAILURE) {
 849                 return;
 850         }
 851 
 852         algorithm = zval_get_long(z_algorithm);
 853 
 854         /* need to convert the first parameter from int constant to string algorithm name */
 855         if (algorithm >= 0 && algorithm < MHASH_NUM_ALGOS) {
 856                 struct mhash_bc_entry algorithm_lookup = mhash_to_hash[algorithm];
 857                 if (algorithm_lookup.hash_name) {
 858                         ZVAL_STRING(z_algorithm, algorithm_lookup.hash_name);
 859                 }
 860         }
 861 
 862         if (ZEND_NUM_ARGS() == 3) {
 863                 php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 1);
 864         } else if (ZEND_NUM_ARGS() == 2) {
 865                 php_hash_do_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 1);
 866         } else {
 867                 WRONG_PARAM_COUNT;
 868         }
 869 }
 870 /* }}} */
 871 
 872 /* {{{ proto string mhash_get_hash_name(int hash)
 873    Gets the name of hash */
 874 PHP_FUNCTION(mhash_get_hash_name)
 875 {
 876         zend_long algorithm;
 877 
 878         if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &algorithm) == FAILURE) {
 879                 return;
 880         }
 881 
 882         if (algorithm >= 0 && algorithm  < MHASH_NUM_ALGOS) {
 883                 struct mhash_bc_entry algorithm_lookup = mhash_to_hash[algorithm];
 884                 if (algorithm_lookup.mhash_name) {
 885                         RETURN_STRING(algorithm_lookup.mhash_name);
 886                 }
 887         }
 888         RETURN_FALSE;
 889 }
 890 /* }}} */
 891 
 892 /* {{{ proto int mhash_count(void)
 893    Gets the number of available hashes */
 894 PHP_FUNCTION(mhash_count)
 895 {
 896         if (zend_parse_parameters_none() == FAILURE) {
 897                 return;
 898         }
 899         RETURN_LONG(MHASH_NUM_ALGOS - 1);
 900 }
 901 /* }}} */
 902 
 903 /* {{{ proto int mhash_get_block_size(int hash)
 904    Gets the block size of hash */
 905 PHP_FUNCTION(mhash_get_block_size)
 906 {
 907         zend_long algorithm;
 908 
 909         if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &algorithm) == FAILURE) {
 910                 return;
 911         }
 912         RETVAL_FALSE;
 913 
 914         if (algorithm >= 0 && algorithm  < MHASH_NUM_ALGOS) {
 915                 struct mhash_bc_entry algorithm_lookup = mhash_to_hash[algorithm];
 916                 if (algorithm_lookup.mhash_name) {
 917                         const php_hash_ops *ops = php_hash_fetch_ops(algorithm_lookup.hash_name, strlen(algorithm_lookup.hash_name));
 918                         if (ops) {
 919                                 RETVAL_LONG(ops->digest_size);
 920                         }
 921                 }
 922         }
 923 }
 924 /* }}} */
 925 
 926 #define SALT_SIZE 8
 927 
 928 /* {{{ proto string mhash_keygen_s2k(int hash, string input_password, string salt, int bytes)
 929    Generates a key using hash functions */
 930 PHP_FUNCTION(mhash_keygen_s2k)
 931 {
 932         zend_long algorithm, l_bytes;
 933         int bytes;
 934         char *password, *salt;
 935         size_t password_len, salt_len;
 936         char padded_salt[SALT_SIZE];
 937 
 938         if (zend_parse_parameters(ZEND_NUM_ARGS(), "lssl", &algorithm, &password, &password_len, &salt, &salt_len, &l_bytes) == FAILURE) {
 939                 return;
 940         }
 941 
 942         bytes = (int)l_bytes;
 943         if (bytes <= 0){
 944                 php_error_docref(NULL, E_WARNING, "the byte parameter must be greater than 0");
 945                 RETURN_FALSE;
 946         }
 947 
 948         salt_len = MIN(salt_len, SALT_SIZE);
 949 
 950         memcpy(padded_salt, salt, salt_len);
 951         if (salt_len < SALT_SIZE) {
 952                 memset(padded_salt + salt_len, 0, SALT_SIZE - salt_len);
 953         }
 954         salt_len = SALT_SIZE;
 955 
 956         RETVAL_FALSE;
 957         if (algorithm >= 0 && algorithm < MHASH_NUM_ALGOS) {
 958                 struct mhash_bc_entry algorithm_lookup = mhash_to_hash[algorithm];
 959                 if (algorithm_lookup.mhash_name) {
 960                         const php_hash_ops *ops = php_hash_fetch_ops(algorithm_lookup.hash_name, strlen(algorithm_lookup.hash_name));
 961                         if (ops) {
 962                                 unsigned char null = '\0';
 963                                 void *context;
 964                                 char *key, *digest;
 965                                 int i = 0, j = 0;
 966                                 int block_size = ops->digest_size;
 967                                 int times = bytes / block_size;
 968                                 if (bytes % block_size  != 0) times++;
 969 
 970                                 context = emalloc(ops->context_size);
 971                                 ops->hash_init(context);
 972 
 973                                 key = ecalloc(1, times * block_size);
 974                                 digest = emalloc(ops->digest_size + 1);
 975 
 976                                 for (i = 0; i < times; i++) {
 977                                         ops->hash_init(context);
 978 
 979                                         for (j=0;j<i;j++) {
 980                                                 ops->hash_update(context, &null, 1);
 981                                         }
 982                                         ops->hash_update(context, (unsigned char *)padded_salt, salt_len);
 983                                         ops->hash_update(context, (unsigned char *)password, password_len);
 984                                         ops->hash_final((unsigned char *)digest, context);
 985                                         memcpy( &key[i*block_size], digest, block_size);
 986                                 }
 987 
 988                                 RETVAL_STRINGL(key, bytes);
 989                                 ZEND_SECURE_ZERO(key, bytes);
 990                                 efree(digest);
 991                                 efree(context);
 992                                 efree(key);
 993                         }
 994                 }
 995         }
 996 }
 997 /* }}} */
 998 
 999 #endif
1000 
1001 /* {{{ PHP_MINIT_FUNCTION
1002  */
1003 PHP_MINIT_FUNCTION(hash)
1004 {
1005         php_hash_le_hash = zend_register_list_destructors_ex(php_hash_dtor, NULL, PHP_HASH_RESNAME, module_number);
1006 
1007         zend_hash_init(&php_hash_hashtable, 35, NULL, NULL, 1);
1008 
1009         php_hash_register_algo("md2",                   &php_hash_md2_ops);
1010         php_hash_register_algo("md4",                   &php_hash_md4_ops);
1011         php_hash_register_algo("md5",                   &php_hash_md5_ops);
1012         php_hash_register_algo("sha1",                  &php_hash_sha1_ops);
1013         php_hash_register_algo("sha224",                &php_hash_sha224_ops);
1014         php_hash_register_algo("sha256",                &php_hash_sha256_ops);
1015         php_hash_register_algo("sha384",                &php_hash_sha384_ops);
1016         php_hash_register_algo("sha512",                &php_hash_sha512_ops);
1017         php_hash_register_algo("ripemd128",             &php_hash_ripemd128_ops);
1018         php_hash_register_algo("ripemd160",             &php_hash_ripemd160_ops);
1019         php_hash_register_algo("ripemd256",             &php_hash_ripemd256_ops);
1020         php_hash_register_algo("ripemd320",             &php_hash_ripemd320_ops);
1021         php_hash_register_algo("whirlpool",             &php_hash_whirlpool_ops);
1022         php_hash_register_algo("tiger128,3",    &php_hash_3tiger128_ops);
1023         php_hash_register_algo("tiger160,3",    &php_hash_3tiger160_ops);
1024         php_hash_register_algo("tiger192,3",    &php_hash_3tiger192_ops);
1025         php_hash_register_algo("tiger128,4",    &php_hash_4tiger128_ops);
1026         php_hash_register_algo("tiger160,4",    &php_hash_4tiger160_ops);
1027         php_hash_register_algo("tiger192,4",    &php_hash_4tiger192_ops);
1028         php_hash_register_algo("snefru",                &php_hash_snefru_ops);
1029         php_hash_register_algo("snefru256",             &php_hash_snefru_ops);
1030         php_hash_register_algo("gost",                  &php_hash_gost_ops);
1031         php_hash_register_algo("gost-crypto",           &php_hash_gost_crypto_ops);
1032         php_hash_register_algo("adler32",               &php_hash_adler32_ops);
1033         php_hash_register_algo("crc32",                 &php_hash_crc32_ops);
1034         php_hash_register_algo("crc32b",                &php_hash_crc32b_ops);
1035         php_hash_register_algo("fnv132",                &php_hash_fnv132_ops);
1036         php_hash_register_algo("fnv1a32",               &php_hash_fnv1a32_ops);
1037         php_hash_register_algo("fnv164",                &php_hash_fnv164_ops);
1038         php_hash_register_algo("fnv1a64",               &php_hash_fnv1a64_ops);
1039         php_hash_register_algo("joaat",                 &php_hash_joaat_ops);
1040 
1041         PHP_HASH_HAVAL_REGISTER(3,128);
1042         PHP_HASH_HAVAL_REGISTER(3,160);
1043         PHP_HASH_HAVAL_REGISTER(3,192);
1044         PHP_HASH_HAVAL_REGISTER(3,224);
1045         PHP_HASH_HAVAL_REGISTER(3,256);
1046 
1047         PHP_HASH_HAVAL_REGISTER(4,128);
1048         PHP_HASH_HAVAL_REGISTER(4,160);
1049         PHP_HASH_HAVAL_REGISTER(4,192);
1050         PHP_HASH_HAVAL_REGISTER(4,224);
1051         PHP_HASH_HAVAL_REGISTER(4,256);
1052 
1053         PHP_HASH_HAVAL_REGISTER(5,128);
1054         PHP_HASH_HAVAL_REGISTER(5,160);
1055         PHP_HASH_HAVAL_REGISTER(5,192);
1056         PHP_HASH_HAVAL_REGISTER(5,224);
1057         PHP_HASH_HAVAL_REGISTER(5,256);
1058 
1059         REGISTER_LONG_CONSTANT("HASH_HMAC",             PHP_HASH_HMAC,  CONST_CS | CONST_PERSISTENT);
1060 
1061 #ifdef PHP_MHASH_BC
1062         mhash_init(INIT_FUNC_ARGS_PASSTHRU);
1063 #endif
1064 
1065         return SUCCESS;
1066 }
1067 /* }}} */
1068 
1069 /* {{{ PHP_MSHUTDOWN_FUNCTION
1070  */
1071 PHP_MSHUTDOWN_FUNCTION(hash)
1072 {
1073         zend_hash_destroy(&php_hash_hashtable);
1074 
1075         return SUCCESS;
1076 }
1077 /* }}} */
1078 
1079 /* {{{ PHP_MINFO_FUNCTION
1080  */
1081 PHP_MINFO_FUNCTION(hash)
1082 {
1083         char buffer[2048];
1084         zend_string *str;
1085         char *s = buffer, *e = s + sizeof(buffer);
1086 
1087         ZEND_HASH_FOREACH_STR_KEY(&php_hash_hashtable, str) {
1088                 s += slprintf(s, e - s, "%s ", ZSTR_VAL(str));
1089         } ZEND_HASH_FOREACH_END();
1090         *s = 0;
1091 
1092         php_info_print_table_start();
1093         php_info_print_table_row(2, "hash support", "enabled");
1094         php_info_print_table_row(2, "Hashing Engines", buffer);
1095         php_info_print_table_end();
1096 
1097 #ifdef PHP_MHASH_BC
1098         php_info_print_table_start();
1099         php_info_print_table_row(2, "MHASH support", "Enabled");
1100         php_info_print_table_row(2, "MHASH API Version", "Emulated Support");
1101         php_info_print_table_end();
1102 #endif
1103 
1104 }
1105 /* }}} */
1106 
1107 /* {{{ arginfo */
1108 #ifdef PHP_HASH_MD5_NOT_IN_CORE
1109 ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_md5, 0, 0, 1)
1110         ZEND_ARG_INFO(0, str)
1111         ZEND_ARG_INFO(0, raw_output)
1112 ZEND_END_ARG_INFO()
1113 
1114 ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_md5_file, 0, 0, 1)
1115         ZEND_ARG_INFO(0, filename)
1116         ZEND_ARG_INFO(0, raw_output)
1117 ZEND_END_ARG_INFO()
1118 #endif
1119 
1120 #ifdef PHP_HASH_SHA1_NOT_IN_CORE
1121 ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_sha1, 0, 0, 1)
1122         ZEND_ARG_INFO(0, str)
1123         ZEND_ARG_INFO(0, raw_output)
1124 ZEND_END_ARG_INFO()
1125 
1126 ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_sha1_file, 0, 0, 1)
1127         ZEND_ARG_INFO(0, filename)
1128         ZEND_ARG_INFO(0, raw_output)
1129 ZEND_END_ARG_INFO()
1130 #endif
1131 
1132 ZEND_BEGIN_ARG_INFO_EX(arginfo_hash, 0, 0, 2)
1133         ZEND_ARG_INFO(0, algo)
1134         ZEND_ARG_INFO(0, data)
1135         ZEND_ARG_INFO(0, raw_output)
1136 ZEND_END_ARG_INFO()
1137 
1138 ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_file, 0, 0, 2)
1139         ZEND_ARG_INFO(0, algo)
1140         ZEND_ARG_INFO(0, filename)
1141         ZEND_ARG_INFO(0, raw_output)
1142 ZEND_END_ARG_INFO()
1143 
1144 ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_hmac, 0, 0, 3)
1145         ZEND_ARG_INFO(0, algo)
1146         ZEND_ARG_INFO(0, data)
1147         ZEND_ARG_INFO(0, key)
1148         ZEND_ARG_INFO(0, raw_output)
1149 ZEND_END_ARG_INFO()
1150 
1151 ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_hmac_file, 0, 0, 3)
1152         ZEND_ARG_INFO(0, algo)
1153         ZEND_ARG_INFO(0, filename)
1154         ZEND_ARG_INFO(0, key)
1155         ZEND_ARG_INFO(0, raw_output)
1156 ZEND_END_ARG_INFO()
1157 
1158 ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_init, 0, 0, 1)
1159         ZEND_ARG_INFO(0, algo)
1160         ZEND_ARG_INFO(0, options)
1161         ZEND_ARG_INFO(0, key)
1162 ZEND_END_ARG_INFO()
1163 
1164 ZEND_BEGIN_ARG_INFO(arginfo_hash_update, 0)
1165         ZEND_ARG_INFO(0, context)
1166         ZEND_ARG_INFO(0, data)
1167 ZEND_END_ARG_INFO()
1168 
1169 ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_update_stream, 0, 0, 2)
1170         ZEND_ARG_INFO(0, context)
1171         ZEND_ARG_INFO(0, handle)
1172         ZEND_ARG_INFO(0, length)
1173 ZEND_END_ARG_INFO()
1174 
1175 ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_update_file, 0, 0, 2)
1176         ZEND_ARG_INFO(0, context)
1177         ZEND_ARG_INFO(0, filename)
1178         ZEND_ARG_INFO(0, context)
1179 ZEND_END_ARG_INFO()
1180 
1181 ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_final, 0, 0, 1)
1182         ZEND_ARG_INFO(0, context)
1183         ZEND_ARG_INFO(0, raw_output)
1184 ZEND_END_ARG_INFO()
1185 
1186 ZEND_BEGIN_ARG_INFO(arginfo_hash_copy, 0)
1187         ZEND_ARG_INFO(0, context)
1188 ZEND_END_ARG_INFO()
1189 
1190 ZEND_BEGIN_ARG_INFO(arginfo_hash_algos, 0)
1191 ZEND_END_ARG_INFO()
1192 
1193 ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_pbkdf2, 0, 0, 4)
1194         ZEND_ARG_INFO(0, algo)
1195         ZEND_ARG_INFO(0, password)
1196         ZEND_ARG_INFO(0, salt)
1197         ZEND_ARG_INFO(0, iterations)
1198         ZEND_ARG_INFO(0, length)
1199         ZEND_ARG_INFO(0, raw_output)
1200 ZEND_END_ARG_INFO()
1201 
1202 ZEND_BEGIN_ARG_INFO(arginfo_hash_equals, 0)
1203         ZEND_ARG_INFO(0, known_string)
1204         ZEND_ARG_INFO(0, user_string)
1205 ZEND_END_ARG_INFO()
1206 
1207 /* BC Land */
1208 #ifdef PHP_MHASH_BC
1209 ZEND_BEGIN_ARG_INFO(arginfo_mhash_get_block_size, 0)
1210         ZEND_ARG_INFO(0, hash)
1211 ZEND_END_ARG_INFO()
1212 
1213 ZEND_BEGIN_ARG_INFO(arginfo_mhash_get_hash_name, 0)
1214         ZEND_ARG_INFO(0, hash)
1215 ZEND_END_ARG_INFO()
1216 
1217 ZEND_BEGIN_ARG_INFO(arginfo_mhash_keygen_s2k, 0)
1218         ZEND_ARG_INFO(0, hash)
1219         ZEND_ARG_INFO(0, input_password)
1220         ZEND_ARG_INFO(0, salt)
1221         ZEND_ARG_INFO(0, bytes)
1222 ZEND_END_ARG_INFO()
1223 
1224 ZEND_BEGIN_ARG_INFO(arginfo_mhash_count, 0)
1225 ZEND_END_ARG_INFO()
1226 
1227 ZEND_BEGIN_ARG_INFO_EX(arginfo_mhash, 0, 0, 2)
1228         ZEND_ARG_INFO(0, hash)
1229         ZEND_ARG_INFO(0, data)
1230         ZEND_ARG_INFO(0, key)
1231 ZEND_END_ARG_INFO()
1232 #endif
1233 
1234 /* }}} */
1235 
1236 /* {{{ hash_functions[]
1237  */
1238 const zend_function_entry hash_functions[] = {
1239         PHP_FE(hash,                                                                    arginfo_hash)
1240         PHP_FE(hash_file,                                                               arginfo_hash_file)
1241 
1242         PHP_FE(hash_hmac,                                                               arginfo_hash_hmac)
1243         PHP_FE(hash_hmac_file,                                                  arginfo_hash_hmac_file)
1244 
1245         PHP_FE(hash_init,                                                               arginfo_hash_init)
1246         PHP_FE(hash_update,                                                             arginfo_hash_update)
1247         PHP_FE(hash_update_stream,                                              arginfo_hash_update_stream)
1248         PHP_FE(hash_update_file,                                                arginfo_hash_update_file)
1249         PHP_FE(hash_final,                                                              arginfo_hash_final)
1250         PHP_FE(hash_copy,                                                               arginfo_hash_copy)
1251 
1252         PHP_FE(hash_algos,                                                              arginfo_hash_algos)
1253         PHP_FE(hash_pbkdf2,                                                             arginfo_hash_pbkdf2)
1254         PHP_FE(hash_equals,                                                             arginfo_hash_equals)
1255 
1256         /* BC Land */
1257 #ifdef PHP_HASH_MD5_NOT_IN_CORE
1258         PHP_NAMED_FE(md5, php_if_md5,                                   arginfo_hash_md5)
1259         PHP_NAMED_FE(md5_file, php_if_md5_file,                 arginfo_hash_md5_file)
1260 #endif /* PHP_HASH_MD5_NOT_IN_CORE */
1261 
1262 #ifdef PHP_HASH_SHA1_NOT_IN_CORE
1263         PHP_NAMED_FE(sha1, php_if_sha1,                                 arginfo_hash_sha1)
1264         PHP_NAMED_FE(sha1_file, php_if_sha1_file,               arginfo_hash_sha1_file)
1265 #endif /* PHP_HASH_SHA1_NOT_IN_CORE */
1266 
1267 #ifdef PHP_MHASH_BC
1268         PHP_FE(mhash_keygen_s2k, arginfo_mhash_keygen_s2k)
1269         PHP_FE(mhash_get_block_size, arginfo_mhash_get_block_size)
1270         PHP_FE(mhash_get_hash_name, arginfo_mhash_get_hash_name)
1271         PHP_FE(mhash_count, arginfo_mhash_count)
1272         PHP_FE(mhash, arginfo_mhash)
1273 #endif
1274 
1275         PHP_FE_END
1276 };
1277 /* }}} */
1278 
1279 /* {{{ hash_module_entry
1280  */
1281 zend_module_entry hash_module_entry = {
1282         STANDARD_MODULE_HEADER,
1283         PHP_HASH_EXTNAME,
1284         hash_functions,
1285         PHP_MINIT(hash),
1286         PHP_MSHUTDOWN(hash),
1287         NULL, /* RINIT */
1288         NULL, /* RSHUTDOWN */
1289         PHP_MINFO(hash),
1290         PHP_HASH_VERSION,
1291         STANDARD_MODULE_PROPERTIES
1292 };
1293 /* }}} */
1294 
1295 #ifdef COMPILE_DL_HASH
1296 ZEND_GET_MODULE(hash)
1297 #endif
1298 
1299 /*
1300  * Local variables:
1301  * tab-width: 4
1302  * c-basic-offset: 4
1303  * End:
1304  * vim600: noet sw=4 ts=4 fdm=marker
1305  * vim<600: noet sw=4 ts=4
1306  */
1307 

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