use {crate::Padding, docext::docext, std::fmt};
#[docext]
#[derive(Debug, Default)]
pub struct Pkcs7(());
impl Padding for Pkcs7 {
type Err = InvalidPadding;
fn pad(&self, mut data: Vec<u8>, n: usize) -> Vec<u8> {
if n >= 256 {
panic!("Pkcs7 does not work for block sizes >= 256");
}
let m = n - data.len() % n;
let m = if m == 0 { n } else { m };
data.resize(data.len() + m, m.try_into().unwrap());
data
}
fn unpad(&self, mut data: Vec<u8>, n: usize) -> Result<Vec<u8>, Self::Err> {
if n >= 256 {
panic!("Pkcs7 does not work for block sizes >= 256");
}
let m: usize = data
.last()
.ok_or(InvalidPadding)?
.to_owned()
.try_into()
.unwrap();
if m == 0 || m > n {
return Err(InvalidPadding);
}
let padding = &data[data.len() - m..];
if !padding.iter().all(|&b| usize::try_from(b).unwrap() == m) {
return Err(InvalidPadding);
}
data.truncate(data.len() - m);
Ok(data)
}
}
#[derive(Debug)]
pub struct InvalidPadding;
impl fmt::Display for InvalidPadding {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("invalid padding")
}
}