Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(aes-siv): generic nonce sizes for SivAead #555

Merged
merged 3 commits into from
Oct 14, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions aes-siv/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,12 @@ pub use aead::{self, AeadCore, AeadInPlace, Error, Key, KeyInit, KeySizeUser};

use crate::siv::Siv;
use aead::{
consts::{U0, U16, U32, U64},
consts::{U0, U1, U16, U32, U64},
generic_array::GenericArray,
Buffer,
};
use aes::{Aes128, Aes256};
use cipher::{BlockCipher, BlockEncryptMut};
use cipher::{typenum::IsGreaterOrEqual, ArrayLength, BlockCipher, BlockEncryptMut};
use cmac::Cmac;
use core::{marker::PhantomData, ops::Add};
use digest::{FixedOutputReset, Mac};
Expand All @@ -105,20 +105,21 @@ use digest::{FixedOutputReset, Mac};
use pmac::Pmac;

/// AES-SIV nonces
pub type Nonce = GenericArray<u8, U16>;
pub type Nonce<NonceSize = U16> = GenericArray<u8, NonceSize>;

/// AES-SIV tags (i.e. the Synthetic Initialization Vector value)
pub type Tag = GenericArray<u8, U16>;

/// The `SivAead` type wraps the more powerful `Siv` interface in a more
/// commonly used Authenticated Encryption with Associated Data (AEAD) API,
/// which accepts a key, nonce, and associated data when encrypting/decrypting.
pub struct SivAead<C, M>
pub struct SivAead<C, M, NonceSize = U16>
where
Self: KeySizeUser,
C: BlockCipher<BlockSize = U16> + BlockEncryptMut + KeyInit + KeySizeUser,
M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
<C as KeySizeUser>::KeySize: Add,
NonceSize: ArrayLength<u8> + IsGreaterOrEqual<U1>,
{
key: GenericArray<u8, <Self as KeySizeUser>::KeySize>,
mac: PhantomData<M>, // TODO(tarcieri): include `M` in `KeySize` calculation
Expand Down Expand Up @@ -148,23 +149,26 @@ pub type Aes128PmacSivAead = PmacSivAead<Aes128>;
#[cfg_attr(docsrs, doc(cfg(feature = "pmac")))]
pub type Aes256PmacSivAead = PmacSivAead<Aes256>;

impl<M> KeySizeUser for SivAead<Aes128, M>
impl<M, NonceSize> KeySizeUser for SivAead<Aes128, M, NonceSize>
where
M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
NonceSize: ArrayLength<u8> + IsGreaterOrEqual<U1>,
{
type KeySize = U32;
}

impl<M> KeySizeUser for SivAead<Aes256, M>
impl<M, NonceSize> KeySizeUser for SivAead<Aes256, M, NonceSize>
where
M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
NonceSize: ArrayLength<u8> + IsGreaterOrEqual<U1>,
{
type KeySize = U64;
}

impl<M> KeyInit for SivAead<Aes128, M>
impl<M, NonceSize> KeyInit for SivAead<Aes128, M, NonceSize>
where
M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
NonceSize: ArrayLength<u8> + IsGreaterOrEqual<U1>,
{
fn new(key: &GenericArray<u8, Self::KeySize>) -> Self {
Self {
Expand All @@ -174,9 +178,10 @@ where
}
}

impl<M> KeyInit for SivAead<Aes256, M>
impl<M, NonceSize> KeyInit for SivAead<Aes256, M, NonceSize>
where
M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
NonceSize: ArrayLength<u8> + IsGreaterOrEqual<U1>,
{
fn new(key: &GenericArray<u8, Self::KeySize>) -> Self {
Self {
Expand All @@ -186,28 +191,31 @@ where
}
}

impl<C, M> AeadCore for SivAead<C, M>
impl<C, M, NonceSize> AeadCore for SivAead<C, M, NonceSize>
where
Self: KeySizeUser,
C: BlockCipher<BlockSize = U16> + BlockEncryptMut + KeyInit + KeySizeUser,
M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
<C as KeySizeUser>::KeySize: Add,
NonceSize: ArrayLength<u8> + IsGreaterOrEqual<U1>,
{
// "If the nonce is random, it SHOULD be at least 128 bits in length"
// https://tools.ietf.org/html/rfc5297#section-3
// TODO(tarcieri): generic nonce sizes
type NonceSize = U16;
// "N_MIN is 1 octet."
// https://tools.ietf.org/html/rfc5297#section-6
type NonceSize = NonceSize;
type TagSize = U16;
type CiphertextOverhead = U0;
}

impl<C, M> AeadInPlace for SivAead<C, M>
impl<C, M, NonceSize> AeadInPlace for SivAead<C, M, NonceSize>
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,
NonceSize: ArrayLength<u8> + IsGreaterOrEqual<U1>,
{
fn encrypt_in_place(
&self,
Expand Down