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 24 use super::{Algorithm, LessSafeKey, MAX_KEY_LEN}; 25 use crate::{error, hkdf}; 26 27 /// An AEAD key without a designated role or nonce sequence. 28 pub struct UnboundKey { 29 inner: LessSafeKey, 30 } 31 32 impl UnboundKey { 33 /// Constructs a `UnboundKey`. 34 /// 35 /// Fails if `key_bytes.len() != algorithm.key_len()`. 36 #[inline] new( algorithm: &'static Algorithm, key_bytes: &[u8], ) -> Result<Self, error::Unspecified>37 pub fn new( 38 algorithm: &'static Algorithm, 39 key_bytes: &[u8], 40 ) -> Result<Self, error::Unspecified> { 41 Ok(Self { 42 inner: LessSafeKey::new_(algorithm, key_bytes)?, 43 }) 44 } 45 46 /// The key's AEAD algorithm. 47 #[inline] algorithm(&self) -> &'static Algorithm48 pub fn algorithm(&self) -> &'static Algorithm { 49 self.inner.algorithm() 50 } 51 52 #[inline] into_inner(self) -> LessSafeKey53 pub(super) fn into_inner(self) -> LessSafeKey { 54 self.inner 55 } 56 } 57 58 impl core::fmt::Debug for UnboundKey { fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error>59 fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> { 60 self.inner.fmt_debug("UnboundKey", f) 61 } 62 } 63 64 impl From<hkdf::Okm<'_, &'static Algorithm>> for UnboundKey { from(okm: hkdf::Okm<&'static Algorithm>) -> Self65 fn from(okm: hkdf::Okm<&'static Algorithm>) -> Self { 66 let mut key_bytes = [0; MAX_KEY_LEN]; 67 let key_bytes = &mut key_bytes[..okm.len().key_len]; 68 let algorithm = *okm.len(); 69 okm.fill(key_bytes).unwrap(); 70 Self { 71 inner: LessSafeKey::new_(algorithm, key_bytes).unwrap(), 72 } 73 } 74 } 75