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