From 227c1bd7e8455220c2abe8e85f367a364c4a3185 Mon Sep 17 00:00:00 2001 From: Lars Eggert Date: Tue, 11 Feb 2025 09:26:55 +0200 Subject: [PATCH] `CryptoSpace` -> `Epoch` --- neqo-crypto/src/constants.rs | 5 +- neqo-transport/src/connection/mod.rs | 13 ++--- neqo-transport/src/connection/saved.rs | 20 +++---- neqo-transport/src/crypto.rs | 81 ++++++++++++-------------- neqo-transport/src/lib.rs | 4 +- neqo-transport/src/packet/mod.rs | 18 +++--- 6 files changed, 66 insertions(+), 75 deletions(-) diff --git a/neqo-crypto/src/constants.rs b/neqo-crypto/src/constants.rs index dae759f768..5ce615faee 100644 --- a/neqo-crypto/src/constants.rs +++ b/neqo-crypto/src/constants.rs @@ -4,8 +4,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![allow(dead_code)] - use enum_map::Enum; use crate::{ssl, Error}; @@ -15,7 +13,7 @@ use crate::{ssl, Error}; pub type Alert = u8; -#[derive(Default, Debug, Enum, Clone, Copy, PartialEq, Eq)] +#[derive(Default, Debug, Enum, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum Epoch { // TLS doesn't really have an "initial" concept that maps to QUIC so directly, // but this should be clear enough. @@ -74,6 +72,7 @@ remap_enum! { } } +#[allow(dead_code)] mod ciphers { include!(concat!(env!("OUT_DIR"), "/nss_ciphers.rs")); } diff --git a/neqo-transport/src/connection/mod.rs b/neqo-transport/src/connection/mod.rs index 20f12152cb..ee4488b94b 100644 --- a/neqo-transport/src/connection/mod.rs +++ b/neqo-transport/src/connection/mod.rs @@ -37,7 +37,7 @@ use crate::{ ConnectionId, ConnectionIdEntry, ConnectionIdGenerator, ConnectionIdManager, ConnectionIdRef, ConnectionIdStore, LOCAL_ACTIVE_CID_LIMIT, }, - crypto::{Crypto, CryptoDxState, CryptoSpace}, + crypto::{Crypto, CryptoDxState, Epoch}, ecn, events::{ConnectionEvent, ConnectionEvents, OutgoingDatagramOutcome}, frame::{ @@ -1292,7 +1292,7 @@ impl Connection { #[allow(clippy::needless_pass_by_value)] // To consume an owned datagram below. fn save_datagram( &mut self, - cspace: CryptoSpace, + cspace: Epoch, d: Datagram>, remaining: usize, now: Instant, @@ -1673,7 +1673,7 @@ impl Connection { // This was a valid-appearing Initial packet: maybe probe with // a Handshake packet to keep the handshake moving. self.received_untracked |= - self.role == Role::Client && cspace == CryptoSpace::Initial; + self.role == Role::Client && cspace == Epoch::Initial; } _ => (), } @@ -2060,7 +2060,7 @@ impl Connection { fn build_packet_header( path: &Path, - cspace: CryptoSpace, + cspace: Epoch, encoder: Encoder, tx: &CryptoDxState, address_validation: &AddressValidationInfo, @@ -2876,7 +2876,7 @@ impl Connection { // server can rely on implicit acknowledgment. self.discard_keys(PacketNumberSpace::Initial, now); } - self.saved_datagrams.make_available(CryptoSpace::Handshake); + self.saved_datagrams.make_available(Epoch::Handshake); } } @@ -3245,8 +3245,7 @@ impl Connection { self.process_tps(now)?; self.set_state(State::Connected, now); self.create_resumption_token(now); - self.saved_datagrams - .make_available(CryptoSpace::ApplicationData); + self.saved_datagrams.make_available(Epoch::ApplicationData); self.stats.borrow_mut().resumed = self .crypto .tls diff --git a/neqo-transport/src/connection/saved.rs b/neqo-transport/src/connection/saved.rs index d5e0313e52..2900cae95c 100644 --- a/neqo-transport/src/connection/saved.rs +++ b/neqo-transport/src/connection/saved.rs @@ -8,7 +8,7 @@ use std::{mem, time::Instant}; use neqo_common::{qdebug, qinfo, Datagram}; -use crate::crypto::CryptoSpace; +use crate::crypto::Epoch; /// The number of datagrams that are saved during the handshake when /// keys to decrypt them are not yet available. @@ -25,19 +25,19 @@ pub struct SavedDatagram { pub struct SavedDatagrams { handshake: Vec, application_data: Vec, - available: Option, + available: Option, } impl SavedDatagrams { - fn store(&mut self, cspace: CryptoSpace) -> &mut Vec { + fn store(&mut self, cspace: Epoch) -> &mut Vec { match cspace { - CryptoSpace::Handshake => &mut self.handshake, - CryptoSpace::ApplicationData => &mut self.application_data, + Epoch::Handshake => &mut self.handshake, + Epoch::ApplicationData => &mut self.application_data, _ => panic!("unexpected space"), } } - pub fn save(&mut self, cspace: CryptoSpace, d: Datagram, t: Instant) { + pub fn save(&mut self, cspace: Epoch, d: Datagram, t: Instant) { let store = self.store(cspace); if store.len() < MAX_SAVED_DATAGRAMS { @@ -48,15 +48,15 @@ impl SavedDatagrams { } } - pub fn make_available(&mut self, cspace: CryptoSpace) { - debug_assert_ne!(cspace, CryptoSpace::ZeroRtt); - debug_assert_ne!(cspace, CryptoSpace::Initial); + pub fn make_available(&mut self, cspace: Epoch) { + debug_assert_ne!(cspace, Epoch::ZeroRtt); + debug_assert_ne!(cspace, Epoch::Initial); if !self.store(cspace).is_empty() { self.available = Some(cspace); } } - pub const fn available(&self) -> Option { + pub const fn available(&self) -> Option { self.available } diff --git a/neqo-transport/src/crypto.rs b/neqo-transport/src/crypto.rs index dbcc21dab1..64bad78d7b 100644 --- a/neqo-transport/src/crypto.rs +++ b/neqo-transport/src/crypto.rs @@ -17,8 +17,9 @@ use std::{ }; use neqo_common::{hex, hex_snip_middle, qdebug, qinfo, qtrace, Encoder, Role}; +pub use neqo_crypto::Epoch; use neqo_crypto::{ - hkdf, hp::HpKey, Aead, Agent, AntiReplay, Cipher, Epoch, Error as CryptoError, HandshakeState, + hkdf, hp::HpKey, Aead, Agent, AntiReplay, Cipher, Error as CryptoError, HandshakeState, PrivateKey, PublicKey, Record, RecordList, ResumptionToken, SymKey, ZeroRttChecker, TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256, TLS_CT_HANDSHAKE, TLS_GRP_EC_SECP256R1, TLS_GRP_EC_SECP384R1, TLS_GRP_EC_SECP521R1, TLS_GRP_EC_X25519, @@ -792,14 +793,6 @@ impl CryptoDxAppData { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub enum CryptoSpace { - Initial, - ZeroRtt, - Handshake, - ApplicationData, -} - /// All of the keying material needed for a connection. /// /// Note that the methods on this struct take a version but those are only ever @@ -827,19 +820,19 @@ impl CryptoStates { &mut self, version: Version, space: PacketNumberSpace, - ) -> Option<(CryptoSpace, &mut CryptoDxState)> { + ) -> Option<(Epoch, &mut CryptoDxState)> { match space { PacketNumberSpace::Initial => self - .tx_mut(version, CryptoSpace::Initial) - .map(|dx| (CryptoSpace::Initial, dx)), + .tx_mut(version, Epoch::Initial) + .map(|dx| (Epoch::Initial, dx)), PacketNumberSpace::Handshake => self - .tx_mut(version, CryptoSpace::Handshake) - .map(|dx| (CryptoSpace::Handshake, dx)), + .tx_mut(version, Epoch::Handshake) + .map(|dx| (Epoch::Handshake, dx)), PacketNumberSpace::ApplicationData => { if let Some(app) = self.app_write.as_mut() { - Some((CryptoSpace::ApplicationData, &mut app.dx)) + Some((Epoch::ApplicationData, &mut app.dx)) } else { - self.zero_rtt.as_mut().map(|dx| (CryptoSpace::ZeroRtt, dx)) + self.zero_rtt.as_mut().map(|dx| (Epoch::ZeroRtt, dx)) } } } @@ -848,30 +841,30 @@ impl CryptoStates { pub fn tx_mut<'a>( &'a mut self, version: Version, - cspace: CryptoSpace, + cspace: Epoch, ) -> Option<&'a mut CryptoDxState> { let tx = |k: Option<&'a mut CryptoState>| k.map(|dx| &mut dx.tx); match cspace { - CryptoSpace::Initial => tx(self.initials.get_mut(&version)), - CryptoSpace::ZeroRtt => self + Epoch::Initial => tx(self.initials.get_mut(&version)), + Epoch::ZeroRtt => self .zero_rtt .as_mut() .filter(|z| z.direction == CryptoDxDirection::Write), - CryptoSpace::Handshake => tx(self.handshake.as_mut()), - CryptoSpace::ApplicationData => self.app_write.as_mut().map(|app| &mut app.dx), + Epoch::Handshake => tx(self.handshake.as_mut()), + Epoch::ApplicationData => self.app_write.as_mut().map(|app| &mut app.dx), } } - pub fn tx<'a>(&'a self, version: Version, cspace: CryptoSpace) -> Option<&'a CryptoDxState> { + pub fn tx<'a>(&'a self, version: Version, cspace: Epoch) -> Option<&'a CryptoDxState> { let tx = |k: Option<&'a CryptoState>| k.map(|dx| &dx.tx); match cspace { - CryptoSpace::Initial => tx(self.initials.get(&version)), - CryptoSpace::ZeroRtt => self + Epoch::Initial => tx(self.initials.get(&version)), + Epoch::ZeroRtt => self .zero_rtt .as_ref() .filter(|z| z.direction == CryptoDxDirection::Write), - CryptoSpace::Handshake => tx(self.handshake.as_ref()), - CryptoSpace::ApplicationData => self.app_write.as_ref().map(|app| &app.dx), + Epoch::Handshake => tx(self.handshake.as_ref()), + Epoch::ApplicationData => self.app_write.as_ref().map(|app| &app.dx), } } @@ -879,23 +872,23 @@ impl CryptoStates { &self, version: Version, space: PacketNumberSpace, - ) -> Option<(CryptoSpace, &CryptoDxState)> { + ) -> Option<(Epoch, &CryptoDxState)> { match space { PacketNumberSpace::Initial => self - .tx(version, CryptoSpace::Initial) - .map(|dx| (CryptoSpace::Initial, dx)), + .tx(version, Epoch::Initial) + .map(|dx| (Epoch::Initial, dx)), PacketNumberSpace::Handshake => self - .tx(version, CryptoSpace::Handshake) - .map(|dx| (CryptoSpace::Handshake, dx)), + .tx(version, Epoch::Handshake) + .map(|dx| (Epoch::Handshake, dx)), PacketNumberSpace::ApplicationData => self.app_write.as_ref().map_or_else( - || self.zero_rtt.as_ref().map(|dx| (CryptoSpace::ZeroRtt, dx)), - |app| Some((CryptoSpace::ApplicationData, &app.dx)), + || self.zero_rtt.as_ref().map(|dx| (Epoch::ZeroRtt, dx)), + |app| Some((Epoch::ApplicationData, &app.dx)), ), } } - pub fn rx_hp(&mut self, version: Version, cspace: CryptoSpace) -> Option<&mut CryptoDxState> { - if cspace == CryptoSpace::ApplicationData { + pub fn rx_hp(&mut self, version: Version, cspace: Epoch) -> Option<&mut CryptoDxState> { + if cspace == Epoch::ApplicationData { self.app_read.as_mut().map(|ar| &mut ar.dx) } else { self.rx(version, cspace, false) @@ -905,18 +898,18 @@ impl CryptoStates { pub fn rx<'a>( &'a mut self, version: Version, - cspace: CryptoSpace, + cspace: Epoch, key_phase: bool, ) -> Option<&'a mut CryptoDxState> { let rx = |x: Option<&'a mut CryptoState>| x.map(|dx| &mut dx.rx); match cspace { - CryptoSpace::Initial => rx(self.initials.get_mut(&version)), - CryptoSpace::ZeroRtt => self + Epoch::Initial => rx(self.initials.get_mut(&version)), + Epoch::ZeroRtt => self .zero_rtt .as_mut() .filter(|z| z.direction == CryptoDxDirection::Read), - CryptoSpace::Handshake => rx(self.handshake.as_mut()), - CryptoSpace::ApplicationData => { + Epoch::Handshake => rx(self.handshake.as_mut()), + Epoch::ApplicationData => { let f = |a: Option<&'a mut CryptoDxAppData>| { a.filter(|ar| ar.dx.key_phase() == key_phase) }; @@ -936,11 +929,11 @@ impl CryptoStates { /// is possible to attribute 0-RTT packets to an existing connection if there /// is a multi-packet Initial, that is an unusual circumstance, so we /// don't do caching for that in those places that call this function. - pub fn rx_pending(&self, space: CryptoSpace) -> bool { + pub fn rx_pending(&self, space: Epoch) -> bool { match space { - CryptoSpace::Initial | CryptoSpace::ZeroRtt => false, - CryptoSpace::Handshake => self.handshake.is_none() && !self.initials.is_empty(), - CryptoSpace::ApplicationData => self.app_read.is_none(), + Epoch::Initial | Epoch::ZeroRtt => false, + Epoch::Handshake => self.handshake.is_none() && !self.initials.is_empty(), + Epoch::ApplicationData => self.app_read.is_none(), } } diff --git a/neqo-transport/src/lib.rs b/neqo-transport/src/lib.rs index d157f04300..e9c8ac2dee 100644 --- a/neqo-transport/src/lib.rs +++ b/neqo-transport/src/lib.rs @@ -118,12 +118,12 @@ pub enum Error { InvalidResumptionToken, InvalidRetry, InvalidStreamId, - KeysDiscarded(crypto::CryptoSpace), + KeysDiscarded(crypto::Epoch), /// Packet protection keys are exhausted. /// Also used when too many key updates have happened. KeysExhausted, /// Packet protection keys aren't available yet for the identified space. - KeysPending(crypto::CryptoSpace), + KeysPending(crypto::Epoch), /// An attempt to update keys can be blocked if /// a packet sent with the current keys hasn't been acknowledged. KeyUpdateBlocked, diff --git a/neqo-transport/src/packet/mod.rs b/neqo-transport/src/packet/mod.rs index ad3b634280..700cc29eb7 100644 --- a/neqo-transport/src/packet/mod.rs +++ b/neqo-transport/src/packet/mod.rs @@ -19,7 +19,7 @@ use neqo_crypto::random; use crate::{ cid::{ConnectionId, ConnectionIdDecoder, ConnectionIdRef, MAX_CONNECTION_ID_LEN}, - crypto::{CryptoDxState, CryptoSpace, CryptoStates}, + crypto::{CryptoDxState, CryptoStates, Epoch}, frame::FRAME_TYPE_PADDING, recovery::SendProfile, version::{Version, WireVersion}, @@ -89,7 +89,7 @@ impl PacketType { } #[allow(clippy::fallible_impl_from)] -impl From for CryptoSpace { +impl From for Epoch { fn from(v: PacketType) -> Self { match v { PacketType::Initial => Self::Initial, @@ -101,13 +101,13 @@ impl From for CryptoSpace { } } -impl From for PacketType { - fn from(cs: CryptoSpace) -> Self { +impl From for PacketType { + fn from(cs: Epoch) -> Self { match cs { - CryptoSpace::Initial => Self::Initial, - CryptoSpace::ZeroRtt => Self::ZeroRtt, - CryptoSpace::Handshake => Self::Handshake, - CryptoSpace::ApplicationData => Self::Short, + Epoch::Initial => Self::Initial, + Epoch::ZeroRtt => Self::ZeroRtt, + Epoch::Handshake => Self::Handshake, + Epoch::ApplicationData => Self::Short, } } } @@ -864,7 +864,7 @@ impl<'a> PublicPacket<'a> { crypto: &mut CryptoStates, release_at: Instant, ) -> Res { - let cspace: CryptoSpace = self.packet_type.into(); + let cspace: Epoch = self.packet_type.into(); // When we don't have a version, the crypto code doesn't need a version // for lookup, so use the default, but fix it up if decryption succeeds. let version = self.version().unwrap_or_default();