summaryrefslogtreecommitdiffstats
path: root/openpgp/src/crypto/backend
diff options
context:
space:
mode:
Diffstat (limited to 'openpgp/src/crypto/backend')
-rw-r--r--openpgp/src/crypto/backend/cng.rs2
-rw-r--r--openpgp/src/crypto/backend/cng/ecdh.rs7
-rw-r--r--openpgp/src/crypto/backend/nettle.rs4
-rw-r--r--openpgp/src/crypto/backend/nettle/asymmetric.rs75
-rw-r--r--openpgp/src/crypto/backend/nettle/ecdh.rs48
-rw-r--r--openpgp/src/crypto/backend/rust.rs2
-rw-r--r--openpgp/src/crypto/backend/rust/ecdh.rs4
7 files changed, 136 insertions, 6 deletions
diff --git a/openpgp/src/crypto/backend/cng.rs b/openpgp/src/crypto/backend/cng.rs
index b2e830d8..767259e5 100644
--- a/openpgp/src/crypto/backend/cng.rs
+++ b/openpgp/src/crypto/backend/cng.rs
@@ -42,6 +42,8 @@ impl Curve {
match &self {
NistP256 | NistP384 | NistP521 | Ed25519 | Cv25519
=> true,
+ Ed448 | Cv448
+ => false,
BrainpoolP256 | BrainpoolP512 | Unknown(_)
=> false,
}
diff --git a/openpgp/src/crypto/backend/cng/ecdh.rs b/openpgp/src/crypto/backend/cng/ecdh.rs
index ab687e24..95bbcb44 100644
--- a/openpgp/src/crypto/backend/cng/ecdh.rs
+++ b/openpgp/src/crypto/backend/cng/ecdh.rs
@@ -60,6 +60,8 @@ where
encrypt_wrap(recipient, session_key, VB, &S)
}
+ Curve::Cv448 =>
+ return Err(Error::UnsupportedEllipticCurve(curve.clone()).into()),
Curve::NistP256 | Curve::NistP384 | Curve::NistP521 => {
let (Rx, Ry) = q.decode_point(curve)?;
@@ -142,7 +144,7 @@ where
Err(Error::UnsupportedEllipticCurve(curve.clone()).into()),
// N/A
- Curve::Unknown(_) | Curve::Ed25519 =>
+ Curve::Unknown(_) | Curve::Ed25519 | Curve::Ed448 =>
Err(Error::UnsupportedEllipticCurve(curve.clone()).into()),
}
}
@@ -204,6 +206,9 @@ where
secret.into()
}
+ Curve::Cv448 =>
+ return Err(Error::UnsupportedEllipticCurve(curve.clone()).into()),
+
Curve::NistP256 | Curve::NistP384 | Curve::NistP521 => {
// Get the public part V of the ephemeral key and
// compute the shared point S = rV = rvG, where (r, R)
diff --git a/openpgp/src/crypto/backend/nettle.rs b/openpgp/src/crypto/backend/nettle.rs
index ef68cc35..c64bb41a 100644
--- a/openpgp/src/crypto/backend/nettle.rs
+++ b/openpgp/src/crypto/backend/nettle.rs
@@ -70,6 +70,10 @@ impl Curve {
match &self {
NistP256 | NistP384 | NistP521 | Ed25519 | Cv25519
=> true,
+ Ed448
+ => nettle::ed448::IS_SUPPORTED,
+ Cv448
+ => nettle::curve448::IS_SUPPORTED,
BrainpoolP256 | BrainpoolP512 | Unknown(_)
=> false,
}
diff --git a/openpgp/src/crypto/backend/nettle/asymmetric.rs b/openpgp/src/crypto/backend/nettle/asymmetric.rs
index 9efad861..fc362401 100644
--- a/openpgp/src/crypto/backend/nettle/asymmetric.rs
+++ b/openpgp/src/crypto/backend/nettle/asymmetric.rs
@@ -4,13 +4,24 @@
//! [`Decryptor`]: super::super::asymmetric::Decryptor
//! [`KeyPair`]: super::super::asymmetric::KeyPair
-use nettle::{curve25519, ecc, ecdh, ecdsa, ed25519, dsa, rsa, random::Yarrow};
+use nettle::{
+ curve25519,
+ curve448,
+ dsa,
+ ecc,
+ ecdh,
+ ecdsa,
+ ed25519,
+ ed448,
+ random::Yarrow,
+ rsa,
+};
use crate::{Error, Result};
use crate::packet::{key, Key};
use crate::crypto::asymmetric::{KeyPair, Decryptor, Signer};
-use crate::crypto::mpi::{self, MPI, PublicKey};
+use crate::crypto::mpi::{self, MPI, ProtectedMPI, PublicKey};
use crate::crypto::SessionKey;
use crate::types::{Curve, HashAlgorithm};
@@ -94,6 +105,17 @@ impl Signer for KeyPair {
s: MPI::new(&sig[ed25519::ED25519_KEY_SIZE..]),
})
},
+
+ Curve::Ed448 => {
+ let public = q.decode_octet_string(curve.field_size()?)?;
+ let secret = scalar.decode_octet_string(curve.field_size()?)?;
+ let mut sig = vec![0; ed448::ED448_SIGNATURE_SIZE];
+ ed448::sign(public, secret, digest, &mut sig)?;
+ Ok(mpi::Signature::EdDSA {
+ r: MPI::new_octet_string(sig),
+ s: MPI::zero(),
+ })
+ },
_ => Err(
Error::UnsupportedEllipticCurve(curve.clone()).into()),
},
@@ -286,6 +308,19 @@ impl<P: key::KeyParts, R: key::KeyRole> Key<P, R> {
ed25519::verify(&q.value()[1..], digest, &signature)?
},
+ Curve::Ed448 => {
+ let public = q.decode_octet_string(curve.field_size()?)?;
+ let signature =
+ r.decode_octet_string(curve.field_size()? * 2)?;
+ assert_eq!(signature.len(), ed448::ED448_SIGNATURE_SIZE);
+ if ! s.is_zero() {
+ return Err(Error::BadSignature(
+ "Ed448 signature's S parameter is not zero".into())
+ .into());
+ }
+
+ ed448::verify(public, digest, signature)?
+ },
_ => return
Err(Error::UnsupportedEllipticCurve(curve.clone()).into()),
},
@@ -492,6 +527,42 @@ impl<R> Key4<SecretParts, R>
(public_mpis, sec, ECDH)
}
+ (Curve::Ed448, true) => {
+ let private: Protected =
+ ed448::private_key(&mut rng).into();
+ let mut public = [0; ed448::ED448_KEY_SIZE];
+ ed448::public_key(&mut public, &private)?;
+
+ let public = PublicKey::EdDSA {
+ curve: Curve::Ed448,
+ q: MPI::new_octet_string(public),
+ };
+ let private = mpi::SecretKeyMaterial::EdDSA {
+ scalar: ProtectedMPI::new_octet_string(private),
+ };
+
+ (public, private.into(), EdDSA)
+ },
+
+ (Curve::Cv448, false) => {
+ let private: Protected =
+ curve448::private_key(&mut rng).into();
+ let mut public = [0; curve448::CURVE448_SIZE];
+ curve448::mul_g(&mut public, &private)?;
+
+ let public = PublicKey::ECDH {
+ curve: Curve::Cv448,
+ q: MPI::new_octet_string(public),
+ hash: HashAlgorithm::SHA512,
+ sym: SymmetricAlgorithm::AES256,
+ };
+ let private = mpi::SecretKeyMaterial::ECDH {
+ scalar: ProtectedMPI::new_octet_string(private),
+ };
+
+ (public, private.into(), ECDH)
+ },
+
(Curve::NistP256, true) | (Curve::NistP384, true)
| (Curve::NistP521, true) => {
let (public, private, field_sz) = match curve {
diff --git a/openpgp/src/crypto/backend/nettle/ecdh.rs b/openpgp/src/crypto/backend/nettle/ecdh.rs
index eea5661d..7aec6d73 100644
--- a/openpgp/src/crypto/backend/nettle/ecdh.rs
+++ b/openpgp/src/crypto/backend/nettle/ecdh.rs
@@ -1,6 +1,12 @@
//! Elliptic Curve Diffie-Hellman.
-use nettle::{curve25519, ecc, ecdh, random::Yarrow};
+use nettle::{
+ curve25519,
+ curve448,
+ ecc,
+ ecdh,
+ random::Yarrow,
+};
use crate::{Error, Result};
use crate::crypto::SessionKey;
@@ -45,6 +51,28 @@ pub fn encrypt<R>(recipient: &Key<key::PublicParts, R>,
encrypt_wrap(recipient, session_key, VB, &S)
}
+ Curve::Cv448 => {
+ // Obtain the authenticated recipient public key R
+ let R = q.decode_octet_string(curve.field_size()?)?;
+
+ // Generate an ephemeral key pair {v, V=vG}
+ let v: Protected =
+ curve448::private_key(&mut rng).into();
+
+ // Compute the public key.
+ let mut VB = [0; curve448::CURVE448_SIZE];
+ curve448::mul_g(&mut VB, &v)
+ .expect("buffers are of the wrong size");
+ let VB = MPI::new_octet_string(&VB);
+
+ // Compute the shared point S = vR;
+ let mut S: Protected =
+ vec![0; curve448::CURVE448_SIZE].into();
+ curve448::mul(&mut S, &v, R)
+ .expect("buffers are of the wrong size");
+
+ encrypt_wrap(recipient, session_key, VB, &S)
+ },
Curve::NistP256 | Curve::NistP384 | Curve::NistP521 => {
// Obtain the authenticated recipient public key R and
// generate an ephemeral private key v.
@@ -107,7 +135,7 @@ pub fn encrypt<R>(recipient: &Key<key::PublicParts, R>,
Err(Error::UnsupportedEllipticCurve(curve.clone()).into()),
// N/A
- Curve::Unknown(_) | Curve::Ed25519 =>
+ Curve::Unknown(_) | Curve::Ed25519 | Curve::Ed448 =>
Err(Error::UnsupportedEllipticCurve(curve.clone()).into()),
}
} else {
@@ -154,6 +182,20 @@ pub fn decrypt<R>(recipient: &Key<key::PublicParts, R>,
S
}
+ Curve::Cv448 => {
+ // Get the public part V of the ephemeral key.
+ let V = e.decode_octet_string(curve.field_size()?)?;
+ let r = scalar.decode_octet_string(curve.field_size()?)?;
+
+ // Compute the shared point S = rV = rvG, where (r, R)
+ // is the recipient's key pair.
+ let mut S: Protected =
+ vec![0; curve448::CURVE448_SIZE].into();
+ curve448::mul(&mut S, r, V)
+ .expect("buffers are of the wrong size");
+ S
+ },
+
Curve::NistP256 | Curve::NistP384 | Curve::NistP521 => {
// Get the public part V of the ephemeral key and
// compute the shared point S = rV = rvG, where (r, R)
@@ -208,7 +250,7 @@ pub fn decrypt<R>(recipient: &Key<key::PublicParts, R>,
Err(Error::UnsupportedEllipticCurve(curve.clone()).into()),
// N/A
- Curve::Unknown(_) | Curve::Ed25519 =>
+ Curve::Unknown(_) | Curve::Ed25519 | Curve::Ed448 =>
return
Err(Error::UnsupportedEllipticCurve(curve.clone()).into()),
};
diff --git a/openpgp/src/crypto/backend/rust.rs b/openpgp/src/crypto/backend/rust.rs
index 26284d33..75274934 100644
--- a/openpgp/src/crypto/backend/rust.rs
+++ b/openpgp/src/crypto/backend/rust.rs
@@ -48,6 +48,8 @@ impl Curve {
=> false,
Ed25519 | Cv25519
=> true,
+ Ed448 | Cv448
+ => false,
BrainpoolP256 | BrainpoolP512 | Unknown(_)
=> false,
}
diff --git a/openpgp/src/crypto/backend/rust/ecdh.rs b/openpgp/src/crypto/backend/rust/ecdh.rs
index 8531013d..b05ee7ba 100644
--- a/openpgp/src/crypto/backend/rust/ecdh.rs
+++ b/openpgp/src/crypto/backend/rust/ecdh.rs
@@ -52,6 +52,8 @@ pub fn encrypt<R>(recipient: &Key<key::PublicParts, R>,
(VB, shared)
},
+ Curve::Cv448 =>
+ return Err(Error::UnsupportedEllipticCurve(curve.clone()).into()),
Curve::NistP256 => {
use p256::{EncodedPoint, PublicKey, ecdh::EphemeralSecret};
@@ -111,6 +113,8 @@ pub fn decrypt<R>(recipient: &Key<key::PublicParts, R>,
let secret = r.diffie_hellman(&V);
Vec::from(secret.to_bytes()).into()
},
+ Curve::Cv448 =>
+ return Err(Error::UnsupportedEllipticCurve(curve.clone()).into()),
Curve::NistP256 => {
use p256::{
SecretKey,