Skip to content
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion aead/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ arrayvec = { version = "0.7", optional = true, default-features = false }
blobby = { version = "0.4.0-pre.0", optional = true }
bytes = { version = "1", optional = true, default-features = false }
heapless = { version = "0.8", optional = true, default-features = false }
inout = { version = "0.2.0-rc.4", optional = true, default-features = false }

[features]
default = ["rand_core"]
default = ["inout", "rand_core"]
alloc = []
dev = ["blobby"]
os_rng = ["crypto-common/os_rng", "rand_core"]
Expand Down
89 changes: 48 additions & 41 deletions aead/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,26 @@ pub use crypto_common::{
pub use arrayvec;
#[cfg(feature = "bytes")]
pub use bytes;
#[cfg(feature = "heapless")]
pub use heapless;

#[cfg(feature = "rand_core")]
pub use crypto_common::rand_core;
#[cfg(feature = "heapless")]
pub use heapless;
#[cfg(feature = "inout")]
pub use inout;

use core::fmt;
use crypto_common::array::{Array, ArraySize, typenum::Unsigned};
use crypto_common::array::{Array, ArraySize};

#[cfg(feature = "alloc")]
use alloc::vec::Vec;
#[cfg(feature = "bytes")]
use bytes::BytesMut;
#[cfg(any(feature = "alloc", feature = "inout"))]
use crypto_common::array::typenum::Unsigned;
#[cfg(feature = "os_rng")]
use crypto_common::rand_core::{OsError, OsRng, TryRngCore};
#[cfg(feature = "inout")]
use inout::InOutBuf;
#[cfg(feature = "rand_core")]
use rand_core::{CryptoRng, TryCryptoRng};

Expand Down Expand Up @@ -240,23 +245,24 @@ pub trait AeadInPlace: AeadCore {
}

/// In-place AEAD trait which handles the authentication tag as a return value/separate parameter.
pub trait AeadInPlaceDetached: AeadCore {
/// Encrypt the data in-place, returning the authentication tag.
fn encrypt_in_place_detached(
#[cfg(feature = "inout")]
pub trait AeadInOut: AeadCore {
/// Encrypt the data in the provided [`InOutBuf`], returning the authentication tag.
fn encrypt_inout_detached(
&self,
nonce: &Nonce<Self>,
associated_data: &[u8],
buffer: &mut [u8],
buffer: InOutBuf<'_, '_, u8>,
) -> Result<Tag<Self>>;

/// Decrypt the message in-place, returning an error in the event the provided
/// authentication tag does not match the given ciphertext (i.e. ciphertext
/// Decrypt the data in the provided [`InOutBuf`], returning an error in the event the
/// provided authentication tag is invalid for the given ciphertext (i.e. ciphertext
/// is modified/unauthentic)
fn decrypt_in_place_detached(
fn decrypt_inout_detached(
&self,
nonce: &Nonce<Self>,
associated_data: &[u8],
buffer: &mut [u8],
buffer: InOutBuf<'_, '_, u8>,
tag: &Tag<Self>,
) -> Result<()>;
}
Expand All @@ -267,14 +273,41 @@ pub trait AeadInPlaceDetached: AeadCore {
/// This is the common convention for AEAD algorithms.
pub trait PostfixTagged {}

impl<T: AeadInPlaceDetached + PostfixTagged> AeadInPlace for T {
#[cfg(feature = "alloc")]
impl<Alg: AeadInPlace> Aead for Alg {
fn encrypt<'msg, 'aad>(
&self,
nonce: &Nonce<Self>,
plaintext: impl Into<Payload<'msg, 'aad>>,
) -> Result<Vec<u8>> {
let payload = plaintext.into();
let mut buffer = Vec::with_capacity(payload.msg.len() + Self::TagSize::to_usize());
buffer.extend_from_slice(payload.msg);
self.encrypt_in_place(nonce, payload.aad, &mut buffer)?;
Ok(buffer)
}

fn decrypt<'msg, 'aad>(
&self,
nonce: &Nonce<Self>,
ciphertext: impl Into<Payload<'msg, 'aad>>,
) -> Result<Vec<u8>> {
let payload = ciphertext.into();
let mut buffer = Vec::from(payload.msg);
self.decrypt_in_place(nonce, payload.aad, &mut buffer)?;
Ok(buffer)
}
}

#[cfg(feature = "inout")]
impl<T: AeadInOut + PostfixTagged> AeadInPlace for T {
fn encrypt_in_place(
&self,
nonce: &Nonce<Self>,
associated_data: &[u8],
buffer: &mut dyn Buffer,
) -> Result<()> {
let tag = self.encrypt_in_place_detached(nonce, associated_data, buffer.as_mut())?;
let tag = self.encrypt_inout_detached(nonce, associated_data, buffer.as_mut().into())?;
buffer.extend_from_slice(tag.as_slice())?;
Ok(())
}
Expand All @@ -293,38 +326,12 @@ impl<T: AeadInPlaceDetached + PostfixTagged> AeadInPlace for T {
let (msg, tag) = buffer.as_mut().split_at_mut(tag_pos);
let tag = Tag::<Self>::try_from(&*tag).expect("tag length mismatch");

self.decrypt_in_place_detached(nonce, associated_data, msg, &tag)?;
self.decrypt_inout_detached(nonce, associated_data, msg.into(), &tag)?;
buffer.truncate(tag_pos);
Ok(())
}
}

#[cfg(feature = "alloc")]
impl<Alg: AeadInPlace> Aead for Alg {
fn encrypt<'msg, 'aad>(
&self,
nonce: &Nonce<Self>,
plaintext: impl Into<Payload<'msg, 'aad>>,
) -> Result<Vec<u8>> {
let payload = plaintext.into();
let mut buffer = Vec::with_capacity(payload.msg.len() + Self::TagSize::to_usize());
buffer.extend_from_slice(payload.msg);
self.encrypt_in_place(nonce, payload.aad, &mut buffer)?;
Ok(buffer)
}

fn decrypt<'msg, 'aad>(
&self,
nonce: &Nonce<Self>,
ciphertext: impl Into<Payload<'msg, 'aad>>,
) -> Result<Vec<u8>> {
let payload = ciphertext.into();
let mut buffer = Vec::from(payload.msg);
self.decrypt_in_place(nonce, payload.aad, &mut buffer)?;
Ok(buffer)
}
}

/// AEAD payloads (message + AAD).
///
/// Combination of a message (plaintext or ciphertext) and
Expand Down