Skip to content

Add php_hash_ops->is_crypto; disallow is_crypto=0 hashes in hash_hmac*(), hash_pbkdf2() #2312

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 11 additions & 21 deletions ext/hash/hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,11 @@ static void php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAMETERS, int isfilename,
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");
Expand Down Expand Up @@ -597,25 +602,6 @@ PHP_FUNCTION(hash_algos)
}
/* }}} */

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)
Expand All @@ -636,8 +622,8 @@ 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;
}
Expand Down Expand Up @@ -736,6 +722,10 @@ PHP_FUNCTION(hash_pbkdf2)
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);
Expand Down
3 changes: 2 additions & 1 deletion ext/hash/hash_adler32.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ const php_hash_ops php_hash_adler32_ops = {
(php_hash_copy_func_t) PHP_ADLER32Copy,
4, /* what to say here? */
4,
sizeof(PHP_ADLER32_CTX)
sizeof(PHP_ADLER32_CTX),
0
};

/*
Expand Down
6 changes: 4 additions & 2 deletions ext/hash/hash_crc32.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ const php_hash_ops php_hash_crc32_ops = {
(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 = {
Expand All @@ -89,7 +90,8 @@ 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
};

/*
Expand Down
14 changes: 9 additions & 5 deletions ext/hash/hash_fnv.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,19 @@ const php_hash_ops php_hash_fnv132_ops = {
(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 = {
Expand All @@ -51,7 +53,8 @@ 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 = {
Expand All @@ -61,7 +64,8 @@ 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
Expand Down
6 changes: 4 additions & 2 deletions ext/hash/hash_gost.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,8 @@ const php_hash_ops php_hash_gost_ops = {
(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 = {
Expand All @@ -326,7 +327,8 @@ 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
};

/*
Expand Down
2 changes: 1 addition & 1 deletion ext/hash/hash_haval.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ const php_hash_ops php_hash_##p##haval##b##_ops = { \
(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]; \
Expand Down
3 changes: 2 additions & 1 deletion ext/hash/hash_joaat.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ const php_hash_ops php_hash_joaat_ops = {
(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)
Expand Down
9 changes: 6 additions & 3 deletions ext/hash/hash_md.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ const php_hash_ops php_hash_md5_ops = {
(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 = {
Expand All @@ -38,7 +39,8 @@ 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 = {
Expand All @@ -48,7 +50,8 @@ 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 */
Expand Down
12 changes: 8 additions & 4 deletions ext/hash/hash_ripemd.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ const php_hash_ops php_hash_ripemd128_ops = {
(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 = {
Expand All @@ -42,7 +43,8 @@ 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 = {
Expand All @@ -52,7 +54,8 @@ 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 = {
Expand All @@ -62,7 +65,8 @@ 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
Expand Down
21 changes: 14 additions & 7 deletions ext/hash/hash_sha.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ const php_hash_ops php_hash_sha1_ops = {
(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
Expand Down Expand Up @@ -415,7 +416,8 @@ const php_hash_ops php_hash_sha256_ops = {
(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 = {
Expand All @@ -425,7 +427,8 @@ 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)))
Expand Down Expand Up @@ -917,7 +920,8 @@ const php_hash_ops php_hash_sha384_ops = {
(php_hash_copy_func_t) php_hash_copy,
48,
128,
sizeof(PHP_SHA384_CTX)
sizeof(PHP_SHA384_CTX),
1
};

/* {{{ PHP_SHA512Init
Expand Down Expand Up @@ -1089,7 +1093,8 @@ const php_hash_ops php_hash_sha512_ops = {
(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 = {
Expand All @@ -1099,7 +1104,8 @@ 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 = {
Expand All @@ -1109,7 +1115,8 @@ 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
};

/*
Expand Down
3 changes: 2 additions & 1 deletion ext/hash/hash_sha3.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,8 @@ const php_hash_ops php_hash_sha3_##bits##_ops = { \
php_hash_copy, \
bits >> 3, \
(1600 - (2 * bits)) >> 3, \
sizeof(PHP_SHA3_##bits##_CTX) \
sizeof(PHP_SHA3_##bits##_CTX), \
1 \
}

DECLARE_SHA3_OPS(224);
Expand Down
3 changes: 2 additions & 1 deletion ext/hash/hash_snefru.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ const php_hash_ops php_hash_snefru_ops = {
(php_hash_copy_func_t) php_hash_copy,
32,
32,
sizeof(PHP_SNEFRU_CTX)
sizeof(PHP_SNEFRU_CTX),
1
};

/*
Expand Down
3 changes: 2 additions & 1 deletion ext/hash/hash_tiger.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,8 @@ PHP_HASH_API void PHP_TIGER192Final(unsigned char digest[24], PHP_TIGER_CTX *con
(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);
Expand Down
3 changes: 2 additions & 1 deletion ext/hash/hash_whirlpool.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,8 @@ const php_hash_ops php_hash_whirlpool_ops = {
(php_hash_copy_func_t) php_hash_copy,
64,
64,
sizeof(PHP_WHIRLPOOL_CTX)
sizeof(PHP_WHIRLPOOL_CTX),
1
};

/*
Expand Down
1 change: 1 addition & 0 deletions ext/hash/php_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ typedef struct _php_hash_ops {
int digest_size;
int block_size;
int context_size;
unsigned is_crypto: 1;
} php_hash_ops;

typedef struct _php_hash_data {
Expand Down
6 changes: 0 additions & 6 deletions ext/hash/tests/hash_hmac_basic.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ echo "*** Testing hash_hmac() : basic functionality ***\n";
$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";
Expand All @@ -34,16 +32,13 @@ echo "sha512: " . hash_hmac('sha512', $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
Expand All @@ -60,7 +55,6 @@ sha512: 7de05636b18e2b0ca3427e03f53074af3a48a7b9df226daba4f22324c570638e7d7b2643
snefru: 67af483046f9cf16fe19f9087929ccfc6ad176ade3290b4d33f43e0ddb07e711
tiger192,3: 00a0f884f15a9e5549ed0e40ca0190522d369027e16d5b59
whirlpool: 4a0f1582b21b7aff59bfba7f9c29131c69741b2ce80acdc7d314040f3b768cf5a17e30b74cceb86fbc6b34b1692e0addd5bfd7cfc043d40c0621f1b97e26fa49
adler32(raw): 12c803f7
md5(raw): 2a632783e2812cf23de100d7d6a463ae
sha256(raw): 49bde3496b9510a17d0edd8a4b0ac70148e32a1d51e881ec76faa96534125838
===Done===
Loading