Skip to content

Commit

Permalink
Use Encryptor/Decryptor defined in aead
Browse files Browse the repository at this point in the history
  • Loading branch information
newpavlov committed Sep 23, 2024
1 parent aa732e1 commit fbabab8
Showing 1 changed file with 5 additions and 186 deletions.
191 changes: 5 additions & 186 deletions aead-stream/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,15 @@ use aead::array::{
typenum::{Unsigned, U4, U5},
Array, ArraySize,
};
use aead::{AeadCore, AeadInPlace, Buffer, Error, Key, KeyInit, Result};
use aead::{AeadCore, AeadInPlace, Buffer, Error, Result};
use core::ops::Sub;

pub use aead;

pub use aead::stream::{NewStream, StreamPrimitive};

#[cfg(feature = "alloc")]
use aead::Payload;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
pub use aead::{
stream::{Decryptor, Encryptor, NewStream, StreamPrimitive},
Key, KeyInit,
};

/// Nonce as used by a given AEAD construction and STREAM primitive.
pub type Nonce<A, S> = Array<u8, NonceSize<A, S>>;
Expand All @@ -76,185 +74,6 @@ pub type EncryptorLE31<A> = Encryptor<A, StreamLE31<A>>;
/// STREAM primitive.
pub type DecryptorLE31<A> = Decryptor<A, StreamLE31<A>>;

/// Implement a stateful STREAM object (i.e. encryptor or decryptor)
macro_rules! impl_stream_object {
(
$name:ident,
$next_method:tt,
$next_in_place_method:tt,
$last_method:tt,
$last_in_place_method:tt,
$op:tt,
$in_place_op:tt,
$op_desc:expr,
$obj_desc:expr
) => {
#[doc = "Stateful STREAM object which can"]
#[doc = $op_desc]
#[doc = "AEAD messages one-at-a-time."]
#[doc = ""]
#[doc = "This corresponds to the "]
#[doc = $obj_desc]
#[doc = "object as defined in the paper"]
#[doc = "[Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance][1]."]
#[doc = ""]
#[doc = "[1]: https://eprint.iacr.org/2015/189.pdf"]
#[derive(Debug)]
pub struct $name<A, S>
where
A: AeadInPlace,
S: StreamPrimitive<A>,
A::NonceSize: Sub<<S as StreamPrimitive<A>>::NonceOverhead>,
NonceSize<A, S>: ArraySize,
{
/// Underlying STREAM primitive.
stream: S,

/// Current position in the STREAM.
position: S::Counter,
}

impl<A, S> $name<A, S>
where
A: AeadInPlace,
S: StreamPrimitive<A>,
A::NonceSize: Sub<<S as StreamPrimitive<A>>::NonceOverhead>,
NonceSize<A, S>: ArraySize,
{
#[doc = "Create a"]
#[doc = $obj_desc]
#[doc = "object from the given AEAD key and nonce."]
pub fn new(key: &Key<A>, nonce: &Nonce<A, S>) -> Self
where
A: KeyInit,
S: NewStream<A>,
{
Self::from_stream_primitive(S::new(key, nonce))
}

#[doc = "Create a"]
#[doc = $obj_desc]
#[doc = "object from the given AEAD primitive."]
pub fn from_aead(aead: A, nonce: &Nonce<A, S>) -> Self
where
A: KeyInit,
S: NewStream<A>,
{
Self::from_stream_primitive(S::from_aead(aead, nonce))
}

#[doc = "Create a"]
#[doc = $obj_desc]
#[doc = "object from the given STREAM primitive."]
pub fn from_stream_primitive(stream: S) -> Self {
Self {
stream,
position: Default::default(),
}
}

#[doc = "Use the underlying AEAD to"]
#[doc = $op_desc]
#[doc = "the next AEAD message in this STREAM, returning the"]
#[doc = "result as a [`Vec`]."]
#[cfg(feature = "alloc")]
pub fn $next_method<'msg, 'aad>(
&mut self,
payload: impl Into<Payload<'msg, 'aad>>,
) -> Result<Vec<u8>> {
if self.position == S::COUNTER_MAX {
// Counter overflow. Note that the maximum counter value is
// deliberately disallowed, as it would preclude being able
// to encrypt a last block (i.e. with `$last_in_place_method`)
return Err(Error);
}

let result = self.stream.$op(self.position, false, payload)?;

// Note: overflow checked above
self.position += S::COUNTER_INCR;
Ok(result)
}

#[doc = "Use the underlying AEAD to"]
#[doc = $op_desc]
#[doc = "the next AEAD message in this STREAM in-place."]
pub fn $next_in_place_method(
&mut self,
associated_data: &[u8],
buffer: &mut dyn Buffer,
) -> Result<()> {
if self.position == S::COUNTER_MAX {
// Counter overflow. Note that the maximum counter value is
// deliberately disallowed, as it would preclude being able
// to encrypt a last block (i.e. with `$last_in_place_method`)
return Err(Error);
}

self.stream
.$in_place_op(self.position, false, associated_data, buffer)?;

// Note: overflow checked above
self.position += S::COUNTER_INCR;
Ok(())
}

#[doc = "Use the underlying AEAD to"]
#[doc = $op_desc]
#[doc = "the last AEAD message in this STREAM,"]
#[doc = "consuming the "]
#[doc = $obj_desc]
#[doc = "object in order to prevent further use."]
#[cfg(feature = "alloc")]
pub fn $last_method<'msg, 'aad>(
self,
payload: impl Into<Payload<'msg, 'aad>>,
) -> Result<Vec<u8>> {
self.stream.$op(self.position, true, payload)
}

#[doc = "Use the underlying AEAD to"]
#[doc = $op_desc]
#[doc = "the last AEAD message in this STREAM in-place,"]
#[doc = "consuming the "]
#[doc = $obj_desc]
#[doc = "object in order to prevent further use."]
pub fn $last_in_place_method(
self,
associated_data: &[u8],
buffer: &mut dyn Buffer,
) -> Result<()> {
self.stream
.$in_place_op(self.position, true, associated_data, buffer)
}
}
};
}

impl_stream_object!(
Encryptor,
encrypt_next,
encrypt_next_in_place,
encrypt_last,
encrypt_last_in_place,
encrypt,
encrypt_in_place,
"encrypt",
"ℰ STREAM encryptor"
);

impl_stream_object!(
Decryptor,
decrypt_next,
decrypt_next_in_place,
decrypt_last,
decrypt_last_in_place,
decrypt,
decrypt_in_place,
"decrypt",
"𝒟 STREAM decryptor"
);

/// The original "Rogaway-flavored" STREAM as described in the paper
/// [Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance][1].
///
Expand Down

0 comments on commit fbabab8

Please sign in to comment.