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