Skip to content

Commit 4bfe98e

Browse files
committed
Fixes
1 parent 5321ee8 commit 4bfe98e

File tree

3 files changed

+26
-30
lines changed

3 files changed

+26
-30
lines changed

ext/random/csprng.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@
6666
static zend_atomic_int random_fd = ZEND_ATOMIC_INT_INITIALIZER(-1);
6767
#endif
6868

69-
ZEND_ATTRIBUTE_NONNULL
70-
PHPAPI zend_result php_random_bytes_ex(void *bytes, size_t size, char *errstr, size_t errstr_size)
69+
ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_random_bytes_ex(void *bytes, size_t size, char *errstr, size_t errstr_size)
7170
{
7271
#ifdef PHP_WIN32
7372
/* Defer to CryptGenRandom on Windows */
@@ -211,7 +210,7 @@ PHPAPI zend_result php_random_bytes_ex(void *bytes, size_t size, char *errstr, s
211210
return SUCCESS;
212211
}
213212

214-
PHPAPI zend_result php_random_bytes(void *bytes, size_t size, bool should_throw)
213+
ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_random_bytes(void *bytes, size_t size, bool should_throw)
215214
{
216215
char errstr[128];
217216
zend_result result = php_random_bytes_ex(bytes, size, errstr, sizeof(errstr));

ext/random/php_random_csprng.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@
2020

2121
# include "php.h"
2222

23-
PHPAPI zend_result php_random_bytes(void *bytes, size_t size, bool should_throw);
24-
PHPAPI zend_result php_random_bytes_ex(void *bytes, size_t size, char *errstr, size_t errstr_size);
23+
ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_random_bytes(void *bytes, size_t size, bool should_throw);
24+
25+
ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_random_bytes_ex(void *bytes, size_t size, char *errstr, size_t errstr_size);
2526

2627
PHPAPI zend_result php_random_int(zend_long min, zend_long max, zend_long *result, bool should_throw);
2728

ext/random/random.c

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -699,54 +699,50 @@ uint64_t php_random_generate_fallback_seed(void)
699699
return php_random_generate_fallback_seed_ex(&RANDOM_G(fallback_seed_state));
700700
}
701701

702-
static zend_result php_general_random_bytes_for_zend_initialize(php_random_state_for_zend *state)
702+
static void php_general_random_bytes_for_zend_initialize(php_random_state_for_zend *state)
703703
{
704704
uint64_t t[4];
705+
php_random_fallback_seed_state fallback_state = {
706+
.initialized = false,
707+
};
705708

706709
do {
707-
char errstr[128];
708-
if (php_random_bytes_ex(&t, sizeof(t), errstr, sizeof(errstr)) == FAILURE) {
710+
/* Skip the CSPRNG if it has already failed */
711+
if (!fallback_state.initialized) {
712+
char errstr[128];
713+
if (php_random_bytes_ex(&t, sizeof(t), errstr, sizeof(errstr)) == FAILURE) {
709714
#if ZEND_DEBUG
710-
fprintf(stderr, "php_random_bytes_ex: Failed to generate a random seed: %s\n", errstr);
715+
fprintf(stderr, "php_random_bytes_ex: Failed to generate a random seed: %s\n", errstr);
711716
#endif
712-
return FAILURE;
717+
goto fallback;
718+
}
719+
} else {
720+
fallback:
721+
t[0] = php_random_generate_fallback_seed_ex(&fallback_state);
722+
t[1] = php_random_generate_fallback_seed_ex(&fallback_state);
723+
t[2] = php_random_generate_fallback_seed_ex(&fallback_state);
724+
t[3] = php_random_generate_fallback_seed_ex(&fallback_state);
713725
}
714726
} while (UNEXPECTED(t[0] == 0 && t[1] == 0 && t[2] == 0 && t[3] == 0));
715727

716728
php_random_xoshiro256starstar_seed256(&state->xoshiro256starstar_state, t[0], t[1], t[2], t[3]);
717-
718-
return SUCCESS;
719-
}
720-
721-
static void php_general_random_bytes_for_zend_initialize_fallback(php_random_state_for_zend *state)
722-
{
723-
uint64_t t;
724-
php_random_fallback_seed_state fallback_state;
725-
726-
do {
727-
t = php_random_generate_fallback_seed_ex(&fallback_state);
728-
} while (UNEXPECTED(t == 0));
729-
730-
php_random_xoshiro256starstar_seed64(&state->xoshiro256starstar_state, t);
731729
}
732730

733731
PHPAPI zend_result php_general_random_bytes_for_zend(zend_utility_general_random_state *opaque_state, void *bytes, size_t size)
734732
{
735733
php_random_state_for_zend *state = (php_random_state_for_zend*) opaque_state;
736734

737735
if (!state->initialized) {
738-
if (php_general_random_bytes_for_zend_initialize(state) == FAILURE) {
739-
php_general_random_bytes_for_zend_initialize_fallback(state);
740-
}
736+
php_general_random_bytes_for_zend_initialize(state);
741737
state->initialized = true;
742738
}
743739

744740
while (size > 0) {
745741
php_random_result result = php_random_algo_xoshiro256starstar.generate(&state->xoshiro256starstar_state);
746-
size_t chunk_size = MIN(size, sizeof(result.size));
747-
memcpy(bytes, &result.result, chunk_size);
742+
ZEND_ASSERT(result.size == 8 && sizeof(result.result) == 8);
743+
size_t chunk_size = MIN(size, 8);
744+
bytes = zend_mempcpy(bytes, &result.result, chunk_size);
748745
size -= chunk_size;
749-
bytes = (char*)bytes + chunk_size;
750746
}
751747

752748
return SUCCESS;

0 commit comments

Comments
 (0)