1use crate::cipher::CipherRef;
55use crate::cipher_ctx::{CipherCtx, CipherCtxRef};
56use crate::error::ErrorStack;
57use crate::nid::Nid;
58use foreign_types::ForeignTypeRef;
59use openssl_macros::corresponds;
60
61#[derive(Copy, Clone)]
62pub enum Mode {
63 Encrypt,
64 Decrypt,
65}
66
67#[derive(Copy, Clone, PartialEq, Eq)]
73pub struct Cipher(*const ffi::EVP_CIPHER);
74
75impl Cipher {
76 #[corresponds(EVP_get_cipherbynid)]
78 pub fn from_nid(nid: Nid) -> Option<Cipher> {
79 let ptr = unsafe { ffi::EVP_get_cipherbyname(ffi::OBJ_nid2sn(nid.as_raw())) };
80 if ptr.is_null() {
81 None
82 } else {
83 Some(Cipher(ptr))
84 }
85 }
86
87 #[corresponds(EVP_CIPHER_nid)]
89 pub fn nid(&self) -> Nid {
90 let nid = unsafe { ffi::EVP_CIPHER_nid(self.0) };
91 Nid::from_raw(nid)
92 }
93
94 pub fn aes_128_ecb() -> Cipher {
95 unsafe { Cipher(ffi::EVP_aes_128_ecb()) }
96 }
97
98 pub fn aes_128_cbc() -> Cipher {
99 unsafe { Cipher(ffi::EVP_aes_128_cbc()) }
100 }
101
102 #[cfg(not(any(boringssl, awslc)))]
103 pub fn aes_128_xts() -> Cipher {
104 unsafe { Cipher(ffi::EVP_aes_128_xts()) }
105 }
106
107 pub fn aes_128_ctr() -> Cipher {
108 unsafe { Cipher(ffi::EVP_aes_128_ctr()) }
109 }
110
111 #[cfg(not(boringssl))]
112 pub fn aes_128_cfb1() -> Cipher {
113 unsafe { Cipher(ffi::EVP_aes_128_cfb1()) }
114 }
115
116 #[cfg(not(boringssl))]
117 pub fn aes_128_cfb128() -> Cipher {
118 unsafe { Cipher(ffi::EVP_aes_128_cfb128()) }
119 }
120
121 #[cfg(not(boringssl))]
122 pub fn aes_128_cfb8() -> Cipher {
123 unsafe { Cipher(ffi::EVP_aes_128_cfb8()) }
124 }
125
126 pub fn aes_128_gcm() -> Cipher {
127 unsafe { Cipher(ffi::EVP_aes_128_gcm()) }
128 }
129
130 #[cfg(not(boringssl))]
131 pub fn aes_128_ccm() -> Cipher {
132 unsafe { Cipher(ffi::EVP_aes_128_ccm()) }
133 }
134
135 pub fn aes_128_ofb() -> Cipher {
136 unsafe { Cipher(ffi::EVP_aes_128_ofb()) }
137 }
138
139 #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
141 pub fn aes_128_ocb() -> Cipher {
142 unsafe { Cipher(ffi::EVP_aes_128_ocb()) }
143 }
144
145 pub fn aes_192_ecb() -> Cipher {
146 unsafe { Cipher(ffi::EVP_aes_192_ecb()) }
147 }
148
149 pub fn aes_192_cbc() -> Cipher {
150 unsafe { Cipher(ffi::EVP_aes_192_cbc()) }
151 }
152
153 pub fn aes_192_ctr() -> Cipher {
154 unsafe { Cipher(ffi::EVP_aes_192_ctr()) }
155 }
156
157 #[cfg(not(boringssl))]
158 pub fn aes_192_cfb1() -> Cipher {
159 unsafe { Cipher(ffi::EVP_aes_192_cfb1()) }
160 }
161
162 #[cfg(not(boringssl))]
163 pub fn aes_192_cfb128() -> Cipher {
164 unsafe { Cipher(ffi::EVP_aes_192_cfb128()) }
165 }
166
167 #[cfg(not(boringssl))]
168 pub fn aes_192_cfb8() -> Cipher {
169 unsafe { Cipher(ffi::EVP_aes_192_cfb8()) }
170 }
171
172 pub fn aes_192_gcm() -> Cipher {
173 unsafe { Cipher(ffi::EVP_aes_192_gcm()) }
174 }
175
176 #[cfg(not(any(boringssl, awslc)))]
177 pub fn aes_192_ccm() -> Cipher {
178 unsafe { Cipher(ffi::EVP_aes_192_ccm()) }
179 }
180
181 pub fn aes_192_ofb() -> Cipher {
182 unsafe { Cipher(ffi::EVP_aes_192_ofb()) }
183 }
184
185 #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
187 pub fn aes_192_ocb() -> Cipher {
188 unsafe { Cipher(ffi::EVP_aes_192_ocb()) }
189 }
190
191 pub fn aes_256_ecb() -> Cipher {
192 unsafe { Cipher(ffi::EVP_aes_256_ecb()) }
193 }
194
195 pub fn aes_256_cbc() -> Cipher {
196 unsafe { Cipher(ffi::EVP_aes_256_cbc()) }
197 }
198
199 #[cfg(not(boringssl))]
200 pub fn aes_256_xts() -> Cipher {
201 unsafe { Cipher(ffi::EVP_aes_256_xts()) }
202 }
203
204 pub fn aes_256_ctr() -> Cipher {
205 unsafe { Cipher(ffi::EVP_aes_256_ctr()) }
206 }
207
208 #[cfg(not(boringssl))]
209 pub fn aes_256_cfb1() -> Cipher {
210 unsafe { Cipher(ffi::EVP_aes_256_cfb1()) }
211 }
212
213 #[cfg(not(boringssl))]
214 pub fn aes_256_cfb128() -> Cipher {
215 unsafe { Cipher(ffi::EVP_aes_256_cfb128()) }
216 }
217
218 #[cfg(not(boringssl))]
219 pub fn aes_256_cfb8() -> Cipher {
220 unsafe { Cipher(ffi::EVP_aes_256_cfb8()) }
221 }
222
223 pub fn aes_256_gcm() -> Cipher {
224 unsafe { Cipher(ffi::EVP_aes_256_gcm()) }
225 }
226
227 #[cfg(not(boringssl))]
228 pub fn aes_256_ccm() -> Cipher {
229 unsafe { Cipher(ffi::EVP_aes_256_ccm()) }
230 }
231
232 pub fn aes_256_ofb() -> Cipher {
233 unsafe { Cipher(ffi::EVP_aes_256_ofb()) }
234 }
235
236 #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
238 pub fn aes_256_ocb() -> Cipher {
239 unsafe { Cipher(ffi::EVP_aes_256_ocb()) }
240 }
241
242 #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
243 pub fn bf_cbc() -> Cipher {
244 unsafe { Cipher(ffi::EVP_bf_cbc()) }
245 }
246
247 #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
248 pub fn bf_ecb() -> Cipher {
249 unsafe { Cipher(ffi::EVP_bf_ecb()) }
250 }
251
252 #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
253 pub fn bf_cfb64() -> Cipher {
254 unsafe { Cipher(ffi::EVP_bf_cfb64()) }
255 }
256
257 #[cfg(not(osslconf = "OPENSSL_NO_BF"))]
258 pub fn bf_ofb() -> Cipher {
259 unsafe { Cipher(ffi::EVP_bf_ofb()) }
260 }
261
262 pub fn des_cbc() -> Cipher {
263 unsafe { Cipher(ffi::EVP_des_cbc()) }
264 }
265
266 pub fn des_ecb() -> Cipher {
267 unsafe { Cipher(ffi::EVP_des_ecb()) }
268 }
269
270 pub fn des_ede3() -> Cipher {
271 unsafe { Cipher(ffi::EVP_des_ede3()) }
272 }
273
274 pub fn des_ede3_cbc() -> Cipher {
275 unsafe { Cipher(ffi::EVP_des_ede3_cbc()) }
276 }
277
278 pub fn des_ede3_ecb() -> Cipher {
279 unsafe { Cipher(ffi::EVP_des_ede3_ecb()) }
280 }
281
282 #[cfg(not(any(boringssl, awslc)))]
283 pub fn des_ede3_cfb64() -> Cipher {
284 unsafe { Cipher(ffi::EVP_des_ede3_cfb64()) }
285 }
286
287 #[cfg(not(any(boringssl, awslc)))]
288 pub fn des_ede3_cfb8() -> Cipher {
289 unsafe { Cipher(ffi::EVP_des_ede3_cfb8()) }
290 }
291
292 #[cfg(not(any(boringssl, awslc)))]
293 pub fn des_ede3_ofb() -> Cipher {
294 unsafe { Cipher(ffi::EVP_des_ede3_ofb()) }
295 }
296
297 #[cfg(not(osslconf = "OPENSSL_NO_RC4"))]
298 pub fn rc4() -> Cipher {
299 unsafe { Cipher(ffi::EVP_rc4()) }
300 }
301
302 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
303 pub fn camellia_128_cbc() -> Cipher {
304 unsafe { Cipher(ffi::EVP_camellia_128_cbc()) }
305 }
306
307 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
308 pub fn camellia_128_ecb() -> Cipher {
309 unsafe { Cipher(ffi::EVP_camellia_128_ecb()) }
310 }
311
312 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
313 pub fn camellia_128_ofb() -> Cipher {
314 unsafe { Cipher(ffi::EVP_camellia_128_ofb()) }
315 }
316
317 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
318 pub fn camellia_128_cfb128() -> Cipher {
319 unsafe { Cipher(ffi::EVP_camellia_128_cfb128()) }
320 }
321
322 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
323 pub fn camellia_192_cbc() -> Cipher {
324 unsafe { Cipher(ffi::EVP_camellia_192_cbc()) }
325 }
326
327 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
328 pub fn camellia_192_ecb() -> Cipher {
329 unsafe { Cipher(ffi::EVP_camellia_192_ecb()) }
330 }
331
332 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
333 pub fn camellia_192_ofb() -> Cipher {
334 unsafe { Cipher(ffi::EVP_camellia_192_ofb()) }
335 }
336
337 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
338 pub fn camellia_192_cfb128() -> Cipher {
339 unsafe { Cipher(ffi::EVP_camellia_192_cfb128()) }
340 }
341
342 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
343 pub fn camellia_256_cbc() -> Cipher {
344 unsafe { Cipher(ffi::EVP_camellia_256_cbc()) }
345 }
346
347 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
348 pub fn camellia_256_ecb() -> Cipher {
349 unsafe { Cipher(ffi::EVP_camellia_256_ecb()) }
350 }
351
352 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
353 pub fn camellia_256_ofb() -> Cipher {
354 unsafe { Cipher(ffi::EVP_camellia_256_ofb()) }
355 }
356
357 #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))]
358 pub fn camellia_256_cfb128() -> Cipher {
359 unsafe { Cipher(ffi::EVP_camellia_256_cfb128()) }
360 }
361
362 #[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
363 pub fn cast5_cbc() -> Cipher {
364 unsafe { Cipher(ffi::EVP_cast5_cbc()) }
365 }
366
367 #[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
368 pub fn cast5_ecb() -> Cipher {
369 unsafe { Cipher(ffi::EVP_cast5_ecb()) }
370 }
371
372 #[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
373 pub fn cast5_ofb() -> Cipher {
374 unsafe { Cipher(ffi::EVP_cast5_ofb()) }
375 }
376
377 #[cfg(not(osslconf = "OPENSSL_NO_CAST"))]
378 pub fn cast5_cfb64() -> Cipher {
379 unsafe { Cipher(ffi::EVP_cast5_cfb64()) }
380 }
381
382 #[cfg(all(any(ossl110, libressl), not(osslconf = "OPENSSL_NO_CHACHA")))]
384 pub fn chacha20() -> Cipher {
385 unsafe { Cipher(ffi::EVP_chacha20()) }
386 }
387
388 #[cfg(all(any(ossl110, libressl360, awslc), not(osslconf = "OPENSSL_NO_CHACHA")))]
390 pub fn chacha20_poly1305() -> Cipher {
391 unsafe { Cipher(ffi::EVP_chacha20_poly1305()) }
392 }
393
394 #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
395 pub fn idea_cbc() -> Cipher {
396 unsafe { Cipher(ffi::EVP_idea_cbc()) }
397 }
398
399 #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
400 pub fn idea_ecb() -> Cipher {
401 unsafe { Cipher(ffi::EVP_idea_ecb()) }
402 }
403
404 #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
405 pub fn idea_ofb() -> Cipher {
406 unsafe { Cipher(ffi::EVP_idea_ofb()) }
407 }
408
409 #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))]
410 pub fn idea_cfb64() -> Cipher {
411 unsafe { Cipher(ffi::EVP_idea_cfb64()) }
412 }
413
414 #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
415 pub fn seed_cbc() -> Cipher {
416 unsafe { Cipher(ffi::EVP_seed_cbc()) }
417 }
418
419 #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
420 pub fn seed_cfb128() -> Cipher {
421 unsafe { Cipher(ffi::EVP_seed_cfb128()) }
422 }
423
424 #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
425 pub fn seed_ecb() -> Cipher {
426 unsafe { Cipher(ffi::EVP_seed_ecb()) }
427 }
428
429 #[cfg(not(osslconf = "OPENSSL_NO_SEED"))]
430 pub fn seed_ofb() -> Cipher {
431 unsafe { Cipher(ffi::EVP_seed_ofb()) }
432 }
433
434 #[cfg(all(any(ossl111, libressl), not(osslconf = "OPENSSL_NO_SM4")))]
435 pub fn sm4_ecb() -> Cipher {
436 unsafe { Cipher(ffi::EVP_sm4_ecb()) }
437 }
438
439 #[cfg(all(any(ossl111, libressl), not(osslconf = "OPENSSL_NO_SM4")))]
440 pub fn sm4_cbc() -> Cipher {
441 unsafe { Cipher(ffi::EVP_sm4_cbc()) }
442 }
443
444 #[cfg(all(any(ossl111, libressl), not(osslconf = "OPENSSL_NO_SM4")))]
445 pub fn sm4_ctr() -> Cipher {
446 unsafe { Cipher(ffi::EVP_sm4_ctr()) }
447 }
448
449 #[cfg(all(any(ossl111, libressl), not(osslconf = "OPENSSL_NO_SM4")))]
450 pub fn sm4_cfb128() -> Cipher {
451 unsafe { Cipher(ffi::EVP_sm4_cfb128()) }
452 }
453
454 #[cfg(all(any(ossl111, libressl), not(osslconf = "OPENSSL_NO_SM4")))]
455 pub fn sm4_ofb() -> Cipher {
456 unsafe { Cipher(ffi::EVP_sm4_ofb()) }
457 }
458
459 #[cfg(not(osslconf = "OPENSSL_NO_RC2"))]
460 pub fn rc2_cbc() -> Cipher {
461 unsafe { Cipher(ffi::EVP_rc2_cbc()) }
462 }
463
464 #[cfg(not(osslconf = "OPENSSL_NO_RC2"))]
465 pub fn rc2_40_cbc() -> Cipher {
466 unsafe { Cipher(ffi::EVP_rc2_40_cbc()) }
467 }
468
469 pub unsafe fn from_ptr(ptr: *const ffi::EVP_CIPHER) -> Cipher {
475 Cipher(ptr)
476 }
477
478 #[allow(clippy::trivially_copy_pass_by_ref)]
479 pub fn as_ptr(&self) -> *const ffi::EVP_CIPHER {
480 self.0
481 }
482
483 #[allow(clippy::trivially_copy_pass_by_ref)]
485 pub fn key_len(&self) -> usize {
486 unsafe { EVP_CIPHER_key_length(self.0) as usize }
487 }
488
489 #[allow(clippy::trivially_copy_pass_by_ref)]
492 pub fn iv_len(&self) -> Option<usize> {
493 unsafe {
494 let len = EVP_CIPHER_iv_length(self.0) as usize;
495 if len == 0 {
496 None
497 } else {
498 Some(len)
499 }
500 }
501 }
502
503 #[allow(clippy::trivially_copy_pass_by_ref)]
509 pub fn block_size(&self) -> usize {
510 unsafe { EVP_CIPHER_block_size(self.0) as usize }
511 }
512
513 #[cfg(not(any(boringssl, awslc)))]
515 fn is_ccm(self) -> bool {
516 matches!(
517 self.nid(),
518 Nid::AES_128_CCM | Nid::AES_192_CCM | Nid::AES_256_CCM
519 )
520 }
521
522 #[cfg(any(boringssl, awslc))]
523 fn is_ccm(self) -> bool {
524 false
525 }
526
527 #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
529 fn is_ocb(self) -> bool {
530 matches!(
531 self.nid(),
532 Nid::AES_128_OCB | Nid::AES_192_OCB | Nid::AES_256_OCB
533 )
534 }
535
536 #[cfg(any(not(ossl110), osslconf = "OPENSSL_NO_OCB"))]
537 const fn is_ocb(self) -> bool {
538 false
539 }
540}
541
542unsafe impl Sync for Cipher {}
543unsafe impl Send for Cipher {}
544
545pub struct Crypter {
606 ctx: CipherCtx,
607}
608
609impl Crypter {
610 pub fn new(
618 t: Cipher,
619 mode: Mode,
620 key: &[u8],
621 iv: Option<&[u8]>,
622 ) -> Result<Crypter, ErrorStack> {
623 assert!(
624 iv.is_some() || t.iv_len().is_none(),
625 "an IV is required for this cipher"
626 );
627 let mut ctx = CipherCtx::new()?;
628
629 let f = match mode {
630 Mode::Encrypt => CipherCtxRef::encrypt_init,
631 Mode::Decrypt => CipherCtxRef::decrypt_init,
632 };
633
634 f(
635 &mut ctx,
636 Some(unsafe { CipherRef::from_ptr(t.as_ptr() as *mut _) }),
637 None,
638 None,
639 )?;
640
641 ctx.set_key_length(key.len())?;
642
643 if let (Some(iv), Some(iv_len)) = (iv, t.iv_len()) {
644 if iv.len() != iv_len {
645 ctx.set_iv_length(iv.len())?;
646 }
647 }
648
649 f(&mut ctx, None, Some(key), iv)?;
650
651 Ok(Crypter { ctx })
652 }
653
654 pub fn pad(&mut self, padding: bool) {
659 self.ctx.set_padding(padding)
660 }
661
662 pub fn set_tag(&mut self, tag: &[u8]) -> Result<(), ErrorStack> {
666 self.ctx.set_tag(tag)
667 }
668
669 pub fn set_tag_len(&mut self, tag_len: usize) -> Result<(), ErrorStack> {
674 self.ctx.set_tag_length(tag_len)
675 }
676
677 pub fn set_data_len(&mut self, data_len: usize) -> Result<(), ErrorStack> {
682 self.ctx.set_data_len(data_len)
683 }
684
685 pub fn aad_update(&mut self, input: &[u8]) -> Result<(), ErrorStack> {
691 self.ctx.cipher_update(input, None)?;
692 Ok(())
693 }
694
695 pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result<usize, ErrorStack> {
710 self.ctx.cipher_update(input, Some(output))
711 }
712
713 pub unsafe fn update_unchecked(
727 &mut self,
728 input: &[u8],
729 output: &mut [u8],
730 ) -> Result<usize, ErrorStack> {
731 self.ctx.cipher_update_unchecked(input, Some(output))
732 }
733
734 pub fn finalize(&mut self, output: &mut [u8]) -> Result<usize, ErrorStack> {
746 self.ctx.cipher_final(output)
747 }
748
749 pub fn get_tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> {
758 self.ctx.tag(tag)
759 }
760}
761
762pub fn encrypt(
793 t: Cipher,
794 key: &[u8],
795 iv: Option<&[u8]>,
796 data: &[u8],
797) -> Result<Vec<u8>, ErrorStack> {
798 cipher(t, Mode::Encrypt, key, iv, data)
799}
800
801pub fn decrypt(
832 t: Cipher,
833 key: &[u8],
834 iv: Option<&[u8]>,
835 data: &[u8],
836) -> Result<Vec<u8>, ErrorStack> {
837 cipher(t, Mode::Decrypt, key, iv, data)
838}
839
840fn cipher(
841 t: Cipher,
842 mode: Mode,
843 key: &[u8],
844 iv: Option<&[u8]>,
845 data: &[u8],
846) -> Result<Vec<u8>, ErrorStack> {
847 let mut c = Crypter::new(t, mode, key, iv)?;
848 let mut out = vec![0; data.len() + t.block_size()];
849 let count = c.update(data, &mut out)?;
850 let rest = c.finalize(&mut out[count..])?;
851 out.truncate(count + rest);
852 Ok(out)
853}
854
855pub fn encrypt_aead(
864 t: Cipher,
865 key: &[u8],
866 iv: Option<&[u8]>,
867 aad: &[u8],
868 data: &[u8],
869 tag: &mut [u8],
870) -> Result<Vec<u8>, ErrorStack> {
871 let mut c = Crypter::new(t, Mode::Encrypt, key, iv)?;
872 let mut out = vec![0; data.len() + t.block_size()];
873
874 let is_ccm = t.is_ccm();
875 if is_ccm || t.is_ocb() {
876 c.set_tag_len(tag.len())?;
877 if is_ccm {
878 c.set_data_len(data.len())?;
879 }
880 }
881
882 c.aad_update(aad)?;
883 let count = c.update(data, &mut out)?;
884 let rest = c.finalize(&mut out[count..])?;
885 c.get_tag(tag)?;
886 out.truncate(count + rest);
887 Ok(out)
888}
889
890pub fn decrypt_aead(
895 t: Cipher,
896 key: &[u8],
897 iv: Option<&[u8]>,
898 aad: &[u8],
899 data: &[u8],
900 tag: &[u8],
901) -> Result<Vec<u8>, ErrorStack> {
902 let mut c = Crypter::new(t, Mode::Decrypt, key, iv)?;
903 let mut out = vec![0; data.len() + t.block_size()];
904
905 let is_ccm = t.is_ccm();
906 if is_ccm || t.is_ocb() {
907 c.set_tag(tag)?;
908 if is_ccm {
909 c.set_data_len(data.len())?;
910 }
911 }
912
913 c.aad_update(aad)?;
914 let count = c.update(data, &mut out)?;
915
916 let rest = if t.is_ccm() {
917 0
918 } else {
919 c.set_tag(tag)?;
920 c.finalize(&mut out[count..])?
921 };
922
923 out.truncate(count + rest);
924 Ok(out)
925}
926
927use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length};
928
929#[cfg(test)]
930mod tests {
931 use super::*;
932 use hex::{self, FromHex};
933
934 #[test]
935 fn test_stream_cipher_output() {
936 let key = [0u8; 16];
937 let iv = [0u8; 16];
938 let mut c = super::Crypter::new(
939 super::Cipher::aes_128_ctr(),
940 super::Mode::Encrypt,
941 &key,
942 Some(&iv),
943 )
944 .unwrap();
945
946 assert_eq!(c.update(&[0u8; 15], &mut [0u8; 15]).unwrap(), 15);
947 assert_eq!(c.update(&[0u8; 1], &mut [0u8; 1]).unwrap(), 1);
948 assert_eq!(c.finalize(&mut [0u8; 0]).unwrap(), 0);
949 }
950
951 #[test]
954 fn test_aes_256_ecb() {
955 let k0 = [
956 0x00u8, 0x01u8, 0x02u8, 0x03u8, 0x04u8, 0x05u8, 0x06u8, 0x07u8, 0x08u8, 0x09u8, 0x0au8,
957 0x0bu8, 0x0cu8, 0x0du8, 0x0eu8, 0x0fu8, 0x10u8, 0x11u8, 0x12u8, 0x13u8, 0x14u8, 0x15u8,
958 0x16u8, 0x17u8, 0x18u8, 0x19u8, 0x1au8, 0x1bu8, 0x1cu8, 0x1du8, 0x1eu8, 0x1fu8,
959 ];
960 let p0 = [
961 0x00u8, 0x11u8, 0x22u8, 0x33u8, 0x44u8, 0x55u8, 0x66u8, 0x77u8, 0x88u8, 0x99u8, 0xaau8,
962 0xbbu8, 0xccu8, 0xddu8, 0xeeu8, 0xffu8,
963 ];
964 let c0 = [
965 0x8eu8, 0xa2u8, 0xb7u8, 0xcau8, 0x51u8, 0x67u8, 0x45u8, 0xbfu8, 0xeau8, 0xfcu8, 0x49u8,
966 0x90u8, 0x4bu8, 0x49u8, 0x60u8, 0x89u8,
967 ];
968 let mut c = super::Crypter::new(
969 super::Cipher::aes_256_ecb(),
970 super::Mode::Encrypt,
971 &k0,
972 None,
973 )
974 .unwrap();
975 c.pad(false);
976 let mut r0 = vec![0; c0.len() + super::Cipher::aes_256_ecb().block_size()];
977 let count = c.update(&p0, &mut r0).unwrap();
978 let rest = c.finalize(&mut r0[count..]).unwrap();
979 r0.truncate(count + rest);
980 assert_eq!(hex::encode(&r0), hex::encode(c0));
981
982 let mut c = super::Crypter::new(
983 super::Cipher::aes_256_ecb(),
984 super::Mode::Decrypt,
985 &k0,
986 None,
987 )
988 .unwrap();
989 c.pad(false);
990 let mut p1 = vec![0; r0.len() + super::Cipher::aes_256_ecb().block_size()];
991 let count = c.update(&r0, &mut p1).unwrap();
992 let rest = c.finalize(&mut p1[count..]).unwrap();
993 p1.truncate(count + rest);
994 assert_eq!(hex::encode(p1), hex::encode(p0));
995 }
996
997 #[test]
998 fn test_aes_256_cbc_decrypt() {
999 let iv = [
1000 4_u8, 223_u8, 153_u8, 219_u8, 28_u8, 142_u8, 234_u8, 68_u8, 227_u8, 69_u8, 98_u8,
1001 107_u8, 208_u8, 14_u8, 236_u8, 60_u8,
1002 ];
1003 let data = [
1004 143_u8, 210_u8, 75_u8, 63_u8, 214_u8, 179_u8, 155_u8, 241_u8, 242_u8, 31_u8, 154_u8,
1005 56_u8, 198_u8, 145_u8, 192_u8, 64_u8, 2_u8, 245_u8, 167_u8, 220_u8, 55_u8, 119_u8,
1006 233_u8, 136_u8, 139_u8, 27_u8, 71_u8, 242_u8, 119_u8, 175_u8, 65_u8, 207_u8,
1007 ];
1008 let ciphered_data = [
1009 0x4a_u8, 0x2e_u8, 0xe5_u8, 0x6_u8, 0xbf_u8, 0xcf_u8, 0xf2_u8, 0xd7_u8, 0xea_u8,
1010 0x2d_u8, 0xb1_u8, 0x85_u8, 0x6c_u8, 0x93_u8, 0x65_u8, 0x6f_u8,
1011 ];
1012 let mut cr = super::Crypter::new(
1013 super::Cipher::aes_256_cbc(),
1014 super::Mode::Decrypt,
1015 &data,
1016 Some(&iv),
1017 )
1018 .unwrap();
1019 cr.pad(false);
1020 let mut unciphered_data = vec![0; data.len() + super::Cipher::aes_256_cbc().block_size()];
1021 let count = cr.update(&ciphered_data, &mut unciphered_data).unwrap();
1022 let rest = cr.finalize(&mut unciphered_data[count..]).unwrap();
1023 unciphered_data.truncate(count + rest);
1024
1025 let expected_unciphered_data = b"I love turtles.\x01";
1026
1027 assert_eq!(&unciphered_data, expected_unciphered_data);
1028 }
1029
1030 fn cipher_test(ciphertype: super::Cipher, pt: &str, ct: &str, key: &str, iv: &str) {
1031 let pt = Vec::from_hex(pt).unwrap();
1032 let ct = Vec::from_hex(ct).unwrap();
1033 let key = Vec::from_hex(key).unwrap();
1034 let iv = Vec::from_hex(iv).unwrap();
1035
1036 let computed = super::decrypt(ciphertype, &key, Some(&iv), &ct).unwrap();
1037 let expected = pt;
1038
1039 if computed != expected {
1040 println!("Computed: {}", hex::encode(&computed));
1041 println!("Expected: {}", hex::encode(&expected));
1042 if computed.len() != expected.len() {
1043 println!(
1044 "Lengths differ: {} in computed vs {} expected",
1045 computed.len(),
1046 expected.len()
1047 );
1048 }
1049 panic!("test failure");
1050 }
1051 }
1052
1053 #[test]
1054 #[cfg(not(any(boringssl, awslc)))]
1055 fn test_aes256_xts() {
1056 let pt = "77f4ef63d734ebd028508da66c22cdebdd52ecd6ee2ab0a50bc8ad0cfd692ca5fcd4e6dedc45df7f\
1059 6503f462611dc542";
1060 let ct = "ce7d905a7776ac72f240d22aafed5e4eb7566cdc7211220e970da634ce015f131a5ecb8d400bc9e8\
1061 4f0b81d8725dbbc7";
1062 let key = "b6bfef891f83b5ff073f2231267be51eb084b791fa19a154399c0684c8b2dfcb37de77d28bbda3b\
1063 4180026ad640b74243b3133e7b9fae629403f6733423dae28";
1064 let iv = "db200efb7eaaa737dbdf40babb68953f";
1065
1066 cipher_test(super::Cipher::aes_256_xts(), pt, ct, key, iv);
1067 }
1068
1069 #[test]
1070 fn test_aes128_ctr() {
1071 let pt = "6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411\
1072 E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710";
1073 let ct = "874D6191B620E3261BEF6864990DB6CE9806F66B7970FDFF8617187BB9FFFDFF5AE4DF3EDBD5D35E\
1074 5B4F09020DB03EAB1E031DDA2FBE03D1792170A0F3009CEE";
1075 let key = "2B7E151628AED2A6ABF7158809CF4F3C";
1076 let iv = "F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF";
1077
1078 cipher_test(super::Cipher::aes_128_ctr(), pt, ct, key, iv);
1079 }
1080
1081 #[test]
1082 #[cfg(not(any(boringssl, awslc)))]
1083 fn test_aes128_cfb1() {
1084 let pt = "6bc1";
1087 let ct = "68b3";
1088 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1089 let iv = "000102030405060708090a0b0c0d0e0f";
1090
1091 cipher_test(super::Cipher::aes_128_cfb1(), pt, ct, key, iv);
1092 }
1093
1094 #[test]
1095 #[cfg(not(any(boringssl, awslc)))]
1096 fn test_aes128_cfb128() {
1097 let pt = "6bc1bee22e409f96e93d7e117393172a";
1098 let ct = "3b3fd92eb72dad20333449f8e83cfb4a";
1099 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1100 let iv = "000102030405060708090a0b0c0d0e0f";
1101
1102 cipher_test(super::Cipher::aes_128_cfb128(), pt, ct, key, iv);
1103 }
1104
1105 #[test]
1106 #[cfg(not(any(boringssl, awslc)))]
1107 fn test_aes128_cfb8() {
1108 let pt = "6bc1bee22e409f96e93d7e117393172aae2d";
1109 let ct = "3b79424c9c0dd436bace9e0ed4586a4f32b9";
1110 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1111 let iv = "000102030405060708090a0b0c0d0e0f";
1112
1113 cipher_test(super::Cipher::aes_128_cfb8(), pt, ct, key, iv);
1114 }
1115
1116 #[test]
1117 fn test_aes128_ofb() {
1118 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710";
1121 let ct = "3b3fd92eb72dad20333449f8e83cfb4a7789508d16918f03f53c52dac54ed8259740051e9c5fecf64344f7a82260edcc304c6528f659c77866a510d9c1d6ae5e";
1122 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1123 let iv = "000102030405060708090a0b0c0d0e0f";
1124
1125 cipher_test(super::Cipher::aes_128_ofb(), pt, ct, key, iv);
1126 }
1127
1128 #[test]
1129 fn test_aes192_ctr() {
1130 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710";
1133 let ct = "1abc932417521ca24f2b0459fe7e6e0b090339ec0aa6faefd5ccc2c6f4ce8e941e36b26bd1ebc670d1bd1d665620abf74f78a7f6d29809585a97daec58c6b050";
1134 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1135 let iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
1136
1137 cipher_test(super::Cipher::aes_192_ctr(), pt, ct, key, iv);
1138 }
1139
1140 #[test]
1141 #[cfg(not(any(boringssl, awslc)))]
1142 fn test_aes192_cfb1() {
1143 let pt = "6bc1";
1146 let ct = "9359";
1147 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1148 let iv = "000102030405060708090a0b0c0d0e0f";
1149
1150 cipher_test(super::Cipher::aes_192_cfb1(), pt, ct, key, iv);
1151 }
1152
1153 #[test]
1154 #[cfg(not(any(boringssl, awslc)))]
1155 fn test_aes192_cfb128() {
1156 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710";
1159 let ct = "cdc80d6fddf18cab34c25909c99a417467ce7f7f81173621961a2b70171d3d7a2e1e8a1dd59b88b1c8e60fed1efac4c9c05f9f9ca9834fa042ae8fba584b09ff";
1160 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1161 let iv = "000102030405060708090a0b0c0d0e0f";
1162
1163 cipher_test(super::Cipher::aes_192_cfb128(), pt, ct, key, iv);
1164 }
1165
1166 #[test]
1167 #[cfg(not(any(boringssl, awslc)))]
1168 fn test_aes192_cfb8() {
1169 let pt = "6bc1bee22e409f96e93d7e117393172aae2d";
1172 let ct = "cda2521ef0a905ca44cd057cbf0d47a0678a";
1173 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1174 let iv = "000102030405060708090a0b0c0d0e0f";
1175
1176 cipher_test(super::Cipher::aes_192_cfb8(), pt, ct, key, iv);
1177 }
1178
1179 #[test]
1180 fn test_aes192_ofb() {
1181 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710";
1184 let ct = "cdc80d6fddf18cab34c25909c99a4174fcc28b8d4c63837c09e81700c11004018d9a9aeac0f6596f559c6d4daf59a5f26d9f200857ca6c3e9cac524bd9acc92a";
1185 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1186 let iv = "000102030405060708090a0b0c0d0e0f";
1187
1188 cipher_test(super::Cipher::aes_192_ofb(), pt, ct, key, iv);
1189 }
1190
1191 #[test]
1192 #[cfg(not(any(boringssl, awslc)))]
1193 fn test_aes256_cfb1() {
1194 let pt = "6bc1";
1195 let ct = "9029";
1196 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1197 let iv = "000102030405060708090a0b0c0d0e0f";
1198
1199 cipher_test(super::Cipher::aes_256_cfb1(), pt, ct, key, iv);
1200 }
1201
1202 #[test]
1203 #[cfg(not(any(boringssl, awslc)))]
1204 fn test_aes256_cfb128() {
1205 let pt = "6bc1bee22e409f96e93d7e117393172a";
1206 let ct = "dc7e84bfda79164b7ecd8486985d3860";
1207 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1208 let iv = "000102030405060708090a0b0c0d0e0f";
1209
1210 cipher_test(super::Cipher::aes_256_cfb128(), pt, ct, key, iv);
1211 }
1212
1213 #[test]
1214 #[cfg(not(any(boringssl, awslc)))]
1215 fn test_aes256_cfb8() {
1216 let pt = "6bc1bee22e409f96e93d7e117393172aae2d";
1217 let ct = "dc1f1a8520a64db55fcc8ac554844e889700";
1218 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1219 let iv = "000102030405060708090a0b0c0d0e0f";
1220
1221 cipher_test(super::Cipher::aes_256_cfb8(), pt, ct, key, iv);
1222 }
1223
1224 #[test]
1225 fn test_aes256_ofb() {
1226 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710";
1229 let ct = "dc7e84bfda79164b7ecd8486985d38604febdc6740d20b3ac88f6ad82a4fb08d71ab47a086e86eedf39d1c5bba97c4080126141d67f37be8538f5a8be740e484";
1230 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1231 let iv = "000102030405060708090a0b0c0d0e0f";
1232
1233 cipher_test(super::Cipher::aes_256_ofb(), pt, ct, key, iv);
1234 }
1235
1236 #[test]
1237 fn test_des_ede3() {
1238 let pt = "9994f4c69d40ae4f34ff403b5cf39d4c8207ea5d3e19a5fd";
1239 let ct = "9e5c4297d60582f81071ac8ab7d0698d4c79de8b94c519858207ea5d3e19a5fd";
1240 let key = "010203040506070801020304050607080102030405060708";
1241 let iv = "5cc118306dc702e4";
1242
1243 cipher_test(super::Cipher::des_ede3(), pt, ct, key, iv);
1244 }
1245
1246 #[test]
1247 fn test_des_ede3_cbc() {
1248 let pt = "54686973206973206120746573742e";
1249 let ct = "6f2867cfefda048a4046ef7e556c7132";
1250 let key = "7cb66337f3d3c0fe7cb66337f3d3c0fe7cb66337f3d3c0fe";
1251 let iv = "0001020304050607";
1252
1253 cipher_test(super::Cipher::des_ede3_cbc(), pt, ct, key, iv);
1254 }
1255
1256 #[test]
1257 #[cfg(not(any(boringssl, awslc)))]
1258 fn test_des_ede3_cfb64() {
1259 let pt = "2b1773784b5889dc788477367daa98ad";
1260 let ct = "6f2867cfefda048a4046ef7e556c7132";
1261 let key = "7cb66337f3d3c0fe7cb66337f3d3c0fe7cb66337f3d3c0fe";
1262 let iv = "0001020304050607";
1263
1264 cipher_test(super::Cipher::des_ede3_cfb64(), pt, ct, key, iv);
1265 }
1266
1267 #[test]
1268 fn test_aes128_gcm() {
1269 let key = "23dc8d23d95b6fd1251741a64f7d4f41";
1270 let iv = "f416f48ad44d9efa1179e167";
1271 let pt = "6cb9b71dd0ccd42cdf87e8e396fc581fd8e0d700e360f590593b748e105390de";
1272 let aad = "45074844c97d515c65bbe37c210a5a4b08c21c588efe5c5f73c4d9c17d34dacddc0bb6a8a53f7bf477b9780c1c2a928660df87016b2873fe876b2b887fb5886bfd63216b7eaecc046372a82c047eb043f0b063226ee52a12c69b";
1273 let ct = "8ad20486778e87387efb3f2574e509951c0626816722018129e578b2787969d3";
1274 let tag = "91e1bc09";
1275
1276 let mut actual_tag = [0; 4];
1279 let out = encrypt_aead(
1280 Cipher::aes_128_gcm(),
1281 &Vec::from_hex(key).unwrap(),
1282 Some(&Vec::from_hex(iv).unwrap()),
1283 &Vec::from_hex(aad).unwrap(),
1284 &Vec::from_hex(pt).unwrap(),
1285 &mut actual_tag,
1286 )
1287 .unwrap();
1288 assert_eq!(ct, hex::encode(out));
1289 assert_eq!(tag, hex::encode(actual_tag));
1290
1291 let out = decrypt_aead(
1292 Cipher::aes_128_gcm(),
1293 &Vec::from_hex(key).unwrap(),
1294 Some(&Vec::from_hex(iv).unwrap()),
1295 &Vec::from_hex(aad).unwrap(),
1296 &Vec::from_hex(ct).unwrap(),
1297 &Vec::from_hex(tag).unwrap(),
1298 )
1299 .unwrap();
1300 assert_eq!(pt, hex::encode(out));
1301 }
1302
1303 #[test]
1304 #[cfg(not(any(boringssl, awslc)))]
1305 fn test_aes128_ccm() {
1306 let key = "3ee186594f110fb788a8bf8aa8be5d4a";
1307 let nonce = "44f705d52acf27b7f17196aa9b";
1308 let aad = "2c16724296ff85e079627be3053ea95adf35722c21886baba343bd6c79b5cb57";
1309
1310 let pt = "d71864877f2578db092daba2d6a1f9f4698a9c356c7830a1";
1311 let ct = "b4dd74e7a0cc51aea45dfb401a41d5822c96901a83247ea0";
1312 let tag = "d6965f5aa6e31302a9cc2b36";
1313
1314 let mut actual_tag = [0; 12];
1315 let out = encrypt_aead(
1316 Cipher::aes_128_ccm(),
1317 &Vec::from_hex(key).unwrap(),
1318 Some(&Vec::from_hex(nonce).unwrap()),
1319 &Vec::from_hex(aad).unwrap(),
1320 &Vec::from_hex(pt).unwrap(),
1321 &mut actual_tag,
1322 )
1323 .unwrap();
1324
1325 assert_eq!(ct, hex::encode(out));
1326 assert_eq!(tag, hex::encode(actual_tag));
1327
1328 let out = decrypt_aead(
1329 Cipher::aes_128_ccm(),
1330 &Vec::from_hex(key).unwrap(),
1331 Some(&Vec::from_hex(nonce).unwrap()),
1332 &Vec::from_hex(aad).unwrap(),
1333 &Vec::from_hex(ct).unwrap(),
1334 &Vec::from_hex(tag).unwrap(),
1335 )
1336 .unwrap();
1337 assert_eq!(pt, hex::encode(out));
1338 }
1339
1340 #[test]
1341 #[cfg(not(any(boringssl, awslc)))]
1342 fn test_aes128_ccm_verify_fail() {
1343 let key = "3ee186594f110fb788a8bf8aa8be5d4a";
1344 let nonce = "44f705d52acf27b7f17196aa9b";
1345 let aad = "2c16724296ff85e079627be3053ea95adf35722c21886baba343bd6c79b5cb57";
1346
1347 let ct = "b4dd74e7a0cc51aea45dfb401a41d5822c96901a83247ea0";
1348 let tag = "00005f5aa6e31302a9cc2b36";
1349
1350 let out = decrypt_aead(
1351 Cipher::aes_128_ccm(),
1352 &Vec::from_hex(key).unwrap(),
1353 Some(&Vec::from_hex(nonce).unwrap()),
1354 &Vec::from_hex(aad).unwrap(),
1355 &Vec::from_hex(ct).unwrap(),
1356 &Vec::from_hex(tag).unwrap(),
1357 );
1358 assert!(out.is_err());
1359 }
1360
1361 #[test]
1362 #[cfg(not(any(boringssl, awslc)))]
1363 fn test_aes256_ccm() {
1364 let key = "7f4af6765cad1d511db07e33aaafd57646ec279db629048aa6770af24849aa0d";
1365 let nonce = "dde2a362ce81b2b6913abc3095";
1366 let aad = "404f5df97ece7431987bc098cce994fc3c063b519ffa47b0365226a0015ef695";
1367
1368 let pt = "7ebef26bf4ecf6f0ebb2eb860edbf900f27b75b4a6340fdb";
1369 let ct = "353022db9c568bd7183a13c40b1ba30fcc768c54264aa2cd";
1370 let tag = "2927a053c9244d3217a7ad05";
1371
1372 let mut actual_tag = [0; 12];
1373 let out = encrypt_aead(
1374 Cipher::aes_256_ccm(),
1375 &Vec::from_hex(key).unwrap(),
1376 Some(&Vec::from_hex(nonce).unwrap()),
1377 &Vec::from_hex(aad).unwrap(),
1378 &Vec::from_hex(pt).unwrap(),
1379 &mut actual_tag,
1380 )
1381 .unwrap();
1382
1383 assert_eq!(ct, hex::encode(out));
1384 assert_eq!(tag, hex::encode(actual_tag));
1385
1386 let out = decrypt_aead(
1387 Cipher::aes_256_ccm(),
1388 &Vec::from_hex(key).unwrap(),
1389 Some(&Vec::from_hex(nonce).unwrap()),
1390 &Vec::from_hex(aad).unwrap(),
1391 &Vec::from_hex(ct).unwrap(),
1392 &Vec::from_hex(tag).unwrap(),
1393 )
1394 .unwrap();
1395 assert_eq!(pt, hex::encode(out));
1396 }
1397
1398 #[test]
1399 #[cfg(not(any(boringssl, awslc)))]
1400 fn test_aes256_ccm_verify_fail() {
1401 let key = "7f4af6765cad1d511db07e33aaafd57646ec279db629048aa6770af24849aa0d";
1402 let nonce = "dde2a362ce81b2b6913abc3095";
1403 let aad = "404f5df97ece7431987bc098cce994fc3c063b519ffa47b0365226a0015ef695";
1404
1405 let ct = "353022db9c568bd7183a13c40b1ba30fcc768c54264aa2cd";
1406 let tag = "0000a053c9244d3217a7ad05";
1407
1408 let out = decrypt_aead(
1409 Cipher::aes_256_ccm(),
1410 &Vec::from_hex(key).unwrap(),
1411 Some(&Vec::from_hex(nonce).unwrap()),
1412 &Vec::from_hex(aad).unwrap(),
1413 &Vec::from_hex(ct).unwrap(),
1414 &Vec::from_hex(tag).unwrap(),
1415 );
1416 assert!(out.is_err());
1417 }
1418
1419 #[test]
1420 #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
1421 fn test_aes_128_ocb() {
1422 let key = "000102030405060708090a0b0c0d0e0f";
1423 let aad = "0001020304050607";
1424 let tag = "16dc76a46d47e1ead537209e8a96d14e";
1425 let iv = "000102030405060708090a0b";
1426 let pt = "0001020304050607";
1427 let ct = "92b657130a74b85a";
1428
1429 let mut actual_tag = [0; 16];
1430 let out = encrypt_aead(
1431 Cipher::aes_128_ocb(),
1432 &Vec::from_hex(key).unwrap(),
1433 Some(&Vec::from_hex(iv).unwrap()),
1434 &Vec::from_hex(aad).unwrap(),
1435 &Vec::from_hex(pt).unwrap(),
1436 &mut actual_tag,
1437 )
1438 .unwrap();
1439
1440 assert_eq!(ct, hex::encode(out));
1441 assert_eq!(tag, hex::encode(actual_tag));
1442
1443 let out = decrypt_aead(
1444 Cipher::aes_128_ocb(),
1445 &Vec::from_hex(key).unwrap(),
1446 Some(&Vec::from_hex(iv).unwrap()),
1447 &Vec::from_hex(aad).unwrap(),
1448 &Vec::from_hex(ct).unwrap(),
1449 &Vec::from_hex(tag).unwrap(),
1450 )
1451 .unwrap();
1452 assert_eq!(pt, hex::encode(out));
1453 }
1454
1455 #[test]
1456 #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))]
1457 fn test_aes_128_ocb_fail() {
1458 let key = "000102030405060708090a0b0c0d0e0f";
1459 let aad = "0001020304050607";
1460 let tag = "16dc76a46d47e1ead537209e8a96d14e";
1461 let iv = "000000000405060708090a0b";
1462 let ct = "92b657130a74b85a";
1463
1464 let out = decrypt_aead(
1465 Cipher::aes_128_ocb(),
1466 &Vec::from_hex(key).unwrap(),
1467 Some(&Vec::from_hex(iv).unwrap()),
1468 &Vec::from_hex(aad).unwrap(),
1469 &Vec::from_hex(ct).unwrap(),
1470 &Vec::from_hex(tag).unwrap(),
1471 );
1472 assert!(out.is_err());
1473 }
1474
1475 #[test]
1476 #[cfg(any(ossl110, libressl))]
1477 fn test_chacha20() {
1478 let key = "0000000000000000000000000000000000000000000000000000000000000000";
1479 let iv = "00000000000000000000000000000000";
1480 let pt =
1481 "000000000000000000000000000000000000000000000000000000000000000000000000000000000\
1482 00000000000000000000000000000000000000000000000";
1483 let ct =
1484 "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7\
1485 724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586";
1486
1487 cipher_test(Cipher::chacha20(), pt, ct, key, iv);
1488 }
1489
1490 #[test]
1491 #[cfg(any(ossl110, libressl360, awslc))]
1492 fn test_chacha20_poly1305() {
1493 let key = "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f";
1494 let iv = "070000004041424344454647";
1495 let aad = "50515253c0c1c2c3c4c5c6c7";
1496 let pt =
1497 "4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393\
1498 a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f722074\
1499 6865206675747572652c2073756e73637265656e20776f756c642062652069742e";
1500 let ct =
1501 "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca967128\
1502 2fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fa\
1503 b324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116";
1504 let tag = "1ae10b594f09e26a7e902ecbd0600691";
1505
1506 let mut actual_tag = [0; 16];
1507 let out = encrypt_aead(
1508 Cipher::chacha20_poly1305(),
1509 &Vec::from_hex(key).unwrap(),
1510 Some(&Vec::from_hex(iv).unwrap()),
1511 &Vec::from_hex(aad).unwrap(),
1512 &Vec::from_hex(pt).unwrap(),
1513 &mut actual_tag,
1514 )
1515 .unwrap();
1516 assert_eq!(ct, hex::encode(out));
1517 assert_eq!(tag, hex::encode(actual_tag));
1518
1519 let out = decrypt_aead(
1520 Cipher::chacha20_poly1305(),
1521 &Vec::from_hex(key).unwrap(),
1522 Some(&Vec::from_hex(iv).unwrap()),
1523 &Vec::from_hex(aad).unwrap(),
1524 &Vec::from_hex(ct).unwrap(),
1525 &Vec::from_hex(tag).unwrap(),
1526 )
1527 .unwrap();
1528 assert_eq!(pt, hex::encode(out));
1529 }
1530
1531 #[test]
1534 #[cfg(all(any(ossl111, libressl), not(osslconf = "OPENSSL_NO_SM4")))]
1535 fn test_sm4_ecb() {
1536 use std::mem;
1537
1538 let key = vec![
1539 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54,
1540 0x32, 0x10,
1541 ];
1542 let pt = vec![
1543 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54,
1544 0x32, 0x10,
1545 ];
1546 let ct = vec![
1547 0x68, 0x1e, 0xdf, 0x34, 0xd2, 0x06, 0x96, 0x5e, 0x86, 0xb3, 0xe9, 0x4f, 0x53, 0x6e,
1548 0x42, 0x46,
1549 ];
1550 let ct1 = vec![
1551 0x59, 0x52, 0x98, 0xc7, 0xc6, 0xfd, 0x27, 0x1f, 0x04, 0x02, 0xf8, 0x04, 0xc3, 0x3d,
1552 0x3f, 0x66,
1553 ];
1554
1555 let block_size = Cipher::sm4_ecb().block_size();
1556 let mut c = Crypter::new(Cipher::sm4_ecb(), Mode::Encrypt, &key, None).unwrap();
1557 c.pad(false);
1558
1559 let mut r = vec![0; pt.len() + Cipher::sm4_ecb().block_size()];
1561 let count = c.update(&pt, &mut r).unwrap();
1562 assert_eq!(ct, &r[..count]);
1563
1564 let mut r1 = vec![0; pt.len() + Cipher::sm4_ecb().block_size()];
1566 for _ in 0..999999 {
1567 c.update(&r[..block_size], &mut r1).unwrap();
1568 mem::swap(&mut r, &mut r1);
1569 }
1570 assert_eq!(ct1, &r[..count]);
1571 }
1572
1573 #[test]
1574 #[should_panic(expected = "an IV is required for this cipher")]
1575 fn test_crypter_panics_for_missing_iv_cbc() {
1576 let key = [0u8; 16];
1577 let _ = Crypter::new(
1578 super::Cipher::aes_128_cbc(),
1579 super::Mode::Encrypt,
1580 &key,
1581 None,
1582 );
1583 }
1584
1585 #[test]
1586 #[should_panic(expected = "an IV is required for this cipher")]
1587 fn test_crypter_panics_for_missing_iv_gcm() {
1588 let key = [0u8; 16];
1589 let _ = Crypter::new(
1590 super::Cipher::aes_128_gcm(),
1591 super::Mode::Encrypt,
1592 &key,
1593 None,
1594 );
1595 }
1596}