Skip to main content

rns_crypto/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2extern crate alloc;
3
4pub mod aes128;
5pub mod aes256;
6pub mod ed25519;
7pub mod hkdf;
8pub mod hmac;
9pub mod identity;
10pub mod pkcs7;
11pub mod sha256;
12pub mod sha512;
13pub mod token;
14pub mod x25519;
15
16/// Trait for random number generation.
17/// Callers provide an implementation; in `std` builds this wraps OS randomness.
18pub trait Rng {
19    fn fill_bytes(&mut self, dest: &mut [u8]);
20}
21
22/// Deterministic RNG for testing.
23pub struct FixedRng {
24    bytes: alloc::vec::Vec<u8>,
25    pos: usize,
26}
27
28impl FixedRng {
29    pub fn new(bytes: &[u8]) -> Self {
30        Self {
31            bytes: bytes.to_vec(),
32            pos: 0,
33        }
34    }
35}
36
37impl Rng for FixedRng {
38    fn fill_bytes(&mut self, dest: &mut [u8]) {
39        for b in dest.iter_mut() {
40            *b = self.bytes[self.pos % self.bytes.len()];
41            self.pos += 1;
42        }
43    }
44}
45
46/// OS-backed RNG using getrandom(2) syscall on Linux.
47#[cfg(feature = "std")]
48pub struct OsRng;
49
50#[cfg(feature = "std")]
51impl Rng for OsRng {
52    fn fill_bytes(&mut self, dest: &mut [u8]) {
53        // ESP-IDF: use hardware RNG via esp_fill_random
54        #[cfg(target_os = "espidf")]
55        {
56            unsafe {
57                esp_idf_sys::esp_fill_random(
58                    dest.as_mut_ptr() as *mut core::ffi::c_void,
59                    dest.len(),
60                );
61            }
62        }
63        #[cfg(not(target_os = "espidf"))]
64        {
65            use std::io::Read;
66            let mut f = std::fs::File::open("/dev/urandom").expect("Failed to open /dev/urandom");
67            f.read_exact(dest)
68                .expect("Failed to read from /dev/urandom");
69        }
70    }
71}