From c97ddaf5d2dc2a55f6013b0eec20de16e1e7ee6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Garillot?= Date: Sun, 20 Sep 2020 07:53:12 -0400 Subject: [PATCH] Make KeyExchange generic in KeyFormat --- src/key_exchange/traits.rs | 4 +-- src/key_exchange/tripledh.rs | 66 ++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/src/key_exchange/traits.rs b/src/key_exchange/traits.rs index 1786bec..72acdd9 100644 --- a/src/key_exchange/traits.rs +++ b/src/key_exchange/traits.rs @@ -6,13 +6,13 @@ use crate::{ errors::{InternalPakeError, ProtocolError}, hash::Hash, - keypair::{Key, KeyPair}, + keypair::KeyPair, }; use rand_core::{CryptoRng, RngCore}; use std::convert::TryFrom; -pub trait KeyExchange> { +pub trait KeyExchange { type KE1State: TryFrom, Error = InternalPakeError> + ToBytes; type KE2State: TryFrom, Error = ProtocolError> + ToBytes; type KE1Message: TryFrom, Error = InternalPakeError> + ToBytes; diff --git a/src/key_exchange/tripledh.rs b/src/key_exchange/tripledh.rs index ad4ec97..ed016e6 100644 --- a/src/key_exchange/tripledh.rs +++ b/src/key_exchange/tripledh.rs @@ -8,7 +8,7 @@ use crate::{ errors::{utils::check_slice_size, InternalPakeError, PakeError, ProtocolError}, hash::Hash, key_exchange::traits::{KeyExchange, ToBytes}, - keypair::{Key, KeyPair, SizedBytes}, + keypair::{KeyPair, SizedBytes}, }; use digest::{Digest, FixedOutput}; use generic_array::{ @@ -31,11 +31,11 @@ static STR_3DH: &[u8] = b"3DH keys"; /// The Triple Diffie-Hellman key exchange implementation pub struct TripleDH; -impl> KeyExchange for TripleDH { - type KE1State = KE1State<::OutputSize>; +impl KeyExchange for TripleDH { + type KE1State = KE1State<::OutputSize, KeyFormat>; type KE2State = KE2State<::OutputSize>; - type KE1Message = KE1Message; - type KE2Message = KE2Message<::OutputSize>; + type KE1Message = KE1Message; + type KE2Message = KE2Message<::OutputSize, KeyFormat>; type KE3Message = KE3Message<::OutputSize>; fn generate_ke1( @@ -158,7 +158,7 @@ impl> KeyExchange for Trip &ke1_state.hashed_l1[..], &l2_component[..], &ke2_message.server_nonce[..], - &ke2_message.server_e_pk[..], + &ke2_message.server_e_pk.to_arr(), ] .concat(); @@ -216,20 +216,22 @@ impl> KeyExchange for Trip /// The client state produced after the first key exchange message #[derive(PartialEq, Eq)] -pub struct KE1State> { - client_e_sk: Key, +pub struct KE1State, KeyFormat: KeyPair> { + client_e_sk: KeyFormat::Repr, client_nonce: GenericArray, hashed_l1: GenericArray, } /// The first key exchange message #[derive(PartialEq, Eq)] -pub struct KE1Message { +pub struct KE1Message { pub(crate) client_nonce: GenericArray, - pub(crate) client_e_pk: Key, + pub(crate) client_e_pk: KeyFormat::Repr, } -impl> TryFrom> for KE1State { +impl, KeyFormat: KeyPair> TryFrom> + for KE1State +{ type Error = InternalPakeError; fn try_from(bytes: Vec) -> Result { @@ -240,7 +242,7 @@ impl> TryFrom> for KE1State { )?; Ok(Self { - client_e_sk: Key::from_bytes(&checked_bytes[..KEY_LEN])?, + client_e_sk: KeyFormat::Repr::from_bytes(&checked_bytes[..KEY_LEN])?, client_nonce: GenericArray::clone_from_slice( &checked_bytes[KEY_LEN..KEY_LEN + NONCE_LEN], ), @@ -249,7 +251,7 @@ impl> TryFrom> for KE1State { } } -impl> ToBytes for KE1State { +impl, KeyFormat: KeyPair> ToBytes for KE1State { fn to_bytes(&self) -> Vec { let output: Vec = [ &self.client_e_sk.to_arr(), @@ -261,13 +263,13 @@ impl> ToBytes for KE1State { } } -impl ToBytes for KE1Message { +impl ToBytes for KE1Message { fn to_bytes(&self) -> Vec { [&self.client_nonce[..], &self.client_e_pk.to_arr()].concat() } } -impl TryFrom> for KE1Message { +impl TryFrom> for KE1Message { type Error = InternalPakeError; fn try_from(ke1_message_bytes: Vec) -> Result { @@ -276,7 +278,7 @@ impl TryFrom> for KE1Message { Ok(Self { client_nonce: GenericArray::clone_from_slice(&checked_bytes[..NONCE_LEN]), - client_e_pk: Key::from_bytes(&checked_bytes[NONCE_LEN..])?, + client_e_pk: KeyFormat::Repr::from_bytes(&checked_bytes[NONCE_LEN..])?, }) } } @@ -289,9 +291,9 @@ pub struct KE2State> { } /// The second key exchange message -pub struct KE2Message> { +pub struct KE2Message, KeyFormat: KeyPair> { server_nonce: GenericArray, - server_e_pk: Key, + server_e_pk: KeyFormat::Repr, mac: GenericArray, } @@ -321,7 +323,7 @@ impl> TryFrom> for KE2State { } } -impl> ToBytes for KE2Message { +impl, KeyFormat: KeyPair> ToBytes for KE2Message { fn to_bytes(&self) -> Vec { let output: Vec = [ &self.server_nonce[..], @@ -333,7 +335,9 @@ impl> ToBytes for KE2Message { } } -impl> TryFrom> for KE2Message { +impl, KeyFormat: KeyPair> TryFrom> + for KE2Message +{ type Error = ProtocolError; fn try_from(ke2_message_bytes: Vec) -> Result { @@ -342,20 +346,22 @@ impl> TryFrom> for KE2Message { Ok(Self { server_nonce: GenericArray::clone_from_slice(&checked_bytes[..NONCE_LEN]), - server_e_pk: Key::from_bytes(&checked_bytes[NONCE_LEN..NONCE_LEN + KEY_LEN])?, + server_e_pk: KeyFormat::Repr::from_bytes( + &checked_bytes[NONCE_LEN..NONCE_LEN + KEY_LEN], + )?, mac: GenericArray::clone_from_slice(&checked_bytes[NONCE_LEN + KEY_LEN..]), }) } } // The triple of public and private components used in the 3DH computation -struct TripleDHComponents { - pk1: Key, - sk1: Key, - pk2: Key, - sk2: Key, - pk3: Key, - sk3: Key, +struct TripleDHComponents { + pk1: KeyFormat::Repr, + sk1: KeyFormat::Repr, + pk2: KeyFormat::Repr, + sk2: KeyFormat::Repr, + pk3: KeyFormat::Repr, + sk3: KeyFormat::Repr, } // Consists of a shared secret, followed by two mac keys @@ -367,8 +373,8 @@ type TripleDHDerivationResult = ( // Internal function which takes the public and private components of the client and server keypairs, along // with some auxiliary metadata, to produce the shared secret and two MAC keys -fn derive_3dh_keys, D: Hash>( - dh: TripleDHComponents, +fn derive_3dh_keys( + dh: TripleDHComponents, client_nonce: &GenericArray, server_nonce: &GenericArray, client_s_pk: KeyFormat::Repr,