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