1#[allow(unused_macros)]
5macro_rules! impl_aead {
6 ($impl:ident, $name:expr, $key_len:ident, $nonce_len:ident, $tag_len:ident) => {
7 impl $crate::ciphers::traits::Aead for $impl {
8 type KeyLength = $key_len;
9 type NonceLength = $nonce_len;
10 type TagLength = $tag_len;
11
12 const NAME: &'static str = $name;
13
14 fn encrypt(
17 key: &$crate::ciphers::traits::Key<Self>,
18 nonce: &$crate::ciphers::traits::Nonce<Self>,
19 associated_data: &[u8],
20 plaintext: &[u8],
21 ciphertext: &mut [u8],
22 tag: &mut $crate::ciphers::traits::Tag<Self>,
23 ) -> crate::Result<usize> {
24 use aead::{AeadInPlace, KeyInit};
25
26 if plaintext.len() > ciphertext.len() {
27 return Err($crate::Error::BufferSize {
28 name: "ciphertext",
29 needs: plaintext.len(),
30 has: ciphertext.len(),
31 });
32 }
33
34 ciphertext[..plaintext.len()].copy_from_slice(plaintext);
35
36 let out: $crate::ciphers::traits::Tag<Self> = Self::new(key)
37 .encrypt_in_place_detached(nonce, associated_data, ciphertext)
38 .map_err(|_| $crate::Error::CipherError { alg: Self::NAME })?;
39
40 tag.copy_from_slice(&out);
41
42 Ok(plaintext.len())
43 }
44
45 fn decrypt(
46 key: &$crate::ciphers::traits::Key<Self>,
47 nonce: &$crate::ciphers::traits::Nonce<Self>,
48 associated_data: &[u8],
49 plaintext: &mut [u8],
50 ciphertext: &[u8],
51 tag: &$crate::ciphers::traits::Tag<Self>,
52 ) -> crate::Result<usize> {
53 use aead::{AeadInPlace, KeyInit};
54
55 if ciphertext.len() > plaintext.len() {
56 return Err($crate::Error::BufferSize {
57 name: "plaintext",
58 needs: ciphertext.len(),
59 has: plaintext.len(),
60 });
61 }
62
63 plaintext[..ciphertext.len()].copy_from_slice(ciphertext);
64
65 Self::new(key)
66 .decrypt_in_place_detached(nonce, associated_data, plaintext, tag)
67 .map_err(|_| $crate::Error::CipherError { alg: Self::NAME })?;
68
69 Ok(ciphertext.len())
70 }
71 }
72
73 #[cfg(all(feature = "random", feature = "std"))]
77 pub fn aead_encrypt(key: &[u8], plaintext: &[u8]) -> crate::Result<Vec<u8>> {
78 if key.len() != <$impl as $crate::ciphers::traits::Aead>::KEY_LENGTH {
79 return Err($crate::Error::BufferSize {
80 name: "key",
81 needs: <$impl as $crate::ciphers::traits::Aead>::KEY_LENGTH,
82 has: key.len(),
83 });
84 }
85
86 let mut nonce = [0; <$impl as $crate::ciphers::traits::Aead>::NONCE_LENGTH];
87 let mut tag = vec![0; <$impl as $crate::ciphers::traits::Aead>::TAG_LENGTH];
88 let mut ciphertext = vec![0; plaintext.len()];
89
90 crate::utils::rand::fill(&mut nonce)?;
91
92 <$impl as $crate::ciphers::traits::Aead>::encrypt(
93 $crate::ciphers::traits::Key::<$impl>::from_slice(&key),
94 $crate::ciphers::traits::Nonce::<$impl>::from_slice(&nonce),
95 &[],
96 plaintext,
97 &mut ciphertext,
98 $crate::ciphers::traits::Tag::<$impl>::from_mut_slice(&mut tag),
99 )?;
100
101 let mut ret = nonce.to_vec();
102 ret.append(&mut tag);
103 ret.append(&mut ciphertext);
104
105 Ok(ret)
106 }
107
108 #[cfg(feature = "std")]
112 pub fn aead_decrypt(key: &[u8], ciphertext: &[u8]) -> crate::Result<Vec<u8>> {
113 if key.len() != <$impl as $crate::ciphers::traits::Aead>::KEY_LENGTH {
114 return Err($crate::Error::BufferSize {
115 name: "key",
116 needs: <$impl as $crate::ciphers::traits::Aead>::KEY_LENGTH,
117 has: key.len(),
118 });
119 }
120
121 let nonce = &ciphertext[..<$impl as $crate::ciphers::traits::Aead>::NONCE_LENGTH];
122 let tag = &ciphertext[<$impl as $crate::ciphers::traits::Aead>::NONCE_LENGTH
123 ..<$impl as $crate::ciphers::traits::Aead>::NONCE_LENGTH
124 + <$impl as $crate::ciphers::traits::Aead>::TAG_LENGTH];
125 let ciphertext = &ciphertext[<$impl as $crate::ciphers::traits::Aead>::NONCE_LENGTH
126 + <$impl as $crate::ciphers::traits::Aead>::TAG_LENGTH..];
127 let mut plaintext = vec![0u8; ciphertext.len()];
128
129 <$impl as $crate::ciphers::traits::Aead>::decrypt(
130 $crate::ciphers::traits::Key::<$impl>::from_slice(&key),
131 $crate::ciphers::traits::Nonce::<$impl>::from_slice(&nonce),
132 &[],
133 &mut plaintext,
134 ciphertext,
135 $crate::ciphers::traits::Tag::<$impl>::from_slice(&tag),
136 )?;
137
138 Ok(plaintext)
139 }
140 };
141}