1 //! High level interface to certain symmetric ciphers.
2 //!
3 //! # Examples
4 //!
5 //! Encrypt data in AES128 CBC mode
6 //!
7 //! ```
8 //! use openssl::symm::{encrypt, Cipher};
9 //!
10 //! let cipher = Cipher::aes_128_cbc();
11 //! let data = b"Some Crypto Text";
12 //! let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F";
13 //! let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07";
14 //! let ciphertext = encrypt(
15 //!     cipher,
16 //!     key,
17 //!     Some(iv),
18 //!     data).unwrap();
19 //!
20 //! assert_eq!(
21 //!     b"\xB4\xB9\xE7\x30\xD6\xD6\xF7\xDE\x77\x3F\x1C\xFF\xB3\x3E\x44\x5A\x91\xD7\x27\x62\x87\x4D\
22 //!       \xFB\x3C\x5E\xC4\x59\x72\x4A\xF4\x7C\xA1",
23 //!     &ciphertext[..]);
24 //! ```
25 //!
26 //! Encrypting an asymmetric key with a symmetric cipher
27 //!
28 //! ```
29 //! use openssl::rsa::{Padding, Rsa};
30 //! use openssl::symm::Cipher;
31 //!
32 //! // Generate keypair and encrypt private key:
33 //! let keypair = Rsa::generate(2048).unwrap();
34 //! let cipher = Cipher::aes_256_cbc();
35 //! let pubkey_pem = keypair.public_key_to_pem_pkcs1().unwrap();
36 //! let privkey_pem = keypair.private_key_to_pem_passphrase(cipher, b"Rust").unwrap();
37 //! // pubkey_pem and privkey_pem could be written to file here.
38 //!
39 //! // Load private and public key from string:
40 //! let pubkey = Rsa::public_key_from_pem_pkcs1(&pubkey_pem).unwrap();
41 //! let privkey = Rsa::private_key_from_pem_passphrase(&privkey_pem, b"Rust").unwrap();
42 //!
43 //! // Use the asymmetric keys to encrypt and decrypt a short message:
44 //! let msg = b"Foo bar";
45 //! let mut encrypted = vec![0; pubkey.size() as usize];
46 //! let mut decrypted = vec![0; privkey.size() as usize];
47 //! let len = pubkey.public_encrypt(msg, &mut encrypted, Padding::PKCS1).unwrap();
48 //! assert!(len > msg.len());
49 //! let len = privkey.private_decrypt(&encrypted, &mut decrypted, Padding::PKCS1).unwrap();
50 //! let output_string = String::from_utf8(decrypted[..len].to_vec()).unwrap();
51 //! assert_eq!("Foo bar", output_string);
52 //! println!("Decrypted: '{}'", output_string);
53 //! ```
54 
55 use cfg_if::cfg_if;
56 use libc::c_int;
57 use std::cmp;
58 use std::ptr;
59 
60 use crate::error::ErrorStack;
61 use crate::nid::Nid;
62 use crate::{cvt, cvt_p};
63 
64 #[derive(Copy, Clone)]
65 pub enum Mode {
66     Encrypt,
67     Decrypt,
68 }
69 
70 /// Represents a particular cipher algorithm.
71 ///
72 /// See OpenSSL doc at [`EVP_EncryptInit`] for more information on each algorithms.
73 ///
74 /// [`EVP_EncryptInit`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_EncryptInit.html
75 #[derive(Copy, Clone, PartialEq, Eq)]
76 pub struct Cipher(*const ffi::EVP_CIPHER);
77 
78 impl Cipher {
79     /// Looks up the cipher for a certain nid.
80     ///
81     /// This corresponds to [`EVP_get_cipherbynid`]
82     ///
83     /// [`EVP_get_cipherbynid`]: https://www.openssl.org/docs/man1.0.2/crypto/EVP_get_cipherbyname.html
from_nid(nid: Nid) -> Option<Cipher>84     pub fn from_nid(nid: Nid) -> Option<Cipher> {
85         let ptr = unsafe { ffi::EVP_get_cipherbyname(ffi::OBJ_nid2sn(nid.as_raw())) };
86         if ptr.is_null() {
87             None
88         } else {
89             Some(Cipher(ptr))
90         }
91     }
92 
93     /// Returns the cipher's Nid.
94     ///
95     /// This corresponds to [`EVP_CIPHER_nid`]
96     ///
97     /// [`EVP_CIPHER_nid`]: https://www.openssl.org/docs/man1.0.2/crypto/EVP_CIPHER_nid.html
nid(&self) -> Nid98     pub fn nid(&self) -> Nid {
99         let nid = unsafe { ffi::EVP_CIPHER_nid(self.0) };
100         Nid::from_raw(nid)
101     }
102 
aes_128_ecb() -> Cipher103     pub fn aes_128_ecb() -> Cipher {
104         unsafe { Cipher(ffi::EVP_aes_128_ecb()) }
105     }
106 
aes_128_cbc() -> Cipher107     pub fn aes_128_cbc() -> Cipher {
108         unsafe { Cipher(ffi::EVP_aes_128_cbc()) }
109     }
110 
aes_128_xts() -> Cipher111     pub fn aes_128_xts() -> Cipher {
112         unsafe { Cipher(ffi::EVP_aes_128_xts()) }
113     }
114 
aes_128_ctr() -> Cipher115     pub fn aes_128_ctr() -> Cipher {
116         unsafe { Cipher(ffi::EVP_aes_128_ctr()) }
117     }
118 
aes_128_cfb1() -> Cipher119     pub fn aes_128_cfb1() -> Cipher {
120         unsafe { Cipher(ffi::EVP_aes_128_cfb1()) }
121     }
122 
aes_128_cfb128() -> Cipher123     pub fn aes_128_cfb128() -> Cipher {
124         unsafe { Cipher(ffi::EVP_aes_128_cfb128()) }
125     }
126 
aes_128_cfb8() -> Cipher127     pub fn aes_128_cfb8() -> Cipher {
128         unsafe { Cipher(ffi::EVP_aes_128_cfb8()) }
129     }
130 
aes_128_gcm() -> Cipher131     pub fn aes_128_gcm() -> Cipher {
132         unsafe { Cipher(ffi::EVP_aes_128_gcm()) }
133     }
134 
aes_128_ccm() -> Cipher135     pub fn aes_128_ccm() -> Cipher {
136         unsafe { Cipher(ffi::EVP_aes_128_ccm()) }
137     }
138 
aes_128_ofb() -> Cipher139     pub fn aes_128_ofb() -> Cipher {
140         unsafe { Cipher(ffi::EVP_aes_128_ofb()) }
141     }
142 
143     /// Requires OpenSSL 1.1.0 or newer.
144     #[cfg(ossl110)]
aes_128_ocb() -> Cipher145     pub fn aes_128_ocb() -> Cipher {
146         unsafe { Cipher(ffi::EVP_aes_128_ocb()) }
147     }
148 
aes_192_ecb() -> Cipher149     pub fn aes_192_ecb() -> Cipher {
150         unsafe { Cipher(ffi::EVP_aes_192_ecb()) }
151     }
152 
aes_192_cbc() -> Cipher153     pub fn aes_192_cbc() -> Cipher {
154         unsafe { Cipher(ffi::EVP_aes_192_cbc()) }
155     }
156 
aes_192_ctr() -> Cipher157     pub fn aes_192_ctr() -> Cipher {
158         unsafe { Cipher(ffi::EVP_aes_192_ctr()) }
159     }
160 
aes_192_cfb1() -> Cipher161     pub fn aes_192_cfb1() -> Cipher {
162         unsafe { Cipher(ffi::EVP_aes_192_cfb1()) }
163     }
164 
aes_192_cfb128() -> Cipher165     pub fn aes_192_cfb128() -> Cipher {
166         unsafe { Cipher(ffi::EVP_aes_192_cfb128()) }
167     }
168 
aes_192_cfb8() -> Cipher169     pub fn aes_192_cfb8() -> Cipher {
170         unsafe { Cipher(ffi::EVP_aes_192_cfb8()) }
171     }
172 
aes_192_gcm() -> Cipher173     pub fn aes_192_gcm() -> Cipher {
174         unsafe { Cipher(ffi::EVP_aes_192_gcm()) }
175     }
176 
aes_192_ccm() -> Cipher177     pub fn aes_192_ccm() -> Cipher {
178         unsafe { Cipher(ffi::EVP_aes_192_ccm()) }
179     }
180 
aes_192_ofb() -> Cipher181     pub fn aes_192_ofb() -> Cipher {
182         unsafe { Cipher(ffi::EVP_aes_192_ofb()) }
183     }
184 
185     /// Requires OpenSSL 1.1.0 or newer.
186     #[cfg(ossl110)]
aes_192_ocb() -> Cipher187     pub fn aes_192_ocb() -> Cipher {
188         unsafe { Cipher(ffi::EVP_aes_192_ocb()) }
189     }
190 
aes_256_ecb() -> Cipher191     pub fn aes_256_ecb() -> Cipher {
192         unsafe { Cipher(ffi::EVP_aes_256_ecb()) }
193     }
194 
aes_256_cbc() -> Cipher195     pub fn aes_256_cbc() -> Cipher {
196         unsafe { Cipher(ffi::EVP_aes_256_cbc()) }
197     }
198 
aes_256_xts() -> Cipher199     pub fn aes_256_xts() -> Cipher {
200         unsafe { Cipher(ffi::EVP_aes_256_xts()) }
201     }
202 
aes_256_ctr() -> Cipher203     pub fn aes_256_ctr() -> Cipher {
204         unsafe { Cipher(ffi::EVP_aes_256_ctr()) }
205     }
206 
aes_256_cfb1() -> Cipher207     pub fn aes_256_cfb1() -> Cipher {
208         unsafe { Cipher(ffi::EVP_aes_256_cfb1()) }
209     }
210 
aes_256_cfb128() -> Cipher211     pub fn aes_256_cfb128() -> Cipher {
212         unsafe { Cipher(ffi::EVP_aes_256_cfb128()) }
213     }
214 
aes_256_cfb8() -> Cipher215     pub fn aes_256_cfb8() -> Cipher {
216         unsafe { Cipher(ffi::EVP_aes_256_cfb8()) }
217     }
218 
aes_256_gcm() -> Cipher219     pub fn aes_256_gcm() -> Cipher {
220         unsafe { Cipher(ffi::EVP_aes_256_gcm()) }
221     }
222 
aes_256_ccm() -> Cipher223     pub fn aes_256_ccm() -> Cipher {
224         unsafe { Cipher(ffi::EVP_aes_256_ccm()) }
225     }
226 
aes_256_ofb() -> Cipher227     pub fn aes_256_ofb() -> Cipher {
228         unsafe { Cipher(ffi::EVP_aes_256_ofb()) }
229     }
230 
231     /// Requires OpenSSL 1.1.0 or newer.
232     #[cfg(ossl110)]
aes_256_ocb() -> Cipher233     pub fn aes_256_ocb() -> Cipher {
234         unsafe { Cipher(ffi::EVP_aes_256_ocb()) }
235     }
236 
237     #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
bf_cbc() -> Cipher238     pub fn bf_cbc() -> Cipher {
239         unsafe { Cipher(ffi::EVP_bf_cbc()) }
240     }
241 
242     #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
bf_ecb() -> Cipher243     pub fn bf_ecb() -> Cipher {
244         unsafe { Cipher(ffi::EVP_bf_ecb()) }
245     }
246 
247     #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
bf_cfb64() -> Cipher248     pub fn bf_cfb64() -> Cipher {
249         unsafe { Cipher(ffi::EVP_bf_cfb64()) }
250     }
251 
252     #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
bf_ofb() -> Cipher253     pub fn bf_ofb() -> Cipher {
254         unsafe { Cipher(ffi::EVP_bf_ofb()) }
255     }
256 
des_cbc() -> Cipher257     pub fn des_cbc() -> Cipher {
258         unsafe { Cipher(ffi::EVP_des_cbc()) }
259     }
260 
des_ecb() -> Cipher261     pub fn des_ecb() -> Cipher {
262         unsafe { Cipher(ffi::EVP_des_ecb()) }
263     }
264 
des_ede3() -> Cipher265     pub fn des_ede3() -> Cipher {
266         unsafe { Cipher(ffi::EVP_des_ede3()) }
267     }
268 
des_ede3_cbc() -> Cipher269     pub fn des_ede3_cbc() -> Cipher {
270         unsafe { Cipher(ffi::EVP_des_ede3_cbc()) }
271     }
272 
des_ede3_cfb64() -> Cipher273     pub fn des_ede3_cfb64() -> Cipher {
274         unsafe { Cipher(ffi::EVP_des_ede3_cfb64()) }
275     }
276 
rc4() -> Cipher277     pub fn rc4() -> Cipher {
278         unsafe { Cipher(ffi::EVP_rc4()) }
279     }
280 
281     /// Requires OpenSSL 1.1.0 or newer.
282     #[cfg(any(ossl110))]
chacha20() -> Cipher283     pub fn chacha20() -> Cipher {
284         unsafe { Cipher(ffi::EVP_chacha20()) }
285     }
286 
287     /// Requires OpenSSL 1.1.0 or newer.
288     #[cfg(any(ossl110))]
chacha20_poly1305() -> Cipher289     pub fn chacha20_poly1305() -> Cipher {
290         unsafe { Cipher(ffi::EVP_chacha20_poly1305()) }
291     }
292 
293     /// Creates a `Cipher` from a raw pointer to its OpenSSL type.
294     ///
295     /// # Safety
296     ///
297     /// The caller must ensure the pointer is valid for the `'static` lifetime.
from_ptr(ptr: *const ffi::EVP_CIPHER) -> Cipher298     pub unsafe fn from_ptr(ptr: *const ffi::EVP_CIPHER) -> Cipher {
299         Cipher(ptr)
300     }
301 
302     #[allow(clippy::trivially_copy_pass_by_ref)]
as_ptr(&self) -> *const ffi::EVP_CIPHER303     pub fn as_ptr(&self) -> *const ffi::EVP_CIPHER {
304         self.0
305     }
306 
307     /// Returns the length of keys used with this cipher.
308     #[allow(clippy::trivially_copy_pass_by_ref)]
key_len(&self) -> usize309     pub fn key_len(&self) -> usize {
310         unsafe { EVP_CIPHER_key_length(self.0) as usize }
311     }
312 
313     /// Returns the length of the IV used with this cipher, or `None` if the
314     /// cipher does not use an IV.
315     #[allow(clippy::trivially_copy_pass_by_ref)]
iv_len(&self) -> Option<usize>316     pub fn iv_len(&self) -> Option<usize> {
317         unsafe {
318             let len = EVP_CIPHER_iv_length(self.0) as usize;
319             if len == 0 {
320                 None
321             } else {
322                 Some(len)
323             }
324         }
325     }
326 
327     /// Returns the block size of the cipher.
328     ///
329     /// # Note
330     ///
331     /// Stream ciphers such as RC4 have a block size of 1.
332     #[allow(clippy::trivially_copy_pass_by_ref)]
block_size(&self) -> usize333     pub fn block_size(&self) -> usize {
334         unsafe { EVP_CIPHER_block_size(self.0) as usize }
335     }
336 
337     /// Determines whether the cipher is using CCM mode
is_ccm(self) -> bool338     fn is_ccm(self) -> bool {
339         // NOTE: OpenSSL returns pointers to static structs, which makes this work as expected
340         self == Cipher::aes_128_ccm() || self == Cipher::aes_256_ccm()
341     }
342 
343     /// Determines whether the cipher is using OCB mode
344     #[cfg(ossl110)]
is_ocb(self) -> bool345     fn is_ocb(self) -> bool {
346         self == Cipher::aes_128_ocb()
347             || self == Cipher::aes_192_ocb()
348             || self == Cipher::aes_256_ocb()
349     }
350 
351     #[cfg(not(ossl110))]
is_ocb(self) -> bool352     const fn is_ocb(self) -> bool {
353         false
354     }
355 }
356 
357 unsafe impl Sync for Cipher {}
358 unsafe impl Send for Cipher {}
359 
360 /// Represents a symmetric cipher context.
361 ///
362 /// Padding is enabled by default.
363 ///
364 /// # Examples
365 ///
366 /// Encrypt some plaintext in chunks, then decrypt the ciphertext back into plaintext, in AES 128
367 /// CBC mode.
368 ///
369 /// ```
370 /// use openssl::symm::{Cipher, Mode, Crypter};
371 ///
372 /// let plaintexts: [&[u8]; 2] = [b"Some Stream of", b" Crypto Text"];
373 /// let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F";
374 /// let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07";
375 /// let data_len = plaintexts.iter().fold(0, |sum, x| sum + x.len());
376 ///
377 /// // Create a cipher context for encryption.
378 /// let mut encrypter = Crypter::new(
379 ///     Cipher::aes_128_cbc(),
380 ///     Mode::Encrypt,
381 ///     key,
382 ///     Some(iv)).unwrap();
383 ///
384 /// let block_size = Cipher::aes_128_cbc().block_size();
385 /// let mut ciphertext = vec![0; data_len + block_size];
386 ///
387 /// // Encrypt 2 chunks of plaintexts successively.
388 /// let mut count = encrypter.update(plaintexts[0], &mut ciphertext).unwrap();
389 /// count += encrypter.update(plaintexts[1], &mut ciphertext[count..]).unwrap();
390 /// count += encrypter.finalize(&mut ciphertext[count..]).unwrap();
391 /// ciphertext.truncate(count);
392 ///
393 /// assert_eq!(
394 ///     b"\x0F\x21\x83\x7E\xB2\x88\x04\xAF\xD9\xCC\xE2\x03\x49\xB4\x88\xF6\xC4\x61\x0E\x32\x1C\xF9\
395 ///       \x0D\x66\xB1\xE6\x2C\x77\x76\x18\x8D\x99",
396 ///     &ciphertext[..]
397 /// );
398 ///
399 ///
400 /// // Let's pretend we don't know the plaintext, and now decrypt the ciphertext.
401 /// let data_len = ciphertext.len();
402 /// let ciphertexts = [&ciphertext[..9], &ciphertext[9..]];
403 ///
404 /// // Create a cipher context for decryption.
405 /// let mut decrypter = Crypter::new(
406 ///     Cipher::aes_128_cbc(),
407 ///     Mode::Decrypt,
408 ///     key,
409 ///     Some(iv)).unwrap();
410 /// let mut plaintext = vec![0; data_len + block_size];
411 ///
412 /// // Decrypt 2 chunks of ciphertexts successively.
413 /// let mut count = decrypter.update(ciphertexts[0], &mut plaintext).unwrap();
414 /// count += decrypter.update(ciphertexts[1], &mut plaintext[count..]).unwrap();
415 /// count += decrypter.finalize(&mut plaintext[count..]).unwrap();
416 /// plaintext.truncate(count);
417 ///
418 /// assert_eq!(b"Some Stream of Crypto Text", &plaintext[..]);
419 /// ```
420 pub struct Crypter {
421     ctx: *mut ffi::EVP_CIPHER_CTX,
422     block_size: usize,
423 }
424 
425 unsafe impl Sync for Crypter {}
426 unsafe impl Send for Crypter {}
427 
428 impl Crypter {
429     /// Creates a new `Crypter`.  The initialisation vector, `iv`, is not necesarry for certain
430     /// types of `Cipher`.
431     ///
432     /// # Panics
433     ///
434     /// Panics if an IV is required by the cipher but not provided.  Also make sure that the key
435     /// and IV size are appropriate for your cipher.
new( t: Cipher, mode: Mode, key: &[u8], iv: Option<&[u8]>, ) -> Result<Crypter, ErrorStack>436     pub fn new(
437         t: Cipher,
438         mode: Mode,
439         key: &[u8],
440         iv: Option<&[u8]>,
441     ) -> Result<Crypter, ErrorStack> {
442         ffi::init();
443 
444         unsafe {
445             let ctx = cvt_p(ffi::EVP_CIPHER_CTX_new())?;
446             let crypter = Crypter {
447                 ctx,
448                 block_size: t.block_size(),
449             };
450 
451             let mode = match mode {
452                 Mode::Encrypt => 1,
453                 Mode::Decrypt => 0,
454             };
455 
456             cvt(ffi::EVP_CipherInit_ex(
457                 crypter.ctx,
458                 t.as_ptr(),
459                 ptr::null_mut(),
460                 ptr::null_mut(),
461                 ptr::null_mut(),
462                 mode,
463             ))?;
464 
465             assert!(key.len() <= c_int::max_value() as usize);
466             cvt(ffi::EVP_CIPHER_CTX_set_key_length(
467                 crypter.ctx,
468                 key.len() as c_int,
469             ))?;
470 
471             let key = key.as_ptr() as *mut _;
472             let iv = match (iv, t.iv_len()) {
473                 (Some(iv), Some(len)) => {
474                     if iv.len() != len {
475                         assert!(iv.len() <= c_int::max_value() as usize);
476                         cvt(ffi::EVP_CIPHER_CTX_ctrl(
477                             crypter.ctx,
478                             ffi::EVP_CTRL_GCM_SET_IVLEN,
479                             iv.len() as c_int,
480                             ptr::null_mut(),
481                         ))?;
482                     }
483                     iv.as_ptr() as *mut _
484                 }
485                 (Some(_), None) | (None, None) => ptr::null_mut(),
486                 (None, Some(_)) => panic!("an IV is required for this cipher"),
487             };
488             cvt(ffi::EVP_CipherInit_ex(
489                 crypter.ctx,
490                 ptr::null(),
491                 ptr::null_mut(),
492                 key,
493                 iv,
494                 mode,
495             ))?;
496 
497             Ok(crypter)
498         }
499     }
500 
501     /// Enables or disables padding.
502     ///
503     /// If padding is disabled, total amount of data encrypted/decrypted must
504     /// be a multiple of the cipher's block size.
pad(&mut self, padding: bool)505     pub fn pad(&mut self, padding: bool) {
506         unsafe {
507             ffi::EVP_CIPHER_CTX_set_padding(self.ctx, padding as c_int);
508         }
509     }
510 
511     /// Sets the tag used to authenticate ciphertext in AEAD ciphers such as AES GCM.
512     ///
513     /// When decrypting cipher text using an AEAD cipher, this must be called before `finalize`.
set_tag(&mut self, tag: &[u8]) -> Result<(), ErrorStack>514     pub fn set_tag(&mut self, tag: &[u8]) -> Result<(), ErrorStack> {
515         unsafe {
516             assert!(tag.len() <= c_int::max_value() as usize);
517             // NB: this constant is actually more general than just GCM.
518             cvt(ffi::EVP_CIPHER_CTX_ctrl(
519                 self.ctx,
520                 ffi::EVP_CTRL_GCM_SET_TAG,
521                 tag.len() as c_int,
522                 tag.as_ptr() as *mut _,
523             ))
524             .map(|_| ())
525         }
526     }
527 
528     /// Sets the length of the authentication tag to generate in AES CCM.
529     ///
530     /// When encrypting with AES CCM, the tag length needs to be explicitly set in order
531     /// to use a value different than the default 12 bytes.
set_tag_len(&mut self, tag_len: usize) -> Result<(), ErrorStack>532     pub fn set_tag_len(&mut self, tag_len: usize) -> Result<(), ErrorStack> {
533         unsafe {
534             assert!(tag_len <= c_int::max_value() as usize);
535             // NB: this constant is actually more general than just GCM.
536             cvt(ffi::EVP_CIPHER_CTX_ctrl(
537                 self.ctx,
538                 ffi::EVP_CTRL_GCM_SET_TAG,
539                 tag_len as c_int,
540                 ptr::null_mut(),
541             ))
542             .map(|_| ())
543         }
544     }
545 
546     /// Feeds total plaintext length to the cipher.
547     ///
548     /// The total plaintext or ciphertext length MUST be passed to the cipher when it operates in
549     /// CCM mode.
set_data_len(&mut self, data_len: usize) -> Result<(), ErrorStack>550     pub fn set_data_len(&mut self, data_len: usize) -> Result<(), ErrorStack> {
551         unsafe {
552             assert!(data_len <= c_int::max_value() as usize);
553             let mut len = 0;
554             cvt(ffi::EVP_CipherUpdate(
555                 self.ctx,
556                 ptr::null_mut(),
557                 &mut len,
558                 ptr::null_mut(),
559                 data_len as c_int,
560             ))
561             .map(|_| ())
562         }
563     }
564 
565     /// Feeds Additional Authenticated Data (AAD) through the cipher.
566     ///
567     /// This can only be used with AEAD ciphers such as AES GCM. Data fed in is not encrypted, but
568     /// is factored into the authentication tag. It must be called before the first call to
569     /// `update`.
aad_update(&mut self, input: &[u8]) -> Result<(), ErrorStack>570     pub fn aad_update(&mut self, input: &[u8]) -> Result<(), ErrorStack> {
571         unsafe {
572             assert!(input.len() <= c_int::max_value() as usize);
573             let mut len = 0;
574             cvt(ffi::EVP_CipherUpdate(
575                 self.ctx,
576                 ptr::null_mut(),
577                 &mut len,
578                 input.as_ptr(),
579                 input.len() as c_int,
580             ))
581             .map(|_| ())
582         }
583     }
584 
585     /// Feeds data from `input` through the cipher, writing encrypted/decrypted
586     /// bytes into `output`.
587     ///
588     /// The number of bytes written to `output` is returned. Note that this may
589     /// not be equal to the length of `input`.
590     ///
591     /// # Panics
592     ///
593     /// Panics for stream ciphers if `output.len() < input.len()`.
594     ///
595     /// Panics for block ciphers if `output.len() < input.len() + block_size`,
596     /// where `block_size` is the block size of the cipher (see `Cipher::block_size`).
597     ///
598     /// Panics if `output.len() > c_int::max_value()`.
update(&mut self, input: &[u8], output: &mut [u8]) -> Result<usize, ErrorStack>599     pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result<usize, ErrorStack> {
600         unsafe {
601             let block_size = if self.block_size > 1 {
602                 self.block_size
603             } else {
604                 0
605             };
606             assert!(output.len() >= input.len() + block_size);
607             assert!(output.len() <= c_int::max_value() as usize);
608             let mut outl = output.len() as c_int;
609             let inl = input.len() as c_int;
610 
611             cvt(ffi::EVP_CipherUpdate(
612                 self.ctx,
613                 output.as_mut_ptr(),
614                 &mut outl,
615                 input.as_ptr(),
616                 inl,
617             ))?;
618 
619             Ok(outl as usize)
620         }
621     }
622 
623     /// Finishes the encryption/decryption process, writing any remaining data
624     /// to `output`.
625     ///
626     /// The number of bytes written to `output` is returned.
627     ///
628     /// `update` should not be called after this method.
629     ///
630     /// # Panics
631     ///
632     /// Panics for block ciphers if `output.len() < block_size`,
633     /// where `block_size` is the block size of the cipher (see `Cipher::block_size`).
finalize(&mut self, output: &mut [u8]) -> Result<usize, ErrorStack>634     pub fn finalize(&mut self, output: &mut [u8]) -> Result<usize, ErrorStack> {
635         unsafe {
636             if self.block_size > 1 {
637                 assert!(output.len() >= self.block_size);
638             }
639             let mut outl = cmp::min(output.len(), c_int::max_value() as usize) as c_int;
640 
641             cvt(ffi::EVP_CipherFinal(
642                 self.ctx,
643                 output.as_mut_ptr(),
644                 &mut outl,
645             ))?;
646 
647             Ok(outl as usize)
648         }
649     }
650 
651     /// Retrieves the authentication tag used to authenticate ciphertext in AEAD ciphers such
652     /// as AES GCM.
653     ///
654     /// When encrypting data with an AEAD cipher, this must be called after `finalize`.
655     ///
656     /// The size of the buffer indicates the required size of the tag. While some ciphers support a
657     /// range of tag sizes, it is recommended to pick the maximum size. For AES GCM, this is 16
658     /// bytes, for example.
get_tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack>659     pub fn get_tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> {
660         unsafe {
661             assert!(tag.len() <= c_int::max_value() as usize);
662             cvt(ffi::EVP_CIPHER_CTX_ctrl(
663                 self.ctx,
664                 ffi::EVP_CTRL_GCM_GET_TAG,
665                 tag.len() as c_int,
666                 tag.as_mut_ptr() as *mut _,
667             ))
668             .map(|_| ())
669         }
670     }
671 }
672 
673 impl Drop for Crypter {
drop(&mut self)674     fn drop(&mut self) {
675         unsafe {
676             ffi::EVP_CIPHER_CTX_free(self.ctx);
677         }
678     }
679 }
680 
681 /// Encrypts data in one go, and returns the encrypted data.
682 ///
683 /// Data is encrypted using the specified cipher type `t` in encrypt mode with the specified `key`
684 /// and initailization vector `iv`. Padding is enabled.
685 ///
686 /// This is a convenient interface to `Crypter` to encrypt all data in one go.  To encrypt a stream
687 /// of data increamentally , use `Crypter` instead.
688 ///
689 /// # Examples
690 ///
691 /// Encrypt data in AES128 CBC mode
692 ///
693 /// ```
694 /// use openssl::symm::{encrypt, Cipher};
695 ///
696 /// let cipher = Cipher::aes_128_cbc();
697 /// let data = b"Some Crypto Text";
698 /// let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F";
699 /// let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07";
700 /// let ciphertext = encrypt(
701 ///     cipher,
702 ///     key,
703 ///     Some(iv),
704 ///     data).unwrap();
705 ///
706 /// assert_eq!(
707 ///     b"\xB4\xB9\xE7\x30\xD6\xD6\xF7\xDE\x77\x3F\x1C\xFF\xB3\x3E\x44\x5A\x91\xD7\x27\x62\x87\x4D\
708 ///       \xFB\x3C\x5E\xC4\x59\x72\x4A\xF4\x7C\xA1",
709 ///     &ciphertext[..]);
710 /// ```
encrypt( t: Cipher, key: &[u8], iv: Option<&[u8]>, data: &[u8], ) -> Result<Vec<u8>, ErrorStack>711 pub fn encrypt(
712     t: Cipher,
713     key: &[u8],
714     iv: Option<&[u8]>,
715     data: &[u8],
716 ) -> Result<Vec<u8>, ErrorStack> {
717     cipher(t, Mode::Encrypt, key, iv, data)
718 }
719 
720 /// Decrypts data in one go, and returns the decrypted data.
721 ///
722 /// Data is decrypted using the specified cipher type `t` in decrypt mode with the specified `key`
723 /// and initailization vector `iv`. Padding is enabled.
724 ///
725 /// This is a convenient interface to `Crypter` to decrypt all data in one go.  To decrypt a  stream
726 /// of data increamentally , use `Crypter` instead.
727 ///
728 /// # Examples
729 ///
730 /// Decrypt data in AES128 CBC mode
731 ///
732 /// ```
733 /// use openssl::symm::{decrypt, Cipher};
734 ///
735 /// let cipher = Cipher::aes_128_cbc();
736 /// let data = b"\xB4\xB9\xE7\x30\xD6\xD6\xF7\xDE\x77\x3F\x1C\xFF\xB3\x3E\x44\x5A\x91\xD7\x27\x62\
737 ///              \x87\x4D\xFB\x3C\x5E\xC4\x59\x72\x4A\xF4\x7C\xA1";
738 /// let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F";
739 /// let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07";
740 /// let ciphertext = decrypt(
741 ///     cipher,
742 ///     key,
743 ///     Some(iv),
744 ///     data).unwrap();
745 ///
746 /// assert_eq!(
747 ///     b"Some Crypto Text",
748 ///     &ciphertext[..]);
749 /// ```
decrypt( t: Cipher, key: &[u8], iv: Option<&[u8]>, data: &[u8], ) -> Result<Vec<u8>, ErrorStack>750 pub fn decrypt(
751     t: Cipher,
752     key: &[u8],
753     iv: Option<&[u8]>,
754     data: &[u8],
755 ) -> Result<Vec<u8>, ErrorStack> {
756     cipher(t, Mode::Decrypt, key, iv, data)
757 }
758 
cipher( t: Cipher, mode: Mode, key: &[u8], iv: Option<&[u8]>, data: &[u8], ) -> Result<Vec<u8>, ErrorStack>759 fn cipher(
760     t: Cipher,
761     mode: Mode,
762     key: &[u8],
763     iv: Option<&[u8]>,
764     data: &[u8],
765 ) -> Result<Vec<u8>, ErrorStack> {
766     let mut c = Crypter::new(t, mode, key, iv)?;
767     let mut out = vec![0; data.len() + t.block_size()];
768     let count = c.update(data, &mut out)?;
769     let rest = c.finalize(&mut out[count..])?;
770     out.truncate(count + rest);
771     Ok(out)
772 }
773 
774 /// Like `encrypt`, but for AEAD ciphers such as AES GCM.
775 ///
776 /// Additional Authenticated Data can be provided in the `aad` field, and the authentication tag
777 /// will be copied into the `tag` field.
778 ///
779 /// The size of the `tag` buffer indicates the required size of the tag. While some ciphers support
780 /// a range of tag sizes, it is recommended to pick the maximum size. For AES GCM, this is 16 bytes,
781 /// for example.
encrypt_aead( t: Cipher, key: &[u8], iv: Option<&[u8]>, aad: &[u8], data: &[u8], tag: &mut [u8], ) -> Result<Vec<u8>, ErrorStack>782 pub fn encrypt_aead(
783     t: Cipher,
784     key: &[u8],
785     iv: Option<&[u8]>,
786     aad: &[u8],
787     data: &[u8],
788     tag: &mut [u8],
789 ) -> Result<Vec<u8>, ErrorStack> {
790     let mut c = Crypter::new(t, Mode::Encrypt, key, iv)?;
791     let mut out = vec![0; data.len() + t.block_size()];
792 
793     let is_ccm = t.is_ccm();
794     if is_ccm || t.is_ocb() {
795         c.set_tag_len(tag.len())?;
796         if is_ccm {
797             c.set_data_len(data.len())?;
798         }
799     }
800 
801     c.aad_update(aad)?;
802     let count = c.update(data, &mut out)?;
803     let rest = c.finalize(&mut out[count..])?;
804     c.get_tag(tag)?;
805     out.truncate(count + rest);
806     Ok(out)
807 }
808 
809 /// Like `decrypt`, but for AEAD ciphers such as AES GCM.
810 ///
811 /// Additional Authenticated Data can be provided in the `aad` field, and the authentication tag
812 /// should be provided in the `tag` field.
decrypt_aead( t: Cipher, key: &[u8], iv: Option<&[u8]>, aad: &[u8], data: &[u8], tag: &[u8], ) -> Result<Vec<u8>, ErrorStack>813 pub fn decrypt_aead(
814     t: Cipher,
815     key: &[u8],
816     iv: Option<&[u8]>,
817     aad: &[u8],
818     data: &[u8],
819     tag: &[u8],
820 ) -> Result<Vec<u8>, ErrorStack> {
821     let mut c = Crypter::new(t, Mode::Decrypt, key, iv)?;
822     let mut out = vec![0; data.len() + t.block_size()];
823 
824     let is_ccm = t.is_ccm();
825     if is_ccm || t.is_ocb() {
826         c.set_tag(tag)?;
827         if is_ccm {
828             c.set_data_len(data.len())?;
829         }
830     }
831 
832     c.aad_update(aad)?;
833     let count = c.update(data, &mut out)?;
834 
835     let rest = if t.is_ccm() {
836         0
837     } else {
838         c.set_tag(tag)?;
839         c.finalize(&mut out[count..])?
840     };
841 
842     out.truncate(count + rest);
843     Ok(out)
844 }
845 
846 cfg_if! {
847     if #[cfg(any(ossl110, libressl273))] {
848         use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length};
849     } else {
850         #[allow(bad_style)]
851         pub unsafe fn EVP_CIPHER_iv_length(ptr: *const ffi::EVP_CIPHER) -> c_int {
852             (*ptr).iv_len
853         }
854 
855         #[allow(bad_style)]
856         pub unsafe fn EVP_CIPHER_block_size(ptr: *const ffi::EVP_CIPHER) -> c_int {
857             (*ptr).block_size
858         }
859 
860         #[allow(bad_style)]
861         pub unsafe fn EVP_CIPHER_key_length(ptr: *const ffi::EVP_CIPHER) -> c_int {
862             (*ptr).key_len
863         }
864     }
865 }
866 
867 #[cfg(test)]
868 mod tests {
869     use super::*;
870     use hex::{self, FromHex};
871 
872     #[test]
test_stream_cipher_output()873     fn test_stream_cipher_output() {
874         let key = [0u8; 16];
875         let iv = [0u8; 16];
876         let mut c = super::Crypter::new(
877             super::Cipher::aes_128_ctr(),
878             super::Mode::Encrypt,
879             &key,
880             Some(&iv),
881         )
882         .unwrap();
883 
884         assert_eq!(c.update(&[0u8; 15], &mut [0u8; 15]).unwrap(), 15);
885         assert_eq!(c.update(&[0u8; 1], &mut [0u8; 1]).unwrap(), 1);
886         assert_eq!(c.finalize(&mut [0u8; 0]).unwrap(), 0);
887     }
888 
889     // Test vectors from FIPS-197:
890     // http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
891     #[test]
test_aes_256_ecb()892     fn test_aes_256_ecb() {
893         let k0 = [
894             0x00u8, 0x01u8, 0x02u8, 0x03u8, 0x04u8, 0x05u8, 0x06u8, 0x07u8, 0x08u8, 0x09u8, 0x0au8,
895             0x0bu8, 0x0cu8, 0x0du8, 0x0eu8, 0x0fu8, 0x10u8, 0x11u8, 0x12u8, 0x13u8, 0x14u8, 0x15u8,
896             0x16u8, 0x17u8, 0x18u8, 0x19u8, 0x1au8, 0x1bu8, 0x1cu8, 0x1du8, 0x1eu8, 0x1fu8,
897         ];
898         let p0 = [
899             0x00u8, 0x11u8, 0x22u8, 0x33u8, 0x44u8, 0x55u8, 0x66u8, 0x77u8, 0x88u8, 0x99u8, 0xaau8,
900             0xbbu8, 0xccu8, 0xddu8, 0xeeu8, 0xffu8,
901         ];
902         let c0 = [
903             0x8eu8, 0xa2u8, 0xb7u8, 0xcau8, 0x51u8, 0x67u8, 0x45u8, 0xbfu8, 0xeau8, 0xfcu8, 0x49u8,
904             0x90u8, 0x4bu8, 0x49u8, 0x60u8, 0x89u8,
905         ];
906         let mut c = super::Crypter::new(
907             super::Cipher::aes_256_ecb(),
908             super::Mode::Encrypt,
909             &k0,
910             None,
911         )
912         .unwrap();
913         c.pad(false);
914         let mut r0 = vec![0; c0.len() + super::Cipher::aes_256_ecb().block_size()];
915         let count = c.update(&p0, &mut r0).unwrap();
916         let rest = c.finalize(&mut r0[count..]).unwrap();
917         r0.truncate(count + rest);
918         assert_eq!(hex::encode(&r0), hex::encode(c0));
919 
920         let mut c = super::Crypter::new(
921             super::Cipher::aes_256_ecb(),
922             super::Mode::Decrypt,
923             &k0,
924             None,
925         )
926         .unwrap();
927         c.pad(false);
928         let mut p1 = vec![0; r0.len() + super::Cipher::aes_256_ecb().block_size()];
929         let count = c.update(&r0, &mut p1).unwrap();
930         let rest = c.finalize(&mut p1[count..]).unwrap();
931         p1.truncate(count + rest);
932         assert_eq!(hex::encode(p1), hex::encode(p0));
933     }
934 
935     #[test]
test_aes_256_cbc_decrypt()936     fn test_aes_256_cbc_decrypt() {
937         let iv = [
938             4_u8, 223_u8, 153_u8, 219_u8, 28_u8, 142_u8, 234_u8, 68_u8, 227_u8, 69_u8, 98_u8,
939             107_u8, 208_u8, 14_u8, 236_u8, 60_u8,
940         ];
941         let data = [
942             143_u8, 210_u8, 75_u8, 63_u8, 214_u8, 179_u8, 155_u8, 241_u8, 242_u8, 31_u8, 154_u8,
943             56_u8, 198_u8, 145_u8, 192_u8, 64_u8, 2_u8, 245_u8, 167_u8, 220_u8, 55_u8, 119_u8,
944             233_u8, 136_u8, 139_u8, 27_u8, 71_u8, 242_u8, 119_u8, 175_u8, 65_u8, 207_u8,
945         ];
946         let ciphered_data = [
947             0x4a_u8, 0x2e_u8, 0xe5_u8, 0x6_u8, 0xbf_u8, 0xcf_u8, 0xf2_u8, 0xd7_u8, 0xea_u8,
948             0x2d_u8, 0xb1_u8, 0x85_u8, 0x6c_u8, 0x93_u8, 0x65_u8, 0x6f_u8,
949         ];
950         let mut cr = super::Crypter::new(
951             super::Cipher::aes_256_cbc(),
952             super::Mode::Decrypt,
953             &data,
954             Some(&iv),
955         )
956         .unwrap();
957         cr.pad(false);
958         let mut unciphered_data = vec![0; data.len() + super::Cipher::aes_256_cbc().block_size()];
959         let count = cr.update(&ciphered_data, &mut unciphered_data).unwrap();
960         let rest = cr.finalize(&mut unciphered_data[count..]).unwrap();
961         unciphered_data.truncate(count + rest);
962 
963         let expected_unciphered_data = b"I love turtles.\x01";
964 
965         assert_eq!(&unciphered_data, expected_unciphered_data);
966     }
967 
cipher_test(ciphertype: super::Cipher, pt: &str, ct: &str, key: &str, iv: &str)968     fn cipher_test(ciphertype: super::Cipher, pt: &str, ct: &str, key: &str, iv: &str) {
969         let pt = Vec::from_hex(pt).unwrap();
970         let ct = Vec::from_hex(ct).unwrap();
971         let key = Vec::from_hex(key).unwrap();
972         let iv = Vec::from_hex(iv).unwrap();
973 
974         let computed = super::decrypt(ciphertype, &key, Some(&iv), &ct).unwrap();
975         let expected = pt;
976 
977         if computed != expected {
978             println!("Computed: {}", hex::encode(&computed));
979             println!("Expected: {}", hex::encode(&expected));
980             if computed.len() != expected.len() {
981                 println!(
982                     "Lengths differ: {} in computed vs {} expected",
983                     computed.len(),
984                     expected.len()
985                 );
986             }
987             panic!("test failure");
988         }
989     }
990 
cipher_test_nopad(ciphertype: super::Cipher, pt: &str, ct: &str, key: &str, iv: &str)991     fn cipher_test_nopad(ciphertype: super::Cipher, pt: &str, ct: &str, key: &str, iv: &str) {
992         let pt = Vec::from_hex(pt).unwrap();
993         let ct = Vec::from_hex(ct).unwrap();
994         let key = Vec::from_hex(key).unwrap();
995         let iv = Vec::from_hex(iv).unwrap();
996 
997         let computed = {
998             let mut c = Crypter::new(ciphertype, Mode::Decrypt, &key, Some(&iv)).unwrap();
999             c.pad(false);
1000             let mut out = vec![0; ct.len() + ciphertype.block_size()];
1001             let count = c.update(&ct, &mut out).unwrap();
1002             let rest = c.finalize(&mut out[count..]).unwrap();
1003             out.truncate(count + rest);
1004             out
1005         };
1006         let expected = pt;
1007 
1008         if computed != expected {
1009             println!("Computed: {}", hex::encode(&computed));
1010             println!("Expected: {}", hex::encode(&expected));
1011             if computed.len() != expected.len() {
1012                 println!(
1013                     "Lengths differ: {} in computed vs {} expected",
1014                     computed.len(),
1015                     expected.len()
1016                 );
1017             }
1018             panic!("test failure");
1019         }
1020     }
1021 
1022     #[test]
1023     #[cfg_attr(ossl300, ignore)]
test_rc4()1024     fn test_rc4() {
1025         let pt = "0000000000000000000000000000000000000000000000000000000000000000000000000000";
1026         let ct = "A68686B04D686AA107BD8D4CAB191A3EEC0A6294BC78B60F65C25CB47BD7BB3A48EFC4D26BE4";
1027         let key = "97CD440324DA5FD1F7955C1C13B6B466";
1028         let iv = "";
1029 
1030         cipher_test(super::Cipher::rc4(), pt, ct, key, iv);
1031     }
1032 
1033     #[test]
test_aes256_xts()1034     fn test_aes256_xts() {
1035         // Test case 174 from
1036         // http://csrc.nist.gov/groups/STM/cavp/documents/aes/XTSTestVectors.zip
1037         let pt = "77f4ef63d734ebd028508da66c22cdebdd52ecd6ee2ab0a50bc8ad0cfd692ca5fcd4e6dedc45df7f\
1038                   6503f462611dc542";
1039         let ct = "ce7d905a7776ac72f240d22aafed5e4eb7566cdc7211220e970da634ce015f131a5ecb8d400bc9e8\
1040                   4f0b81d8725dbbc7";
1041         let key = "b6bfef891f83b5ff073f2231267be51eb084b791fa19a154399c0684c8b2dfcb37de77d28bbda3b\
1042                    4180026ad640b74243b3133e7b9fae629403f6733423dae28";
1043         let iv = "db200efb7eaaa737dbdf40babb68953f";
1044 
1045         cipher_test(super::Cipher::aes_256_xts(), pt, ct, key, iv);
1046     }
1047 
1048     #[test]
test_aes128_ctr()1049     fn test_aes128_ctr() {
1050         let pt = "6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411\
1051                   E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710";
1052         let ct = "874D6191B620E3261BEF6864990DB6CE9806F66B7970FDFF8617187BB9FFFDFF5AE4DF3EDBD5D35E\
1053                   5B4F09020DB03EAB1E031DDA2FBE03D1792170A0F3009CEE";
1054         let key = "2B7E151628AED2A6ABF7158809CF4F3C";
1055         let iv = "F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF";
1056 
1057         cipher_test(super::Cipher::aes_128_ctr(), pt, ct, key, iv);
1058     }
1059 
1060     #[test]
test_aes128_cfb1()1061     fn test_aes128_cfb1() {
1062         // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1063 
1064         let pt = "6bc1";
1065         let ct = "68b3";
1066         let key = "2b7e151628aed2a6abf7158809cf4f3c";
1067         let iv = "000102030405060708090a0b0c0d0e0f";
1068 
1069         cipher_test(super::Cipher::aes_128_cfb1(), pt, ct, key, iv);
1070     }
1071 
1072     #[test]
test_aes128_cfb128()1073     fn test_aes128_cfb128() {
1074         let pt = "6bc1bee22e409f96e93d7e117393172a";
1075         let ct = "3b3fd92eb72dad20333449f8e83cfb4a";
1076         let key = "2b7e151628aed2a6abf7158809cf4f3c";
1077         let iv = "000102030405060708090a0b0c0d0e0f";
1078 
1079         cipher_test(super::Cipher::aes_128_cfb128(), pt, ct, key, iv);
1080     }
1081 
1082     #[test]
test_aes128_cfb8()1083     fn test_aes128_cfb8() {
1084         let pt = "6bc1bee22e409f96e93d7e117393172aae2d";
1085         let ct = "3b79424c9c0dd436bace9e0ed4586a4f32b9";
1086         let key = "2b7e151628aed2a6abf7158809cf4f3c";
1087         let iv = "000102030405060708090a0b0c0d0e0f";
1088 
1089         cipher_test(super::Cipher::aes_128_cfb8(), pt, ct, key, iv);
1090     }
1091 
1092     #[test]
test_aes128_ofb()1093     fn test_aes128_ofb() {
1094         // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1095 
1096         let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710";
1097         let ct = "3b3fd92eb72dad20333449f8e83cfb4a7789508d16918f03f53c52dac54ed8259740051e9c5fecf64344f7a82260edcc304c6528f659c77866a510d9c1d6ae5e";
1098         let key = "2b7e151628aed2a6abf7158809cf4f3c";
1099         let iv = "000102030405060708090a0b0c0d0e0f";
1100 
1101         cipher_test(super::Cipher::aes_128_ofb(), pt, ct, key, iv);
1102     }
1103 
1104     #[test]
test_aes192_ctr()1105     fn test_aes192_ctr() {
1106         // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1107 
1108         let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710";
1109         let ct = "1abc932417521ca24f2b0459fe7e6e0b090339ec0aa6faefd5ccc2c6f4ce8e941e36b26bd1ebc670d1bd1d665620abf74f78a7f6d29809585a97daec58c6b050";
1110         let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1111         let iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
1112 
1113         cipher_test(super::Cipher::aes_192_ctr(), pt, ct, key, iv);
1114     }
1115 
1116     #[test]
test_aes192_cfb1()1117     fn test_aes192_cfb1() {
1118         // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1119 
1120         let pt = "6bc1";
1121         let ct = "9359";
1122         let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1123         let iv = "000102030405060708090a0b0c0d0e0f";
1124 
1125         cipher_test(super::Cipher::aes_192_cfb1(), pt, ct, key, iv);
1126     }
1127 
1128     #[test]
test_aes192_cfb128()1129     fn test_aes192_cfb128() {
1130         // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1131 
1132         let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710";
1133         let ct = "cdc80d6fddf18cab34c25909c99a417467ce7f7f81173621961a2b70171d3d7a2e1e8a1dd59b88b1c8e60fed1efac4c9c05f9f9ca9834fa042ae8fba584b09ff";
1134         let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1135         let iv = "000102030405060708090a0b0c0d0e0f";
1136 
1137         cipher_test(super::Cipher::aes_192_cfb128(), pt, ct, key, iv);
1138     }
1139 
1140     #[test]
test_aes192_cfb8()1141     fn test_aes192_cfb8() {
1142         // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1143 
1144         let pt = "6bc1bee22e409f96e93d7e117393172aae2d";
1145         let ct = "cda2521ef0a905ca44cd057cbf0d47a0678a";
1146         let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1147         let iv = "000102030405060708090a0b0c0d0e0f";
1148 
1149         cipher_test(super::Cipher::aes_192_cfb8(), pt, ct, key, iv);
1150     }
1151 
1152     #[test]
test_aes192_ofb()1153     fn test_aes192_ofb() {
1154         // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1155 
1156         let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710";
1157         let ct = "cdc80d6fddf18cab34c25909c99a4174fcc28b8d4c63837c09e81700c11004018d9a9aeac0f6596f559c6d4daf59a5f26d9f200857ca6c3e9cac524bd9acc92a";
1158         let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1159         let iv = "000102030405060708090a0b0c0d0e0f";
1160 
1161         cipher_test(super::Cipher::aes_192_ofb(), pt, ct, key, iv);
1162     }
1163 
1164     #[test]
test_aes256_cfb1()1165     fn test_aes256_cfb1() {
1166         let pt = "6bc1";
1167         let ct = "9029";
1168         let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1169         let iv = "000102030405060708090a0b0c0d0e0f";
1170 
1171         cipher_test(super::Cipher::aes_256_cfb1(), pt, ct, key, iv);
1172     }
1173 
1174     #[test]
test_aes256_cfb128()1175     fn test_aes256_cfb128() {
1176         let pt = "6bc1bee22e409f96e93d7e117393172a";
1177         let ct = "dc7e84bfda79164b7ecd8486985d3860";
1178         let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1179         let iv = "000102030405060708090a0b0c0d0e0f";
1180 
1181         cipher_test(super::Cipher::aes_256_cfb128(), pt, ct, key, iv);
1182     }
1183 
1184     #[test]
test_aes256_cfb8()1185     fn test_aes256_cfb8() {
1186         let pt = "6bc1bee22e409f96e93d7e117393172aae2d";
1187         let ct = "dc1f1a8520a64db55fcc8ac554844e889700";
1188         let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1189         let iv = "000102030405060708090a0b0c0d0e0f";
1190 
1191         cipher_test(super::Cipher::aes_256_cfb8(), pt, ct, key, iv);
1192     }
1193 
1194     #[test]
test_aes256_ofb()1195     fn test_aes256_ofb() {
1196         // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1197 
1198         let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710";
1199         let ct = "dc7e84bfda79164b7ecd8486985d38604febdc6740d20b3ac88f6ad82a4fb08d71ab47a086e86eedf39d1c5bba97c4080126141d67f37be8538f5a8be740e484";
1200         let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1201         let iv = "000102030405060708090a0b0c0d0e0f";
1202 
1203         cipher_test(super::Cipher::aes_256_ofb(), pt, ct, key, iv);
1204     }
1205 
1206     #[test]
1207     #[cfg_attr(ossl300, ignore)]
test_bf_cbc()1208     fn test_bf_cbc() {
1209         // https://www.schneier.com/code/vectors.txt
1210 
1211         let pt = "37363534333231204E6F77206973207468652074696D6520666F722000000000";
1212         let ct = "6B77B4D63006DEE605B156E27403979358DEB9E7154616D959F1652BD5FF92CC";
1213         let key = "0123456789ABCDEFF0E1D2C3B4A59687";
1214         let iv = "FEDCBA9876543210";
1215 
1216         cipher_test_nopad(super::Cipher::bf_cbc(), pt, ct, key, iv);
1217     }
1218 
1219     #[test]
1220     #[cfg_attr(ossl300, ignore)]
test_bf_ecb()1221     fn test_bf_ecb() {
1222         let pt = "5CD54CA83DEF57DA";
1223         let ct = "B1B8CC0B250F09A0";
1224         let key = "0131D9619DC1376E";
1225         let iv = "0000000000000000";
1226 
1227         cipher_test_nopad(super::Cipher::bf_ecb(), pt, ct, key, iv);
1228     }
1229 
1230     #[test]
1231     #[cfg_attr(ossl300, ignore)]
test_bf_cfb64()1232     fn test_bf_cfb64() {
1233         let pt = "37363534333231204E6F77206973207468652074696D6520666F722000";
1234         let ct = "E73214A2822139CAF26ECF6D2EB9E76E3DA3DE04D1517200519D57A6C3";
1235         let key = "0123456789ABCDEFF0E1D2C3B4A59687";
1236         let iv = "FEDCBA9876543210";
1237 
1238         cipher_test_nopad(super::Cipher::bf_cfb64(), pt, ct, key, iv);
1239     }
1240 
1241     #[test]
1242     #[cfg_attr(ossl300, ignore)]
test_bf_ofb()1243     fn test_bf_ofb() {
1244         let pt = "37363534333231204E6F77206973207468652074696D6520666F722000";
1245         let ct = "E73214A2822139CA62B343CC5B65587310DD908D0C241B2263C2CF80DA";
1246         let key = "0123456789ABCDEFF0E1D2C3B4A59687";
1247         let iv = "FEDCBA9876543210";
1248 
1249         cipher_test_nopad(super::Cipher::bf_ofb(), pt, ct, key, iv);
1250     }
1251 
1252     #[test]
1253     #[cfg_attr(ossl300, ignore)]
test_des_cbc()1254     fn test_des_cbc() {
1255         let pt = "54686973206973206120746573742e";
1256         let ct = "6f2867cfefda048a4046ef7e556c7132";
1257         let key = "7cb66337f3d3c0fe";
1258         let iv = "0001020304050607";
1259 
1260         cipher_test(super::Cipher::des_cbc(), pt, ct, key, iv);
1261     }
1262 
1263     #[test]
1264     #[cfg_attr(ossl300, ignore)]
test_des_ecb()1265     fn test_des_ecb() {
1266         let pt = "54686973206973206120746573742e";
1267         let ct = "0050ab8aecec758843fe157b4dde938c";
1268         let key = "7cb66337f3d3c0fe";
1269         let iv = "0001020304050607";
1270 
1271         cipher_test(super::Cipher::des_ecb(), pt, ct, key, iv);
1272     }
1273 
1274     #[test]
test_des_ede3()1275     fn test_des_ede3() {
1276         let pt = "9994f4c69d40ae4f34ff403b5cf39d4c8207ea5d3e19a5fd";
1277         let ct = "9e5c4297d60582f81071ac8ab7d0698d4c79de8b94c519858207ea5d3e19a5fd";
1278         let key = "010203040506070801020304050607080102030405060708";
1279         let iv = "5cc118306dc702e4";
1280 
1281         cipher_test(super::Cipher::des_ede3(), pt, ct, key, iv);
1282     }
1283 
1284     #[test]
test_des_ede3_cbc()1285     fn test_des_ede3_cbc() {
1286         let pt = "54686973206973206120746573742e";
1287         let ct = "6f2867cfefda048a4046ef7e556c7132";
1288         let key = "7cb66337f3d3c0fe7cb66337f3d3c0fe7cb66337f3d3c0fe";
1289         let iv = "0001020304050607";
1290 
1291         cipher_test(super::Cipher::des_ede3_cbc(), pt, ct, key, iv);
1292     }
1293 
1294     #[test]
test_des_ede3_cfb64()1295     fn test_des_ede3_cfb64() {
1296         let pt = "2b1773784b5889dc788477367daa98ad";
1297         let ct = "6f2867cfefda048a4046ef7e556c7132";
1298         let key = "7cb66337f3d3c0fe7cb66337f3d3c0fe7cb66337f3d3c0fe";
1299         let iv = "0001020304050607";
1300 
1301         cipher_test(super::Cipher::des_ede3_cfb64(), pt, ct, key, iv);
1302     }
1303 
1304     #[test]
test_aes128_gcm()1305     fn test_aes128_gcm() {
1306         let key = "23dc8d23d95b6fd1251741a64f7d4f41";
1307         let iv = "f416f48ad44d9efa1179e167";
1308         let pt = "6cb9b71dd0ccd42cdf87e8e396fc581fd8e0d700e360f590593b748e105390de";
1309         let aad = "45074844c97d515c65bbe37c210a5a4b08c21c588efe5c5f73c4d9c17d34dacddc0bb6a8a53f7bf477b9780c1c2a928660df87016b2873fe876b2b887fb5886bfd63216b7eaecc046372a82c047eb043f0b063226ee52a12c69b";
1310         let ct = "8ad20486778e87387efb3f2574e509951c0626816722018129e578b2787969d3";
1311         let tag = "91e1bc09";
1312 
1313         // this tag is smaller than you'd normally want, but I pulled this test from the part of
1314         // the NIST test vectors that cover 4 byte tags.
1315         let mut actual_tag = [0; 4];
1316         let out = encrypt_aead(
1317             Cipher::aes_128_gcm(),
1318             &Vec::from_hex(key).unwrap(),
1319             Some(&Vec::from_hex(iv).unwrap()),
1320             &Vec::from_hex(aad).unwrap(),
1321             &Vec::from_hex(pt).unwrap(),
1322             &mut actual_tag,
1323         )
1324         .unwrap();
1325         assert_eq!(ct, hex::encode(out));
1326         assert_eq!(tag, hex::encode(actual_tag));
1327 
1328         let out = decrypt_aead(
1329             Cipher::aes_128_gcm(),
1330             &Vec::from_hex(key).unwrap(),
1331             Some(&Vec::from_hex(iv).unwrap()),
1332             &Vec::from_hex(aad).unwrap(),
1333             &Vec::from_hex(ct).unwrap(),
1334             &Vec::from_hex(tag).unwrap(),
1335         )
1336         .unwrap();
1337         assert_eq!(pt, hex::encode(out));
1338     }
1339 
1340     #[test]
test_aes128_ccm()1341     fn test_aes128_ccm() {
1342         let key = "3ee186594f110fb788a8bf8aa8be5d4a";
1343         let nonce = "44f705d52acf27b7f17196aa9b";
1344         let aad = "2c16724296ff85e079627be3053ea95adf35722c21886baba343bd6c79b5cb57";
1345 
1346         let pt = "d71864877f2578db092daba2d6a1f9f4698a9c356c7830a1";
1347         let ct = "b4dd74e7a0cc51aea45dfb401a41d5822c96901a83247ea0";
1348         let tag = "d6965f5aa6e31302a9cc2b36";
1349 
1350         let mut actual_tag = [0; 12];
1351         let out = encrypt_aead(
1352             Cipher::aes_128_ccm(),
1353             &Vec::from_hex(key).unwrap(),
1354             Some(&Vec::from_hex(nonce).unwrap()),
1355             &Vec::from_hex(aad).unwrap(),
1356             &Vec::from_hex(pt).unwrap(),
1357             &mut actual_tag,
1358         )
1359         .unwrap();
1360 
1361         assert_eq!(ct, hex::encode(out));
1362         assert_eq!(tag, hex::encode(actual_tag));
1363 
1364         let out = decrypt_aead(
1365             Cipher::aes_128_ccm(),
1366             &Vec::from_hex(key).unwrap(),
1367             Some(&Vec::from_hex(nonce).unwrap()),
1368             &Vec::from_hex(aad).unwrap(),
1369             &Vec::from_hex(ct).unwrap(),
1370             &Vec::from_hex(tag).unwrap(),
1371         )
1372         .unwrap();
1373         assert_eq!(pt, hex::encode(out));
1374     }
1375 
1376     #[test]
test_aes128_ccm_verify_fail()1377     fn test_aes128_ccm_verify_fail() {
1378         let key = "3ee186594f110fb788a8bf8aa8be5d4a";
1379         let nonce = "44f705d52acf27b7f17196aa9b";
1380         let aad = "2c16724296ff85e079627be3053ea95adf35722c21886baba343bd6c79b5cb57";
1381 
1382         let ct = "b4dd74e7a0cc51aea45dfb401a41d5822c96901a83247ea0";
1383         let tag = "00005f5aa6e31302a9cc2b36";
1384 
1385         let out = decrypt_aead(
1386             Cipher::aes_128_ccm(),
1387             &Vec::from_hex(key).unwrap(),
1388             Some(&Vec::from_hex(nonce).unwrap()),
1389             &Vec::from_hex(aad).unwrap(),
1390             &Vec::from_hex(ct).unwrap(),
1391             &Vec::from_hex(tag).unwrap(),
1392         );
1393         assert!(out.is_err());
1394     }
1395 
1396     #[test]
test_aes256_ccm()1397     fn test_aes256_ccm() {
1398         let key = "7f4af6765cad1d511db07e33aaafd57646ec279db629048aa6770af24849aa0d";
1399         let nonce = "dde2a362ce81b2b6913abc3095";
1400         let aad = "404f5df97ece7431987bc098cce994fc3c063b519ffa47b0365226a0015ef695";
1401 
1402         let pt = "7ebef26bf4ecf6f0ebb2eb860edbf900f27b75b4a6340fdb";
1403         let ct = "353022db9c568bd7183a13c40b1ba30fcc768c54264aa2cd";
1404         let tag = "2927a053c9244d3217a7ad05";
1405 
1406         let mut actual_tag = [0; 12];
1407         let out = encrypt_aead(
1408             Cipher::aes_256_ccm(),
1409             &Vec::from_hex(key).unwrap(),
1410             Some(&Vec::from_hex(nonce).unwrap()),
1411             &Vec::from_hex(aad).unwrap(),
1412             &Vec::from_hex(pt).unwrap(),
1413             &mut actual_tag,
1414         )
1415         .unwrap();
1416 
1417         assert_eq!(ct, hex::encode(out));
1418         assert_eq!(tag, hex::encode(actual_tag));
1419 
1420         let out = decrypt_aead(
1421             Cipher::aes_256_ccm(),
1422             &Vec::from_hex(key).unwrap(),
1423             Some(&Vec::from_hex(nonce).unwrap()),
1424             &Vec::from_hex(aad).unwrap(),
1425             &Vec::from_hex(ct).unwrap(),
1426             &Vec::from_hex(tag).unwrap(),
1427         )
1428         .unwrap();
1429         assert_eq!(pt, hex::encode(out));
1430     }
1431 
1432     #[test]
test_aes256_ccm_verify_fail()1433     fn test_aes256_ccm_verify_fail() {
1434         let key = "7f4af6765cad1d511db07e33aaafd57646ec279db629048aa6770af24849aa0d";
1435         let nonce = "dde2a362ce81b2b6913abc3095";
1436         let aad = "404f5df97ece7431987bc098cce994fc3c063b519ffa47b0365226a0015ef695";
1437 
1438         let ct = "353022db9c568bd7183a13c40b1ba30fcc768c54264aa2cd";
1439         let tag = "0000a053c9244d3217a7ad05";
1440 
1441         let out = decrypt_aead(
1442             Cipher::aes_256_ccm(),
1443             &Vec::from_hex(key).unwrap(),
1444             Some(&Vec::from_hex(nonce).unwrap()),
1445             &Vec::from_hex(aad).unwrap(),
1446             &Vec::from_hex(ct).unwrap(),
1447             &Vec::from_hex(tag).unwrap(),
1448         );
1449         assert!(out.is_err());
1450     }
1451 
1452     #[test]
1453     #[cfg(ossl110)]
test_aes_128_ocb()1454     fn test_aes_128_ocb() {
1455         let key = "000102030405060708090a0b0c0d0e0f";
1456         let aad = "0001020304050607";
1457         let tag = "16dc76a46d47e1ead537209e8a96d14e";
1458         let iv = "000102030405060708090a0b";
1459         let pt = "0001020304050607";
1460         let ct = "92b657130a74b85a";
1461 
1462         let mut actual_tag = [0; 16];
1463         let out = encrypt_aead(
1464             Cipher::aes_128_ocb(),
1465             &Vec::from_hex(key).unwrap(),
1466             Some(&Vec::from_hex(iv).unwrap()),
1467             &Vec::from_hex(aad).unwrap(),
1468             &Vec::from_hex(pt).unwrap(),
1469             &mut actual_tag,
1470         )
1471         .unwrap();
1472 
1473         assert_eq!(ct, hex::encode(out));
1474         assert_eq!(tag, hex::encode(actual_tag));
1475 
1476         let out = decrypt_aead(
1477             Cipher::aes_128_ocb(),
1478             &Vec::from_hex(key).unwrap(),
1479             Some(&Vec::from_hex(iv).unwrap()),
1480             &Vec::from_hex(aad).unwrap(),
1481             &Vec::from_hex(ct).unwrap(),
1482             &Vec::from_hex(tag).unwrap(),
1483         )
1484         .unwrap();
1485         assert_eq!(pt, hex::encode(out));
1486     }
1487 
1488     #[test]
1489     #[cfg(ossl110)]
test_aes_128_ocb_fail()1490     fn test_aes_128_ocb_fail() {
1491         let key = "000102030405060708090a0b0c0d0e0f";
1492         let aad = "0001020304050607";
1493         let tag = "16dc76a46d47e1ead537209e8a96d14e";
1494         let iv = "000000000405060708090a0b";
1495         let ct = "92b657130a74b85a";
1496 
1497         let out = decrypt_aead(
1498             Cipher::aes_128_ocb(),
1499             &Vec::from_hex(key).unwrap(),
1500             Some(&Vec::from_hex(iv).unwrap()),
1501             &Vec::from_hex(aad).unwrap(),
1502             &Vec::from_hex(ct).unwrap(),
1503             &Vec::from_hex(tag).unwrap(),
1504         );
1505         assert!(out.is_err());
1506     }
1507 
1508     #[test]
1509     #[cfg(any(ossl110))]
test_chacha20()1510     fn test_chacha20() {
1511         let key = "0000000000000000000000000000000000000000000000000000000000000000";
1512         let iv = "00000000000000000000000000000000";
1513         let pt =
1514             "000000000000000000000000000000000000000000000000000000000000000000000000000000000\
1515              00000000000000000000000000000000000000000000000";
1516         let ct =
1517             "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7\
1518              724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586";
1519 
1520         cipher_test(Cipher::chacha20(), pt, ct, key, iv);
1521     }
1522 
1523     #[test]
1524     #[cfg(any(ossl110))]
test_chacha20_poly1305()1525     fn test_chacha20_poly1305() {
1526         let key = "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f";
1527         let iv = "070000004041424344454647";
1528         let aad = "50515253c0c1c2c3c4c5c6c7";
1529         let pt =
1530             "4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393\
1531              a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f722074\
1532              6865206675747572652c2073756e73637265656e20776f756c642062652069742e";
1533         let ct =
1534             "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca967128\
1535              2fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fa\
1536              b324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116";
1537         let tag = "1ae10b594f09e26a7e902ecbd0600691";
1538 
1539         let mut actual_tag = [0; 16];
1540         let out = encrypt_aead(
1541             Cipher::chacha20_poly1305(),
1542             &Vec::from_hex(key).unwrap(),
1543             Some(&Vec::from_hex(iv).unwrap()),
1544             &Vec::from_hex(aad).unwrap(),
1545             &Vec::from_hex(pt).unwrap(),
1546             &mut actual_tag,
1547         )
1548         .unwrap();
1549         assert_eq!(ct, hex::encode(out));
1550         assert_eq!(tag, hex::encode(actual_tag));
1551 
1552         let out = decrypt_aead(
1553             Cipher::chacha20_poly1305(),
1554             &Vec::from_hex(key).unwrap(),
1555             Some(&Vec::from_hex(iv).unwrap()),
1556             &Vec::from_hex(aad).unwrap(),
1557             &Vec::from_hex(ct).unwrap(),
1558             &Vec::from_hex(tag).unwrap(),
1559         )
1560         .unwrap();
1561         assert_eq!(pt, hex::encode(out));
1562     }
1563 }
1564