Skip to content
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
20 changes: 10 additions & 10 deletions ext/hash/hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ static void php_hash_do_hash(
}
php_stream_close(stream);
if (n < 0) {
efree(context);
php_hash_free_context(ops, context);
RETURN_FALSE;
}
} else {
Expand All @@ -397,7 +397,7 @@ static void php_hash_do_hash(

digest = zend_string_alloc(ops->digest_size, 0);
ops->hash_final((unsigned char *) ZSTR_VAL(digest), context);
efree(context);
php_hash_free_context(ops, context);

if (raw_output) {
ZSTR_VAL(digest)[ops->digest_size] = 0;
Expand Down Expand Up @@ -536,7 +536,7 @@ static void php_hash_do_hash_hmac(
}
php_stream_close(stream);
if (n < 0) {
efree(context);
php_hash_free_context(ops, context);
efree(K);
zend_string_efree(digest);
RETURN_FALSE;
Expand All @@ -554,7 +554,7 @@ static void php_hash_do_hash_hmac(
/* Zero the key */
ZEND_SECURE_ZERO(K, ops->block_size);
efree(K);
efree(context);
php_hash_free_context(ops, context);

if (raw_output) {
ZSTR_VAL(digest)[ops->digest_size] = 0;
Expand Down Expand Up @@ -815,7 +815,7 @@ PHP_FUNCTION(hash_final)
ZSTR_VAL(digest)[digest_len] = 0;

/* Invalidate the object from further use */
efree(hash->context);
php_hash_free_context(hash->ops, hash->context);
hash->context = NULL;

if (raw_output) {
Expand Down Expand Up @@ -973,7 +973,7 @@ PHP_FUNCTION(hash_hkdf)
ZEND_SECURE_ZERO(digest, ops->digest_size);
ZEND_SECURE_ZERO(prk, ops->digest_size);
efree(K);
efree(context);
php_hash_free_context(ops, context);
efree(prk);
efree(digest);
ZSTR_VAL(returnval)[length] = 0;
Expand Down Expand Up @@ -1089,7 +1089,7 @@ PHP_FUNCTION(hash_pbkdf2)
efree(K1);
efree(K2);
efree(computed_salt);
efree(context);
php_hash_free_context(ops, context);
efree(digest);
efree(temp);

Expand Down Expand Up @@ -1356,7 +1356,7 @@ PHP_FUNCTION(mhash_keygen_s2k)
RETVAL_STRINGL(key, bytes);
ZEND_SECURE_ZERO(key, bytes);
efree(digest);
efree(context);
php_hash_free_context(ops, context);
efree(key);
}
}
Expand Down Expand Up @@ -1386,7 +1386,7 @@ static void php_hashcontext_dtor(zend_object *obj) {
php_hashcontext_object *hash = php_hashcontext_from_object(obj);

if (hash->context) {
efree(hash->context);
php_hash_free_context(hash->ops, hash->context);
hash->context = NULL;
}

Expand Down Expand Up @@ -1422,7 +1422,7 @@ static zend_object *php_hashcontext_clone(zend_object *zobj) {
newobj->ops->hash_init(newobj->context, NULL);

if (SUCCESS != newobj->ops->hash_copy(newobj->ops, oldobj->context, newobj->context)) {
efree(newobj->context);
php_hash_free_context(newobj->ops, newobj->context);
newobj->context = NULL;
return znew;
}
Expand Down
6 changes: 4 additions & 2 deletions ext/hash/hash_xxhash.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ const php_hash_ops php_hash_xxh3_64_ops = {
8,
8,
sizeof(PHP_XXH3_64_CTX),
0
0,
64
};

typedef XXH_errorcode (*xxh3_reset_with_secret_func_t)(XXH3_state_t*, const void*, size_t);
Expand Down Expand Up @@ -257,7 +258,8 @@ const php_hash_ops php_hash_xxh3_128_ops = {
16,
8,
sizeof(PHP_XXH3_128_CTX),
0
0,
64
};

PHP_HASH_API void PHP_XXH3_128_Init(PHP_XXH3_128_CTX *ctx, HashTable *args)
Expand Down
18 changes: 18 additions & 0 deletions ext/hash/php_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ typedef struct _php_hash_ops {
size_t block_size;
size_t context_size;
unsigned is_crypto: 1;
size_t context_align;
} php_hash_ops;

struct _php_hashcontext_object {
Expand Down Expand Up @@ -163,9 +164,26 @@ PHP_HASH_API hash_spec_result php_hash_unserialize_spec(php_hashcontext_object *

static inline void *php_hash_alloc_context(const php_hash_ops *ops) {
/* Zero out context memory so serialization doesn't expose internals */
if (ops->context_align > 0) {
size_t align = ops->context_align;
char *base = ecalloc(1, ops->context_size + align);
size_t offset = align - ((uintptr_t)base & (align - 1));
char *ptr = base + offset;
ptr[-1] = (char)offset;
return ptr;
}
return ecalloc(1, ops->context_size);
}

static inline void php_hash_free_context(const php_hash_ops *ops, void *ctx) {
if (ops->context_align > 0) {
unsigned char offset = ((unsigned char *)ctx)[-1];
efree((char *)ctx - offset);
return;
}
efree(ctx);
}

static inline void php_hash_bin2hex(char *out, const unsigned char *in, size_t in_len)
{
static const char hexits[17] = "0123456789abcdef";
Expand Down
Loading