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