Skip to main content

openssl/
symm.rs

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