diff --git a/dsa/examples/export.rs b/dsa/examples/export.rs index 658b83b..e11ee36 100644 --- a/dsa/examples/export.rs +++ b/dsa/examples/export.rs @@ -7,7 +7,8 @@ use std::{fs::File, io::Write}; fn main() { let mut rng = rand_core::UnwrapErr(SysRng); - let components = Components::generate(&mut rng, KeySize::DSA_2048_256); + let components = + Components::try_generate_from_rng_with_key_size(&mut rng, KeySize::DSA_2048_256).unwrap(); let signing_key = SigningKey::generate(&mut rng, components); let verifying_key = signing_key.verifying_key(); diff --git a/dsa/examples/generate.rs b/dsa/examples/generate.rs index a341b5f..187c0fd 100644 --- a/dsa/examples/generate.rs +++ b/dsa/examples/generate.rs @@ -5,7 +5,8 @@ use getrandom::{SysRng, rand_core::UnwrapErr}; fn main() { let mut rng = UnwrapErr(SysRng); - let components = Components::generate(&mut rng, KeySize::DSA_2048_256); + let components = + Components::try_generate_from_rng_with_key_size(&mut rng, KeySize::DSA_2048_256).unwrap(); let signing_key = SigningKey::generate(&mut rng, components); let _verifying_key = signing_key.verifying_key(); } diff --git a/dsa/examples/sign.rs b/dsa/examples/sign.rs index ce934c7..d8566d0 100644 --- a/dsa/examples/sign.rs +++ b/dsa/examples/sign.rs @@ -7,8 +7,11 @@ use signature::{RandomizedDigestSigner, SignatureEncoding}; use std::{fs::File, io::Write}; fn main() { + let components = + Components::try_generate_from_rng_with_key_size(&mut SysRng, KeySize::DSA_2048_256) + .unwrap(); + let mut rng = UnwrapErr(SysRng); - let components = Components::generate(&mut rng, KeySize::DSA_2048_256); let signing_key = SigningKey::generate(&mut rng, components); let verifying_key = signing_key.verifying_key(); diff --git a/dsa/src/components.rs b/dsa/src/components.rs index f827dc0..ad053b3 100644 --- a/dsa/src/components.rs +++ b/dsa/src/components.rs @@ -2,13 +2,13 @@ //! Module containing the definition of the common components container //! -use crate::{size::KeySize, two}; +use crate::{generate, size::KeySize, two}; use crypto_bigint::{BoxedUint, NonZero, Odd}; use der::{ self, DecodeValue, Encode, EncodeValue, Header, Length, Reader, Sequence, Tag, Writer, asn1::UintRef, }; -use signature::rand_core::CryptoRng; +use signature::rand_core::TryCryptoRng; /// The common components of an DSA keypair /// @@ -87,10 +87,13 @@ impl Components { } /// Generate a new pair of common components - pub fn generate(rng: &mut R, key_size: KeySize) -> Self { - let (p, q, g) = crate::generate::common_components(rng, key_size); - Self::from_components(p.get(), q.get(), g.get()) - .expect("[Bug] Newly generated components considered invalid") + pub fn try_generate_from_rng_with_key_size( + rng: &mut R, + key_size: KeySize, + ) -> Result { + let (p, q, g) = generate::common_components(rng, key_size)?; + Ok(Self::from_components(p.get(), q.get(), g.get()) + .expect("[Bug] Newly generated components considered invalid")) } /// DSA prime p diff --git a/dsa/src/generate.rs b/dsa/src/generate.rs index 031b65a..62a8d49 100644 --- a/dsa/src/generate.rs +++ b/dsa/src/generate.rs @@ -1,6 +1,6 @@ use crypto_bigint::{BoxedUint, NonZero, Resize}; use crypto_primes::{Flavor, random_prime}; -use signature::rand_core::CryptoRng; +use signature::rand_core::{TryCryptoRng, UnwrapErr}; mod components; mod keypair; @@ -33,6 +33,7 @@ fn calculate_bounds(size: u32) -> (NonZero, NonZero) { /// /// This wrapper function mainly exists to enforce the [`CryptoRng`](rand::CryptoRng) requirement (I might otherwise forget it) #[inline] -fn generate_prime(bit_length: u32, rng: &mut R) -> BoxedUint { - random_prime(rng, Flavor::Any, bit_length) +fn generate_prime(bit_length: u32, rng: &mut R) -> BoxedUint { + let mut rng = UnwrapErr(rng); + random_prime(&mut rng, Flavor::Any, bit_length) } diff --git a/dsa/src/generate/components.rs b/dsa/src/generate/components.rs index a67129b..1058bae 100644 --- a/dsa/src/generate/components.rs +++ b/dsa/src/generate/components.rs @@ -8,11 +8,11 @@ use crate::{ two, }; use crypto_bigint::{ - BoxedUint, ConcatenatingMul, NonZero, Odd, RandomBits, Resize, + BoxedUint, ConcatenatingMul, NonZero, Odd, RandomBits, RandomBitsError, Resize, modular::{BoxedMontyForm, BoxedMontyParams}, }; use crypto_primes::{Flavor, is_prime}; -use signature::rand_core::CryptoRng; +use signature::rand_core::TryCryptoRng; #[cfg(feature = "hazmat")] use {crate::Components, crypto_bigint::CtOption}; @@ -22,10 +22,11 @@ use {crate::Components, crypto_bigint::CtOption}; /// # Returns /// /// Tuple of three `BoxedUint`s. Ordered like this `(p, q, g)` -pub(crate) fn common( +#[allow(clippy::type_complexity, reason = "internal helper")] +pub(crate) fn common( rng: &mut R, KeySize { l, n }: KeySize, -) -> (Odd, NonZero, NonZero) { +) -> Result<(Odd, NonZero, NonZero), R::Error> { // Calculate the lower and upper bounds of p and q let (p_min, p_max) = calculate_bounds(l); let (q_min, q_max): (NonZero<_>, _) = calculate_bounds(n); @@ -41,7 +42,11 @@ pub(crate) fn common( // Attempt to find a prime p which has a subgroup of the order q for _ in 0..4096 { let m = 'gen_m: loop { - let m = BoxedUint::random_bits(rng, l); + let m = match BoxedUint::try_random_bits(rng, l) { + Ok(m) => m, + Err(RandomBitsError::RandCore(err)) => return Err(err), + Err(other) => unreachable!("[bug] RNG error: {other}"), + }; if m > *p_min && m < *p_max { break 'gen_m m; @@ -82,7 +87,7 @@ pub(crate) fn common( let q = q.resize(n); - (p, q, g) + Ok((p, q, g)) } /// Calculate the public component from the common components and the private component diff --git a/dsa/src/lib.rs b/dsa/src/lib.rs index bba9612..5ecd2ee 100644 --- a/dsa/src/lib.rs +++ b/dsa/src/lib.rs @@ -14,13 +14,17 @@ //! #![cfg_attr(feature = "hazmat", doc = "```")] #![cfg_attr(not(feature = "hazmat"), doc = "```ignore")] -//! # use dsa::{KeySize, Components, SigningKey}; -//! use getrandom::{SysRng, rand_core::UnwrapErr}; +//! # fn main() -> Result<(), core::convert::Infallible> { +//! use dsa::{KeySize, Components, SigningKey}; //! -//! let mut csprng = UnwrapErr(SysRng); -//! let components = Components::generate(&mut csprng, KeySize::DSA_2048_256); +//! # use getrandom::{SysRng, rand_core::UnwrapErr}; +//! # let mut csprng = UnwrapErr(SysRng); +//! +//! let components = Components::try_generate_from_rng_with_key_size(&mut csprng, KeySize::DSA_2048_256)?; //! let signing_key = SigningKey::generate(&mut csprng, components); //! let verifying_key = signing_key.verifying_key(); +//! # Ok(()) +//! # } //! ``` //! //! Create keypair from existing components diff --git a/dsa/tests/proptest.rs b/dsa/tests/proptest.rs index 90e7a44..811358d 100644 --- a/dsa/tests/proptest.rs +++ b/dsa/tests/proptest.rs @@ -20,7 +20,7 @@ prop_compose! { fn private_key()(seed in any::<[u8; 32]>()) -> SigningKey { let mut rng = ChaCha8Rng::from_seed(seed); #[allow(deprecated)] - let components = Components::generate(&mut rng, KeySize::DSA_1024_160); + let components = Components::try_generate_from_rng_with_key_size(&mut rng, KeySize::DSA_1024_160).unwrap(); SigningKey::generate(&mut rng, components) } } diff --git a/dsa/tests/signature.rs b/dsa/tests/signature.rs index a721e20..126017a 100644 --- a/dsa/tests/signature.rs +++ b/dsa/tests/signature.rs @@ -34,7 +34,8 @@ const MESSAGE_SIGNATURE_OPENSSL_ASN1: &[u8] = &hex!( /// Generate a random DSA keypair fn generate_random_keypair() -> SigningKey { let mut rng = UnwrapErr(SysRng); - let components = Components::generate(&mut rng, KeySize::DSA_1024_160); + let components = + Components::try_generate_from_rng_with_key_size(&mut rng, KeySize::DSA_1024_160).unwrap(); SigningKey::generate(&mut rng, components) } diff --git a/dsa/tests/signing_key.rs b/dsa/tests/signing_key.rs index cac24c0..7fdc488 100644 --- a/dsa/tests/signing_key.rs +++ b/dsa/tests/signing_key.rs @@ -18,7 +18,8 @@ const OPENSSL_PEM_PRIVATE_KEY: &str = include_str!("pems/private.pem"); fn generate_keypair() -> SigningKey { let mut rng = UnwrapErr(SysRng); - let components = Components::generate(&mut rng, KeySize::DSA_1024_160); + let components = + Components::try_generate_from_rng_with_key_size(&mut rng, KeySize::DSA_1024_160).unwrap(); SigningKey::generate(&mut rng, components) } diff --git a/dsa/tests/verifying_key.rs b/dsa/tests/verifying_key.rs index 1253f65..5513ddd 100644 --- a/dsa/tests/verifying_key.rs +++ b/dsa/tests/verifying_key.rs @@ -21,7 +21,8 @@ const OPENSSL_PEM_PUBLIC_KEY: &str = include_str!("pems/public.pem"); #[cfg(feature = "hazmat")] fn generate_verifying_key() -> VerifyingKey { let mut rng = rand_core::UnwrapErr(SysRng); - let components = Components::generate(&mut rng, KeySize::DSA_1024_160); + let components = + Components::try_generate_from_rng_with_key_size(&mut rng, KeySize::DSA_1024_160).unwrap(); let signing_key = SigningKey::generate(&mut rng, components); signing_key.verifying_key().clone()