use super::block;
use crate::crypto::cipher::Block;
pub const BLOCK_SIZE: usize = 16;
pub struct Cipher {
enc: Vec<u32>,
dec: Vec<u32>,
}
#[derive(Debug)]
pub struct KeySizeError(usize);
impl std::fmt::Display for KeySizeError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "crypto/aes: invalid key size: {}", self.0)
}
}
fn new_cipher_generic(key: &[u8]) -> Cipher {
let n = key.len() + 28;
let mut c = Cipher {
enc: vec![0; n],
dec: vec![0; n],
};
super::block::expand_key_go(key, &mut c.enc, &mut c.dec);
c
}
impl Cipher {
pub fn new(key: &[u8]) -> Result<Cipher, KeySizeError> {
let k = key.len();
match k {
16 | 24 | 32 => {}
_ => return Err(KeySizeError(k)),
};
Ok(new_cipher_generic(key))
}
}
impl Block for Cipher {
fn block_size(&self) -> usize {
BLOCK_SIZE
}
fn encrypt(&self, dst: &mut [u8], src: &[u8]) {
if src.len() < BLOCK_SIZE {
panic!("crypto/aes: input not full block");
}
if dst.len() < BLOCK_SIZE {
panic!("crypto/aes: output not full block");
}
block::encrypt_block_go(&self.enc, dst, src);
}
fn decrypt(&self, dst: &mut [u8], src: &[u8]) {
if src.len() < BLOCK_SIZE {
panic!("crypto/aes: input not full block");
}
if dst.len() < BLOCK_SIZE {
panic!("crypto/aes: output not full block");
}
block::decrypt_block_go(&self.dec, dst, src);
}
fn encrypt_inplace(&self, buffer: &mut [u8]) {
if buffer.len() < BLOCK_SIZE {
panic!("crypto/aes: input not full block");
}
block::encrypt_block_inplace_go(&self.enc, buffer);
}
fn decrypt_inplace(&self, buffer: &mut [u8]) {
if buffer.len() < BLOCK_SIZE {
panic!("crypto/aes: input not full block");
}
block::decrypt_block_inplace_go(&self.dec, buffer);
}
}