diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2020-11-10 15:28:07 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2020-11-12 10:32:00 +0100 |
commit | 8b390e8a38d8a31b5ada19a5ebbce924ee777fd8 (patch) | |
tree | 730ba04c27a8ceb603d00bffa22c6851a43c54d6 /openpgp/src/crypto | |
parent | 91e82329cb50dda79243d933f13fd22888af5cdd (diff) |
openpgp: Mitigate collision attacks on SHA-1.
- Use a collision detecting implementation of SHA-1. When a
collision attack is detected, the algorithm employs a mitigation,
changing the hash function to discriminate the colliding preimage.
Diffstat (limited to 'openpgp/src/crypto')
-rw-r--r-- | openpgp/src/crypto/backend.rs | 2 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/sha1cd.rs | 30 | ||||
-rw-r--r-- | openpgp/src/crypto/hash.rs | 22 |
3 files changed, 45 insertions, 9 deletions
diff --git a/openpgp/src/crypto/backend.rs b/openpgp/src/crypto/backend.rs index abd7d53c..11727d74 100644 --- a/openpgp/src/crypto/backend.rs +++ b/openpgp/src/crypto/backend.rs @@ -1,6 +1,8 @@ //! Concrete implementation of the crypto primitives used by the rest of the //! crypto API. +pub(crate) mod sha1cd; + #[cfg(feature = "crypto-nettle")] mod nettle; #[cfg(feature = "crypto-nettle")] diff --git a/openpgp/src/crypto/backend/sha1cd.rs b/openpgp/src/crypto/backend/sha1cd.rs new file mode 100644 index 00000000..1de5f078 --- /dev/null +++ b/openpgp/src/crypto/backend/sha1cd.rs @@ -0,0 +1,30 @@ +use crate::crypto::hash::Digest; +use crate::Result; + +pub(crate) fn build() -> sha1collisiondetection::Sha1CD { + sha1collisiondetection::Builder::default() + .detect_collisions(true) + .use_ubc(true) + .safe_hash(true) + .build() +} + +impl Digest for sha1collisiondetection::Sha1CD { + fn digest_size(&self) -> usize { + 20 + } + + fn update(&mut self, data: &[u8]) { + digest::Update::update(self, data); + } + + fn digest(&mut self, digest: &mut [u8]) -> Result<()> { + let mut d = + generic_array::GenericArray::<u8, digest::consts::U20>::default(); + let r = self.finalize_into_dirty_cd(&mut d); + digest::Reset::reset(self); + let l = digest.len().min(d.len()); + &mut digest[..l].copy_from_slice(&d[..l]); + r.map_err(Into::into) + } +} diff --git a/openpgp/src/crypto/hash.rs b/openpgp/src/crypto/hash.rs index 5643a30a..5517d205 100644 --- a/openpgp/src/crypto/hash.rs +++ b/openpgp/src/crypto/hash.rs @@ -137,15 +137,19 @@ impl HashAlgorithm { /// /// [`HashAlgorithm::is_supported`]: #method.is_supported pub fn context(self) -> Result<Context> { - self.new_hasher() - .map(|hasher| Context { - algo: self, - ctx: if let Some(prefix) = DUMP_HASHED_VALUES { - Box::new(HashDumper::new(hasher, prefix)) - } else { - hasher - }, - }) + let hasher = match self { + HashAlgorithm::SHA1 => + Box::new(crate::crypto::backend::sha1cd::build()), + _ => self.new_hasher()?, + }; + Ok(Context { + algo: self, + ctx: if let Some(prefix) = DUMP_HASHED_VALUES { + Box::new(HashDumper::new(hasher, prefix)) + } else { + hasher + }, + }) } } |