pub mod permutation;
pub use secured_cipher_key::{random_bytes, Key};
pub use permutation::{ChaCha20, Permutation, Poly1305, SignedEnvelope};
use std::error::Error;
pub struct Cipher {
permutation: Box<dyn Permutation>,
aead: Poly1305,
}
pub enum CipherMode {
ChaCha20,
}
impl Cipher {
pub fn new(mode: CipherMode) -> Self {
let permutation: Box<dyn Permutation> = match mode {
_ => Box::new(ChaCha20::new()),
};
Self {
permutation,
aead: Poly1305::new(),
}
}
pub fn init(&mut self, key: &[u8], iv: &[u8]) -> &mut Self {
self.permutation.init(key, iv);
self.aead.init(&self.permutation.process(&[0; 64]), iv);
self
}
pub fn encrypt(&mut self, data: &[u8]) -> Vec<u8> {
self.permutation.process(data)
}
pub fn sign(&mut self, header: &[u8], data: &[u8]) -> SignedEnvelope {
let mac = self
.aead
.process(&[header.to_vec(), data.to_vec()].concat());
SignedEnvelope {
header: header.to_vec(),
data: data.into(),
mac,
}
}
pub fn decrypt(&mut self, data: &[u8]) -> Vec<u8> {
self.permutation.process(&data)
}
pub fn decrypt_and_verify(&mut self, envelope: &SignedEnvelope) -> Result<Vec<u8>, CipherError> {
if envelope.mac
!= self
.aead
.process(&[envelope.header.clone(), envelope.data.clone()].concat())
{
return Err(CipherError::AuthenticationFailed);
}
Ok(self.permutation.process(&envelope.data))
}
}
impl Default for Cipher {
fn default() -> Self {
Self::new(CipherMode::ChaCha20)
}
}
#[derive(Debug)]
pub enum CipherError {
AuthenticationFailed,
}
impl Error for CipherError {}
impl std::fmt::Display for CipherError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
CipherError::AuthenticationFailed => write!(f, "Authentication failed"),
}
}
}