use super::mac::{ClusterMac, Mac};
use super::{Authenticator, WIRE_VERSION};
use crate::replay::{Seq, Stamp, REPLAY_HEADER_LEN};
fn encode_replay_header(seq: Seq, stamp: Stamp) -> [u8; REPLAY_HEADER_LEN] {
let mut header = [0u8; REPLAY_HEADER_LEN];
header[..8].copy_from_slice(&seq.to_le_bytes());
header[8..].copy_from_slice(&stamp.to_le_bytes());
header
}
impl Authenticator {
pub fn seal(&self, seq: Seq, stamp: Stamp, payload: &[u8]) -> Vec<u8> {
match self {
Authenticator::Disabled => {
let mut framed = Vec::with_capacity(super::VERSION_LEN + payload.len());
framed.push(WIRE_VERSION);
framed.extend_from_slice(payload);
framed
}
Authenticator::Enabled(keys) => {
let header = encode_replay_header(seq, stamp);
let mut protected =
Vec::with_capacity(REPLAY_HEADER_LEN + super::VERSION_LEN + payload.len());
protected.extend_from_slice(&header);
protected.push(WIRE_VERSION);
protected.extend_from_slice(payload);
let tag = ClusterMac::tag(&keys.primary, &protected);
let mut framed = Vec::with_capacity(super::TAG_LEN + protected.len());
framed.extend_from_slice(tag.as_bytes());
framed.extend_from_slice(&protected);
framed
}
#[cfg(feature = "encryption")]
Authenticator::Encrypted(keys) => {
let header = encode_replay_header(seq, stamp);
let mut plaintext =
Vec::with_capacity(REPLAY_HEADER_LEN + super::VERSION_LEN + payload.len());
plaintext.extend_from_slice(&header);
plaintext.push(WIRE_VERSION);
plaintext.extend_from_slice(payload);
super::encryption::seal(&keys.primary, &plaintext)
}
}
}
}