variant_ssl/
symm.rs

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