sequoia_openpgp/crypto/backend/nettle/
hash.rs1use crate::crypto::hash::Digest;
2use crate::{Error, Result};
3use crate::types::{HashAlgorithm};
4
5macro_rules! impl_digest_for {
6 ($t: path, $algo: ident) => {
7 impl Digest for $t {
8 fn update(&mut self, data: &[u8]) {
9 nettle::hash::Hash::update(self, data);
10 }
11
12 fn digest(&mut self, digest: &mut [u8]) -> Result<()> {
13 nettle::hash::Hash::digest(self, digest);
14 Ok(())
15 }
16 }
17 }
18}
19
20impl_digest_for!(nettle::hash::Sha224, SHA224);
21impl_digest_for!(nettle::hash::Sha256, SHA256);
22impl_digest_for!(nettle::hash::Sha384, SHA384);
23impl_digest_for!(nettle::hash::Sha512, SHA512);
24impl_digest_for!(nettle::hash::Sha3_256, SHA3_256);
25impl_digest_for!(nettle::hash::Sha3_512, SHA3_512);
26impl_digest_for!(nettle::hash::insecure_do_not_use::Sha1, SHA1);
27impl_digest_for!(nettle::hash::insecure_do_not_use::Md5, MD5);
28impl_digest_for!(nettle::hash::insecure_do_not_use::Ripemd160, RipeMD);
29
30impl HashAlgorithm {
31 pub fn is_supported(self) -> bool {
33 match self {
34 HashAlgorithm::SHA1 => true,
35 HashAlgorithm::SHA224 => true,
36 HashAlgorithm::SHA256 => true,
37 HashAlgorithm::SHA384 => true,
38 HashAlgorithm::SHA512 => true,
39 HashAlgorithm::SHA3_256 => true,
40 HashAlgorithm::SHA3_512 => true,
41 HashAlgorithm::RipeMD => true,
42 HashAlgorithm::MD5 => true,
43 HashAlgorithm::Private(_) => false,
44 HashAlgorithm::Unknown(_) => false,
45 }
46 }
47
48 pub(crate) fn new_hasher(self) -> Result<Box<dyn Digest>> {
58 use nettle::hash::{Sha224, Sha256, Sha384, Sha512, Sha3_256, Sha3_512};
59 use nettle::hash::insecure_do_not_use::{
60 Sha1,
61 Md5,
62 Ripemd160,
63 };
64
65 match self {
66 HashAlgorithm::SHA1 => Ok(Box::new(Sha1::default())),
67 HashAlgorithm::SHA224 => Ok(Box::new(Sha224::default())),
68 HashAlgorithm::SHA256 => Ok(Box::new(Sha256::default())),
69 HashAlgorithm::SHA384 => Ok(Box::new(Sha384::default())),
70 HashAlgorithm::SHA512 => Ok(Box::new(Sha512::default())),
71 HashAlgorithm::SHA3_256 => Ok(Box::new(Sha3_256::default())),
72 HashAlgorithm::SHA3_512 => Ok(Box::new(Sha3_512::default())),
73 HashAlgorithm::MD5 => Ok(Box::new(Md5::default())),
74 HashAlgorithm::RipeMD => Ok(Box::new(Ripemd160::default())),
75 HashAlgorithm::Private(_) | HashAlgorithm::Unknown(_) =>
76 Err(Error::UnsupportedHashAlgorithm(self).into()),
77 }
78 }
79}
80
81#[cfg(all(test, feature = "crypto-nettle"))]
82mod tests {
83 use super::*;
84 use nettle::rsa;
85
86 #[test]
87 fn oids_match_nettle() {
88 assert_eq!(HashAlgorithm::SHA1.oid().unwrap(), rsa::ASN1_OID_SHA1);
89 assert_eq!(HashAlgorithm::SHA224.oid().unwrap(), rsa::ASN1_OID_SHA224);
90 assert_eq!(HashAlgorithm::SHA256.oid().unwrap(), rsa::ASN1_OID_SHA256);
91 assert_eq!(HashAlgorithm::SHA384.oid().unwrap(), rsa::ASN1_OID_SHA384);
92 assert_eq!(HashAlgorithm::SHA512.oid().unwrap(), rsa::ASN1_OID_SHA512);
93 assert_eq!(HashAlgorithm::MD5.oid().unwrap(), rsa::ASN1_OID_MD5);
94 assert_eq!(HashAlgorithm::RipeMD.oid().unwrap(), rsa::ASN1_OID_RIPEMD160);
95 }
96}