aboutsummaryrefslogtreecommitdiffstats
path: root/src/sys.rs
diff options
context:
space:
mode:
authormurilo ijanc2026-03-24 15:04:03 -0300
committermurilo ijanc2026-03-24 15:04:03 -0300
commit9821aabf0b50d2487b07502d3d2cd89e7d62bdbe (patch)
tree53da095ff90cc755bac3d4bf699172b5e8cd07d6 /src/sys.rs
downloadtesseras-dht-0.1.0.tar.gz
Initial commitv0.1.0
NAT-aware Kademlia DHT library for peer-to-peer networks. Features: - Distributed key-value storage (iterative FIND_NODE, FIND_VALUE, STORE) - NAT traversal via DTUN hole-punching and proxy relay - Reliable Datagram Protocol (RDP) with 7-state connection machine - Datagram transport with automatic fragmentation/reassembly - Ed25519 packet authentication - 256-bit node IDs (Ed25519 public keys) - Rate limiting, ban list, and eclipse attack mitigation - Persistence and metrics - OpenBSD and Linux support
Diffstat (limited to 'src/sys.rs')
-rw-r--r--src/sys.rs127
1 files changed, 127 insertions, 0 deletions
diff --git a/src/sys.rs b/src/sys.rs
new file mode 100644
index 0000000..e4d5b7e
--- /dev/null
+++ b/src/sys.rs
@@ -0,0 +1,127 @@
+//! Cryptographically secure random bytes.
+//!
+//! Uses the best available platform source:
+//! - OpenBSD/macOS: arc4random_buf(3)
+//! - Linux/FreeBSD: getrandom(2)
+//! - Fallback: /dev/urandom
+
+/// Fill buffer with cryptographically secure random
+/// bytes.
+pub fn random_bytes(buf: &mut [u8]) {
+ platform::fill(buf);
+}
+
+#[cfg(any(target_os = "openbsd", target_os = "macos"))]
+mod platform {
+ use std::ffi::c_void;
+
+ // SAFETY: arc4random_buf always fills the entire
+ // buffer. Pointer valid from mutable slice.
+ unsafe extern "C" {
+ fn arc4random_buf(buf: *mut c_void, nbytes: usize);
+ }
+
+ pub fn fill(buf: &mut [u8]) {
+ unsafe {
+ arc4random_buf(buf.as_mut_ptr() as *mut c_void, buf.len());
+ }
+ }
+}
+
+#[cfg(target_os = "linux")]
+mod platform {
+ pub fn fill(buf: &mut [u8]) {
+ // getrandom(2) — available since Linux 3.17
+ // Flags: 0 = block until entropy available
+ let ret = unsafe {
+ libc_getrandom(
+ buf.as_mut_ptr() as *mut std::ffi::c_void,
+ buf.len(),
+ 0,
+ )
+ };
+ if ret < 0 {
+ // Fallback to /dev/urandom
+ urandom_fill(buf);
+ }
+ }
+
+ unsafe extern "C" {
+ fn getrandom(
+ buf: *mut std::ffi::c_void,
+ buflen: usize,
+ flags: std::ffi::c_uint,
+ ) -> isize;
+ }
+
+ // Rename to avoid conflict with the syscall
+ unsafe fn libc_getrandom(
+ buf: *mut std::ffi::c_void,
+ buflen: usize,
+ flags: std::ffi::c_uint,
+ ) -> isize {
+ getrandom(buf, buflen, flags)
+ }
+
+ fn urandom_fill(buf: &mut [u8]) {
+ use std::io::Read;
+ let mut f = std::fs::File::open("/dev/urandom").expect(
+ "FATAL: cannot open /dev/urandom — no secure randomness available",
+ );
+ f.read_exact(buf).expect("FATAL: cannot read /dev/urandom");
+ }
+}
+
+#[cfg(target_os = "freebsd")]
+mod platform {
+ use std::ffi::c_void;
+
+ unsafe extern "C" {
+ fn arc4random_buf(buf: *mut c_void, nbytes: usize);
+ }
+
+ pub fn fill(buf: &mut [u8]) {
+ unsafe {
+ arc4random_buf(buf.as_mut_ptr() as *mut c_void, buf.len());
+ }
+ }
+}
+
+#[cfg(not(any(
+ target_os = "openbsd",
+ target_os = "macos",
+ target_os = "linux",
+ target_os = "freebsd"
+)))]
+mod platform {
+ pub fn fill(buf: &mut [u8]) {
+ use std::io::Read;
+ let mut f = std::fs::File::open("/dev/urandom").expect(
+ "FATAL: cannot open /dev/urandom — no secure randomness available",
+ );
+ f.read_exact(buf).expect("FATAL: cannot read /dev/urandom");
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn random_bytes_not_zero() {
+ let mut buf = [0u8; 32];
+ random_bytes(&mut buf);
+
+ // Probability of all zeros: 2^-256
+ assert!(buf.iter().any(|&b| b != 0));
+ }
+
+ #[test]
+ fn random_bytes_different_calls() {
+ let mut a = [0u8; 32];
+ let mut b = [0u8; 32];
+ random_bytes(&mut a);
+ random_bytes(&mut b);
+ assert_ne!(a, b);
+ }
+}