Implement handshake_secret test
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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,
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user