pub fn pad_mac(buf: &mut alloc::vec::Vec<u8>) {
let rem = buf.len() % 16;
if rem == 0 {
return;
}
buf.push(0x80);
let need = 16 - ((rem + 1) % 16);
if need != 16 {
buf.extend(core::iter::repeat_n(0u8, need));
}
}
pub fn pad_data(buf: &mut alloc::vec::Vec<u8>) {
buf.push(0x80);
let rem = buf.len() % 16;
if rem != 0 {
buf.extend(core::iter::repeat_n(0u8, 16 - rem));
}
}
pub fn unpad_data(buf: &[u8]) -> Result<&[u8], crate::error::SecureSessionError> {
let mut i = buf.len();
while i > 0 {
i -= 1;
match buf[i] {
0x00 => continue,
0x80 => return Ok(&buf[..i]),
_ => return Err(crate::error::SecureSessionError::BadPadding),
}
}
Err(crate::error::SecureSessionError::BadPadding)
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::vec::Vec;
#[test]
fn mac_padding_skipped_when_aligned() {
let mut buf: Vec<u8> = (0..16).collect();
pad_mac(&mut buf);
assert_eq!(buf.len(), 16);
}
#[test]
fn mac_padding_when_unaligned() {
let mut buf: Vec<u8> = (0..3).collect();
pad_mac(&mut buf);
assert_eq!(buf.len(), 16);
assert_eq!(buf[3], 0x80);
assert!(buf[4..].iter().all(|&b| b == 0));
}
#[test]
fn data_padding_always_applied() {
let mut buf: Vec<u8> = (0..16).collect();
pad_data(&mut buf);
assert_eq!(buf.len(), 32);
assert_eq!(buf[16], 0x80);
}
#[test]
fn unpad_roundtrip() {
for n in 0..32usize {
let mut buf: Vec<u8> = (0..n as u8).collect();
let original = buf.clone();
pad_data(&mut buf);
let stripped = unpad_data(&buf).unwrap();
assert_eq!(stripped, original);
}
}
}