1use crate::libc_types::c_int;
56use crate::{ffi, try_int};
57use foreign_types::ForeignTypeRef;
58use openssl_macros::corresponds;
59use std::cmp;
60use std::ptr;
61
62use crate::error::ErrorStack;
63use crate::nid::Nid;
64use crate::{cvt, cvt_p};
65
66#[derive(Copy, Clone)]
67pub enum Mode {
68 Encrypt,
69 Decrypt,
70}
71
72foreign_type_and_impl_send_sync! {
73 type CType = ffi::EVP_CIPHER_CTX;
74 fn drop = ffi::EVP_CIPHER_CTX_free;
75
76 pub struct CipherCtx;
77}
78
79impl CipherCtxRef {
80 #[corresponds(EVP_EncryptInit_ex)]
83 pub fn init_encrypt(
84 &mut self,
85 cipher: &Cipher,
86 key: &[u8],
87 iv: &[u8; ffi::EVP_MAX_IV_LENGTH as usize],
88 ) -> Result<(), ErrorStack> {
89 ffi::init();
90
91 if key.len() != cipher.key_len() {
92 return Err(ErrorStack::internal_error_str("invalid key size"));
93 }
94
95 unsafe {
96 cvt(ffi::EVP_EncryptInit_ex(
97 self.as_ptr(),
98 cipher.as_ptr(),
99 ptr::null_mut(),
101 key.as_ptr(),
102 iv.as_ptr(),
103 ))
104 .map(|_| ())
105 }
106 }
107
108 #[corresponds(EVP_DecryptInit_ex)]
111 pub fn init_decrypt(
112 &mut self,
113 cipher: &Cipher,
114 key: &[u8],
115 iv: &[u8; ffi::EVP_MAX_IV_LENGTH as usize],
116 ) -> Result<(), ErrorStack> {
117 ffi::init();
118
119 if key.len() != cipher.key_len() {
120 return Err(ErrorStack::internal_error_str("invalid key size"));
121 }
122
123 unsafe {
124 cvt(ffi::EVP_DecryptInit_ex(
125 self.as_ptr(),
126 cipher.as_ptr(),
127 ptr::null_mut(),
129 key.as_ptr(),
130 iv.as_ptr(),
131 ))
132 .map(|_| ())
133 }
134 }
135}
136
137#[derive(Copy, Clone, Debug, PartialEq, Eq)]
143pub struct Cipher(*const ffi::EVP_CIPHER);
144
145impl Cipher {
146 #[corresponds(EVP_get_cipherbynid)]
148 #[must_use]
149 pub fn from_nid(nid: Nid) -> Option<Cipher> {
150 let ptr = unsafe { ffi::EVP_get_cipherbynid(nid.as_raw()) };
151 if ptr.is_null() {
152 None
153 } else {
154 Some(Cipher(ptr))
155 }
156 }
157
158 #[must_use]
159 pub fn aes_128_ecb() -> Cipher {
160 unsafe { Cipher(ffi::EVP_aes_128_ecb()) }
161 }
162
163 #[must_use]
164 pub fn aes_128_cbc() -> Cipher {
165 unsafe { Cipher(ffi::EVP_aes_128_cbc()) }
166 }
167
168 #[must_use]
169 pub fn aes_128_ctr() -> Cipher {
170 unsafe { Cipher(ffi::EVP_aes_128_ctr()) }
171 }
172
173 #[must_use]
174 pub fn aes_128_gcm() -> Cipher {
175 unsafe { Cipher(ffi::EVP_aes_128_gcm()) }
176 }
177
178 #[must_use]
179 pub fn aes_128_ofb() -> Cipher {
180 unsafe { Cipher(ffi::EVP_aes_128_ofb()) }
181 }
182
183 #[must_use]
184 pub fn aes_192_ecb() -> Cipher {
185 unsafe { Cipher(ffi::EVP_aes_192_ecb()) }
186 }
187
188 #[must_use]
189 pub fn aes_192_cbc() -> Cipher {
190 unsafe { Cipher(ffi::EVP_aes_192_cbc()) }
191 }
192
193 #[must_use]
194 pub fn aes_192_ctr() -> Cipher {
195 unsafe { Cipher(ffi::EVP_aes_192_ctr()) }
196 }
197
198 #[must_use]
199 pub fn aes_192_gcm() -> Cipher {
200 unsafe { Cipher(ffi::EVP_aes_192_gcm()) }
201 }
202
203 #[must_use]
204 pub fn aes_192_ofb() -> Cipher {
205 unsafe { Cipher(ffi::EVP_aes_192_ofb()) }
206 }
207
208 #[must_use]
209 pub fn aes_256_ecb() -> Cipher {
210 unsafe { Cipher(ffi::EVP_aes_256_ecb()) }
211 }
212
213 #[must_use]
214 pub fn aes_256_cbc() -> Cipher {
215 unsafe { Cipher(ffi::EVP_aes_256_cbc()) }
216 }
217
218 #[must_use]
219 pub fn aes_256_ctr() -> Cipher {
220 unsafe { Cipher(ffi::EVP_aes_256_ctr()) }
221 }
222
223 #[must_use]
224 pub fn aes_256_gcm() -> Cipher {
225 unsafe { Cipher(ffi::EVP_aes_256_gcm()) }
226 }
227
228 #[must_use]
229 pub fn aes_256_ofb() -> Cipher {
230 unsafe { Cipher(ffi::EVP_aes_256_ofb()) }
231 }
232
233 #[must_use]
234 pub fn des_cbc() -> Cipher {
235 unsafe { Cipher(ffi::EVP_des_cbc()) }
236 }
237
238 #[must_use]
239 pub fn des_ecb() -> Cipher {
240 unsafe { Cipher(ffi::EVP_des_ecb()) }
241 }
242
243 #[must_use]
244 pub fn des_ede3() -> Cipher {
245 unsafe { Cipher(ffi::EVP_des_ede3()) }
246 }
247
248 #[must_use]
249 pub fn des_ede3_cbc() -> Cipher {
250 unsafe { Cipher(ffi::EVP_des_ede3_cbc()) }
251 }
252
253 #[must_use]
254 pub fn rc4() -> Cipher {
255 unsafe { Cipher(ffi::EVP_rc4()) }
256 }
257
258 #[must_use]
264 pub unsafe fn from_ptr(ptr: *const ffi::EVP_CIPHER) -> Cipher {
265 Cipher(ptr)
266 }
267
268 #[allow(clippy::trivially_copy_pass_by_ref)]
269 #[must_use]
270 pub fn as_ptr(&self) -> *const ffi::EVP_CIPHER {
271 self.0
272 }
273
274 #[allow(clippy::trivially_copy_pass_by_ref)]
276 #[must_use]
277 pub fn key_len(&self) -> usize {
278 unsafe { EVP_CIPHER_key_length(self.0) as usize }
279 }
280
281 #[allow(clippy::trivially_copy_pass_by_ref)]
284 #[must_use]
285 pub fn iv_len(&self) -> Option<usize> {
286 unsafe {
287 let len = EVP_CIPHER_iv_length(self.0) as usize;
288 if len == 0 {
289 None
290 } else {
291 Some(len)
292 }
293 }
294 }
295
296 #[allow(clippy::trivially_copy_pass_by_ref)]
302 pub fn block_size(&self) -> usize {
303 unsafe { EVP_CIPHER_block_size(self.0) as usize }
304 }
305
306 #[corresponds(EVP_CIPHER_nid)]
308 pub fn nid(&self) -> Nid {
309 ffi::init();
310 let nid = unsafe { ffi::EVP_CIPHER_nid(self.as_ptr()) };
311 Nid::from_raw(nid)
312 }
313}
314
315unsafe impl Sync for Cipher {}
316unsafe impl Send for Cipher {}
317
318pub struct Crypter {
379 ctx: *mut ffi::EVP_CIPHER_CTX,
380 block_size: usize,
381}
382
383unsafe impl Sync for Crypter {}
384unsafe impl Send for Crypter {}
385
386impl Crypter {
387 pub fn new(
395 t: Cipher,
396 mode: Mode,
397 key: &[u8],
398 iv: Option<&[u8]>,
399 ) -> Result<Crypter, ErrorStack> {
400 ffi::init();
401
402 unsafe {
403 let ctx = cvt_p(ffi::EVP_CIPHER_CTX_new())?;
404 let crypter = Crypter {
405 ctx,
406 block_size: t.block_size(),
407 };
408
409 let mode = match mode {
410 Mode::Encrypt => 1,
411 Mode::Decrypt => 0,
412 };
413
414 cvt(ffi::EVP_CipherInit_ex(
415 crypter.ctx,
416 t.as_ptr(),
417 ptr::null_mut(),
418 ptr::null_mut(),
419 ptr::null_mut(),
420 mode,
421 ))?;
422
423 assert!(key.len() <= c_int::MAX as usize);
424 cvt(ffi::EVP_CIPHER_CTX_set_key_length(
425 crypter.ctx,
426 try_int(key.len())?,
427 ))?;
428
429 let iv = match (iv, t.iv_len()) {
430 (Some(iv), Some(len)) => {
431 if iv.len() != len {
432 assert!(iv.len() <= c_int::MAX as usize);
433 cvt(ffi::EVP_CIPHER_CTX_ctrl(
434 crypter.ctx,
435 ffi::EVP_CTRL_GCM_SET_IVLEN,
436 try_int(iv.len())?,
437 ptr::null_mut(),
438 ))?;
439 }
440 iv.as_ptr().cast_mut()
441 }
442 (Some(_) | None, None) => ptr::null_mut(),
443 (None, Some(_)) => panic!("an IV is required for this cipher"),
444 };
445 cvt(ffi::EVP_CipherInit_ex(
446 crypter.ctx,
447 ptr::null(),
448 ptr::null_mut(),
449 key.as_ptr().cast_mut(),
450 iv,
451 mode,
452 ))?;
453
454 Ok(crypter)
455 }
456 }
457
458 pub fn pad(&mut self, padding: bool) {
463 unsafe {
464 ffi::EVP_CIPHER_CTX_set_padding(self.ctx, c_int::from(padding));
465 }
466 }
467
468 pub fn set_tag(&mut self, tag: &[u8]) -> Result<(), ErrorStack> {
472 unsafe {
473 assert!(tag.len() <= c_int::MAX as usize);
474 cvt(ffi::EVP_CIPHER_CTX_ctrl(
476 self.ctx,
477 ffi::EVP_CTRL_GCM_SET_TAG,
478 try_int(tag.len())?,
479 tag.as_ptr().cast_mut().cast(),
480 ))
481 }
482 }
483
484 pub fn set_tag_len(&mut self, tag_len: usize) -> Result<(), ErrorStack> {
489 unsafe {
490 assert!(tag_len <= c_int::MAX as usize);
491 cvt(ffi::EVP_CIPHER_CTX_ctrl(
493 self.ctx,
494 ffi::EVP_CTRL_GCM_SET_TAG,
495 try_int(tag_len)?,
496 ptr::null_mut(),
497 ))
498 }
499 }
500
501 pub fn set_data_len(&mut self, data_len: usize) -> Result<(), ErrorStack> {
506 unsafe {
507 assert!(data_len <= c_int::MAX as usize);
508 let mut len = 0;
509 cvt(ffi::EVP_CipherUpdate(
510 self.ctx,
511 ptr::null_mut(),
512 &mut len,
513 ptr::null_mut(),
514 try_int(data_len)?,
515 ))
516 }
517 }
518
519 pub fn aad_update(&mut self, input: &[u8]) -> Result<(), ErrorStack> {
525 unsafe {
526 assert!(input.len() <= c_int::MAX as usize);
527 let mut len = 0;
528 cvt(ffi::EVP_CipherUpdate(
529 self.ctx,
530 ptr::null_mut(),
531 &mut len,
532 input.as_ptr(),
533 try_int(input.len())?,
534 ))
535 }
536 }
537
538 pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result<usize, ErrorStack> {
553 unsafe {
554 let block_size = if self.block_size > 1 {
555 self.block_size
556 } else {
557 0
558 };
559 assert!(output.len() >= input.len() + block_size);
560 let mut outl = try_int(output.len())?;
561
562 cvt(ffi::EVP_CipherUpdate(
563 self.ctx,
564 output.as_mut_ptr(),
565 &mut outl,
566 input.as_ptr(),
567 try_int(input.len())?,
568 ))?;
569
570 Ok(outl as usize)
571 }
572 }
573
574 pub fn finalize(&mut self, output: &mut [u8]) -> Result<usize, ErrorStack> {
586 unsafe {
587 if self.block_size > 1 {
588 assert!(output.len() >= self.block_size);
589 }
590 let mut outl = cmp::min(output.len(), c_int::MAX as usize) as c_int;
591
592 cvt(ffi::EVP_CipherFinal_ex(
593 self.ctx,
594 output.as_mut_ptr(),
595 &mut outl,
596 ))?;
597
598 Ok(outl as usize)
599 }
600 }
601
602 pub fn get_tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> {
611 unsafe {
612 assert!(tag.len() <= c_int::MAX as usize);
613 cvt(ffi::EVP_CIPHER_CTX_ctrl(
614 self.ctx,
615 ffi::EVP_CTRL_GCM_GET_TAG,
616 try_int(tag.len())?,
617 tag.as_mut_ptr().cast(),
618 ))
619 .map(|_| ())
620 }
621 }
622}
623
624impl Drop for Crypter {
625 fn drop(&mut self) {
626 unsafe {
627 ffi::EVP_CIPHER_CTX_free(self.ctx);
628 }
629 }
630}
631
632pub fn encrypt(
663 t: Cipher,
664 key: &[u8],
665 iv: Option<&[u8]>,
666 data: &[u8],
667) -> Result<Vec<u8>, ErrorStack> {
668 cipher(t, Mode::Encrypt, key, iv, data)
669}
670
671pub fn decrypt(
702 t: Cipher,
703 key: &[u8],
704 iv: Option<&[u8]>,
705 data: &[u8],
706) -> Result<Vec<u8>, ErrorStack> {
707 cipher(t, Mode::Decrypt, key, iv, data)
708}
709
710fn cipher(
711 t: Cipher,
712 mode: Mode,
713 key: &[u8],
714 iv: Option<&[u8]>,
715 data: &[u8],
716) -> Result<Vec<u8>, ErrorStack> {
717 let mut c = Crypter::new(t, mode, key, iv)?;
718 let mut out = vec![0; data.len() + t.block_size()];
719 let count = c.update(data, &mut out)?;
720 let rest = c.finalize(&mut out[count..])?;
721 out.truncate(count + rest);
722 Ok(out)
723}
724
725pub fn encrypt_aead(
734 t: Cipher,
735 key: &[u8],
736 iv: Option<&[u8]>,
737 aad: &[u8],
738 data: &[u8],
739 tag: &mut [u8],
740) -> Result<Vec<u8>, ErrorStack> {
741 let mut c = Crypter::new(t, Mode::Encrypt, key, iv)?;
742 let mut out = vec![0; data.len() + t.block_size()];
743
744 c.aad_update(aad)?;
745 let count = c.update(data, &mut out)?;
746 let rest = c.finalize(&mut out[count..])?;
747 c.get_tag(tag)?;
748 out.truncate(count + rest);
749 Ok(out)
750}
751
752pub fn decrypt_aead(
757 t: Cipher,
758 key: &[u8],
759 iv: Option<&[u8]>,
760 aad: &[u8],
761 data: &[u8],
762 tag: &[u8],
763) -> Result<Vec<u8>, ErrorStack> {
764 let mut c = Crypter::new(t, Mode::Decrypt, key, iv)?;
765 let mut out = vec![0; data.len() + t.block_size()];
766
767 c.aad_update(aad)?;
768 let count = c.update(data, &mut out)?;
769
770 c.set_tag(tag)?;
771 let rest = c.finalize(&mut out[count..])?;
772
773 out.truncate(count + rest);
774 Ok(out)
775}
776
777use crate::ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length};
778
779#[cfg(test)]
780mod tests {
781 use super::*;
782 use hex::{self, FromHex};
783
784 #[test]
785 fn test_stream_cipher_output() {
786 let key = [0u8; 16];
787 let iv = [0u8; 16];
788 let mut c = super::Crypter::new(
789 super::Cipher::aes_128_ctr(),
790 super::Mode::Encrypt,
791 &key,
792 Some(&iv),
793 )
794 .unwrap();
795
796 assert_eq!(c.update(&[0u8; 15], &mut [0u8; 15]).unwrap(), 15);
797 assert_eq!(c.update(&[0u8; 1], &mut [0u8; 1]).unwrap(), 1);
798 assert_eq!(c.finalize(&mut [0u8; 0]).unwrap(), 0);
799 }
800
801 #[test]
804 fn test_aes_256_ecb() {
805 let k0 = [
806 0x00u8, 0x01u8, 0x02u8, 0x03u8, 0x04u8, 0x05u8, 0x06u8, 0x07u8, 0x08u8, 0x09u8, 0x0au8,
807 0x0bu8, 0x0cu8, 0x0du8, 0x0eu8, 0x0fu8, 0x10u8, 0x11u8, 0x12u8, 0x13u8, 0x14u8, 0x15u8,
808 0x16u8, 0x17u8, 0x18u8, 0x19u8, 0x1au8, 0x1bu8, 0x1cu8, 0x1du8, 0x1eu8, 0x1fu8,
809 ];
810 let p0 = [
811 0x00u8, 0x11u8, 0x22u8, 0x33u8, 0x44u8, 0x55u8, 0x66u8, 0x77u8, 0x88u8, 0x99u8, 0xaau8,
812 0xbbu8, 0xccu8, 0xddu8, 0xeeu8, 0xffu8,
813 ];
814 let c0 = [
815 0x8eu8, 0xa2u8, 0xb7u8, 0xcau8, 0x51u8, 0x67u8, 0x45u8, 0xbfu8, 0xeau8, 0xfcu8, 0x49u8,
816 0x90u8, 0x4bu8, 0x49u8, 0x60u8, 0x89u8,
817 ];
818 let mut c = super::Crypter::new(
819 super::Cipher::aes_256_ecb(),
820 super::Mode::Encrypt,
821 &k0,
822 None,
823 )
824 .unwrap();
825 c.pad(false);
826 let mut r0 = vec![0; c0.len() + super::Cipher::aes_256_ecb().block_size()];
827 let count = c.update(&p0, &mut r0).unwrap();
828 let rest = c.finalize(&mut r0[count..]).unwrap();
829 r0.truncate(count + rest);
830 assert_eq!(hex::encode(&r0), hex::encode(c0));
831
832 let mut c = super::Crypter::new(
833 super::Cipher::aes_256_ecb(),
834 super::Mode::Decrypt,
835 &k0,
836 None,
837 )
838 .unwrap();
839 c.pad(false);
840 let mut p1 = vec![0; r0.len() + super::Cipher::aes_256_ecb().block_size()];
841 let count = c.update(&r0, &mut p1).unwrap();
842 let rest = c.finalize(&mut p1[count..]).unwrap();
843 p1.truncate(count + rest);
844 assert_eq!(hex::encode(p1), hex::encode(p0));
845 }
846
847 #[test]
848 fn test_aes_256_cbc_decrypt() {
849 let iv = [
850 4_u8, 223_u8, 153_u8, 219_u8, 28_u8, 142_u8, 234_u8, 68_u8, 227_u8, 69_u8, 98_u8,
851 107_u8, 208_u8, 14_u8, 236_u8, 60_u8,
852 ];
853 let data = [
854 143_u8, 210_u8, 75_u8, 63_u8, 214_u8, 179_u8, 155_u8, 241_u8, 242_u8, 31_u8, 154_u8,
855 56_u8, 198_u8, 145_u8, 192_u8, 64_u8, 2_u8, 245_u8, 167_u8, 220_u8, 55_u8, 119_u8,
856 233_u8, 136_u8, 139_u8, 27_u8, 71_u8, 242_u8, 119_u8, 175_u8, 65_u8, 207_u8,
857 ];
858 let ciphered_data = [
859 0x4a_u8, 0x2e_u8, 0xe5_u8, 0x6_u8, 0xbf_u8, 0xcf_u8, 0xf2_u8, 0xd7_u8, 0xea_u8,
860 0x2d_u8, 0xb1_u8, 0x85_u8, 0x6c_u8, 0x93_u8, 0x65_u8, 0x6f_u8,
861 ];
862 let mut cr = super::Crypter::new(
863 super::Cipher::aes_256_cbc(),
864 super::Mode::Decrypt,
865 &data,
866 Some(&iv),
867 )
868 .unwrap();
869 cr.pad(false);
870 let mut unciphered_data = vec![0; data.len() + super::Cipher::aes_256_cbc().block_size()];
871 let count = cr.update(&ciphered_data, &mut unciphered_data).unwrap();
872 let rest = cr.finalize(&mut unciphered_data[count..]).unwrap();
873 unciphered_data.truncate(count + rest);
874
875 let expected_unciphered_data = b"I love turtles.\x01";
876
877 assert_eq!(&unciphered_data, expected_unciphered_data);
878 }
879
880 fn cipher_test(ciphertype: super::Cipher, pt: &str, ct: &str, key: &str, iv: &str) {
881 let pt = Vec::from_hex(pt).unwrap();
882 let ct = Vec::from_hex(ct).unwrap();
883 let key = Vec::from_hex(key).unwrap();
884 let iv = Vec::from_hex(iv).unwrap();
885
886 let computed = super::decrypt(ciphertype, &key, Some(&iv), &ct).unwrap();
887 let expected = pt;
888
889 if computed != expected {
890 println!("Computed: {}", hex::encode(&computed));
891 println!("Expected: {}", hex::encode(&expected));
892 if computed.len() != expected.len() {
893 println!(
894 "Lengths differ: {} in computed vs {} expected",
895 computed.len(),
896 expected.len()
897 );
898 }
899 panic!("test failure");
900 }
901 }
902
903 #[test]
904 fn test_rc4() {
905 let pt = "0000000000000000000000000000000000000000000000000000000000000000000000000000";
906 let ct = "A68686B04D686AA107BD8D4CAB191A3EEC0A6294BC78B60F65C25CB47BD7BB3A48EFC4D26BE4";
907 let key = "97CD440324DA5FD1F7955C1C13B6B466";
908 let iv = "";
909
910 cipher_test(super::Cipher::rc4(), pt, ct, key, iv);
911 }
912
913 #[test]
914 fn test_aes128_ctr() {
915 let pt = "6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411\
916 E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710";
917 let ct = "874D6191B620E3261BEF6864990DB6CE9806F66B7970FDFF8617187BB9FFFDFF5AE4DF3EDBD5D35E\
918 5B4F09020DB03EAB1E031DDA2FBE03D1792170A0F3009CEE";
919 let key = "2B7E151628AED2A6ABF7158809CF4F3C";
920 let iv = "F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF";
921
922 cipher_test(super::Cipher::aes_128_ctr(), pt, ct, key, iv);
923 }
924
925 #[test]
926 fn test_aes128_ofb() {
927 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710";
930 let ct = "3b3fd92eb72dad20333449f8e83cfb4a7789508d16918f03f53c52dac54ed8259740051e9c5fecf64344f7a82260edcc304c6528f659c77866a510d9c1d6ae5e";
931 let key = "2b7e151628aed2a6abf7158809cf4f3c";
932 let iv = "000102030405060708090a0b0c0d0e0f";
933
934 cipher_test(super::Cipher::aes_128_ofb(), pt, ct, key, iv);
935 }
936
937 #[test]
938 fn test_aes192_ctr() {
939 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710";
942 let ct = "1abc932417521ca24f2b0459fe7e6e0b090339ec0aa6faefd5ccc2c6f4ce8e941e36b26bd1ebc670d1bd1d665620abf74f78a7f6d29809585a97daec58c6b050";
943 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
944 let iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
945
946 cipher_test(super::Cipher::aes_192_ctr(), pt, ct, key, iv);
947 }
948
949 #[test]
950 fn test_aes192_ofb() {
951 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710";
954 let ct = "cdc80d6fddf18cab34c25909c99a4174fcc28b8d4c63837c09e81700c11004018d9a9aeac0f6596f559c6d4daf59a5f26d9f200857ca6c3e9cac524bd9acc92a";
955 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
956 let iv = "000102030405060708090a0b0c0d0e0f";
957
958 cipher_test(super::Cipher::aes_192_ofb(), pt, ct, key, iv);
959 }
960
961 #[test]
962 fn test_aes256_ofb() {
963 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710";
966 let ct = "dc7e84bfda79164b7ecd8486985d38604febdc6740d20b3ac88f6ad82a4fb08d71ab47a086e86eedf39d1c5bba97c4080126141d67f37be8538f5a8be740e484";
967 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
968 let iv = "000102030405060708090a0b0c0d0e0f";
969
970 cipher_test(super::Cipher::aes_256_ofb(), pt, ct, key, iv);
971 }
972
973 #[test]
974 fn test_des_cbc() {
975 let pt = "54686973206973206120746573742e";
976 let ct = "6f2867cfefda048a4046ef7e556c7132";
977 let key = "7cb66337f3d3c0fe";
978 let iv = "0001020304050607";
979
980 cipher_test(super::Cipher::des_cbc(), pt, ct, key, iv);
981 }
982
983 #[test]
984 fn test_des_ecb() {
985 let pt = "54686973206973206120746573742e";
986 let ct = "0050ab8aecec758843fe157b4dde938c";
987 let key = "7cb66337f3d3c0fe";
988 let iv = "0001020304050607";
989
990 cipher_test(super::Cipher::des_ecb(), pt, ct, key, iv);
991 }
992
993 #[test]
994 fn test_des_ede3() {
995 let pt = "9994f4c69d40ae4f34ff403b5cf39d4c8207ea5d3e19a5fd";
996 let ct = "9e5c4297d60582f81071ac8ab7d0698d4c79de8b94c519858207ea5d3e19a5fd";
997 let key = "010203040506070801020304050607080102030405060708";
998 let iv = "5cc118306dc702e4";
999
1000 cipher_test(super::Cipher::des_ede3(), pt, ct, key, iv);
1001 }
1002
1003 #[test]
1004 fn test_des_ede3_cbc() {
1005 let pt = "54686973206973206120746573742e";
1006 let ct = "6f2867cfefda048a4046ef7e556c7132";
1007 let key = "7cb66337f3d3c0fe7cb66337f3d3c0fe7cb66337f3d3c0fe";
1008 let iv = "0001020304050607";
1009
1010 cipher_test(super::Cipher::des_ede3_cbc(), pt, ct, key, iv);
1011 }
1012
1013 #[test]
1014 fn test_aes128_gcm() {
1015 let key = "0e00c76561d2bd9b40c3c15427e2b08f";
1016 let iv = "492cadaccd3ca3fbc9cf9f06eb3325c4e159850b0dbe98199b89b7af528806610b6f63998e1eae80c348e7\
1017 4cbb921d8326631631fc6a5d304f39166daf7ea15fa1977f101819adb510b50fe9932e12c5a85aa3fd1e73\
1018 d8d760af218be829903a77c63359d75edd91b4f6ed5465a72662f5055999e059e7654a8edc921aa0d496";
1019 let pt = "fef03c2d7fb15bf0d2df18007d99f967c878ad59359034f7bb2c19af120685d78e32f6b8b83b032019956c\
1020 a9c0195721476b85";
1021 let aad = "d8f1163d8c840292a2b2dacf4ac7c36aff8733f18fabb4fa5594544125e03d1e6e5d6d0fd61656c8d8f327\
1022 c92839ae5539bb469c9257f109ebff85aad7bd220fdaa95c022dbd0c7bb2d878ad504122c943045d3c5eba\
1023 8f1f56c0";
1024 let ct = "4f6cf471be7cbd2575cd5a1747aea8fe9dea83e51936beac3e68f66206922060c697ffa7af80ad6bb68f2c\
1025 f4fc97416ee52abe";
1026 let tag = "e20b6655";
1027
1028 let mut actual_tag = [0; 4];
1031 let out = encrypt_aead(
1032 Cipher::aes_128_gcm(),
1033 &Vec::from_hex(key).unwrap(),
1034 Some(&Vec::from_hex(iv).unwrap()),
1035 &Vec::from_hex(aad).unwrap(),
1036 &Vec::from_hex(pt).unwrap(),
1037 &mut actual_tag,
1038 )
1039 .unwrap();
1040 assert_eq!(ct, hex::encode(out));
1041 assert_eq!(tag, hex::encode(actual_tag));
1042
1043 let out = decrypt_aead(
1044 Cipher::aes_128_gcm(),
1045 &Vec::from_hex(key).unwrap(),
1046 Some(&Vec::from_hex(iv).unwrap()),
1047 &Vec::from_hex(aad).unwrap(),
1048 &Vec::from_hex(ct).unwrap(),
1049 &Vec::from_hex(tag).unwrap(),
1050 )
1051 .unwrap();
1052 assert_eq!(pt, hex::encode(out));
1053 }
1054
1055 #[test]
1056 fn test_nid_roundtrip() {
1057 for cipher in [
1058 Cipher::aes_128_gcm(),
1059 Cipher::aes_192_gcm(),
1060 Cipher::aes_256_gcm(),
1061 Cipher::aes_128_ecb(),
1062 Cipher::aes_128_cbc(),
1063 Cipher::aes_128_ctr(),
1064 Cipher::aes_128_ofb(),
1065 Cipher::aes_192_ecb(),
1066 Cipher::aes_192_cbc(),
1067 Cipher::aes_192_ctr(),
1068 Cipher::aes_192_ofb(),
1069 Cipher::aes_256_ecb(),
1070 Cipher::aes_256_cbc(),
1071 Cipher::aes_256_ctr(),
1072 Cipher::aes_256_ofb(),
1073 Cipher::des_ecb(),
1074 Cipher::des_ede3_cbc(),
1075 Cipher::des_cbc(),
1076 Cipher::rc4(),
1077 ] {
1078 let name = cipher.nid().short_name().unwrap_or("unknown");
1079 assert_eq!(Cipher::from_nid(cipher.nid()), Some(cipher), "{}", name);
1080 }
1081
1082 assert_eq!(Cipher::from_nid(Cipher::des_ede3().nid()), None);
1083 }
1084
1085 #[test]
1087 fn test_nid_regression() {
1088 struct TestCase {
1089 cipher: Cipher,
1090 nid: c_int,
1091 }
1092
1093 for t in [
1094 TestCase {
1095 cipher: Cipher::aes_128_ecb(),
1096 nid: 418,
1097 },
1098 TestCase {
1099 cipher: Cipher::aes_128_cbc(),
1100 nid: 419,
1101 },
1102 TestCase {
1103 cipher: Cipher::aes_128_ctr(),
1104 nid: 904,
1105 },
1106 TestCase {
1107 cipher: Cipher::aes_128_gcm(),
1108 nid: 895,
1109 },
1110 TestCase {
1111 cipher: Cipher::aes_128_ofb(),
1112 nid: 420,
1113 },
1114 TestCase {
1115 cipher: Cipher::aes_192_ecb(),
1116 nid: 422,
1117 },
1118 TestCase {
1119 cipher: Cipher::aes_192_cbc(),
1120 nid: 423,
1121 },
1122 TestCase {
1123 cipher: Cipher::aes_192_ctr(),
1124 nid: 905,
1125 },
1126 TestCase {
1127 cipher: Cipher::aes_192_gcm(),
1128 nid: 898,
1129 },
1130 TestCase {
1131 cipher: Cipher::aes_192_ofb(),
1132 nid: 424,
1133 },
1134 TestCase {
1135 cipher: Cipher::aes_256_ecb(),
1136 nid: 426,
1137 },
1138 TestCase {
1139 cipher: Cipher::aes_256_cbc(),
1140 nid: 427,
1141 },
1142 TestCase {
1143 cipher: Cipher::aes_256_ctr(),
1144 nid: 906,
1145 },
1146 TestCase {
1147 cipher: Cipher::aes_256_gcm(),
1148 nid: 901,
1149 },
1150 TestCase {
1151 cipher: Cipher::aes_256_ofb(),
1152 nid: 428,
1153 },
1154 TestCase {
1155 cipher: Cipher::des_ecb(),
1156 nid: 29,
1157 },
1158 TestCase {
1159 cipher: Cipher::des_ede3_cbc(),
1160 nid: 44,
1161 },
1162 TestCase {
1163 cipher: Cipher::des_cbc(),
1164 nid: 31,
1165 },
1166 TestCase {
1167 cipher: Cipher::rc4(),
1168 nid: 5,
1169 },
1170 TestCase {
1171 cipher: Cipher::des_ede3(),
1172 nid: 33,
1173 },
1174 ] {
1175 let name = t.cipher.nid().short_name().unwrap_or("unknown");
1176 assert_eq!(t.cipher.nid().as_raw(), t.nid, "{}", name);
1177 }
1178 }
1179}