diff --git a/src/lib.rs b/src/lib.rs index 33256f98..9dafc478 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -58,17 +58,16 @@ //! //! let bits = 2048; //! let private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key"); -//! let signing_key = SigningKey::new_with_hash(private_key, Hash::SHA2_256); +//! let signing_key = SigningKey::new_with_hash(private_key, Hash::SHA2_256, Box::new(Sha256::new())); //! let verifying_key: VerifyingKey = (&signing_key).into(); //! //! // Sign //! let data = b"hello world"; -//! let digest = Sha256::digest(data).to_vec(); -//! let signature = signing_key.sign_with_rng(&mut rng, &digest); +//! let signature = signing_key.sign_with_rng(&mut rng, data); //! assert_ne!(signature.as_bytes(), data); //! //! // Verify -//! verifying_key.verify(&digest, &signature).expect("failed to verify"); +//! verifying_key.verify(data, &signature).expect("failed to verify"); //! ``` //! //! Using PSS signatures @@ -87,12 +86,11 @@ //! //! // Sign //! let data = b"hello world"; -//! let digest = Sha256::digest(data).to_vec(); -//! let signature = signing_key.sign_with_rng(&mut rng, &digest); +//! let signature = signing_key.sign_with_rng(&mut rng, data); //! assert_ne!(signature.as_bytes(), data); //! //! // Verify -//! verifying_key.verify(&digest, &signature).expect("failed to verify"); +//! verifying_key.verify(data, &signature).expect("failed to verify"); //! ``` //! //! ## PKCS#1 RSA Key Encoding diff --git a/src/pkcs1v15.rs b/src/pkcs1v15.rs index 9e0ee594..e0999903 100644 --- a/src/pkcs1v15.rs +++ b/src/pkcs1v15.rs @@ -1,6 +1,8 @@ +use alloc::boxed::Box; use alloc::vec; use alloc::vec::Vec; use core::fmt::{Debug, Display, Formatter, LowerHex, UpperHex}; +use digest::DynDigest; use rand_core::{CryptoRng, RngCore}; use signature::{RandomizedSigner, Signature as SignSignature, Signer, Verifier}; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq}; @@ -288,6 +290,7 @@ fn non_zero_random_bytes(rng: &mut R, data: &mut [u8]) { pub struct SigningKey { inner: RsaPrivateKey, hash: Option, + digest: Box, } impl SigningKey { @@ -299,24 +302,33 @@ impl SigningKey { self.hash } - pub fn new(key: RsaPrivateKey) -> Self { + pub(crate) fn digest(&self) -> Box { + self.digest.box_clone() + } + + pub fn new(key: RsaPrivateKey, digest: Box) -> Self { Self { inner: key, hash: None, + digest, } } - pub fn new_with_hash(key: RsaPrivateKey, hash: Hash) -> Self { + pub fn new_with_hash(key: RsaPrivateKey, hash: Hash, digest: Box) -> Self { Self { inner: key, hash: Some(hash), + digest, } } } impl Signer for SigningKey { - fn try_sign(&self, digest: &[u8]) -> signature::Result { - sign::(None, &self.inner, self.hash.as_ref(), digest) + fn try_sign(&self, msg: &[u8]) -> signature::Result { + let mut digest = self.digest.box_clone(); + digest.update(msg); + let hashed = digest.finalize_reset(); + sign::(None, &self.inner, self.hash.as_ref(), &hashed) .map(|v| v.into()) .map_err(|e| e.into()) } @@ -326,9 +338,12 @@ impl RandomizedSigner for SigningKey { fn try_sign_with_rng( &self, mut rng: impl CryptoRng + RngCore, - digest: &[u8], + msg: &[u8], ) -> signature::Result { - sign(Some(&mut rng), &self.inner, self.hash.as_ref(), digest) + let mut digest = self.digest.box_clone(); + digest.update(msg); + let hashed = digest.finalize_reset(); + sign(Some(&mut rng), &self.inner, self.hash.as_ref(), &hashed) .map(|v| v.into()) .map_err(|e| e.into()) } @@ -337,20 +352,23 @@ impl RandomizedSigner for SigningKey { pub struct VerifyingKey { inner: RsaPublicKey, hash: Option, + digest: Box, } impl VerifyingKey { - pub fn new(key: RsaPublicKey) -> Self { + pub fn new(key: RsaPublicKey, digest: Box) -> Self { Self { inner: key, hash: None, + digest, } } - pub fn new_with_hash(key: RsaPublicKey, hash: Hash) -> Self { + pub fn new_with_hash(key: RsaPublicKey, hash: Hash, digest: Box) -> Self { Self { inner: key, hash: Some(hash), + digest, } } } @@ -360,6 +378,7 @@ impl From for VerifyingKey { Self { inner: key.key().into(), hash: key.hash(), + digest: key.digest(), } } } @@ -369,13 +388,17 @@ impl From<&SigningKey> for VerifyingKey { Self { inner: key.key().into(), hash: key.hash(), + digest: key.digest(), } } } impl Verifier for VerifyingKey { fn verify(&self, msg: &[u8], signature: &Signature) -> signature::Result<()> { - verify(&self.inner, self.hash.as_ref(), msg, signature.as_ref()).map_err(|e| e.into()) + let mut digest = self.digest.box_clone(); + digest.update(msg); + let hashed = digest.finalize_reset(); + verify(&self.inner, self.hash.as_ref(), &hashed, signature.as_ref()).map_err(|e| e.into()) } } @@ -526,17 +549,18 @@ mod tests { ), )]; - let signing_key = SigningKey::new_with_hash(priv_key, Hash::SHA1); + let signing_key = SigningKey::new_with_hash(priv_key, Hash::SHA1, Box::new(Sha1::new())); for (text, expected) in &tests { let digest = Sha1::digest(text.as_bytes()).to_vec(); - let out = signing_key.sign(&digest); + let out = signing_key.sign(text.as_bytes()); + assert_ne!(out.as_ref(), text.as_bytes()); assert_ne!(out.as_ref(), digest); assert_eq!(out.as_ref(), expected); let mut rng = ChaCha8Rng::from_seed([42; 32]); - let out2 = signing_key.sign_with_rng(&mut rng, &digest); + let out2 = signing_key.sign_with_rng(&mut rng, text.as_bytes()); assert_eq!(out2.as_ref(), expected); } } @@ -606,12 +630,10 @@ mod tests { ), ]; let pub_key: RsaPublicKey = priv_key.into(); - let verifying_key = VerifyingKey::new_with_hash(pub_key, Hash::SHA1); + let verifying_key = VerifyingKey::new_with_hash(pub_key, Hash::SHA1, Box::new(Sha1::new())); for (text, sig, expected) in &tests { - let digest = Sha1::digest(text.as_bytes()).to_vec(); - - let result = verifying_key.verify(&digest, &Signature::from_bytes(sig).unwrap()); + let result = verifying_key.verify(text.as_bytes(), &Signature::from_bytes(sig).unwrap()); match expected { true => result.expect("failed to verify"), false => { @@ -642,10 +664,10 @@ mod tests { #[test] fn test_unpadded_signature_signer() { let msg = b"Thu Dec 19 18:06:16 EST 2013\n"; - let expected_sig = Base64::decode_vec("pX4DR8azytjdQ1rtUiC040FjkepuQut5q2ZFX1pTjBrOVKNjgsCDyiJDGZTCNoh9qpXYbhl7iEym30BWWwuiZg==").unwrap(); + let expected_sig = Base64::decode_vec("F8rxGUnrRLYr9nTWrYMZYk3Y0msVzfl9daWt32AZHJNCVENOWUS17OwcFawgmYhyJZDG3leTT6S5QZLaozun/A==").unwrap(); let priv_key = get_private_key(); - let signing_key = SigningKey::new(priv_key); + let signing_key = SigningKey::new(priv_key, Box::new(Sha1::new())); let sig = signing_key.sign(msg); assert_eq!(sig.as_ref(), expected_sig); diff --git a/src/pss.rs b/src/pss.rs index d577be19..e4891fed 100644 --- a/src/pss.rs +++ b/src/pss.rs @@ -358,15 +358,18 @@ impl RandomizedSigner for SigningKey { fn try_sign_with_rng( &self, mut rng: impl CryptoRng + RngCore, - digest: &[u8], + msg: &[u8], ) -> signature::Result { + let mut digest = self.digest.box_clone(); + digest.update(msg); + let hashed = digest.finalize_reset(); sign_int( &mut rng, false, &self.inner, - digest, + &hashed, self.salt_len, - self.digest.box_clone().as_mut(), + digest.as_mut(), ) .map(|v| v.into()) .map_err(|e| e.into()) @@ -401,15 +404,18 @@ impl RandomizedSigner for BlindedSigningKey { fn try_sign_with_rng( &self, mut rng: impl CryptoRng + RngCore, - digest: &[u8], + msg: &[u8], ) -> signature::Result { + let mut digest = self.digest.box_clone(); + digest.update(msg); + let hashed = digest.finalize_reset(); sign_int( &mut rng, true, &self.inner, - digest, + &hashed, self.salt_len, - self.digest.box_clone().as_mut(), + digest.as_mut(), ) .map(|v| v.into()) .map_err(|e| e.into()) @@ -468,11 +474,14 @@ impl From<&BlindedSigningKey> for VerifyingKey { impl Verifier for VerifyingKey { fn verify(&self, msg: &[u8], signature: &Signature) -> signature::Result<()> { + let mut digest = self.digest.box_clone(); + digest.update(msg); + let hashed = digest.finalize_reset(); verify( &self.inner, - msg, + &hashed, signature.as_ref(), - self.digest.box_clone().as_mut(), + digest.as_mut(), ) .map_err(|e| e.into()) } @@ -578,8 +587,7 @@ mod test { let verifying_key: VerifyingKey = VerifyingKey::new(pub_key, Box::new(Sha1::new())); for (text, sig, expected) in &tests { - let digest = Sha1::digest(text.as_bytes()).to_vec(); - let result = verifying_key.verify(&digest, &Signature::from_bytes(sig).unwrap()); + let result = verifying_key.verify(text.as_bytes(), &Signature::from_bytes(sig).unwrap()); match expected { true => result.expect("failed to verify"), false => { @@ -627,10 +635,9 @@ mod test { let verifying_key: VerifyingKey = (&signing_key).into(); for test in &tests { - let digest = Sha1::digest(test.as_bytes()).to_vec(); - let sig = signing_key.sign_with_rng(&mut rng, &digest); + let sig = signing_key.sign_with_rng(&mut rng, test.as_bytes()); verifying_key - .verify(&digest, &sig) + .verify(test.as_bytes(), &sig) .expect("failed to verify"); } } @@ -645,10 +652,9 @@ mod test { let verifying_key: VerifyingKey = (&signing_key).into(); for test in &tests { - let digest = Sha1::digest(test.as_bytes()).to_vec(); - let sig = signing_key.sign_with_rng(&mut rng, &digest); + let sig = signing_key.sign_with_rng(&mut rng, test.as_bytes()); verifying_key - .verify(&digest, &sig) + .verify(test.as_bytes(), &sig) .expect("failed to verify"); } }