summaryrefslogtreecommitdiffstats
path: root/openpgp
diff options
context:
space:
mode:
authorWiktor Kwapisiewicz <wiktor@metacode.biz>2023-09-05 14:50:36 +0200
committerWiktor Kwapisiewicz <wiktor@metacode.biz>2023-09-11 12:14:44 +0200
commitf4addd7cc4163302a62a922c7deb1a84db66c898 (patch)
tree51d87b3622fa5fe9244fe7cdbe725d1e147cf7ae /openpgp
parentf6afcf90357cc0d0c33eceab7d489fb80805435b (diff)
openpgp: Migrate from x25519-dalek-ng to x25519-dalek v2.
- Fixes https://gitlab.com/sequoia-pgp/sequoia/-/issues/1051.
Diffstat (limited to 'openpgp')
-rw-r--r--openpgp/Cargo.toml15
-rw-r--r--openpgp/src/crypto/backend/rust/asymmetric.rs16
-rw-r--r--openpgp/src/crypto/backend/rust/ecdh.rs4
3 files changed, 16 insertions, 19 deletions
diff --git a/openpgp/Cargo.toml b/openpgp/Cargo.toml
index 4cadd511..5a7a9d60 100644
--- a/openpgp/Cargo.toml
+++ b/openpgp/Cargo.toml
@@ -90,18 +90,7 @@ sha-1 = { version = "0.10", features = ["oid"], optional = true }
sha2 = { 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
-# last release. The latest stable release of x25519-dalek depends on
-# zeroize =1.3, which is a problem, because other crates, like rsa,
-# depend on newer versions of zeroize. Thus, depending on
-# x25519-dalek prevents us from updating those crates. Although this
-# problem is known for over two years (as of April 2023), upstream
-# hasn't fixed it. The x25519-dalek-ng fork, however, has.
-# Unfortunately, it is not actively developed. So we use
-# x25519-dalek-ng for now. Medium term, we should find a replacement
-# for this crate, or switch back to x25519-dalek if it becomes after
-# again.
-x25519-dalek-ng = { version = "1", optional = true }
+x25519-dalek = { version = "2", optional = true, default-features = false, features = ["static_secrets"] }
[target.'cfg(windows)'.dependencies]
win-crypto-ng = { version = ">=0.4, <0.6", features = ["rand", "block-cipher"], optional = true }
@@ -127,7 +116,7 @@ crypto-rust = [
"aes", "block-padding", "blowfish", "camellia", "cast5", "cfb-mode", "cipher", "des",
"digest", "eax", "ecb", "ed25519", "ed25519-dalek", "generic-array", "idea",
"md-5", "num-bigint-dig", "ripemd", "rsa", "sha-1", "sha2",
- "twofish", "typenum", "x25519-dalek-ng", "p256",
+ "twofish", "typenum", "x25519-dalek", "p256",
"rand_core", "rand_core/getrandom", "ecdsa", "aes-gcm", "dsa"
]
crypto-cng = [
diff --git a/openpgp/src/crypto/backend/rust/asymmetric.rs b/openpgp/src/crypto/backend/rust/asymmetric.rs
index 8717e3fb..b1a7abd9 100644
--- a/openpgp/src/crypto/backend/rust/asymmetric.rs
+++ b/openpgp/src/crypto/backend/rust/asymmetric.rs
@@ -7,7 +7,6 @@
use std::convert::TryFrom;
use std::time::SystemTime;
-use x25519_dalek_ng as x25519_dalek;
use num_bigint_dig::{traits::ModInverse, BigUint};
use rsa::traits::{PrivateKeyParts, PublicKeyParts};
use rsa::{Pkcs1v15Encrypt, RsaPublicKey, RsaPrivateKey, Pkcs1v15Sign};
@@ -76,10 +75,10 @@ impl Asymmetric for super::Backend {
// depends on rand 0.8.
use rand::rngs::OsRng;
- let secret = StaticSecret::new(&mut OsRng);
+ let secret = StaticSecret::random_from_rng(&mut OsRng);
let public = PublicKey::from(&secret);
let mut secret_bytes = secret.to_bytes();
- let secret = secret_bytes.as_ref().into();
+ let secret: Protected = secret_bytes.as_ref().into();
unsafe {
memsec::memzero(secret_bytes.as_mut_ptr(), secret_bytes.len());
}
@@ -587,6 +586,17 @@ impl<R> Key4<SecretParts, R>
let (mut private, public) =
super::Backend::x25519_generate_key()?;
+ // x25519-dalek since v 2.0.0-rc.3 does not return clamped
+ // integers from Static Secrets but clamps them on usage.
+ // See: https://github.com/dalek-cryptography/x25519-dalek/blob/main/CHANGELOG.md#200-rc3
+ //
+ // Clamp the scalar. X25519 does the clamping implicitly, but
+ // OpenPGP's ECDH over Curve25519 requires the secret to be
+ // clamped.
+ private[0] &= 0b1111_1000;
+ private[31] &= !0b1000_0000;
+ private[31] |= 0b0100_0000;
+
private.reverse();
let public_mpis = mpi::PublicKey::ECDH {
diff --git a/openpgp/src/crypto/backend/rust/ecdh.rs b/openpgp/src/crypto/backend/rust/ecdh.rs
index c7d4c4e1..105f1d61 100644
--- a/openpgp/src/crypto/backend/rust/ecdh.rs
+++ b/openpgp/src/crypto/backend/rust/ecdh.rs
@@ -2,8 +2,6 @@
use std::convert::TryInto;
-use x25519_dalek_ng as x25519_dalek;
-
use crate::{Error, Result};
use crate::crypto::SessionKey;
use crate::crypto::mem::Protected;
@@ -40,7 +38,7 @@ pub fn encrypt<R>(recipient: &Key<key::PublicParts, R>,
let recipient_key = PublicKey::from(R);
// Generate a keypair and perform Diffie-Hellman.
- let secret = EphemeralSecret::new(OsRng);
+ let secret = EphemeralSecret::random_from_rng(OsRng);
let public = PublicKey::from(&secret);
let shared = secret.diffie_hellman(&recipient_key);