in src/key_exchange/tripledh.rs [280:343]
fn generate_ke2<'a, 'b, 'c, 'd, R: RngCore + CryptoRng, S: SecretKey<KG>>(
rng: &mut R,
serialized_credential_request: impl Iterator<Item = &'a [u8]>,
l2_bytes: impl Iterator<Item = &'b [u8]>,
ke1_message: Self::KE1Message,
client_s_pk: PublicKey<KG>,
server_s_sk: S,
id_u: impl Iterator<Item = &'c [u8]>,
id_s: impl Iterator<Item = &'d [u8]>,
context: &[u8],
) -> Result<GenerateKe2Result<Self, D, KG>, ProtocolError<S::Error>> {
let server_e_kp = KeyPair::<KG>::generate_random(rng);
let server_nonce = generate_nonce::<R>(rng);
let mut transcript_hasher = D::new()
.chain(STR_RFC)
.chain_iter(
Serialize::<U2>::from(context)
.map_err(ProtocolError::into_custom)?
.iter(),
)
.chain_iter(id_u.into_iter())
.chain_iter(serialized_credential_request)
.chain_iter(id_s.into_iter())
.chain_iter(l2_bytes)
.chain(server_nonce)
.chain(&server_e_kp.public().to_bytes());
let result = derive_3dh_keys::<D, KG, S>(
TripleDHComponents {
pk1: ke1_message.client_e_pk.clone(),
sk1: server_e_kp.private().clone(),
pk2: ke1_message.client_e_pk.clone(),
sk2: server_s_sk,
pk3: client_s_pk,
sk3: server_e_kp.private().clone(),
},
&transcript_hasher.clone().finalize(),
)?;
let mut mac_hasher =
Hmac::<D>::new_from_slice(&result.1).map_err(|_| InternalError::HmacError)?;
mac_hasher.update(&transcript_hasher.clone().finalize());
let mac = mac_hasher.finalize().into_bytes();
Digest::update(&mut transcript_hasher, &mac);
Ok((
Ke2State {
km3: result.2,
hashed_transcript: transcript_hasher.finalize(),
session_key: result.0,
},
Ke2Message {
server_nonce,
server_e_pk: server_e_kp.public().clone(),
mac,
},
#[cfg(test)]
result.3,
#[cfg(test)]
result.1,
))
}