Skip to content

Commit d89d149

Browse files
narfbgnikic
authored andcommitted
Disallow non-crypto hashes in HMAC and PBKDF2
For this purpose add is_crypto flag to php_hash_ops.
1 parent 5bc8162 commit d89d149

21 files changed

+107
-73
lines changed

UPGRADING

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ PHP 7.2 UPGRADE NOTES
4242
such, its behavior now follows fmod() rather than the `%` operator. For
4343
example `bcmod('4', '3.5')` now returns '0.5' instead of '1'.
4444

45+
- Hash:
46+
. The hash_hmac(), hash_hmac_file() and hash_pbkdf2() functions no longer
47+
accept non-cryptographic hashes.
48+
4549
- PCRE:
4650
. preg_match() and other PCRE functions now distinguish between unmatched
4751
subpatterns and empty matches by reporting NULL and "" (empty string),

ext/hash/hash.c

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,11 @@ static void php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAMETERS, int isfilename,
248248
php_error_docref(NULL, E_WARNING, "Unknown hashing algorithm: %s", algo);
249249
RETURN_FALSE;
250250
}
251+
else if (!ops->is_crypto) {
252+
php_error_docref(NULL, E_WARNING, "Non-cryptographic hashing algorithm: %s", algo);
253+
RETURN_FALSE;
254+
}
255+
251256
if (isfilename) {
252257
if (CHECK_NULL_PATH(data, data_len)) {
253258
php_error_docref(NULL, E_WARNING, "Invalid path");
@@ -597,25 +602,6 @@ PHP_FUNCTION(hash_algos)
597602
}
598603
/* }}} */
599604

600-
static inline zend_bool php_hash_is_crypto(const char *algo, size_t algo_len) {
601-
602-
char *blacklist[] = { "adler32", "crc32", "crc32b", "fnv132", "fnv1a32", "fnv164", "fnv1a64", "joaat", NULL };
603-
char *lower = zend_str_tolower_dup(algo, algo_len);
604-
int i = 0;
605-
606-
while (blacklist[i]) {
607-
if (strcmp(lower, blacklist[i]) == 0) {
608-
efree(lower);
609-
return 0;
610-
}
611-
612-
i++;
613-
}
614-
615-
efree(lower);
616-
return 1;
617-
}
618-
619605
/* {{{ proto string hash_hkdf(string algo, string ikm [, int length = 0, string info = '', string salt = ''])
620606
RFC5869 HMAC-based key derivation function */
621607
PHP_FUNCTION(hash_hkdf)
@@ -636,8 +622,8 @@ PHP_FUNCTION(hash_hkdf)
636622
php_error_docref(NULL, E_WARNING, "Unknown hashing algorithm: %s", ZSTR_VAL(algo));
637623
RETURN_FALSE;
638624
}
639-
640-
if (!php_hash_is_crypto(ZSTR_VAL(algo), ZSTR_LEN(algo))) {
625+
626+
if (!ops->is_crypto) {
641627
php_error_docref(NULL, E_WARNING, "Non-cryptographic hashing algorithm: %s", ZSTR_VAL(algo));
642628
RETURN_FALSE;
643629
}
@@ -736,6 +722,10 @@ PHP_FUNCTION(hash_pbkdf2)
736722
php_error_docref(NULL, E_WARNING, "Unknown hashing algorithm: %s", algo);
737723
RETURN_FALSE;
738724
}
725+
else if (!ops->is_crypto) {
726+
php_error_docref(NULL, E_WARNING, "Non-cryptographic hashing algorithm: %s", algo);
727+
RETURN_FALSE;
728+
}
739729

740730
if (iterations <= 0) {
741731
php_error_docref(NULL, E_WARNING, "Iterations must be a positive integer: " ZEND_LONG_FMT, iterations);

ext/hash/hash_adler32.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ const php_hash_ops php_hash_adler32_ops = {
6969
(php_hash_copy_func_t) PHP_ADLER32Copy,
7070
4, /* what to say here? */
7171
4,
72-
sizeof(PHP_ADLER32_CTX)
72+
sizeof(PHP_ADLER32_CTX),
73+
0
7374
};
7475

7576
/*

ext/hash/hash_crc32.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ const php_hash_ops php_hash_crc32_ops = {
7979
(php_hash_copy_func_t) PHP_CRC32Copy,
8080
4, /* what to say here? */
8181
4,
82-
sizeof(PHP_CRC32_CTX)
82+
sizeof(PHP_CRC32_CTX),
83+
0
8384
};
8485

