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_nidnull81 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
nidnull95 pub fn nid(&self) -> Nid {
96 let nid = unsafe { ffi::EVP_CIPHER_nid(self.0) };
97 Nid::from_raw(nid)
98 }
99
aes_128_ecbnull100 pub fn aes_128_ecb() -> Cipher {
101 unsafe { Cipher(ffi::EVP_aes_128_ecb()) }
102 }
103
aes_128_cbcnull104 pub fn aes_128_cbc() -> Cipher {
105 unsafe { Cipher(ffi::EVP_aes_128_cbc()) }
106 }
107
108 #[cfg(not(boringssl))]
aes_128_xtsnull109 pub fn aes_128_xts() -> Cipher {
110 unsafe { Cipher(ffi::EVP_aes_128_xts()) }
111 }
112
aes_128_ctrnull113 pub fn aes_128_ctr() -> Cipher {
114 unsafe { Cipher(ffi::EVP_aes_128_ctr()) }
115 }
116
117 #[cfg(not(boringssl))]
aes_128_cfb1null118 pub fn aes_128_cfb1() -> Cipher {
119 unsafe { Cipher(ffi::EVP_aes_128_cfb1()) }
120 }
121
aes_128_cfb128null122 pub fn aes_128_cfb128() -> Cipher {
123 unsafe { Cipher(ffi::EVP_aes_128_cfb128()) }
124 }
125
126 #[cfg(not(boringssl))]
aes_128_cfb8null127 pub fn aes_128_cfb8() -> Cipher {
128 unsafe { Cipher(ffi::EVP_aes_128_cfb8()) }
129 }
130
aes_128_gcmnull131 pub fn aes_128_gcm() -> Cipher {
132 unsafe { Cipher(ffi::EVP_aes_128_gcm()) }
133 }
134
135 #[cfg(not(boringssl))]
aes_128_ccmnull136 pub fn aes_128_ccm() -> Cipher {
137 unsafe { Cipher(ffi::EVP_aes_128_ccm()) }
138 }
139
aes_128_ofbnull140 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_ocbnull146 pub fn aes_128_ocb() -> Cipher {
147 unsafe { Cipher(ffi::EVP_aes_128_ocb()) }
148 }
149
aes_192_ecbnull150 pub fn aes_192_ecb() -> Cipher {
151 unsafe { Cipher(ffi::EVP_aes_192_ecb()) }
152 }
153
aes_192_cbcnull154 pub fn aes_192_cbc() -> Cipher {
155 unsafe { Cipher(ffi::EVP_aes_192_cbc()) }
156 }
157
aes_192_ctrnull158 pub fn aes_192_ctr() -> Cipher {
159 unsafe { Cipher(ffi::EVP_aes_192_ctr()) }
160 }
161
162 #[cfg(not(boringssl))]
aes_192_cfb1null163 pub fn aes_192_cfb1() -> Cipher {
164 unsafe { Cipher(ffi::EVP_aes_192_cfb1()) }
165 }
166
aes_192_cfb128null167 pub fn aes_192_cfb128() -> Cipher {
168 unsafe { Cipher(ffi::EVP_aes_192_cfb128()) }
169 }
170
171 #[cfg(not(boringssl))]
aes_192_cfb8null172 pub fn aes_192_cfb8() -> Cipher {
173 unsafe { Cipher(ffi::EVP_aes_192_cfb8()) }
174 }
175
aes_192_gcmnull176 pub fn aes_192_gcm() -> Cipher {
177 unsafe { Cipher(ffi::EVP_aes_192_gcm()) }
178 }
179
180 #[cfg(not(boringssl))]
aes_192_ccmnull181 pub fn aes_192_ccm() -> Cipher {
182 unsafe { Cipher(ffi::EVP_aes_192_ccm()) }
183 }
184
aes_192_ofbnull185 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_ocbnull191 pub fn aes_192_ocb() -> Cipher {
192 unsafe { Cipher(ffi::EVP_aes_192_ocb()) }
193 }
194
aes_256_ecbnull195 pub fn aes_256_ecb() -> Cipher {
196 unsafe { Cipher(ffi::EVP_aes_256_ecb()) }
197 }
198
aes_256_cbcnull199 pub fn aes_256_cbc() -> Cipher {
200 unsafe { Cipher(ffi::EVP_aes_256_cbc()) }
201 }
202
203 #[cfg(not(boringssl))]
aes_256_xtsnull204 pub fn aes_256_xts() -> Cipher {
205 unsafe { Cipher(ffi::EVP_aes_256_xts()) }
206 }
207
aes_256_ctrnull208 pub fn aes_256_ctr() -> Cipher {
209 unsafe { Cipher(ffi::EVP_aes_256_ctr()) }
210 }
211
212 #[cfg(not(boringssl))]
aes_256_cfb1null213 pub fn aes_256_cfb1() -> Cipher {
214 unsafe { Cipher(ffi::EVP_aes_256_cfb1()) }
215 }
216
aes_256_cfb128null217 pub fn aes_256_cfb128() -> Cipher {
218 unsafe { Cipher(ffi::EVP_aes_256_cfb128()) }
219 }
220
221 #[cfg(not(boringssl))]
aes_256_cfb8null222 pub fn aes_256_cfb8() -> Cipher {
223 unsafe { Cipher(ffi::EVP_aes_256_cfb8()) }
224 }
225
aes_256_gcmnull226 pub fn aes_256_gcm() -> Cipher {
227 unsafe { Cipher(ffi::EVP_aes_256_gcm()) }
228 }
229
230 #[cfg(not(boringssl))]
aes_256_ccmnull231 pub fn aes_256_ccm() -> Cipher {
232 unsafe { Cipher(ffi::EVP_aes_256_ccm()) }
233 }
234
aes_256_ofbnull235 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_ocbnull241 pub fn aes_256_ocb() -> Cipher {
242 unsafe { Cipher(ffi::EVP_aes_256_ocb()) }
243 }
244
245 #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
bf_cbcnull246 pub fn bf_cbc() -> Cipher {
247 unsafe { Cipher(ffi::EVP_bf_cbc()) }
248 }
249
250 #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
bf_ecbnull251 pub fn bf_ecb() -> Cipher {
252 unsafe { Cipher(ffi::EVP_bf_ecb()) }
253 }
254
255 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_BF")))]
bf_cfb64null256 pub fn bf_cfb64() -> Cipher {
257 unsafe { Cipher(ffi::EVP_bf_cfb64()) }
258 }
259
260 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_BF")))]
bf_ofbnull261 pub fn bf_ofb() -> Cipher {
262 unsafe { Cipher(ffi::EVP_bf_ofb()) }
263 }
264
des_cbcnull265 pub fn des_cbc() -> Cipher {
266 unsafe { Cipher(ffi::EVP_des_cbc()) }
267 }
268
des_ecbnull269 pub fn des_ecb() -> Cipher {
270 unsafe { Cipher(ffi::EVP_des_ecb()) }
271 }
272
des_ede3null273 pub fn des_ede3() -> Cipher {
274 unsafe { Cipher(ffi::EVP_des_ede3()) }
275 }
276
des_ede3_cbcnull277 pub fn des_ede3_cbc() -> Cipher {
278 unsafe { Cipher(ffi::EVP_des_ede3_cbc()) }
279 }
280
281 #[cfg(not(boringssl))]
des_ede3_cfb64null282 pub fn des_ede3_cfb64() -> Cipher {
283 unsafe { Cipher(ffi::EVP_des_ede3_cfb64()) }
284 }
285
286 #[cfg(not(osslconf = "OPENSSL_NO_RC4"))]
rc4null287 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")))]
chacha20null293 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_poly1305null299 pub fn chacha20_poly1305() -> Cipher {
300 unsafe { Cipher(ffi::EVP_chacha20_poly1305()) }
301 }
302
303 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))]
seed_cbcnull304 pub fn seed_cbc() -> Cipher {
305 unsafe { Cipher(ffi::EVP_seed_cbc()) }
306 }
307
308 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))]
seed_cfb128null309 pub fn seed_cfb128() -> Cipher {
310 unsafe { Cipher(ffi::EVP_seed_cfb128()) }
311 }
312
313 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))]
seed_ecbnull314 pub fn seed_ecb() -> Cipher {
315 unsafe { Cipher(ffi::EVP_seed_ecb()) }
316 }
317
318 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))]
seed_ofbnull319 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_ecbnull324 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_cbcnull329 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_ctrnull334 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_cfb128null339 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_ofbnull344 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_ptrnull353 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_ptrnull358 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_lennull364 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_lennull371 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_sizenull388 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_ccmnull394 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_ccmnull400 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_ocbnull406 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"))]
413 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.
newnull493 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.
padnull530 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_tagnull537 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_lennull545 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_lennull553 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_updatenull562 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()`.
updatenull581 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`).
finalizenull596 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_tagnull608 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 /// ```
encryptnull643 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 /// ```
decryptnull682 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
ciphernull691 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_aeadnull714 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_aeadnull745 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)]
EVP_CIPHER_iv_lengthnull785 pub unsafe fn EVP_CIPHER_iv_length(ptr: *const ffi::EVP_CIPHER) -> LenType {
786 (*ptr).iv_len
787 }
788
789 #[allow(bad_style)]
EVP_CIPHER_block_sizenull790 pub unsafe fn EVP_CIPHER_block_size(ptr: *const ffi::EVP_CIPHER) -> LenType {
791 (*ptr).block_size
792 }
793
794 #[allow(bad_style)]
EVP_CIPHER_key_lengthnull795 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_outputnull807 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_ecbnull826 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_decryptnull870 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_testnull902 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_nopadnull926 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_rc4null958 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_xtsnull972 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_ctrnull987 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_cfb1null1000 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_cfb128null1013 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_cfb8null1024 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_ofbnull1034 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_ctrnull1046 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_cfb1null1059 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_cfb128null1072 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_cfb8null1085 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_ofbnull1097 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_cfb1null1110 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_cfb128null1121 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_cfb8null1132 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_ofbnull1142 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_cbcnull1156 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_ecbnull1173 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_cfb64null1188 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_ofbnull1203 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_cbcnull1216 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_ecbnull1229 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_ede3null1242 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_cbcnull1252 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_cfb64null1263 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_gcmnull1273 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_ccmnull1310 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_failnull1347 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_ccmnull1368 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_failnull1405 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_ocbnull1426 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_failnull1462 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_chacha20null1482 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_poly1305null1497 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_cbcnull1538 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_cfb128null1552 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_ecbnull1566 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_ofbnull1580 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_ecbnull1596 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