Skip to content

Commit

Permalink
stream-cipher: add FromBlockCipherMut trait (#334)
Browse files Browse the repository at this point in the history
Support for initializing a stream cipher from a `BlockCipherMut`.

This is a corollary to `FromBlockCipher`, but for cases where `mut`
access is needed to the inner block cipher instance (e.g. cryptographic
accelerator hardware peripherals).

Using chained blanket impls, it's possible to allow a blanket impl of
`NewStreamCipher` for types which impl either `FromBlockCipherMut` or
`FromBlockCipher`.
  • Loading branch information
tarcieri committed Oct 14, 2020
1 parent 6c23a07 commit cdd3492
Showing 1 changed file with 39 additions and 7 deletions.
46 changes: 39 additions & 7 deletions stream-cipher/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use generic_array::typenum::Unsigned;
use generic_array::{ArrayLength, GenericArray};

#[cfg(feature = "block-cipher")]
use block_cipher::{BlockCipher, NewBlockCipher};
use block_cipher::{BlockCipher, BlockCipherMut, NewBlockCipher};

/// Key for an algorithm that implements [`NewStreamCipher`].
pub type Key<C> = GenericArray<u8, <C as NewStreamCipher>::KeySize>;
Expand Down Expand Up @@ -184,18 +184,50 @@ pub trait FromBlockCipher {
) -> Self;
}

/// Trait for initializing a stream cipher from a mutable block cipher
#[cfg(feature = "block-cipher")]
impl<C> NewStreamCipher for C
#[cfg_attr(docsrs, doc(cfg(feature = "block-cipher")))]
pub trait FromBlockCipherMut {
/// Block cipher
type BlockCipher: BlockCipherMut;
/// Nonce size in bytes
type NonceSize: ArrayLength<u8>;

/// Instantiate a stream cipher from a block cipher
fn from_block_cipher_mut(
cipher: Self::BlockCipher,
nonce: &GenericArray<u8, Self::NonceSize>,
) -> Self;
}

#[cfg(feature = "block-cipher")]
impl<C> FromBlockCipherMut for C
where
C: FromBlockCipher,
C::BlockCipher: NewBlockCipher,
{
type KeySize = <<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::KeySize;
type BlockCipher = <Self as FromBlockCipher>::BlockCipher;
type NonceSize = <Self as FromBlockCipher>::NonceSize;

fn from_block_cipher_mut(
cipher: Self::BlockCipher,
nonce: &GenericArray<u8, Self::NonceSize>,
) -> C {
C::from_block_cipher(cipher, nonce)
}
}

#[cfg(feature = "block-cipher")]
impl<C> NewStreamCipher for C
where
C: FromBlockCipherMut,
C::BlockCipher: NewBlockCipher,
{
type KeySize = <<Self as FromBlockCipherMut>::BlockCipher as NewBlockCipher>::KeySize;
type NonceSize = <Self as FromBlockCipherMut>::NonceSize;

fn new(key: &Key<Self>, nonce: &Nonce<Self>) -> C {
C::from_block_cipher(
<<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::new(key),
C::from_block_cipher_mut(
<<Self as FromBlockCipherMut>::BlockCipher as NewBlockCipher>::new(key),
nonce,
)
}
Expand All @@ -208,7 +240,7 @@ where
.map_err(|_| InvalidKeyNonceLength)
.map(|cipher| {
let nonce = GenericArray::from_slice(nonce);
Self::from_block_cipher(cipher, nonce)
Self::from_block_cipher_mut(cipher, nonce)
})
}
}
Expand Down

0 comments on commit cdd3492

Please sign in to comment.