1pub use aead::{AeadCore, AeadInPlace, Buffer, Error, KeyInit, KeySizeUser};
4
5#[cfg(feature = "alloc")]
6pub use aead::{Aead, Payload};
7
8use aead::{
9 consts::{U0, U12, U16, U32},
10 generic_array::GenericArray,
11};
12use ring::aead::{
13 Aad, LessSafeKey as Key, Nonce, UnboundKey, AES_128_GCM, AES_256_GCM, CHACHA20_POLY1305,
14};
15
16pub type Tag = GenericArray<u8, U16>;
18
19pub struct Aes128Gcm(Cipher);
21
22pub struct Aes256Gcm(Cipher);
24
25pub struct ChaCha20Poly1305(Cipher);
27
28macro_rules! impl_aead {
29 ($cipher:ty, $algorithm:expr, $key_size:ty) => {
30 impl KeySizeUser for $cipher {
31 type KeySize = $key_size;
32 }
33
34 impl KeyInit for $cipher {
35 fn new(key: &GenericArray<u8, Self::KeySize>) -> Self {
36 let key = UnboundKey::new(&$algorithm, key.as_slice()).unwrap();
37 Self(Cipher::new(key))
38 }
39 }
40
41 impl AeadCore for $cipher {
42 type NonceSize = U12;
43 type TagSize = U16;
44 type CiphertextOverhead = U0;
45 }
46
47 impl AeadInPlace for $cipher {
48 fn encrypt_in_place_detached(
49 &self,
50 nonce: &GenericArray<u8, Self::NonceSize>,
51 associated_data: &[u8],
52 buffer: &mut [u8],
53 ) -> Result<Tag, Error> {
54 self.0
55 .encrypt_in_place_detached(nonce.as_slice(), associated_data, buffer)
56 }
57
58 fn decrypt_in_place(
59 &self,
60 nonce: &GenericArray<u8, Self::NonceSize>,
61 associated_data: &[u8],
62 buffer: &mut dyn Buffer,
63 ) -> Result<(), Error> {
64 self.0
65 .decrypt_in_place(nonce.as_slice(), associated_data, buffer)
66 }
67
68 fn decrypt_in_place_detached(
69 &self,
70 _nonce: &GenericArray<u8, Self::NonceSize>,
71 _associated_data: &[u8],
72 _buffer: &mut [u8],
73 _tag: &Tag,
74 ) -> Result<(), Error> {
75 unimplemented!(); }
77 }
78 };
79}
80
81impl_aead!(Aes128Gcm, AES_128_GCM, U16);
82impl_aead!(Aes256Gcm, AES_256_GCM, U32);
83impl_aead!(ChaCha20Poly1305, CHACHA20_POLY1305, U32);
84
85pub(crate) struct Cipher(Key);
87
88impl Cipher {
89 pub fn new(key: UnboundKey) -> Self {
91 Cipher(Key::new(key))
92 }
93
94 fn encrypt_in_place_detached(
96 &self,
97 nonce: &[u8],
98 associated_data: &[u8],
99 buffer: &mut [u8],
100 ) -> Result<Tag, Error> {
101 self.0
102 .seal_in_place_separate_tag(
103 Nonce::try_assume_unique_for_key(nonce).map_err(|_| Error)?,
104 Aad::from(associated_data),
105 buffer,
106 )
107 .map(|tag| Tag::clone_from_slice(tag.as_ref()))
108 .map_err(|_| Error)
109 }
110
111 fn decrypt_in_place(
112 &self,
113 nonce: &[u8],
114 associated_data: &[u8],
115 buffer: &mut dyn Buffer,
116 ) -> Result<(), Error> {
117 let pt_len = self
118 .0
119 .open_in_place(
120 Nonce::try_assume_unique_for_key(nonce).map_err(|_| Error)?,
121 Aad::from(associated_data),
122 buffer.as_mut(),
123 )
124 .map_err(|_| Error)?
125 .len();
126
127 buffer.truncate(pt_len);
128 Ok(())
129 }
130}