Begin work on creating initiation
This commit is contained in:
@@ -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::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();
|
||||
|
||||
@@ -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[..]));
|
||||
}
|
||||
}
|
||||
|
||||
114
src/noise.rs
114
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(())
|
||||
}
|
||||
|
||||
|
||||
25
src/types.rs
25
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,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user