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

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