summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMathias Hall-Andersen <mathias@hall-andersen.dk>2019-07-13 23:15:01 +0200
committerMathias Hall-Andersen <mathias@hall-andersen.dk>2019-07-13 23:15:01 +0200
commit7805fd9f596870046c3bc607f5e5199b738a02cb (patch)
treeb47a20e6e1736c5beafd473748d3b00f9bb7f847 /src
parentAdd peers and psks to device (diff)
downloadwireguard-rs-7805fd9f596870046c3bc607f5e5199b738a02cb.tar.xz
wireguard-rs-7805fd9f596870046c3bc607f5e5199b738a02cb.zip
Begin work on creating initiation
Diffstat (limited to 'src')
-rw-r--r--src/machine.rs26
-rw-r--r--src/messages.rs48
-rw-r--r--src/noise.rs114
-rw-r--r--src/types.rs25
4 files changed, 169 insertions, 44 deletions
diff --git a/src/machine.rs b/src/machine.rs
index 8cb6fba..a056d0c 100644
--- a/src/machine.rs
+++ b/src/machine.rs
@@ -6,30 +6,10 @@ use rand::rngs::OsRng;
use x25519_dalek::PublicKey;
use x25519_dalek::StaticSecret;
-use x25519_dalek::SharedSecret;
-use crate::noise;
-use crate::types;
-
-pub struct Output (
- Option<types::KeyPair>, // resulting key-pair of successful handshake
- Option<Vec<u8>> // message to send
-);
-pub struct Peer {
- // mutable state
- m : Mutex<State>,
-
- // constant state
- pk : PublicKey, // public key of peer
- ss : SharedSecret, // precomputed DH(static, static)
- psk : [u8; 32] // psk of peer
-}
-
-enum State {
- Reset,
- InitiationSent,
-}
+use crate::noise;
+use crate::types::*;
struct Device {
sk : StaticSecret, // static secret key
@@ -162,7 +142,7 @@ impl Device {
impl Device {
// allocate a new index (id), for peer with idx
fn allocate(&self, idx : usize) -> u32 {
- let mut rng = OsRng;
+ let mut rng = OsRng::new().unwrap();
let mut table = self.ids.lock().unwrap();
loop {
let id = rng.gen();
diff --git a/src/messages.rs b/src/messages.rs
index 1ec50bf..92a5a3e 100644
--- a/src/messages.rs
+++ b/src/messages.rs
@@ -5,10 +5,7 @@ const SIZE_TAG : usize = 16;
const SIZE_X25519_POINT : usize = 32;
const SIZE_TIMESTAMP : usize = 12;
-pub const SIZE_MESSAGE_INITIATE : usize = 116;
-pub const SIZE_MESSAGE_RESPONSE : usize = 116;
-
-pub const TYPE_INITIATE : u8 = 1;
+pub const TYPE_INITIATION : u8 = 1;
pub const TYPE_RESPONSE : u8 = 2;
/* Wireguard handshake initiation message
@@ -16,16 +13,16 @@ pub const TYPE_RESPONSE : u8 = 2;
*/
#[repr(C)]
#[derive(Copy, Clone)]
-struct MessageInitiate {
- f_type : u8,
- f_reserved : [u8; 3],
- f_sender : u32,
- f_ephemeral : [u8; SIZE_X25519_POINT],
- f_static : [u8; SIZE_X25519_POINT + SIZE_TAG],
- f_timestamp : [u8; SIZE_TIMESTAMP + SIZE_TAG],
+pub struct Initiation {
+ pub f_type : u8,
+ f_reserved : [u8; 3],
+ pub f_sender : u32,
+ pub f_ephemeral : [u8; SIZE_X25519_POINT],
+ pub f_static : [u8; SIZE_X25519_POINT + SIZE_TAG],
+ pub f_timestamp : [u8; SIZE_TIMESTAMP + SIZE_TAG],
}
-impl From<&[u8]> for MessageInitiate {
+impl From<&[u8]> for Initiation {
fn from(b: &[u8]) -> Self {
// create owned copy
let mut owned = [0u8; mem::size_of::<Self>()];
@@ -44,7 +41,7 @@ impl From<&[u8]> for MessageInitiate {
}
}
-impl Into<Vec<u8>> for MessageInitiate {
+impl Into<Vec<u8>> for Initiation {
fn into(self) -> Vec<u8> {
// correct endianness
let mut msg = self;
@@ -61,7 +58,7 @@ impl Into<Vec<u8>> for MessageInitiate {
}
}
-impl fmt::Debug for MessageInitiate {
+impl fmt::Debug for Initiation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f,
"MessageInitiate {{ type = {} }}",
@@ -70,8 +67,21 @@ impl fmt::Debug for MessageInitiate {
}
}
+impl Default for Initiation {
+ fn default() -> Self {
+ Self {
+ f_type : TYPE_INITIATION,
+ f_reserved : [0u8; 3],
+ f_sender : 0,
+ f_ephemeral : [0u8; SIZE_X25519_POINT],
+ f_static : [0u8; SIZE_X25519_POINT + SIZE_TAG],
+ f_timestamp : [0u8; SIZE_TIMESTAMP + SIZE_TAG],
+ }
+ }
+}
+
#[cfg(test)]
-impl PartialEq for MessageInitiate {
+impl PartialEq for Initiation {
fn eq(&self, other: &Self) -> bool {
self.f_type == other.f_type &&
self.f_reserved == other.f_reserved &&
@@ -83,7 +93,7 @@ impl PartialEq for MessageInitiate {
}
#[cfg(test)]
-impl Eq for MessageInitiate {}
+impl Eq for Initiation {}
/* Wireguard handshake responder message
@@ -91,7 +101,7 @@ impl Eq for MessageInitiate {}
*/
#[repr(C)]
#[derive(Copy, Clone)]
-struct MessageResponse {
+pub struct MessageResponse {
f_type : u8,
f_reserved : [u8; 3],
f_sender : u32,
@@ -190,7 +200,7 @@ mod tests {
#[test]
fn message_initiate_identity() {
- let msg = MessageInitiate {
+ let msg = Initiation {
f_type : TYPE_RESPONSE,
f_reserved : [0u8; 3],
f_sender : 575757,
@@ -224,6 +234,6 @@ mod tests {
};
let buf : Vec<u8> = msg.into();
- assert_eq!(msg, MessageInitiate::from(&buf[..]));
+ assert_eq!(msg, Initiation::from(&buf[..]));
}
}
diff --git a/src/noise.rs b/src/noise.rs
index 2d4c122..6d3850c 100644
--- a/src/noise.rs
+++ b/src/noise.rs
@@ -1,6 +1,116 @@
-use crate::machine::Peer;
-use crate::machine::Output;
+use hmac::{Mac, Hmac};
+use blake2::{Blake2s, Digest};
+
+use x25519_dalek::PublicKey;
+use x25519_dalek::StaticSecret;
+use x25519_dalek::SharedSecret;
+
+use rand::rngs::OsRng;
+
+use generic_array::*;
+
+use crate::types::*;
+use crate::messages;
+
+type HMACBlake2s = Hmac<Blake2s>;
+
+/* Internal functions for processing and creating noise messages */
+
+const IDENTIFIER : &[u8] = b"WireGuard v1 zx2c4 Jason@zx2c4.com";
+const CONSTRUCTION : &[u8] = b"Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s";
+
+const SIZE_CK : usize = 32;
+const SIZE_HS : usize = 32;
+
+// C := Hash(Construction)
+const INITIAL_CK : [u8; SIZE_CK] = [
+ 0x60, 0xe2, 0x6d, 0xae, 0xf3, 0x27, 0xef, 0xc0,
+ 0x2e, 0xc3, 0x35, 0xe2, 0xa0, 0x25, 0xd2, 0xd0,
+ 0x16, 0xeb, 0x42, 0x06, 0xf8, 0x72, 0x77, 0xf5,
+ 0x2d, 0x38, 0xd1, 0x98, 0x8b, 0x78, 0xcd, 0x36
+];
+
+// H := Hash(C || Identifier)
+const INITIAL_HS : [u8; SIZE_HS] = [
+ 0x22, 0x11, 0xb3, 0x61, 0x08, 0x1a, 0xc5, 0x66,
+ 0x69, 0x12, 0x43, 0xdb, 0x45, 0x8a, 0xd5, 0x32,
+ 0x2d, 0x9c, 0x6c, 0x66, 0x22, 0x93, 0xe8, 0xb7,
+ 0x0e, 0xe1, 0x9c, 0x65, 0xba, 0x07, 0x9e, 0xf3
+];
+
+macro_rules! HASH {
+ ($input1:expr, $input2:expr) => {
+ {
+ let mut hsh = <Blake2s as Digest>::new();
+ Digest::input(&mut hsh, $input1);
+ Digest::input(&mut hsh, $input2);
+ Digest::result(hsh)
+ }
+ };
+}
+
+macro_rules! HMAC {
+ ($key:expr, $input:expr) => {
+ HMACBlake2s::new($key).hash($input).result()
+ };
+
+ ($key:expr, $input1:expr, $input2:expr) => {
+ HMACBlake2s::new($key).hash($input2).hash($input2).result()
+ };
+}
+
+macro_rules! KDF1 {
+ ($ck:expr, $input:expr) => {
+ {
+ let t0 = HMAC!($ck, $input);
+ t0
+ }
+ }
+}
+
+macro_rules! KDF2 {
+ ($ck:expr, $input:expr) => {
+
+ }
+}
+
+macro_rules! KDF2 {
+ ($ck:expr, $input:expr) => {
+
+ }
+}
pub fn create_initiation(peer : &Peer, id : u32) -> Result<Vec<u8>, ()> {
+ let mut rng = OsRng::new().unwrap();
+ let mut msg : messages::Initiation = Default::default();
+
+ // initialize state
+
+ let ck = INITIAL_CK;
+ let hs = INITIAL_HS;
+ let hs = HASH!(&hs, peer.pk.as_bytes());
+
+ msg.f_sender = id;
+
+ // token : e
+
+ let sk = StaticSecret::new(&mut rng);
+ let pk = PublicKey::from(&sk);
+
+ msg.f_ephemeral = *pk.as_bytes();
+
+ // let ck = KDF1!(&ck, pk.as_bytes());
+
+ // token : es
+
+ // token : s
+
+ // token : ss
+
Ok(vec![])
}
+
+pub fn process_initiation(peer : &Peer) -> Result<Output, ()> {
+ Err(())
+}
+
diff --git a/src/types.rs b/src/types.rs
index 3729555..391b029 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -1,3 +1,8 @@
+use std::sync::Mutex;
+
+use x25519_dalek::PublicKey;
+use x25519_dalek::SharedSecret;
+
struct Key {
key : [u8; 32],
id : u32
@@ -8,3 +13,23 @@ pub struct KeyPair {
send : Key, // key for outbound messages
recv : Key // key for inbound messages
}
+
+pub struct Output (
+ Option<KeyPair>, // resulting key-pair of successful handshake
+ Option<Vec<u8>> // message to send
+);
+
+pub struct Peer {
+ // mutable state
+ pub m : Mutex<State>,
+
+ // constant state
+ pub pk : PublicKey, // public key of peer
+ pub ss : SharedSecret, // precomputed DH(static, static)
+ pub psk : [u8; 32] // psk of peer
+}
+
+pub enum State {
+ Reset,
+ InitiationSent,
+}