8586
const php_hash_ops php_hash_crc32b_ops = {
@@ -89,7 +90,8 @@ const php_hash_ops php_hash_crc32b_ops = {
8990
(php_hash_copy_func_t) PHP_CRC32Copy,
9091
4, /* what to say here? */
9192
4,
92-
sizeof(PHP_CRC32_CTX)
93+
sizeof(PHP_CRC32_CTX),
94+
0
9395
};
9496

9597
/*

ext/hash/hash_fnv.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,19 @@ const php_hash_ops php_hash_fnv132_ops = {
3131
(php_hash_copy_func_t) php_hash_copy,
3232
4,
3333
4,
34-
sizeof(PHP_FNV132_CTX)
34+
sizeof(PHP_FNV132_CTX),
35+
0
3536
};
3637

37-
const php_hash_ops php_hash_fnv1a32_ops = {
38+
const php_hash_ops php_hash_fnv1a32_ops = {
3839
(php_hash_init_func_t) PHP_FNV132Init,
3940
(php_hash_update_func_t) PHP_FNV1a32Update,
4041
(php_hash_final_func_t) PHP_FNV132Final,
4142
(php_hash_copy_func_t) php_hash_copy,
4243
4,
4344
4,
44-
sizeof(PHP_FNV132_CTX)
45+
sizeof(PHP_FNV132_CTX),
46+
0
4547
};
4648

4749
const php_hash_ops php_hash_fnv164_ops = {
@@ -51,7 +53,8 @@ const php_hash_ops php_hash_fnv164_ops = {
5153
(php_hash_copy_func_t) php_hash_copy,
5254
8,
5355
4,
54-
sizeof(PHP_FNV164_CTX)
56+
sizeof(PHP_FNV164_CTX),
57+
0
5558
};
5659

5760
const php_hash_ops php_hash_fnv1a64_ops = {
@@ -61,7 +64,8 @@ const php_hash_ops php_hash_fnv1a64_ops = {
6164
(php_hash_copy_func_t) php_hash_copy,
6265
8,
6366
4,
64-
sizeof(PHP_FNV164_CTX)
67+
sizeof(PHP_FNV164_CTX),
68+
0
6569
};
6670

6771
/* {{{ PHP_FNV132Init

ext/hash/hash_gost.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,8 @@ const php_hash_ops php_hash_gost_ops = {
316316
(php_hash_copy_func_t) php_hash_copy,
317317
32,
318318
32,
319-
sizeof(PHP_GOST_CTX)
319+
sizeof(PHP_GOST_CTX),
320+
1
320321
};
321322

322323
const php_hash_ops php_hash_gost_crypto_ops = {
@@ -326,7 +327,8 @@ const php_hash_ops php_hash_gost_crypto_ops = {
326327
(php_hash_copy_func_t) php_hash_copy,
327328
32,
328329
32,
329-
sizeof(PHP_GOST_CTX)
330+
sizeof(PHP_GOST_CTX),
331+
1
330332
};
331333

332334
/*

ext/hash/hash_haval.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ const php_hash_ops php_hash_##p##haval##b##_ops = { \
255255
(php_hash_update_func_t) PHP_HAVALUpdate, \
256256
(php_hash_final_func_t) PHP_HAVAL##b##Final, \
257257
(php_hash_copy_func_t) php_hash_copy, \
258-
((b) / 8), 128, sizeof(PHP_HAVAL_CTX) }; \
258+
((b) / 8), 128, sizeof(PHP_HAVAL_CTX), 1 }; \
259259
PHP_HASH_API void PHP_##p##HAVAL##b##Init(PHP_HAVAL_CTX *context) \
260260
{ int i; context->count[0] = context->count[1] = 0; \
261261
for(i = 0; i < 8; i++) context->state[i] = D0[i]; \

ext/hash/hash_joaat.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ const php_hash_ops php_hash_joaat_ops = {
3232
(php_hash_copy_func_t) php_hash_copy,
3333
4,
3434
4,
35-
sizeof(PHP_JOAAT_CTX)
35+
sizeof(PHP_JOAAT_CTX),
36+
0
3637
};
3738

3839
PHP_HASH_API void PHP_JOAATInit(PHP_JOAAT_CTX *context)

ext/hash/hash_md.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ const php_hash_ops php_hash_md5_ops = {
2828
(php_hash_copy_func_t) php_hash_copy,
2929
16,
3030
64,
31-
sizeof(PHP_MD5_CTX)
31+
sizeof(PHP_MD5_CTX),
32+
1
3233
};
3334

3435
const php_hash_ops php_hash_md4_ops = {
@@ -38,7 +39,8 @@ const php_hash_ops php_hash_md4_ops = {
3839
(php_hash_copy_func_t) php_hash_copy,
3940
16,
4041
64,
41-
sizeof(PHP_MD4_CTX)
42+
sizeof(PHP_MD4_CTX),
43+
1
4244
};
4345

4446
const php_hash_ops php_hash_md2_ops = {
@@ -48,7 +50,8 @@ const php_hash_ops php_hash_md2_ops = {
4850
(php_hash_copy_func_t) php_hash_copy,
4951
16,
5052
16,
51-
sizeof(PHP_MD2_CTX)
53+
sizeof(PHP_MD2_CTX),
54+
1
5255
};
5356

5457
/* MD common stuff */

ext/hash/hash_ripemd.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ const php_hash_ops php_hash_ripemd128_ops = {
3232
(php_hash_copy_func_t) php_hash_copy,
3333
16,
3434
64,
35-
sizeof(PHP_RIPEMD128_CTX)
35+
sizeof(PHP_RIPEMD128_CTX),
36+
1
3637
};
3738

3839
const php_hash_ops php_hash_ripemd160_ops = {
@@ -42,7 +43,8 @@ const php_hash_ops php_hash_ripemd160_ops = {
4243
(php_hash_copy_func_t) php_hash_copy,
4344
20,
4445
64,
45-
sizeof(PHP_RIPEMD160_CTX)
46+
sizeof(PHP_RIPEMD160_CTX),
47+
1
4648
};
4749

4850
const php_hash_ops php_hash_ripemd256_ops = {
@@ -52,7 +54,8 @@ const php_hash_ops php_hash_ripemd256_ops = {
5254
(php_hash_copy_func_t) php_hash_copy,
5355
32,
5456
64,
55-
sizeof(PHP_RIPEMD256_CTX)
57+
sizeof(PHP_RIPEMD256_CTX),
58+
1
5659
};
5760

5861
const php_hash_ops php_hash_ripemd320_ops = {
@@ -62,7 +65,8 @@ const php_hash_ops php_hash_ripemd320_ops = {
6265
(php_hash_copy_func_t) php_hash_copy,
6366
40,
6467
64,
65-
sizeof(PHP_RIPEMD320_CTX)
68+
sizeof(PHP_RIPEMD320_CTX),
69+
1
6670
};
6771

6872
/* {{{ PHP_RIPEMD128Init

ext/hash/hash_sha.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ const php_hash_ops php_hash_sha1_ops = {
7373
(php_hash_copy_func_t) php_hash_copy,
7474
20,
7575
64,
76-
sizeof(PHP_SHA1_CTX)
76+
sizeof(PHP_SHA1_CTX),
77+
1
7778
};
7879

7980
#ifdef PHP_HASH_SHA1_NOT_IN_CORE
@@ -415,7 +416,8 @@ const php_hash_ops php_hash_sha256_ops = {
415416
(php_hash_copy_func_t) php_hash_copy,
416417
32,
417418
64,
418-
sizeof(PHP_SHA256_CTX)
419+
sizeof(PHP_SHA256_CTX),
420+
1
419421
};
420422

421423
const php_hash_ops php_hash_sha224_ops = {
@@ -425,7 +427,8 @@ const php_hash_ops php_hash_sha224_ops = {
425427
(php_hash_copy_func_t) php_hash_copy,
426428
28,
427429
64,
428-
sizeof(PHP_SHA224_CTX)
430+
sizeof(PHP_SHA224_CTX),
431+
1
429432
};
430433

431434
#define ROTR32(b,x) ((x >> b) | (x << (32 - b)))
@@ -917,7 +920,8 @@ const php_hash_ops php_hash_sha384_ops = {
917920
(php_hash_copy_func_t) php_hash_copy,
918921
48,
919922
128,
920-
sizeof(PHP_SHA384_CTX)
923+
sizeof(PHP_SHA384_CTX),
924+
1
921925
};
922926

923927
/* {{{ PHP_SHA512Init
@@ -1089,7 +1093,8 @@ const php_hash_ops php_hash_sha512_ops = {
10891093
(php_hash_copy_func_t) php_hash_copy,
10901094
64,
10911095
128,
1092-
sizeof(PHP_SHA512_CTX)
1096+
sizeof(PHP_SHA512_CTX),
1097+
1
10931098
};
10941099

10951100
const php_hash_ops php_hash_sha512_256_ops = {
@@ -1099,7 +1104,8 @@ const php_hash_ops php_hash_sha512_256_ops = {
10991104
(php_hash_copy_func_t) php_hash_copy,
11001105
32,
11011106
128,
1102-
sizeof(PHP_SHA512_CTX)
1107+
sizeof(PHP_SHA512_CTX),
1108+
1
11031109
};
11041110

11051111
const php_hash_ops php_hash_sha512_224_ops = {
@@ -1109,7 +1115,8 @@ const php_hash_ops php_hash_sha512_224_ops = {
11091115
(php_hash_copy_func_t) php_hash_copy,
11101116
28,
11111117
128,
1112-
sizeof(PHP_SHA512_CTX)
1118+
sizeof(PHP_SHA512_CTX),
1119+
1
11131120
};
11141121

11151122
/*

ext/hash/hash_sha3.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,8 @@ const php_hash_ops php_hash_sha3_##bits##_ops = { \
218218
php_hash_copy, \
219219
bits >> 3, \
220220
(1600 - (2 * bits)) >> 3, \
221-
sizeof(PHP_SHA3_##bits##_CTX) \
221+
sizeof(PHP_SHA3_##bits##_CTX), \
222+
1 \
222223
}
223224

224225
DECLARE_SHA3_OPS(224);

ext/hash/hash_snefru.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ const php_hash_ops php_hash_snefru_ops = {
200200
(php_hash_copy_func_t) php_hash_copy,
201201
32,
202202
32,
203-
sizeof(PHP_SNEFRU_CTX)
203+
sizeof(PHP_SNEFRU_CTX),
204+
1
204205
};
205206

206207
/*

ext/hash/hash_tiger.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,8 @@ PHP_HASH_API void PHP_TIGER192Final(unsigned char digest[24], PHP_TIGER_CTX *con
251251
(php_hash_copy_func_t) php_hash_copy, \
252252
b/8, \
253253
64, \
254-
sizeof(PHP_TIGER_CTX) \
254+
sizeof(PHP_TIGER_CTX), \
255+
1 \
255256
}
256257

257258
PHP_HASH_TIGER_OPS(3, 128);

ext/hash/hash_whirlpool.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,8 @@ const php_hash_ops php_hash_whirlpool_ops = {
440440
(php_hash_copy_func_t) php_hash_copy,
441441
64,
442442
64,
443-
sizeof(PHP_WHIRLPOOL_CTX)
443+
sizeof(PHP_WHIRLPOOL_CTX),
444+
1
444445
};
445446

446447
/*

ext/hash/php_hash.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ typedef struct _php_hash_ops {
4646
int digest_size;
4747
int block_size;
4848
int context_size;
49+
unsigned is_crypto: 1;
4950
} php_hash_ops;
5051

5152
typedef struct _php_hash_data {

0 commit comments

Comments
 (0)