1use crate::ffi;
56use libc::{c_int, c_uint};
57use std::cmp;
58use std::ptr;
59
60use crate::error::ErrorStack;
61use crate::nid::Nid;
62use crate::{cvt, cvt_p};
63
64#[derive(Copy, Clone)]
65pub enum Mode {
66 Encrypt,
67 Decrypt,
68}
69
70#[derive(Copy, Clone, PartialEq, Eq)]
76pub struct Cipher(*const ffi::EVP_CIPHER);
77
78impl Cipher {
79 pub fn from_nid(nid: Nid) -> Option<Cipher> {
85 let ptr = unsafe { ffi::EVP_get_cipherbyname(ffi::OBJ_nid2sn(nid.as_raw())) };
86 if ptr.is_null() {
87 None
88 } else {
89 Some(Cipher(ptr))
90 }
91 }
92
93 pub fn aes_128_ecb() -> Cipher {
94 unsafe { Cipher(ffi::EVP_aes_128_ecb()) }
95 }
96
97 pub fn aes_128_cbc() -> Cipher {
98 unsafe { Cipher(ffi::EVP_aes_128_cbc()) }
99 }
100
101 pub fn aes_128_ctr() -> Cipher {
102 unsafe { Cipher(ffi::EVP_aes_128_ctr()) }
103 }
104
105 pub fn aes_128_gcm() -> Cipher {
106 unsafe { Cipher(ffi::EVP_aes_128_gcm()) }
107 }
108
109 pub fn aes_128_ofb() -> Cipher {
110 unsafe { Cipher(ffi::EVP_aes_128_ofb()) }
111 }
112
113 pub fn aes_192_ecb() -> Cipher {
114 unsafe { Cipher(ffi::EVP_aes_192_ecb()) }
115 }
116
117 pub fn aes_192_cbc() -> Cipher {
118 unsafe { Cipher(ffi::EVP_aes_192_cbc()) }
119 }
120
121 pub fn aes_192_ctr() -> Cipher {
122 unsafe { Cipher(ffi::EVP_aes_192_ctr()) }
123 }
124
125 pub fn aes_192_gcm() -> Cipher {
126 unsafe { Cipher(ffi::EVP_aes_192_gcm()) }
127 }
128
129 pub fn aes_192_ofb() -> Cipher {
130 unsafe { Cipher(ffi::EVP_aes_192_ofb()) }
131 }
132
133 pub fn aes_256_ecb() -> Cipher {
134 unsafe { Cipher(ffi::EVP_aes_256_ecb()) }
135 }
136
137 pub fn aes_256_cbc() -> Cipher {
138 unsafe { Cipher(ffi::EVP_aes_256_cbc()) }
139 }
140
141 pub fn aes_256_ctr() -> Cipher {
142 unsafe { Cipher(ffi::EVP_aes_256_ctr()) }
143 }
144
145 pub fn aes_256_gcm() -> Cipher {
146 unsafe { Cipher(ffi::EVP_aes_256_gcm()) }
147 }
148
149 pub fn aes_256_ofb() -> Cipher {
150 unsafe { Cipher(ffi::EVP_aes_256_ofb()) }
151 }
152
153 pub fn des_cbc() -> Cipher {
154 unsafe { Cipher(ffi::EVP_des_cbc()) }
155 }
156
157 pub fn des_ecb() -> Cipher {
158 unsafe { Cipher(ffi::EVP_des_ecb()) }
159 }
160
161 pub fn des_ede3() -> Cipher {
162 unsafe { Cipher(ffi::EVP_des_ede3()) }
163 }
164
165 pub fn des_ede3_cbc() -> Cipher {
166 unsafe { Cipher(ffi::EVP_des_ede3_cbc()) }
167 }
168
169 pub fn rc4() -> Cipher {
170 unsafe { Cipher(ffi::EVP_rc4()) }
171 }
172
173 pub unsafe fn from_ptr(ptr: *const ffi::EVP_CIPHER) -> Cipher {
179 Cipher(ptr)
180 }
181
182 #[allow(clippy::trivially_copy_pass_by_ref)]
183 pub fn as_ptr(&self) -> *const ffi::EVP_CIPHER {
184 self.0
185 }
186
187 #[allow(clippy::trivially_copy_pass_by_ref)]
189 pub fn key_len(&self) -> usize {
190 unsafe { EVP_CIPHER_key_length(self.0) as usize }
191 }
192
193 #[allow(clippy::trivially_copy_pass_by_ref)]
196 pub fn iv_len(&self) -> Option<usize> {
197 unsafe {
198 let len = EVP_CIPHER_iv_length(self.0) as usize;
199 if len == 0 {
200 None
201 } else {
202 Some(len)
203 }
204 }
205 }
206
207 #[allow(clippy::trivially_copy_pass_by_ref)]
213 pub fn block_size(&self) -> usize {
214 unsafe { EVP_CIPHER_block_size(self.0) as usize }
215 }
216}
217
218unsafe impl Sync for Cipher {}
219unsafe impl Send for Cipher {}
220
221pub struct Crypter {
282 ctx: *mut ffi::EVP_CIPHER_CTX,
283 block_size: usize,
284}
285
286unsafe impl Sync for Crypter {}
287unsafe impl Send for Crypter {}
288
289impl Crypter {
290 pub fn new(
298 t: Cipher,
299 mode: Mode,
300 key: &[u8],
301 iv: Option<&[u8]>,
302 ) -> Result<Crypter, ErrorStack> {
303 ffi::init();
304
305 unsafe {
306 let ctx = cvt_p(ffi::EVP_CIPHER_CTX_new())?;
307 let crypter = Crypter {
308 ctx,
309 block_size: t.block_size(),
310 };
311
312 let mode = match mode {
313 Mode::Encrypt => 1,
314 Mode::Decrypt => 0,
315 };
316
317 cvt(ffi::EVP_CipherInit_ex(
318 crypter.ctx,
319 t.as_ptr(),
320 ptr::null_mut(),
321 ptr::null_mut(),
322 ptr::null_mut(),
323 mode,
324 ))?;
325
326 assert!(key.len() <= c_int::MAX as usize);
327 cvt(ffi::EVP_CIPHER_CTX_set_key_length(
328 crypter.ctx,
329 key.len() as c_uint,
330 ))?;
331
332 let key = key.as_ptr() as *mut _;
333 let iv = match (iv, t.iv_len()) {
334 (Some(iv), Some(len)) => {
335 if iv.len() != len {
336 assert!(iv.len() <= c_int::MAX as usize);
337 cvt(ffi::EVP_CIPHER_CTX_ctrl(
338 crypter.ctx,
339 ffi::EVP_CTRL_GCM_SET_IVLEN,
340 iv.len() as c_int,
341 ptr::null_mut(),
342 ))?;
343 }
344 iv.as_ptr() as *mut _
345 }
346 (Some(_), None) | (None, None) => ptr::null_mut(),
347 (None, Some(_)) => panic!("an IV is required for this cipher"),
348 };
349 cvt(ffi::EVP_CipherInit_ex(
350 crypter.ctx,
351 ptr::null(),
352 ptr::null_mut(),
353 key,
354 iv,
355 mode,
356 ))?;
357
358 Ok(crypter)
359 }
360 }
361
362 pub fn pad(&mut self, padding: bool) {
367 unsafe {
368 ffi::EVP_CIPHER_CTX_set_padding(self.ctx, padding as c_int);
369 }
370 }
371
372 pub fn set_tag(&mut self, tag: &[u8]) -> Result<(), ErrorStack> {
376 unsafe {
377 assert!(tag.len() <= c_int::MAX as usize);
378 cvt(ffi::EVP_CIPHER_CTX_ctrl(
380 self.ctx,
381 ffi::EVP_CTRL_GCM_SET_TAG,
382 tag.len() as c_int,
383 tag.as_ptr() as *mut _,
384 ))
385 .map(|_| ())
386 }
387 }
388
389 pub fn set_tag_len(&mut self, tag_len: usize) -> Result<(), ErrorStack> {
394 unsafe {
395 assert!(tag_len <= c_int::MAX as usize);
396 cvt(ffi::EVP_CIPHER_CTX_ctrl(
398 self.ctx,
399 ffi::EVP_CTRL_GCM_SET_TAG,
400 tag_len as c_int,
401 ptr::null_mut(),
402 ))
403 .map(|_| ())
404 }
405 }
406
407 pub fn set_data_len(&mut self, data_len: usize) -> Result<(), ErrorStack> {
412 unsafe {
413 assert!(data_len <= c_int::MAX as usize);
414 let mut len = 0;
415 cvt(ffi::EVP_CipherUpdate(
416 self.ctx,
417 ptr::null_mut(),
418 &mut len,
419 ptr::null_mut(),
420 data_len as c_int,
421 ))
422 .map(|_| ())
423 }
424 }
425
426 pub fn aad_update(&mut self, input: &[u8]) -> Result<(), ErrorStack> {
432 unsafe {
433 assert!(input.len() <= c_int::MAX as usize);
434 let mut len = 0;
435 cvt(ffi::EVP_CipherUpdate(
436 self.ctx,
437 ptr::null_mut(),
438 &mut len,
439 input.as_ptr(),
440 input.len() as c_int,
441 ))
442 .map(|_| ())
443 }
444 }
445
446 pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result<usize, ErrorStack> {
461 unsafe {
462 let block_size = if self.block_size > 1 {
463 self.block_size
464 } else {
465 0
466 };
467 assert!(output.len() >= input.len() + block_size);
468 assert!(output.len() <= c_int::MAX as usize);
469 let mut outl = output.len() as c_int;
470 let inl = input.len() as c_int;
471
472 cvt(ffi::EVP_CipherUpdate(
473 self.ctx,
474 output.as_mut_ptr(),
475 &mut outl,
476 input.as_ptr(),
477 inl,
478 ))?;
479
480 Ok(outl as usize)
481 }
482 }
483
484 pub fn finalize(&mut self, output: &mut [u8]) -> Result<usize, ErrorStack> {
496 unsafe {
497 if self.block_size > 1 {
498 assert!(output.len() >= self.block_size);
499 }
500 let mut outl = cmp::min(output.len(), c_int::MAX as usize) as c_int;
501
502 cvt(ffi::EVP_CipherFinal_ex(
503 self.ctx,
504 output.as_mut_ptr(),
505 &mut outl,
506 ))?;
507
508 Ok(outl as usize)
509 }
510 }
511
512 pub fn get_tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> {
521 unsafe {
522 assert!(tag.len() <= c_int::MAX as usize);
523 cvt(ffi::EVP_CIPHER_CTX_ctrl(
524 self.ctx,
525 ffi::EVP_CTRL_GCM_GET_TAG,
526 tag.len() as c_int,
527 tag.as_mut_ptr() as *mut _,
528 ))
529 .map(|_| ())
530 }
531 }
532}
533
534impl Drop for Crypter {
535 fn drop(&mut self) {
536 unsafe {
537 ffi::EVP_CIPHER_CTX_free(self.ctx);
538 }
539 }
540}
541
542pub fn encrypt(
573 t: Cipher,
574 key: &[u8],
575 iv: Option<&[u8]>,
576 data: &[u8],
577) -> Result<Vec<u8>, ErrorStack> {
578 cipher(t, Mode::Encrypt, key, iv, data)
579}
580
581pub fn decrypt(
612 t: Cipher,
613 key: &[u8],
614 iv: Option<&[u8]>,
615 data: &[u8],
616) -> Result<Vec<u8>, ErrorStack> {
617 cipher(t, Mode::Decrypt, key, iv, data)
618}
619
620fn cipher(
621 t: Cipher,
622 mode: Mode,
623 key: &[u8],
624 iv: Option<&[u8]>,
625 data: &[u8],
626) -> Result<Vec<u8>, ErrorStack> {
627 let mut c = Crypter::new(t, mode, key, iv)?;
628 let mut out = vec![0; data.len() + t.block_size()];
629 let count = c.update(data, &mut out)?;
630 let rest = c.finalize(&mut out[count..])?;
631 out.truncate(count + rest);
632 Ok(out)
633}
634
635pub fn encrypt_aead(
644 t: Cipher,
645 key: &[u8],
646 iv: Option<&[u8]>,
647 aad: &[u8],
648 data: &[u8],
649 tag: &mut [u8],
650) -> Result<Vec<u8>, ErrorStack> {
651 let mut c = Crypter::new(t, Mode::Encrypt, key, iv)?;
652 let mut out = vec![0; data.len() + t.block_size()];
653
654 c.aad_update(aad)?;
655 let count = c.update(data, &mut out)?;
656 let rest = c.finalize(&mut out[count..])?;
657 c.get_tag(tag)?;
658 out.truncate(count + rest);
659 Ok(out)
660}
661
662pub fn decrypt_aead(
667 t: Cipher,
668 key: &[u8],
669 iv: Option<&[u8]>,
670 aad: &[u8],
671 data: &[u8],
672 tag: &[u8],
673) -> Result<Vec<u8>, ErrorStack> {
674 let mut c = Crypter::new(t, Mode::Decrypt, key, iv)?;
675 let mut out = vec![0; data.len() + t.block_size()];
676
677 c.aad_update(aad)?;
678 let count = c.update(data, &mut out)?;
679
680 c.set_tag(tag)?;
681 let rest = c.finalize(&mut out[count..])?;
682
683 out.truncate(count + rest);
684 Ok(out)
685}
686
687use crate::ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length};
688
689#[cfg(test)]
690mod tests {
691 use super::*;
692 use hex::{self, FromHex};
693
694 #[test]
695 fn test_stream_cipher_output() {
696 let key = [0u8; 16];
697 let iv = [0u8; 16];
698 let mut c = super::Crypter::new(
699 super::Cipher::aes_128_ctr(),
700 super::Mode::Encrypt,
701 &key,
702 Some(&iv),
703 )
704 .unwrap();
705
706 assert_eq!(c.update(&[0u8; 15], &mut [0u8; 15]).unwrap(), 15);
707 assert_eq!(c.update(&[0u8; 1], &mut [0u8; 1]).unwrap(), 1);
708 assert_eq!(c.finalize(&mut [0u8; 0]).unwrap(), 0);
709 }
710
711 #[test]
714 fn test_aes_256_ecb() {
715 let k0 = [
716 0x00u8, 0x01u8, 0x02u8, 0x03u8, 0x04u8, 0x05u8, 0x06u8, 0x07u8, 0x08u8, 0x09u8, 0x0au8,
717 0x0bu8, 0x0cu8, 0x0du8, 0x0eu8, 0x0fu8, 0x10u8, 0x11u8, 0x12u8, 0x13u8, 0x14u8, 0x15u8,
718 0x16u8, 0x17u8, 0x18u8, 0x19u8, 0x1au8, 0x1bu8, 0x1cu8, 0x1du8, 0x1eu8, 0x1fu8,
719 ];
720 let p0 = [
721 0x00u8, 0x11u8, 0x22u8, 0x33u8, 0x44u8, 0x55u8, 0x66u8, 0x77u8, 0x88u8, 0x99u8, 0xaau8,
722 0xbbu8, 0xccu8, 0xddu8, 0xeeu8, 0xffu8,
723 ];
724 let c0 = [
725 0x8eu8, 0xa2u8, 0xb7u8, 0xcau8, 0x51u8, 0x67u8, 0x45u8, 0xbfu8, 0xeau8, 0xfcu8, 0x49u8,
726 0x90u8, 0x4bu8, 0x49u8, 0x60u8, 0x89u8,
727 ];
728 let mut c = super::Crypter::new(
729 super::Cipher::aes_256_ecb(),
730 super::Mode::Encrypt,
731 &k0,
732 None,
733 )
734 .unwrap();
735 c.pad(false);
736 let mut r0 = vec![0; c0.len() + super::Cipher::aes_256_ecb().block_size()];
737 let count = c.update(&p0, &mut r0).unwrap();
738 let rest = c.finalize(&mut r0[count..]).unwrap();
739 r0.truncate(count + rest);
740 assert_eq!(hex::encode(&r0), hex::encode(c0));
741
742 let mut c = super::Crypter::new(
743 super::Cipher::aes_256_ecb(),
744 super::Mode::Decrypt,
745 &k0,
746 None,
747 )
748 .unwrap();
749 c.pad(false);
750 let mut p1 = vec![0; r0.len() + super::Cipher::aes_256_ecb().block_size()];
751 let count = c.update(&r0, &mut p1).unwrap();
752 let rest = c.finalize(&mut p1[count..]).unwrap();
753 p1.truncate(count + rest);
754 assert_eq!(hex::encode(p1), hex::encode(p0));
755 }
756
757 #[test]
758 fn test_aes_256_cbc_decrypt() {
759 let iv = [
760 4_u8, 223_u8, 153_u8, 219_u8, 28_u8, 142_u8, 234_u8, 68_u8, 227_u8, 69_u8, 98_u8,
761 107_u8, 208_u8, 14_u8, 236_u8, 60_u8,
762 ];
763 let data = [
764 143_u8, 210_u8, 75_u8, 63_u8, 214_u8, 179_u8, 155_u8, 241_u8, 242_u8, 31_u8, 154_u8,
765 56_u8, 198_u8, 145_u8, 192_u8, 64_u8, 2_u8, 245_u8, 167_u8, 220_u8, 55_u8, 119_u8,
766 233_u8, 136_u8, 139_u8, 27_u8, 71_u8, 242_u8, 119_u8, 175_u8, 65_u8, 207_u8,
767 ];
768 let ciphered_data = [
769 0x4a_u8, 0x2e_u8, 0xe5_u8, 0x6_u8, 0xbf_u8, 0xcf_u8, 0xf2_u8, 0xd7_u8, 0xea_u8,
770 0x2d_u8, 0xb1_u8, 0x85_u8, 0x6c_u8, 0x93_u8, 0x65_u8, 0x6f_u8,
771 ];
772 let mut cr = super::Crypter::new(
773 super::Cipher::aes_256_cbc(),
774 super::Mode::Decrypt,
775 &data,
776 Some(&iv),
777 )
778 .unwrap();
779 cr.pad(false);
780 let mut unciphered_data = vec![0; data.len() + super::Cipher::aes_256_cbc().block_size()];
781 let count = cr.update(&ciphered_data, &mut unciphered_data).unwrap();
782 let rest = cr.finalize(&mut unciphered_data[count..]).unwrap();
783 unciphered_data.truncate(count + rest);
784
785 let expected_unciphered_data = b"I love turtles.\x01";
786
787 assert_eq!(&unciphered_data, expected_unciphered_data);
788 }
789
790 fn cipher_test(ciphertype: super::Cipher, pt: &str, ct: &str, key: &str, iv: &str) {
791 let pt = Vec::from_hex(pt).unwrap();
792 let ct = Vec::from_hex(ct).unwrap();
793 let key = Vec::from_hex(key).unwrap();
794 let iv = Vec::from_hex(iv).unwrap();
795
796 let computed = super::decrypt(ciphertype, &key, Some(&iv), &ct).unwrap();
797 let expected = pt;
798
799 if computed != expected {
800 println!("Computed: {}", hex::encode(&computed));
801 println!("Expected: {}", hex::encode(&expected));
802 if computed.len() != expected.len() {
803 println!(
804 "Lengths differ: {} in computed vs {} expected",
805 computed.len(),
806 expected.len()
807 );
808 }
809 panic!("test failure");
810 }
811 }
812
813 #[test]
814 fn test_rc4() {
815 let pt = "0000000000000000000000000000000000000000000000000000000000000000000000000000";
816 let ct = "A68686B04D686AA107BD8D4CAB191A3EEC0A6294BC78B60F65C25CB47BD7BB3A48EFC4D26BE4";
817 let key = "97CD440324DA5FD1F7955C1C13B6B466";
818 let iv = "";
819
820 cipher_test(super::Cipher::rc4(), pt, ct, key, iv);
821 }
822
823 #[test]
824 fn test_aes128_ctr() {
825 let pt = "6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411\
826 E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710";
827 let ct = "874D6191B620E3261BEF6864990DB6CE9806F66B7970FDFF8617187BB9FFFDFF5AE4DF3EDBD5D35E\
828 5B4F09020DB03EAB1E031DDA2FBE03D1792170A0F3009CEE";
829 let key = "2B7E151628AED2A6ABF7158809CF4F3C";
830 let iv = "F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF";
831
832 cipher_test(super::Cipher::aes_128_ctr(), pt, ct, key, iv);
833 }
834
835 #[test]
836 fn test_aes128_ofb() {
837 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710";
840 let ct = "3b3fd92eb72dad20333449f8e83cfb4a7789508d16918f03f53c52dac54ed8259740051e9c5fecf64344f7a82260edcc304c6528f659c77866a510d9c1d6ae5e";
841 let key = "2b7e151628aed2a6abf7158809cf4f3c";
842 let iv = "000102030405060708090a0b0c0d0e0f";
843
844 cipher_test(super::Cipher::aes_128_ofb(), pt, ct, key, iv);
845 }
846
847 #[test]
848 fn test_aes192_ctr() {
849 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710";
852 let ct = "1abc932417521ca24f2b0459fe7e6e0b090339ec0aa6faefd5ccc2c6f4ce8e941e36b26bd1ebc670d1bd1d665620abf74f78a7f6d29809585a97daec58c6b050";
853 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
854 let iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
855
856 cipher_test(super::Cipher::aes_192_ctr(), pt, ct, key, iv);
857 }
858
859 #[test]
860 fn test_aes192_ofb() {
861 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710";
864 let ct = "cdc80d6fddf18cab34c25909c99a4174fcc28b8d4c63837c09e81700c11004018d9a9aeac0f6596f559c6d4daf59a5f26d9f200857ca6c3e9cac524bd9acc92a";
865 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
866 let iv = "000102030405060708090a0b0c0d0e0f";
867
868 cipher_test(super::Cipher::aes_192_ofb(), pt, ct, key, iv);
869 }
870
871 #[test]
872 fn test_aes256_ofb() {
873 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710";
876 let ct = "dc7e84bfda79164b7ecd8486985d38604febdc6740d20b3ac88f6ad82a4fb08d71ab47a086e86eedf39d1c5bba97c4080126141d67f37be8538f5a8be740e484";
877 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
878 let iv = "000102030405060708090a0b0c0d0e0f";
879
880 cipher_test(super::Cipher::aes_256_ofb(), pt, ct, key, iv);
881 }
882
883 #[test]
884 fn test_des_cbc() {
885 let pt = "54686973206973206120746573742e";
886 let ct = "6f2867cfefda048a4046ef7e556c7132";
887 let key = "7cb66337f3d3c0fe";
888 let iv = "0001020304050607";
889
890 cipher_test(super::Cipher::des_cbc(), pt, ct, key, iv);
891 }
892
893 #[test]
894 fn test_des_ecb() {
895 let pt = "54686973206973206120746573742e";
896 let ct = "0050ab8aecec758843fe157b4dde938c";
897 let key = "7cb66337f3d3c0fe";
898 let iv = "0001020304050607";
899
900 cipher_test(super::Cipher::des_ecb(), pt, ct, key, iv);
901 }
902
903 #[test]
904 fn test_des_ede3() {
905 let pt = "9994f4c69d40ae4f34ff403b5cf39d4c8207ea5d3e19a5fd";
906 let ct = "9e5c4297d60582f81071ac8ab7d0698d4c79de8b94c519858207ea5d3e19a5fd";
907 let key = "010203040506070801020304050607080102030405060708";
908 let iv = "5cc118306dc702e4";
909
910 cipher_test(super::Cipher::des_ede3(), pt, ct, key, iv);
911 }
912
913 #[test]
914 fn test_des_ede3_cbc() {
915 let pt = "54686973206973206120746573742e";
916 let ct = "6f2867cfefda048a4046ef7e556c7132";
917 let key = "7cb66337f3d3c0fe7cb66337f3d3c0fe7cb66337f3d3c0fe";
918 let iv = "0001020304050607";
919
920 cipher_test(super::Cipher::des_ede3_cbc(), pt, ct, key, iv);
921 }
922
923 #[test]
924 fn test_aes128_gcm() {
925 let key = "0e00c76561d2bd9b40c3c15427e2b08f";
926 let iv = "492cadaccd3ca3fbc9cf9f06eb3325c4e159850b0dbe98199b89b7af528806610b6f63998e1eae80c348e7\
927 4cbb921d8326631631fc6a5d304f39166daf7ea15fa1977f101819adb510b50fe9932e12c5a85aa3fd1e73\
928 d8d760af218be829903a77c63359d75edd91b4f6ed5465a72662f5055999e059e7654a8edc921aa0d496";
929 let pt = "fef03c2d7fb15bf0d2df18007d99f967c878ad59359034f7bb2c19af120685d78e32f6b8b83b032019956c\
930 a9c0195721476b85";
931 let aad = "d8f1163d8c840292a2b2dacf4ac7c36aff8733f18fabb4fa5594544125e03d1e6e5d6d0fd61656c8d8f327\
932 c92839ae5539bb469c9257f109ebff85aad7bd220fdaa95c022dbd0c7bb2d878ad504122c943045d3c5eba\
933 8f1f56c0";
934 let ct = "4f6cf471be7cbd2575cd5a1747aea8fe9dea83e51936beac3e68f66206922060c697ffa7af80ad6bb68f2c\
935 f4fc97416ee52abe";
936 let tag = "e20b6655";
937
938 let mut actual_tag = [0; 4];
941 let out = encrypt_aead(
942 Cipher::aes_128_gcm(),
943 &Vec::from_hex(key).unwrap(),
944 Some(&Vec::from_hex(iv).unwrap()),
945 &Vec::from_hex(aad).unwrap(),
946 &Vec::from_hex(pt).unwrap(),
947 &mut actual_tag,
948 )
949 .unwrap();
950 assert_eq!(ct, hex::encode(out));
951 assert_eq!(tag, hex::encode(actual_tag));
952
953 let out = decrypt_aead(
954 Cipher::aes_128_gcm(),
955 &Vec::from_hex(key).unwrap(),
956 Some(&Vec::from_hex(iv).unwrap()),
957 &Vec::from_hex(aad).unwrap(),
958 &Vec::from_hex(ct).unwrap(),
959 &Vec::from_hex(tag).unwrap(),
960 )
961 .unwrap();
962 assert_eq!(pt, hex::encode(out));
963 }
964}