Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 124 additions & 24 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ der = { version = "0.8", default-features = false }
digest = { version = "0.11", default-features = false }
ecdsa = { version = "0.17", default-features = false, features = ["alloc"] }
ed25519-dalek = { version = "3", default-features = false, features = ["pkcs8"] }
ed448-goldilocks = { version = "0.14.0-pre.15", default-features = false, features = ["pkcs8", "signing"] }
getrandom = { version = "0.4", default-features = false, features = ["sys_rng"] }
hmac = { version = "0.13", default-features = false }
p256 = { version = "0.14", default-features = false, features = ["pem", "ecdsa", "ecdh"] }
Expand All @@ -39,6 +40,7 @@ sec1 = { version = "0.8", default-features = false }
sha2 = { version = "0.11", default-features = false }
signature = { version = "3", default-features = false }
x25519-dalek = { version = "3", default-features = false }
x448 = { version = "0.14.0-pre.12", default-features = false }

[features]
default = ["std", "tls12", "zeroize"]
Expand All @@ -51,5 +53,5 @@ tls12 = ["rustls/tls12"]
# TODO: go through all of these that what gets exposed re: std error type
std = ["alloc", "pki-types/std", "rustls/std"]
# TODO: go through all of these to ensure to_vec etc. impls are exposed
alloc = ["pki-types/alloc", "aead/alloc", "ed25519-dalek/alloc"]
alloc = ["pki-types/alloc", "aead/alloc", "ed25519-dalek/alloc", "ed448-goldilocks/alloc"]
zeroize = ["ed25519-dalek/zeroize", "x25519-dalek/zeroize"]
45 changes: 44 additions & 1 deletion src/kx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,49 @@ impl crypto::ActiveKeyExchange for X25519KeyExchange {
}
}

#[derive(Debug)]
pub struct X448;

impl crypto::SupportedKxGroup for X448 {
fn name(&self) -> rustls::NamedGroup {
rustls::NamedGroup::X448
}

fn start(&self) -> Result<Box<dyn crypto::ActiveKeyExchange>, rustls::Error> {
let mut rng = UnwrapErr(getrandom::SysRng);
let priv_key = x448::EphemeralSecret::try_generate_from_rng(&mut rng)
.map_err(|_| rustls::Error::from(rustls::PeerMisbehaved::InvalidKeyShare))?;
let pub_key = x448::PublicKey::from(&priv_key);
Ok(Box::new(X448KeyExchange { priv_key, pub_key }))
}
}

pub struct X448KeyExchange {
priv_key: x448::EphemeralSecret,
pub_key: x448::PublicKey,
}

impl crypto::ActiveKeyExchange for X448KeyExchange {
fn complete(self: Box<X448KeyExchange>, peer: &[u8]) -> Result<SharedSecret, rustls::Error> {
let peer_pub = x448::PublicKey::from_bytes(peer)
.ok_or_else(|| rustls::Error::from(rustls::PeerMisbehaved::InvalidKeyShare))?;
Ok(self
.priv_key
.diffie_hellman(&peer_pub)
.as_bytes()
.as_slice()
.into())
}

fn pub_key(&self) -> &[u8] {
self.pub_key.as_bytes()
}

fn group(&self) -> rustls::NamedGroup {
X448.name()
}
}

macro_rules! impl_kx {
($name:ident, $kx_name:ty, $secret:ty, $public_key:ty) => {
paste! {
Expand Down Expand Up @@ -109,4 +152,4 @@ macro_rules! impl_kx {
impl_kx! {SecP256R1, rustls::NamedGroup::secp256r1, p256::ecdh::EphemeralSecret, p256::PublicKey}
impl_kx! {SecP384R1, rustls::NamedGroup::secp384r1, p384::ecdh::EphemeralSecret, p384::PublicKey}

pub const ALL_KX_GROUPS: &[&dyn SupportedKxGroup] = &[&X25519, &SecP256R1, &SecP384R1];
pub const ALL_KX_GROUPS: &[&dyn SupportedKxGroup] = &[&X448, &X25519, &SecP256R1, &SecP384R1];
Loading