Skip to content

Commit

Permalink
aes-siv: generic nonce sizes for SivAead (#555)
Browse files Browse the repository at this point in the history
  • Loading branch information
Direktor799 authored Oct 14, 2023
1 parent 3ab8f05 commit f0f102e
Showing 1 changed file with 20 additions and 12 deletions.
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

0 comments on commit f0f102e

Please sign in to comment.