#![no_std]
#![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")]
#![warn(missing_docs, rust_2018_idioms, unused_qualifications)]
#[cfg(feature = "alloc")]
extern crate alloc;
pub use aead;
pub mod siv;
use crate::siv::Siv;
use aead::{
consts::{U0, U16, U32, U64},
generic_array::{ArrayLength, GenericArray},
AeadInPlace, Buffer, Error, NewAead,
};
use aes::{Aes128, Aes256};
use cmac::Cmac;
use core::{marker::PhantomData, ops::Add};
use crypto_mac::{Mac, NewMac};
use ctr::Ctr128;
use stream_cipher::{NewStreamCipher, SyncStreamCipher};
#[cfg(feature = "pmac")]
use pmac::Pmac;
pub type KeySize<C> = <<C as NewStreamCipher>::KeySize as Add>::Output;
pub type Tag = GenericArray<u8, U16>;
pub struct SivAead<C, M>
where
C: NewStreamCipher<NonceSize = U16> + SyncStreamCipher,
M: Mac<OutputSize = U16>,
<C as NewStreamCipher>::KeySize: Add,
KeySize<C>: ArrayLength<u8>,
{
key: GenericArray<u8, KeySize<C>>,
mac: PhantomData<M>, }
pub type CmacSivAead<BlockCipher> = SivAead<Ctr128<BlockCipher>, Cmac<BlockCipher>>;
#[cfg(feature = "pmac")]
pub type PmacSivAead<BlockCipher> = SivAead<Ctr128<BlockCipher>, Pmac<BlockCipher>>;
pub type Aes128SivAead = CmacSivAead<Aes128>;
pub type Aes256SivAead = CmacSivAead<Aes256>;
#[cfg(feature = "pmac")]
pub type Aes128PmacSivAead = PmacSivAead<Aes128>;
#[cfg(feature = "pmac")]
pub type Aes256PmacSivAead = PmacSivAead<Aes256>;
impl<M> NewAead for SivAead<Ctr128<Aes128>, M>
where
M: Mac<OutputSize = U16>,
{
type KeySize = U32;
fn new(key: &GenericArray<u8, Self::KeySize>) -> Self {
Self {
key: *key,
mac: PhantomData,
}
}
}
impl<M> NewAead for SivAead<Ctr128<Aes256>, M>
where
M: Mac<OutputSize = U16>,
{
type KeySize = U64;
fn new(key: &GenericArray<u8, Self::KeySize>) -> Self {
Self {
key: *key,
mac: PhantomData,
}
}
}
impl<C, M> AeadInPlace for SivAead<C, M>
where
C: NewStreamCipher<NonceSize = U16> + SyncStreamCipher,
M: Mac<OutputSize = U16> + NewMac,
<C as NewStreamCipher>::KeySize: Add,
KeySize<C>: ArrayLength<u8>,
{
type NonceSize = U16;
type TagSize = U16;
type CiphertextOverhead = U0;
fn encrypt_in_place(
&self,
nonce: &GenericArray<u8, Self::NonceSize>,
associated_data: &[u8],
buffer: &mut dyn Buffer,
) -> Result<(), Error> {
Siv::<C, M>::new(self.key.clone())
.encrypt_in_place(&[associated_data, nonce.as_slice()], buffer)
}
fn encrypt_in_place_detached(
&self,
nonce: &GenericArray<u8, Self::NonceSize>,
associated_data: &[u8],
buffer: &mut [u8],
) -> Result<GenericArray<u8, Self::TagSize>, Error> {
Siv::<C, M>::new(self.key.clone())
.encrypt_in_place_detached(&[associated_data, nonce.as_slice()], buffer)
}
fn decrypt_in_place(
&self,
nonce: &GenericArray<u8, Self::NonceSize>,
associated_data: &[u8],
buffer: &mut dyn Buffer,
) -> Result<(), Error> {
Siv::<C, M>::new(self.key.clone())
.decrypt_in_place(&[associated_data, nonce.as_slice()], buffer)
}
fn decrypt_in_place_detached(
&self,
nonce: &GenericArray<u8, Self::NonceSize>,
associated_data: &[u8],
buffer: &mut [u8],
tag: &GenericArray<u8, Self::TagSize>,
) -> Result<(), Error> {
Siv::<C, M>::new(self.key.clone()).decrypt_in_place_detached(
&[associated_data, nonce.as_slice()],
buffer,
tag,
)
}
}