diff options
author | Wiktor Kwapisiewicz <wiktor@metacode.biz> | 2021-05-10 11:26:22 +0200 |
---|---|---|
committer | Wiktor Kwapisiewicz <wiktor@metacode.biz> | 2021-05-14 13:41:04 +0200 |
commit | a1460fa0d43462ec7648029a9c1ce13a429529e2 (patch) | |
tree | f2df38a14fb1fc7b4525c612bb44f24295ff944b | |
parent | c087de178d7fae8753c229ba2a07ff8932c54a76 (diff) |
cng: Replace cng with x25519-dalek for ECDH decryption.wiktor-k/fix-windows-25519-decryption
- Apparently CNG decryption using ECDH doesn't work on Windows.
- Replace it with x25519-dalek code.
- Remove unused code.
Co-authored-by: Nikhil Benesch <nikhil.benesch@gmail.com>
-rw-r--r-- | Cargo.lock | 12 | ||||
-rw-r--r-- | openpgp/Cargo.toml | 3 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/cng/ecdh.rs | 38 |
3 files changed, 23 insertions, 30 deletions
@@ -2180,6 +2180,7 @@ dependencies = [ "unicode-normalization", "win-crypto-ng", "winapi 0.3.9", + "x25519-dalek", ] [[package]] @@ -2863,6 +2864,17 @@ dependencies = [ ] [[package]] +name = "x25519-dalek" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" +dependencies = [ + "curve25519-dalek", + "rand_core 0.5.1", + "zeroize", +] + +[[package]] name = "zbase32" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/openpgp/Cargo.toml b/openpgp/Cargo.toml index a520645b..942186d4 100644 --- a/openpgp/Cargo.toml +++ b/openpgp/Cargo.toml @@ -49,6 +49,7 @@ unicode-normalization = "0.1.9" win-crypto-ng = { version = "0.4", features = ["rand", "block-cipher"], optional = true } num-bigint-dig = { version = "0.6", default-features = false, optional = true } ed25519-dalek = { version = "1", default-features = false, features = ["rand", "u64_backend"], optional = true } +x25519-dalek = { version = "1", optional = true } winapi = { version = "0.3.8", default-features = false, features = ["bcrypt"], optional = true } eax = "0.3" @@ -68,7 +69,7 @@ criterion = { version = "0.3.4", features = ["html_reports"] } default = ["compression", "crypto-nettle"] # TODO(#333): Allow for/implement more backends crypto-nettle = ["nettle"] -crypto-cng = ["winapi", "win-crypto-ng", "ed25519-dalek", "num-bigint-dig"] +crypto-cng = ["winapi", "win-crypto-ng", "ed25519-dalek", "x25519-dalek", "num-bigint-dig"] # The compression algorithms. compression = ["compression-deflate", "compression-bzip2"] diff --git a/openpgp/src/crypto/backend/cng/ecdh.rs b/openpgp/src/crypto/backend/cng/ecdh.rs index b8f38577..3bfb9648 100644 --- a/openpgp/src/crypto/backend/cng/ecdh.rs +++ b/openpgp/src/crypto/backend/cng/ecdh.rs @@ -164,30 +164,19 @@ where let S: Protected = match curve { Curve::Cv25519 => { - // Get the public part V of the ephemeral key. - let V = e.decode_point(curve)?.0; + use x25519_dalek::{PublicKey, StaticSecret}; + use std::convert::TryInto; - let provider = AsymmetricAlgorithm::open(AsymmetricAlgorithmId::Ecdh(NamedCurve::Curve25519))?; - let V = AsymmetricKey::<Ecdh<Curve25519>, Public>::import_from_parts( - &provider, - V, - )?; + // Get the public part V of the ephemeral key. + let V: [u8; 32] = e.decode_point(curve)?.0.try_into()?; + let V = PublicKey::from(V); - let mut scalar = pad_secret_to(scalar.value(), 32).into_owned(); - // Reverse the scalar. See - // https://lists.gnupg.org/pipermail/gnupg-devel/2018-February/033437.html. + let mut scalar: [u8; 32] = scalar.value().try_into()?; scalar.reverse(); + let r = StaticSecret::from(scalar); - let r = AsymmetricKey::<Ecdh<Curve25519>, Private>::import_from_parts( - &provider, - &scalar, - )?; - - let secret = cng::asymmetric::agreement::secret_agreement(&r, &V)?; - // Returned secret is little-endian, flip it to big-endian - let mut secret = secret.derive_raw()?; - secret.reverse(); - secret.into() + let secret = r.diffie_hellman(&V); + Vec::from(secret.to_bytes()).into() } Curve::NistP256 | Curve::NistP384 | Curve::NistP521 => { @@ -300,12 +289,3 @@ impl AsRef<[u8]> for PaddedSecret<'_> { } } } - -impl PaddedSecret<'_> { - fn into_owned(self) -> Protected { - match self { - PaddedSecret::Ref(value) => Protected::from(value), - PaddedSecret::Own(value) => value, - } - } -} |