diff options
| author | Linus Färnstrand <faern@faern.net> | 2022-09-29 11:51:22 +0200 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2022-10-03 09:00:51 +0200 |
| commit | f33f7f437516c0b68e45ed52f993d9de36f7ad48 (patch) | |
| tree | 8e4f6d6883851311e3a8ea0bfaee4a71c9f25ac8 | |
| parent | fb3272bd82f281711db397539afb3da8f2636ee5 (diff) | |
| download | mullvadvpn-f33f7f437516c0b68e45ed52f993d9de36f7ad48.tar.xz mullvadvpn-f33f7f437516c0b68e45ed52f993d9de36f7ad48.zip | |
Implement zeroize for the WireGuard PresharedKey type
| -rw-r--r-- | Cargo.lock | 1 | ||||
| -rw-r--r-- | talpid-tunnel-config-client/src/lib.rs | 4 | ||||
| -rw-r--r-- | talpid-types/Cargo.toml | 1 | ||||
| -rw-r--r-- | talpid-types/src/net/wireguard.rs | 37 |
4 files changed, 18 insertions, 25 deletions
diff --git a/Cargo.lock b/Cargo.lock index 572e38f197..17e28e5b65 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3232,6 +3232,7 @@ dependencies = [ "rand 0.8.5", "serde", "x25519-dalek", + "zeroize", ] [[package]] diff --git a/talpid-tunnel-config-client/src/lib.rs b/talpid-tunnel-config-client/src/lib.rs index e3080741f9..de7db33c26 100644 --- a/talpid-tunnel-config-client/src/lib.rs +++ b/talpid-tunnel-config-client/src/lib.rs @@ -84,7 +84,9 @@ pub async fn push_pq_key( } })?; - let mut psk_data = [0u8; 32]; + // Store the PSK data on the heap. So it can be passed around and then zeroized on drop without + // being stored in a bunch of places on the stack. + let mut psk_data = Box::new([0u8; 32]); // Decapsulate Classic McEliece and mix into PSK { let ciphertext_array = diff --git a/talpid-types/Cargo.toml b/talpid-types/Cargo.toml index ff007b74ab..4db8315c99 100644 --- a/talpid-types/Cargo.toml +++ b/talpid-types/Cargo.toml @@ -14,6 +14,7 @@ base64 = "0.13" x25519-dalek = { version = "2.0.0-pre.1" } rand = "0.8.5" err-derive = "0.3.1" +zeroize = "1.5.7" [target.'cfg(target_os = "android")'.dependencies] jnix = { version = "0.5", features = ["derive"] } diff --git a/talpid-types/src/net/wireguard.rs b/talpid-types/src/net/wireguard.rs index 8306c773a1..b5c3268af5 100644 --- a/talpid-types/src/net/wireguard.rs +++ b/talpid-types/src/net/wireguard.rs @@ -9,6 +9,7 @@ use std::{ hash::{Hash, Hasher}, net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}, }; +use zeroize::{Zeroize, ZeroizeOnDrop}; /// Tunnel parameters required to start a `WireguardMonitor`. /// See [`crate::net::TunnelParameters`]. @@ -55,7 +56,10 @@ pub struct PeerConfig { pub allowed_ips: Vec<IpNetwork>, /// IP address of the WireGuard server. pub endpoint: SocketAddr, - /// Preshared key. + /// Preshared key (PSK). The PSK should never be persisted, so it does not serialize + /// or deserialize. A PSK is only used with quantum-resistant tunnels and are then + /// ephemeral and living in memory only. + #[serde(skip)] pub psk: Option<PresharedKey>, } @@ -260,40 +264,25 @@ impl fmt::Display for PublicKey { } } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct PresharedKey([u8; 32]); +/// A WireGuard preshared key (PSK). Used to make the tunnel quantum-resistant. +#[derive(Debug, Clone, PartialEq, Eq, Hash, Zeroize, ZeroizeOnDrop)] +pub struct PresharedKey(Box<[u8; 32]>); impl PresharedKey { - /// Get the PSK as bytes + /// Get the PSK as bytes. Try to move or dereference this data as little as possible, + /// since copying it to more memory locations potentially leaves the secret in more memory + /// locations. pub fn as_bytes(&self) -> &[u8; 32] { &self.0 } } -impl From<[u8; 32]> for PresharedKey { - fn from(key: [u8; 32]) -> PresharedKey { +impl From<Box<[u8; 32]>> for PresharedKey { + fn from(key: Box<[u8; 32]>) -> PresharedKey { PresharedKey(key) } } -impl Serialize for PresharedKey { - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> - where - S: Serializer, - { - serialize_key(&self.0, serializer) - } -} - -impl<'de> Deserialize<'de> for PresharedKey { - fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> - where - D: Deserializer<'de>, - { - deserialize_key(deserializer) - } -} - fn serialize_key<S>(key: &[u8; 32], serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, |
