aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMathias Hall-Andersen <mathias@hall-andersen.dk>2019-08-27 21:17:55 +0200
committerMathias Hall-Andersen <mathias@hall-andersen.dk>2019-08-27 21:17:55 +0200
commitcdbcd55eda5a153b6fa7b0e871308286eae7cb54 (patch)
tree6988f08200ddd2a14187b90f29ee9e5c889b202b /src
parentRemoved unused sub-module (diff)
downloadwireguard-rs-cdbcd55eda5a153b6fa7b0e871308286eae7cb54.tar.xz
wireguard-rs-cdbcd55eda5a153b6fa7b0e871308286eae7cb54.zip
Added sealing/opening to the router worker
Diffstat (limited to 'src')
-rw-r--r--src/handshake/macs.rs2
-rw-r--r--src/router/messages.rs11
-rw-r--r--src/router/mod.rs7
-rw-r--r--src/router/workers.rs70
4 files changed, 68 insertions, 22 deletions
diff --git a/src/handshake/macs.rs b/src/handshake/macs.rs
index 721fc88..5773f3d 100644
--- a/src/handshake/macs.rs
+++ b/src/handshake/macs.rs
@@ -194,7 +194,7 @@ struct Secret {
}
pub struct Validator {
- mac1_key: [u8; 32], // mac1 key, derieved from device public key
+ mac1_key: [u8; 32], // mac1 key, derived from device public key
cookie_key: [u8; 32], // xchacha20poly key for sealing cookie response
secret: RwLock<Secret>,
}
diff --git a/src/router/messages.rs b/src/router/messages.rs
new file mode 100644
index 0000000..d09bbb3
--- /dev/null
+++ b/src/router/messages.rs
@@ -0,0 +1,11 @@
+use byteorder::LittleEndian;
+use zerocopy::byteorder::{U32, U64};
+use zerocopy::{AsBytes, ByteSlice, FromBytes, LayoutVerified};
+
+#[repr(packed)]
+#[derive(Copy, Clone, FromBytes, AsBytes)]
+pub struct TransportHeader {
+ pub f_type: U32<LittleEndian>,
+ pub f_receiver: U32<LittleEndian>,
+ pub f_counter: U64<LittleEndian>
+} \ No newline at end of file
diff --git a/src/router/mod.rs b/src/router/mod.rs
index 613d88c..70ac868 100644
--- a/src/router/mod.rs
+++ b/src/router/mod.rs
@@ -1,8 +1,9 @@
mod anti_replay;
mod device;
-mod types;
-// mod inbound;
mod peer;
+mod types;
mod workers;
+mod messages;
-pub use device::Device;pub use peer::Peer;
+pub use device::Device;
+pub use peer::Peer;
diff --git a/src/router/workers.rs b/src/router/workers.rs
index 4f39fb2..0888db1 100644
--- a/src/router/workers.rs
+++ b/src/router/workers.rs
@@ -1,24 +1,28 @@
-use super::device::DecryptionState;
-use super::device::DeviceInner;
-use super::peer::PeerInner;
-
-use crossbeam_deque::{Injector, Steal, Stealer, Worker};
-use spin;
use std::iter;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{sync_channel, Receiver, TryRecvError};
use std::sync::{Arc, Weak};
use std::thread;
-use super::types::{Opaque, Callback, KeyCallback};
+use spin;
+
+use crossbeam_deque::{Injector, Steal, Stealer, Worker};
+use ring::aead::{Aad, LessSafeKey, Nonce, UnboundKey, CHACHA20_POLY1305};
+use zerocopy::{AsBytes, ByteSlice, ByteSliceMut, FromBytes, LayoutVerified, Unaligned};
-#[derive(PartialEq)]
+use super::device::DecryptionState;
+use super::device::DeviceInner;
+use super::messages::TransportHeader;
+use super::peer::PeerInner;
+use super::types::{Callback, KeyCallback, Opaque};
+
+#[derive(PartialEq, Debug)]
enum Operation {
Encryption,
Decryption,
}
-#[derive(PartialEq)]
+#[derive(PartialEq, Debug)]
enum Status {
Fault, // unsealing failed
Done, // job valid and complete
@@ -82,9 +86,9 @@ fn wait_recv<T>(stopped: &AtomicBool, recv: &Receiver<T>) -> Result<T, TryRecvEr
return Err(TryRecvError::Disconnected);
}
-pub fn worker_inbound<T : Opaque, S: Callback<T>, R: Callback<T>, K: KeyCallback<T>>(
- device: Arc<DeviceInner<T, S, R, K>>, // related device
- peer: Arc<PeerInner<T, S, R, K>>, // related peer
+pub fn worker_inbound<T: Opaque, S: Callback<T>, R: Callback<T>, K: KeyCallback<T>>(
+ device: Arc<DeviceInner<T, S, R, K>>, // related device
+ peer: Arc<PeerInner<T, S, R, K>>, // related peer
recv: Receiver<JobInbound<T, S, R, K>>, // in order queue
) {
loop {
@@ -110,10 +114,10 @@ pub fn worker_inbound<T : Opaque, S: Callback<T>, R: Callback<T>, K: KeyCallback
}
}
-pub fn worker_outbound<T : Opaque, S: Callback<T>, R: Callback<T>, K: KeyCallback<T>>(
+pub fn worker_outbound<T: Opaque, S: Callback<T>, R: Callback<T>, K: KeyCallback<T>>(
device: Arc<DeviceInner<T, S, R, K>>, // related device
- peer: Arc<PeerInner<T, S, R, K>>, // related peer
- recv: Receiver<JobOutbound>, // in order queue
+ peer: Arc<PeerInner<T, S, R, K>>, // related peer
+ recv: Receiver<JobOutbound>, // in order queue
) {
loop {
match wait_recv(&peer.stopped, &recv) {
@@ -153,14 +157,44 @@ pub fn worker_parallel(
// take ownership of the job buffer and complete it
{
let mut buf = buf.lock();
+
+ // cast and check size of packet
+ let (header, packet) = match LayoutVerified::new_from_prefix(&buf.msg[..]) {
+ Some(v) => v,
+ None => continue,
+ };
+
+ if packet.len() < CHACHA20_POLY1305.nonce_len() {
+ continue;
+ }
+
+ let header: LayoutVerified<&[u8], TransportHeader> = header;
+
+ // do the weird ring AEAD dance
+ let key = LessSafeKey::new(
+ UnboundKey::new(&CHACHA20_POLY1305, &buf.key[..]).unwrap(),
+ );
+
+ // create a nonce object
+ let mut nonce = [0u8; 12];
+ debug_assert_eq!(nonce.len(), CHACHA20_POLY1305.nonce_len()); // why the fuck this is not a constant, god knows...
+ nonce[4..].copy_from_slice(header.f_counter.as_bytes());
+ let nonce = Nonce::assume_unique_for_key(nonce);
+
match buf.op {
Operation::Encryption => {
- // TODO: encryption
+ // note: extends the vector to accommodate the tag
+ key.seal_in_place_append_tag(nonce, Aad::empty(), &mut buf.msg)
+ .unwrap();
buf.status = Status::Done;
}
Operation::Decryption => {
- // TODO: decryption
- buf.status = Status::Done;
+ // opening failure is signaled by fault state
+ buf.status = match key.open_in_place(nonce, Aad::empty(), &mut buf.msg)
+ {
+ Ok(_) => Status::Done,
+ Err(_) => Status::Fault,
+ };
}
}
}