this will become stale

This commit is contained in:
Georgio Nicolas
2026-02-06 22:39:45 +01:00
parent c385d14342
commit 064718a75a
11 changed files with 305 additions and 464 deletions
Generated
+36 -36
View File
@@ -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",
+4 -4
View File
@@ -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();
+20 -20
View File
@@ -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 {
+6 -6
View File
@@ -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();
+6 -6
View File
@@ -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"),
+10 -2
View File
@@ -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;
+1 -1
View File
@@ -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<ThreadRng>,
initiator_message: &[u8],
) -> Vec<u8> {
+133 -291
View File
@@ -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<EncapsulationKey>,
/// 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<Result<LpMessage, LpError>> {
pub fn prepare_psq_request(&mut self) -> Option<Result<LpMessage, LpError>> {
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<ReadResult, LpError> {
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<LpMessage, LpError> {
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());
+12 -12
View File
@@ -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");
+12 -13
View File
@@ -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<Result<LpMessage, LpError>> {
// self.prepare_handshake_message(lp_id)
// self.prepare_psq_request(lp_id)
// }
//
// pub fn prepare_handshake_message(& self, lp_id: u32) -> Option<Result<LpMessage, LpError>> {
// self.with_state_machine(lp_id, |sm| sm.session().ok()?.prepare_handshake_message())
// pub fn prepare_psq_request(& self, lp_id: u32) -> Option<Result<LpMessage, LpError>> {
// 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<ReadResult, LpError> {
self.state_machine(lp_id)?
.session()?
.process_handshake_message(message)
}
// pub fn process_handshake_message(
// &self,
// lp_id: u32,
// message: &LpMessage,
// ) -> Result<ReadResult, LpError> {
// self.state_machine(lp_id)?
// .session()?
// .process_handshake_message(message)
// }
pub fn session_count(&self) -> usize {
self.state_machines.len()
+65 -73
View File
@@ -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<LpSession> }, // Kept for now, logic might merge later
PSQExchange { session: Box<LpSession> }, // Kept for now, logic might merge later
/// Handshake complete, ready for data transport.
Transport { session: Box<LpSession> },
@@ -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();