Skip to content

Commit 9f3e4c6

Browse files
committed
Fix hkdf() with (length % digestSize) > 0
1 parent d781e62 commit 9f3e4c6

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

ext/hash/hash.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,11 @@ PHP_FUNCTION(hkdf)
682682
ops->hash_final(digest, context);
683683
php_hash_string_xor_char(K, K, 0x6A, ops->block_size);
684684
php_hash_hmac_round(digest, ops, context, K, digest, ops->digest_size);
685-
memcpy(returnval->val + ((i - 1) * ops->digest_size), digest, ops->digest_size);
685+
memcpy(
686+
returnval->val + ((i - 1) * ops->digest_size),
687+
digest,
688+
(i == rounds ? length - ((i - 1) * ops->digest_size) : ops->digest_size)
689+
);
686690
}
687691

688692
ZEND_SECURE_ZERO(K, ops->block_size);

ext/hash/tests/hkdf_edges.phpt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
Test hkdf() function: edge cases
3+
--SKIPIF--
4+
<?php extension_loaded('hash') or die('skip: hash extension not loaded.'); ?>
5+
--FILE--
6+
<?php
7+
8+
/* Prototype : string hkdf ( string $algo , string $ikm [, int $length , string $info = '' , string $salt = '' ] )
9+
* Description: HMAC-based Key Derivation Function
10+
* Source code: ext/hash/hash.c
11+
*/
12+
13+
echo "*** Testing hkdf(): edge cases ***\n";
14+
15+
$ikm = 'input key material';
16+
17+
echo 'Length < digestSize: ', bin2hex(hkdf('md5', $ikm, 7)), "\n";
18+
echo 'Length % digestSize != 0: ', bin2hex(hkdf('md5', $ikm, 17)), "\n";
19+
20+
?>
21+
--EXPECTF--
22+
*** Testing hkdf(): edge cases ***
23+
Length < digestSize: 98b16391063ece
24+
Length % digestSize != 0: 98b16391063ecee006a3ca8ee5776b1e5f

0 commit comments

Comments
 (0)