use std::ops::{Deref, DerefMut};
use constants::{
AEADAlgorithm,
SymmetricAlgorithm,
};
use packet::{self, Common};
use Packet;
use Error;
use Result;
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
pub struct AED1 {
pub(crate) common: packet::Common,
sym_algo: SymmetricAlgorithm,
aead: AEADAlgorithm,
chunk_size: usize,
iv: Box<[u8]>,
}
impl AED1 {
pub fn new(sym_algo: SymmetricAlgorithm,
aead: AEADAlgorithm,
chunk_size: usize,
iv: Box<[u8]>) -> Result<Self> {
if chunk_size.count_ones() != 1 {
return Err(Error::InvalidArgument(
format!("chunk size is not a power of two: {}", chunk_size))
.into());
}
if chunk_size < 64 {
return Err(Error::InvalidArgument(
format!("chunk size is too small: {}", chunk_size))
.into());
}
Ok(AED1 {
common: Default::default(),
sym_algo: sym_algo,
aead: aead,
chunk_size: chunk_size,
iv: iv,
})
}
pub fn symmetric_algo(&self) -> SymmetricAlgorithm {
self.sym_algo
}
pub fn set_sym_algo(&mut self, sym_algo: SymmetricAlgorithm)
-> SymmetricAlgorithm {
::std::mem::replace(&mut self.sym_algo, sym_algo)
}
pub fn aead(&self) -> AEADAlgorithm {
self.aead
}
pub fn set_aead(&mut self, aead: AEADAlgorithm) -> AEADAlgorithm {
::std::mem::replace(&mut self.aead, aead)
}
pub fn chunk_size(&self) -> usize {
self.chunk_size
}
pub fn set_chunk_size(&mut self, chunk_size: usize) -> Result<()> {
if chunk_size.count_ones() != 1 {
return Err(Error::InvalidArgument(
format!("chunk size is not a power of two: {}", chunk_size))
.into());
}
if chunk_size < 64 {
return Err(Error::InvalidArgument(
format!("chunk size is too small: {}", chunk_size))
.into());
}
self.chunk_size = chunk_size;
Ok(())
}
pub fn chunk_digest_size(&self) -> Result<usize> {
Ok(self.chunk_size + self.aead.digest_size()?)
}
pub fn iv(&self) -> &[u8] {
&self.iv
}
pub fn set_iv(&mut self, iv: Box<[u8]>) -> Box<[u8]> {
::std::mem::replace(&mut self.iv, iv)
}
}
impl From<AED1> for Packet {
fn from(p: AED1) -> Self {
super::AED::from(p).into()
}
}
impl From<AED1> for super::AED {
fn from(p: AED1) -> Self {
super::AED::V1(p)
}
}
impl<'a> Deref for AED1 {
type Target = Common;
fn deref(&self) -> &Self::Target {
&self.common
}
}
impl<'a> DerefMut for AED1 {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.common
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deref() {
let mut s = AED1::new(SymmetricAlgorithm::AES128,
AEADAlgorithm::EAX,
64,
vec![].into_boxed_slice()).unwrap();
assert_eq!(s.body(), None);
s.set_body(vec![0, 1, 2]);
assert_eq!(s.body(), Some(&[0, 1, 2][..]));
}
}