use crate::crypto::OneRttKey;
pub struct Key<K> {
key: K,
encrypted_packets: u64,
decrypted_packets: u64,
confidentiality_limit: u64,
}
#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
pub struct Limits {
pub key_update_window: u64,
}
impl Default for Limits {
fn default() -> Self {
Self {
key_update_window: KEY_UPDATE_WINDOW,
}
}
}
const KEY_UPDATE_WINDOW: u64 = 10_000;
impl<K: OneRttKey> Key<K> {
pub fn new(key: K) -> Self {
Key {
confidentiality_limit: key.aead_confidentiality_limit(),
key,
encrypted_packets: 0,
decrypted_packets: 0,
}
}
#[inline]
pub fn expired(&self) -> bool {
self.encrypted_packets >= self.confidentiality_limit
}
#[inline]
pub fn needs_update(&self, limits: &Limits) -> bool {
self.encrypted_packets
> (self
.confidentiality_limit
.saturating_sub(limits.key_update_window))
}
pub fn derive_next_key(&self) -> K {
self.key.derive_next_key()
}
#[inline]
pub fn encrypted_packets(&self) -> u64 {
self.encrypted_packets
}
#[inline]
pub fn on_packet_encryption(&mut self) {
self.encrypted_packets += 1;
}
#[inline]
pub fn on_packet_decryption(&mut self) {
self.decrypted_packets += 1;
}
#[inline]
pub fn key_mut(&mut self) -> &mut K {
&mut self.key
}
}