2024-01-16 02:44:48 +00:00
|
|
|
//! Utilities for reading entropy from secure sources.
|
|
|
|
|
2024-01-10 00:59:58 +00:00
|
|
|
use std::{fs::{read_dir, read_to_string, File}, io::Read};
|
2023-09-21 22:30:48 +00:00
|
|
|
|
|
|
|
static WARNING_LINKS: [&str; 1] =
|
|
|
|
["https://lore.kernel.org/lkml/20211223141113.1240679-2-Jason@zx2c4.com/"];
|
|
|
|
|
|
|
|
fn ensure_safe_kernel_version() {
|
|
|
|
let kernel_version = read_to_string("/proc/version").expect("/proc/version");
|
|
|
|
let v = kernel_version
|
|
|
|
.split(' ')
|
|
|
|
.nth(2)
|
|
|
|
.expect("Unable to parse kernel version")
|
|
|
|
.split('.')
|
|
|
|
.take(2)
|
|
|
|
.map(str::parse)
|
|
|
|
.map(|x| x.expect("Unable to parse kernel version number"))
|
|
|
|
.collect::<Vec<u32>>();
|
|
|
|
let [major, minor, ..] = v.as_slice() else {
|
|
|
|
panic!("Unable to determine major and minor: {kernel_version}");
|
|
|
|
};
|
|
|
|
assert!(
|
|
|
|
[major, minor] > [&5, &4],
|
|
|
|
"kernel can't generate clean entropy: {}",
|
|
|
|
WARNING_LINKS[0]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn ensure_offline() {
|
|
|
|
let paths = read_dir("/sys/class/net").expect("Unable to read network interfaces");
|
|
|
|
for entry in paths {
|
|
|
|
let mut path = entry.expect("Unable to read directory entry").path();
|
|
|
|
if path
|
|
|
|
.as_os_str()
|
|
|
|
.to_str()
|
|
|
|
.expect("Unable to decode UTF-8 filepath")
|
|
|
|
.split('/')
|
|
|
|
.last()
|
2023-09-26 02:16:33 +00:00
|
|
|
.expect("No data in file path")
|
2023-09-21 22:30:48 +00:00
|
|
|
== "lo"
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
path.push("operstate");
|
|
|
|
let isup = read_to_string(&path).expect("Unable to read operstate of network interfaces");
|
|
|
|
assert_ne!(isup.trim(), "up", "No network interfaces should be up");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-16 02:44:48 +00:00
|
|
|
/// Ensure the system is safe.
|
2023-09-21 22:30:48 +00:00
|
|
|
pub fn ensure_safe() {
|
|
|
|
if !std::env::vars()
|
|
|
|
.any(|(name, _)| name == "SHOOT_SELF_IN_FOOT" || name == "INSECURE_HARDWARE_ALLOWED")
|
|
|
|
{
|
|
|
|
ensure_safe_kernel_version();
|
|
|
|
ensure_offline();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-16 02:44:48 +00:00
|
|
|
/// Read system entropy of a given size.
|
|
|
|
///
|
|
|
|
/// # Errors
|
|
|
|
/// An error may be returned if an error occurred while reading from the random source.
|
2023-09-21 22:30:48 +00:00
|
|
|
pub fn generate_entropy_of_size(byte_count: usize) -> Result<Vec<u8>, std::io::Error> {
|
2024-01-10 00:59:58 +00:00
|
|
|
ensure_safe();
|
2023-09-21 22:30:48 +00:00
|
|
|
let mut vec = vec![0u8; byte_count];
|
2024-01-10 00:59:58 +00:00
|
|
|
let mut entropy_file = File::open("/dev/urandom")?;
|
2023-09-21 22:30:48 +00:00
|
|
|
entropy_file.read_exact(&mut vec[..])?;
|
|
|
|
Ok(vec)
|
|
|
|
}
|