For this purpose add is_crypto flag to php_hash_ops.
such, its behavior now follows fmod() rather than the `%` operator. For
example `bcmod('4', '3.5')` now returns '0.5' instead of '1'.
+- Hash:
+ . The hash_hmac(), hash_hmac_file() and hash_pbkdf2() functions no longer
+ accept non-cryptographic hashes.
+
- PCRE:
. preg_match() and other PCRE functions now distinguish between unmatched
subpatterns and empty matches by reporting NULL and "" (empty string),
php_error_docref(NULL, E_WARNING, "Unknown hashing algorithm: %s", algo);
RETURN_FALSE;
}
+ else if (!ops->is_crypto) {
+ php_error_docref(NULL, E_WARNING, "Non-cryptographic hashing algorithm: %s", algo);
+ RETURN_FALSE;
+ }
+
if (isfilename) {
if (CHECK_NULL_PATH(data, data_len)) {
php_error_docref(NULL, E_WARNING, "Invalid path");
}
/* }}} */
-static inline zend_bool php_hash_is_crypto(const char *algo, size_t algo_len) {
-
- char *blacklist[] = { "adler32", "crc32", "crc32b", "fnv132", "fnv1a32", "fnv164", "fnv1a64", "joaat", NULL };
- char *lower = zend_str_tolower_dup(algo, algo_len);
- int i = 0;
-
- while (blacklist[i]) {
- if (strcmp(lower, blacklist[i]) == 0) {
- efree(lower);
- return 0;
- }
-
- i++;
- }
-
- efree(lower);
- return 1;
-}
-
/* {{{ proto string hash_hkdf(string algo, string ikm [, int length = 0, string info = '', string salt = ''])
RFC5869 HMAC-based key derivation function */
PHP_FUNCTION(hash_hkdf)
php_error_docref(NULL, E_WARNING, "Unknown hashing algorithm: %s", ZSTR_VAL(algo));
RETURN_FALSE;
}
-
- if (!php_hash_is_crypto(ZSTR_VAL(algo), ZSTR_LEN(algo))) {
+
+ if (!ops->is_crypto) {
php_error_docref(NULL, E_WARNING, "Non-cryptographic hashing algorithm: %s", ZSTR_VAL(algo));
RETURN_FALSE;
}
php_error_docref(NULL, E_WARNING, "Unknown hashing algorithm: %s", algo);
RETURN_FALSE;
}
+ else if (!ops->is_crypto) {
+ php_error_docref(NULL, E_WARNING, "Non-cryptographic hashing algorithm: %s", algo);
+ RETURN_FALSE;
+ }
if (iterations <= 0) {
php_error_docref(NULL, E_WARNING, "Iterations must be a positive integer: " ZEND_LONG_FMT, iterations);
(php_hash_copy_func_t) PHP_ADLER32Copy,
4, /* what to say here? */
4,
- sizeof(PHP_ADLER32_CTX)
+ sizeof(PHP_ADLER32_CTX),
+ 0
};
/*
(php_hash_copy_func_t) PHP_CRC32Copy,
4, /* what to say here? */
4,
- sizeof(PHP_CRC32_CTX)
+ sizeof(PHP_CRC32_CTX),
+ 0
};
const php_hash_ops php_hash_crc32b_ops = {
(php_hash_copy_func_t) PHP_CRC32Copy,
4, /* what to say here? */
4,
- sizeof(PHP_CRC32_CTX)
+ sizeof(PHP_CRC32_CTX),
+ 0
};
/*
(php_hash_copy_func_t) php_hash_copy,
4,
4,
- sizeof(PHP_FNV132_CTX)
+ sizeof(PHP_FNV132_CTX),
+ 0
};
- const php_hash_ops php_hash_fnv1a32_ops = {
+const php_hash_ops php_hash_fnv1a32_ops = {
(php_hash_init_func_t) PHP_FNV132Init,
(php_hash_update_func_t) PHP_FNV1a32Update,
(php_hash_final_func_t) PHP_FNV132Final,
(php_hash_copy_func_t) php_hash_copy,
4,
4,
- sizeof(PHP_FNV132_CTX)
+ sizeof(PHP_FNV132_CTX),
+ 0
};
const php_hash_ops php_hash_fnv164_ops = {
(php_hash_copy_func_t) php_hash_copy,
8,
4,
- sizeof(PHP_FNV164_CTX)
+ sizeof(PHP_FNV164_CTX),
+ 0
};
const php_hash_ops php_hash_fnv1a64_ops = {
(php_hash_copy_func_t) php_hash_copy,
8,
4,
- sizeof(PHP_FNV164_CTX)
+ sizeof(PHP_FNV164_CTX),
+ 0
};
/* {{{ PHP_FNV132Init
(php_hash_copy_func_t) php_hash_copy,
32,
32,
- sizeof(PHP_GOST_CTX)
+ sizeof(PHP_GOST_CTX),
+ 1
};
const php_hash_ops php_hash_gost_crypto_ops = {
(php_hash_copy_func_t) php_hash_copy,
32,
32,
- sizeof(PHP_GOST_CTX)
+ sizeof(PHP_GOST_CTX),
+ 1
};
/*
(php_hash_update_func_t) PHP_HAVALUpdate, \
(php_hash_final_func_t) PHP_HAVAL##b##Final, \
(php_hash_copy_func_t) php_hash_copy, \
- ((b) / 8), 128, sizeof(PHP_HAVAL_CTX) }; \
+ ((b) / 8), 128, sizeof(PHP_HAVAL_CTX), 1 }; \
PHP_HASH_API void PHP_##p##HAVAL##b##Init(PHP_HAVAL_CTX *context) \
{ int i; context->count[0] = context->count[1] = 0; \
for(i = 0; i < 8; i++) context->state[i] = D0[i]; \
(php_hash_copy_func_t) php_hash_copy,
4,
4,
- sizeof(PHP_JOAAT_CTX)
+ sizeof(PHP_JOAAT_CTX),
+ 0
};
PHP_HASH_API void PHP_JOAATInit(PHP_JOAAT_CTX *context)
(php_hash_copy_func_t) php_hash_copy,
16,
64,
- sizeof(PHP_MD5_CTX)
+ sizeof(PHP_MD5_CTX),
+ 1
};
const php_hash_ops php_hash_md4_ops = {
(php_hash_copy_func_t) php_hash_copy,
16,
64,
- sizeof(PHP_MD4_CTX)
+ sizeof(PHP_MD4_CTX),
+ 1
};
const php_hash_ops php_hash_md2_ops = {
(php_hash_copy_func_t) php_hash_copy,
16,
16,
- sizeof(PHP_MD2_CTX)
+ sizeof(PHP_MD2_CTX),
+ 1
};
/* MD common stuff */
(php_hash_copy_func_t) php_hash_copy,
16,
64,
- sizeof(PHP_RIPEMD128_CTX)
+ sizeof(PHP_RIPEMD128_CTX),
+ 1
};
const php_hash_ops php_hash_ripemd160_ops = {
(php_hash_copy_func_t) php_hash_copy,
20,
64,
- sizeof(PHP_RIPEMD160_CTX)
+ sizeof(PHP_RIPEMD160_CTX),
+ 1
};
const php_hash_ops php_hash_ripemd256_ops = {
(php_hash_copy_func_t) php_hash_copy,
32,
64,
- sizeof(PHP_RIPEMD256_CTX)
+ sizeof(PHP_RIPEMD256_CTX),
+ 1
};
const php_hash_ops php_hash_ripemd320_ops = {
(php_hash_copy_func_t) php_hash_copy,
40,
64,
- sizeof(PHP_RIPEMD320_CTX)
+ sizeof(PHP_RIPEMD320_CTX),
+ 1
};
/* {{{ PHP_RIPEMD128Init
(php_hash_copy_func_t) php_hash_copy,
20,
64,
- sizeof(PHP_SHA1_CTX)
+ sizeof(PHP_SHA1_CTX),
+ 1
};
#ifdef PHP_HASH_SHA1_NOT_IN_CORE
(php_hash_copy_func_t) php_hash_copy,
32,
64,
- sizeof(PHP_SHA256_CTX)
+ sizeof(PHP_SHA256_CTX),
+ 1
};
const php_hash_ops php_hash_sha224_ops = {
(php_hash_copy_func_t) php_hash_copy,
28,
64,
- sizeof(PHP_SHA224_CTX)
+ sizeof(PHP_SHA224_CTX),
+ 1
};
#define ROTR32(b,x) ((x >> b) | (x << (32 - b)))
(php_hash_copy_func_t) php_hash_copy,
48,
128,
- sizeof(PHP_SHA384_CTX)
+ sizeof(PHP_SHA384_CTX),
+ 1
};
/* {{{ PHP_SHA512Init
(php_hash_copy_func_t) php_hash_copy,
64,
128,
- sizeof(PHP_SHA512_CTX)
+ sizeof(PHP_SHA512_CTX),
+ 1
};
const php_hash_ops php_hash_sha512_256_ops = {
(php_hash_copy_func_t) php_hash_copy,
32,
128,
- sizeof(PHP_SHA512_CTX)
+ sizeof(PHP_SHA512_CTX),
+ 1
};
const php_hash_ops php_hash_sha512_224_ops = {
(php_hash_copy_func_t) php_hash_copy,
28,
128,
- sizeof(PHP_SHA512_CTX)
+ sizeof(PHP_SHA512_CTX),
+ 1
};
/*
php_hash_copy, \
bits >> 3, \
(1600 - (2 * bits)) >> 3, \
- sizeof(PHP_SHA3_##bits##_CTX) \
+ sizeof(PHP_SHA3_##bits##_CTX), \
+ 1 \
}
DECLARE_SHA3_OPS(224);
(php_hash_copy_func_t) php_hash_copy,
32,
32,
- sizeof(PHP_SNEFRU_CTX)
+ sizeof(PHP_SNEFRU_CTX),
+ 1
};
/*
(php_hash_copy_func_t) php_hash_copy, \
b/8, \
64, \
- sizeof(PHP_TIGER_CTX) \
+ sizeof(PHP_TIGER_CTX), \
+ 1 \
}
PHP_HASH_TIGER_OPS(3, 128);
(php_hash_copy_func_t) php_hash_copy,
64,
64,
- sizeof(PHP_WHIRLPOOL_CTX)
+ sizeof(PHP_WHIRLPOOL_CTX),
+ 1
};
/*
int digest_size;
int block_size;
int context_size;
+ unsigned is_crypto: 1;
} php_hash_ops;
typedef struct _php_hash_data {
$content = "This is a sample string used to test the hash_hmac function with various hashing algorithms";
$key = 'secret';
-echo "adler32: " . hash_hmac('adler32', $content, $key) . "\n";
-echo "crc32: " . hash_hmac('crc32', $content, $key) . "\n";
echo "gost: " . hash_hmac('gost', $content, $key) . "\n";
echo "haval128,3: " . hash_hmac('haval128,3', $content, $key) . "\n";
echo "md2: " . hash_hmac('md2', $content, $key) . "\n";
echo "snefru: " . hash_hmac('snefru', $content, $key) . "\n";
echo "tiger192,3: " . hash_hmac('tiger192,3', $content, $key) . "\n";
echo "whirlpool: " . hash_hmac('whirlpool', $content, $key) . "\n";
-echo "adler32(raw): " . bin2hex(hash_hmac('adler32', $content, $key, TRUE)) . "\n";
echo "md5(raw): " . bin2hex(hash_hmac('md5', $content, $key, TRUE)) . "\n";
echo "sha256(raw): " . bin2hex(hash_hmac('sha256', $content, $key, TRUE)) . "\n";
===Done===
--EXPECTF--
*** Testing hash_hmac() : basic functionality ***
-adler32: 12c803f7
-crc32: 96859101
gost: a4a3c80bdf3f8665bf07376a34dc9c1b11af7c813f4928f62e39f0c0dc564dad
haval128,3: 4d1318607f0406bd1b7bd50907772672
md2: 6d111dab563025e4cb5f4425c991fa12
snefru: 67af483046f9cf16fe19f9087929ccfc6ad176ade3290b4d33f43e0ddb07e711
tiger192,3: 00a0f884f15a9e5549ed0e40ca0190522d369027e16d5b59
whirlpool: 4a0f1582b21b7aff59bfba7f9c29131c69741b2ce80acdc7d314040f3b768cf5a17e30b74cceb86fbc6b34b1692e0addd5bfd7cfc043d40c0621f1b97e26fa49
-adler32(raw): 12c803f7
md5(raw): 2a632783e2812cf23de100d7d6a463ae
sha256(raw): 49bde3496b9510a17d0edd8a4b0ac70148e32a1d51e881ec76faa96534125838
===Done===
echo "\n-- Testing hash_hmac() function with less than expected no. of arguments --\n";
var_dump(hash_hmac());
-var_dump(hash_hmac('crc32'));
-var_dump(hash_hmac('crc32', $data));
+var_dump(hash_hmac('md5'));
+var_dump(hash_hmac('md5', $data));
echo "\n-- Testing hash_hmac() function with more than expected no. of arguments --\n";
$extra_arg = 10;
-var_dump(hash_hmac('crc32', $data, $key, TRUE, $extra_arg));
+var_dump(hash_hmac('md5', $data, $key, TRUE, $extra_arg));
echo "\n-- Testing hash_hmac() function with invalid hash algorithm --\n";
var_dump(hash_hmac('foo', $data, $key));
+echo "\n-- Testing hash_hmac() function with non-cryptographic hash algorithm --\n";
+var_dump(hash_hmac('crc32', $data, $key));
+
?>
===Done===
--EXPECTF--
Warning: hash_hmac(): Unknown hashing algorithm: foo in %s on line %d
bool(false)
-===Done===
\ No newline at end of file
+
+-- Testing hash_hmac() function with non-cryptographic hash algorithm --
+
+Warning: hash_hmac(): Non-cryptographic hashing algorithm: crc32 in %s on line %d
+bool(false)
+===Done===
$key = 'secret';
-echo "adler32: " . hash_hmac_file('adler32', $file, $key) . "\n";
-echo "crc32: " . hash_hmac_file('crc32', $file, $key) . "\n";
echo "gost: " . hash_hmac_file('gost', $file, $key) . "\n";
echo "haval128,3: " . hash_hmac_file('haval128,3', $file, $key) . "\n";
echo "md2: " . hash_hmac_file('md2', $file, $key) . "\n";
echo "tiger192,3: " . hash_hmac_file('tiger192,3', $file, $key) . "\n";
echo "whirlpool: " . hash_hmac_file('whirlpool', $file, $key) . "\n";
-echo "adler32(raw): " . bin2hex(hash_hmac_file('adler32', $file, $key, TRUE)) . "\n";
echo "md5(raw): " . bin2hex(hash_hmac_file('md5', $file, $key, TRUE)). "\n";
echo "sha256(raw): " . bin2hex(hash_hmac_file('sha256', $file, $key, TRUE)). "\n";
===Done===
--EXPECTF--
*** Testing hash_hmac_file() : basic functionality ***
-adler32: 0f8c02f9
-crc32: f2a60b9c
gost: 94c39a40d5db852a8dc3d24e37eebf2d53e3d711457c59cd02b614f792a9d918
haval128,3: f1cea637451097d790354a86de3f54a3
md2: a685475e600314bb549ab4f33c3b27cb
snefru: 7b79787e1c1d926b6cc98327f05c5d04ba6227ab51c1398661861196016ef34c
tiger192,3: ca89badf843ba68e3fae5832635aa848a72a4bc11676edd4
whirlpool: 37a0fbb90547690d5e5e11c046f6654ffdb7bab15e16d9d79c7d85765cc4bdcbfd9df8db7a3ce9558f3f244fead00ca29cf05297f75596555195a0683f15d69f
-adler32(raw): 0f8c02f9
md5(raw): 8bddf39dd1c566c27acc7fa85ec36acf
sha256(raw): 9135286ca4c84dec711e4b831f6cd39e672e5ff93d011321274eb76733cc1e40
Error cases:
echo "\n-- Testing hash_hmac_file() function with invalid hash algorithm --\n";
hash_hmac_file('foo', $file, $key, TRUE);
+echo "\n-- Testing hash_hmac_file() function with non-cryptographic hash algorithm --\n";
+hash_hmac_file('crc32', $file, $key, TRUE);
+
echo "\n-- Testing hash_hmac_file() function with bad path --\n";
-hash_hmac_file('crc32', $file.chr(0).$file, $key, TRUE);
+hash_hmac_file('md5', $file.chr(0).$file, $key, TRUE);
?>
===Done===
Warning: hash_hmac_file(): Unknown hashing algorithm: foo in %s on line %d
+-- Testing hash_hmac_file() function with non-cryptographic hash algorithm --
+
+Warning: hash_hmac_file(): Non-cryptographic hashing algorithm: crc32 in %s on line %d
+
-- Testing hash_hmac_file() function with bad path --
Warning: hash_hmac_file(): Invalid path in %s on line %d
-===Done===
\ No newline at end of file
+===Done===
echo "\n-- Testing hash_pbkdf2() function with less than expected no. of arguments --\n";
var_dump(@hash_pbkdf2());
echo $php_errormsg . "\n";
-var_dump(@hash_pbkdf2('crc32'));
+var_dump(@hash_pbkdf2('md5'));
echo $php_errormsg . "\n";
-var_dump(@hash_pbkdf2('crc32', $password));
+var_dump(@hash_pbkdf2('md5', $password));
echo $php_errormsg . "\n";
-var_dump(@hash_pbkdf2('crc32', $password, $salt));
+var_dump(@hash_pbkdf2('md5', $password, $salt));
echo $php_errormsg . "\n";
echo "\n-- Testing hash_pbkdf2() function with more than expected no. of arguments --\n";
-var_dump(@hash_pbkdf2('crc32', $password, $salt, 10, 10, true, 'extra arg'));
+var_dump(@hash_pbkdf2('md5', $password, $salt, 10, 10, true, 'extra arg'));
echo $php_errormsg . "\n";
echo "\n-- Testing hash_pbkdf2() function with invalid hash algorithm --\n";
var_dump(@hash_pbkdf2('foo', $password, $salt, 1));
echo $php_errormsg . "\n";
+echo "\n-- Testing hash_pbkdf2() function with non-cryptographic hash algorithm --\n";
+var_dump(@hash_pbkdf2('crc32', $password, $salt, 1));
+echo $php_errormsg . "\n";
+
echo "\n-- Testing hash_pbkdf2() function with invalid iterations --\n";
var_dump(@hash_pbkdf2('md5', $password, $salt, 0));
echo $php_errormsg . "\n";
bool(false)
hash_pbkdf2(): Unknown hashing algorithm: foo
+-- Testing hash_pbkdf2() function with non-cryptographic hash algorithm --
+bool(false)
+hash_pbkdf2(): Non-cryptographic hashing algorithm: crc32
+
-- Testing hash_pbkdf2() function with invalid iterations --
bool(false)
hash_pbkdf2(): Iterations must be a positive integer: 0