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