diff --git a/Cargo.lock b/Cargo.lock index b4844a4..2c69f78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -344,7 +344,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "typenum", ] @@ -542,6 +542,7 @@ dependencies = [ "cfg-if", "libc", "r-efi 6.0.0", + "rand_core 0.10.1", ] [[package]] @@ -770,7 +771,7 @@ dependencies = [ "argon2", "chacha20poly1305", "chrono", - "rand", + "rand 0.10.2", "rmp-serde", "serde", "serde_json", @@ -891,7 +892,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" dependencies = [ "base64ct", - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -977,7 +978,17 @@ checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a" dependencies = [ "libc", "rand_chacha", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" +dependencies = [ + "getrandom 0.4.3", + "rand_core 0.10.1", ] [[package]] @@ -987,7 +998,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -999,6 +1010,12 @@ dependencies = [ "getrandom 0.2.17", ] +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + [[package]] name = "ratatui" version = "0.30.2" @@ -1587,7 +1604,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45e820b97864028eb5069aabf2d90ad7bc279a0ed0292f1306451ce4b91adc13" dependencies = [ "libm", - "rand", + "rand 0.8.7", "serde", "serde_bytes", ] diff --git a/Cargo.toml b/Cargo.toml index d101894..733d7bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ chacha20poly1305 = "0.10" chrono = { version = "0.4", default-features = false, features = ["clock", "serde"] } clap = { version = "4.5", features = ["derive"] } crossterm = "0.29" -rand = "0.8" +rand = { version = "0.10", default-features = false, features = ["sys_rng"] } ratatui = { version = "0.30.1", default-features = false, features = ["crossterm_0_29"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/crates/mge-core/src/security.rs b/crates/mge-core/src/security.rs index 4374e58..c5527d1 100644 --- a/crates/mge-core/src/security.rs +++ b/crates/mge-core/src/security.rs @@ -19,8 +19,8 @@ use std::str::FromStr; use argon2::{Algorithm, Argon2, Params, Version}; use chacha20poly1305::aead::{Aead, KeyInit, Payload}; use chacha20poly1305::{XChaCha20Poly1305, XNonce}; -use rand::rngs::OsRng; -use rand::RngCore; +use rand::rngs::SysRng; +use rand::TryRng; use serde::{Deserialize, Serialize}; use zeroize::Zeroize; @@ -40,6 +40,12 @@ const KDF_PARALLELISM: u32 = 1; const KEY_CHECK_PLAINTEXT: &[u8] = b"MGE key check v1"; const KEY_CHECK_AAD: &[u8] = b"mge:key_check:v1"; +fn fill_secure_random(bytes: &mut [u8]) -> Result<()> { + SysRng + .try_fill_bytes(bytes) + .map_err(|error| MgeError::Crypto(format!("operating system RNG failed: {error}"))) +} + #[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "snake_case")] pub enum SecurityMode { @@ -168,7 +174,7 @@ pub fn create_security_metadata(passphrase: &str) -> Result<(SecurityMetadata, S } let mut salt = vec![0u8; SALT_LEN]; - OsRng.fill_bytes(&mut salt); + fill_secure_random(&mut salt)?; let kdf = KdfMetadata { algorithm: KDF_ALGORITHM.to_string(), version: KDF_VERSION, @@ -237,7 +243,7 @@ pub fn unlock_security_metadata( pub fn encrypt_payload(key: &SessionKey, aad: &[u8], plaintext: &[u8]) -> Result { let mut nonce = vec![0u8; NONCE_LEN]; - OsRng.fill_bytes(&mut nonce); + fill_secure_random(&mut nonce)?; let cipher = XChaCha20Poly1305::new_from_slice(key.expose()) .map_err(|_| MgeError::Crypto("failed to initialize AEAD".to_string()))?; let ciphertext = cipher