@@ -7,6 +7,7 @@ use crate::{
77 Errno , HostInterface , arch:: ioport:: serial_print_string,
88 host:: per_cpu_variables:: with_per_cpu_variables,
99} ;
10+ use rand_core:: { RngCore , SeedableRng } ;
1011
1112pub type LvbsLinuxKernel = crate :: LinuxKernel < HostLvbsInterface > ;
1213
@@ -102,16 +103,31 @@ unsafe impl litebox::platform::ThreadLocalStorageProvider for LvbsLinuxKernel {
102103
103104impl litebox:: platform:: CrngProvider for LvbsLinuxKernel {
104105 fn fill_bytes_crng ( & self , buf : & mut [ u8 ] ) {
105- // FIXME: generate real random data.
106- static RANDOM : spin:: mutex:: SpinMutex < litebox:: utils:: rng:: FastRng > =
107- spin:: mutex:: SpinMutex :: new ( litebox:: utils:: rng:: FastRng :: new_from_seed (
108- core:: num:: NonZeroU64 :: new ( 0x4d595df4d0f33173 ) . unwrap ( ) ,
109- ) ) ;
106+ static RANDOM : spin:: mutex:: SpinMutex < Option < rand_chacha:: ChaCha20Rng > > =
107+ spin:: mutex:: SpinMutex :: new ( None ) ;
108+
110109 let mut random = RANDOM . lock ( ) ;
111- for b in buf. chunks_mut ( 8 ) {
112- b. copy_from_slice ( & random. next_u64 ( ) . to_ne_bytes ( ) [ ..b. len ( ) ] ) ;
110+ random
111+ . get_or_insert_with ( || rand_chacha:: ChaCha20Rng :: from_seed ( rdrand_seed ( ) ) )
112+ . fill_bytes ( buf) ;
113+ }
114+ }
115+
116+ fn rdrand_seed ( ) -> <rand_chacha:: ChaCha20Rng as SeedableRng >:: Seed {
117+ let mut seed = <rand_chacha:: ChaCha20Rng as SeedableRng >:: Seed :: default ( ) ;
118+ for chunk in seed. chunks_mut ( 8 ) {
119+ let mut word = 0 ;
120+ loop {
121+ // Safety: `RDRAND` is available on the LVBS target CPUs. A false
122+ // carry flag means random data is temporarily unavailable.
123+ if unsafe { core:: arch:: x86_64:: _rdrand64_step ( & mut word) } == 1 {
124+ break ;
125+ }
126+ core:: hint:: spin_loop ( ) ;
113127 }
128+ chunk. copy_from_slice ( & word. to_ne_bytes ( ) [ ..chunk. len ( ) ] ) ;
114129 }
130+ seed
115131}
116132
117133pub struct HostLvbsInterface ;
0 commit comments