summaryrefslogtreecommitdiffstats
path: root/openpgp/src/crypto
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2020-11-10 15:28:07 +0100
committerJustus Winter <justus@sequoia-pgp.org>2020-11-12 10:32:00 +0100
commit8b390e8a38d8a31b5ada19a5ebbce924ee777fd8 (patch)
tree730ba04c27a8ceb603d00bffa22c6851a43c54d6 /openpgp/src/crypto
parent91e82329cb50dda79243d933f13fd22888af5cdd (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.rs2
-rw-r--r--openpgp/src/crypto/backend/sha1cd.rs30
-rw-r--r--openpgp/src/crypto/hash.rs22
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
+ },
+ })
}
}