From cdbcd55eda5a153b6fa7b0e871308286eae7cb54 Mon Sep 17 00:00:00 2001 From: Mathias Hall-Andersen Date: Tue, 27 Aug 2019 21:17:55 +0200 Subject: Added sealing/opening to the router worker --- src/handshake/macs.rs | 2 +- src/router/messages.rs | 11 ++++++++ src/router/mod.rs | 7 ++--- src/router/workers.rs | 70 +++++++++++++++++++++++++++++++++++++------------- 4 files changed, 68 insertions(+), 22 deletions(-) create mode 100644 src/router/messages.rs (limited to 'src') 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, } 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, + pub f_receiver: U32, + pub f_counter: U64 +} \ 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(stopped: &AtomicBool, recv: &Receiver) -> Result, R: Callback, K: KeyCallback>( - device: Arc>, // related device - peer: Arc>, // related peer +pub fn worker_inbound, R: Callback, K: KeyCallback>( + device: Arc>, // related device + peer: Arc>, // related peer recv: Receiver>, // in order queue ) { loop { @@ -110,10 +114,10 @@ pub fn worker_inbound, R: Callback, K: KeyCallback } } -pub fn worker_outbound, R: Callback, K: KeyCallback>( +pub fn worker_outbound, R: Callback, K: KeyCallback>( device: Arc>, // related device - peer: Arc>, // related peer - recv: Receiver, // in order queue + peer: Arc>, // related peer + recv: Receiver, // 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, + }; } } } -- cgit v1.2.3-59-g8ed1b