diff options
Diffstat (limited to 'openpgp/src/crypto/backend')
-rw-r--r-- | openpgp/src/crypto/backend/nettle.rs | 1 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/nettle/hash.rs | 84 |
2 files changed, 85 insertions, 0 deletions
diff --git a/openpgp/src/crypto/backend/nettle.rs b/openpgp/src/crypto/backend/nettle.rs index 73b37569..25fc64eb 100644 --- a/openpgp/src/crypto/backend/nettle.rs +++ b/openpgp/src/crypto/backend/nettle.rs @@ -5,6 +5,7 @@ use nettle::random::{Random, Yarrow}; pub mod aead; pub mod asymmetric; pub mod ecdh; +pub mod hash; /// Fills the given buffer with random data. pub fn random<B: AsMut<[u8]>>(mut buf: B) { diff --git a/openpgp/src/crypto/backend/nettle/hash.rs b/openpgp/src/crypto/backend/nettle/hash.rs new file mode 100644 index 00000000..12271762 --- /dev/null +++ b/openpgp/src/crypto/backend/nettle/hash.rs @@ -0,0 +1,84 @@ +use crate::crypto::hash::Digest; +use crate::{Error, Result}; +use crate::types::{HashAlgorithm}; + +impl<T: nettle::hash::Hash + Clone> Digest for T { + fn digest_size(&self) -> usize { + self.digest_size() + } + + fn update(&mut self, data: &[u8]) { + self.update(data); + } + + fn digest(&mut self, digest: &mut [u8]) { + self.digest(digest); + } +} + +impl HashAlgorithm { + /// Whether Sequoia supports this algorithm. + pub fn is_supported(self) -> bool { + match self { + HashAlgorithm::SHA1 => true, + HashAlgorithm::SHA224 => true, + HashAlgorithm::SHA256 => true, + HashAlgorithm::SHA384 => true, + HashAlgorithm::SHA512 => true, + HashAlgorithm::RipeMD => true, + HashAlgorithm::MD5 => true, + HashAlgorithm::Private(_) => false, + HashAlgorithm::Unknown(_) => false, + HashAlgorithm::__Nonexhaustive => unreachable!(), + } + } + + /// Creates a new hash context for this algorithm. + /// + /// # Errors + /// + /// Fails with `Error::UnsupportedHashAlgorithm` if Sequoia does + /// not support this algorithm. See + /// [`HashAlgorithm::is_supported`]. + /// + /// [`HashAlgorithm::is_supported`]: #method.is_supported + pub fn new_hasher(self) -> Result<Box<dyn Digest>> { + use nettle::hash::{Sha224, Sha256, Sha384, Sha512}; + use nettle::hash::insecure_do_not_use::{ + Sha1, + Md5, + Ripemd160, + }; + + match self { + HashAlgorithm::SHA1 => Ok(Box::new(Sha1::default())), + HashAlgorithm::SHA224 => Ok(Box::new(Sha224::default())), + HashAlgorithm::SHA256 => Ok(Box::new(Sha256::default())), + HashAlgorithm::SHA384 => Ok(Box::new(Sha384::default())), + HashAlgorithm::SHA512 => Ok(Box::new(Sha512::default())), + HashAlgorithm::MD5 => Ok(Box::new(Md5::default())), + HashAlgorithm::RipeMD => Ok(Box::new(Ripemd160::default())), + HashAlgorithm::Private(_) | HashAlgorithm::Unknown(_) => + Err(Error::UnsupportedHashAlgorithm(self).into()), + HashAlgorithm::__Nonexhaustive => unreachable!(), + } + } + + /// Returns the ASN.1 OID of this hash algorithm. + pub fn oid(self) -> Result<&'static [u8]> { + use nettle::rsa; + + match self { + HashAlgorithm::SHA1 => Ok(rsa::ASN1_OID_SHA1), + HashAlgorithm::SHA224 => Ok(rsa::ASN1_OID_SHA224), + HashAlgorithm::SHA256 => Ok(rsa::ASN1_OID_SHA256), + HashAlgorithm::SHA384 => Ok(rsa::ASN1_OID_SHA384), + HashAlgorithm::SHA512 => Ok(rsa::ASN1_OID_SHA512), + HashAlgorithm::MD5 => Ok(rsa::ASN1_OID_MD5), + HashAlgorithm::RipeMD => Ok(rsa::ASN1_OID_RIPEMD160), + HashAlgorithm::Private(_) | HashAlgorithm::Unknown(_) => + Err(Error::UnsupportedHashAlgorithm(self).into()), + HashAlgorithm::__Nonexhaustive => unreachable!(), + } + } +} |