Skip to content
Closed
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
2 changes: 1 addition & 1 deletion aes-gcm-siv/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ categories = ["cryptography", "no-std"]
rust-version = "1.85"

[dependencies]
aead = { version = "0.6.0-rc.0", default-features = false }
aead = { version = "0.6.0-rc.0", default-features = false, features = ["inout"] }
aes = { version = "=0.9.0-pre.3", optional = true }
cipher = "=0.5.0-pre.8"
ctr = "0.10.0-pre.2"
Expand Down
18 changes: 9 additions & 9 deletions aes-gcm-siv/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,13 @@ pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser};
#[cfg(feature = "aes")]
pub use aes;

use aead::{inout::InOutBuf, PostfixTagged};
use aead::{PostfixTagged, inout::InOutBuf};
use cipher::{
BlockCipherEncrypt, BlockSizeUser, InnerIvInit, StreamCipherCore,
array::Array,
consts::{U12, U16},
BlockCipherEncrypt, BlockSizeUser, InnerIvInit, StreamCipherCore,
};
use polyval::{universal_hash::UniversalHash, Polyval};
use polyval::{Polyval, universal_hash::UniversalHash};

/// AES is optional to allow swapping in hardware-specific backends.
#[cfg(feature = "aes")]
Expand Down Expand Up @@ -278,10 +278,10 @@ where
}

self.polyval.update_padded(associated_data);
self.polyval.update_padded(buffer);
self.polyval.update_padded(buffer.get_in());

let tag = self.finish_tag(associated_data.len(), buffer.len());
init_ctr(&self.enc_cipher, &tag).apply_keystream_partial(buffer.into());
init_ctr(&self.enc_cipher, &tag).apply_keystream_partial(buffer);

Ok(tag)
}
Expand All @@ -291,7 +291,7 @@ where
pub(crate) fn decrypt_inout_detached(
mut self,
associated_data: &[u8],
buffer: InOutBuf<'_, '_, u8>,
mut buffer: InOutBuf<'_, '_, u8>,
tag: &Tag,
) -> Result<(), Error> {
if buffer.len() as u64 > C_MAX || associated_data.len() as u64 > A_MAX {
Expand All @@ -301,8 +301,8 @@ where
self.polyval.update_padded(associated_data);

// TODO(tarcieri): interleave decryption and authentication
init_ctr(&self.enc_cipher, tag).apply_keystream_partial(buffer.into());
self.polyval.update_padded(buffer);
init_ctr(&self.enc_cipher, tag).apply_keystream_partial(buffer.reborrow());
self.polyval.update_padded(buffer.get_in());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this one needs to be get_out, since it's authenticating the decrypted plaintext (since the "SIV" tag is calculated from the plaintext)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, in case it's not the same backing buffer for in and out?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes


let expected_tag = self.finish_tag(associated_data.len(), buffer.len());

Expand All @@ -312,7 +312,7 @@ where
} else {
// On MAC verify failure, re-encrypt the plaintext buffer to
// prevent accidental exposure.
init_ctr(&self.enc_cipher, tag).apply_keystream_partial(buffer.into());
init_ctr(&self.enc_cipher, tag).apply_keystream_partial(buffer);
Err(Error)
}
}
Expand Down
2 changes: 1 addition & 1 deletion aes-gcm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ categories = ["cryptography", "no-std"]
rust-version = "1.85"

[dependencies]
aead = { version = "0.6.0-rc.0", default-features = false }
aead = { version = "0.6.0-rc.0", default-features = false, features = ["inout"] }
aes = { version = "=0.9.0-pre.3", optional = true }
cipher = "=0.5.0-pre.8"
ctr = "0.10.0-pre.2"
Expand Down
18 changes: 9 additions & 9 deletions aes-gcm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,21 +103,21 @@ pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser};
#[cfg(feature = "aes")]
pub use aes;

use aead::{inout::InOutBuf, PostfixTagged};
use aead::{PostfixTagged, inout::InOutBuf};

use cipher::{
BlockCipherEncrypt, BlockSizeUser, InnerIvInit, StreamCipherCore,
array::{Array, ArraySize},
consts::U16,
BlockCipherEncrypt, BlockSizeUser, InnerIvInit, StreamCipherCore,
};
use core::marker::PhantomData;
use ghash::{universal_hash::UniversalHash, GHash};
use ghash::{GHash, universal_hash::UniversalHash};

#[cfg(feature = "zeroize")]
use zeroize::Zeroize;

