use crate::{errors::InvalidLength, BlockCipher, NewBlockCipher}; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; /// Key for an algorithm that implements [`NewCipher`]. pub type CipherKey = GenericArray::KeySize>; /// Nonce for an algorithm that implements [`NewCipher`]. pub type Nonce = GenericArray::NonceSize>; /// Cipher creation trait. /// /// It can be used for creation of block modes, synchronous and asynchronous stream ciphers. pub trait NewCipher: Sized { /// Key size in bytes type KeySize: ArrayLength; /// Nonce size in bytes type NonceSize: ArrayLength; /// Create new stream cipher instance from key and nonce arrays. fn new(key: &CipherKey, nonce: &Nonce) -> Self; /// Create new stream cipher instance from variable length key and nonce /// given as byte slices. #[inline] fn new_from_slices(key: &[u8], nonce: &[u8]) -> Result { let kl = Self::KeySize::to_usize(); let nl = Self::NonceSize::to_usize(); if key.len() != kl || nonce.len() != nl { Err(InvalidLength) } else { let key = GenericArray::from_slice(key); let nonce = GenericArray::from_slice(nonce); Ok(Self::new(key, nonce)) } } } /// Trait for types which can be initialized from a block cipher and nonce. pub trait FromBlockCipher { /// Block cipher type BlockCipher: BlockCipher; /// Nonce size in bytes type NonceSize: ArrayLength; /// Instantiate a stream cipher from a block cipher fn from_block_cipher( cipher: Self::BlockCipher, nonce: &GenericArray, ) -> Self; } impl NewCipher for C where C: FromBlockCipher, C::BlockCipher: NewBlockCipher, { type KeySize = <::BlockCipher as NewBlockCipher>::KeySize; type NonceSize = ::NonceSize; fn new(key: &CipherKey, nonce: &Nonce) -> C { C::from_block_cipher( <::BlockCipher as NewBlockCipher>::new(key), nonce, ) } fn new_from_slices(key: &[u8], nonce: &[u8]) -> Result { if nonce.len() != Self::NonceSize::USIZE { Err(InvalidLength) } else { C::BlockCipher::new_from_slice(key) .map_err(|_| InvalidLength) .map(|cipher| { let nonce = GenericArray::from_slice(nonce); Self::from_block_cipher(cipher, nonce) }) } } }