Coverage Report

Created: 2025-09-04 06:37

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