/rust/git/checkouts/nss-rs-71e20fe79ef91440/9b94ca3/src/aead/mod.rs
Line | Count | Source |
1 | | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
2 | | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
3 | | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your |
4 | | // option. This file may not be copied, modified, or distributed |
5 | | // except according to those terms. |
6 | | |
7 | | use std::{os::raw::c_int, ptr::null_mut}; |
8 | | |
9 | | #[cfg(feature = "disable-encryption")] |
10 | | pub use recprot::AEAD_NULL_TAG; |
11 | | pub use recprot::RecordProtection; |
12 | | |
13 | | use crate::{ |
14 | | SECItemBorrowed, SymKey, |
15 | | err::{Error, Res}, |
16 | | p11::{ |
17 | | self, CK_ATTRIBUTE_TYPE, CK_GENERATOR_FUNCTION, CK_MECHANISM_TYPE, CKA_DECRYPT, |
18 | | CKA_ENCRYPT, CKA_NSS_MESSAGE, CKG_GENERATE_COUNTER_XOR, CKG_NO_GENERATE, CKM_AES_GCM, |
19 | | CKM_CHACHA20_POLY1305, Context, PK11_AEADOp, PK11_CreateContextBySymKey, |
20 | | }, |
21 | | secstatus_to_res, |
22 | | }; |
23 | | |
24 | | #[cfg_attr(feature = "disable-encryption", path = "recprot_null.rs")] |
25 | | #[cfg_attr(not(feature = "disable-encryption"), path = "recprot.rs")] |
26 | | mod recprot; |
27 | | |
28 | | /// All the nonces are the same length. Exploit that. |
29 | | pub const NONCE_LEN: usize = 12; |
30 | | |
31 | | /// The portion of the nonce that is a counter. |
32 | | const COUNTER_LEN: usize = size_of::<SequenceNumber>(); |
33 | | |
34 | 4.06k | fn xor_nonce(base: &[u8; NONCE_LEN], count: SequenceNumber) -> [u8; NONCE_LEN] { |
35 | 4.06k | let mut nonce = *base; |
36 | 32.4k | for (n, &s) in nonce[NONCE_LEN - COUNTER_LEN..] |
37 | 4.06k | .iter_mut() |
38 | 4.06k | .zip(&count.to_be_bytes()) |
39 | 32.4k | { |
40 | 32.4k | *n ^= s; |
41 | 32.4k | } |
42 | 4.06k | nonce |
43 | 4.06k | } |
44 | | |
45 | | /// The NSS API insists on us identifying the tag separately, which is awful. |
46 | | /// All of the AEAD functions here have a tag of this length, so use a fixed offset. |
47 | | const TAG_LEN: usize = 16; |
48 | | |
49 | | pub type SequenceNumber = u64; |
50 | | |
51 | | /// All the lengths used by `PK11_AEADOp` are signed. This converts to that. |
52 | 24.3k | fn c_int_len<T>(l: T) -> Res<c_int> |
53 | 24.3k | where |
54 | 24.3k | T: TryInto<c_int>, |
55 | 24.3k | T::Error: std::error::Error, |
56 | | { |
57 | 24.3k | l.try_into().map_err(|_| Error::IntegerOverflow) |
58 | 24.3k | } |
59 | | |
60 | | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
61 | | pub enum Mode { |
62 | | Encrypt, |
63 | | Decrypt, |
64 | | } |
65 | | |
66 | | impl Mode { |
67 | 0 | fn p11mode(self) -> CK_ATTRIBUTE_TYPE { |
68 | 0 | CK_ATTRIBUTE_TYPE::from( |
69 | | CKA_NSS_MESSAGE |
70 | 0 | | match self { |
71 | 0 | Self::Encrypt => CKA_ENCRYPT, |
72 | 0 | Self::Decrypt => CKA_DECRYPT, |
73 | | }, |
74 | | ) |
75 | 0 | } |
76 | | } |
77 | | |
78 | | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
79 | | pub enum AeadAlgorithms { |
80 | | Aes128Gcm, |
81 | | Aes256Gcm, |
82 | | ChaCha20Poly1305, |
83 | | } |
84 | | |
85 | | pub struct Aead { |
86 | | mode: Mode, |
87 | | ctx: Context, |
88 | | nonce_base: [u8; NONCE_LEN], |
89 | | } |
90 | | |
91 | | impl Aead { |
92 | 0 | fn mech(algorithm: AeadAlgorithms) -> CK_MECHANISM_TYPE { |
93 | 0 | CK_MECHANISM_TYPE::from(match algorithm { |
94 | 0 | AeadAlgorithms::Aes128Gcm | AeadAlgorithms::Aes256Gcm => CKM_AES_GCM, |
95 | 0 | AeadAlgorithms::ChaCha20Poly1305 => CKM_CHACHA20_POLY1305, |
96 | | }) |
97 | 0 | } |
98 | | |
99 | 0 | pub fn import_key(algorithm: AeadAlgorithms, key: &[u8]) -> Result<SymKey, Error> { |
100 | 0 | let slot = p11::Slot::internal().map_err(|_| Error::Internal)?; |
101 | | |
102 | 0 | let key_item = SECItemBorrowed::wrap(key)?; |
103 | 0 | let key_item_ptr = std::ptr::from_ref(key_item.as_ref()).cast_mut(); |
104 | | |
105 | 0 | let ptr = unsafe { |
106 | 0 | p11::PK11_ImportSymKey( |
107 | 0 | *slot, |
108 | 0 | Self::mech(algorithm), |
109 | | p11::PK11Origin::PK11_OriginUnwrap, |
110 | 0 | CK_ATTRIBUTE_TYPE::from(CKA_ENCRYPT | CKA_DECRYPT), |
111 | 0 | key_item_ptr, |
112 | 0 | null_mut(), |
113 | | ) |
114 | | }; |
115 | 0 | SymKey::from_ptr(ptr) |
116 | 0 | } |
117 | | |
118 | 0 | pub fn new( |
119 | 0 | mode: Mode, |
120 | 0 | algorithm: AeadAlgorithms, |
121 | 0 | key: &SymKey, |
122 | 0 | nonce_base: [u8; NONCE_LEN], |
123 | 0 | ) -> Result<Self, Error> { |
124 | 0 | crate::init()?; |
125 | | |
126 | 0 | let ptr = unsafe { |
127 | 0 | PK11_CreateContextBySymKey( |
128 | 0 | Self::mech(algorithm), |
129 | 0 | mode.p11mode(), |
130 | 0 | **key, |
131 | 0 | SECItemBorrowed::wrap(&nonce_base[..])?.as_ref(), |
132 | | ) |
133 | | }; |
134 | | Ok(Self { |
135 | 0 | mode, |
136 | 0 | ctx: Context::from_ptr(ptr)?, |
137 | 0 | nonce_base, |
138 | | }) |
139 | 0 | } |
140 | | |
141 | 0 | pub fn encrypt(&mut self, aad: &[u8], pt: &[u8]) -> Result<Vec<u8>, Error> { |
142 | 0 | crate::init()?; |
143 | | |
144 | 0 | assert_eq!(self.mode, Mode::Encrypt); |
145 | | // A copy for the nonce generator to write into. But we don't use the value. |
146 | 0 | let mut nonce = self.nonce_base; |
147 | | // Ciphertext with enough space for the tag. |
148 | | // Even though we give the operation a separate buffer for the tag, |
149 | | // reserve the capacity on allocation. |
150 | 0 | let mut ct = vec![0; pt.len() + TAG_LEN]; |
151 | 0 | let mut ct_len: c_int = 0; |
152 | 0 | let mut tag = vec![0; TAG_LEN]; |
153 | 0 | secstatus_to_res(unsafe { |
154 | 0 | PK11_AEADOp( |
155 | 0 | *self.ctx, |
156 | 0 | CK_GENERATOR_FUNCTION::from(CKG_GENERATE_COUNTER_XOR), |
157 | 0 | c_int_len(NONCE_LEN - COUNTER_LEN)?, // Fixed portion of the nonce. |
158 | 0 | nonce.as_mut_ptr(), |
159 | 0 | c_int_len(nonce.len())?, |
160 | 0 | aad.as_ptr(), |
161 | 0 | c_int_len(aad.len())?, |
162 | 0 | ct.as_mut_ptr(), |
163 | 0 | &raw mut ct_len, |
164 | 0 | c_int_len(ct.len())?, // signed :( |
165 | 0 | tag.as_mut_ptr(), |
166 | 0 | c_int_len(tag.len())?, |
167 | 0 | pt.as_ptr(), |
168 | 0 | c_int_len(pt.len())?, |
169 | | ) |
170 | 0 | })?; |
171 | 0 | ct.truncate(usize::try_from(ct_len).map_err(|_| Error::IntegerOverflow)?); |
172 | 0 | debug_assert_eq!(ct.len(), pt.len()); |
173 | 0 | ct.append(&mut tag); |
174 | 0 | Ok(ct) |
175 | 0 | } |
176 | | |
177 | | /// Encrypt with an explicit sequence number. Mirrors `decrypt`'s nonce |
178 | | /// construction: the final nonce is `nonce_base XOR encode_be(seq)` over |
179 | | /// the trailing 8 bytes. The NSS PKCS#11 context's internal counter is |
180 | | /// not used (`CKG_NO_GENERATE`). The caller must never reuse |
181 | | /// `(nonce_base, seq)` with the same key. |
182 | 0 | pub fn encrypt_with_seq( |
183 | 0 | &mut self, |
184 | 0 | aad: &[u8], |
185 | 0 | seq: SequenceNumber, |
186 | 0 | pt: &[u8], |
187 | 0 | ) -> Result<Vec<u8>, Error> { |
188 | 0 | crate::init()?; |
189 | | |
190 | 0 | assert_eq!(self.mode, Mode::Encrypt); |
191 | 0 | let mut nonce = xor_nonce(&self.nonce_base, seq); |
192 | 0 | let mut ct = vec![0; pt.len() + TAG_LEN]; |
193 | 0 | let mut ct_len: c_int = 0; |
194 | 0 | let mut tag = vec![0; TAG_LEN]; |
195 | 0 | secstatus_to_res(unsafe { |
196 | 0 | PK11_AEADOp( |
197 | 0 | *self.ctx, |
198 | 0 | CK_GENERATOR_FUNCTION::from(CKG_NO_GENERATE), |
199 | 0 | c_int_len(NONCE_LEN - COUNTER_LEN)?, |
200 | 0 | nonce.as_mut_ptr(), |
201 | 0 | c_int_len(nonce.len())?, |
202 | 0 | aad.as_ptr(), |
203 | 0 | c_int_len(aad.len())?, |
204 | 0 | ct.as_mut_ptr(), |
205 | 0 | &raw mut ct_len, |
206 | 0 | c_int_len(ct.len())?, |
207 | 0 | tag.as_mut_ptr(), |
208 | 0 | c_int_len(tag.len())?, |
209 | 0 | pt.as_ptr(), |
210 | 0 | c_int_len(pt.len())?, |
211 | | ) |
212 | 0 | })?; |
213 | 0 | ct.truncate(usize::try_from(ct_len).map_err(|_| Error::IntegerOverflow)?); |
214 | 0 | debug_assert_eq!(ct.len(), pt.len()); |
215 | 0 | ct.append(&mut tag); |
216 | 0 | Ok(ct) |
217 | 0 | } |
218 | | |
219 | 0 | pub fn decrypt( |
220 | 0 | &mut self, |
221 | 0 | aad: &[u8], |
222 | 0 | seq: SequenceNumber, |
223 | 0 | ct: &[u8], |
224 | 0 | ) -> Result<Vec<u8>, Error> { |
225 | 0 | crate::init()?; |
226 | | |
227 | 0 | assert_eq!(self.mode, Mode::Decrypt); |
228 | 0 | let mut nonce = xor_nonce(&self.nonce_base, seq); |
229 | 0 | let mut pt = vec![0; ct.len()]; // NSS needs more space than it uses for plaintext. |
230 | 0 | let mut pt_len: c_int = 0; |
231 | 0 | let pt_expected = ct.len().checked_sub(TAG_LEN).ok_or(Error::AeadTruncated)?; |
232 | 0 | secstatus_to_res(unsafe { |
233 | 0 | PK11_AEADOp( |
234 | 0 | *self.ctx, |
235 | 0 | CK_GENERATOR_FUNCTION::from(CKG_NO_GENERATE), |
236 | 0 | c_int_len(NONCE_LEN - COUNTER_LEN)?, // Fixed portion of the nonce. |
237 | 0 | nonce.as_mut_ptr(), |
238 | 0 | c_int_len(nonce.len())?, |
239 | 0 | aad.as_ptr(), |
240 | 0 | c_int_len(aad.len())?, |
241 | 0 | pt.as_mut_ptr(), |
242 | 0 | &raw mut pt_len, |
243 | 0 | c_int_len(pt.len())?, |
244 | 0 | ct.as_ptr().add(pt_expected).cast_mut(), |
245 | 0 | c_int_len(TAG_LEN)?, |
246 | 0 | ct.as_ptr(), |
247 | 0 | c_int_len(pt_expected)?, |
248 | | ) |
249 | 0 | })?; |
250 | 0 | let len = usize::try_from(pt_len).map_err(|_| Error::IntegerOverflow)?; |
251 | 0 | debug_assert_eq!(len, pt_expected); |
252 | 0 | pt.truncate(len); |
253 | 0 | Ok(pt) |
254 | 0 | } |
255 | | } |
256 | | |
257 | | #[cfg(test)] |
258 | | mod test { |
259 | | use test_fixture::fixture_init; |
260 | | |
261 | | use crate::aead::{Aead, AeadAlgorithms, Mode, NONCE_LEN, SequenceNumber}; |
262 | | |
263 | | /// Check that the first invocation of encryption matches expected values. |
264 | | /// Also check decryption of the same. |
265 | | fn check0( |
266 | | algorithm: AeadAlgorithms, |
267 | | key: &[u8], |
268 | | nonce: &[u8; NONCE_LEN], |
269 | | aad: &[u8], |
270 | | pt: &[u8], |
271 | | ct: &[u8], |
272 | | ) { |
273 | | fixture_init(); |
274 | | let k = Aead::import_key(algorithm, key).unwrap(); |
275 | | |
276 | | let mut enc = Aead::new(Mode::Encrypt, algorithm, &k, *nonce).unwrap(); |
277 | | let ciphertext = enc.encrypt(aad, pt).unwrap(); |
278 | | assert_eq!(&ciphertext[..], ct); |
279 | | |
280 | | let mut dec = Aead::new(Mode::Decrypt, algorithm, &k, *nonce).unwrap(); |
281 | | let plaintext = dec.decrypt(aad, 0, ct).unwrap(); |
282 | | assert_eq!(&plaintext[..], pt); |
283 | | } |
284 | | |
285 | | fn decrypt( |
286 | | algorithm: AeadAlgorithms, |
287 | | key: &[u8], |
288 | | nonce: &[u8; NONCE_LEN], |
289 | | seq: SequenceNumber, |
290 | | aad: &[u8], |
291 | | pt: &[u8], |
292 | | ct: &[u8], |
293 | | ) { |
294 | | let k = Aead::import_key(algorithm, key).unwrap(); |
295 | | let mut dec = Aead::new(Mode::Decrypt, algorithm, &k, *nonce).unwrap(); |
296 | | let plaintext = dec.decrypt(aad, seq, ct).unwrap(); |
297 | | assert_eq!(&plaintext[..], pt); |
298 | | } |
299 | | |
300 | | /// This tests the AEAD in QUIC in combination with the HKDF code. |
301 | | /// This is an AEAD-only example. |
302 | | #[test] |
303 | | fn quic_retry() { |
304 | | const KEY: &[u8] = &[ |
305 | | 0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66, 0x57, 0x5a, 0x1d, 0x76, 0x6b, 0x54, 0xe3, 0x68, |
306 | | 0xc8, 0x4e, |
307 | | ]; |
308 | | const NONCE: &[u8; NONCE_LEN] = &[ |
309 | | 0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb, |
310 | | ]; |
311 | | const AAD: &[u8] = &[ |
312 | | 0x08, 0x83, 0x94, 0xc8, 0xf0, 0x3e, 0x51, 0x57, 0x08, 0xff, 0x00, 0x00, 0x00, 0x01, |
313 | | 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a, 0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, |
314 | | 0x6e, |
315 | | ]; |
316 | | const CT: &[u8] = &[ |
317 | | 0x04, 0xa2, 0x65, 0xba, 0x2e, 0xff, 0x4d, 0x82, 0x90, 0x58, 0xfb, 0x3f, 0x0f, 0x24, |
318 | | 0x96, 0xba, |
319 | | ]; |
320 | | check0(AeadAlgorithms::Aes128Gcm, KEY, NONCE, AAD, &[], CT); |
321 | | } |
322 | | |
323 | | #[test] |
324 | | fn quic_server_initial() { |
325 | | const ALG: AeadAlgorithms = AeadAlgorithms::Aes128Gcm; |
326 | | const KEY: &[u8] = &[ |
327 | | 0xcf, 0x3a, 0x53, 0x31, 0x65, 0x3c, 0x36, 0x4c, 0x88, 0xf0, 0xf3, 0x79, 0xb6, 0x06, |
328 | | 0x7e, 0x37, |
329 | | ]; |
330 | | const NONCE_BASE: &[u8; NONCE_LEN] = &[ |
331 | | 0x0a, 0xc1, 0x49, 0x3c, 0xa1, 0x90, 0x58, 0x53, 0xb0, 0xbb, 0xa0, 0x3e, |
332 | | ]; |
333 | | // Note that this integrates the sequence number of 1 from the example, |
334 | | // otherwise we can't use a sequence number of 0 to encrypt. |
335 | | const NONCE: &[u8; NONCE_LEN] = &[ |
336 | | 0x0a, 0xc1, 0x49, 0x3c, 0xa1, 0x90, 0x58, 0x53, 0xb0, 0xbb, 0xa0, 0x3f, |
337 | | ]; |
338 | | const AAD: &[u8] = &[ |
339 | | 0xc1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a, 0x42, 0x62, |
340 | | 0xb5, 0x00, 0x40, 0x75, 0x00, 0x01, |
341 | | ]; |
342 | | const PT: &[u8] = &[ |
343 | | 0x02, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x5a, 0x02, 0x00, 0x00, 0x56, 0x03, |
344 | | 0x03, 0xee, 0xfc, 0xe7, 0xf7, 0xb3, 0x7b, 0xa1, 0xd1, 0x63, 0x2e, 0x96, 0x67, 0x78, |
345 | | 0x25, 0xdd, 0xf7, 0x39, 0x88, 0xcf, 0xc7, 0x98, 0x25, 0xdf, 0x56, 0x6d, 0xc5, 0x43, |
346 | | 0x0b, 0x9a, 0x04, 0x5a, 0x12, 0x00, 0x13, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x33, 0x00, |
347 | | 0x24, 0x00, 0x1d, 0x00, 0x20, 0x9d, 0x3c, 0x94, 0x0d, 0x89, 0x69, 0x0b, 0x84, 0xd0, |
348 | | 0x8a, 0x60, 0x99, 0x3c, 0x14, 0x4e, 0xca, 0x68, 0x4d, 0x10, 0x81, 0x28, 0x7c, 0x83, |
349 | | 0x4d, 0x53, 0x11, 0xbc, 0xf3, 0x2b, 0xb9, 0xda, 0x1a, 0x00, 0x2b, 0x00, 0x02, 0x03, |
350 | | 0x04, |
351 | | ]; |
352 | | const CT: &[u8] = &[ |
353 | | 0x5a, 0x48, 0x2c, 0xd0, 0x99, 0x1c, 0xd2, 0x5b, 0x0a, 0xac, 0x40, 0x6a, 0x58, 0x16, |
354 | | 0xb6, 0x39, 0x41, 0x00, 0xf3, 0x7a, 0x1c, 0x69, 0x79, 0x75, 0x54, 0x78, 0x0b, 0xb3, |
355 | | 0x8c, 0xc5, 0xa9, 0x9f, 0x5e, 0xde, 0x4c, 0xf7, 0x3c, 0x3e, 0xc2, 0x49, 0x3a, 0x18, |
356 | | 0x39, 0xb3, 0xdb, 0xcb, 0xa3, 0xf6, 0xea, 0x46, 0xc5, 0xb7, 0x68, 0x4d, 0xf3, 0x54, |
357 | | 0x8e, 0x7d, 0xde, 0xb9, 0xc3, 0xbf, 0x9c, 0x73, 0xcc, 0x3f, 0x3b, 0xde, 0xd7, 0x4b, |
358 | | 0x56, 0x2b, 0xfb, 0x19, 0xfb, 0x84, 0x02, 0x2f, 0x8e, 0xf4, 0xcd, 0xd9, 0x37, 0x95, |
359 | | 0xd7, 0x7d, 0x06, 0xed, 0xbb, 0x7a, 0xaf, 0x2f, 0x58, 0x89, 0x18, 0x50, 0xab, 0xbd, |
360 | | 0xca, 0x3d, 0x20, 0x39, 0x8c, 0x27, 0x64, 0x56, 0xcb, 0xc4, 0x21, 0x58, 0x40, 0x7d, |
361 | | 0xd0, 0x74, 0xee, |
362 | | ]; |
363 | | check0(ALG, KEY, NONCE, AAD, PT, CT); |
364 | | decrypt(ALG, KEY, NONCE_BASE, 1, AAD, PT, CT); |
365 | | } |
366 | | |
367 | | #[test] |
368 | | fn quic_chacha() { |
369 | | const ALG: AeadAlgorithms = AeadAlgorithms::ChaCha20Poly1305; |
370 | | const KEY: &[u8] = &[ |
371 | | 0xc6, 0xd9, 0x8f, 0xf3, 0x44, 0x1c, 0x3f, 0xe1, 0xb2, 0x18, 0x20, 0x94, 0xf6, 0x9c, |
372 | | 0xaa, 0x2e, 0xd4, 0xb7, 0x16, 0xb6, 0x54, 0x88, 0x96, 0x0a, 0x7a, 0x98, 0x49, 0x79, |
373 | | 0xfb, 0x23, 0xe1, 0xc8, |
374 | | ]; |
375 | | const NONCE_BASE: &[u8; NONCE_LEN] = &[ |
376 | | 0xe0, 0x45, 0x9b, 0x34, 0x74, 0xbd, 0xd0, 0xe4, 0x4a, 0x41, 0xc1, 0x44, |
377 | | ]; |
378 | | // Note that this integrates the sequence number of 654360564 from the example, |
379 | | // otherwise we can't use a sequence number of 0 to encrypt. |
380 | | const NONCE: &[u8; NONCE_LEN] = &[ |
381 | | 0xe0, 0x45, 0x9b, 0x34, 0x74, 0xbd, 0xd0, 0xe4, 0x6d, 0x41, 0x7e, 0xb0, |
382 | | ]; |
383 | | const AAD: &[u8] = &[0x42, 0x00, 0xbf, 0xf4]; |
384 | | const PT: &[u8] = &[0x01]; |
385 | | const CT: &[u8] = &[ |
386 | | 0x65, 0x5e, 0x5c, 0xd5, 0x5c, 0x41, 0xf6, 0x90, 0x80, 0x57, 0x5d, 0x79, 0x99, 0xc2, |
387 | | 0x5a, 0x5b, 0xfb, |
388 | | ]; |
389 | | check0(ALG, KEY, NONCE, AAD, PT, CT); |
390 | | // Now use the real nonce and sequence number from the example. |
391 | | decrypt(ALG, KEY, NONCE_BASE, 654_360_564, AAD, PT, CT); |
392 | | } |
393 | | |
394 | | fn roundtrip_encrypt_with_seq(algorithm: AeadAlgorithms, key: &[u8]) { |
395 | | const NONCE_BASE: [u8; NONCE_LEN] = [0; NONCE_LEN]; |
396 | | const AAD: &[u8] = b"associated"; |
397 | | const PT: &[u8] = b"hello sframe"; |
398 | | const SEQ: SequenceNumber = 0x0123_4567_89ab; |
399 | | |
400 | | fixture_init(); |
401 | | |
402 | | let k = Aead::import_key(algorithm, key).unwrap(); |
403 | | let mut enc = Aead::new(Mode::Encrypt, algorithm, &k, NONCE_BASE).unwrap(); |
404 | | let ct = enc.encrypt_with_seq(AAD, SEQ, PT).unwrap(); |
405 | | |
406 | | let mut dec = Aead::new(Mode::Decrypt, algorithm, &k, NONCE_BASE).unwrap(); |
407 | | let pt = dec.decrypt(AAD, SEQ, &ct).unwrap(); |
408 | | assert_eq!(&pt[..], PT); |
409 | | } |
410 | | |
411 | | #[test] |
412 | | fn encrypt_with_seq_aes128gcm() { |
413 | | const KEY: &[u8] = &[0x42; 16]; |
414 | | roundtrip_encrypt_with_seq(AeadAlgorithms::Aes128Gcm, KEY); |
415 | | } |
416 | | |
417 | | #[test] |
418 | | fn encrypt_with_seq_aes256gcm() { |
419 | | const KEY: &[u8] = &[0x42; 32]; |
420 | | roundtrip_encrypt_with_seq(AeadAlgorithms::Aes256Gcm, KEY); |
421 | | } |
422 | | |
423 | | #[test] |
424 | | fn encrypt_with_seq_chacha20poly1305() { |
425 | | const KEY: &[u8] = &[0x42; 32]; |
426 | | roundtrip_encrypt_with_seq(AeadAlgorithms::ChaCha20Poly1305, KEY); |
427 | | } |
428 | | } |