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