diff --git a/Cargo.lock b/Cargo.lock index 9f7031be..457222cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -696,9 +696,9 @@ dependencies = [ [[package]] name = "signature" -version = "3.0.0-rc.3" +version = "3.0.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39195ff4c0dc41c93e123825ca1f0d11b856df8b26d5fe140a522355632c4345" +checksum = "fc280a6ff65c79fbd6622f64d7127f32b85563bca8c53cd2e9141d6744a9056d" dependencies = [ "digest", "rand_core", diff --git a/Cargo.toml b/Cargo.toml index f8d09e80..d85dbdef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ crypto-bigint = { version = "0.7.0-rc.6", default-features = false, features = [ crypto-primes = { version = "0.7.0-pre.2", default-features = false } digest = { version = "0.11.0-rc.1", default-features = false, features = ["alloc", "oid"] } rand_core = { version = "0.9", default-features = false } -signature = { version = "3.0.0-rc.3", default-features = false, features = ["alloc", "digest", "rand_core"] } +signature = { version = "3.0.0-rc.4", default-features = false, features = ["alloc", "digest", "rand_core"] } subtle = { version = "2.6.1", default-features = false } zeroize = { version = "1.5", features = ["alloc"] } diff --git a/src/pkcs1v15.rs b/src/pkcs1v15.rs index b3608e95..439cc134 100644 --- a/src/pkcs1v15.rs +++ b/src/pkcs1v15.rs @@ -533,16 +533,16 @@ mod tests { for (text, expected) in &tests { let mut digest = Sha1::new(); digest.update(text.as_bytes()); - let out = signing_key.sign_digest(digest).to_bytes(); + let out = signing_key + .sign_digest(|digest: &mut Sha1| digest.update(text.as_bytes())) + .to_bytes(); assert_ne!(out.as_ref(), text.as_bytes()); assert_ne!(out.as_ref(), &Sha1::digest(text.as_bytes()).to_vec()); assert_eq!(out.as_ref(), expected); let mut rng = ChaCha8Rng::from_seed([42; 32]); - let mut digest = Sha1::new(); - digest.update(text.as_bytes()); let out2 = signing_key - .sign_digest_with_rng(&mut rng, digest) + .sign_digest_with_rng(&mut rng, |digest: &mut Sha1| digest.update(text.as_bytes())) .to_bytes(); assert_eq!(out2.as_ref(), expected); } @@ -650,10 +650,13 @@ mod tests { let verifying_key = VerifyingKey::new(pub_key); for (text, sig, expected) in &tests { - let mut digest = Sha1::new(); - digest.update(text.as_bytes()); - let result = - verifying_key.verify_digest(digest, &Signature::try_from(sig.as_slice()).unwrap()); + let result = verifying_key.verify_digest( + |digest: &mut Sha1| { + digest.update(text.as_bytes()); + Ok(()) + }, + &Signature::try_from(sig.as_slice()).unwrap(), + ); match expected { true => result.expect("failed to verify"), false => { diff --git a/src/pkcs1v15/signing_key.rs b/src/pkcs1v15/signing_key.rs index 222b202a..0968e3f2 100644 --- a/src/pkcs1v15/signing_key.rs +++ b/src/pkcs1v15/signing_key.rs @@ -3,7 +3,7 @@ use crate::{dummy_rng::DummyRng, Result, RsaPrivateKey}; use alloc::vec::Vec; use const_oid::AssociatedOid; use core::marker::PhantomData; -use digest::Digest; +use digest::{Digest, FixedOutput, HashMarker, Update}; use rand_core::{CryptoRng, TryCryptoRng}; use signature::{ hazmat::PrehashSigner, DigestSigner, Keypair, MultipartSigner, RandomizedDigestSigner, @@ -95,10 +95,15 @@ where impl DigestSigner for SigningKey where - D: Digest, + D: Default + FixedOutput + HashMarker + Update, { - fn try_sign_digest(&self, digest: D) -> signature::Result { - sign::(None, &self.inner, &self.prefix, &digest.finalize())? + fn try_sign_digest signature::Result<()>>( + &self, + f: F, + ) -> signature::Result { + let mut digest = D::default(); + f(&mut digest)?; + sign::(None, &self.inner, &self.prefix, &digest.finalize_fixed())? .as_slice() .try_into() } @@ -117,16 +122,26 @@ where impl RandomizedDigestSigner for SigningKey where - D: Digest, + D: Default + FixedOutput + HashMarker + Update, { - fn try_sign_digest_with_rng( + fn try_sign_digest_with_rng< + R: TryCryptoRng + ?Sized, + F: Fn(&mut D) -> signature::Result<()>, + >( &self, rng: &mut R, - digest: D, + f: F, ) -> signature::Result { - sign(Some(rng), &self.inner, &self.prefix, &digest.finalize())? - .as_slice() - .try_into() + let mut digest = D::default(); + f(&mut digest)?; + sign( + Some(rng), + &self.inner, + &self.prefix, + &digest.finalize_fixed(), + )? + .as_slice() + .try_into() } } diff --git a/src/pkcs1v15/verifying_key.rs b/src/pkcs1v15/verifying_key.rs index f2f1cf0d..6e1350e3 100644 --- a/src/pkcs1v15/verifying_key.rs +++ b/src/pkcs1v15/verifying_key.rs @@ -3,7 +3,7 @@ use crate::RsaPublicKey; use alloc::vec::Vec; use const_oid::AssociatedOid; use core::marker::PhantomData; -use digest::Digest; +use digest::{Digest, FixedOutput, HashMarker, Update}; use signature::{hazmat::PrehashVerifier, DigestVerifier, Verifier}; #[cfg(feature = "encoding")] @@ -71,13 +71,19 @@ where impl DigestVerifier for VerifyingKey where - D: Digest, + D: Default + FixedOutput + HashMarker + Update, { - fn verify_digest(&self, digest: D, signature: &Signature) -> signature::Result<()> { + fn verify_digest signature::Result<()>>( + &self, + f: F, + signature: &Signature, + ) -> signature::Result<()> { + let mut digest = D::default(); + f(&mut digest)?; verify( &self.inner, &self.prefix, - &digest.finalize(), + &digest.finalize_fixed(), &signature.inner, ) .map_err(|e| e.into()) diff --git a/src/pss.rs b/src/pss.rs index 227deb0a..830d9e40 100644 --- a/src/pss.rs +++ b/src/pss.rs @@ -398,10 +398,13 @@ tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V let verifying_key = VerifyingKey::new(pub_key); for (text, sig, expected) in &tests { - let mut digest = Sha1::new(); - digest.update(text.as_bytes()); - let result = - verifying_key.verify_digest(digest, &Signature::try_from(sig.as_slice()).unwrap()); + let result = verifying_key.verify_digest( + |digest: &mut Sha1| { + digest.update(text.as_bytes()); + Ok(()) + }, + &Signature::try_from(sig.as_slice()).unwrap(), + ); match expected { true => result.expect("failed to verify"), false => { @@ -495,14 +498,17 @@ tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V let verifying_key = signing_key.verifying_key(); for test in &tests { - let mut digest = Sha1::new(); - digest.update(test.as_bytes()); - let sig = signing_key.sign_digest_with_rng(&mut rng, digest); + let sig = signing_key + .sign_digest_with_rng(&mut rng, |digest: &mut Sha1| digest.update(test.as_bytes())); - let mut digest = Sha1::new(); - digest.update(test.as_bytes()); verifying_key - .verify_digest(digest, &sig) + .verify_digest( + |digest: &mut Sha1| { + digest.update(test.as_bytes()); + Ok(()) + }, + &sig, + ) .expect("failed to verify"); } } @@ -517,14 +523,17 @@ tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V let verifying_key = signing_key.verifying_key(); for test in &tests { - let mut digest = Sha1::new(); - digest.update(test.as_bytes()); - let sig = signing_key.sign_digest_with_rng(&mut rng, digest); + let sig = signing_key + .sign_digest_with_rng(&mut rng, |digest: &mut Sha1| digest.update(test.as_bytes())); - let mut digest = Sha1::new(); - digest.update(test.as_bytes()); verifying_key - .verify_digest(digest, &sig) + .verify_digest( + |digest: &mut Sha1| { + digest.update(test.as_bytes()); + Ok(()) + }, + &sig, + ) .expect("failed to verify"); } } diff --git a/src/pss/blinded_signing_key.rs b/src/pss/blinded_signing_key.rs index d3439cfb..6dd29aab 100644 --- a/src/pss/blinded_signing_key.rs +++ b/src/pss/blinded_signing_key.rs @@ -1,7 +1,7 @@ use super::{sign_digest, Signature, VerifyingKey}; use crate::{Result, RsaPrivateKey}; use core::marker::PhantomData; -use digest::{Digest, FixedOutputReset}; +use digest::{Digest, FixedOutputReset, HashMarker, Update}; use rand_core::{CryptoRng, TryCryptoRng}; use signature::{ hazmat::RandomizedPrehashSigner, Keypair, RandomizedDigestSigner, RandomizedMultipartSigner, @@ -122,13 +122,18 @@ where impl RandomizedDigestSigner for BlindedSigningKey where - D: Digest + FixedOutputReset, + D: Default + FixedOutputReset + HashMarker + Update, { - fn try_sign_digest_with_rng( + fn try_sign_digest_with_rng< + R: TryCryptoRng + ?Sized, + F: Fn(&mut D) -> signature::Result<()>, + >( &self, rng: &mut R, - digest: D, + f: F, ) -> signature::Result { + let mut digest = D::default(); + f(&mut digest)?; sign_digest::<_, D>(rng, true, &self.inner, &digest.finalize(), self.salt_len)? .as_slice() .try_into() diff --git a/src/pss/signing_key.rs b/src/pss/signing_key.rs index d66a0574..32c28107 100644 --- a/src/pss/signing_key.rs +++ b/src/pss/signing_key.rs @@ -1,13 +1,14 @@ use super::{sign_digest, Signature, VerifyingKey}; use crate::{Result, RsaPrivateKey}; use core::marker::PhantomData; -use digest::{Digest, FixedOutputReset}; +use digest::{Digest, FixedOutputReset, Update}; use rand_core::{CryptoRng, TryCryptoRng}; use signature::{ hazmat::RandomizedPrehashSigner, Keypair, RandomizedDigestSigner, RandomizedMultipartSigner, RandomizedSigner, }; use zeroize::ZeroizeOnDrop; + #[cfg(feature = "serde")] use { pkcs8::DecodePrivateKey, @@ -25,6 +26,7 @@ use { AssociatedAlgorithmIdentifier, DynSignatureAlgorithmIdentifier, }, }; + #[cfg(feature = "os_rng")] use { rand_core::OsRng, @@ -95,13 +97,18 @@ where impl RandomizedDigestSigner for SigningKey where - D: Digest + FixedOutputReset, + D: Digest + FixedOutputReset + Update, { - fn try_sign_digest_with_rng( + fn try_sign_digest_with_rng< + R: TryCryptoRng + ?Sized, + F: Fn(&mut D) -> signature::Result<()>, + >( &self, rng: &mut R, - digest: D, + f: F, ) -> signature::Result { + let mut digest = D::new(); + f(&mut digest)?; sign_digest::<_, D>(rng, false, &self.inner, &digest.finalize(), self.salt_len)? .as_slice() .try_into() @@ -110,36 +117,39 @@ where impl RandomizedSigner for SigningKey where - D: Digest + FixedOutputReset, + D: Digest + FixedOutputReset + Update, { fn try_sign_with_rng( &self, rng: &mut R, msg: &[u8], ) -> signature::Result { - self.try_sign_digest_with_rng(rng, D::new_with_prefix(msg)) + self.try_sign_digest_with_rng(rng, |digest: &mut D| { + Update::update(digest, msg); + Ok(()) + }) } } impl RandomizedMultipartSigner for SigningKey where - D: Digest + FixedOutputReset, + D: Digest + FixedOutputReset + Update, { fn try_multipart_sign_with_rng( &self, rng: &mut R, msg: &[&[u8]], ) -> signature::Result { - let mut digest = D::new(); - msg.iter() - .for_each(|slice| ::update(&mut digest, slice)); - self.try_sign_digest_with_rng(rng, digest) + self.try_sign_digest_with_rng(rng, |digest: &mut D| { + msg.iter().for_each(|slice| Update::update(digest, slice)); + Ok(()) + }) } } impl RandomizedPrehashSigner for SigningKey where - D: Digest + FixedOutputReset, + D: Digest + FixedOutputReset + Update, { fn sign_prehash_with_rng( &self, diff --git a/src/pss/verifying_key.rs b/src/pss/verifying_key.rs index 9294330e..5bc5f26a 100644 --- a/src/pss/verifying_key.rs +++ b/src/pss/verifying_key.rs @@ -1,7 +1,7 @@ use super::{verify_digest, Signature}; use crate::RsaPublicKey; use core::marker::PhantomData; -use digest::{Digest, FixedOutputReset}; +use digest::{Digest, FixedOutputReset, Update}; use signature::{hazmat::PrehashVerifier, DigestVerifier, Verifier}; #[cfg(feature = "encoding")] @@ -72,9 +72,15 @@ where impl DigestVerifier for VerifyingKey where - D: Digest + FixedOutputReset, + D: Digest + FixedOutputReset + Update, { - fn verify_digest(&self, digest: D, signature: &Signature) -> signature::Result<()> { + fn verify_digest signature::Result<()>>( + &self, + f: F, + signature: &Signature, + ) -> signature::Result<()> { + let mut digest = D::new(); + f(&mut digest)?; verify_digest::( &self.inner, &digest.finalize(),