use crate::Error;
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum KeyCount {
Des(u8),
Aes(u8),
}
impl KeyCount {
pub fn as_u8<IoBackendErrorT>(&self) -> Result<u8, Error<IoBackendErrorT>> {
Ok(match self {
KeyCount::Des(v @ 1..=14) => *v,
KeyCount::Aes(v @ 1..=14) => *v | 0x80,
_ => return Err(Error::BadKeyId),
})
}
pub fn from_u8<IoBackendErrorT>(kc: u8) -> Result<Self, Error<IoBackendErrorT>> {
let count = kc & 0x0F;
let type_ = kc & 0xF0;
match (type_, count) {
(0x00, 1..=14) => Ok(Self::Des(count)),
(0x80, 1..=14) => Ok(Self::Aes(count)),
(0x00, _) => Err(Error::BadKeyId),
(0x80, _) => Err(Error::BadKeyId),
(_, _) => Err(Error::UnsupportedAlgorithm),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn every_des_count() {
for count_in in 1..=14 {
let count_out = KeyCount::Des(count_in).as_u8::<()>().unwrap();
assert_eq!(count_in, count_out);
}
for count_in in 15..=255 {
assert!(KeyCount::Des(count_in).as_u8::<()>().is_err());
}
}
#[test]
fn every_aes_count() {
for count_in in 1..=14 {
let count_out = KeyCount::Aes(count_in).as_u8::<()>().unwrap();
assert_eq!(count_in | 0x80, count_out);
}
for count_in in 15..=255 {
assert!(KeyCount::Aes(count_in).as_u8::<()>().is_err());
}
}
#[test]
fn every_aes_round_trip() {
for count_in in 1..=14 {
let count_in = count_in | 0x80;
let count = KeyCount::from_u8::<()>(count_in).unwrap();
let count_out = count.as_u8::<()>().unwrap();
assert_eq!(count_in, count_out);
}
for count_in in &[0, 15] {
let count_in = count_in | 0x80;
assert!(KeyCount::from_u8::<()>(count_in).is_err());
}
}
#[test]
fn every_des_round_trip() {
for count_in in 1..=14 {
let count = KeyCount::from_u8::<()>(count_in).unwrap();
let count_out = count.as_u8::<()>().unwrap();
assert_eq!(count_in, count_out);
}
for count_in in [0u8, 15] {
assert!(KeyCount::from_u8::<()>(count_in).is_err());
}
}
}