diff options
author | Mathias Hall-Andersen <mathias@hall-andersen.dk> | 2019-07-13 23:15:01 +0200 |
---|---|---|
committer | Mathias Hall-Andersen <mathias@hall-andersen.dk> | 2019-07-13 23:15:01 +0200 |
commit | 7805fd9f596870046c3bc607f5e5199b738a02cb (patch) | |
tree | b47a20e6e1736c5beafd473748d3b00f9bb7f847 /src | |
parent | Add peers and psks to device (diff) | |
download | wireguard-rs-7805fd9f596870046c3bc607f5e5199b738a02cb.tar.xz wireguard-rs-7805fd9f596870046c3bc607f5e5199b738a02cb.zip |
Begin work on creating initiation
Diffstat (limited to 'src')
-rw-r--r-- | src/machine.rs | 26 | ||||
-rw-r--r-- | src/messages.rs | 48 | ||||
-rw-r--r-- | src/noise.rs | 114 | ||||
-rw-r--r-- | src/types.rs | 25 |
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, +} |