diff options
author | Jake McGinty <me@jake.su> | 2018-02-12 19:53:15 +0000 |
---|---|---|
committer | Jake McGinty <me@jake.su> | 2018-02-12 19:53:15 +0000 |
commit | d4f3e47327c358e320f8929ac9aacfb54421a4c0 (patch) | |
tree | 855a3907465e1570649a539f6dfe960175e883d6 | |
parent | wait for first packet before next -> current transition (diff) | |
download | wireguard-rs-d4f3e47327c358e320f8929ac9aacfb54421a4c0.tar.xz wireguard-rs-d4f3e47327c358e320f8929ac9aacfb54421a4c0.zip |
consolidate more handshake crypto
-rw-r--r-- | src/interface/mod.rs | 9 | ||||
-rw-r--r-- | src/interface/peer_server.rs | 12 | ||||
-rw-r--r-- | src/noise.rs | 11 | ||||
-rw-r--r-- | src/protocol/peer.rs | 52 |
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) } |