diff options
| author | Felipe Balbi <[email protected]> | 2025-12-11 11:38:56 -0800 |
|---|---|---|
| committer | Felipe Balbi <[email protected]> | 2025-12-11 11:38:56 -0800 |
| commit | 3284620b7940e7598373ff404445858e0e7858b8 (patch) | |
| tree | aca3a3a0cd74f0730cce16838a75e0e5715ae937 /embassy-mcxa | |
| parent | 26430facff49cf3d34bba84b4e287f57025fed4e (diff) | |
Replace AsyncTrng with Mode typestate
Diffstat (limited to 'embassy-mcxa')
| -rw-r--r-- | embassy-mcxa/src/trng.rs | 305 |
1 files changed, 115 insertions, 190 deletions
diff --git a/embassy-mcxa/src/trng.rs b/embassy-mcxa/src/trng.rs index 56fe8eca2..16c759841 100644 --- a/embassy-mcxa/src/trng.rs +++ b/embassy-mcxa/src/trng.rs | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | //! True Random Number Generator | 1 | //! True Random Number Generator |
| 2 | 2 | ||
| 3 | use core::marker::PhantomData; | ||
| 4 | |||
| 3 | use embassy_hal_internal::Peri; | 5 | use embassy_hal_internal::Peri; |
| 4 | use embassy_hal_internal::interrupt::InterruptExt; | 6 | use embassy_hal_internal::interrupt::InterruptExt; |
| 5 | use maitake_sync::WaitCell; | 7 | use maitake_sync::WaitCell; |
| @@ -13,73 +15,39 @@ use crate::peripherals::TRNG0; | |||
| 13 | 15 | ||
| 14 | static WAIT_CELL: WaitCell = WaitCell::new(); | 16 | static WAIT_CELL: WaitCell = WaitCell::new(); |
| 15 | 17 | ||
| 16 | /// TRNG Driver | 18 | #[allow(private_bounds)] |
| 17 | pub struct Trng<'d> { | 19 | pub trait Mode: sealed::SealedMode {} |
| 18 | _peri: Peri<'d, TRNG0>, | ||
| 19 | } | ||
| 20 | 20 | ||
| 21 | impl<'d> Trng<'d> { | 21 | mod sealed { |
| 22 | /// Instantiates a new TRNG peripheral driver with 128 samples of entropy. | 22 | pub trait SealedMode {} |
| 23 | pub fn new_128(_peri: Peri<'d, TRNG0>) -> Self { | 23 | } |
| 24 | Self::new_inner( | ||
| 25 | _peri, | ||
| 26 | Config { | ||
| 27 | sample_size: 128, | ||
| 28 | retry_count: 1, | ||
| 29 | long_run_limit_max: 29, | ||
| 30 | monobit_limit_max: 94, | ||
| 31 | monobit_limit_range: 61, | ||
| 32 | run_length1_limit_max: 39, | ||
| 33 | run_length1_limit_range: 39, | ||
| 34 | run_length2_limit_max: 24, | ||
| 35 | run_length2_limit_range: 25, | ||
| 36 | run_length3_limit_max: 17, | ||
| 37 | run_length3_limit_range: 18, | ||
| 38 | ..Default::default() | ||
| 39 | }, | ||
| 40 | ) | ||
| 41 | } | ||
| 42 | 24 | ||
| 43 | /// Instantiates a new TRNG peripheral driver with 256 samples of entropy. | 25 | macro_rules! define_mode { |
| 44 | pub fn new_256(_peri: Peri<'d, TRNG0>) -> Self { | 26 | ($mode:ident) => { |
| 45 | Self::new_inner( | 27 | pub struct $mode; |
| 46 | _peri, | 28 | impl sealed::SealedMode for $mode {} |
| 47 | Config { | 29 | impl Mode for $mode {} |
| 48 | sample_size: 256, | 30 | }; |
| 49 | retry_count: 1, | 31 | } |
| 50 | long_run_limit_max: 31, | ||
| 51 | monobit_limit_max: 171, | ||
| 52 | monobit_limit_range: 86, | ||
| 53 | run_length1_limit_max: 63, | ||
| 54 | run_length1_limit_range: 56, | ||
| 55 | run_length2_limit_max: 38, | ||
| 56 | run_length2_limit_range: 38, | ||
| 57 | run_length3_limit_max: 25, | ||
| 58 | run_length3_limit_range: 26, | ||
| 59 | ..Default::default() | ||
| 60 | }, | ||
| 61 | ) | ||
| 62 | } | ||
| 63 | 32 | ||
| 64 | /// Instantiates a new TRNG peripheral driver with 512 samples of entropy. | 33 | define_mode!(Blocking); |
| 65 | pub fn new_512(_peri: Peri<'d, TRNG0>) -> Self { | 34 | define_mode!(Async); |
| 66 | Self::new_inner(_peri, Default::default()) | ||
| 67 | } | ||
| 68 | 35 | ||
| 69 | /// Instantiates a new TRNG peripheral driver. | 36 | /// TRNG Driver |
| 70 | /// | 37 | pub struct Trng<'d, M: Mode> { |
| 71 | /// NOTE: this constructor makes not attempt at validating the | 38 | _peri: Peri<'d, TRNG0>, |
| 72 | /// parameters. If you get this wrong, the security guarantees of | 39 | _phantom: PhantomData<M>, |
| 73 | /// the TRNG with regards to entropy may be violated | 40 | } |
| 74 | pub fn new_with_custom_config(_peri: Peri<'d, TRNG0>, config: Config) -> Self { | ||
| 75 | Self::new_inner(_peri, config) | ||
| 76 | } | ||
| 77 | 41 | ||
| 42 | impl<'d, M: Mode> Trng<'d, M> { | ||
| 78 | fn new_inner(_peri: Peri<'d, TRNG0>, config: Config) -> Self { | 43 | fn new_inner(_peri: Peri<'d, TRNG0>, config: Config) -> Self { |
| 79 | _ = unsafe { enable_and_reset::<TRNG0>(&NoConfig) }; | 44 | _ = unsafe { enable_and_reset::<TRNG0>(&NoConfig) }; |
| 80 | 45 | ||
| 81 | Self::configure(config); | 46 | Self::configure(config); |
| 82 | Self { _peri } | 47 | Self { |
| 48 | _peri, | ||
| 49 | _phantom: PhantomData, | ||
| 50 | } | ||
| 83 | } | 51 | } |
| 84 | 52 | ||
| 85 | fn configure(config: Config) { | 53 | fn configure(config: Config) { |
| @@ -241,31 +209,72 @@ impl<'d> Trng<'d> { | |||
| 241 | } | 209 | } |
| 242 | } | 210 | } |
| 243 | 211 | ||
| 244 | impl Drop for Trng<'_> { | 212 | impl<'d> Trng<'d, Blocking> { |
| 245 | fn drop(&mut self) { | 213 | /// Instantiates a new TRNG peripheral driver with 128 samples of entropy. |
| 246 | // wait until allowed to stop | 214 | pub fn new_blocking_128(_peri: Peri<'d, TRNG0>) -> Self { |
| 247 | while regs().mctl().read().tstop_ok().bit_is_clear() {} | 215 | Self::new_inner( |
| 248 | // stop | 216 | _peri, |
| 249 | Self::stop(); | 217 | Config { |
| 250 | // reset the TRNG | 218 | sample_size: 128, |
| 251 | regs().mctl().write(|w| w.rst_def().set_bit()); | 219 | retry_count: 1, |
| 220 | long_run_limit_max: 29, | ||
| 221 | monobit_limit_max: 94, | ||
| 222 | monobit_limit_range: 61, | ||
| 223 | run_length1_limit_max: 39, | ||
| 224 | run_length1_limit_range: 39, | ||
| 225 | run_length2_limit_max: 24, | ||
| 226 | run_length2_limit_range: 25, | ||
| 227 | run_length3_limit_max: 17, | ||
| 228 | run_length3_limit_range: 18, | ||
| 229 | ..Default::default() | ||
| 230 | }, | ||
| 231 | ) | ||
| 252 | } | 232 | } |
| 253 | } | ||
| 254 | 233 | ||
| 255 | /// TRNG Async Driver | 234 | /// Instantiates a new TRNG peripheral driver with 256 samples of entropy. |
| 256 | pub struct AsyncTrng<'d> { | 235 | pub fn new_blocking_256(_peri: Peri<'d, TRNG0>) -> Self { |
| 257 | _peri: Peri<'d, TRNG0>, | 236 | Self::new_inner( |
| 237 | _peri, | ||
| 238 | Config { | ||
| 239 | sample_size: 256, | ||
| 240 | retry_count: 1, | ||
| 241 | long_run_limit_max: 31, | ||
| 242 | monobit_limit_max: 171, | ||
| 243 | monobit_limit_range: 86, | ||
| 244 | run_length1_limit_max: 63, | ||
| 245 | run_length1_limit_range: 56, | ||
| 246 | run_length2_limit_max: 38, | ||
| 247 | run_length2_limit_range: 38, | ||
| 248 | run_length3_limit_max: 25, | ||
| 249 | run_length3_limit_range: 26, | ||
| 250 | ..Default::default() | ||
| 251 | }, | ||
| 252 | ) | ||
| 253 | } | ||
| 254 | |||
| 255 | /// Instantiates a new TRNG peripheral driver with 512 samples of entropy. | ||
| 256 | pub fn new_blocking_512(_peri: Peri<'d, TRNG0>) -> Self { | ||
| 257 | Self::new_inner(_peri, Default::default()) | ||
| 258 | } | ||
| 259 | |||
| 260 | /// Instantiates a new TRNG peripheral driver. | ||
| 261 | /// | ||
| 262 | /// NOTE: this constructor makes no attempt at validating the | ||
| 263 | /// parameters. If you get this wrong, the security guarantees of | ||
| 264 | /// the TRNG with regards to entropy may be violated | ||
| 265 | pub fn new_blocking_with_custom_config(_peri: Peri<'d, TRNG0>, config: Config) -> Self { | ||
| 266 | Self::new_inner(_peri, config) | ||
| 267 | } | ||
| 258 | } | 268 | } |
| 259 | 269 | ||
| 260 | impl<'d> AsyncTrng<'d> { | 270 | impl<'d> Trng<'d, Async> { |
| 261 | /// Instantiates a new TRNG peripheral driver with 128 samples of entropy. | 271 | /// Instantiates a new TRNG peripheral driver with 128 samples of entropy. |
| 262 | pub fn new_128( | 272 | pub fn new_128( |
| 263 | _peri: Peri<'d, TRNG0>, | 273 | _peri: Peri<'d, TRNG0>, |
| 264 | _irq: impl crate::interrupt::typelevel::Binding<typelevel::TRNG0, InterruptHandler> + 'd, | 274 | _irq: impl crate::interrupt::typelevel::Binding<typelevel::TRNG0, InterruptHandler> + 'd, |
| 265 | ) -> Self { | 275 | ) -> Self { |
| 266 | Self::new_inner( | 276 | let inst = Self::new_inner( |
| 267 | _peri, | 277 | _peri, |
| 268 | _irq, | ||
| 269 | Config { | 278 | Config { |
| 270 | sample_size: 128, | 279 | sample_size: 128, |
| 271 | retry_count: 1, | 280 | retry_count: 1, |
| @@ -280,7 +289,12 @@ impl<'d> AsyncTrng<'d> { | |||
| 280 | run_length3_limit_range: 18, | 289 | run_length3_limit_range: 18, |
| 281 | ..Default::default() | 290 | ..Default::default() |
| 282 | }, | 291 | }, |
| 283 | ) | 292 | ); |
| 293 | crate::pac::Interrupt::TRNG0.unpend(); | ||
| 294 | unsafe { | ||
| 295 | crate::pac::Interrupt::TRNG0.enable(); | ||
| 296 | } | ||
| 297 | inst | ||
| 284 | } | 298 | } |
| 285 | 299 | ||
| 286 | /// Instantiates a new TRNG peripheral driver with 256 samples of entropy. | 300 | /// Instantiates a new TRNG peripheral driver with 256 samples of entropy. |
| @@ -288,9 +302,8 @@ impl<'d> AsyncTrng<'d> { | |||
| 288 | _peri: Peri<'d, TRNG0>, | 302 | _peri: Peri<'d, TRNG0>, |
| 289 | _irq: impl crate::interrupt::typelevel::Binding<typelevel::TRNG0, InterruptHandler> + 'd, | 303 | _irq: impl crate::interrupt::typelevel::Binding<typelevel::TRNG0, InterruptHandler> + 'd, |
| 290 | ) -> Self { | 304 | ) -> Self { |
| 291 | Self::new_inner( | 305 | let inst = Self::new_inner( |
| 292 | _peri, | 306 | _peri, |
| 293 | _irq, | ||
| 294 | Config { | 307 | Config { |
| 295 | sample_size: 256, | 308 | sample_size: 256, |
| 296 | retry_count: 1, | 309 | retry_count: 1, |
| @@ -305,7 +318,12 @@ impl<'d> AsyncTrng<'d> { | |||
| 305 | run_length3_limit_range: 26, | 318 | run_length3_limit_range: 26, |
| 306 | ..Default::default() | 319 | ..Default::default() |
| 307 | }, | 320 | }, |
| 308 | ) | 321 | ); |
| 322 | crate::pac::Interrupt::TRNG0.unpend(); | ||
| 323 | unsafe { | ||
| 324 | crate::pac::Interrupt::TRNG0.enable(); | ||
| 325 | } | ||
| 326 | inst | ||
| 309 | } | 327 | } |
| 310 | 328 | ||
| 311 | /// Instantiates a new TRNG peripheral driver with 512 samples of entropy. | 329 | /// Instantiates a new TRNG peripheral driver with 512 samples of entropy. |
| @@ -313,12 +331,17 @@ impl<'d> AsyncTrng<'d> { | |||
| 313 | _peri: Peri<'d, TRNG0>, | 331 | _peri: Peri<'d, TRNG0>, |
| 314 | _irq: impl crate::interrupt::typelevel::Binding<typelevel::TRNG0, InterruptHandler> + 'd, | 332 | _irq: impl crate::interrupt::typelevel::Binding<typelevel::TRNG0, InterruptHandler> + 'd, |
| 315 | ) -> Self { | 333 | ) -> Self { |
| 316 | Self::new_inner(_peri, _irq, Default::default()) | 334 | let inst = Self::new_inner(_peri, Default::default()); |
| 335 | crate::pac::Interrupt::TRNG0.unpend(); | ||
| 336 | unsafe { | ||
| 337 | crate::pac::Interrupt::TRNG0.enable(); | ||
| 338 | } | ||
| 339 | inst | ||
| 317 | } | 340 | } |
| 318 | 341 | ||
| 319 | /// Instantiates a new TRNG peripheral driver. | 342 | /// Instantiates a new TRNG peripheral driver. |
| 320 | /// | 343 | /// |
| 321 | /// NOTE: this constructor makes not attempt at validating the | 344 | /// NOTE: this constructor makes no attempt at validating the |
| 322 | /// parameters. If you get this wrong, the security guarantees of | 345 | /// parameters. If you get this wrong, the security guarantees of |
| 323 | /// the TRNG with regards to entropy may be violated | 346 | /// the TRNG with regards to entropy may be violated |
| 324 | pub fn new_with_custom_config( | 347 | pub fn new_with_custom_config( |
| @@ -326,24 +349,12 @@ impl<'d> AsyncTrng<'d> { | |||
| 326 | _irq: impl crate::interrupt::typelevel::Binding<typelevel::TRNG0, InterruptHandler> + 'd, | 349 | _irq: impl crate::interrupt::typelevel::Binding<typelevel::TRNG0, InterruptHandler> + 'd, |
| 327 | config: Config, | 350 | config: Config, |
| 328 | ) -> Self { | 351 | ) -> Self { |
| 329 | Self::new_inner(_peri, _irq, config) | 352 | let inst = Self::new_inner(_peri, config); |
| 330 | } | ||
| 331 | |||
| 332 | fn new_inner( | ||
| 333 | _peri: Peri<'d, TRNG0>, | ||
| 334 | _irq: impl crate::interrupt::typelevel::Binding<typelevel::TRNG0, InterruptHandler> + 'd, | ||
| 335 | config: Config, | ||
| 336 | ) -> Self { | ||
| 337 | _ = unsafe { enable_and_reset::<TRNG0>(&NoConfig) }; | ||
| 338 | |||
| 339 | Trng::configure(config); | ||
| 340 | |||
| 341 | crate::pac::Interrupt::TRNG0.unpend(); | 353 | crate::pac::Interrupt::TRNG0.unpend(); |
| 342 | unsafe { | 354 | unsafe { |
| 343 | crate::pac::Interrupt::TRNG0.enable(); | 355 | crate::pac::Interrupt::TRNG0.enable(); |
| 344 | } | 356 | } |
| 345 | 357 | inst | |
| 346 | Self { _peri } | ||
| 347 | } | 358 | } |
| 348 | 359 | ||
| 349 | fn enable_ints() { | 360 | fn enable_ints() { |
| @@ -377,88 +388,39 @@ impl<'d> AsyncTrng<'d> { | |||
| 377 | return Ok(()); // nothing to fill | 388 | return Ok(()); // nothing to fill |
| 378 | } | 389 | } |
| 379 | 390 | ||
| 380 | Trng::start(); | ||
| 381 | for chunk in buf.chunks_mut(32) { | 391 | for chunk in buf.chunks_mut(32) { |
| 382 | Self::wait_for_generation().await?; | 392 | Self::wait_for_generation().await?; |
| 383 | Trng::fill_chunk(chunk); | 393 | Self::fill_chunk(chunk); |
| 384 | } | 394 | } |
| 385 | Trng::stop(); | ||
| 386 | 395 | ||
| 387 | Ok(()) | 396 | Ok(()) |
| 388 | } | 397 | } |
| 389 | 398 | ||
| 390 | /// Return a random u32, async version. | 399 | /// Return a random u32, async version. |
| 391 | pub async fn async_next_u32(&mut self) -> Result<u32, Error> { | 400 | pub async fn async_next_u32(&mut self) -> Result<u32, Error> { |
| 392 | Trng::start(); | ||
| 393 | Self::wait_for_generation().await?; | 401 | Self::wait_for_generation().await?; |
| 394 | // New random bytes are generated only after reading ENT7 | 402 | // New random bytes are generated only after reading ENT7 |
| 395 | let result = regs().ent(7).read().bits(); | 403 | Ok(regs().ent(7).read().bits()) |
| 396 | Trng::stop(); | ||
| 397 | |||
| 398 | Ok(result) | ||
| 399 | } | 404 | } |
| 400 | 405 | ||
| 401 | /// Return a random u64, async version. | 406 | /// Return a random u64, async version. |
| 402 | pub async fn async_next_u64(&mut self) -> Result<u64, Error> { | 407 | pub async fn async_next_u64(&mut self) -> Result<u64, Error> { |
| 403 | Trng::start(); | ||
| 404 | Self::wait_for_generation().await?; | 408 | Self::wait_for_generation().await?; |
| 405 | 409 | ||
| 406 | let mut result = u64::from(regs().ent(6).read().bits()) << 32; | 410 | let mut result = u64::from(regs().ent(6).read().bits()) << 32; |
| 407 | // New random bytes are generated only after reading ENT7 | 411 | // New random bytes are generated only after reading ENT7 |
| 408 | result |= u64::from(regs().ent(7).read().bits()); | 412 | result |= u64::from(regs().ent(7).read().bits()); |
| 409 | 413 | ||
| 410 | Trng::stop(); | ||
| 411 | |||
| 412 | Ok(result) | 414 | Ok(result) |
| 413 | } | 415 | } |
| 414 | |||
| 415 | // Blocking API | ||
| 416 | |||
| 417 | /// Fill the buffer with random bytes, blocking version. | ||
| 418 | pub fn blocking_fill_bytes(&mut self, buf: &mut [u8]) { | ||
| 419 | if buf.is_empty() { | ||
| 420 | return; // nothing to fill | ||
| 421 | } | ||
| 422 | |||
| 423 | Trng::start(); | ||
| 424 | for chunk in buf.chunks_mut(32) { | ||
| 425 | Trng::blocking_wait_for_generation(); | ||
| 426 | Trng::fill_chunk(chunk); | ||
| 427 | } | ||
| 428 | Trng::stop(); | ||
| 429 | } | ||
| 430 | |||
| 431 | /// Return a random u32, blocking version. | ||
| 432 | pub fn blocking_next_u32(&mut self) -> u32 { | ||
| 433 | Trng::start(); | ||
| 434 | Trng::blocking_wait_for_generation(); | ||
| 435 | let result = regs().ent(0).read().bits(); | ||
| 436 | |||
| 437 | // New random bytes are generated only after reading ENT7 | ||
| 438 | let _ = regs().ent(7).read().bits(); | ||
| 439 | Trng::stop(); | ||
| 440 | |||
| 441 | result | ||
| 442 | } | ||
| 443 | |||
| 444 | /// Return a random u64, blocking version. | ||
| 445 | pub fn blocking_next_u64(&mut self) -> u64 { | ||
| 446 | Trng::start(); | ||
| 447 | Trng::blocking_wait_for_generation(); | ||
| 448 | |||
| 449 | let mut result = u64::from(regs().ent(0).read().bits()) << 32; | ||
| 450 | result |= u64::from(regs().ent(1).read().bits()); | ||
| 451 | |||
| 452 | // New random bytes are generated only after reading ENT7 | ||
| 453 | let _ = regs().ent(7).read().bits(); | ||
| 454 | Trng::stop(); | ||
| 455 | |||
| 456 | result | ||
| 457 | } | ||
| 458 | } | 416 | } |
| 459 | 417 | ||
| 460 | impl Drop for AsyncTrng<'_> { | 418 | impl<M: Mode> Drop for Trng<'_, M> { |
| 461 | fn drop(&mut self) { | 419 | fn drop(&mut self) { |
| 420 | // wait until allowed to stop | ||
| 421 | while regs().mctl().read().tstop_ok().bit_is_clear() {} | ||
| 422 | // stop | ||
| 423 | Self::stop(); | ||
| 462 | // reset the TRNG | 424 | // reset the TRNG |
| 463 | regs().mctl().write(|w| w.rst_def().set_bit()); | 425 | regs().mctl().write(|w| w.rst_def().set_bit()); |
| 464 | } | 426 | } |
| @@ -678,44 +640,7 @@ impl From<OscMode> for TrngEntCtl { | |||
| 678 | } | 640 | } |
| 679 | } | 641 | } |
| 680 | 642 | ||
| 681 | impl<'d> rand_core_06::RngCore for Trng<'d> { | 643 | impl<'d, M: Mode> rand_core_06::RngCore for Trng<'d, M> { |
| 682 | fn next_u32(&mut self) -> u32 { | ||
| 683 | self.blocking_next_u32() | ||
| 684 | } | ||
| 685 | |||
| 686 | fn next_u64(&mut self) -> u64 { | ||
| 687 | self.blocking_next_u64() | ||
| 688 | } | ||
| 689 | |||
| 690 | fn fill_bytes(&mut self, dest: &mut [u8]) { | ||
| 691 | self.blocking_fill_bytes(dest); | ||
| 692 | } | ||
| 693 | |||
| 694 | fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> { | ||
| 695 | self.blocking_fill_bytes(dest); | ||
| 696 | Ok(()) | ||
| 697 | } | ||
| 698 | } | ||
| 699 | |||
| 700 | impl<'d> rand_core_06::CryptoRng for Trng<'d> {} | ||
| 701 | |||
| 702 | impl<'d> rand_core_09::RngCore for Trng<'d> { | ||
| 703 | fn next_u32(&mut self) -> u32 { | ||
| 704 | self.blocking_next_u32() | ||
| 705 | } | ||
| 706 | |||
| 707 | fn next_u64(&mut self) -> u64 { | ||
| 708 | self.blocking_next_u64() | ||
| 709 | } | ||
| 710 | |||
| 711 | fn fill_bytes(&mut self, dest: &mut [u8]) { | ||
| 712 | self.blocking_fill_bytes(dest); | ||
| 713 | } | ||
| 714 | } | ||
| 715 | |||
| 716 | impl<'d> rand_core_09::CryptoRng for Trng<'d> {} | ||
| 717 | |||
| 718 | impl<'d> rand_core_06::RngCore for AsyncTrng<'d> { | ||
| 719 | fn next_u32(&mut self) -> u32 { | 644 | fn next_u32(&mut self) -> u32 { |
| 720 | self.blocking_next_u32() | 645 | self.blocking_next_u32() |
| 721 | } | 646 | } |
| @@ -734,9 +659,9 @@ impl<'d> rand_core_06::RngCore for AsyncTrng<'d> { | |||
| 734 | } | 659 | } |
| 735 | } | 660 | } |
| 736 | 661 | ||
| 737 | impl<'d> rand_core_06::CryptoRng for AsyncTrng<'d> {} | 662 | impl<'d, M: Mode> rand_core_06::CryptoRng for Trng<'d, M> {} |
| 738 | 663 | ||
| 739 | impl<'d> rand_core_09::RngCore for AsyncTrng<'d> { | 664 | impl<'d, M: Mode> rand_core_09::RngCore for Trng<'d, M> { |
| 740 | fn next_u32(&mut self) -> u32 { | 665 | fn next_u32(&mut self) -> u32 { |
| 741 | self.blocking_next_u32() | 666 | self.blocking_next_u32() |
| 742 | } | 667 | } |
| @@ -750,4 +675,4 @@ impl<'d> rand_core_09::RngCore for AsyncTrng<'d> { | |||
| 750 | } | 675 | } |
| 751 | } | 676 | } |
| 752 | 677 | ||
| 753 | impl<'d> rand_core_09::CryptoRng for AsyncTrng<'d> {} | 678 | impl<'d, M: Mode> rand_core_09::CryptoRng for Trng<'d, M> {} |
