diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2021-06-04 18:52:28 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2021-06-07 12:29:18 +0200 |
commit | b1ddb1f3c03e3340c461f1d90a64616884f11ceb (patch) | |
tree | c2f89589202ea63452807d5d80e6aa8325ce5870 /openpgp/src/crypto/backend/cng/ecdh.rs | |
parent | 9478f48e6b692d06c83126e93b77ce581cf979bf (diff) |
openpgp: Clamp cv25519 secrets for use with CNG.
- Some bits of cv25519 keys must be clamped. However, some
implementations may not do that at key generation time. Nettle
implicitly clamps the secrets, and hence gracefully works with
these keys. CNG, however, does not. Clamp the bits right before
use with CNG.
- Fixes #715.
Diffstat (limited to 'openpgp/src/crypto/backend/cng/ecdh.rs')
-rw-r--r-- | openpgp/src/crypto/backend/cng/ecdh.rs | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/openpgp/src/crypto/backend/cng/ecdh.rs b/openpgp/src/crypto/backend/cng/ecdh.rs index b8f38577..c115ca88 100644 --- a/openpgp/src/crypto/backend/cng/ecdh.rs +++ b/openpgp/src/crypto/backend/cng/ecdh.rs @@ -15,6 +15,8 @@ use cng::asymmetric::{Public, Private, AsymmetricAlgorithm, AsymmetricAlgorithmI use cng::asymmetric::ecc::{NamedCurve, NistP256, NistP384, NistP521, Curve25519}; use cng::key_blob::{EccKeyPublicPayload, EccKeyPrivatePayload}; +const CURVE25519_SIZE: usize = 32; + /// Wraps a session key using Elliptic Curve Diffie-Hellman. #[allow(non_snake_case)] pub fn encrypt<R>( @@ -178,6 +180,18 @@ where // https://lists.gnupg.org/pipermail/gnupg-devel/2018-February/033437.html. scalar.reverse(); + // Some bits must be clamped. Usually, this is done + // during key creation. However, if that is not done, we + // should do that before handing it to CNG. See + // Curve25519 Paper, Sec. 3: + // + // > A user can, for example, generate 32 uniform random + // > bytes, clear bits 0, 1, 2 of the first byte, clear bit + // > 7 of the last byte, and set bit 6 of the last byte. + scalar[0] &= 0b1111_1000; + scalar[CURVE25519_SIZE - 1] &= !0b1000_0000; + scalar[CURVE25519_SIZE - 1] |= 0b0100_0000; + let r = AsymmetricKey::<Ecdh<Curve25519>, Private>::import_from_parts( &provider, &scalar, |