Skip to content

Commit

Permalink
convert internals to TryCryptoRng
Browse files Browse the repository at this point in the history
  • Loading branch information
baloo committed Feb 22, 2025
1 parent 33089e9 commit e174e9f
Show file tree
Hide file tree
Showing 15 changed files with 108 additions and 136 deletions.
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,7 @@ crypto-bigint = { git = "https://github.com/RustCrypto/crypto-bigint.git" }

# https://github.com/entropyxyz/crypto-primes/pull/74
crypto-primes = { git = "https://github.com/entropyxyz/crypto-primes.git" }

# https://github.com/RustCrypto/traits/pull/1765
signature = { git = "https://github.com/RustCrypto/traits.git" }

4 changes: 2 additions & 2 deletions src/algorithms/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub struct RsaPrivateKeyComponents {
///
/// [1]: https://patents.google.com/patent/US4405829A/en
/// [2]: http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf
pub(crate) fn generate_multi_prime_key_with_exp<R: CryptoRng>(
pub(crate) fn generate_multi_prime_key_with_exp<R: CryptoRng + ?Sized>(
rng: &mut R,
nprimes: usize,
bit_size: usize,
Expand Down Expand Up @@ -120,7 +120,7 @@ pub(crate) fn generate_multi_prime_key_with_exp<R: CryptoRng>(
})
}

fn generate_prime_with_rng<R: CryptoRng>(rng: &mut R, bit_length: u32) -> BoxedUint {
fn generate_prime_with_rng<R: CryptoRng + ?Sized>(rng: &mut R, bit_length: u32) -> BoxedUint {
sieve_and_find(
rng,
SmallPrimesSieveFactory::new(bit_length, SetBits::TwoMsb),
Expand Down
10 changes: 5 additions & 5 deletions src/algorithms/oaep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use alloc::boxed::Box;
use alloc::vec::Vec;

use digest::{Digest, DynDigest, FixedOutputReset};
use rand_core::CryptoRng;
use rand_core::TryCryptoRng;
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
use zeroize::Zeroizing;

Expand All @@ -19,7 +19,7 @@ use crate::errors::{Error, Result};
const MAX_LABEL_LEN: u64 = 1 << 61;

#[inline]
fn encrypt_internal<R: CryptoRng + ?Sized, MGF: FnMut(&mut [u8], &mut [u8])>(
fn encrypt_internal<R: TryCryptoRng + ?Sized, MGF: FnMut(&mut [u8], &mut [u8])>(
rng: &mut R,
msg: &[u8],
p_hash: &[u8],
Expand All @@ -35,7 +35,7 @@ fn encrypt_internal<R: CryptoRng + ?Sized, MGF: FnMut(&mut [u8], &mut [u8])>(

let (_, payload) = em.split_at_mut(1);
let (seed, db) = payload.split_at_mut(h_size);
rng.fill_bytes(seed);
rng.try_fill_bytes(seed).map_err(|_| Error::Rng)?;

// Data block DB = pHash || PS || 01 || M
let db_len = k - h_size - 1;
Expand All @@ -57,7 +57,7 @@ fn encrypt_internal<R: CryptoRng + ?Sized, MGF: FnMut(&mut [u8], &mut [u8])>(
///
/// [PKCS#1 OAEP]: https://datatracker.ietf.org/doc/html/rfc8017#section-7.1
#[inline]
pub(crate) fn oaep_encrypt<R: CryptoRng + ?Sized>(
pub(crate) fn oaep_encrypt<R: TryCryptoRng + ?Sized>(
rng: &mut R,
msg: &[u8],
digest: &mut dyn DynDigest,
Expand Down Expand Up @@ -90,7 +90,7 @@ pub(crate) fn oaep_encrypt<R: CryptoRng + ?Sized>(
/// [PKCS#1 OAEP]: https://datatracker.ietf.org/doc/html/rfc8017#section-7.1
#[inline]
pub(crate) fn oaep_encrypt_digest<
R: CryptoRng + ?Sized,
R: TryCryptoRng + ?Sized,
D: Digest,
MGD: Digest + FixedOutputReset,
>(
Expand Down
19 changes: 12 additions & 7 deletions src/algorithms/pkcs1v15.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use alloc::vec::Vec;
use digest::Digest;
use pkcs8::AssociatedOid;
use rand_core::CryptoRng;
use rand_core::TryCryptoRng;
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
use zeroize::Zeroizing;

Expand All @@ -18,17 +18,22 @@ use crate::errors::{Error, Result};
/// Fills the provided slice with random values, which are guaranteed
/// to not be zero.
#[inline]
fn non_zero_random_bytes<R: CryptoRng + ?Sized>(rng: &mut R, data: &mut [u8]) {
rng.fill_bytes(data);
fn non_zero_random_bytes<R: TryCryptoRng + ?Sized>(
rng: &mut R,
data: &mut [u8],
) -> core::result::Result<(), R::Error> {
rng.try_fill_bytes(data)?;

for el in data {
if *el == 0u8 {
// TODO: break after a certain amount of time
while *el == 0u8 {
rng.fill_bytes(core::slice::from_mut(el));
rng.try_fill_bytes(core::slice::from_mut(el))?;
}
}
}

Ok(())
}

/// Applied the padding scheme from PKCS#1 v1.5 for encryption. The message must be no longer than
Expand All @@ -39,7 +44,7 @@ pub(crate) fn pkcs1v15_encrypt_pad<R>(
k: usize,
) -> Result<Zeroizing<Vec<u8>>>
where
R: CryptoRng + ?Sized,
R: TryCryptoRng + ?Sized,
{
if msg.len() + 11 > k {
return Err(Error::MessageTooLong);
Expand All @@ -48,7 +53,7 @@ where
// EM = 0x00 || 0x02 || PS || 0x00 || M
let mut em = Zeroizing::new(vec![0u8; k]);
em[1] = 2;
non_zero_random_bytes(rng, &mut em[2..k - msg.len() - 1]);
non_zero_random_bytes(rng, &mut em[2..k - msg.len() - 1]).map_err(|_: R::Error| Error::Rng)?;
em[k - msg.len() - 1] = 0;
em[k - msg.len()..].copy_from_slice(msg);
Ok(em)
Expand Down Expand Up @@ -189,7 +194,7 @@ mod tests {
for _ in 0..10 {
let mut rng = ChaCha8Rng::from_seed([42; 32]);
let mut b = vec![0u8; 512];
non_zero_random_bytes(&mut rng, &mut b);
non_zero_random_bytes(&mut rng, &mut b).unwrap();
for el in &b {
assert_ne!(*el, 0u8);
}
Expand Down
20 changes: 10 additions & 10 deletions src/algorithms/rsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use core::cmp::Ordering;

use crypto_bigint::modular::{BoxedMontyForm, BoxedMontyParams};
use crypto_bigint::{BoxedUint, Gcd, NonZero, Odd, RandomMod, Wrapping};
use rand_core::CryptoRng;
use rand_core::TryCryptoRng;
use zeroize::Zeroize;

use crate::errors::{Error, Result};
Expand All @@ -31,8 +31,8 @@ pub fn rsa_encrypt<K: PublicKeyParts>(key: &K, m: &BoxedUint) -> Result<BoxedUin
/// Use this function with great care! Raw RSA should never be used without an appropriate padding
/// or signature scheme. See the [module-level documentation][crate::hazmat] for more information.
#[inline]
pub fn rsa_decrypt<R: CryptoRng + ?Sized>(
mut rng: Option<&mut R>,
pub fn rsa_decrypt<R: TryCryptoRng + ?Sized>(
rng: Option<&mut R>,
priv_key: &impl PrivateKeyParts,
c: &BoxedUint,
) -> Result<BoxedUint> {
Expand All @@ -48,8 +48,8 @@ pub fn rsa_decrypt<R: CryptoRng + ?Sized>(
let n_params = priv_key.n_params();
let bits = d.bits_precision();

let c = if let Some(ref mut rng) = rng {
let (blinded, unblinder) = blind(rng, priv_key, c, n_params);
let c = if let Some(rng) = rng {
let (blinded, unblinder) = blind(rng, priv_key, c, n_params)?;
ir = Some(unblinder);
blinded.widen(bits)
} else {
Expand Down Expand Up @@ -123,7 +123,7 @@ pub fn rsa_decrypt<R: CryptoRng + ?Sized>(
/// Use this function with great care! Raw RSA should never be used without an appropriate padding
/// or signature scheme. See the [module-level documentation][crate::hazmat] for more information.
#[inline]
pub fn rsa_decrypt_and_check<R: CryptoRng + ?Sized>(
pub fn rsa_decrypt_and_check<R: TryCryptoRng + ?Sized>(
priv_key: &impl PrivateKeyParts,
rng: Option<&mut R>,
c: &BoxedUint,
Expand All @@ -142,12 +142,12 @@ pub fn rsa_decrypt_and_check<R: CryptoRng + ?Sized>(
}

/// Returns the blinded c, along with the unblinding factor.
fn blind<R: CryptoRng, K: PublicKeyParts>(
fn blind<R: TryCryptoRng + ?Sized, K: PublicKeyParts>(
rng: &mut R,
key: &K,
c: &BoxedUint,
n_params: &BoxedMontyParams,
) -> (BoxedUint, BoxedUint) {
) -> Result<(BoxedUint, BoxedUint)> {
// Blinding involves multiplying c by r^e.
// Then the decryption operation performs (m^e * r^e)^d mod n
// which equals mr mod n. The factor of r can then be removed
Expand All @@ -158,7 +158,7 @@ fn blind<R: CryptoRng, K: PublicKeyParts>(
let mut r: BoxedUint = BoxedUint::one_with_precision(bits);
let mut ir: Option<BoxedUint> = None;
while ir.is_none() {
r = BoxedUint::random_mod(rng, key.n());
r = BoxedUint::try_random_mod(rng, key.n()).map_err(|_| Error::Rng)?;
if r.is_zero().into() {
r = BoxedUint::one_with_precision(bits);
}
Expand All @@ -181,7 +181,7 @@ fn blind<R: CryptoRng, K: PublicKeyParts>(
debug_assert_eq!(blinded.bits_precision(), bits);
debug_assert_eq!(ir.bits_precision(), bits);

(blinded, ir)
Ok((blinded, ir))
}

/// Given an m and and unblinding factor, unblind the m.
Expand Down
4 changes: 4 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ pub enum Error {

/// Decoding error.
Decode(crypto_bigint::DecodeError),

/// Random number generator error.
Rng,
}

#[cfg(feature = "std")]
Expand Down Expand Up @@ -99,6 +102,7 @@ impl core::fmt::Display for Error {
Error::InvalidPadLen => write!(f, "invalid padding length"),
Error::InvalidArguments => write!(f, "invalid arguments"),
Error::Decode(err) => write!(f, "{:?}", err),
Error::Rng => write!(f, "rng error"),
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ impl PublicKeyParts for RsaPublicKey {

impl RsaPublicKey {
/// Encrypt the given message.
pub fn encrypt<R: CryptoRng, P: PaddingScheme>(
pub fn encrypt<R: CryptoRng + ?Sized, P: PaddingScheme>(
&self,
rng: &mut R,
padding: P,
Expand Down Expand Up @@ -254,15 +254,15 @@ impl RsaPrivateKey {
const EXP: u64 = 65537;

/// Generate a new Rsa key pair of the given bit size using the passed in `rng`.
pub fn new<R: CryptoRng>(rng: &mut R, bit_size: usize) -> Result<RsaPrivateKey> {
pub fn new<R: CryptoRng + ?Sized>(rng: &mut R, bit_size: usize) -> Result<RsaPrivateKey> {
Self::new_with_exp(rng, bit_size, BoxedUint::from(Self::EXP))
}

/// Generate a new RSA key pair of the given bit size and the public exponent
/// using the passed in `rng`.
///
/// Unless you have specific needs, you should use `RsaPrivateKey::new` instead.
pub fn new_with_exp<R: CryptoRng>(
pub fn new_with_exp<R: CryptoRng + ?Sized>(
rng: &mut R,
bit_size: usize,
exp: BoxedUint,
Expand Down Expand Up @@ -493,7 +493,7 @@ impl RsaPrivateKey {
/// Decrypt the given message.
///
/// Uses `rng` to blind the decryption process.
pub fn decrypt_blinded<R: CryptoRng, P: PaddingScheme>(
pub fn decrypt_blinded<R: CryptoRng + ?Sized, P: PaddingScheme>(
&self,
rng: &mut R,
padding: P,
Expand All @@ -517,7 +517,7 @@ impl RsaPrivateKey {
/// [`Pss::new`][`crate::Pss::new`] for a standard RSASSA-PSS signature, or
/// [`Pss::new_blinded`][`crate::Pss::new_blinded`] for RSA-BSSA blind
/// signatures.
pub fn sign_with_rng<R: CryptoRng, S: SignatureScheme>(
pub fn sign_with_rng<R: CryptoRng + ?Sized, S: SignatureScheme>(
&self,
rng: &mut R,
padding: S,
Expand Down
14 changes: 7 additions & 7 deletions src/oaep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use core::fmt;
use crypto_bigint::BoxedUint;

use digest::{Digest, DynDigest, FixedOutputReset};
use rand_core::CryptoRng;
use rand_core::TryCryptoRng;

use crate::algorithms::oaep::*;
use crate::algorithms::pad::{uint_to_be_pad, uint_to_zeroizing_be_pad};
Expand Down Expand Up @@ -135,7 +135,7 @@ impl Oaep {
}

impl PaddingScheme for Oaep {
fn decrypt<Rng: CryptoRng>(
fn decrypt<Rng: TryCryptoRng + ?Sized>(
mut self,
rng: Option<&mut Rng>,
priv_key: &RsaPrivateKey,
Expand All @@ -151,7 +151,7 @@ impl PaddingScheme for Oaep {
)
}

fn encrypt<Rng: CryptoRng>(
fn encrypt<Rng: TryCryptoRng + ?Sized>(
mut self,
rng: &mut Rng,
pub_key: &RsaPublicKey,
Expand Down Expand Up @@ -186,7 +186,7 @@ impl fmt::Debug for Oaep {
///
/// [PKCS#1 OAEP]: https://datatracker.ietf.org/doc/html/rfc8017#section-7.1
#[inline]
fn encrypt<R: CryptoRng + ?Sized>(
fn encrypt<R: TryCryptoRng + ?Sized>(
rng: &mut R,
pub_key: &RsaPublicKey,
msg: &[u8],
Expand All @@ -209,7 +209,7 @@ fn encrypt<R: CryptoRng + ?Sized>(
/// `2 + (2 * hash.size())`.
///
/// [PKCS#1 OAEP]: https://datatracker.ietf.org/doc/html/rfc8017#section-7.1
fn encrypt_digest<R: CryptoRng + ?Sized, D: Digest, MGD: Digest + FixedOutputReset>(
fn encrypt_digest<R: TryCryptoRng + ?Sized, D: Digest, MGD: Digest + FixedOutputReset>(
rng: &mut R,
pub_key: &RsaPublicKey,
msg: &[u8],
Expand All @@ -236,7 +236,7 @@ fn encrypt_digest<R: CryptoRng + ?Sized, D: Digest, MGD: Digest + FixedOutputRes
///
/// [PKCS#1 OAEP]: https://datatracker.ietf.org/doc/html/rfc8017#section-7.1
#[inline]
fn decrypt<R: CryptoRng + ?Sized>(
fn decrypt<R: TryCryptoRng + ?Sized>(
rng: Option<&mut R>,
priv_key: &RsaPrivateKey,
ciphertext: &[u8],
Expand Down Expand Up @@ -269,7 +269,7 @@ fn decrypt<R: CryptoRng + ?Sized>(
///
/// [PKCS#1 OAEP]: https://datatracker.ietf.org/doc/html/rfc8017#section-7.1
#[inline]
fn decrypt_digest<R: CryptoRng + ?Sized, D: Digest, MGD: Digest + FixedOutputReset>(
fn decrypt_digest<R: TryCryptoRng + ?Sized, D: Digest, MGD: Digest + FixedOutputReset>(
rng: Option<&mut R>,
priv_key: &RsaPrivateKey,
ciphertext: &[u8],
Expand Down
Loading

0 comments on commit e174e9f

Please sign in to comment.