@@ -622,7 +622,7 @@ static inline void fallback_seed_add(PHP_SHA1_CTX *c, void *p, size_t l){
622622 PHP_SHA1Update (c , p , l );
623623}
624624
625- uint64_t php_random_generate_fallback_seed ( void )
625+ uint64_t php_random_generate_fallback_seed_ex ( php_random_fallback_seed_state * state )
626626{
627627 /* Mix various values using SHA-1 as a PRF to obtain as
628628 * much entropy as possible, hopefully generating an
@@ -640,7 +640,7 @@ uint64_t php_random_generate_fallback_seed(void)
640640 char buf [64 + 1 ];
641641
642642 PHP_SHA1Init (& c );
643- if (!RANDOM_G ( fallback_seed_initialized ) ) {
643+ if (!state -> initialized ) {
644644 /* Current time. */
645645 gettimeofday (& tv , NULL );
646646 fallback_seed_add (& c , & tv , sizeof (tv ));
@@ -656,7 +656,7 @@ uint64_t php_random_generate_fallback_seed(void)
656656 fallback_seed_add (& c , & tid , sizeof (tid ));
657657#endif
658658 /* Pointer values to benefit from ASLR. */
659- pointer = & RANDOM_G ( fallback_seed_initialized ) ;
659+ pointer = state ;
660660 fallback_seed_add (& c , & pointer , sizeof (pointer ));
661661 pointer = & c ;
662662 fallback_seed_add (& c , & pointer , sizeof (pointer ));
@@ -680,24 +680,82 @@ uint64_t php_random_generate_fallback_seed(void)
680680 gettimeofday (& tv , NULL );
681681 fallback_seed_add (& c , & tv , sizeof (tv ));
682682 /* Previous state. */
683- fallback_seed_add (& c , RANDOM_G ( fallback_seed ) , 20 );
683+ fallback_seed_add (& c , state -> seed , 20 );
684684 }
685- PHP_SHA1Final (RANDOM_G ( fallback_seed ) , & c );
686- RANDOM_G ( fallback_seed_initialized ) = true;
685+ PHP_SHA1Final (state -> seed , & c );
686+ state -> initialized = true;
687687
688688 uint64_t result = 0 ;
689689
690690 for (int i = 0 ; i < sizeof (result ); i ++ ) {
691- result = result | (((uint64_t )RANDOM_G ( fallback_seed ) [i ]) << (i * 8 ));
691+ result = result | (((uint64_t )state -> seed [i ]) << (i * 8 ));
692692 }
693693
694694 return result ;
695695}
696696
697+ uint64_t php_random_generate_fallback_seed (void )
698+ {
699+ return php_random_generate_fallback_seed_ex (& RANDOM_G (fallback_seed_state ));
700+ }
701+
702+ static zend_result php_general_random_bytes_for_zend_initialize (php_random_state_for_zend * state )
703+ {
704+ uint64_t t [4 ];
705+
706+ do {
707+ char errstr [128 ];
708+ if (php_random_bytes_ex (& t , sizeof (t ), errstr , sizeof (errstr )) == FAILURE ) {
709+ #if ZEND_DEBUG
710+ fprintf (stderr , "php_random_bytes_ex: Failed to generate a random seed: %s\n" , errstr );
711+ #endif
712+ return FAILURE ;
713+ }
714+ } while (UNEXPECTED (t [0 ] == 0 && t [1 ] == 0 && t [2 ] == 0 && t [3 ] == 0 ));
715+
716+ 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 );
731+ }
732+
733+ PHPAPI zend_result php_general_random_bytes_for_zend (zend_utility_general_random_state * opaque_state , void * bytes , size_t size )
734+ {
735+ php_random_state_for_zend * state = (php_random_state_for_zend * ) opaque_state ;
736+
737+ 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+ }
741+ state -> initialized = true;
742+ }
743+
744+ while (size > 0 ) {
745+ 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 );
748+ size -= chunk_size ;
749+ bytes += chunk_size ;
750+ }
751+
752+ return SUCCESS ;
753+ }
754+
697755/* {{{ PHP_GINIT_FUNCTION */
698756static PHP_GINIT_FUNCTION (random )
699757{
700- random_globals -> fallback_seed_initialized = false;
758+ random_globals -> fallback_seed_state . initialized = false;
701759}
702760/* }}} */
703761
0 commit comments