mirror of
https://github.com/zama-ai/tfhe-rs.git
synced 2026-01-09 14:47:56 -05:00
chore(csprng): use getrandom as random source for unix seeder
This commit is contained in:
committed by
Nicolas Sarlin
parent
baad6a6b49
commit
e2c7359057
@@ -33,6 +33,7 @@ rand = "0.8"
|
||||
rayon = "1.11"
|
||||
serde = { version = "1.0", default-features = false }
|
||||
wasm-bindgen = "0.2.100"
|
||||
getrandom = "0.2.8"
|
||||
|
||||
[profile.bench]
|
||||
lto = "fat"
|
||||
|
||||
@@ -14,6 +14,7 @@ rust-version = "1.72"
|
||||
[dependencies]
|
||||
aes = "0.8.2"
|
||||
rayon = { workspace = true, optional = true }
|
||||
getrandom = { workspace = true }
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
libc = "0.2.133"
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
use crate::seeders::{Seed, Seeder};
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
|
||||
/// A seeder which uses the `/dev/random` source on unix-like systems.
|
||||
/// A seeder which uses the system entropy source on unix-like systems.
|
||||
///
|
||||
/// If available, this will use `getrandom` or `getentropy` system call. Otherwise it will draw from
|
||||
/// `/dev/urandom` after successfully polling `/dev/random`.
|
||||
pub struct UnixSeeder {
|
||||
counter: u128,
|
||||
secret: u128,
|
||||
file: File,
|
||||
}
|
||||
|
||||
impl UnixSeeder {
|
||||
@@ -15,35 +14,34 @@ impl UnixSeeder {
|
||||
/// Important:
|
||||
/// ----------
|
||||
///
|
||||
/// This secret is used to ensure the quality of the seed in scenarios where `/dev/random` may
|
||||
/// be compromised.
|
||||
/// This secret is used to ensure the quality of the seed in scenarios where the system random
|
||||
/// source may be compromised.
|
||||
///
|
||||
/// The attack hypotheses are as follow:
|
||||
/// - `/dev/random` output can be predicted by a process running on the machine by just
|
||||
/// - The kernel random output can be predicted by a process running on the machine by just
|
||||
/// observing various states of the machine
|
||||
/// - The attacker cannot read data from the process where `tfhe-csprng` is running
|
||||
///
|
||||
/// Using a secret in `tfhe-csprng` allows to generate values that the attacker cannot
|
||||
/// predict, making this seeder secure on systems were `/dev/random` outputs can be
|
||||
/// predict, making this seeder secure on systems were the kernel random outputs can be
|
||||
/// predicted.
|
||||
pub fn new(secret: u128) -> UnixSeeder {
|
||||
let file = std::fs::File::open("/dev/random").expect("Failed to open /dev/random .");
|
||||
let counter = std::time::UNIX_EPOCH
|
||||
.elapsed()
|
||||
.expect("Failed to initialize unix seeder.")
|
||||
.as_nanos();
|
||||
UnixSeeder {
|
||||
secret,
|
||||
counter,
|
||||
file,
|
||||
}
|
||||
UnixSeeder { secret }
|
||||
}
|
||||
}
|
||||
|
||||
impl Seeder for UnixSeeder {
|
||||
/// Draws entropy from a system source to seed a CSPRNG.
|
||||
///
|
||||
/// It may be blocking at system startup if the kernel entropy pool has not been initialized,
|
||||
/// but should not be blocking after.
|
||||
///
|
||||
/// # Panics
|
||||
/// This may panic if the `getrandom` system call is not available and no file descriptor is
|
||||
/// available on the system.
|
||||
fn seed(&mut self) -> Seed {
|
||||
let output = self.secret ^ self.counter ^ dev_random(&mut self.file);
|
||||
self.counter = self.counter.wrapping_add(1);
|
||||
let output = self.secret ^ get_system_entropy();
|
||||
|
||||
Seed(output)
|
||||
}
|
||||
|
||||
@@ -52,11 +50,14 @@ impl Seeder for UnixSeeder {
|
||||
}
|
||||
}
|
||||
|
||||
fn dev_random(random: &mut File) -> u128 {
|
||||
fn get_system_entropy() -> u128 {
|
||||
let mut buf = [0u8; 16];
|
||||
random
|
||||
.read_exact(&mut buf[..])
|
||||
.expect("Failed to read from /dev/random .");
|
||||
// This will use the getrandom syscall if possible (from linux 3.17). This syscall is not
|
||||
// vulnerable to fd exhaustion since it directly pulls from kernel entropy sources.
|
||||
//
|
||||
// This syscall will use the urandom entropy source but block at startup until it is correctly
|
||||
// seeded. See <https://www.2uo.de/myths-about-urandom/> for a rational around random/urandom.
|
||||
getrandom::getrandom(&mut buf).expect("Failed to read entropy from system");
|
||||
u128::from_ne_bytes(buf)
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ serde_json = "1.0.96"
|
||||
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
|
||||
wasm-bindgen-test = "0.3"
|
||||
wasm-bindgen = { workspace = true }
|
||||
getrandom = { version = "0.2", features = ["js"] }
|
||||
getrandom = { workspace = true, features = ["js"] }
|
||||
|
||||
[target.'cfg(all(not(target_os = "windows"), not(target_arch = "wasm32")))'.dev-dependencies]
|
||||
rug = "1.19.1"
|
||||
|
||||
@@ -86,7 +86,7 @@ wasm-bindgen-rayon = { version = "1.3.0", optional = true }
|
||||
js-sys = { version = "0.3", optional = true }
|
||||
console_error_panic_hook = { version = "0.1.7", optional = true }
|
||||
serde-wasm-bindgen = { version = "0.6.0", optional = true }
|
||||
getrandom = { version = "0.2.8", optional = true }
|
||||
getrandom = { workspace = true, optional = true }
|
||||
bytemuck = { workspace = true }
|
||||
|
||||
tfhe-hpu-backend = { version = "0.2", path = "../backends/tfhe-hpu-backend", optional = true }
|
||||
|
||||
Reference in New Issue
Block a user