Skip to content

Commit

Permalink
crypto-common: change generate_* to support getrandom (#1371)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tarcieri committed Oct 31, 2023
1 parent bbcb9c2 commit 128d4e6
Showing 1 changed file with 48 additions and 7 deletions.
55 changes: 48 additions & 7 deletions crypto-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<B> = ByteArray<<B as BlockSizeUser>::BlockSize>;
Expand Down Expand Up @@ -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> {
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<Self> {
fn generate_key_with_rng(rng: &mut impl CryptoRngCore) -> Key<Self> {
let mut key = Key::<Self>::default();
rng.fill_bytes(&mut key);
key
Expand All @@ -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> {
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<Self> {
fn generate_key_with_rng(rng: &mut impl CryptoRngCore) -> Key<Self> {
let mut key = Key::<Self>::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> {
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<Self> {
fn generate_iv_with_rng(rng: &mut impl CryptoRngCore) -> Iv<Self> {
let mut iv = Iv::<Self>::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<Self>, Iv<Self>) {
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<Self>, Iv<Self>) {
(Self::generate_key(&mut rng), Self::generate_iv(&mut rng))
fn generate_key_iv_with_rng(rng: &mut impl CryptoRngCore) -> (Key<Self>, Iv<Self>) {
(
Self::generate_key_with_rng(rng),
Self::generate_iv_with_rng(rng),
)
}
}

Expand All @@ -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> {
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<Self> {
fn generate_iv_with_rng(rng: &mut impl CryptoRngCore) -> Iv<Self> {
let mut iv = Iv::<Self>::default();
rng.fill_bytes(&mut iv);
iv
Expand Down

0 comments on commit 128d4e6

Please sign in to comment.