summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/handshake/device.rs41
-rw-r--r--src/handshake/macs.rs13
-rw-r--r--src/handshake/messages.rs48
-rw-r--r--src/handshake/noise.rs42
-rw-r--r--src/handshake/peer.rs5
5 files changed, 84 insertions, 65 deletions
diff --git a/src/handshake/device.rs b/src/handshake/device.rs
index b28613a..f3458ae 100644
--- a/src/handshake/device.rs
+++ b/src/handshake/device.rs
@@ -1,5 +1,6 @@
use spin::RwLock;
use std::collections::HashMap;
+use zerocopy::AsBytes;
use rand::prelude::*;
use rand::rngs::OsRng;
@@ -159,7 +160,16 @@ where
None => Err(HandshakeError::UnknownPublicKey),
Some(peer) => {
let sender = self.allocate(peer);
- noise::create_initiation(self, peer, sender)
+
+ let mut msg = Initiation::default();
+
+ noise::create_initiation(self, peer, sender, &mut msg.noise)?;
+
+ // add macs to initation
+
+ peer.macs.generate(msg.noise.as_bytes(), &mut msg.macs);
+
+ Ok(msg.as_bytes().to_owned())
}
}
}
@@ -174,7 +184,7 @@ where
Some(&TYPE_INITIATION) => {
let msg = Initiation::parse(msg)?;
- // check mac footer and ratelimiter
+ // check mac footer and ratelimiter for initiation
// consume the initiation
let (peer, st) = noise::consume_initiation(self, &msg.noise)?;
@@ -182,12 +192,25 @@ where
// allocate new index for response
let sender = self.allocate(peer);
- // create response (release id on error), TODO: take slice
+ // prepare memory for response, TODO: take slice for zero allocation
let mut resp = Response::default();
- noise::create_response(peer, sender, st, &mut resp.noise).map_err(|e| {
- self.release(sender);
- e
- })
+
+ // create response (release id on error)
+ let keys =
+ noise::create_response(peer, sender, st, &mut resp.noise).map_err(|e| {
+ self.release(sender);
+ e
+ })?;
+
+ // add macs to response
+
+ resp.macs.f_mac1 = [8u8; 16];
+
+ Ok((
+ peer.identifier,
+ Some(resp.as_bytes().to_owned()),
+ Some(keys),
+ ))
}
Some(&TYPE_RESPONSE) => {
let msg = Response::parse(msg)?;
@@ -297,7 +320,7 @@ mod tests {
let msg1 = dev1.begin(&pk2).unwrap();
- println!("msg1 = {}", hex::encode(&msg1[..]));
+ println!("msg1 = {} : {} bytes", hex::encode(&msg1[..]), msg1.len());
println!("msg1 = {:?}", Initiation::parse(&msg1[..]).unwrap());
// process initiation and create response
@@ -307,7 +330,7 @@ mod tests {
let ks_r = ks_r.unwrap();
let msg2 = msg2.unwrap();
- println!("msg2 = {}", hex::encode(&msg2[..]));
+ println!("msg2 = {} : {} bytes", hex::encode(&msg2[..]), msg2.len());
println!("msg2 = {:?}", Response::parse(&msg2[..]).unwrap());
assert!(!ks_r.confirmed, "Responders key-pair is confirmed");
diff --git a/src/handshake/macs.rs b/src/handshake/macs.rs
index 05546a7..9092daa 100644
--- a/src/handshake/macs.rs
+++ b/src/handshake/macs.rs
@@ -38,14 +38,14 @@ macro_rules! MAC {
}};
}
-struct Generator {
+pub struct Generator {
mac1_key: [u8; 32],
cookie_value: [u8; 16],
cookie_birth: Option<Instant>, // when was the cookie set?
}
impl Generator {
- fn new(pk: PublicKey) -> Generator {
+ pub fn new(pk: PublicKey) -> Generator {
Generator {
mac1_key: HASH!(LABEL_MAC1, pk.as_bytes()).into(),
cookie_value: [0u8; SIZE_COOKIE],
@@ -66,14 +66,11 @@ impl Generator {
self.cookie_value = *cookie;
}
- pub fn generate(&self, msg: &[u8]) -> MacsFooter {
- MacsFooter {
- f_mac1: self.mac1(msg),
- f_mac2: self.mac2(msg),
- }
+ pub fn generate(&self, inner: &[u8], macs : &mut MacsFooter) {
+
}
}
-struct Validator {}
+pub struct Validator {}
impl Validator {}
diff --git a/src/handshake/messages.rs b/src/handshake/messages.rs
index a2ff19a..004e059 100644
--- a/src/handshake/messages.rs
+++ b/src/handshake/messages.rs
@@ -11,7 +11,7 @@ use zerocopy::{AsBytes, ByteSlice, FromBytes, LayoutVerified};
use super::timestamp;
use super::types::*;
-const SIZE_MAC: usize = 16;
+const SIZE_MAC: usize = 16;
const SIZE_TAG: usize = 16; // poly1305 tag
const SIZE_NONCE: usize = 16; // xchacha20 nonce
const SIZE_COOKIE: usize = 16; //
@@ -23,21 +23,21 @@ pub const TYPE_COOKIEREPLY: u8 = 3;
/* Handshake messsages */
-#[repr(C)]
+#[repr(packed)]
#[derive(Copy, Clone, FromBytes, AsBytes)]
pub struct Response {
pub noise: NoiseResponse, // inner message covered by macs
pub macs: MacsFooter,
}
-#[repr(C)]
+#[repr(packed)]
#[derive(Copy, Clone, FromBytes, AsBytes)]
pub struct Initiation {
pub noise: NoiseInitiation, // inner message covered by macs
pub macs: MacsFooter,
}
-#[repr(C)]
+#[repr(packed)]
#[derive(Copy, Clone, FromBytes, AsBytes)]
pub struct CookieReply {
f_type: U32<LittleEndian>,
@@ -49,14 +49,14 @@ pub struct CookieReply {
/* Inner sub-messages */
-#[repr(C)]
+#[repr(packed)]
#[derive(Copy, Clone, FromBytes, AsBytes)]
pub struct MacsFooter {
pub f_mac1: [u8; SIZE_MAC],
pub f_mac2: [u8; SIZE_MAC],
}
-#[repr(C)]
+#[repr(packed)]
#[derive(Copy, Clone, FromBytes, AsBytes)]
pub struct NoiseInitiation {
f_type: U32<LittleEndian>,
@@ -65,17 +65,17 @@ pub struct NoiseInitiation {
pub f_static: [u8; SIZE_X25519_POINT],
pub f_static_tag: [u8; SIZE_TAG],
pub f_timestamp: timestamp::TAI64N,
- pub f_timestamp_tag: [u8; SIZE_TAG]
+ pub f_timestamp_tag: [u8; SIZE_TAG],
}
-#[repr(C)]
+#[repr(packed)]
#[derive(Copy, Clone, FromBytes, AsBytes)]
pub struct NoiseResponse {
f_type: U32<LittleEndian>,
pub f_sender: U32<LittleEndian>,
pub f_receiver: U32<LittleEndian>,
pub f_ephemeral: [u8; SIZE_X25519_POINT],
- pub f_empty_tag: [u8; SIZE_TAG]
+ pub f_empty_tag: [u8; SIZE_TAG],
}
/* Zero copy parsing of handshake messages */
@@ -124,8 +124,8 @@ impl CookieReply {
impl Default for Response {
fn default() -> Self {
Self {
- noise: Default::default(),
- macs: Default::default(),
+ noise: Default::default(),
+ macs: Default::default(),
}
}
}
@@ -133,8 +133,8 @@ impl Default for Response {
impl Default for Initiation {
fn default() -> Self {
Self {
- noise: Default::default(),
- macs: Default::default(),
+ noise: Default::default(),
+ macs: Default::default(),
}
}
}
@@ -142,11 +142,11 @@ impl Default for Initiation {
impl Default for CookieReply {
fn default() -> Self {
Self {
- f_type: <U32<LittleEndian>>::new(TYPE_COOKIEREPLY as u32),
- f_receiver: <U32<LittleEndian>>::ZERO,
- f_nonce: [0u8; SIZE_NONCE],
- f_cookie: [0u8; SIZE_COOKIE],
- f_cookie_tag: [0u8; SIZE_TAG],
+ f_type: <U32<LittleEndian>>::new(TYPE_COOKIEREPLY as u32),
+ f_receiver: <U32<LittleEndian>>::ZERO,
+ f_nonce: [0u8; SIZE_NONCE],
+ f_cookie: [0u8; SIZE_COOKIE],
+ f_cookie_tag: [0u8; SIZE_TAG],
}
}
}
@@ -161,7 +161,7 @@ impl Default for MacsFooter {
}
impl Default for NoiseInitiation {
- fn default() -> Self {
+ fn default() -> Self {
Self {
f_type: <U32<LittleEndian>>::new(TYPE_INITIATION as u32),
@@ -170,7 +170,7 @@ impl Default for NoiseInitiation {
f_static: [0u8; SIZE_X25519_POINT],
f_static_tag: [0u8; SIZE_TAG],
f_timestamp: timestamp::ZERO,
- f_timestamp_tag: [0u8; SIZE_TAG]
+ f_timestamp_tag: [0u8; SIZE_TAG],
}
}
}
@@ -206,7 +206,8 @@ impl fmt::Debug for Response {
#[cfg(test)]
impl fmt::Debug for CookieReply {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f,
+ write!(
+ f,
"CookieReply {{ type = {}, receiver = {}, nonce = {}, cookie = {}|{} }}",
self.f_type,
self.f_receiver,
@@ -250,7 +251,8 @@ impl fmt::Debug for NoiseResponse {
#[cfg(test)]
impl fmt::Debug for MacsFooter {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f,
+ write!(
+ f,
"Macs {{ mac1 = {}, mac2 = {} }}",
hex::encode(self.f_mac1),
hex::encode(self.f_mac2)
@@ -268,7 +270,7 @@ macro_rules! eq_as_bytes {
}
}
impl Eq for $type {}
- }
+ };
}
#[cfg(test)]
diff --git a/src/handshake/noise.rs b/src/handshake/noise.rs
index 72e0f47..b0d492c 100644
--- a/src/handshake/noise.rs
+++ b/src/handshake/noise.rs
@@ -15,8 +15,6 @@ use rand::rngs::OsRng;
use generic_array::typenum::*;
use generic_array::GenericArray;
-use zerocopy::AsBytes;
-
use super::device::Device;
use super::messages::{NoiseInitiation, NoiseResponse};
use super::peer::{Peer, State};
@@ -140,9 +138,9 @@ pub fn create_initiation<T: Copy>(
device: &Device<T>,
peer: &Peer<T>,
sender: u32,
-) -> Result<Vec<u8>, HandshakeError> {
+ msg: &mut NoiseInitiation,
+) -> Result<(), HandshakeError> {
let mut rng = OsRng::new().unwrap();
- let mut msg: NoiseInitiation = Default::default();
// initialize state
@@ -214,9 +212,7 @@ pub fn create_initiation<T: Copy>(
sender,
});
- // return message as vector
-
- Ok(msg.as_bytes().to_vec())
+ Ok(())
}
pub fn consume_initiation<'a, T: Copy>(
@@ -294,7 +290,7 @@ pub fn create_response<T: Copy>(
sender: u32, // sending identifier
state: TemporaryState, // state from "consume_initiation"
msg: &mut NoiseResponse, // resulting response
-) -> Result<Output<T>, HandshakeError> {
+) -> Result<KeyPair, HandshakeError> {
let mut rng = OsRng::new().unwrap();
let (receiver, eph_r_pk, hs, ck) = state;
@@ -354,23 +350,19 @@ pub fn create_response<T: Copy>(
let (key_recv, key_send) = KDF2!(&ck, &[]);
- // return response and unconfirmed key-pair
-
- Ok((
- peer.identifier,
- Some(msg.as_bytes().to_vec()),
- Some(KeyPair {
- confirmed: false,
- send: Key {
- id: sender,
- key: key_send.into(),
- },
- recv: Key {
- id: receiver,
- key: key_recv.into(),
- },
- }),
- ))
+ // return unconfirmed key-pair
+
+ Ok(KeyPair {
+ confirmed: false,
+ send: Key {
+ id: sender,
+ key: key_send.into(),
+ },
+ recv: Key {
+ id: receiver,
+ key: key_recv.into(),
+ },
+ })
}
pub fn consume_response<T: Copy>(
diff --git a/src/handshake/peer.rs b/src/handshake/peer.rs
index 5b01d75..309a9cf 100644
--- a/src/handshake/peer.rs
+++ b/src/handshake/peer.rs
@@ -10,6 +10,7 @@ use x25519_dalek::StaticSecret;
use super::device::Device;
use super::timestamp;
use super::types::*;
+use super::macs;
/* Represents the recomputation and state of a peer.
*
@@ -24,6 +25,9 @@ pub struct Peer<T> {
state: Mutex<State>,
timestamp: Mutex<Option<timestamp::TAI64N>>,
+ // state related to DoS mitigation fields
+ pub(crate) macs: macs::Generator,
+
// constant state
pub(crate) pk: PublicKey, // public key of peer
pub(crate) ss: SharedSecret, // precomputed DH(static, static)
@@ -69,6 +73,7 @@ where
ss: SharedSecret, // precomputed DH(static, static)
) -> Self {
Self {
+ macs: macs::Generator::new(pk),
identifier: identifier,
state: Mutex::new(State::Reset),
timestamp: Mutex::new(None),