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//! ```
54use crate::cipher::CipherRef;
55use crate::cipher_ctx::{CipherCtx, CipherCtxRef};
56use crate::error::ErrorStack;
57use crate::nid::Nid;
58use cfg_if::cfg_if;
59use foreign_types::ForeignTypeRef;
60
61#[derive(Copy, Clone)]
62pub 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)]
73pub struct Cipher(*const ffi::EVP_CIPHER);
74
75impl 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
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/manmaster/crypto/EVP_CIPHER_nid.html
95    pub fn nid(&self) -> Nid {
96        let nid = unsafe { ffi::EVP_CIPHER_nid(self.0) };
97        Nid::from_raw(nid)
98    }
99
100    pub fn aes_128_ecb() -> Cipher {
101        unsafe { Cipher(ffi::EVP_aes_128_ecb()) }
102    }
103
104    pub fn aes_128_cbc() -> Cipher {
105        unsafe { Cipher(ffi::EVP_aes_128_cbc()) }
106    }
107
108    #[cfg(not(boringssl))]
109    pub fn aes_128_xts() -> Cipher {
110        unsafe { Cipher(ffi::EVP_aes_128_xts()) }
111    }
112
113    pub fn aes_128_ctr() -> Cipher {
114        unsafe { Cipher(ffi::EVP_aes_128_ctr()) }
115    }
116
117    #[cfg(not(boringssl))]
118    pub fn aes_128_cfb1() -> Cipher {
119        unsafe { Cipher(ffi::EVP_aes_128_cfb1()) }
120    }
121
122    pub fn aes_128_cfb128() -> Cipher {
123        unsafe { Cipher(ffi::EVP_aes_128_cfb128()) }
124    }
125
126    #[cfg(not(boringssl))]
127    pub fn aes_128_cfb8() -> Cipher {
128        unsafe { Cipher(ffi::EVP_aes_128_cfb8()) }
129    }
130
131    pub fn aes_128_gcm() -> Cipher {
132        unsafe { Cipher(ffi::EVP_aes_128_gcm()) }
133    }
134
135    #[cfg(not(boringssl))]
136    pub fn aes_128_ccm() -> Cipher {
137        unsafe { Cipher(ffi::EVP_aes_128_ccm()) }
138    }
139
140    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")))]
146    pub fn aes_128_ocb() -> Cipher {
147        unsafe { Cipher(ffi::EVP_aes_128_ocb()) }
148    }
149
150    pub fn aes_192_ecb() -> Cipher {
151        unsafe { Cipher(ffi::EVP_aes_192_ecb()) }
152    }
153
154    pub fn aes_192_cbc() -> Cipher {
155        unsafe { Cipher(ffi::EVP_aes_192_cbc()) }
156    }
157
158    pub fn aes_192_ctr() -> Cipher {
159        unsafe { Cipher(ffi::EVP_aes_192_ctr()) }
160    }
161
162    #[cfg(not(boringssl))]
163    pub fn aes_192_cfb1() -> Cipher {
164        unsafe { Cipher(ffi::EVP_aes_192_cfb1()) }
165    }
166
167    pub fn aes_192_cfb128() -> Cipher {
168        unsafe { Cipher(ffi::EVP_aes_192_cfb128()) }
169    }
170
171    #[cfg(not(boringssl))]
172    pub fn aes_192_cfb8() -> Cipher {
173        unsafe { Cipher(ffi::EVP_aes_192_cfb8()) }
174    }
175
176    pub fn aes_192_gcm() -> Cipher {
177        unsafe { Cipher(ffi::EVP_aes_192_gcm()) }
178    }
179
180    #[cfg(not(boringssl))]
181    pub fn aes_192_ccm() -> Cipher {
182        unsafe { Cipher(ffi::EVP_aes_192_ccm()) }
183    }
184
185    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")))]
191    pub fn aes_192_ocb() -> Cipher {
192        unsafe { Cipher(ffi::EVP_aes_192_ocb()) }
193    }
194
195    pub fn aes_256_ecb() -> Cipher {
196        unsafe { Cipher(ffi::EVP_aes_256_ecb()) }
197    }
198
199    pub fn aes_256_cbc() -> Cipher {
200        unsafe { Cipher(ffi::EVP_aes_256_cbc()) }
201    }
202
203    #[cfg(not(boringssl))]
204    pub fn aes_256_xts() -> Cipher {
205        unsafe { Cipher(ffi::EVP_aes_256_xts()) }
206    }
207
208    pub fn aes_256_ctr() -> Cipher {
209        unsafe { Cipher(ffi::EVP_aes_256_ctr()) }
210    }
211
212    #[cfg(not(boringssl))]
213    pub fn aes_256_cfb1() -> Cipher {
214        unsafe { Cipher(ffi::EVP_aes_256_cfb1()) }
215    }
216
217    pub fn aes_256_cfb128() -> Cipher {
218        unsafe { Cipher(ffi::EVP_aes_256_cfb128()) }
219    }
220
221    #[cfg(not(boringssl))]
222    pub fn aes_256_cfb8() -> Cipher {
223        unsafe { Cipher(ffi::EVP_aes_256_cfb8()) }
224    }
225
226    pub fn aes_256_gcm() -> Cipher {
227        unsafe { Cipher(ffi::EVP_aes_256_gcm()) }
228    }
229
230    #[cfg(not(boringssl))]
231    pub fn aes_256_ccm() -> Cipher {
232        unsafe { Cipher(ffi::EVP_aes_256_ccm()) }
233    }
234
235    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")))]
241    pub fn aes_256_ocb() -> Cipher {
242        unsafe { Cipher(ffi::EVP_aes_256_ocb()) }
243    }
244
245    #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
246    pub fn bf_cbc() -> Cipher {
247        unsafe { Cipher(ffi::EVP_bf_cbc()) }
248    }
249
250    #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
251    pub fn bf_ecb() -> Cipher {
252        unsafe { Cipher(ffi::EVP_bf_ecb()) }
253    }
254
255    #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_BF")))]
256    pub fn bf_cfb64() -> Cipher {
257        unsafe { Cipher(ffi::EVP_bf_cfb64()) }
258    }
259
260    #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_BF")))]
261    pub fn bf_ofb() -> Cipher {
262        unsafe { Cipher(ffi::EVP_bf_ofb()) }
263    }
264
265    pub fn des_cbc() -> Cipher {
266        unsafe { Cipher(ffi::EVP_des_cbc()) }
267    }
268
269    pub fn des_ecb() -> Cipher {
270        unsafe { Cipher(ffi::EVP_des_ecb()) }
271    }
272
273    pub fn des_ede3() -> Cipher {
274        unsafe { Cipher(ffi::EVP_des_ede3()) }
275    }
276
277    pub fn des_ede3_cbc() -> Cipher {
278        unsafe { Cipher(ffi::EVP_des_ede3_cbc()) }
279    }
280
281    #[cfg(not(boringssl))]
282    pub fn des_ede3_cfb64() -> Cipher {
283        unsafe { Cipher(ffi::EVP_des_ede3_cfb64()) }
284    }
285
286    #[cfg(not(osslconf = "OPENSSL_NO_RC4"))]
287    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")))]
293    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")))]
299    pub fn chacha20_poly1305() -> Cipher {
300        unsafe { Cipher(ffi::EVP_chacha20_poly1305()) }
301    }
302
303    #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))]
304    pub fn seed_cbc() -> Cipher {
305        unsafe { Cipher(ffi::EVP_seed_cbc()) }
306    }
307
308    #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))]
309    pub fn seed_cfb128() -> Cipher {
310        unsafe { Cipher(ffi::EVP_seed_cfb128()) }
311    }
312
313    #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))]
314    pub fn seed_ecb() -> Cipher {
315        unsafe { Cipher(ffi::EVP_seed_ecb()) }
316    }
317
318    #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))]
319    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")))]
324    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")))]
329    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")))]
334    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")))]
339    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")))]
344    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.
353    pub unsafe fn from_ptr(ptr: *const ffi::EVP_CIPHER) -> Cipher {
354        Cipher(ptr)
355    }
356
357    #[allow(clippy::trivially_copy_pass_by_ref)]
358    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)]
364    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)]
371    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)]
388    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))]
394    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)]
400    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")))]
406    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
418unsafe impl Sync for Cipher {}
419unsafe 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/// ```
481pub struct Crypter {
482    ctx: CipherCtx,
483}
484
485impl 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.
493    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.
530    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`.
537    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.
545    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.
553    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`.
562    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()`.
581    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`).
596    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.
608    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/// ```
643pub 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/// ```
682pub 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
691fn 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.
714pub 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.
745pub 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
778cfg_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)]
785        pub unsafe fn EVP_CIPHER_iv_length(ptr: *const ffi::EVP_CIPHER) -> LenType {
786            (*ptr).iv_len
787        }
788
789        #[allow(bad_style)]
790        pub unsafe fn EVP_CIPHER_block_size(ptr: *const ffi::EVP_CIPHER) -> LenType {
791            (*ptr).block_size
792        }
793
794        #[allow(bad_style)]
795        pub unsafe fn EVP_CIPHER_key_length(ptr: *const ffi::EVP_CIPHER) -> LenType {
796            (*ptr).key_len
797        }
798    }
799}
800
801#[cfg(test)]
802mod tests {
803    use super::*;
804    use hex::{self, FromHex};
805
806    #[test]
807    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]
826    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]
870    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
902    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))]
926    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]
958    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))]
972    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]
987    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))]
1000    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))]
1013    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))]
1024    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]
1034    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]
1046    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))]
1059    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))]
1072    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))]
1085    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]
1097    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))]
1110    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))]
1121    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))]
1132    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]
1142    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))]
1156    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))]
1173    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))]
1188    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))]
1203    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]
1216    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]
1229    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]
1242    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]
1252    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))]
1263    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]
1273    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))]
1310    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))]
1347    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))]
1368    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))]
1405    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")))]
1426    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")))]
1462    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)]
1482    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)]
1497    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)))]
1538    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)))]
1552    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)))]
1566    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)))]
1580    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")))]
1596    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