@@ -622,7 +622,7 @@ static inline void fallback_seed_add(PHP_SHA1_CTX *c, void *p, size_t l){
622
622
PHP_SHA1Update (c , p , l );
623
623
}
624
624
625
- uint64_t php_random_generate_fallback_seed ( void )
625
+ uint64_t php_random_generate_fallback_seed_ex ( php_random_fallback_seed_state * state )
626
626
{
627
627
/* Mix various values using SHA-1 as a PRF to obtain as
628
628
* much entropy as possible, hopefully generating an
@@ -640,7 +640,7 @@ uint64_t php_random_generate_fallback_seed(void)
640
640
char buf [64 + 1 ];
641
641
642
642
PHP_SHA1Init (& c );
643
- if (!RANDOM_G ( fallback_seed_initialized ) ) {
643
+ if (!state -> initialized ) {
644
644
/* Current time. */
645
645
gettimeofday (& tv , NULL );
646
646
fallback_seed_add (& c , & tv , sizeof (tv ));
@@ -656,7 +656,7 @@ uint64_t php_random_generate_fallback_seed(void)
656
656
fallback_seed_add (& c , & tid , sizeof (tid ));
657
657
#endif
658
658
/* Pointer values to benefit from ASLR. */
659
- pointer = & RANDOM_G ( fallback_seed_initialized ) ;
659
+ pointer = state ;
660
660
fallback_seed_add (& c , & pointer , sizeof (pointer ));
661
661
pointer = & c ;
662
662
fallback_seed_add (& c , & pointer , sizeof (pointer ));
@@ -680,24 +680,82 @@ uint64_t php_random_generate_fallback_seed(void)
680
680
gettimeofday (& tv , NULL );
681
681
fallback_seed_add (& c , & tv , sizeof (tv ));
682
682
/* Previous state. */
683
- fallback_seed_add (& c , RANDOM_G ( fallback_seed ) , 20 );
683
+ fallback_seed_add (& c , state -> seed , 20 );
684
684
}
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;
687
687
688
688
uint64_t result = 0 ;
689
689
690
690
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 ));
692
692
}
693
693
694
694
return result ;
695
695
}
696
696
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
+
697
755
/* {{{ PHP_GINIT_FUNCTION */
698
756
static PHP_GINIT_FUNCTION (random )
699
757
{
700
- random_globals -> fallback_seed_initialized = false;
758
+ random_globals -> fallback_seed_state . initialized = false;
701
759
}
702
760
/* }}} */
703
761
0 commit comments