From edf1fd4d69c482b68bd85b8a1e71f3f9466f1c65 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 11 Jan 2023 20:05:35 -0500 Subject: [PATCH] Implement max skip-ahead for counter, which is really about filtering bad packets. --- zssp/src/constants.rs | 6 ++++++ zssp/src/zssp.rs | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/zssp/src/constants.rs b/zssp/src/constants.rs index 73425d6ef..f38973cf1 100644 --- a/zssp/src/constants.rs +++ b/zssp/src/constants.rs @@ -78,6 +78,12 @@ pub(crate) const SESSION_ID_SIZE: usize = 6; /// Maximum difference between out-of-order incoming packet counters, and size of deduplication buffer. pub(crate) const COUNTER_WINDOW_MAX_OUT_OF_ORDER: usize = 16; +/// Maximum skip-ahead for counter. +/// +/// This is huge (2^24) because its real purpose is to filter out bad packets where decryption of +/// the counter yields an invalid value. +pub(crate) const COUNTER_WINDOW_MAX_SKIP_AHEAD: u64 = 16777216; + // Packet types can range from 0 to 15 (4 bits) -- 0-3 are defined and 4-15 are reserved for future use pub(crate) const PACKET_TYPE_DATA: u8 = 0; pub(crate) const PACKET_TYPE_INITIAL_KEY_OFFER: u8 = 1; // "alice" diff --git a/zssp/src/zssp.rs b/zssp/src/zssp.rs index 9e8410966..49cf71bb8 100644 --- a/zssp/src/zssp.rs +++ b/zssp/src/zssp.rs @@ -328,14 +328,16 @@ impl Session { /// Check the receive window without mutating state. #[inline(always)] fn check_receive_window(&self, counter: u64) -> bool { - self.receive_window[(counter as usize) % COUNTER_WINDOW_MAX_OUT_OF_ORDER].load(Ordering::Acquire) < counter + counter.wrapping_sub(self.receive_window[(counter as usize) % COUNTER_WINDOW_MAX_OUT_OF_ORDER].load(Ordering::Acquire)) + < COUNTER_WINDOW_MAX_SKIP_AHEAD } /// Update the receive window, returning true if the packet is still valid. /// This should only be called after the packet is authenticated. #[inline(always)] fn update_receive_window(&self, counter: u64) -> bool { - self.receive_window[(counter as usize) % COUNTER_WINDOW_MAX_OUT_OF_ORDER].fetch_max(counter, Ordering::AcqRel) < counter + counter.wrapping_sub(self.receive_window[(counter as usize) % COUNTER_WINDOW_MAX_OUT_OF_ORDER].fetch_max(counter, Ordering::AcqRel)) + < COUNTER_WINDOW_MAX_SKIP_AHEAD } }