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