diff --git a/Cargo.lock b/Cargo.lock index 7c90fab7f9..d72ea6d2e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1065,9 +1065,9 @@ checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6" [[package]] name = "cc" -version = "1.2.54" +version = "1.2.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6354c81bbfd62d9cfa9cb3c773c2b7b2a3a482d569de977fd0e961f6e7c00583" +checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" dependencies = [ "find-msvc-tools", "jobserver", @@ -1195,9 +1195,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.55" +version = "4.5.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e34525d5bbbd55da2bb745d34b36121baac88d07619a9a09cfcf4a6c0832785" +checksum = "a75ca66430e33a14957acc24c5077b503e7d374151b2b4b3a10c83b4ceb4be0e" dependencies = [ "clap_builder", "clap_derive", @@ -1205,9 +1205,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.55" +version = "4.5.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a20016a20a3da95bef50ec7238dbd09baeef4311dcdd38ec15aba69812fb61" +checksum = "793207c7fa6300a0608d1080b858e5fdbe713cdc1c8db9fb17777d8a13e63df0" dependencies = [ "anstream", "anstyle", @@ -1459,7 +1459,7 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "core-models" version = "0.0.5" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "hax-lib", "pastey 0.2.1", @@ -2724,9 +2724,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "fixedbitset" @@ -4372,7 +4372,7 @@ checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" [[package]] name = "libcrux-aesgcm" version = "0.0.6" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "libcrux-intrinsics", "libcrux-platform", @@ -4383,7 +4383,7 @@ dependencies = [ [[package]] name = "libcrux-chacha20poly1305" version = "0.0.5" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "libcrux-hacl-rs", "libcrux-macros", @@ -4395,7 +4395,7 @@ dependencies = [ [[package]] name = "libcrux-curve25519" version = "0.0.5" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "libcrux-hacl-rs", "libcrux-macros", @@ -4406,7 +4406,7 @@ dependencies = [ [[package]] name = "libcrux-ecdh" version = "0.0.5" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "libcrux-curve25519", "libcrux-p256", @@ -4417,7 +4417,7 @@ dependencies = [ [[package]] name = "libcrux-ed25519" version = "0.0.5" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "libcrux-hacl-rs", "libcrux-macros", @@ -4429,7 +4429,7 @@ dependencies = [ [[package]] name = "libcrux-hacl-rs" version = "0.0.4" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "libcrux-macros", ] @@ -4437,7 +4437,7 @@ dependencies = [ [[package]] name = "libcrux-hkdf" version = "0.0.5" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "libcrux-hacl-rs", "libcrux-hmac", @@ -4447,7 +4447,7 @@ dependencies = [ [[package]] name = "libcrux-hmac" version = "0.0.5" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "libcrux-hacl-rs", "libcrux-macros", @@ -4457,7 +4457,7 @@ dependencies = [ [[package]] name = "libcrux-intrinsics" version = "0.0.5" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "core-models", "hax-lib", @@ -4466,7 +4466,7 @@ dependencies = [ [[package]] name = "libcrux-kem" version = "0.0.5" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "libcrux-curve25519", "libcrux-ecdh", @@ -4481,7 +4481,7 @@ dependencies = [ [[package]] name = "libcrux-macros" version = "0.0.3" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "quote", "syn 2.0.114", @@ -4490,7 +4490,7 @@ dependencies = [ [[package]] name = "libcrux-ml-dsa" version = "0.0.6" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "core-models", "hax-lib", @@ -4504,7 +4504,7 @@ dependencies = [ [[package]] name = "libcrux-ml-kem" version = "0.0.6" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "hax-lib", "libcrux-intrinsics", @@ -4519,7 +4519,7 @@ dependencies = [ [[package]] name = "libcrux-p256" version = "0.0.5" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "libcrux-hacl-rs", "libcrux-macros", @@ -4531,7 +4531,7 @@ dependencies = [ [[package]] name = "libcrux-platform" version = "0.0.3" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "libc", ] @@ -4539,7 +4539,7 @@ dependencies = [ [[package]] name = "libcrux-poly1305" version = "0.0.4" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "libcrux-hacl-rs", "libcrux-macros", @@ -4548,7 +4548,7 @@ dependencies = [ [[package]] name = "libcrux-psq" version = "0.0.6" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "classic-mceliece-rust", "libcrux-aesgcm", @@ -4570,7 +4570,7 @@ dependencies = [ [[package]] name = "libcrux-secrets" version = "0.0.5" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "hax-lib", ] @@ -4578,7 +4578,7 @@ dependencies = [ [[package]] name = "libcrux-sha2" version = "0.0.5" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "libcrux-hacl-rs", "libcrux-macros", @@ -4588,7 +4588,7 @@ dependencies = [ [[package]] name = "libcrux-sha3" version = "0.0.6" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "hax-lib", "libcrux-intrinsics", @@ -4599,7 +4599,7 @@ dependencies = [ [[package]] name = "libcrux-traits" version = "0.0.5" -source = "git+https://github.com/cryspen/libcrux#a09022c5811ca7fd1c6d9a239ff294d64ee86734" +source = "git+https://github.com/cryspen/libcrux#9533ca365760e56b5b41978332e4e87dc52cd2e8" dependencies = [ "libcrux-secrets", "rand 0.9.2", @@ -9345,9 +9345,9 @@ dependencies = [ [[package]] name = "psl" -version = "2.1.183" +version = "2.1.184" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4171658a0c9db483caa2dbd02dd4ade6574a23d7e3ff3483646f9b5e9dbd5b0" +checksum = "81dc6a90669f481b41cae3005c68efa36bef275b95aa9123a7af7f1c68c6e5b2" dependencies = [ "psl-types", ] @@ -13758,18 +13758,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.35" +version = "0.8.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdea86ddd5568519879b8187e1cf04e24fce28f7fe046ceecbce472ff19a2572" +checksum = "dafd85c832c1b68bbb4ec0c72c7f6f4fc5179627d2bc7c26b30e4c0cc11e76cc" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.35" +version = "0.8.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c15e1b46eff7c6c91195752e0eeed8ef040e391cdece7c25376957d5f15df22" +checksum = "7cb7e4e8436d9db52fbd6625dbf2f45243ab84994a72882ec8227b99e72b439a" dependencies = [ "proc-macro2", "quote", diff --git a/common/nym-kkt/src/carrier.rs b/common/nym-kkt/src/carrier.rs index 6f795f4c9f..43fb550b60 100644 --- a/common/nym-kkt/src/carrier.rs +++ b/common/nym-kkt/src/carrier.rs @@ -10,7 +10,7 @@ use crate::{ frame::KKT_SESSION_ID_LEN, }; -const MAX_PAYLOAD_LEN: usize = 65535; +const MAX_PAYLOAD_LEN: usize = 1_000_000; pub struct Carrier { tx_key: [u8; 32], @@ -228,7 +228,7 @@ mod tests { &mut r_context, i_frame_r.session_id(), responder_ed25519_keypair.private_key(), - &responder_kem_public_key, + &responder_kem_public_key.encode(), ) .unwrap(); @@ -258,7 +258,7 @@ mod tests { i_context.role(), &i_frame.session_id(), &responder_x25519_keypair.pk, - &i_obtained_key, + &i_obtained_key.encode(), ) .unwrap(); @@ -267,7 +267,7 @@ mod tests { r_context.role(), &r_frame.session_id(), &responder_x25519_keypair.pk, - &responder_kem_public_key, + &responder_kem_public_key.encode(), ) .unwrap(); diff --git a/common/nym-kkt/src/ciphersuite.rs b/common/nym-kkt/src/ciphersuite.rs index 1b86fa68dc..6eb6939b61 100644 --- a/common/nym-kkt/src/ciphersuite.rs +++ b/common/nym-kkt/src/ciphersuite.rs @@ -25,27 +25,27 @@ impl EncapsulationKey { } } -impl Clone for EncapsulationKey { - fn clone(&self) -> Self { - match self { - Self::MlKem768(arg0) => Self::MlKem768(arg0.clone()), - Self::XWing(arg0) => Self::XWing( - libcrux_kem::PublicKey::decode(Algorithm::XWingKemDraft06, &arg0.encode()).unwrap(), - ), - Self::X25519(arg0) => Self::X25519( - libcrux_kem::PublicKey::decode(Algorithm::X25519, &arg0.encode()).unwrap(), - ), - Self::McEliece(arg0) => { - let mut array = [0u8; mceliece::PUBLIC_KEY_LENGTH]; - array.clone_from_slice(arg0.as_ref()); +// impl Clone for EncapsulationKey { +// fn clone(&self) -> Self { +// match self { +// Self::MlKem768(arg0) => Self::MlKem768(arg0.clone()), +// Self::XWing(arg0) => Self::XWing( +// libcrux_kem::PublicKey::decode(Algorithm::XWingKemDraft06, &arg0.encode()).unwrap(), +// ), +// Self::X25519(arg0) => Self::X25519( +// libcrux_kem::PublicKey::decode(Algorithm::X25519, &arg0.encode()).unwrap(), +// ), +// Self::McEliece(arg0) => { +// let mut array = [0u8; mceliece::PUBLIC_KEY_LENGTH]; +// array.clone_from_slice(arg0.as_ref()); - Self::McEliece(libcrux_psq::classic_mceliece::PublicKey::from(Box::new( - array, - ))) - } - } - } -} +// Self::McEliece(libcrux_psq::classic_mceliece::PublicKey::from(Box::new( +// array, +// ))) +// } +// } +// } +// } impl Debug for EncapsulationKey { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { diff --git a/common/nym-kkt/src/lib.rs b/common/nym-kkt/src/lib.rs index 38e92315ec..775471de9e 100644 --- a/common/nym-kkt/src/lib.rs +++ b/common/nym-kkt/src/lib.rs @@ -118,7 +118,7 @@ mod test { &mut r_context, i_frame_r.session_id(), responder_ed25519_keypair.private_key(), - &responder_kem_public_key, + &responder_kem_public_key.encode(), ) .unwrap(); @@ -166,7 +166,7 @@ mod test { &mut r_context, i_frame_r.session_id(), responder_ed25519_keypair.private_key(), - &responder_kem_public_key, + &responder_kem_public_key.encode(), ) .unwrap(); @@ -215,7 +215,7 @@ mod test { &mut r_context, i_frame_r.session_id(), responder_ed25519_keypair.private_key(), - &responder_kem_public_key, + &responder_kem_public_key.encode(), ) .unwrap(); @@ -327,7 +327,7 @@ mod test { &mut r_context, i_frame_r.session_id(), responder_ed25519_keypair.private_key(), - &responder_kem_public_key, + &responder_kem_public_key.encode(), ) .unwrap(); @@ -388,7 +388,7 @@ mod test { &mut r_context, i_frame_r.session_id(), responder_ed25519_keypair.private_key(), - &responder_kem_public_key, + &responder_kem_public_key.encode(), ) .unwrap(); @@ -450,7 +450,7 @@ mod test { &mut r_context, i_frame_r.session_id(), responder_ed25519_keypair.private_key(), - &responder_kem_public_key, + &responder_kem_public_key.encode(), ) .unwrap(); diff --git a/common/nym-lp/src/codec.rs b/common/nym-lp/src/codec.rs index 231877a55e..136498ba3e 100644 --- a/common/nym-lp/src/codec.rs +++ b/common/nym-lp/src/codec.rs @@ -323,7 +323,7 @@ mod tests { use super::{OuterAeadKey, parse_lp_packet, serialize_lp_packet}; // Keep necessary imports use crate::LpError; - use crate::message::{EncryptedDataPayload, HandshakeData, LpMessage, MessageType}; + use crate::message::{EncryptedDataPayload, LpMessage, MessageType, PSQRequestData}; use crate::packet::{LpHeader, LpPacket, TRAILER_LEN}; use bytes::BytesMut; use nym_crypto::asymmetric::{ed25519, x25519}; @@ -378,7 +378,7 @@ mod tests { receiver_idx: 42, counter: 123, }, - message: LpMessage::Handshake(HandshakeData(payload.clone())), + message: LpMessage::PSQRequest(PSQRequestData(payload.clone())), trailer: [0; TRAILER_LEN], }; @@ -395,8 +395,8 @@ mod tests { // Verify message type and data match decoded.message { - LpMessage::Handshake(decoded_payload) => { - assert_eq!(decoded_payload, HandshakeData(payload)); + LpMessage::PSQRequest(decoded_payload) => { + assert_eq!(decoded_payload, PSQRequestData(payload)); } _ => panic!("Expected Handshake message"), } @@ -1055,7 +1055,7 @@ mod tests { receiver_idx: 99999, counter: 2, }, - message: LpMessage::Handshake(HandshakeData(handshake_data.clone())), + message: LpMessage::PSQRequest(PSQRequestData(handshake_data.clone())), trailer: [0; TRAILER_LEN], }; @@ -1065,7 +1065,7 @@ mod tests { let decoded = parse_lp_packet(&encrypted, Some(&outer_key)).unwrap(); match decoded.message { - LpMessage::Handshake(data) => { + LpMessage::PSQResponse(data) => { assert_eq!(data.0, handshake_data); } _ => panic!("Expected Handshake message"), diff --git a/common/nym-lp/src/lib.rs b/common/nym-lp/src/lib.rs index 7f520c85c7..e3324375fb 100644 --- a/common/nym-lp/src/lib.rs +++ b/common/nym-lp/src/lib.rs @@ -62,6 +62,7 @@ mod tests { use crate::session_manager::SessionManager; use crate::{LpError, kem_list, sessions_for_tests}; use bytes::BytesMut; + use nym_kkt::ciphersuite::{Ciphersuite, HashFunction, SignatureScheme}; // Import the new standalone functions use crate::codec::{parse_lp_packet, serialize_lp_packet}; @@ -171,13 +172,20 @@ mod tests { #[test] fn test_session_manager_integration() { // Create session manager - let local_manager = SessionManager::new(); - let remote_manager = SessionManager::new(); + let mut local_manager = SessionManager::new(); + let mut remote_manager = SessionManager::new(); for kem in kem_list() { // Generate Ed25519 keypairs for PSQ authentication let (init, resp) = mock_peers(kem); + let mut ciphersuite = Ciphersuite::resolve_ciphersuite( + kem, + HashFunction::Blake3, + SignatureScheme::Ed25519, + None, + ); + // Use fixed receiver_index for deterministic test let receiver_index: u32 = 54321; diff --git a/common/nym-lp/src/psq.rs b/common/nym-lp/src/psq.rs index 82e164c353..f77e9fff03 100644 --- a/common/nym-lp/src/psq.rs +++ b/common/nym-lp/src/psq.rs @@ -118,7 +118,7 @@ pub fn build_responder<'a>( .unwrap() } -pub fn responder_process<'a>( +pub fn psq_responder_process<'a>( responder: &'a mut Responder, initiator_message: &[u8], ) -> Vec { diff --git a/common/nym-lp/src/session.rs b/common/nym-lp/src/session.rs index 89944aec89..4cc473a057 100644 --- a/common/nym-lp/src/session.rs +++ b/common/nym-lp/src/session.rs @@ -17,12 +17,14 @@ use crate::noise_protocol::{NoiseError, NoiseProtocol, ReadResult}; use crate::packet::LpHeader; use crate::peer::{LpLocalPeer, LpRemotePeer}; use crate::psk::{ - derive_subsession_psk, psq_initiator_create_message, psq_responder_process_message, + derive_subsession_psk }; -use crate::psq::{build_initiator, build_responder, initiator_process}; +use crate::psq::{ + build_initiator, build_responder, initiator_process, psq_responder_process}; use crate::replay::ReceivingKeyCounterValidator; use crate::{LpError, LpMessage, LpPacket}; use libcrux_psq::v1::traits::PSQ; +use libcrux_psq::{Channel, IntoSession}; use rand09::rngs::ThreadRng; use libcrux_psq::{ @@ -104,19 +106,9 @@ pub enum KKTState { }, /// KKT exchange completed (initiator received and validated KEM key). - Completed { - /// Responder's KEM public key for PSQ encapsulation - kem_pk: Box, - - /// This can be used to send encrypted messages - carrier: Carrier, - }, - + Completed, /// Responder processed a KKT request and sent response. - ResponderProcessed { - /// This can be used to send encrypted messages - carrier: Carrier, - }, + ResponderProcessed, } impl std::fmt::Debug for KKTState { @@ -259,6 +251,13 @@ impl HandshakeState { }; Ok(psq_state) } + pub fn into_session(mut self) -> Session { + let HandshakeState::PSQ(mut psq_state) = self else { + panic!(); + } + psq_state.into_session() + + } } /// A session in the Lewes Protocol, handling connection state with Noise. @@ -778,9 +777,7 @@ impl LpSession { // Mark KKT as processed // Responder doesn't store the kem_pk since they already have their own KEM keypair - self.handshake_state = HandshakeState::KKT(KKTState::ResponderProcessed { - carrier: responder_carrier, - }); + self.carrier = Some(responder_carrier); Ok(LpMessage::KKTResponse(crate::message::KKTResponseData( response_bytes, @@ -802,7 +799,7 @@ impl LpSession { /// /// * `None` if no message needs to be sent currently (e.g., waiting for peer, or handshake complete). /// * `Some(LpError)` if there's an error within the Noise protocol or PSQ. - pub fn prepare_handshake_message(&mut self) -> Option> { + pub fn prepare_psq_request(&mut self) -> Option> { let state = self.handshake_state.psq_state_mut().expect("TODO error"); // PSQ always runs for initiator on first message @@ -861,149 +858,59 @@ impl LpSession { )))) } - /// Processes a received handshake message from the peer. - /// - /// This should be called by the driver/IO layer after receiving a potential - /// handshake message payload from an LP packet. - /// - /// For responders, PSQ always runs on the first message: - /// 1. Extracts PSQ payload from the first handshake message: [u16 len][psq_payload][noise_msg] - /// 2. Converts X25519 keys to DHKEM format - /// 3. Decapsulates PSK from PSQ payload - /// 4. Injects PSK into Noise HandshakeState - /// 5. Processes the remaining Noise handshake message - /// - /// # Arguments - /// - /// * `message` - The LP message received from the peer, expected to be a Handshake message. - /// - /// # Returns - /// - /// * `Ok(ReadResult)` detailing the outcome (e.g., handshake complete, no-op). - /// * `Err(LpError)` if the message is invalid or causes a Noise/PSQ protocol error. - pub fn process_handshake_message(&self, message: &LpMessage) -> Result { - todo!() - // let mut noise_state = self.noise_state.lock(); - // let mut psq_state = self.psq_state.lock(); - // - // match message { - // LpMessage::Handshake(HandshakeData(payload)) => { - // // PSQ always runs for responder on first message - // if !self.is_initiator && matches!(*psq_state, PSQState::ResponderWaiting) { - // // Extract PSQ payload: [u16 psq_len][psq_payload][noise_msg] - // if payload.len() < 2 { - // return Err(LpError::NoiseError(NoiseError::Other( - // "Payload too short for PSQ extraction".to_string(), - // ))); - // } - // - // let psq_len = u16::from_le_bytes([payload[0], payload[1]]) as usize; - // - // if payload.len() < 2 + psq_len { - // return Err(LpError::NoiseError(NoiseError::Other( - // "Payload length mismatch for PSQ extraction".to_string(), - // ))); - // } - // - // let psq_payload = &payload[2..2 + psq_len]; - // let noise_payload = &payload[2 + psq_len..]; - // - // let (dec_key, enc_key) = self.encapsulated_kem_keys()?; - // - // // Decapsulate PSK from PSQ payload using X25519 as DHKEM - // let session_context = self.id.to_le_bytes(); - // - // let psq_result = match psq_responder_process_message( - // self.psq_state.borrow_local_peer().x25519.sk(), - // &self.psq_state.borrow_remote_peer().x25519_public, - // (&dec_key, &enc_key), - // &self.psq_state.borrow_remote_peer().ed25519_public, - // psq_payload, - // &self.salt, - // &session_context, - // ) { - // Ok(result) => result, - // Err(e) => { - // tracing::error!("PSQ handshake processing failed, aborting: {:?}", e); - // return Err(e); - // } - // }; - // let psk = psq_result.psk; - // - // // Store PQ shared secret for subsession PSK derivation - // *self.pq_shared_secret.lock() = - // Some(PqSharedSecret::new(psq_result.pq_shared_secret)); - // - // // Store the PSK handle (ctxt_B) for transmission in next message - // { - // let mut psk_handle = self.psk_handle.lock(); - // *psk_handle = Some(psq_result.psk_handle); - // } - // - // // Inject PSK into Noise HandshakeState - // noise_state.set_psk(3, &psk)?; - // // Mark PSK as injected for safety checks in transport mode - // self.psk_injected.store(true, Ordering::Release); - // - // // Derive and store outer AEAD key from PSK - // { - // let mut outer_key = self.outer_aead_key.lock(); - // *outer_key = Some(OuterAeadKey::from_psk(&psk)); - // } - // - // // Update PSQ state to Completed - // *psq_state = PSQState::Completed { psk }; - // - // // Process the Noise handshake message (without PSQ prefix) - // drop(psq_state); // Release lock before processing - // return noise_state - // .read_message(noise_payload) - // .map_err(LpError::NoiseError); - // } - // - // // Check if initiator should extract PSK handle from message 2 - // if let PSQState::InitiatorWaiting { psk } = *psq_state - // && self.is_initiator - // { - // // Extract PSK handle: [u16 handle_len][handle_bytes][noise_msg] - // if payload.len() >= 2 { - // let handle_len = u16::from_le_bytes([payload[0], payload[1]]) as usize; - // - // if handle_len > 0 && payload.len() >= 2 + handle_len { - // // Extract and store the PSK handle - // let handle_bytes = &payload[2..2 + handle_len]; - // let noise_payload = &payload[2 + handle_len..]; - // - // tracing::debug!( - // "Extracted PSK handle ({} bytes) from message 2", - // handle_len - // ); - // - // { - // let mut psk_handle = self.psk_handle.lock(); - // *psk_handle = Some(handle_bytes.to_vec()); - // } - // - // // Transition to Completed - we've received confirmation from responder - // *psq_state = PSQState::Completed { psk }; - // drop(psq_state); - // - // // Process only the Noise message part - // return noise_state - // .read_message(noise_payload) - // .map_err(LpError::NoiseError); - // } - // } - // // If no valid handle found, fall through to normal processing - // } - // - // // The sans-io NoiseProtocol::read_message expects only the payload. - // noise_state - // .read_message(payload) - // .map_err(LpError::NoiseError) - // } - // _ => Err(LpError::NoiseError(NoiseError::IncorrectStateError)), - // } + pub fn process_psq_request(&mut self, message: &[u8]) -> Result { + let state = self.handshake_state.psq_state_mut().expect("TODO error"); + + if self.is_initiator || !matches!(state.borrow_state_bare(), PSQStateBare::ResponderWaiting) + { + panic!("not responder"); + } + + let mut responder = + build_responder(&self.base.local_peer.x25519, self.local_kem_keys().unwrap()); + + let psq_response = psq_responder_process(&mut responder, message); + + let encrypted_psq_response = self + .carrier + .as_ref() + .expect("carrier should have been set i guess") + .encrypt(&psq_response) + .unwrap(); + + self.psq_session = Mutex::new(Some(responder.into_session().unwrap())); + + Ok(LpMessage::PSQResponse(PSQResponseData( + encrypted_psq_response, + ))) + } + + pub fn process_psq_response(&mut self, message: &[u8]) -> Result<(), LpError> { + let state = self.handshake_state.psq_state_mut().expect("TODO error"); + + state.with_psq_state_mut(|state| match state { + PSQState::InitiatorWaiting { initiator } => { + // will move this elsewhere + initiator + .read_message(message, &mut []) + .expect("Failed to read message"); + } + _ => panic!("Not initiator waiting"), + }); + let session = state.with_psq_state_mut(|state| match state { + PSQState::InitiatorWaiting { initiator } => { + // will move this elsewhere + // initiator + // .read_message(message, &mut []) + // .expect("Failed to read message"); + + initiator + + } + _ => panic!("Not initiator waiting"), + }); + + Ok(()) } /// Checks if the Noise handshake phase is complete. @@ -1012,15 +919,6 @@ impl LpSession { // self.noise_state.lock().is_handshake_finished() } - /// Returns the PQ shared secret (K_pq) if available. - /// - /// This is the raw KEM output from PSQ before Blake3 KDF combination. - /// Used for deriving subsession PSKs to maintain PQ protection. - pub fn pq_shared_secret(&self) -> Option<[u8; 32]> { - todo!() - // self.pq_shared_secret.lock().as_ref().map(|s| *s.as_bytes()) - } - /// Gets the next subsession index and increments the counter. /// /// Each subsession requires a unique index to ensure unique PSK derivation. @@ -1141,9 +1039,7 @@ impl LpSession { .expect("Test KEM key conversion failed"); let kem_pk = EncapsulationKey::X25519(libcrux_public_key); - self.kkt_state = KKTState::Completed { - kem_pk: Box::new(kem_pk), - }; + self.kkt_state = KKTState::Completed; } // noiserm @@ -1500,7 +1396,7 @@ mod tests { } #[test] - fn test_prepare_handshake_message_initial_state() { + fn test_prepare_psq_request_initial_state() { let receiver_index = 12345u32; for kem in kem_list() { let initiator_session = create_handshake_test_session(kem, receiver_index, true); @@ -1512,7 +1408,7 @@ mod tests { ); // Initiator should have a message to send immediately (-> e) - let initiator_msg_result = initiator_session.prepare_handshake_message(); + let initiator_msg_result = initiator_session.prepare_psq_request(); assert!(initiator_msg_result.is_some()); let initiator_msg = initiator_msg_result .unwrap() @@ -1520,13 +1416,13 @@ mod tests { assert!(!initiator_msg.is_empty()); // Responder should have nothing to send initially (waits for <- e) - let responder_msg_result = responder_session.prepare_handshake_message(); + let responder_msg_result = responder_session.prepare_psq_request(); assert!(responder_msg_result.is_none()); } } #[test] - fn test_process_handshake_message_first_step() { + fn test_process_psq_request_first_step() { let receiver_index = 12345u32; for kem in kem_list() { @@ -1534,13 +1430,13 @@ mod tests { let responder_session = create_handshake_test_session(kem, receiver_index, false); // 1. Initiator prepares the first message (-> e) - let initiator_msg_result = initiator_session.prepare_handshake_message(); + let initiator_msg_result = initiator_session.prepare_psq_request(); let initiator_msg = initiator_msg_result .unwrap() .expect("Initiator msg prep failed"); // 2. Responder processes the message (<- e) - let process_result = responder_session.process_handshake_message(&initiator_msg); + let process_result = responder_session.process_psq_request(&initiator_msg); // Check the result of processing match process_result { @@ -1552,7 +1448,7 @@ mod tests { } // 3. After processing, responder should now have a message to send (-> e, es) - let responder_response_result = responder_session.prepare_handshake_message(); + let responder_response_result = responder_session.prepare_psq_request(); assert!(responder_response_result.is_some()); let responder_response = responder_response_result .unwrap() @@ -1573,7 +1469,7 @@ mod tests { // Start by priming the initiator message let mut initiator_to_responder_msg = - initiator_session.prepare_handshake_message().unwrap().ok(); + initiator_session.prepare_psq_request().unwrap().ok(); assert!( initiator_to_responder_msg.is_some(), "Initiator did not produce initial message" @@ -1585,16 +1481,14 @@ mod tests { // === Initiator -> Responder === if let Some(msg) = initiator_to_responder_msg.take() { // Process message - match responder_session.process_handshake_message(&msg) { + match responder_session.process_psq_request(&msg) { Ok(_) => {} Err(e) => panic!("Responder processing failed: {:?}", e), } // Check if responder needs to send a reply - responder_to_initiator_msg = responder_session - .prepare_handshake_message() - .transpose() - .unwrap(); + responder_to_initiator_msg = + responder_session.prepare_psq_request().transpose().unwrap(); } // Check completion after potentially processing responder's message below @@ -1607,16 +1501,14 @@ mod tests { // === Responder -> Initiator === if let Some(msg) = responder_to_initiator_msg.take() { // Process message - match initiator_session.process_handshake_message(&msg) { + match initiator_session.process_psq_request(&msg) { Ok(_) => {} Err(e) => panic!("Initiator processing failed: {:?}", e), } // Check if initiator needs to send a reply (should be last message in XK) - initiator_to_responder_msg = initiator_session - .prepare_handshake_message() - .transpose() - .unwrap(); + initiator_to_responder_msg = + initiator_session.prepare_psq_request().transpose().unwrap(); } // Check completion again after potentially processing initiator's message above @@ -1652,21 +1544,12 @@ mod tests { let responder_session = create_handshake_test_session(kem, 12345u32, false); // Drive handshake to completion (simplified loop from previous test) - let mut i_msg = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - responder_session.process_handshake_message(&i_msg).unwrap(); - let r_msg = responder_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - initiator_session.process_handshake_message(&r_msg).unwrap(); - i_msg = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - responder_session.process_handshake_message(&i_msg).unwrap(); + let mut i_msg = initiator_session.prepare_psq_request().unwrap().unwrap(); + responder_session.process_psq_request(&i_msg).unwrap(); + let r_msg = responder_session.prepare_psq_request().unwrap().unwrap(); + initiator_session.process_psq_request(&r_msg).unwrap(); + i_msg = initiator_session.prepare_psq_request().unwrap().unwrap(); + responder_session.process_psq_request(&i_msg).unwrap(); assert!(initiator_session.is_handshake_complete()); assert!(responder_session.is_handshake_complete()); @@ -1780,7 +1663,7 @@ mod tests { // Drive the handshake let mut i_msg = initiator_session - .prepare_handshake_message() + .prepare_psq_request() .expect("Initiator should have message") .expect("Message prep should succeed"); @@ -1795,26 +1678,26 @@ mod tests { // Responder processes message (which includes PSQ decapsulation) responder_session - .process_handshake_message(&i_msg) + .process_psq_request(&i_msg) .expect("Responder should process first message"); // Continue handshake let r_msg = responder_session - .prepare_handshake_message() + .prepare_psq_request() .expect("Responder should have message") .expect("Responder message prep should succeed"); initiator_session - .process_handshake_message(&r_msg) + .process_psq_request(&r_msg) .expect("Initiator should process responder message"); i_msg = initiator_session - .prepare_handshake_message() + .prepare_psq_request() .expect("Initiator should have final message") .expect("Final message prep should succeed"); responder_session - .process_handshake_message(&i_msg) + .process_psq_request(&i_msg) .expect("Responder should process final message"); // Verify handshake completed @@ -1870,7 +1753,7 @@ mod tests { // Prepare first message (initiator runs PSQ and injects PSK) let i_msg = initiator_session - .prepare_handshake_message() + .prepare_psq_request() .expect("Initiator should have message") .expect("Message prep should succeed"); @@ -1882,24 +1765,16 @@ mod tests { // Complete handshake responder_session - .process_handshake_message(&i_msg) + .process_psq_request(&i_msg) .expect("Responder should process message"); - let r_msg = responder_session - .prepare_handshake_message() - .unwrap() - .unwrap(); + let r_msg = responder_session.prepare_psq_request().unwrap().unwrap(); - initiator_session.process_handshake_message(&r_msg).unwrap(); + initiator_session.process_psq_request(&r_msg).unwrap(); - let final_msg = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); + let final_msg = initiator_session.prepare_psq_request().unwrap().unwrap(); - responder_session - .process_handshake_message(&final_msg) - .unwrap(); + responder_session.process_psq_request(&final_msg).unwrap(); // Test that encryption produces non-trivial ciphertext // (would fail if using dummy PSK incorrectly) @@ -1938,7 +1813,7 @@ mod tests { // Round 1: Initiator -> Responder (contains PSQ encapsulation) let msg1 = initiator_session - .prepare_handshake_message() + .prepare_psq_request() .expect("Initiator should prepare message") .expect("Message should succeed"); @@ -1946,29 +1821,29 @@ mod tests { assert!(!initiator_session.is_handshake_complete()); responder_session - .process_handshake_message(&msg1) + .process_psq_request(&msg1) .expect("Responder should process PSQ message"); assert!(!responder_session.is_handshake_complete()); // Round 2: Responder -> Initiator let msg2 = responder_session - .prepare_handshake_message() + .prepare_psq_request() .expect("Responder should prepare message") .expect("Message should succeed"); initiator_session - .process_handshake_message(&msg2) + .process_psq_request(&msg2) .expect("Initiator should process message"); // Round 3: Initiator -> Responder (final) let msg3 = initiator_session - .prepare_handshake_message() + .prepare_psq_request() .expect("Initiator should prepare final message") .expect("Message should succeed"); responder_session - .process_handshake_message(&msg3) + .process_psq_request(&msg3) .expect("Responder should process final message"); // Verify both sides completed @@ -2010,23 +1885,14 @@ mod tests { assert_eq!(initiator_session.id(), responder_session.id()); // Complete handshake - let msg1 = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - responder_session.process_handshake_message(&msg1).unwrap(); + let msg1 = initiator_session.prepare_psq_request().unwrap().unwrap(); + responder_session.process_psq_request(&msg1).unwrap(); - let msg2 = responder_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - initiator_session.process_handshake_message(&msg2).unwrap(); + let msg2 = responder_session.prepare_psq_request().unwrap().unwrap(); + initiator_session.process_psq_request(&msg2).unwrap(); - let msg3 = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - responder_session.process_handshake_message(&msg3).unwrap(); + let msg3 = initiator_session.prepare_psq_request().unwrap().unwrap(); + responder_session.process_psq_request(&msg3).unwrap(); // If Ed25519 authentication failed, handshake would not complete assert!(initiator_session.is_handshake_complete()); @@ -2052,7 +1918,7 @@ mod tests { let bad_message = LpMessage::Handshake(HandshakeData(corrupted_psq_data)); // Attempt to process corrupted message - should fail - let result = responder_session.process_handshake_message(&bad_message); + let result = responder_session.process_psq_request(&bad_message); // Should return error (PSQ deserialization will fail) assert!(result.is_err(), "Expected error for corrupted PSQ payload"); @@ -2094,12 +1960,12 @@ mod tests { // Initiator prepares message (should succeed - signing works) let msg1 = initiator_session - .prepare_handshake_message() + .prepare_psq_request() .expect("Initiator should prepare message") .expect("Initiator should have message"); // Responder processes message - should FAIL (signature verification fails) - let result = responder_session.process_handshake_message(&msg1); + let result = responder_session.process_psq_request(&msg1); // Should return CredError due to Ed25519 signature mismatch assert!( @@ -2137,14 +2003,11 @@ mod tests { responder_session.set_kkt_completed_for_test(&init.x25519.pk); // Initiator creates message with valid signature (signed with [1u8]) - let msg = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); + let msg = initiator_session.prepare_psq_request().unwrap().unwrap(); // Responder tries to verify with wrong public key [99u8] // This should fail Ed25519 signature verification - let result = responder_session.process_handshake_message(&msg); + let result = responder_session.process_psq_request(&msg); assert!(result.is_err(), "Expected signature verification to fail"); @@ -2171,7 +2034,7 @@ mod tests { let corrupted_message = LpMessage::Handshake(HandshakeData(vec![0xFF; 100])); // Process should fail - let result = responder_session.process_handshake_message(&corrupted_message); + let result = responder_session.process_psq_request(&corrupted_message); assert!(result.is_err()); // After error, session should still be in handshake mode (not complete) @@ -2181,13 +2044,10 @@ mod tests { // Create a proper initiator to send valid message let initiator_session = create_handshake_test_session(kem, 12345u32, true); - let valid_msg = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); + let valid_msg = initiator_session.prepare_psq_request().unwrap().unwrap(); // After the error, responder should still be able to process valid messages - let result2 = responder_session.process_handshake_message(&valid_msg); + let result2 = responder_session.process_psq_request(&valid_msg); // Should succeed (session state was not corrupted by previous error) assert!( @@ -2270,21 +2130,12 @@ mod tests { let responder_session = create_handshake_test_session(kem, 12345u32, false); // Drive handshake to completion - let i_msg = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - responder_session.process_handshake_message(&i_msg).unwrap(); - let r_msg = responder_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - initiator_session.process_handshake_message(&r_msg).unwrap(); - let i_msg = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - responder_session.process_handshake_message(&i_msg).unwrap(); + let i_msg = initiator_session.prepare_psq_request().unwrap().unwrap(); + responder_session.process_psq_request(&i_msg).unwrap(); + let r_msg = responder_session.prepare_psq_request().unwrap().unwrap(); + initiator_session.process_psq_request(&r_msg).unwrap(); + let i_msg = initiator_session.prepare_psq_request().unwrap().unwrap(); + responder_session.process_psq_request(&i_msg).unwrap(); assert!(initiator_session.is_handshake_complete()); @@ -2316,21 +2167,12 @@ mod tests { let responder_session = create_handshake_test_session(kem, 12345u32, false); // Drive handshake to completion - let i_msg = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - responder_session.process_handshake_message(&i_msg).unwrap(); - let r_msg = responder_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - initiator_session.process_handshake_message(&r_msg).unwrap(); - let i_msg = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - responder_session.process_handshake_message(&i_msg).unwrap(); + let i_msg = initiator_session.prepare_psq_request().unwrap().unwrap(); + responder_session.process_psq_request(&i_msg).unwrap(); + let r_msg = responder_session.prepare_psq_request().unwrap().unwrap(); + initiator_session.process_psq_request(&r_msg).unwrap(); + let i_msg = initiator_session.prepare_psq_request().unwrap().unwrap(); + responder_session.process_psq_request(&i_msg).unwrap(); assert!(initiator_session.is_handshake_complete()); assert!(responder_session.is_handshake_complete()); diff --git a/common/nym-lp/src/session_integration/mod.rs b/common/nym-lp/src/session_integration/mod.rs index 1de9f6ea7a..201c8192ad 100644 --- a/common/nym-lp/src/session_integration/mod.rs +++ b/common/nym-lp/src/session_integration/mod.rs @@ -94,7 +94,7 @@ mod tests { // Prime initiator's first message i_msg_payload = session_manager_1 - .prepare_handshake_message(peer_a_sm) + .prepare_psq_request(peer_a_sm) .transpose() .unwrap(); @@ -134,7 +134,7 @@ mod tests { .expect("B replay check failed (A->B)"); match session_manager_2 - .process_handshake_message(peer_b_sm, &decoded_packet.message) + .process_psq_request(peer_b_sm, &decoded_packet.message) { Ok(_) => { // Mark counter only after successful processing @@ -146,7 +146,7 @@ mod tests { } // Check if responder needs to send a reply r_msg_payload = session_manager_2 - .prepare_handshake_message(peer_b_sm) + .prepare_psq_request(peer_b_sm) .transpose() .unwrap(); println!("{:?}", r_msg_payload); @@ -187,7 +187,7 @@ mod tests { .expect("A replay check failed (B->A)"); match session_manager_1 - .process_handshake_message(peer_a_sm, &decoded_packet.message) + .process_psq_request(peer_a_sm, &decoded_packet.message) { Ok(_) => { // Mark counter only after successful processing @@ -200,7 +200,7 @@ mod tests { // Check if initiator needs to send a reply i_msg_payload = session_manager_1 - .prepare_handshake_message(peer_a_sm) + .prepare_psq_request(peer_a_sm) .transpose() .unwrap(); } @@ -518,36 +518,36 @@ mod tests { // Drive handshake to completion (simplified) let mut i_msg = session_manager_1 - .prepare_handshake_message(peer_a_sm) + .prepare_psq_request(peer_a_sm) .transpose() .unwrap() .unwrap(); session_manager_2 - .process_handshake_message(peer_b_sm, &i_msg) + .process_psq_request(peer_b_sm, &i_msg) .unwrap(); session_manager_2 .receiving_counter_mark(peer_b_sm, 0) .unwrap(); // Assume counter 0 for first msg let r_msg = session_manager_2 - .prepare_handshake_message(peer_b_sm) + .prepare_psq_request(peer_b_sm) .transpose() .unwrap() .unwrap(); session_manager_1 - .process_handshake_message(peer_a_sm, &r_msg) + .process_psq_request(peer_a_sm, &r_msg) .unwrap(); session_manager_1 .receiving_counter_mark(peer_a_sm, 0) .unwrap(); // Assume counter 0 for first msg i_msg = session_manager_1 - .prepare_handshake_message(peer_a_sm) + .prepare_psq_request(peer_a_sm) .transpose() .unwrap() .unwrap(); session_manager_2 - .process_handshake_message(peer_b_sm, &i_msg) + .process_psq_request(peer_b_sm, &i_msg) .unwrap(); session_manager_2 .receiving_counter_mark(peer_b_sm, 1) @@ -960,7 +960,7 @@ mod tests { // This might be the case if KKT completion doesn't automatically send the first Noise message // Let's try to prepare the handshake message if let Some(msg_result) = - session_manager_1.prepare_handshake_message(receiver_index) + session_manager_1.prepare_psq_request(receiver_index) { let msg = msg_result.expect("Failed to prepare handshake message after KKT"); diff --git a/common/nym-lp/src/session_manager.rs b/common/nym-lp/src/session_manager.rs index ecd7163e44..d16b39dd55 100644 --- a/common/nym-lp/src/session_manager.rs +++ b/common/nym-lp/src/session_manager.rs @@ -6,7 +6,6 @@ //! This module implements session lifecycle management functionality, handling //! creation, retrieval, and storage of sessions. -use crate::noise_protocol::ReadResult; use crate::peer::{LpLocalPeer, LpRemotePeer}; use crate::state_machine::{LpAction, LpInput, LpState, LpStateBare}; use crate::{LpError, LpMessage, LpSession, LpStateMachine}; @@ -104,11 +103,11 @@ impl SessionManager { } // pub fn start_handshake(& self, lp_id: u32) -> Option> { - // self.prepare_handshake_message(lp_id) + // self.prepare_psq_request(lp_id) // } // - // pub fn prepare_handshake_message(& self, lp_id: u32) -> Option> { - // self.with_state_machine(lp_id, |sm| sm.session().ok()?.prepare_handshake_message()) + // pub fn prepare_psq_request(& self, lp_id: u32) -> Option> { + // self.with_state_machine(lp_id, |sm| sm.session().ok()?.prepare_psq_request()) // .ok()? // } @@ -141,15 +140,15 @@ impl SessionManager { Ok(self.state_machine(lp_id)?.session()?.current_packet_cnt()) } - pub fn process_handshake_message( - &self, - lp_id: u32, - message: &LpMessage, - ) -> Result { - self.state_machine(lp_id)? - .session()? - .process_handshake_message(message) - } + // pub fn process_handshake_message( + // &self, + // lp_id: u32, + // message: &LpMessage, + // ) -> Result { + // self.state_machine(lp_id)? + // .session()? + // .process_handshake_message(message) + // } pub fn session_count(&self) -> usize { self.state_machines.len() diff --git a/common/nym-lp/src/state_machine.rs b/common/nym-lp/src/state_machine.rs index 6cd32add1e..035676b9e3 100644 --- a/common/nym-lp/src/state_machine.rs +++ b/common/nym-lp/src/state_machine.rs @@ -40,7 +40,7 @@ pub enum LpState { /// Actively performing the Noise handshake. /// (We might be able to merge this with ReadyToHandshake if the first step always happens) - Handshaking { session: Box }, // Kept for now, logic might merge later + PSQExchange { session: Box }, // Kept for now, logic might merge later /// Handshake complete, ready for data transport. Transport { session: Box }, @@ -80,7 +80,7 @@ impl From<&LpState> for LpStateBare { match state { LpState::ReadyToHandshake { .. } => LpStateBare::ReadyToHandshake, LpState::KKTExchange { .. } => LpStateBare::KKTExchange, - LpState::Handshaking { .. } => LpStateBare::Handshaking, + LpState::PSQExchange { .. } => LpStateBare::Handshaking, LpState::Transport { .. } => LpStateBare::Transport, LpState::SubsessionHandshaking { .. } => LpStateBare::SubsessionHandshaking, LpState::ReadOnlyTransport { .. } => LpStateBare::ReadOnlyTransport, @@ -117,7 +117,7 @@ pub enum LpAction { /// Inform the environment that KKT exchange completed successfully. KKTComplete, /// Inform the environment that the handshake is complete. - HandshakeComplete, + PSQComplete, /// Inform the environment that the connection is closed. ConnectionClosed, /// Subsession KK handshake initiated by this side. @@ -219,7 +219,7 @@ impl LpStateMachine { match &self.state { LpState::ReadyToHandshake { session } | LpState::KKTExchange { session } - | LpState::Handshaking { session } + | LpState::PSQExchange { session } | LpState::Transport { session } | LpState::SubsessionHandshaking { session, .. } | LpState::ReadOnlyTransport { session } => Ok(session), @@ -235,7 +235,7 @@ impl LpStateMachine { match self.state { LpState::ReadyToHandshake { session } | LpState::KKTExchange { session } - | LpState::Handshaking { session } + | LpState::PSQExchange { session } | LpState::Transport { session } | LpState::SubsessionHandshaking { session, .. } | LpState::ReadOnlyTransport { session } => Ok(*session), @@ -370,7 +370,7 @@ impl LpStateMachine { Ok(response_packet) => { result_action = Some(Ok(LpAction::SendPacket(response_packet))); // After KKT exchange, move to Handshaking - LpState::Handshaking { session } + LpState::PSQExchange { session } } Err(e) => { let reason = e.to_string(); @@ -391,7 +391,7 @@ impl LpStateMachine { Ok(()) => { result_action = Some(Ok(LpAction::KKTComplete)); // After successful KKT, move to Handshaking - LpState::Handshaking { session } + LpState::PSQExchange { session } } Err(e) => { let reason = e.to_string(); @@ -433,101 +433,91 @@ impl LpStateMachine { } // --- Handshaking State --- - (LpState::Handshaking { mut session }, LpInput::ReceivePacket(packet)) => { + (LpState::PSQExchange { mut session }, LpInput::ReceivePacket(packet)) => { // Check if packet lp_id matches our session if packet.header.receiver_idx() != session.id() { result_action = Some(Err(LpError::UnknownSessionId(packet.header.receiver_idx()))); // Don't change state, return the original state variant - LpState::Handshaking { session } + LpState::PSQExchange { session } } else { // --- Inline handle_handshake_packet logic --- // 1. Check replay protection *before* processing if let Err(e) = session.receiving_counter_quick_check(packet.header.counter) { let _reason = e.to_string(); result_action = Some(Err(e)); - LpState::Handshaking { session } + LpState::PSQExchange { session } // LpState::Closed { reason } } else { - // 2. Process the handshake message - match session.process_handshake_message(&packet.message) { - Ok(_) => { - // 3. Mark counter as received *after* successful processing - if let Err(e) = session.receiving_counter_mark(packet.header.counter) { - let _reason = e.to_string(); - result_action = Some(Err(e)); - // LpState::Closed { reason } - LpState::Handshaking { session } - } else { - // 4. First check if we need to send a handshake message (before checking completion) - match session.prepare_handshake_message() { - Some(Ok(message)) => { - match session.next_packet(message) { - Ok(response_packet) => { - result_action = Some(Ok(LpAction::SendPacket(response_packet))); - // Check if handshake became complete after preparing message - if session.is_handshake_complete() { - LpState::Transport { session } // Transition to Transport - } else { - LpState::Handshaking { session } // Remain Handshaking - } - } - Err(e) => { - let reason = e.to_string(); - result_action = Some(Err(e)); - LpState::Closed { reason } - } - } + match &packet.message { + LpMessage::PSQRequest(psq_request) if !session.is_initiator() => { + match session.process_psq_request(&psq_request.0) { + Ok(psq_response_message) => { + match session.next_packet(psq_response_message) { + Ok(psq_response_packet) => { + result_action = Some(Ok(LpAction::SendPacket(psq_response_packet))); + // PSQ Complete (Responder side) + LpState::Transport { session } } - Some(Err(e)) => { + Err(e) => { let reason = e.to_string(); result_action = Some(Err(e)); LpState::Closed { reason } } - None => { - // 5. No message to send - check if handshake is complete - if session.is_handshake_complete() { - result_action = Some(Ok(LpAction::HandshakeComplete)); - LpState::Transport { session } // Transition to Transport - } else { - // Handshake stalled unexpectedly - let err = LpError::NoiseError(NoiseError::Other( - "Handshake stalled unexpectedly".to_string(), - )); - let reason = err.to_string(); - result_action = Some(Err(err)); - LpState::Closed { reason } - } - } } } - } - Err(e) => { // Error from process_handshake_message - let reason = e.to_string(); - result_action = Some(Err(e)); - LpState::Closed { reason } + Err(e) => { + let reason = e.to_string(); + result_action = Some(Err(e)); + LpState::Closed { reason } + } } } + LpMessage::PSQResponse(psq_response) if session.is_initiator() => { + match session.process_psq_response(&psq_response.0) { + Ok(()) => { + result_action = Some(Ok(LpAction::PSQComplete)); + // PSQ Complete (Initiator side) + LpState::Transport { session } + } + Err(e) => { + let reason = e.to_string(); + result_action = Some(Err(e)); + LpState::Closed { reason } + } + } + } + _ => { + // Wrong message type for KKT state + let err = LpError::InvalidStateTransition { + state: "PSQExchange".to_string(), + input: format!("Unexpected message type: {:?}", packet.message), + }; + let reason = err.to_string(); + result_action = Some(Err(err)); + LpState::Closed { reason } + } + } } // --- End inline handle_handshake_packet logic --- } } // Reject SendData during handshake - (LpState::Handshaking { session }, LpInput::SendData(_)) => { // Keep session if returning to this state + (LpState::PSQExchange { session }, LpInput::SendData(_)) => { // Keep session if returning to this state result_action = Some(Err(LpError::InvalidStateTransition { state: "Handshaking".to_string(), input: "SendData".to_string(), })); // Invalid input, remain in Handshaking state - LpState::Handshaking { session } + LpState::PSQExchange { session } } // Reject StartHandshake if already handshaking - (LpState::Handshaking { session }, LpInput::StartHandshake) => { // Keep session + (LpState::PSQExchange { session }, LpInput::StartHandshake) => { // Keep session result_action = Some(Err(LpError::InvalidStateTransition { state: "Handshaking".to_string(), input: "StartHandshake".to_string(), })); // Invalid input, remain in Handshaking state - LpState::Handshaking { session } + LpState::PSQExchange { session } } // --- Transport State --- @@ -1048,7 +1038,7 @@ impl LpStateMachine { ( LpState::ReadyToHandshake { .. } // We consume the session here | LpState::KKTExchange { .. } - | LpState::Handshaking { .. } + | LpState::PSQExchange { .. } | LpState::Transport { .. } | LpState::SubsessionHandshaking { .. } | LpState::ReadOnlyTransport { .. }, @@ -1138,6 +1128,8 @@ mod tests { let receiver_index: u32 = 77777; + let ciphersuite = Ciphersuite::default(); + let initiator_sm = LpStateMachine::new(receiver_index, true, init.clone(), resp.as_remote(), &salt); assert!(initiator_sm.is_ok()); @@ -1235,7 +1227,7 @@ mod tests { panic!("Responder should send KKT response"); }; assert!( - matches!(responder.state, LpState::Handshaking { .. }), + matches!(responder.state, LpState::PSQExchange { .. }), "Responder should be Handshaking after KKT" ); @@ -1247,7 +1239,7 @@ mod tests { "Initiator should signal KKT complete" ); assert!( - matches!(initiator.state, LpState::Handshaking { .. }), + matches!(initiator.state, LpState::PSQExchange { .. }), "Initiator should be Handshaking after KKT" ); @@ -1262,7 +1254,7 @@ mod tests { // With KKT, we need the initiator to send the first Noise message now. // Initiator prepares and sends first Noise handshake message - let init_noise_msg = initiator.session().unwrap().prepare_handshake_message(); + let init_noise_msg = initiator.session().unwrap().prepare_psq_request(); let init_packet_1 = if let Some(Ok(msg)) = init_noise_msg { initiator.session().unwrap().next_packet(msg).unwrap() } else { @@ -1276,7 +1268,7 @@ mod tests { panic!("Responder should send packet 2"); }; assert!( - matches!(responder.state, LpState::Handshaking { .. }), + matches!(responder.state, LpState::PSQExchange { .. }), "Responder still Handshaking" ); assert_eq!( @@ -1305,7 +1297,7 @@ mod tests { println!("--- Step 7: Responder receives Noise msg 3, completes handshake ---"); let resp_actions_4 = responder.process_input(LpInput::ReceivePacket(init_packet_3)); assert!( - matches!(resp_actions_4, Some(Ok(LpAction::HandshakeComplete))), + matches!(resp_actions_4, Some(Ok(LpAction::PSQComplete))), "Responder should complete handshake" ); assert!( @@ -1451,14 +1443,14 @@ mod tests { panic!("Responder should send KKT response"); }; // After sending KKT response, responder moves to Handshaking - assert!(matches!(responder.state, LpState::Handshaking { .. })); + assert!(matches!(responder.state, LpState::PSQExchange { .. })); // Step 4: Initiator receives KKT response, completes KKT let init_action = initiator.process_input(LpInput::ReceivePacket(kkt_response_packet)); assert!(matches!(init_action, Some(Ok(LpAction::KKTComplete)))); // After KKT complete, initiator moves to Handshaking - assert!(matches!(initiator.state, LpState::Handshaking { .. })); + assert!(matches!(initiator.state, LpState::PSQExchange { .. })); } } #[test] @@ -1561,7 +1553,7 @@ mod tests { let noise1_msg = alice .session() .unwrap() - .prepare_handshake_message() + .prepare_psq_request() .unwrap() .unwrap(); let noise1_packet = alice.session().unwrap().next_packet(noise1_msg).unwrap();