summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2023-06-26 13:27:35 +0200
committerJustus Winter <justus@sequoia-pgp.org>2023-06-26 13:27:35 +0200
commit0c8869b7fb711a85610687b05e00661d145dabe1 (patch)
tree9ea3b0a5dbd1ab251f366d57ef31feff1da2018e
parentf44e788d7aefc1f781b17798115849b88cc6aa5a (diff)
parent90a0c9e4c7d2de2cffc32bce4cd6d56802a9bcc2 (diff)
Merge branch 'crypto-refresh-sha3' into crypto-refresh
-rw-r--r--Cargo.lock20
-rw-r--r--openpgp/Cargo.toml4
-rw-r--r--openpgp/NEWS11
-rw-r--r--openpgp/src/crypto/backend/botan/hash.rs4
-rw-r--r--openpgp/src/crypto/backend/cng/hash.rs24
-rw-r--r--openpgp/src/crypto/backend/nettle/hash.rs8
-rw-r--r--openpgp/src/crypto/backend/openssl/hash.rs5
-rw-r--r--openpgp/src/crypto/backend/rust/hash.rs6
-rw-r--r--openpgp/src/crypto/hash.rs14
-rw-r--r--openpgp/src/types/mod.rs20
10 files changed, 110 insertions, 6 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 19ddf72d..c50a0d8e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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(_) =>