#![cfg_attr(all(feature = "getrandom", feature = "std"), doc = "```")]
#![cfg_attr(not(all(feature = "getrandom", feature = "std")), doc = "```ignore")]
#![cfg_attr(
all(feature = "getrandom", feature = "heapless", feature = "std"),
doc = "```"
)]
#![cfg_attr(
not(all(feature = "getrandom", feature = "heapless", feature = "std")),
doc = "```ignore"
)]
#![no_std]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg"
)]
#![warn(missing_docs, rust_2018_idioms, unused_qualifications)]
#[cfg(feature = "alloc")]
extern crate alloc;
pub mod siv;
pub use aead::{self, AeadCore, AeadInPlace, Error, Key, KeyInit, KeySizeUser};
use crate::siv::Siv;
use aead::{
consts::{U0, U16, U32, U64},
generic_array::GenericArray,
Buffer,
};
use aes::{Aes128, Aes256};
use cipher::{BlockCipher, BlockEncryptMut};
use cmac::Cmac;
use core::{marker::PhantomData, ops::Add};
use digest::{FixedOutputReset, Mac};
#[cfg(feature = "pmac")]
use pmac::Pmac;
pub type Nonce = GenericArray<u8, U16>;
pub type Tag = GenericArray<u8, U16>;
pub struct SivAead<C, M>
where
Self: KeySizeUser,
C: BlockCipher<BlockSize = U16> + BlockEncryptMut + KeyInit + KeySizeUser,
M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
<C as KeySizeUser>::KeySize: Add,
{
key: GenericArray<u8, <Self as KeySizeUser>::KeySize>,
mac: PhantomData<M>, }
pub type CmacSivAead<BlockCipher> = SivAead<BlockCipher, Cmac<BlockCipher>>;
#[cfg(feature = "pmac")]
#[cfg_attr(docsrs, doc(cfg(feature = "pmac")))]
pub type PmacSivAead<BlockCipher> = SivAead<BlockCipher, Pmac<BlockCipher>>;
pub type Aes128SivAead = CmacSivAead<Aes128>;
pub type Aes256SivAead = CmacSivAead<Aes256>;
#[cfg(feature = "pmac")]
#[cfg_attr(docsrs, doc(cfg(feature = "pmac")))]
pub type Aes128PmacSivAead = PmacSivAead<Aes128>;
#[cfg(feature = "pmac")]
#[cfg_attr(docsrs, doc(cfg(feature = "pmac")))]
pub type Aes256PmacSivAead = PmacSivAead<Aes256>;
impl<M> KeySizeUser for SivAead<Aes128, M>
where
M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
{
type KeySize = U32;
}
impl<M> KeySizeUser for SivAead<Aes256, M>
where
M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
{
type KeySize = U64;
}
impl<M> KeyInit for SivAead<Aes128, M>
where
M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
{
fn new(key: &GenericArray<u8, Self::KeySize>) -> Self {
Self {
key: *key,
mac: PhantomData,
}
}
}
impl<M> KeyInit for SivAead<Aes256, M>
where
M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
{
fn new(key: &GenericArray<u8, Self::KeySize>) -> Self {
Self {
key: *key,
mac: PhantomData,
}
}
}
impl<C, M> AeadCore for SivAead<C, M>
where
Self: KeySizeUser,
C: BlockCipher<BlockSize = U16> + BlockEncryptMut + KeyInit + KeySizeUser,
M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
<C as KeySizeUser>::KeySize: Add,
{
type NonceSize = U16;
type TagSize = U16;
type CiphertextOverhead = U0;
}
impl<C, M> AeadInPlace for SivAead<C, M>
where
Self: KeySizeUser,
Siv<C, M>: KeyInit + KeySizeUser<KeySize = <Self as KeySizeUser>::KeySize>,
C: BlockCipher<BlockSize = U16> + BlockEncryptMut + KeyInit + KeySizeUser,
M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
<C as KeySizeUser>::KeySize: Add,
{
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).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)
.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).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).decrypt_in_place_detached(
&[associated_data, nonce.as_slice()],
buffer,
tag,
)
}
}