use ::ring::hkdf;
use s2n_codec::{Encoder, EncoderBuffer};
use zeroize::Zeroize;
pub use ring::aead::NONCE_LEN;
pub struct Iv([u8; NONCE_LEN]);
impl Iv {
#[inline]
pub fn new(secret: &hkdf::Prk, label: &[u8]) -> Self {
let mut bytes = [0u8; NONCE_LEN];
secret
.expand(&[label], IvLen)
.expect("label size verified")
.fill(&mut bytes)
.expect("fill size verified");
Self(bytes)
}
#[inline]
pub fn nonce(&self, packet_number: u64) -> [u8; NONCE_LEN] {
let mut nonce = [0; NONCE_LEN];
let mut encoder = EncoderBuffer::new(&mut nonce);
encoder.encode(&0u32);
encoder.encode(&packet_number);
for (a, b) in nonce.iter_mut().zip(self.0.iter()) {
*a ^= b;
}
nonce
}
}
impl Zeroize for Iv {
#[inline]
fn zeroize(&mut self) {
self.0.zeroize()
}
}
struct IvLen;
impl hkdf::KeyType for IvLen {
#[inline]
fn len(&self) -> usize {
NONCE_LEN
}
}