1pub fn pad_mac(buf: &mut alloc::vec::Vec<u8>) {
12 let rem = buf.len() % 16;
13 if rem == 0 {
14 return;
15 }
16 buf.push(0x80);
17 let need = 16 - ((rem + 1) % 16);
18 if need != 16 {
19 buf.extend(core::iter::repeat_n(0u8, need));
20 }
21}
22
23pub fn pad_data(buf: &mut alloc::vec::Vec<u8>) {
25 buf.push(0x80);
26 let rem = buf.len() % 16;
27 if rem != 0 {
28 buf.extend(core::iter::repeat_n(0u8, 16 - rem));
29 }
30}
31
32pub fn unpad_data(buf: &[u8]) -> Result<&[u8], crate::error::SecureSessionError> {
36 let mut i = buf.len();
37 while i > 0 {
38 i -= 1;
39 match buf[i] {
40 0x00 => continue,
41 0x80 => return Ok(&buf[..i]),
42 _ => return Err(crate::error::SecureSessionError::BadPadding),
43 }
44 }
45 Err(crate::error::SecureSessionError::BadPadding)
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51 use alloc::vec::Vec;
52
53 #[test]
54 fn mac_padding_skipped_when_aligned() {
55 let mut buf: Vec<u8> = (0..16).collect();
56 pad_mac(&mut buf);
57 assert_eq!(buf.len(), 16);
58 }
59
60 #[test]
61 fn mac_padding_when_unaligned() {
62 let mut buf: Vec<u8> = (0..3).collect();
63 pad_mac(&mut buf);
64 assert_eq!(buf.len(), 16);
65 assert_eq!(buf[3], 0x80);
66 assert!(buf[4..].iter().all(|&b| b == 0));
67 }
68
69 #[test]
70 fn data_padding_always_applied() {
71 let mut buf: Vec<u8> = (0..16).collect();
72 pad_data(&mut buf);
73 assert_eq!(buf.len(), 32);
74 assert_eq!(buf[16], 0x80);
75 }
76
77 #[test]
78 fn unpad_roundtrip() {
79 for n in 0..32usize {
80 let mut buf: Vec<u8> = (0..n as u8).collect();
81 let original = buf.clone();
82 pad_data(&mut buf);
83 let stripped = unpad_data(&buf).unwrap();
84 assert_eq!(stripped, original);
85 }
86 }
87}