From 9154c997fa8b9ffc04c5924c572283723795b011 Mon Sep 17 00:00:00 2001 From: Mathias Hall-Andersen Date: Wed, 10 Jul 2019 18:22:48 +0200 Subject: Encoding / decoding of messages --- src/lib.rs | 11 ++++++ src/machine.rs | 54 +++++++++++++++++++++++++++ src/messages.rs | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 176 insertions(+) create mode 100644 src/lib.rs create mode 100644 src/machine.rs create mode 100644 src/messages.rs (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..a1aa18a --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,11 @@ +mod messages; +mod machine; + +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + assert_eq!(2 + 2, 4); + } +} + diff --git a/src/machine.rs b/src/machine.rs new file mode 100644 index 0000000..a9a3904 --- /dev/null +++ b/src/machine.rs @@ -0,0 +1,54 @@ +use x25519_dalek::PublicKey; +use x25519_dalek::StaticSecret; +use x25519_dalek::SharedSecret; + +/* Mutable part of handshake state */ +enum StateMutable { + Reset, + InitiationSent, + InitiationProcessed, + ReponseSent +} + +/* Immutable part of the handshake state */ +struct StateFixed { + sk : StaticSecret, + pk : PublicKey, + ss : SharedSecret +} + +struct State { + m : StateMutable, + f : StateFixed, +} + +struct KeyPair { + send : [u8; 32], + recv : [u8; 32] +} + +impl State { + /* Initialize a new handshake state machine + */ + fn new(sk : StaticSecret, pk : PublicKey) -> State { + let ss = sk.diffie_hellman(&pk); + State { + m : StateMutable::Reset, + f : StateFixed{sk, pk, ss} + } + } + + /* Begin a new handshake, returns the initial handshake message + */ + fn begin(&self) -> Vec { + vec![] + } + + /* Process a handshake message. + * + * Result is either a new state (and optionally a new key pair) or an error + */ + fn process(&self, msg : &[u8]) -> Result<(State, Option), ()> { + Err(()) + } +} diff --git a/src/messages.rs b/src/messages.rs new file mode 100644 index 0000000..c9c4239 --- /dev/null +++ b/src/messages.rs @@ -0,0 +1,111 @@ +use std::mem; + +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_RESPONSE : u8 = 2; + +/* Wireguard handshake initiation message + * initator -> responder + */ +#[repr(C)] +#[derive(Copy, Clone)] +struct MessageInitiate { + f_type : u32, + f_sender : u32, + f_ephemeral : [u8; SIZE_X25519_POINT], + f_static : [u8; SIZE_X25519_POINT + SIZE_TAG], + f_timestamp : [u8; SIZE_TIMESTAMP + SIZE_TAG], +} + +impl From<&[u8]> for MessageInitiate { + fn from(b: &[u8]) -> Self { + // create owned copy + let mut owned = [0u8; mem::size_of::()]; + let mut msg : Self; + owned.copy_from_slice(b); + + // cast to MessageInitiate + unsafe { + msg = mem::transmute::<[u8; mem::size_of::()], Self>(owned); + }; + + // correct endianness + msg.f_type = msg.f_type.to_le(); + msg.f_sender = msg.f_sender.to_le(); + msg + } +} + +impl Into> for MessageInitiate { + fn into(self) -> Vec { + // correct endianness + let mut msg = self; + msg.f_type = msg.f_type.to_le(); + msg.f_sender = msg.f_sender.to_le(); + + // cast to array + let array : [u8; mem::size_of::()]; + unsafe { + array = mem::transmute::()]>(msg) + }; + + array.to_vec() + } +} + +/* Wireguard handshake responder message + * responder -> initator + */ +#[repr(C)] +#[derive(Copy, Clone)] +struct MessageResponse { + f_type : u32, + f_sender : u32, + f_receiver : u32, + f_ephemeral : [u8; SIZE_X25519_POINT], + f_empty : [u8; SIZE_TAG], +} + +impl From<&[u8]> for MessageResponse { + fn from(b: &[u8]) -> Self { + // create owned copy + let mut owned = [0u8; mem::size_of::()]; + let mut msg : Self; + owned.copy_from_slice(b); + + // cast to MessageInitiate + unsafe { + msg = mem::transmute::<[u8; mem::size_of::()], Self>(owned); + }; + + // correct endianness + msg.f_type = msg.f_type.to_le(); + msg.f_sender = msg.f_sender.to_le(); + msg.f_receiver = msg.f_receiver.to_le(); + msg + } +} + +impl Into> for MessageResponse { + fn into(self) -> Vec { + // correct endianness + let mut msg = self; + msg.f_type = msg.f_type.to_le(); + msg.f_sender = msg.f_sender.to_le(); + msg.f_receiver = msg.f_receiver.to_le(); + + // cast to array + let array : [u8; mem::size_of::()]; + unsafe { + array = mem::transmute::()]>(msg) + }; + + array.to_vec() + } +} -- cgit v1.2.3-59-g8ed1b