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