Allow Aad to own its contents.

This allows `Aad` to be returned by value from functions, which is useful in
many cases.
This commit is contained in:
Brian Smith 2019-01-20 10:17:30 -10:00
parent 7b8bfa745a
commit c1c9c2221e
4 changed files with 54 additions and 20 deletions

View File

@ -100,8 +100,21 @@ impl OpeningKey {
/// and `ciphertext_and_tag_modified_in_place` because Rust's type system
/// does not allow us to have two slices, one mutable and one immutable, that
/// reference overlapping memory.)
pub fn open_in_place<'a>(
key: &OpeningKey, nonce: Nonce, aad: Aad, in_prefix_len: usize,
pub fn open_in_place<'a, A: AsRef<[u8]>>(
key: &OpeningKey, nonce: Nonce, Aad(aad): Aad<A>, in_prefix_len: usize,
ciphertext_and_tag_modified_in_place: &'a mut [u8],
) -> Result<&'a mut [u8], error::Unspecified> {
open_in_place_(
key,
nonce,
Aad::from(aad.as_ref()),
in_prefix_len,
ciphertext_and_tag_modified_in_place,
)
}
fn open_in_place_<'a>(
key: &OpeningKey, nonce: Nonce, aad: Aad<&[u8]>, in_prefix_len: usize,
ciphertext_and_tag_modified_in_place: &'a mut [u8],
) -> Result<&'a mut [u8], error::Unspecified> {
let ciphertext_and_tag_len = ciphertext_and_tag_modified_in_place
@ -168,8 +181,20 @@ impl SealingKey {
/// also `MAX_TAG_LEN`.
///
/// `aad` is the additional authenticated data, if any.
pub fn seal_in_place(
key: &SealingKey, nonce: Nonce, aad: Aad, in_out: &mut [u8], out_suffix_capacity: usize,
pub fn seal_in_place<A: AsRef<[u8]>>(
key: &SealingKey, nonce: Nonce, Aad(aad): Aad<A>, in_out: &mut [u8], out_suffix_capacity: usize,
) -> Result<usize, error::Unspecified> {
seal_in_place_(
key,
nonce,
Aad::from(aad.as_ref()),
in_out,
out_suffix_capacity,
)
}
fn seal_in_place_(
key: &SealingKey, nonce: Nonce, aad: Aad<&[u8]>, in_out: &mut [u8], out_suffix_capacity: usize,
) -> Result<usize, error::Unspecified> {
if out_suffix_capacity < key.key.algorithm.tag_len() {
return Err(error::Unspecified);
@ -191,17 +216,17 @@ pub fn seal_in_place(
/// The additionally authenticated data (AAD) for an opening or sealing
/// operation. This data is authenticated but is **not** encrypted.
#[repr(transparent)]
pub struct Aad<'a>(&'a [u8]);
pub struct Aad<A: AsRef<[u8]>>(A);
impl<'a> Aad<'a> {
/// Construct the `Aad` by borrowing a contiguous sequence of bytes.
impl<A: AsRef<[u8]>> Aad<A> {
/// Construct the `Aad` from the given bytes.
#[inline]
pub fn from(aad: &'a [u8]) -> Self { Aad(aad) }
pub fn from(aad: A) -> Self { Aad(aad) }
}
impl Aad<'static> {
impl Aad<[u8; 0]> {
/// Construct an empty `Aad`.
pub fn empty() -> Self { Self::from(&[]) }
pub fn empty() -> Self { Self::from([]) }
}
/// `OpeningKey` and `SealingKey` are type-safety wrappers around `Key`, which
@ -235,9 +260,14 @@ impl Key {
pub struct Algorithm {
init: fn(key: &[u8]) -> Result<KeyInner, error::Unspecified>,
seal: fn(key: &KeyInner, nonce: Nonce, aad: Aad, in_out: &mut [u8]) -> Tag,
open:
fn(key: &KeyInner, nonce: Nonce, aad: Aad, in_prefix_len: usize, in_out: &mut [u8]) -> Tag,
seal: fn(key: &KeyInner, nonce: Nonce, aad: Aad<&[u8]>, in_out: &mut [u8]) -> Tag,
open: fn(
key: &KeyInner,
nonce: Nonce,
aad: Aad<&[u8]>,
in_prefix_len: usize,
in_out: &mut [u8],
) -> Tag,
key_len: usize,
id: AlgorithmID,

View File

@ -59,12 +59,12 @@ fn init(key: &[u8], variant: aes::Variant) -> Result<aead::KeyInner, error::Unsp
const CHUNK_BLOCKS: usize = 3 * 1024 / 16;
fn aes_gcm_seal(key: &aead::KeyInner, nonce: Nonce, aad: Aad, in_out: &mut [u8]) -> Tag {
fn aes_gcm_seal(key: &aead::KeyInner, nonce: Nonce, aad: Aad<&[u8]>, in_out: &mut [u8]) -> Tag {
aead(key, nonce, aad, in_out, Direction::Sealing)
}
fn aes_gcm_open(
key: &aead::KeyInner, nonce: Nonce, aad: Aad, in_prefix_len: usize, in_out: &mut [u8],
key: &aead::KeyInner, nonce: Nonce, aad: Aad<&[u8]>, in_prefix_len: usize, in_out: &mut [u8],
) -> Tag {
aead(
key,
@ -77,7 +77,8 @@ fn aes_gcm_open(
#[inline(always)] // Avoid branching on `direction`.
fn aead(
key: &aead::KeyInner, nonce: Nonce, aad: Aad, in_out: &mut [u8], direction: Direction) -> Tag {
key: &aead::KeyInner, nonce: Nonce, aad: Aad<&[u8]>, in_out: &mut [u8], direction: Direction,
) -> Tag {
let Key { aes_key, gcm_key } = match key {
aead::KeyInner::AesGcm(key) => key,
_ => unreachable!(),

View File

@ -44,12 +44,14 @@ fn chacha20_poly1305_init(key: &[u8]) -> Result<aead::KeyInner, error::Unspecifi
Ok(aead::KeyInner::ChaCha20Poly1305(chacha::Key::from(key)))
}
fn chacha20_poly1305_seal(key: &aead::KeyInner, nonce: Nonce, aad: Aad, in_out: &mut [u8]) -> Tag {
fn chacha20_poly1305_seal(
key: &aead::KeyInner, nonce: Nonce, aad: Aad<&[u8]>, in_out: &mut [u8],
) -> Tag {
aead(key, nonce, aad, in_out, Direction::Sealing)
}
fn chacha20_poly1305_open(
key: &aead::KeyInner, nonce: Nonce, aad: Aad, in_prefix_len: usize, in_out: &mut [u8],
key: &aead::KeyInner, nonce: Nonce, aad: Aad<&[u8]>, in_prefix_len: usize, in_out: &mut [u8],
) -> Tag {
aead(
key,
@ -64,7 +66,8 @@ pub type Key = chacha::Key;
#[inline(always)] // Statically eliminate branches on `direction`.
fn aead(
key: &aead::KeyInner, nonce: Nonce, Aad(aad): Aad, in_out: &mut [u8], direction: Direction,
key: &aead::KeyInner, nonce: Nonce, Aad(aad): Aad<&[u8]>, in_out: &mut [u8],
direction: Direction,
) -> Tag {
let chacha20_key = match key {
aead::KeyInner::ChaCha20Poly1305(key) => key,

View File

@ -38,7 +38,7 @@ impl Key {
pub struct Context(GCM128_CONTEXT);
impl Context {
pub fn new(key: &Key, aad: Aad) -> Self {
pub fn new(key: &Key, aad: Aad<&[u8]>) -> Self {
let mut ctx = Context(GCM128_CONTEXT {
Xi: Block::zero(),
H_unused: Block::zero(),