From 128d4e6df73f9ec528e0b0a6dd88a9e6917aa221 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 31 Oct 2023 13:19:58 -0600 Subject: [PATCH] crypto-common: change `generate_*` to support getrandom (#1371) This commit splits the existing `generate_*` functions into two different variants: - `fn generate_*`: accepts no parameters and uses `OsRng` automatically. Gated on the `getrandom` feature. - `fn generate_*_with_rng`: accepts a `&mut impl CryptoRngCore` parameter. Gated on the `rand_core`. Previously all of the `generate_*` methods were parameterized on a `CryptoRngCore`. Splitting them up like this makes it very easy for users to do the right thing, which is use `getrandom`/`OsRng`, but without the need to document how to import `OsRng` into their code everywhere. Retaining the parameterized versions as `*_with_rng` allows users to pass a custom RNG where it makes sense, for example `rand::thread_rng`, or potentially an embedded peripheral/entropy pool. --- crypto-common/src/lib.rs | 55 +++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 57058605..d3303ca4 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -20,8 +20,11 @@ pub use hybrid_array::typenum; use core::fmt; use hybrid_array::{typenum::Unsigned, Array, ArraySize, ByteArray}; + #[cfg(feature = "rand_core")] use rand_core::CryptoRngCore; +#[cfg(feature = "getrandom")] +use rand_core::OsRng; /// Block on which [`BlockSizeUser`] implementors operate. pub type Block = ByteArray<::BlockSize>; @@ -156,10 +159,17 @@ pub trait KeyInit: KeySizeUser + Sized { .map_err(|_| InvalidLength) } + /// Generate random key using the operating system's secure RNG. + #[cfg(feature = "getrandom")] + #[inline] + fn generate_key() -> Key { + Self::generate_key_with_rng(&mut OsRng) + } + /// Generate random key using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_key(mut rng: impl CryptoRngCore) -> Key { + fn generate_key_with_rng(rng: &mut impl CryptoRngCore) -> Key { let mut key = Key::::default(); rng.fill_bytes(&mut key); key @@ -179,29 +189,53 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { Ok(Self::new(key, iv)) } + /// Generate random key using the operating system's secure RNG. + #[cfg(feature = "getrandom")] + #[inline] + fn generate_key() -> Key { + Self::generate_key_with_rng(&mut OsRng) + } + /// Generate random key using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_key(mut rng: impl CryptoRngCore) -> Key { + fn generate_key_with_rng(rng: &mut impl CryptoRngCore) -> Key { let mut key = Key::::default(); rng.fill_bytes(&mut key); key } + /// Generate random IV using the operating system's secure RNG. + #[cfg(feature = "getrandom")] + #[inline] + fn generate_iv() -> Iv { + Self::generate_iv_with_rng(&mut OsRng) + } + /// Generate random IV using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_iv(mut rng: impl CryptoRngCore) -> Iv { + fn generate_iv_with_rng(rng: &mut impl CryptoRngCore) -> Iv { let mut iv = Iv::::default(); rng.fill_bytes(&mut iv); iv } - /// Generate random key and nonce using the provided [`CryptoRngCore`]. + /// Generate random key and IV using the operating system's secure RNG. + #[cfg(feature = "getrandom")] + #[inline] + fn generate_key_iv() -> (Key, Iv) { + Self::generate_key_iv_with_rng(&mut OsRng) + } + + /// Generate random key and IV using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_key_iv(mut rng: impl CryptoRngCore) -> (Key, Iv) { - (Self::generate_key(&mut rng), Self::generate_iv(&mut rng)) + fn generate_key_iv_with_rng(rng: &mut impl CryptoRngCore) -> (Key, Iv) { + ( + Self::generate_key_with_rng(rng), + Self::generate_iv_with_rng(rng), + ) } } @@ -228,10 +262,17 @@ pub trait InnerIvInit: InnerUser + IvSizeUser + Sized { Ok(Self::inner_iv_init(inner, iv)) } + /// Generate random IV using the operating system's secure RNG. + #[cfg(feature = "getrandom")] + #[inline] + fn generate_iv() -> Iv { + Self::generate_iv_with_rng(&mut OsRng) + } + /// Generate random IV using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_iv(mut rng: impl CryptoRngCore) -> Iv { + fn generate_iv_with_rng(rng: &mut impl CryptoRngCore) -> Iv { let mut iv = Iv::::default(); rng.fill_bytes(&mut iv); iv