Skip to content

Commit

Permalink
PaddingScheme: remove rng from PSS padding scheme (#172) (#173)
Browse files Browse the repository at this point in the history
The passed rng is not necessary for PSS signature verification. Instead
of passing artificial unused RNG through the PaddingScheme, add new
sign_with_rng() API and pass rng directly. In the sign_blinded() use the
passed rng both for salt generation and for the blinding process.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
  • Loading branch information
lumag committed Aug 29, 2022
1 parent 40242fb commit 2ffd3ae
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 55 deletions.
34 changes: 16 additions & 18 deletions src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -512,18 +512,24 @@ impl RsaPrivateKey {
PaddingScheme::PKCS1v15Sign { ref hash } => {
pkcs1v15::sign::<DummyRng, _>(None, self, hash.as_ref(), digest_in)
}
_ => Err(Error::InvalidPaddingScheme),
}
}

/// Sign the given digest using the provided rng
///
/// Use `rng` for signature process.
pub fn sign_with_rng<R: RngCore + CryptoRng>(
&self,
rng: &mut R,
padding: PaddingScheme,
digest_in: &[u8],
) -> Result<Vec<u8>> {
match padding {
PaddingScheme::PSS {
mut salt_rng,
mut digest,
salt_len,
} => pss::sign::<_, DummyRng, _>(
&mut *salt_rng,
None,
self,
digest_in,
salt_len,
&mut *digest,
),
} => pss::sign::<R, _>(rng, false, self, digest_in, salt_len, &mut *digest),
_ => Err(Error::InvalidPaddingScheme),
}
}
Expand All @@ -542,17 +548,9 @@ impl RsaPrivateKey {
pkcs1v15::sign(Some(rng), self, hash.as_ref(), digest_in)
}
PaddingScheme::PSS {
mut salt_rng,
mut digest,
salt_len,
} => pss::sign::<_, R, _>(
&mut *salt_rng,
Some(rng),
self,
digest_in,
salt_len,
&mut *digest,
),
} => pss::sign::<R, _>(rng, true, self, digest_in, salt_len, &mut *digest),
_ => Err(Error::InvalidPaddingScheme),
}
}
Expand Down
11 changes: 2 additions & 9 deletions src/padding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use alloc::string::{String, ToString};
use core::fmt;

use digest::{Digest, DynDigest};
use rand_core::RngCore;

use crate::hash::Hash;

Expand All @@ -30,7 +29,6 @@ pub enum PaddingScheme {
},
/// Sign and Verify using PSS padding.
PSS {
salt_rng: Box<dyn RngCore>,
digest: Box<dyn DynDigest>,
salt_len: Option<usize>,
},
Expand Down Expand Up @@ -142,20 +140,15 @@ impl PaddingScheme {
}
}

pub fn new_pss<T: 'static + Digest + DynDigest, S: 'static + RngCore>(rng: S) -> Self {
pub fn new_pss<T: 'static + Digest + DynDigest>() -> Self {
PaddingScheme::PSS {
salt_rng: Box::new(rng),
digest: Box::new(T::new()),
salt_len: None,
}
}

pub fn new_pss_with_salt<T: 'static + Digest + DynDigest, S: 'static + RngCore>(
rng: S,
len: usize,
) -> Self {
pub fn new_pss_with_salt<T: 'static + Digest + DynDigest>(len: usize) -> Self {
PaddingScheme::PSS {
salt_rng: Box::new(rng),
digest: Box::new(T::new()),
salt_len: Some(len),
}
Expand Down
53 changes: 25 additions & 28 deletions src/pss.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,20 +102,7 @@ pub(crate) fn verify<PK: PublicKey>(
/// given hash function. The opts argument may be nil, in which case sensible
/// defaults are used.
// TODO: bind T with the CryptoRng trait
pub(crate) fn sign<T: RngCore + ?Sized, S: CryptoRng + RngCore, SK: PrivateKey>(
rng: &mut T,
blind_rng: Option<&mut S>,
priv_key: &SK,
hashed: &[u8],
salt_len: Option<usize>,
digest: &mut dyn DynDigest,
) -> Result<Vec<u8>> {
let salt = generate_salt(rng, priv_key, salt_len, digest);

sign_pss_with_salt(blind_rng, priv_key, hashed, &salt, digest)
}

fn sign_int<T: RngCore + CryptoRng, SK: PrivateKey>(
pub(crate) fn sign<T: RngCore + CryptoRng, SK: PrivateKey>(
rng: &mut T,
blind: bool,
priv_key: &SK,
Expand Down Expand Up @@ -360,7 +347,7 @@ impl RandomizedSigner<Signature> for SigningKey {
mut rng: impl CryptoRng + RngCore,
digest: &[u8],
) -> signature::Result<Signature> {
sign_int(
sign(
&mut rng,
false,
&self.inner,
Expand Down Expand Up @@ -403,7 +390,7 @@ impl RandomizedSigner<Signature> for BlindedSigningKey {
mut rng: impl CryptoRng + RngCore,
digest: &[u8],
) -> signature::Result<Signature> {
sign_int(
sign(
&mut rng,
true,
&self.inner,
Expand Down Expand Up @@ -540,8 +527,7 @@ mod test {

for (text, sig, expected) in &tests {
let digest = Sha1::digest(text.as_bytes()).to_vec();
let rng = ChaCha8Rng::from_seed([42; 32]);
let result = pub_key.verify(PaddingScheme::new_pss::<Sha1, _>(rng), &digest, sig);
let result = pub_key.verify(PaddingScheme::new_pss::<Sha1>(), &digest, sig);
match expected {
true => result.expect("failed to verify"),
false => {
Expand Down Expand Up @@ -600,19 +586,30 @@ mod test {
for test in &tests {
let digest = Sha1::digest(test.as_bytes()).to_vec();
let sig = priv_key
.sign_blinded(
&mut rng.clone(),
PaddingScheme::new_pss::<Sha1, _>(rng.clone()),
&digest,
)
.sign_with_rng(&mut rng.clone(), PaddingScheme::new_pss::<Sha1>(), &digest)
.expect("failed to sign");

priv_key
.verify(PaddingScheme::new_pss::<Sha1>(), &digest, &sig)
.expect("failed to verify");
}
}

#[test]
fn test_sign_blinded_and_verify_roundtrip() {
let priv_key = get_private_key();

let tests = ["test\n"];
let rng = ChaCha8Rng::from_seed([42; 32]);

for test in &tests {
let digest = Sha1::digest(test.as_bytes()).to_vec();
let sig = priv_key
.sign_blinded(&mut rng.clone(), PaddingScheme::new_pss::<Sha1>(), &digest)
.expect("failed to sign");

priv_key
.verify(
PaddingScheme::new_pss::<Sha1, _>(rng.clone()),
&digest,
&sig,
)
.verify(PaddingScheme::new_pss::<Sha1>(), &digest, &sig)
.expect("failed to verify");
}
}
Expand Down

0 comments on commit 2ffd3ae

Please sign in to comment.