added comments

This commit is contained in:
mamoniot 2022-12-14 16:30:18 -05:00
parent ceec943d4f
commit 03b8f9158d
2 changed files with 47 additions and 19 deletions

View file

@ -81,7 +81,7 @@ pub(crate) const KEY_HISTORY_SIZE: usize = 3;
// Packet types can range from 0 to 15 (4 bits) -- 0-3 are defined and 4-15 are reserved for future use // Packet types can range from 0 to 15 (4 bits) -- 0-3 are defined and 4-15 are reserved for future use
pub(crate) const PACKET_TYPE_DATA: u8 = 0; pub(crate) const PACKET_TYPE_DATA: u8 = 0;
pub(crate) const PACKET_TYPE_NOP: u8 = 1; pub(crate) const PACKET_TYPE_NOP: u8 = 1;
pub(crate) const PACKET_TYPE_KEY_OFFER: u8 = 2; // "alice" pub(crate) const PACKET_TYPE_INITIAL_KEY_OFFER: u8 = 2; // "alice"
pub(crate) const PACKET_TYPE_KEY_COUNTER_OFFER: u8 = 3; // "bob" pub(crate) const PACKET_TYPE_KEY_COUNTER_OFFER: u8 = 3; // "bob"
// Key usage labels for sub-key derivation using NIST-style KBKDF (basically just HMAC KDF). // Key usage labels for sub-key derivation using NIST-style KBKDF (basically just HMAC KDF).

View file

