ring/aead/
sealing_key.rs

1// Copyright 2015-2021 Brian Smith.
2//
3// Permission to use, copy, modify, and/or distribute this software for any
4// purpose with or without fee is hereby granted, provided that the above
5// copyright notice and this permission notice appear in all copies.
6//
7// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
8// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
10// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15//! Authenticated Encryption with Associated Data (AEAD).
16//!
17//! See [Authenticated encryption: relations among notions and analysis of the
18//! generic composition paradigm][AEAD] for an introduction to the concept of
19//! AEADs.
20//!
21//! [AEAD]: https://eprint.iacr.org/2000/025.pdf
22//! [`crypto.cipher.AEAD`]: https://golang.org/pkg/crypto/cipher/#AEAD
23
24use super::{Aad, Algorithm, BoundKey, LessSafeKey, NonceSequence, Tag, UnboundKey};
25use crate::error;
26
27/// An AEAD key for encrypting and signing ("sealing"), bound to a nonce
28/// sequence.
29///
30/// Intentionally not `Clone` or `Copy` since cloning would allow duplication
31/// of the nonce sequence.
32pub struct SealingKey<N: NonceSequence> {
33    key: LessSafeKey,
34    nonce_sequence: N,
35}
36
37impl<N: NonceSequence> BoundKey<N> for SealingKey<N> {
38    fn new(key: UnboundKey, nonce_sequence: N) -> Self {
39        Self {
40            key: key.into_inner(),
41            nonce_sequence,
42        }
43    }
44
45    #[inline]
46    fn algorithm(&self) -> &'static Algorithm {
47        self.key.algorithm()
48    }
49}
50
51impl<N: NonceSequence> core::fmt::Debug for SealingKey<N> {
52    fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
53        self.key.fmt_debug("SealingKey", f)
54    }
55}
56
57impl<N: NonceSequence> SealingKey<N> {
58    /// Encrypts and signs (“seals”) data in place, appending the tag to the
59    /// resulting ciphertext.
60    ///
61    /// `key.seal_in_place_append_tag(aad, in_out)` is equivalent to:
62    ///
63    /// ```skip
64    /// key.seal_in_place_separate_tag(aad, in_out.as_mut())
65    ///     .map(|tag| in_out.extend(tag.as_ref()))
66    /// ```
67    #[inline]
68    pub fn seal_in_place_append_tag<A, InOut>(
69        &mut self,
70        aad: Aad<A>,
71        in_out: &mut InOut,
72    ) -> Result<(), error::Unspecified>
73    where
74        A: AsRef<[u8]>,
75        InOut: AsMut<[u8]> + for<'in_out> Extend<&'in_out u8>,
76    {
77        self.key
78            .seal_in_place_append_tag(self.nonce_sequence.advance()?, aad, in_out)
79    }
80
81    /// Encrypts and signs (“seals”) data in place.
82    ///
83    /// `aad` is the additional authenticated data (AAD), if any. This is
84    /// authenticated but not encrypted. The type `A` could be a byte slice
85    /// `&[u8]`, a byte array `[u8; N]` for some constant `N`, `Vec<u8>`, etc.
86    /// If there is no AAD then use `Aad::empty()`.
87    ///
88    /// The plaintext is given as the input value of `in_out`. `seal_in_place()`
89    /// will overwrite the plaintext with the ciphertext and return the tag.
90    /// For most protocols, the caller must append the tag to the ciphertext.
91    /// The tag will be `self.algorithm.tag_len()` bytes long.
92    #[inline]
93    pub fn seal_in_place_separate_tag<A>(
94        &mut self,
95        aad: Aad<A>,
96        in_out: &mut [u8],
97    ) -> Result<Tag, error::Unspecified>
98    where
99        A: AsRef<[u8]>,
100    {
101        self.key
102            .seal_in_place_separate_tag(self.nonce_sequence.advance()?, aad, in_out)
103    }
104}