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