@ -302,6 +302,10 @@ impl<Layer: ApplicationLayer> Session<Layer> {
// This outgoing packet's nonce counter value. // This outgoing packet's nonce counter value.
let counter = self.send_counter.next(); let counter = self.send_counter.next();
////////////////////////////////////////////////////////////////
// packet encoding for post-noise transport
////////////////////////////////////////////////////////////////
// Create initial header for first fragment of packet and place in first HEADER_SIZE bytes of buffer. // Create initial header for first fragment of packet and place in first HEADER_SIZE bytes of buffer.
create_packet_header( create_packet_header(
mtu_buffer, mtu_buffer,
@ -605,6 +609,9 @@ impl<Layer: ApplicationLayer> ReceiveContext<Layer> {
if let Some(session_key) = state.session_keys[key_idx].as_ref() { if let Some(session_key) = state.session_keys[key_idx].as_ref() {
let mut c = session_key.get_receive_cipher(); let mut c = session_key.get_receive_cipher();
c.reset_init_gcm(canonical_header_bytes); c.reset_init_gcm(canonical_header_bytes);
////////////////////////////////////////////////////////////////
// packet decoding for post-noise transport
////////////////////////////////////////////////////////////////
let mut data_len = 0; let mut data_len = 0;
@ -709,7 +716,7 @@ impl<Layer: ApplicationLayer> ReceiveContext<Layer> {
} }
match packet_type { match packet_type {
PACKET_TYPE_KEY_OFFER => { PACKET_TYPE_INITIAL_KEY_OFFER => {
// alice (remote) -> bob (local) // alice (remote) -> bob (local)
if kex_packet_len < (HEADER_SIZE + 1 + P384_PUBLIC_KEY_SIZE + AES_GCM_TAG_SIZE + HMAC_SIZE + HMAC_SIZE) { if kex_packet_len < (HEADER_SIZE + 1 + P384_PUBLIC_KEY_SIZE + AES_GCM_TAG_SIZE + HMAC_SIZE + HMAC_SIZE) {
@ -741,11 +748,15 @@ impl<Layer: ApplicationLayer> ReceiveContext<Layer> {
} }
} }
////////////////////////////////////////////////////////////////
// packet decoding for noise initial key offer
// -> e, es, s, ss
////////////////////////////////////////////////////////////////
// Key agreement: alice (remote) ephemeral NIST P-384 <> local static NIST P-384 // Key agreement: alice (remote) ephemeral NIST P-384 <> local static NIST P-384
let (alice_e_public, noise_es) = let (alice_e_public, noise_es) =
P384PublicKey::from_bytes(&kex_packet[(HEADER_SIZE + 1)..(HEADER_SIZE + 1 + P384_PUBLIC_KEY_SIZE)]) P384PublicKey::from_bytes(&kex_packet[(HEADER_SIZE + 1)..(HEADER_SIZE + 1 + P384_PUBLIC_KEY_SIZE)])
.and_then(|pk| host.get_local_s_keypair().agree(&pk).map(move |s| (pk, s))) .and_then(|pk| host.get_local_s_keypair().agree(&pk).map(move |s| (pk, s)))
.ok_or(Error::FailedAuthentication)?; .ok_or(Error::FailedAuthentication)?;
// Initial key derivation from starting point, mixing in alice's ephemeral public and the es. // Initial key derivation from starting point, mixing in alice's ephemeral public and the es.
let es_key = Secret(hmac_sha512(&hmac_sha512(&INITIAL_KEY, alice_e_public.as_bytes()), noise_es.as_bytes())); let es_key = Secret(hmac_sha512(&hmac_sha512(&INITIAL_KEY, alice_e_public.as_bytes()), noise_es.as_bytes()));
@ -900,7 +911,10 @@ impl<Layer: ApplicationLayer> ReceiveContext<Layer> {
(None, None) (None, None)
}; };
// Create reply packet. ////////////////////////////////////////////////////////////////
// packet encoding for noise key counter offer
// <- e, ee, se
////////////////////////////////////////////////////////////////
let mut reply_buf = [0_u8; KEX_BUF_LEN]; let mut reply_buf = [0_u8; KEX_BUF_LEN];
let reply_counter = session.send_counter.next(); let reply_counter = session.send_counter.next();
let mut idx = HEADER_SIZE; let mut idx = HEADER_SIZE;
@ -1001,14 +1015,19 @@ impl<Layer: ApplicationLayer> ReceiveContext<Layer> {
if let Some(session) = session { if let Some(session) = session {
let state = session.state.read().unwrap(); let state = session.state.read().unwrap();
if let Some(offer) = state.offer.as_ref() { if let Some(offer) = state.offer.as_ref() {
////////////////////////////////////////////////////////////////
// packet decoding for noise key counter offer
// <- e, ee, se
////////////////////////////////////////////////////////////////
let (bob_e_public, noise_ee) = let (bob_e_public, noise_ee) =
P384PublicKey::from_bytes(&kex_packet[(HEADER_SIZE + 1)..(HEADER_SIZE + 1 + P384_PUBLIC_KEY_SIZE)]) P384PublicKey::from_bytes(&kex_packet[(HEADER_SIZE + 1)..(HEADER_SIZE + 1 + P384_PUBLIC_KEY_SIZE)])
.and_then(|pk| offer.alice_e_keypair.agree(&pk).map(move |s| (pk, s))) .and_then(|pk| offer.alice_e_keypair.agree(&pk).map(move |s| (pk, s)))
.ok_or(Error::FailedAuthentication)?; .ok_or(Error::FailedAuthentication)?;
let noise_se = host let noise_se = host
.get_local_s_keypair() .get_local_s_keypair()
.agree(&bob_e_public) .agree(&bob_e_public)
.ok_or(Error::FailedAuthentication)?; .ok_or(Error::FailedAuthentication)?;
let noise_ik_key = Secret(hmac_sha512( let noise_ik_key = Secret(hmac_sha512(
session.psk.as_bytes(), session.psk.as_bytes(),
@ -1074,6 +1093,9 @@ impl<Layer: ApplicationLayer> ReceiveContext<Layer> {
let counter = session.send_counter.next(); let counter = session.send_counter.next();
let session_key = SessionKey::new(session_key, Role::Alice, current_time, counter, ratchet_count + 1, hybrid_kk.is_some()); let session_key = SessionKey::new(session_key, Role::Alice, current_time, counter, ratchet_count + 1, hybrid_kk.is_some());
////////////////////////////////////////////////////////////////
// packet encoding for post-noise session start ack
////////////////////////////////////////////////////////////////
let mut reply_buf = [0_u8; HEADER_SIZE + AES_GCM_TAG_SIZE]; let mut reply_buf = [0_u8; HEADER_SIZE + AES_GCM_TAG_SIZE];
create_packet_header( create_packet_header(
&mut reply_buf, &mut reply_buf,
@ -1125,7 +1147,7 @@ fn send_ephemeral_offer<SendFunction: FnMut(&mut [u8])>(
alice_metadata: &[u8], alice_metadata: &[u8],
bob_s_public_p384: &P384PublicKey, bob_s_public_p384: &P384PublicKey,
bob_s_public_hash: &[u8], bob_s_public_hash: &[u8],
ss: &Secret<48>, noise_ss: &Secret<48>,
current_key: Option<&SessionKey>, current_key: Option<&SessionKey>,
header_check_cipher: Option<&Aes>, // None to use one based on the recipient's public key for initial contact header_check_cipher: Option<&Aes>, // None to use one based on the recipient's public key for initial contact
mtu: usize, mtu: usize,
@ -1154,6 +1176,12 @@ fn send_ephemeral_offer<SendFunction: FnMut(&mut [u8])>(
// Random ephemeral offer ID // Random ephemeral offer ID
let id: [u8; 16] = random::get_bytes_secure(); let id: [u8; 16] = random::get_bytes_secure();
////////////////////////////////////////////////////////////////
// packet encoding for noise initial key offer and for noise rekeying
// -> e, es, s, ss
////////////////////////////////////////////////////////////////
// Create ephemeral offer packet (not fragmented yet). // Create ephemeral offer packet (not fragmented yet).
const PACKET_BUF_SIZE: usize = MIN_TRANSPORT_MTU * KEY_EXCHANGE_MAX_FRAGMENTS; const PACKET_BUF_SIZE: usize = MIN_TRANSPORT_MTU * KEY_EXCHANGE_MAX_FRAGMENTS;
let mut packet_buf = [0_u8; PACKET_BUF_SIZE]; let mut packet_buf = [0_u8; PACKET_BUF_SIZE];
@ -1170,9 +1198,9 @@ fn send_ephemeral_offer<SendFunction: FnMut(&mut [u8])>(
idx = safe_write_all(&mut packet_buf, idx, alice_s_public)?; idx = safe_write_all(&mut packet_buf, idx, alice_s_public)?;
idx = varint_safe_write(&mut packet_buf, idx, alice_metadata.len() as u64)?; idx = varint_safe_write(&mut packet_buf, idx, alice_metadata.len() as u64)?;
idx = safe_write_all(&mut packet_buf, idx, alice_metadata)?; idx = safe_write_all(&mut packet_buf, idx, alice_metadata)?;
if let Some(hkkp) = alice_hk_keypair { if let Some(hkp) = alice_hk_keypair {
idx = safe_write_all(&mut packet_buf, idx, &[E1_TYPE_KYBER1024])?; idx = safe_write_all(&mut packet_buf, idx, &[E1_TYPE_KYBER1024])?;
idx = safe_write_all(&mut packet_buf, idx, &hkkp.public)?; idx = safe_write_all(&mut packet_buf, idx, &hkp.public)?;
} else { } else {
idx = safe_write_all(&mut packet_buf, idx, &[E1_TYPE_NONE])?; idx = safe_write_all(&mut packet_buf, idx, &[E1_TYPE_NONE])?;
} }
@ -1192,9 +1220,9 @@ fn send_ephemeral_offer<SendFunction: FnMut(&mut [u8])>(
)); ));
let bob_session_id = bob_session_id.unwrap_or(SessionId::NIL); let bob_session_id = bob_session_id.unwrap_or(SessionId::NIL);
create_packet_header(&mut packet_buf, end_of_ciphertext, mtu, PACKET_TYPE_KEY_OFFER, bob_session_id, counter)?; create_packet_header(&mut packet_buf, end_of_ciphertext, mtu, PACKET_TYPE_INITIAL_KEY_OFFER, bob_session_id, counter)?;
let canonical_header = CanonicalHeader::make(bob_session_id, PACKET_TYPE_KEY_OFFER, counter.to_u32()); let canonical_header = CanonicalHeader::make(bob_session_id, PACKET_TYPE_INITIAL_KEY_OFFER, counter.to_u32());
// Encrypt packet and attach AES-GCM tag. // Encrypt packet and attach AES-GCM tag.
let gcm_tag = { let gcm_tag = {
@ -1209,7 +1237,7 @@ fn send_ephemeral_offer<SendFunction: FnMut(&mut [u8])>(
idx = safe_write_all(&mut packet_buf, idx, &gcm_tag)?; idx = safe_write_all(&mut packet_buf, idx, &gcm_tag)?;
// Mix in static secret. // Mix in static secret.
let ss_key = Secret(hmac_sha512(es_key.as_bytes(), ss.as_bytes())); let ss_key = Secret(hmac_sha512(es_key.as_bytes(), noise_ss.as_bytes()));
drop(es_key); drop(es_key);
// HMAC packet using static + ephemeral key. // HMAC packet using static + ephemeral key.
@ -1352,7 +1380,7 @@ fn parse_key_offer_after_header(
let alice_hk_public_raw = match safe_read_exact(&mut p, 1)?[0] { let alice_hk_public_raw = match safe_read_exact(&mut p, 1)?[0] {
E1_TYPE_KYBER1024 => { E1_TYPE_KYBER1024 => {
if packet_type == PACKET_TYPE_KEY_OFFER { if packet_type == PACKET_TYPE_INITIAL_KEY_OFFER {
safe_read_exact(&mut p, pqc_kyber::KYBER_PUBLICKEYBYTES)? safe_read_exact(&mut p, pqc_kyber::KYBER_PUBLICKEYBYTES)?
} else { } else {
safe_read_exact(&mut p, pqc_kyber::KYBER_CIPHERTEXTBYTES)? safe_read_exact(&mut p, pqc_kyber::KYBER_CIPHERTEXTBYTES)?