1use alloc::collections::VecDeque;
25use alloc::sync::Arc;
26use alloc::vec::Vec;
27use core::any::Any;
28use spin::{Mutex, Once};
29
30use crate::device::char::CharDevice;
31use crate::device::{Device, DeviceType};
32use crate::object::capability::{ControlOps, MemoryMappingOps, Selectable};
33
34const RANDOM_POOL_SIZE: usize = 4096;
36
37pub trait EntropySource: Send + Sync {
39 fn name(&self) -> &'static str;
41
42 fn read_entropy(&self, buffer: &mut [u8]) -> usize;
52
53 fn is_available(&self) -> bool;
55}
56
57pub struct RandomManager {
62 sources: Mutex<Vec<Arc<dyn EntropySource>>>,
64 pool: Mutex<VecDeque<u8>>,
66}
67
68impl RandomManager {
69 fn new() -> Self {
71 Self {
72 sources: Mutex::new(Vec::new()),
73 pool: Mutex::new(VecDeque::with_capacity(RANDOM_POOL_SIZE)),
74 }
75 }
76
77 fn instance() -> &'static RandomManager {
79 static INSTANCE: Once<RandomManager> = Once::new();
80 INSTANCE.call_once(|| RandomManager::new())
81 }
82
83 pub fn register_entropy_source(source: Arc<dyn EntropySource>) {
89 let manager = Self::instance();
90 let mut sources = manager.sources.lock();
91 crate::early_println!("[Random] Registering entropy source: {}", source.name());
92 sources.push(source);
93 }
94
95 fn fill_pool(&self) -> Result<usize, &'static str> {
97 let sources = self.sources.lock();
98
99 if sources.is_empty() {
100 return Err("No entropy sources available");
101 }
102
103 let mut total_bytes = 0;
104 let mut temp_buffer = [0u8; 256];
105
106 for source in sources.iter() {
108 if !source.is_available() {
109 continue;
110 }
111
112 let bytes_read = source.read_entropy(&mut temp_buffer);
113 if bytes_read > 0 {
114 let mut pool = self.pool.lock();
115 let available_space = RANDOM_POOL_SIZE.saturating_sub(pool.len());
116 let bytes_to_add = bytes_read.min(available_space);
117
118 if bytes_to_add < bytes_read {
119 crate::early_println!(
120 "[Random] Pool full, discarding {} entropy bytes",
121 bytes_read - bytes_to_add
122 );
123 }
124
125 for i in 0..bytes_to_add {
126 pool.push_back(temp_buffer[i]);
127 }
128 total_bytes += bytes_to_add;
129 break; }
131 }
132
133 if total_bytes == 0 {
134 Err("Failed to read from any entropy source")
135 } else {
136 Ok(total_bytes)
137 }
138 }
139
140 pub fn get_random_bytes(buffer: &mut [u8]) -> usize {
150 let manager = Self::instance();
151 let mut bytes_read = 0;
152
153 for i in 0..buffer.len() {
154 let mut pool = manager.pool.lock();
156 if let Some(byte) = pool.pop_front() {
157 buffer[i] = byte;
158 bytes_read += 1;
159 } else {
160 drop(pool);
162 if manager.fill_pool().is_err() {
163 return bytes_read;
165 }
166 pool = manager.pool.lock();
168 if let Some(byte) = pool.pop_front() {
169 buffer[i] = byte;
170 bytes_read += 1;
171 } else {
172 drop(pool);
174 return bytes_read;
175 }
176 }
177 }
178
179 bytes_read
180 }
181
182 pub fn get_random_byte() -> Option<u8> {
184 let mut buffer = [0u8; 1];
185 if Self::get_random_bytes(&mut buffer) == 1 {
186 Some(buffer[0])
187 } else {
188 None
189 }
190 }
191}
192
193pub struct RandomCharDevice;
197
198impl RandomCharDevice {
199 pub fn new() -> Self {
200 Self
201 }
202}
203
204impl Device for RandomCharDevice {
205 fn device_type(&self) -> DeviceType {
206 DeviceType::Char
207 }
208
209 fn name(&self) -> &'static str {
210 "random"
211 }
212
213 fn as_any(&self) -> &dyn Any {
214 self
215 }
216
217 fn as_any_mut(&mut self) -> &mut dyn Any {
218 self
219 }
220
221 fn as_char_device(&self) -> Option<&dyn CharDevice> {
222 Some(self)
223 }
224}
225
226impl CharDevice for RandomCharDevice {
227 fn read_byte(&self) -> Option<u8> {
228 RandomManager::get_random_byte()
229 }
230
231 fn write_byte(&self, _byte: u8) -> Result<(), &'static str> {
232 Err("Write not supported for random device")
233 }
234
235 fn can_read(&self) -> bool {
236 let manager = RandomManager::instance();
238 let sources = manager.sources.lock();
239 !sources.is_empty() && sources.iter().any(|s| s.is_available())
240 }
241
242 fn can_write(&self) -> bool {
243 false
244 }
245}
246
247impl ControlOps for RandomCharDevice {
248 fn control(&self, _command: u32, _arg: usize) -> Result<i32, &'static str> {
249 Err("Control operations not supported for random device")
250 }
251}
252
253impl MemoryMappingOps for RandomCharDevice {
254 fn get_mapping_info(
255 &self,
256 _offset: usize,
257 _length: usize,
258 ) -> Result<(usize, usize, bool), &'static str> {
259 Err("Memory mapping not supported for random device")
260 }
261}
262
263impl Selectable for RandomCharDevice {
264 fn wait_until_ready(
265 &self,
266 _interest: crate::object::capability::selectable::ReadyInterest,
267 _trapframe: &mut crate::arch::Trapframe,
268 _timeout_ticks: Option<u64>,
269 ) -> crate::object::capability::selectable::SelectWaitOutcome {
270 crate::object::capability::selectable::SelectWaitOutcome::Ready
271 }
272}