@@ -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
733731PHPAPI 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