aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJake McGinty <me@jake.su>2018-02-12 19:53:15 +0000
committerJake McGinty <me@jake.su>2018-02-12 19:53:15 +0000
commitd4f3e47327c358e320f8929ac9aacfb54421a4c0 (patch)
tree855a3907465e1570649a539f6dfe960175e883d6
parentwait for first packet before next -> current transition (diff)
downloadwireguard-rs-d4f3e47327c358e320f8929ac9aacfb54421a4c0.tar.xz
wireguard-rs-d4f3e47327c358e320f8929ac9aacfb54421a4c0.zip
consolidate more handshake crypto
-rw-r--r--src/interface/mod.rs9
-rw-r--r--src/interface/peer_server.rs12
-rw-r--r--src/noise.rs11
-rw-r--r--src/protocol/peer.rs52
4 files changed, 39 insertions, 45 deletions
diff --git a/src/interface/mod.rs b/src/interface/mod.rs
index edbe4b0..41b4a66 100644
--- a/src/interface/mod.rs
+++ b/src/interface/mod.rs
@@ -199,16 +199,11 @@ impl Interface {
},
UpdateEvent::UpdatePeer(info) => {
info!("added new peer: {}", info);
- let noise = Noise::build_initiator(
- &state.interface_info.private_key.expect("no private key!"),
- &info.pub_key,
- &info.psk).unwrap();
let mut peer = Peer::new(info.clone());
- peer.set_next_session(noise.into());
+ let private_key = &state.interface_info.private_key.expect("no private key!");
+ let (init_packet, our_index) = peer.initiate_new_session(private_key).unwrap();
- let init_packet = peer.get_handshake_packet().unwrap();
- let our_index = peer.our_next_index().unwrap();
let peer = Rc::new(RefCell::new(peer));
state.router.add_allowed_ips(&info.allowed_ips, peer.clone());
diff --git a/src/interface/peer_server.rs b/src/interface/peer_server.rs
index e48db10..2470335 100644
--- a/src/interface/peer_server.rs
+++ b/src/interface/peer_server.rs
@@ -226,16 +226,12 @@ impl PeerServer {
match message {
TimerMessage::Rekey(peer_ref, _our_index) => {
let mut peer = peer_ref.borrow_mut();
- let noise = Noise::build_initiator(
- &state.interface_info.private_key.expect("no private key!"),
- &peer.info.pub_key,
- &peer.info.psk)?;
- peer.set_next_session(noise.into());
- let _ = state.index_map.insert(peer.our_next_index().unwrap(), peer_ref.clone());
+ let private_key = &state.interface_info.private_key.expect("no private key!");
+ let (init_packet, our_index) = peer.initiate_new_session(private_key).unwrap();
+ let _ = state.index_map.insert(our_index, peer_ref.clone());
- let init_packet = peer.get_handshake_packet().unwrap();
- let endpoint = peer.info.endpoint.unwrap().clone();
+ let endpoint = peer.info.endpoint.ok_or_else(|| format_err!("no endpoint for peer"))?;
self.send_to_peer((endpoint, init_packet));
info!("sent rekey");
diff --git a/src/noise.rs b/src/noise.rs
index 501226f..beddbfa 100644
--- a/src/noise.rs
+++ b/src/noise.rs
@@ -1,3 +1,4 @@
+use blake2_rfc::blake2s::{Blake2s, blake2s};
use failure::{Error, SyncFailure};
use snow::{NoiseBuilder, Session};
use snow::params::NoiseParams;
@@ -31,4 +32,14 @@ impl Noise {
.map_err(SyncFailure::new)?)
}
+
+ pub fn build_mac1(pub_key: &[u8], mac_input: &mut [u8], mac_output: &mut [u8]) {
+ debug_assert!(mac_output.len() == 16);
+ let mut mac_key_input = [0; 40];
+ mac_key_input[..8].copy_from_slice(b"mac1----");
+ mac_key_input[8..40].copy_from_slice(pub_key);
+ let mac_key = blake2s(32, &[], &mac_key_input);
+ let mac = blake2s(16, mac_key.as_bytes(), mac_input);
+ mac_output.copy_from_slice(mac.as_bytes());
+ }
}
diff --git a/src/protocol/peer.rs b/src/protocol/peer.rs
index 3e1bac5..2afb4c4 100644
--- a/src/protocol/peer.rs
+++ b/src/protocol/peer.rs
@@ -1,8 +1,8 @@
use anti_replay::AntiReplay;
use byteorder::{ByteOrder, BigEndian, LittleEndian};
-use blake2_rfc::blake2s::{Blake2s, blake2s};
use consts::{TRANSPORT_OVERHEAD, TRANSPORT_HEADER_SIZE, MAX_SEGMENT_SIZE};
use failure::{Error, SyncFailure};
+use noise::Noise;
use pnet::packet::Packet;
use pnet::packet::ip::IpNextHeaderProtocols;
use pnet::packet::ipv4::{self, MutableIpv4Packet};
@@ -108,10 +108,6 @@ impl Debug for Peer {
}
}
-fn memcpy(out: &mut [u8], data: &[u8]) {
- out[..data.len()].copy_from_slice(data);
-}
-
impl Peer {
pub fn new(info: PeerInfo) -> Peer {
let mut peer = Peer::default();
@@ -138,14 +134,6 @@ impl Peer {
}
}
- pub fn our_next_index(&self) -> Option<u32> {
- if let Some(ref session) = self.sessions.next {
- Some(session.our_index)
- } else {
- None
- }
- }
-
pub fn our_current_index(&self) -> Option<u32> {
if let Some(ref session) = self.sessions.current {
Some(session.our_index)
@@ -162,23 +150,28 @@ impl Peer {
}
}
- pub fn get_handshake_packet(&mut self) -> Result<Vec<u8>, Error> {
+ pub fn initiate_new_session(&mut self, private_key: &[u8]) -> Result<(Vec<u8>, u32), Error> {
+ let noise = Noise::build_initiator(
+ &private_key,
+ &self.info.pub_key,
+ &self.info.psk)?;
+ let mut session: Session = noise.into();
+
let tai64n = TAI64N::now();
let mut initiation_packet = vec![0; 148];
initiation_packet[0] = 1; /* Type: Initiation */
- let next = self.sessions.next.as_mut().ok_or_else(|| format_err!("missing next session"))?;
- LittleEndian::write_u32(&mut initiation_packet[4..], next.our_index);
- next.noise.write_message(&*tai64n, &mut initiation_packet[8..]).map_err(SyncFailure::new)?;
+ LittleEndian::write_u32(&mut initiation_packet[4..], session.our_index);
+ session.noise.write_message(&*tai64n, &mut initiation_packet[8..]).map_err(SyncFailure::new)?;
+ {
+ let (mac_in, mac_out) = initiation_packet.split_at_mut(116);
+ Noise::build_mac1(&self.info.pub_key, mac_in, &mut mac_out[..16]);
+ }
- let mut mac_key_input = [0; 40];
- memcpy(&mut mac_key_input, b"mac1----");
- memcpy(&mut mac_key_input[8..], &self.info.pub_key);
- let mac_key = blake2s(32, &[], &mac_key_input);
- let mac = blake2s(16, mac_key.as_bytes(), &initiation_packet[0..116]);
- memcpy(&mut initiation_packet[116..], mac.as_bytes());
+ let our_index = session.our_index;
+ let _ = mem::replace(&mut self.sessions.next, Some(session));
- Ok(initiation_packet)
+ Ok((initiation_packet, our_index))
}
/// Takes a new handshake packet (type 0x01), updates the internal peer state,
@@ -217,12 +210,11 @@ impl Peer {
LittleEndian::write_u32(&mut packet[4..], next_session.our_index);
LittleEndian::write_u32(&mut packet[8..], next_session.their_index);
next_session.noise.write_message(&[], &mut packet[12..]).map_err(SyncFailure::new)?;
- let mut mac_key_input = [0; 40];
- memcpy(&mut mac_key_input, b"mac1----");
- memcpy(&mut mac_key_input[8..], &self.info.pub_key);
- let mac_key = blake2s(32, &[], &mac_key_input);
- let mac = blake2s(16, mac_key.as_bytes(), &packet[0..44]);
- memcpy(&mut packet[44..], mac.as_bytes());
+
+ {
+ let (mac_in, mac_out) = packet.split_at_mut(44);
+ Noise::build_mac1(&self.info.pub_key, mac_in, &mut mac_out[..16]);
+ }
Ok(packet)
}