Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement verify-only PSS PaddingScheme #173

Merged
merged 1 commit into from
Aug 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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