#[cfg(feature = "aes")]
use aes::{cipher::consts::U12, Aes128, Aes256};
use aes::{Aes128, Aes256, cipher::consts::U12};

/// Maximum length of associated data.
pub const A_MAX: u64 = 1 << 36;
Expand Down Expand Up @@ -270,7 +270,7 @@ where
&self,
nonce: &Nonce<NonceSize>,
associated_data: &[u8],
buffer: InOutBuf<'_, '_, u8>,
mut buffer: InOutBuf<'_, '_, u8>,
) -> Result<Tag<TagSize>, Error> {
if buffer.len() as u64 > P_MAX || associated_data.len() as u64 > A_MAX {
return Err(Error);
Expand All @@ -280,9 +280,9 @@ where

// TODO(tarcieri): interleave encryption with GHASH
// See: <https://github.com/RustCrypto/AEADs/issues/74>
ctr.apply_keystream_partial(buffer.into());
ctr.apply_keystream_partial(buffer.reborrow());

let full_tag = self.compute_tag(mask, associated_data, buffer);
let full_tag = self.compute_tag(mask, associated_data, buffer.get_in());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one probably needs to be get_out, to compute a MAC over the ciphertext

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah there is probably a whole slew of those, I assumed the backing buffer was unique.

Ok(Tag::try_from(&full_tag[..TagSize::to_usize()]).expect("tag size mismatch"))
}

Expand All @@ -301,11 +301,11 @@ where

// TODO(tarcieri): interleave encryption with GHASH
// See: <https://github.com/RustCrypto/AEADs/issues/74>
let expected_tag = self.compute_tag(mask, associated_data, buffer);
let expected_tag = self.compute_tag(mask, associated_data, buffer.get_in());

use subtle::ConstantTimeEq;
if expected_tag[..TagSize::to_usize()].ct_eq(tag).into() {
ctr.apply_keystream_partial(buffer.into());
ctr.apply_keystream_partial(buffer);
Ok(())
} else {
Err(Error)
Expand Down
2 changes: 1 addition & 1 deletion aes-gcm/tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ macro_rules! tests {
let cipher = <$aead>::new(&key);
assert!(
cipher
.decrypt_inout_detached(&nonce, &[], &mut buffer, &tag)
.decrypt_inout_detached(&nonce, &[], (buffer.as_mut_slice()).into(), &tag)
.is_err()
);

Expand Down
18 changes: 9 additions & 9 deletions aes-siv/src/siv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ where
// TODO(tarcieri): add offset param to `encrypt_inout_detached`
buffer.as_mut().copy_within(..pt_len, IV_SIZE);

let tag = self.encrypt_inout_detached(headers, &mut buffer.as_mut()[IV_SIZE..])?;
let tag = self.encrypt_inout_detached(headers, (&mut buffer.as_mut()[IV_SIZE..]).into())?;
buffer.as_mut()[..IV_SIZE].copy_from_slice(tag.as_slice());
Ok(())
}
Expand All @@ -227,15 +227,15 @@ where
pub fn encrypt_inout_detached<I, T>(
&mut self,
headers: I,
plaintext: InOutBuf<'_, '_, u8>,
mut plaintext: InOutBuf<'_, '_, u8>,
) -> Result<Tag, Error>
where
I: IntoIterator<Item = T>,
T: AsRef<[u8]>,
{
// Compute the synthetic IV for this plaintext
let siv_tag = s2v(&mut self.mac, headers, plaintext)?;
self.xor_with_keystream(siv_tag, plaintext);
let siv_tag = s2v(&mut self.mac, headers, plaintext.get_in())?;
self.xor_with_keystream(siv_tag, plaintext.get_out());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably needs to pass plaintext and the receiver needs to load plaintext from in and write to out

Ok(siv_tag)
}

Expand Down Expand Up @@ -271,7 +271,7 @@ where
}

let siv_tag = Tag::try_from(&buffer.as_ref()[..IV_SIZE]).expect("tag size mismatch");
self.decrypt_inout_detached(headers, &mut buffer.as_mut()[IV_SIZE..], &siv_tag)?;
self.decrypt_inout_detached(headers, (&mut buffer.as_mut()[IV_SIZE..]).into(), &siv_tag)?;

let pt_len = buffer.len() - IV_SIZE;

Expand All @@ -290,22 +290,22 @@ where
pub fn decrypt_inout_detached<I, T>(
&mut self,
headers: I,
ciphertext: InOutBuf<'_, '_, u8>,
mut ciphertext: InOutBuf<'_, '_, u8>,
siv_tag: &Tag,
) -> Result<(), Error>
where
I: IntoIterator<Item = T>,
T: AsRef<[u8]>,
{
self.xor_with_keystream(*siv_tag, ciphertext);
let computed_siv_tag = s2v(&mut self.mac, headers, ciphertext)?;
self.xor_with_keystream(*siv_tag, ciphertext.get_out());
let computed_siv_tag = s2v(&mut self.mac, headers, ciphertext.get_in())?;

// Note: `CtOutput` provides constant-time equality
if CtOutput::<M>::new(computed_siv_tag) == CtOutput::new(*siv_tag) {
Ok(())
} else {
// Re-encrypt the decrypted plaintext to avoid revealing it
self.xor_with_keystream(*siv_tag, ciphertext);
self.xor_with_keystream(*siv_tag, ciphertext.get_out());
Err(Error)
}
}
Expand Down
4 changes: 2 additions & 2 deletions aes-siv/tests/aead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ macro_rules! tests {

let cipher = <$aead>::new(&key);
let tag = cipher
.encrypt_inout_detached(&nonce, vector.aad, &mut buffer)
.encrypt_inout_detached(&nonce, vector.aad, buffer.as_mut_slice().into())
.unwrap();
let (expected_tag, expected_ciphertext) = vector.ciphertext.split_at(16);
assert_eq!(expected_tag, &tag[..]);
Expand Down Expand Up @@ -75,7 +75,7 @@ macro_rules! tests {
let mut buffer = vector.ciphertext[16..].to_vec();

<$aead>::new(&key)
.decrypt_inout_detached(&nonce, vector.aad, &mut buffer, &tag)
.decrypt_inout_detached(&nonce, vector.aad, buffer.as_mut_slice().into(), &tag)
.unwrap();

assert_eq!(vector.plaintext, buffer.as_slice());
Expand Down
2 changes: 1 addition & 1 deletion ascon-aead/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"]
rust-version = "1.85"

[dependencies]
aead = { version = "0.6.0-rc.0", default-features = false }
aead = { version = "0.6.0-rc.0", default-features = false, features = ["inout"] }
subtle = { version = "2", default-features = false }
zeroize = { version = "1.6", optional = true, default-features = false, features = ["derive"] }
ascon = "0.4"
Expand Down
15 changes: 8 additions & 7 deletions ascon-aead/src/asconcore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use aead::{
Error,
array::{Array, ArraySize, typenum::Unsigned},
consts::{U16, U20},
inout::InOutBuf,
};
use ascon::{State, pad};
use subtle::ConstantTimeEq;
Expand Down Expand Up @@ -337,30 +338,30 @@ impl<'a, P: Parameters> AsconCore<'a, P> {
tag
}

pub(crate) fn encrypt_inplace(
pub(crate) fn encrypt_inout(
&mut self,
message: &mut [u8],
mut message: InOutBuf<'_, '_, u8>,
associated_data: &[u8],
) -> Array<u8, U16> {
self.process_associated_data(associated_data);
self.process_encrypt_inplace(message);
self.process_encrypt_inplace(message.get_out());
Array::from(self.process_final())
}

pub(crate) fn decrypt_inplace(
pub(crate) fn decrypt_inout(
&mut self,
ciphertext: &mut [u8],
mut ciphertext: InOutBuf<'_, '_, u8>,
associated_data: &[u8],
expected_tag: &Array<u8, U16>,
) -> Result<(), Error> {
self.process_associated_data(associated_data);
self.process_decrypt_inplace(ciphertext);
self.process_decrypt_inplace(ciphertext.get_out());

let tag = self.process_final();
if bool::from(tag.ct_eq(expected_tag)) {
Ok(())
} else {
ciphertext.fill(0);
ciphertext.get_out().fill(0);
Err(Error)
}
}
Expand Down
4 changes: 2 additions & 2 deletions ascon-aead/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ impl<P: Parameters> AeadInOut for Ascon<P> {
}

let mut core = AsconCore::<P>::new(&self.key, nonce);
Ok(core.encrypt_inplace(buffer, associated_data))
Ok(core.encrypt_inout(buffer, associated_data))
}

fn decrypt_inout_detached(
Expand All @@ -176,7 +176,7 @@ impl<P: Parameters> AeadInOut for Ascon<P> {
}

let mut core = AsconCore::<P>::new(&self.key, nonce);
core.decrypt_inplace(buffer, associated_data, tag)
core.decrypt_inout(buffer, associated_data, tag)
}
}

Expand Down
3 changes: 2 additions & 1 deletion ascon-aead/tests/kats_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ fn run_tv<A: KeyInit + Aead + AeadInOut>(

let bad_tag = Tag::<A>::default();
let mut buf = ciphertext[..ciphertext.len() - bad_tag.len()].to_vec();
let res = core.decrypt_inout_detached(nonce, associated_data, &mut buf, &bad_tag);
let res =
core.decrypt_inout_detached(nonce, associated_data, buf.as_mut_slice().into(), &bad_tag);
assert!(res.is_err());
assert!(buf.iter().all(|b| *b == 0));
}
Expand Down
2 changes: 1 addition & 1 deletion ccm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ keywords = ["encryption", "aead"]
rust-version = "1.85"

[dependencies]
aead = { version = "0.6.0-rc.0", default-features = false }
aead = { version = "0.6.0-rc.0", default-features = false, features = ["inout"] }
cipher = { version = "=0.5.0-pre.8", default-features = false }
ctr = { version = "0.10.0-pre.2", default-features = false }
subtle = { version = "2", default-features = false }
Expand Down
24 changes: 12 additions & 12 deletions ccm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@
//! [aead]: https://docs.rs/aead
//! [1]: https://en.wikipedia.org/wiki/Authenticated_encryption

pub use aead::{self, consts, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser};
pub use aead::{self, AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser, consts};

use aead::{
array::{typenum::Unsigned, Array, ArraySize},
PostfixTagged,
array::{Array, ArraySize, typenum::Unsigned},
consts::U16,
inout::InOutBuf,
PostfixTagged,
};
use cipher::{
Block, BlockCipherEncrypt, BlockSizeUser, InnerIvInit, StreamCipher, StreamCipherSeek,
Expand Down Expand Up @@ -232,9 +232,9 @@ where
&self,
nonce: &Nonce<N>,
adata: &[u8],
buffer: InOutBuf<'_, '_, u8>,
mut buffer: InOutBuf<'_, '_, u8>,
) -> Result<Tag<Self::TagSize>, Error> {
let mut full_tag = self.calc_mac(nonce, adata, buffer)?;
let mut full_tag = self.calc_mac(nonce, adata, buffer.get_in())?;

let ext_nonce = Self::extend_nonce(nonce);
// number of bytes left for counter (max 8)
Expand All @@ -243,11 +243,11 @@ where
if cb > 4 {
let mut ctr = Ctr64BE::from_core(CtrCore::inner_iv_init(&self.cipher, &ext_nonce));
ctr.apply_keystream(&mut full_tag);
ctr.apply_keystream(buffer);
ctr.apply_keystream(buffer.get_out());
} else {
let mut ctr = Ctr32BE::from_core(CtrCore::inner_iv_init(&self.cipher, &ext_nonce));
ctr.apply_keystream(&mut full_tag);
ctr.apply_keystream(buffer);
ctr.apply_keystream(buffer.get_out());
}

Ok(Tag::try_from(&full_tag[..M::to_usize()]).expect("tag size mismatch"))
Expand All @@ -257,7 +257,7 @@ where
&self,
nonce: &Nonce<N>,
adata: &[u8],
buffer: InOutBuf<'_, '_, u8>,
mut buffer: InOutBuf<'_, '_, u8>,
tag: &Tag<Self::TagSize>,
) -> Result<(), Error> {
let ext_nonce = Self::extend_nonce(nonce);
Expand All @@ -267,14 +267,14 @@ where
if cb > 4 {
let mut ctr = Ctr64BE::from_core(CtrCore::inner_iv_init(&self.cipher, &ext_nonce));
ctr.seek(C::BlockSize::USIZE);
ctr.apply_keystream(buffer);
ctr.apply_keystream(buffer.get_out());
} else {
let mut ctr = Ctr32BE::from_core(CtrCore::inner_iv_init(&self.cipher, &ext_nonce));
ctr.seek(C::BlockSize::USIZE);
ctr.apply_keystream(buffer);
ctr.apply_keystream(buffer.get_out());
}

let mut full_tag = self.calc_mac(nonce, adata, buffer)?;
let mut full_tag = self.calc_mac(nonce, adata, buffer.get_in())?;

if cb > 4 {
let mut ctr = Ctr64BE::from_core(CtrCore::inner_iv_init(&self.cipher, &ext_nonce));
Expand All @@ -287,7 +287,7 @@ where
if full_tag[..tag.len()].ct_eq(tag).into() {
Ok(())
} else {
buffer.iter_mut().for_each(|v| *v = 0);
buffer.get_out().fill(0);
Err(Error)
}
}
Expand Down
Loading