Implement handshake_secret test

This commit is contained in:
dAxpeDDa
2021-07-30 14:45:27 -07:00
committed by Kevin Lewi
parent 49dc5b9050
commit 4298deadff
5 changed files with 79 additions and 20 deletions
+18 -2
View File
@@ -13,6 +13,22 @@ use crate::{
use rand::{CryptoRng, RngCore};
use zeroize::Zeroize;
#[cfg(not(test))]
pub type GenerateKe2Result<K, D, G> = (
<K as KeyExchange<D, G>>::KE2State,
<K as KeyExchange<D, G>>::KE2Message,
);
#[cfg(test)]
pub type GenerateKe2Result<K, D, G> = (
<K as KeyExchange<D, G>>::KE2State,
<K as KeyExchange<D, G>>::KE2Message,
Vec<u8>,
);
#[cfg(not(test))]
pub type GenerateKe3Result<K, D, G> = (Vec<u8>, <K as KeyExchange<D, G>>::KE3Message);
#[cfg(test)]
pub type GenerateKe3Result<K, D, G> = (Vec<u8>, <K as KeyExchange<D, G>>::KE3Message, Vec<u8>);
pub trait KeyExchange<D: Hash, G: Group> {
type KE1State: FromBytes + ToBytesWithPointers + Zeroize + Clone;
type KE2State: FromBytes + ToBytesWithPointers + Zeroize + Clone;
@@ -35,7 +51,7 @@ pub trait KeyExchange<D: Hash, G: Group> {
id_u: Vec<u8>,
id_s: Vec<u8>,
context: Vec<u8>,
) -> Result<(Self::KE2State, Self::KE2Message), ProtocolError<S::Error>>;
) -> Result<GenerateKe2Result<Self, D, G>, ProtocolError<S::Error>>;
#[allow(clippy::too_many_arguments, clippy::type_complexity)]
fn generate_ke3(
@@ -48,7 +64,7 @@ pub trait KeyExchange<D: Hash, G: Group> {
id_u: Vec<u8>,
id_s: Vec<u8>,
context: Vec<u8>,
) -> Result<(Vec<u8>, Self::KE3Message), ProtocolError>;
) -> Result<GenerateKe3Result<Self, D, G>, ProtocolError>;
#[allow(clippy::type_complexity)]
fn finish_ke(
+28 -12
View File
@@ -12,7 +12,9 @@ use crate::{
},
group::Group,
hash::Hash,
key_exchange::traits::{FromBytes, KeyExchange, ToBytes, ToBytesWithPointers},
key_exchange::traits::{
FromBytes, GenerateKe2Result, GenerateKe3Result, KeyExchange, ToBytes, ToBytesWithPointers,
},
keypair::{KeyPair, PrivateKey, PublicKey, SecretKey, SizedBytesExt},
serialization::serialize,
};
@@ -80,7 +82,7 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
id_u: Vec<u8>,
id_s: Vec<u8>,
context: Vec<u8>,
) -> Result<(Self::KE2State, Self::KE2Message), ProtocolError<S::Error>> {
) -> Result<GenerateKe2Result<Self, D, G>, ProtocolError<S::Error>> {
let server_e_kp = KeyPair::<G>::generate_random(rng);
let server_nonce = generate_nonce::<R>(rng);
@@ -94,7 +96,7 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
.chain(&server_nonce[..])
.chain(&server_e_kp.public().to_arr());
let (session_key, km2, km3) = derive_3dh_keys::<D, G, S>(
let result = derive_3dh_keys::<D, G, S>(
TripleDHComponents {
pk1: ke1_message.client_e_pk.clone(),
sk1: server_e_kp.private().clone(),
@@ -107,7 +109,7 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
)?;
let mut mac_hasher =
Hmac::<D>::new_from_slice(&km2).map_err(|_| InternalPakeError::HmacError)?;
Hmac::<D>::new_from_slice(&result.1).map_err(|_| InternalPakeError::HmacError)?;
mac_hasher.update(&transcript_hasher.clone().finalize());
let mac = mac_hasher.finalize().into_bytes();
@@ -115,15 +117,17 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
Ok((
Ke2State {
km3,
km3: result.2,
hashed_transcript: transcript_hasher.finalize(),
session_key,
session_key: result.0,
},
Ke2Message {
server_nonce,
server_e_pk: server_e_kp.public().clone(),
mac,
},
#[cfg(test)]
result.3,
))
}
@@ -138,7 +142,7 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
id_u: Vec<u8>,
id_s: Vec<u8>,
context: Vec<u8>,
) -> Result<(Vec<u8>, Self::KE3Message), ProtocolError> {
) -> Result<GenerateKe3Result<Self, D, G>, ProtocolError> {
let mut transcript_hasher = D::new()
.chain(STR_RFC)
.chain(&serialize(&context, 2)?)
@@ -148,7 +152,7 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
.chain(&l2_component[..])
.chain(&ke2_message.to_bytes_without_info_or_mac());
let (session_key, km2, km3) = derive_3dh_keys::<D, G, PrivateKey<G>>(
let result = derive_3dh_keys::<D, G, PrivateKey<G>>(
TripleDHComponents {
pk1: ke2_message.server_e_pk.clone(),
sk1: ke1_state.client_e_sk.clone(),
@@ -161,7 +165,7 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
)?;
let mut server_mac =
Hmac::<D>::new_from_slice(&km2).map_err(|_| InternalPakeError::HmacError)?;
Hmac::<D>::new_from_slice(&result.1).map_err(|_| InternalPakeError::HmacError)?;
server_mac.update(&transcript_hasher.clone().finalize());
if server_mac.verify(&ke2_message.mac).is_err() {
@@ -173,14 +177,16 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
transcript_hasher.update(ke2_message.mac.to_vec());
let mut client_mac =
Hmac::<D>::new_from_slice(&km3).map_err(|_| InternalPakeError::HmacError)?;
Hmac::<D>::new_from_slice(&result.2).map_err(|_| InternalPakeError::HmacError)?;
client_mac.update(&transcript_hasher.finalize());
Ok((
session_key.to_vec(),
result.0.to_vec(),
Ke3Message {
mac: client_mac.finalize().into_bytes(),
},
#[cfg(test)]
result.3,
))
}
@@ -417,13 +423,21 @@ struct TripleDHComponents<G: Group, S: SecretKey<G>> {
sk3: PrivateKey<G>,
}
#[allow(clippy::upper_case_acronyms)]
// Consists of a session key, followed by two mac keys: (session_key, km2, km3)
#[cfg(not(test))]
#[allow(clippy::upper_case_acronyms)]
type TripleDHDerivationResult<D> = (
GenericArray<u8, <D as FixedOutput>::OutputSize>,
GenericArray<u8, <D as FixedOutput>::OutputSize>,
GenericArray<u8, <D as FixedOutput>::OutputSize>,
);
#[cfg(test)]
type TripleDHDerivationResult<D> = (
GenericArray<u8, <D as FixedOutput>::OutputSize>,
GenericArray<u8, <D as FixedOutput>::OutputSize>,
GenericArray<u8, <D as FixedOutput>::OutputSize>,
Vec<u8>,
);
/// The third key exchange message
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
@@ -501,6 +515,8 @@ fn derive_3dh_keys<D: Hash, G: Group, S: SecretKey<G>>(
GenericArray::clone_from_slice(&session_key),
GenericArray::clone_from_slice(&km2),
GenericArray::clone_from_slice(&km3),
#[cfg(test)]
handshake_secret,
))
}