diff --git a/ext/hash/hash.c b/ext/hash/hash.c index 928ec778dcdb1..146695b580342 100644 --- a/ext/hash/hash.c +++ b/ext/hash/hash.c @@ -729,6 +729,32 @@ PHP_FUNCTION(hash_pbkdf2) } /* }}} */ +PHP_FUNCTION(hash_equals) +{ + char *known, *given, *known_given, *a, *b; + int known_len, given_len, i, k, result; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &known, &known_len, &given, &given_len) == FAILURE) { + return; + } + + known_given = (char *)emalloc(known_len + given_len); + memcpy(known_given, known, known_len); + memcpy(known_given + known_len, given, given_len); + + result = known_len - given_len; + a = known_given; + b = known_given + known_len; + + for (i = 0; i < given_len; ++i) { + result |= *a++ ^ *b++; + } + + efree(known_given); + + RETVAL_BOOL(result == 0); +} + /* Module Housekeeping */ static void php_hash_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ @@ -881,6 +907,7 @@ PHP_FUNCTION(mhash_get_block_size) } /* }}} */ + #define SALT_SIZE 8 /* {{{ proto string mhash_keygen_s2k(int hash, string input_password, string salt, int bytes) @@ -1178,6 +1205,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_mhash, 0, 0, 2) ZEND_END_ARG_INFO() #endif +ZEND_BEGIN_ARG_INFO(arginfo_hash_equals, 0) + ZEND_ARG_INFO(0, known) + ZEND_ARG_INFO(0, given) +ZEND_END_ARG_INFO() + /* }}} */ /* {{{ hash_functions[] @@ -1198,6 +1230,7 @@ const zend_function_entry hash_functions[] = { PHP_FE(hash_algos, arginfo_hash_algos) PHP_FE(hash_pbkdf2, arginfo_hash_pbkdf2) + PHP_FE(hash_equals, arginfo_hash_equals) /* BC Land */ #ifdef PHP_HASH_MD5_NOT_IN_CORE diff --git a/ext/hash/php_hash.h b/ext/hash/php_hash.h index a104522c8888d..729b4ad37db79 100644 --- a/ext/hash/php_hash.h +++ b/ext/hash/php_hash.h @@ -134,6 +134,7 @@ PHP_FUNCTION(hash_update_file); PHP_FUNCTION(hash_final); PHP_FUNCTION(hash_algos); PHP_FUNCTION(hash_pbkdf2); +PHP_FUNCTION(hash_equals); PHP_HASH_API const php_hash_ops *php_hash_fetch_ops(const char *algo, int algo_len); PHP_HASH_API void php_hash_register_algo(const char *algo, const php_hash_ops *ops);