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