Implement max skip-ahead for counter, which is really about filtering bad packets.

This commit is contained in:
Adam Ierymenko 2023-01-11 20:05:35 -05:00
parent 2479645341
commit edf1fd4d69
2 changed files with 10 additions and 2 deletions

View file

@ -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"

View file

@ -328,14 +328,16 @@ impl<Application: ApplicationLayer> Session<Application> {
/// 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
}
}