Skip to content

Commit 5eb7bf8

Browse files
committed
Address PBKDF2 SHA-256 review followups
1 parent 1e94d0b commit 5eb7bf8

2 files changed

Lines changed: 17 additions & 38 deletions

File tree

ext/hash/hash.c

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@
3131
# define PHP_HASH_HAVE_COMMONCRYPTO_PBKDF2 1
3232
#endif
3333

34-
/* Internal helper from hash_sha.c, not part of the public hash API. */
35-
void php_hash_sha256_final32_from_context(unsigned char digest[32], const PHP_SHA256_CTX *context, const unsigned char data[32]);
36-
3734
#include "zend_attributes.h"
3835
#include "zend_exceptions.h"
3936
#include "zend_interfaces.h"
@@ -524,10 +521,10 @@ static const unsigned char php_hash_sha_padding[128] = {
524521

525522
static inline void php_hash_sha256_encode(unsigned char digest[32], const uint32_t state[8]) {
526523
for (size_t i = 0; i < 8; i++) {
527-
digest[i * 4] = (unsigned char) ((state[i] >> 24) & 0xff);
524+
digest[(i * 4) + 0] = (unsigned char) ((state[i] >> 24) & 0xff);
528525
digest[(i * 4) + 1] = (unsigned char) ((state[i] >> 16) & 0xff);
529526
digest[(i * 4) + 2] = (unsigned char) ((state[i] >> 8) & 0xff);
530-
digest[(i * 4) + 3] = (unsigned char) (state[i] & 0xff);
527+
digest[(i * 4) + 3] = (unsigned char) ((state[i] >> 0) & 0xff);
531528
}
532529
}
533530

@@ -552,10 +549,17 @@ static inline void php_hash_sha256_final_no_zero(unsigned char digest[32], PHP_S
552549
php_hash_sha256_encode(digest, context->state);
553550
}
554551

552+
static inline void php_hash_sha256_final32_from_context(unsigned char digest[32], const PHP_SHA256_CTX *base_context, const unsigned char data[32]) {
553+
PHP_SHA256_CTX context = *base_context;
554+
555+
PHP_SHA256Update(&context, data, 32);
556+
php_hash_sha256_final_no_zero(digest, &context);
557+
ZEND_SECURE_ZERO(&context, sizeof(context));
558+
}
559+
555560
static zend_string *php_hash_pbkdf2_sha256(const char *pass, size_t pass_len, const char *salt, size_t salt_len, zend_long iterations, zend_long length, bool raw_output) {
556-
zend_string *returnval;
557561
unsigned char *digest, *result, *K = NULL, counter[4];
558-
zend_long loops, i, j, digest_length = 0;
562+
zend_long digest_length;
559563
const size_t digest_size = 32;
560564
const size_t block_size = 64;
561565
PHP_SHA256_CTX inner_context, outer_context, context;
@@ -584,11 +588,10 @@ static zend_string *php_hash_pbkdf2_sha256(const char *pass, size_t pass_len, co
584588
digest_length = (length / 2) + (length % 2);
585589
}
586590

587-
loops = (digest_length / digest_size) + ((digest_length % digest_size) ? 1 : 0);
588-
591+
const zend_long loops = (digest_length / digest_size) + ((digest_length % digest_size) ? 1 : 0);
589592
result = safe_emalloc(loops, digest_size, 0);
590593

591-
for (i = 1; i <= loops; i++) {
594+
for (zend_long i = 1; i <= loops; i++) {
592595
unsigned char *result_block = result + ((i - 1) * digest_size);
593596

594597
counter[0] = (unsigned char) (i >> 24);
@@ -604,7 +607,7 @@ static zend_string *php_hash_pbkdf2_sha256(const char *pass, size_t pass_len, co
604607
php_hash_sha256_final32_from_context(digest, &outer_context, digest);
605608
memcpy(result_block, digest, digest_size);
606609

607-
for (j = 1; j < iterations; j++) {
610+
for (zend_long j = 1; j < iterations; j++) {
608611
php_hash_sha256_final32_from_context(digest, &inner_context, digest);
609612
php_hash_sha256_final32_from_context(digest, &outer_context, digest);
610613

@@ -620,7 +623,7 @@ static zend_string *php_hash_pbkdf2_sha256(const char *pass, size_t pass_len, co
620623
efree(K);
621624
efree(digest);
622625

623-
returnval = zend_string_alloc(length, 0);
626+
zend_string *returnval = zend_string_alloc(length, 0);
624627
if (raw_output) {
625628
memcpy(ZSTR_VAL(returnval), result, length);
626629
} else {
@@ -634,9 +637,8 @@ static zend_string *php_hash_pbkdf2_sha256(const char *pass, size_t pass_len, co
634637

635638
#ifdef PHP_HASH_HAVE_COMMONCRYPTO_PBKDF2
636639
static zend_string *php_hash_pbkdf2_sha256_commoncrypto(const char *pass, size_t pass_len, const char *salt, size_t salt_len, zend_long iterations, zend_long length, bool raw_output) {
637-
zend_string *returnval;
638640
unsigned char *derived = NULL;
639-
zend_long derived_len = 0;
641+
zend_long derived_len;
640642

641643
if (iterations > UINT32_MAX) {
642644
return NULL;
@@ -663,7 +665,7 @@ static zend_string *php_hash_pbkdf2_sha256_commoncrypto(const char *pass, size_t
663665
return NULL;
664666
}
665667

666-
returnval = zend_string_alloc(length, 0);
668+
zend_string *returnval = zend_string_alloc(length, 0);
667669
if (raw_output) {
668670
memcpy(ZSTR_VAL(returnval), derived, length);
669671
} else {

ext/hash/hash_sha.c

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -390,29 +390,6 @@ PHP_HASH_API void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * con
390390
}
391391
/* }}} */
392392

393-
/* {{{ php_hash_sha256_final32_from_context
394-
Compute SHA256(base_ctx || data[32]) where base_ctx already hashed one full 64-byte block.
395-
*/
396-
void php_hash_sha256_final32_from_context(unsigned char digest[32], const PHP_SHA256_CTX *context, const unsigned char data[32])
397-
{
398-
uint32_t state[8];
399-
unsigned char block[64];
400-
401-
ZEND_ASSERT(context->count[1] == 0);
402-
ZEND_ASSERT(context->count[0] == 512);
403-
404-
memcpy(state, context->state, sizeof(state));
405-
memcpy(block, data, 32);
406-
block[32] = 0x80;
407-
memset(block + 33, 0, 23);
408-
memset(block + 56, 0, 8);
409-
block[62] = 0x03;
410-
411-
SHA256Transform(state, block);
412-
SHAEncode32(digest, state, 32);
413-
}
414-
/* }}} */
415-
416393
/* sha384/sha512 */
417394

418395
/* Ch */

0 commit comments

Comments
 (0)