diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2023-06-26 13:27:35 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2023-06-26 13:27:35 +0200 |
commit | 0c8869b7fb711a85610687b05e00661d145dabe1 (patch) | |
tree | 9ea3b0a5dbd1ab251f366d57ef31feff1da2018e | |
parent | f44e788d7aefc1f781b17798115849b88cc6aa5a (diff) | |
parent | 90a0c9e4c7d2de2cffc32bce4cd6d56802a9bcc2 (diff) |
Merge branch 'crypto-refresh-sha3' into crypto-refresh
-rw-r--r-- | Cargo.lock | 20 | ||||
-rw-r--r-- | openpgp/Cargo.toml | 4 | ||||
-rw-r--r-- | openpgp/NEWS | 11 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/botan/hash.rs | 4 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/cng/hash.rs | 24 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/nettle/hash.rs | 8 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/openssl/hash.rs | 5 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/rust/hash.rs | 6 | ||||
-rw-r--r-- | openpgp/src/crypto/hash.rs | 14 | ||||
-rw-r--r-- | openpgp/src/types/mod.rs | 20 |
10 files changed, 110 insertions, 6 deletions
@@ -1424,6 +1424,15 @@ dependencies = [ ] [[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + +[[package]] name = "lalrpop" version = "0.19.12" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2450,6 +2459,7 @@ dependencies = [ "sha-1", "sha1collisiondetection", "sha2 0.10.6", + "sha3", "thiserror", "twofish", "typenum", @@ -2536,6 +2546,16 @@ dependencies = [ ] [[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.6", + "keccak", +] + +[[package]] name = "shlex" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/openpgp/Cargo.toml b/openpgp/Cargo.toml index 523086b1..f934d178 100644 --- a/openpgp/Cargo.toml +++ b/openpgp/Cargo.toml @@ -93,6 +93,7 @@ ripemd = { version = "0.1", features = ["oid"], optional = true } rsa = { version = "0.9.0", optional = true } sha-1 = { version = "0.10", features = ["oid"], optional = true } sha2 = { version = "0.10", features = ["oid"], optional = true } +sha3 = { version = "0.10", features = ["oid"], optional = true } twofish = { version = "0.7", optional = true } typenum = { version = "1.12.0", optional = true } # XXX: x25519-dalek-ng is a fork of x25519-dalek shortly before its @@ -133,7 +134,8 @@ crypto-nettle = ["nettle"] crypto-rust = [ "aes", "block-padding", "blowfish", "cast5", "cfb-mode", "cipher", "des", "digest", "eax", "ecb", "ed25519", "ed25519-dalek", "generic-array", "idea", - "md-5", "num-bigint-dig", "rand", "rand07", "ripemd", "rsa", "sha-1", "sha2", + "md-5", "num-bigint-dig", "rand", "rand07", "ripemd", "rsa", + "sha-1", "sha2", "sha3", "twofish", "typenum", "x25519-dalek-ng", "p256", "rand_core", "rand_core/getrandom", "ecdsa", "aes-gcm", "hkdf" ] diff --git a/openpgp/NEWS b/openpgp/NEWS index 0f11119c..3e623100 100644 --- a/openpgp/NEWS +++ b/openpgp/NEWS @@ -3,6 +3,17 @@ #+TITLE: sequoia-openpgp NEWS – history of user-visible changes #+STARTUP: content hidestars +* Changes in 2.0.0 + The major new feature is the support for RFCXXXX, which modernizes + the cryptographic primitives used in OpenPGP. Notably, it adds + Authenticated Encryption, Elliptic Curve Cryptography, and + deprecates old algorithms. + + We have also used the opportunity to clean up our API. Most + programs should only require minor adjustments. +** New functionality + - HashAlgorithm::SHA3_256 + - HashAlgorithm::SHA3_512 * Changes in 1.17.0 ** New functionality - crypto::SessionKey::as_protected diff --git a/openpgp/src/crypto/backend/botan/hash.rs b/openpgp/src/crypto/backend/botan/hash.rs index 0e02b5dd..7f5934e3 100644 --- a/openpgp/src/crypto/backend/botan/hash.rs +++ b/openpgp/src/crypto/backend/botan/hash.rs @@ -48,6 +48,8 @@ impl HashAlgorithm { HashAlgorithm::SHA256 => true, HashAlgorithm::SHA384 => true, HashAlgorithm::SHA512 => true, + HashAlgorithm::SHA3_256 => true, + HashAlgorithm::SHA3_512 => true, HashAlgorithm::RipeMD => true, HashAlgorithm::MD5 => true, HashAlgorithm::Private(_) => false, @@ -82,6 +84,8 @@ impl HashAlgorithm { HashAlgorithm::SHA256 => Ok("SHA-256"), HashAlgorithm::SHA384 => Ok("SHA-384"), HashAlgorithm::SHA512 => Ok("SHA-512"), + HashAlgorithm::SHA3_256 => Ok("SHA-3(256)"), + HashAlgorithm::SHA3_512 => Ok("SHA-3(512)"), HashAlgorithm::MD5 => Ok("MD5"), HashAlgorithm::RipeMD => Ok("RIPEMD-160"), HashAlgorithm::Private(_) | HashAlgorithm::Unknown(_) => diff --git a/openpgp/src/crypto/backend/cng/hash.rs b/openpgp/src/crypto/backend/cng/hash.rs index 6254d12d..e71789d1 100644 --- a/openpgp/src/crypto/backend/cng/hash.rs +++ b/openpgp/src/crypto/backend/cng/hash.rs @@ -83,7 +83,18 @@ impl TryFrom<HashAlgorithm> for cng::HashAlgorithmId { HashAlgorithm::SHA384 => cng::HashAlgorithmId::Sha384, HashAlgorithm::SHA512 => cng::HashAlgorithmId::Sha512, HashAlgorithm::MD5 => cng::HashAlgorithmId::Md5, - algo => Err(Error::UnsupportedHashAlgorithm(algo))?, + + // SHA3 support is on the horizon, see + // https://blogs.windows.com/windows-insider/2023/03/23/announcing-windows-11-insider-preview-build-25324/ + HashAlgorithm::SHA3_256 | + HashAlgorithm::SHA3_512 => + return Err(Error::UnsupportedHashAlgorithm(value)), + + HashAlgorithm::SHA224 | + HashAlgorithm::RipeMD | + HashAlgorithm::Private(_) | + HashAlgorithm::Unknown(_) => + return Err(Error::UnsupportedHashAlgorithm(value)), }) } } @@ -113,7 +124,16 @@ impl HashAlgorithm { HashAlgorithm::SHA384 => true, HashAlgorithm::SHA512 => true, HashAlgorithm::MD5 => true, - _ => false, + + // SHA3 support is on the horizon, see + // https://blogs.windows.com/windows-insider/2023/03/23/announcing-windows-11-insider-preview-build-25324/ + HashAlgorithm::SHA3_256 | + HashAlgorithm::SHA3_512 => false, + + HashAlgorithm::SHA224 | + HashAlgorithm::RipeMD | + HashAlgorithm::Private(_) | + HashAlgorithm::Unknown(_) => false, } } diff --git a/openpgp/src/crypto/backend/nettle/hash.rs b/openpgp/src/crypto/backend/nettle/hash.rs index 4bf1535e..3e9d12a6 100644 --- a/openpgp/src/crypto/backend/nettle/hash.rs +++ b/openpgp/src/crypto/backend/nettle/hash.rs @@ -29,6 +29,8 @@ impl_digest_for!(nettle::hash::Sha224, SHA224); impl_digest_for!(nettle::hash::Sha256, SHA256); impl_digest_for!(nettle::hash::Sha384, SHA384); impl_digest_for!(nettle::hash::Sha512, SHA512); +impl_digest_for!(nettle::hash::Sha3_256, SHA3_256); +impl_digest_for!(nettle::hash::Sha3_512, SHA3_512); impl_digest_for!(nettle::hash::insecure_do_not_use::Sha1, SHA1); impl_digest_for!(nettle::hash::insecure_do_not_use::Md5, MD5); impl_digest_for!(nettle::hash::insecure_do_not_use::Ripemd160, RipeMD); @@ -42,6 +44,8 @@ impl HashAlgorithm { HashAlgorithm::SHA256 => true, HashAlgorithm::SHA384 => true, HashAlgorithm::SHA512 => true, + HashAlgorithm::SHA3_256 => true, + HashAlgorithm::SHA3_512 => true, HashAlgorithm::RipeMD => true, HashAlgorithm::MD5 => true, HashAlgorithm::Private(_) => false, @@ -59,7 +63,7 @@ impl HashAlgorithm { /// /// [`HashAlgorithm::is_supported`]: HashAlgorithm::is_supported() pub(crate) fn new_hasher(self) -> Result<Box<dyn Digest>> { - use nettle::hash::{Sha224, Sha256, Sha384, Sha512}; + use nettle::hash::{Sha224, Sha256, Sha384, Sha512, Sha3_256, Sha3_512}; use nettle::hash::insecure_do_not_use::{ Sha1, Md5, @@ -72,6 +76,8 @@ impl HashAlgorithm { HashAlgorithm::SHA256 => Ok(Box::new(Sha256::default())), HashAlgorithm::SHA384 => Ok(Box::new(Sha384::default())), HashAlgorithm::SHA512 => Ok(Box::new(Sha512::default())), + HashAlgorithm::SHA3_256 => Ok(Box::new(Sha3_256::default())), + HashAlgorithm::SHA3_512 => Ok(Box::new(Sha3_512::default())), HashAlgorithm::MD5 => Ok(Box::new(Md5::default())), HashAlgorithm::RipeMD => Ok(Box::new(Ripemd160::default())), HashAlgorithm::Private(_) | HashAlgorithm::Unknown(_) => diff --git a/openpgp/src/crypto/backend/openssl/hash.rs b/openpgp/src/crypto/backend/openssl/hash.rs index 7dc9b5d1..e8db9373 100644 --- a/openpgp/src/crypto/backend/openssl/hash.rs +++ b/openpgp/src/crypto/backend/openssl/hash.rs @@ -73,7 +73,10 @@ fn get_md(algo: HashAlgorithm) -> Option<MessageDigest> { SHA384 => Nid::SHA384, SHA512 => Nid::SHA512, SHA224 => Nid::SHA224, - _ => return None, + SHA3_256 => Nid::SHA3_256, + SHA3_512 => Nid::SHA3_512, + HashAlgorithm::Private(_) | + HashAlgorithm::Unknown(_) => return None, }; MessageDigest::from_nid(nid) } diff --git a/openpgp/src/crypto/backend/rust/hash.rs b/openpgp/src/crypto/backend/rust/hash.rs index 42c6050a..13ec311a 100644 --- a/openpgp/src/crypto/backend/rust/hash.rs +++ b/openpgp/src/crypto/backend/rust/hash.rs @@ -38,6 +38,8 @@ impl_digest_for!(sha2::Sha224, SHA224); impl_digest_for!(sha2::Sha256, SHA256); impl_digest_for!(sha2::Sha384, SHA384); impl_digest_for!(sha2::Sha512, SHA512); +impl_digest_for!(sha3::Sha3_256, SHA3_256); +impl_digest_for!(sha3::Sha3_512, SHA3_512); impl HashAlgorithm { /// Whether Sequoia supports this algorithm. @@ -48,6 +50,8 @@ impl HashAlgorithm { HashAlgorithm::SHA256 => true, HashAlgorithm::SHA384 => true, HashAlgorithm::SHA512 => true, + HashAlgorithm::SHA3_256 => true, + HashAlgorithm::SHA3_512 => true, HashAlgorithm::RipeMD => true, HashAlgorithm::MD5 => true, HashAlgorithm::Private(_) => false, @@ -71,6 +75,8 @@ impl HashAlgorithm { HashAlgorithm::SHA256 => Ok(Box::new(sha2::Sha256::new())), HashAlgorithm::SHA384 => Ok(Box::new(sha2::Sha384::new())), HashAlgorithm::SHA512 => Ok(Box::new(sha2::Sha512::new())), + HashAlgorithm::SHA3_256 => Ok(Box::new(sha3::Sha3_256::new())), + HashAlgorithm::SHA3_512 => Ok(Box::new(sha3::Sha3_512::new())), HashAlgorithm::RipeMD => Ok(Box::new(ripemd::Ripemd160::new())), HashAlgorithm::MD5 => Ok(Box::new(md5::Md5::new())), HashAlgorithm::Private(_) | HashAlgorithm::Unknown(_) => diff --git a/openpgp/src/crypto/hash.rs b/openpgp/src/crypto/hash.rs index bb905b63..680dc7e9 100644 --- a/openpgp/src/crypto/hash.rs +++ b/openpgp/src/crypto/hash.rs @@ -96,6 +96,18 @@ const ASN1_OID_SHA512: &[u8] = &[ 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40, ]; +/// ASN.1 OID for SHA3-256 +const ASN1_OID_SHA3_256: &[u8] = &[ + 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x08, 0x05, 0x00, 0x04, 0x20 +]; + +/// ASN.1 OID for SHA3-512. +const ASN1_OID_SHA3_512: &[u8] = &[ + 0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x0a, 0x05, 0x00, 0x04, 0x40 +]; + lazy_static::lazy_static! { /// List of hashes that the signer may produce. /// This list is ordered by the preference so that the most preferred @@ -234,6 +246,8 @@ impl HashAlgorithm { HashAlgorithm::SHA256 => Ok(ASN1_OID_SHA256), HashAlgorithm::SHA384 => Ok(ASN1_OID_SHA384), HashAlgorithm::SHA512 => Ok(ASN1_OID_SHA512), + HashAlgorithm::SHA3_256 => Ok(ASN1_OID_SHA3_256), + HashAlgorithm::SHA3_512 => Ok(ASN1_OID_SHA3_512), HashAlgorithm::MD5 => Ok(ASN1_OID_MD5), HashAlgorithm::RipeMD => Ok(ASN1_OID_RIPEMD160), HashAlgorithm::Private(_) | HashAlgorithm::Unknown(_) => diff --git a/openpgp/src/types/mod.rs b/openpgp/src/types/mod.rs index 88f82107..1c0a5f77 100644 --- a/openpgp/src/types/mod.rs +++ b/openpgp/src/types/mod.rs @@ -1318,6 +1318,10 @@ pub enum HashAlgorithm { SHA512, /// 224-bit version of SHA2 SHA224, + /// 256-bit version of SHA3 + SHA3_256, + /// 512-bit version of SHA3 + SHA3_512, /// Private hash algorithm identifier. Private(u8), /// Unknown hash algorithm identifier. @@ -1325,7 +1329,7 @@ pub enum HashAlgorithm { } assert_send_and_sync!(HashAlgorithm); -const HASH_ALGORITHM_VARIANTS: [HashAlgorithm; 7] = [ +const HASH_ALGORITHM_VARIANTS: [HashAlgorithm; 9] = [ HashAlgorithm::MD5, HashAlgorithm::SHA1, HashAlgorithm::RipeMD, @@ -1333,6 +1337,8 @@ const HASH_ALGORITHM_VARIANTS: [HashAlgorithm; 7] = [ HashAlgorithm::SHA384, HashAlgorithm::SHA512, HashAlgorithm::SHA224, + HashAlgorithm::SHA3_256, + HashAlgorithm::SHA3_512, ]; impl Default for HashAlgorithm { @@ -1353,6 +1359,8 @@ impl From<u8> for HashAlgorithm { 9 => HashAlgorithm::SHA384, 10 => HashAlgorithm::SHA512, 11 => HashAlgorithm::SHA224, + 12 => HashAlgorithm::SHA3_256, + 14 => HashAlgorithm::SHA3_512, 100..=110 => HashAlgorithm::Private(u), u => HashAlgorithm::Unknown(u), } @@ -1369,6 +1377,8 @@ impl From<HashAlgorithm> for u8 { HashAlgorithm::SHA384 => 9, HashAlgorithm::SHA512 => 10, HashAlgorithm::SHA224 => 11, + HashAlgorithm::SHA3_256 => 12, + HashAlgorithm::SHA3_512 => 14, HashAlgorithm::Private(u) => u, HashAlgorithm::Unknown(u) => u, } @@ -1393,6 +1403,10 @@ impl FromStr for HashAlgorithm { Ok(HashAlgorithm::SHA512) } else if s.eq_ignore_ascii_case("SHA224") { Ok(HashAlgorithm::SHA224) + } else if s.eq_ignore_ascii_case("SHA3-256") { + Ok(HashAlgorithm::SHA3_256) + } else if s.eq_ignore_ascii_case("SHA3-512") { + Ok(HashAlgorithm::SHA3_512) } else { Err(()) } @@ -1409,6 +1423,8 @@ impl fmt::Display for HashAlgorithm { HashAlgorithm::SHA384 => f.write_str("SHA384"), HashAlgorithm::SHA512 => f.write_str("SHA512"), HashAlgorithm::SHA224 => f.write_str("SHA224"), + HashAlgorithm::SHA3_256 => f.write_str("SHA3-256"), + HashAlgorithm::SHA3_512 => f.write_str("SHA3-512"), HashAlgorithm::Private(u) => f.write_fmt(format_args!("Private/Experimental hash algorithm {}", u)), HashAlgorithm::Unknown(u) => @@ -1445,6 +1461,8 @@ impl HashAlgorithm { HashAlgorithm::SHA384 => Ok("SHA384"), HashAlgorithm::SHA512 => Ok("SHA512"), HashAlgorithm::SHA224 => Ok("SHA224"), + HashAlgorithm::SHA3_256 => Ok("SHA3-256"), + HashAlgorithm::SHA3_512 => Ok("SHA3-512"), HashAlgorithm::Private(_) => Err(Error::UnsupportedHashAlgorithm(*self).into()), HashAlgorithm::Unknown(_) => |