Restore the OpeningKey and SealingKey naming.

Experiments with the `Role` pattern indicate that it might not work as
well as initially hoped. Replace it with the pattern more common in Rust.
This commit is contained in:
Brian Smith 2019-07-13 12:06:28 -10:00
parent 38462247ac
commit c23d537847
2 changed files with 66 additions and 49 deletions

View File

@ -50,64 +50,49 @@ pub trait NonceSequence {
fn advance(&mut self) -> Result<Nonce, error::Unspecified>;
}
mod sealed {
pub trait Role: core::fmt::Debug {
const VALUE: Self;
}
/// An AEAD key bound to a nonce sequence.
pub trait BoundKey<N: NonceSequence>: core::fmt::Debug {
/// Constructs a new key from the given `UnboundKey` and `NonceSequence`.
fn new(key: UnboundKey, nonce_sequence: N) -> Self;
/// The key's AEAD algorithm.
#[inline]
fn algorithm(&self) -> &'static Algorithm;
}
/// The role for which an AEAD key will be used.
pub trait Role: self::sealed::Role {}
impl<R: self::sealed::Role> Role for R {}
/// The key is for opening (authenticating and decrypting).
#[derive(Debug)]
pub struct Opening(());
impl self::sealed::Role for Opening {
const VALUE: Self = Self(());
}
/// The key is for sealing (encrypting and authenticating).
#[derive(Debug)]
pub struct Sealing(());
impl self::sealed::Role for Sealing {
const VALUE: Self = Self(());
}
/// An AEAD key with a designated role and nonce sequence.
pub struct Key<R: Role, N: NonceSequence> {
/// An AEAD key for authenticating and decrypting ("opening"), bound to a nonce
/// sequence.
///
/// Intentionally not `Clone` or `Copy` since cloning would allow duplication
/// of the nonce sequence.
pub struct OpeningKey<N: NonceSequence> {
key: UnboundKey,
nonce_sequence: N,
role: R,
}
impl<R: Role, N: NonceSequence> Key<R, N> {
/// Constructs a new `Key` from the given `UnboundKey` and `NonceSequence`.
pub fn new(key: UnboundKey, nonce_sequence: N) -> Self {
impl<N: NonceSequence> BoundKey<N> for OpeningKey<N> {
fn new(key: UnboundKey, nonce_sequence: N) -> Self {
Self {
key,
nonce_sequence,
role: R::VALUE,
}
}
/// The key's AEAD algorithm.
#[inline(always)]
pub fn algorithm(&self) -> &'static Algorithm {
self.key.algorithm()
#[inline]
fn algorithm(&self) -> &'static Algorithm {
self.key.algorithm
}
}
impl<R: Role, N: NonceSequence> core::fmt::Debug for Key<R, N> {
impl<N: NonceSequence> core::fmt::Debug for OpeningKey<N> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
f.debug_struct("Key")
f.debug_struct("OpeningKey")
.field("algorithm", &self.algorithm())
.field("role", &self.role)
.finish()
}
}
impl<N: NonceSequence> Key<Opening, N> {
impl<N: NonceSequence> OpeningKey<N> {
/// Authenticates and decrypts (“opens”) data in place.
///
/// The input may have a prefix that is `in_prefix_len` bytes long; any such
@ -210,7 +195,39 @@ fn open_in_place_<'a>(
Ok(&mut in_out[..ciphertext_len])
}
impl<N: NonceSequence> Key<Sealing, N> {
/// An AEAD key for encrypting and signing ("sealing"), bound to a nonce
/// sequence.
///
/// Intentionally not `Clone` or `Copy` since cloning would allow duplication
/// of the nonce sequence.
pub struct SealingKey<N: NonceSequence> {
key: UnboundKey,
nonce_sequence: N,
}
impl<N: NonceSequence> BoundKey<N> for SealingKey<N> {
fn new(key: UnboundKey, nonce_sequence: N) -> Self {
Self {
key,
nonce_sequence,
}
}
#[inline]
fn algorithm(&self) -> &'static Algorithm {
self.key.algorithm
}
}
impl<N: NonceSequence> core::fmt::Debug for SealingKey<N> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
f.debug_struct("SealingKey")
.field("algorithm", &self.algorithm())
.finish()
}
}
impl<N: NonceSequence> SealingKey<N> {
/// Encrypts and signs (“seals”) data in place.
///
/// `nonce` must be unique for every use of the key to seal data.
@ -326,8 +343,8 @@ impl UnboundKey {
}
/// The key's AEAD algorithm.
#[inline(always)]
fn algorithm(&self) -> &'static Algorithm {
#[inline]
pub fn algorithm(&self) -> &'static Algorithm {
self.algorithm
}
}

View File

@ -251,7 +251,7 @@ fn seal_with_key(
aad: aead::Aad<&[u8]>,
in_out: &mut [u8],
) -> Result<usize, error::Unspecified> {
let mut s_key = make_key(algorithm, key, nonce);
let mut s_key: aead::SealingKey<OneNonceSequence> = make_key(algorithm, key, nonce);
s_key.seal_in_place(aad, in_out, algorithm.tag_len())
}
@ -263,7 +263,7 @@ fn open_with_key<'a>(
in_prefix_len: usize,
in_out: &'a mut [u8],
) -> Result<&'a mut [u8], error::Unspecified> {
let mut o_key = make_key(algorithm, key, nonce);
let mut o_key: aead::OpeningKey<OneNonceSequence> = make_key(algorithm, key, nonce);
o_key.open_in_place(aad, in_prefix_len, in_out)
}
@ -403,23 +403,23 @@ fn test_aead_key_debug() {
format!("{:?}", key)
);
let sealing_key: aead::Key<aead::Sealing, OneNonceSequence> = make_key(
let sealing_key: aead::SealingKey<OneNonceSequence> = make_key(
&aead::CHACHA20_POLY1305,
&key_bytes,
aead::Nonce::try_assume_unique_for_key(&nonce).unwrap(),
);
assert_eq!(
"Key { algorithm: CHACHA20_POLY1305, role: Sealing(()) }",
"SealingKey { algorithm: CHACHA20_POLY1305 }",
format!("{:?}", sealing_key)
);
let opening_key: aead::Key<aead::Opening, OneNonceSequence> = make_key(
let opening_key: aead::OpeningKey<OneNonceSequence> = make_key(
&aead::AES_256_GCM,
&key_bytes,
aead::Nonce::try_assume_unique_for_key(&nonce).unwrap(),
);
assert_eq!(
"Key { algorithm: AES_256_GCM, role: Opening(()) }",
"OpeningKey { algorithm: AES_256_GCM }",
format!("{:?}", opening_key)
);
@ -427,14 +427,14 @@ fn test_aead_key_debug() {
assert_eq!("Key { algorithm: CHACHA20_POLY1305 }", format!("{:?}", key));
}
fn make_key<R: aead::Role>(
fn make_key<K: aead::BoundKey<OneNonceSequence>>(
algorithm: &'static aead::Algorithm,
key: &[u8],
nonce: aead::Nonce,
) -> aead::Key<R, OneNonceSequence> {
) -> K {
let key = aead::UnboundKey::new(algorithm, key).unwrap();
let nonce_sequence = OneNonceSequence::new(nonce);
aead::Key::new(key, nonce_sequence)
K::new(key, nonce_sequence)
}
fn make_less_safe_key(algorithm: &'static aead::Algorithm, key: &[u8]) -> aead::LessSafeKey {