1#![warn(missing_docs)]
52
53use crate::cipher::CipherRef;
54use crate::error::ErrorStack;
55#[cfg(not(any(boringssl, awslc)))]
56use crate::pkey::{HasPrivate, HasPublic, PKey, PKeyRef};
57use crate::{cvt, cvt_p};
58#[cfg(ossl102)]
59use bitflags::bitflags;
60use cfg_if::cfg_if;
61use foreign_types::{ForeignType, ForeignTypeRef};
62use libc::{c_int, c_uchar};
63use openssl_macros::corresponds;
64use std::convert::{TryFrom, TryInto};
65use std::ptr;
66
67cfg_if! {
68 if #[cfg(ossl300)] {
69 use ffi::EVP_CIPHER_CTX_get0_cipher;
70 } else {
71 use ffi::EVP_CIPHER_CTX_cipher as EVP_CIPHER_CTX_get0_cipher;
72 }
73}
74
75foreign_type_and_impl_send_sync! {
76 type CType = ffi::EVP_CIPHER_CTX;
77 fn drop = ffi::EVP_CIPHER_CTX_free;
78
79 pub struct CipherCtx;
81 pub struct CipherCtxRef;
83}
84
85#[cfg(ossl102)]
86bitflags! {
87 pub struct CipherCtxFlags : c_int {
89 const FLAG_WRAP_ALLOW = ffi::EVP_CIPHER_CTX_FLAG_WRAP_ALLOW;
91 }
92}
93
94impl CipherCtx {
95 #[corresponds(EVP_CIPHER_CTX_new)]
97 pub fn new() -> Result<Self, ErrorStack> {
98 ffi::init();
99
100 unsafe {
101 let ptr = cvt_p(ffi::EVP_CIPHER_CTX_new())?;
102 Ok(CipherCtx::from_ptr(ptr))
103 }
104 }
105}
106
107impl CipherCtxRef {
108 #[corresponds(EVP_CIPHER_CTX_copy)]
109 pub fn copy(&mut self, src: &CipherCtxRef) -> Result<(), ErrorStack> {
110 unsafe {
111 cvt(ffi::EVP_CIPHER_CTX_copy(self.as_ptr(), src.as_ptr()))?;
112 Ok(())
113 }
114 }
115
116 #[corresponds(EVP_EncryptInit_ex)]
127 pub fn encrypt_init(
128 &mut self,
129 type_: Option<&CipherRef>,
130 key: Option<&[u8]>,
131 iv: Option<&[u8]>,
132 ) -> Result<(), ErrorStack> {
133 self.cipher_init(type_, key, iv, ffi::EVP_EncryptInit_ex)
134 }
135
136 #[corresponds(EVP_DecryptInit_ex)]
147 pub fn decrypt_init(
148 &mut self,
149 type_: Option<&CipherRef>,
150 key: Option<&[u8]>,
151 iv: Option<&[u8]>,
152 ) -> Result<(), ErrorStack> {
153 self.cipher_init(type_, key, iv, ffi::EVP_DecryptInit_ex)
154 }
155
156 fn cipher_init(
157 &mut self,
158 type_: Option<&CipherRef>,
159 key: Option<&[u8]>,
160 iv: Option<&[u8]>,
161 f: unsafe extern "C" fn(
162 *mut ffi::EVP_CIPHER_CTX,
163 *const ffi::EVP_CIPHER,
164 *mut ffi::ENGINE,
165 *const c_uchar,
166 *const c_uchar,
167 ) -> c_int,
168 ) -> Result<(), ErrorStack> {
169 if let Some(key) = key {
170 let key_len = type_.map_or_else(|| self.key_length(), |c| c.key_length());
171 assert!(key_len <= key.len());
172 }
173
174 if let Some(iv) = iv {
175 let iv_len = type_.map_or_else(|| self.iv_length(), |c| c.iv_length());
176 assert!(iv_len <= iv.len());
177 }
178
179 unsafe {
180 cvt(f(
181 self.as_ptr(),
182 type_.map_or(ptr::null(), |p| p.as_ptr()),
183 ptr::null_mut(),
184 key.map_or(ptr::null(), |k| k.as_ptr()),
185 iv.map_or(ptr::null(), |iv| iv.as_ptr()),
186 ))?;
187 }
188
189 Ok(())
190 }
191
192 #[corresponds(EVP_SealInit)]
205 #[cfg(not(any(boringssl, awslc)))]
206 pub fn seal_init<T>(
207 &mut self,
208 type_: Option<&CipherRef>,
209 pub_keys: &[PKey<T>],
210 encrypted_keys: &mut [Vec<u8>],
211 iv: Option<&mut [u8]>,
212 ) -> Result<(), ErrorStack>
213 where
214 T: HasPublic,
215 {
216 assert_eq!(pub_keys.len(), encrypted_keys.len());
217 if !pub_keys.is_empty() {
218 let iv_len = type_.map_or_else(|| self.iv_length(), |c| c.iv_length());
219 assert!(iv.as_ref().map_or(0, |b| b.len()) >= iv_len);
220 }
221
222 for (pub_key, buf) in pub_keys.iter().zip(&mut *encrypted_keys) {
223 buf.resize(pub_key.size(), 0);
224 }
225
226 let mut keys = encrypted_keys
227 .iter_mut()
228 .map(|b| b.as_mut_ptr())
229 .collect::<Vec<_>>();
230 let mut key_lengths = vec![0; pub_keys.len()];
231 let pub_keys_len = i32::try_from(pub_keys.len()).unwrap();
232
233 unsafe {
234 cvt(ffi::EVP_SealInit(
235 self.as_ptr(),
236 type_.map_or(ptr::null(), |p| p.as_ptr()),
237 keys.as_mut_ptr(),
238 key_lengths.as_mut_ptr(),
239 iv.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
240 pub_keys.as_ptr() as *mut _,
241 pub_keys_len,
242 ))?;
243 }
244
245 for (buf, len) in encrypted_keys.iter_mut().zip(key_lengths) {
246 buf.truncate(len as usize);
247 }
248
249 Ok(())
250 }
251
252 #[corresponds(EVP_OpenInit)]
262 #[cfg(not(any(boringssl, awslc)))]
263 pub fn open_init<T>(
264 &mut self,
265 type_: Option<&CipherRef>,
266 encrypted_key: &[u8],
267 iv: Option<&[u8]>,
268 priv_key: Option<&PKeyRef<T>>,
269 ) -> Result<(), ErrorStack>
270 where
271 T: HasPrivate,
272 {
273 if priv_key.is_some() {
274 let iv_len = type_.map_or_else(|| self.iv_length(), |c| c.iv_length());
275 assert!(iv.map_or(0, |b| b.len()) >= iv_len);
276 }
277
278 let len = c_int::try_from(encrypted_key.len()).unwrap();
279 unsafe {
280 cvt(ffi::EVP_OpenInit(
281 self.as_ptr(),
282 type_.map_or(ptr::null(), |p| p.as_ptr()),
283 encrypted_key.as_ptr(),
284 len,
285 iv.map_or(ptr::null(), |b| b.as_ptr()),
286 priv_key.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr),
287 ))?;
288 }
289
290 Ok(())
291 }
292
293 fn assert_cipher(&self) {
294 unsafe {
295 assert!(!EVP_CIPHER_CTX_get0_cipher(self.as_ptr()).is_null());
296 }
297 }
298
299 #[corresponds(EVP_CIPHER_CTX_block_size)]
307 pub fn block_size(&self) -> usize {
308 self.assert_cipher();
309
310 unsafe { ffi::EVP_CIPHER_CTX_block_size(self.as_ptr()) as usize }
311 }
312
313 #[corresponds(EVP_CIPHER_CTX_key_length)]
319 pub fn key_length(&self) -> usize {
320 self.assert_cipher();
321
322 unsafe { ffi::EVP_CIPHER_CTX_key_length(self.as_ptr()) as usize }
323 }
324
325 #[corresponds(EVP_CIPHER_CTX_rand_key)]
332 #[cfg(not(any(boringssl, awslc)))]
333 pub fn rand_key(&self, buf: &mut [u8]) -> Result<(), ErrorStack> {
334 assert!(buf.len() >= self.key_length());
335
336 unsafe {
337 cvt(ffi::EVP_CIPHER_CTX_rand_key(
338 self.as_ptr(),
339 buf.as_mut_ptr(),
340 ))?;
341 }
342
343 Ok(())
344 }
345
346 #[corresponds(EVP_CIPHER_CTX_set_key_length)]
354 pub fn set_key_length(&mut self, len: usize) -> Result<(), ErrorStack> {
355 self.assert_cipher();
356
357 unsafe {
358 cvt(ffi::EVP_CIPHER_CTX_set_key_length(
359 self.as_ptr(),
360 len.try_into().unwrap(),
361 ))?;
362 }
363
364 Ok(())
365 }
366
367 #[corresponds(EVP_CIPHER_CTX_iv_length)]
375 pub fn iv_length(&self) -> usize {
376 self.assert_cipher();
377
378 unsafe { ffi::EVP_CIPHER_CTX_iv_length(self.as_ptr()) as usize }
379 }
380
381 #[corresponds(EVP_CIPHER_CTX_num)]
390 #[cfg(ossl110)]
391 pub fn num(&self) -> usize {
392 self.assert_cipher();
393
394 unsafe { ffi::EVP_CIPHER_CTX_num(self.as_ptr()) as usize }
395 }
396
397 #[corresponds(EVP_CIPHER_CTX_ctrl)]
405 pub fn set_iv_length(&mut self, len: usize) -> Result<(), ErrorStack> {
406 self.assert_cipher();
407
408 let len = c_int::try_from(len).unwrap();
409
410 unsafe {
411 cvt(ffi::EVP_CIPHER_CTX_ctrl(
412 self.as_ptr(),
413 ffi::EVP_CTRL_GCM_SET_IVLEN,
414 len,
415 ptr::null_mut(),
416 ))?;
417 }
418
419 Ok(())
420 }
421
422 #[corresponds(EVP_CIPHER_CTX_get_tag_length)]
432 #[cfg(ossl300)]
433 pub fn tag_length(&self) -> usize {
434 self.assert_cipher();
435
436 unsafe { ffi::EVP_CIPHER_CTX_get_tag_length(self.as_ptr()) as usize }
437 }
438
439 #[corresponds(EVP_CIPHER_CTX_ctrl)]
446 pub fn tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> {
447 let len = c_int::try_from(tag.len()).unwrap();
448
449 unsafe {
450 cvt(ffi::EVP_CIPHER_CTX_ctrl(
451 self.as_ptr(),
452 ffi::EVP_CTRL_GCM_GET_TAG,
453 len,
454 tag.as_mut_ptr() as *mut _,
455 ))?;
456 }
457
458 Ok(())
459 }
460
461 #[corresponds(EVP_CIPHER_CTX_ctrl)]
465 pub fn set_tag_length(&mut self, len: usize) -> Result<(), ErrorStack> {
466 let len = c_int::try_from(len).unwrap();
467
468 unsafe {
469 cvt(ffi::EVP_CIPHER_CTX_ctrl(
470 self.as_ptr(),
471 ffi::EVP_CTRL_GCM_SET_TAG,
472 len,
473 ptr::null_mut(),
474 ))?;
475 }
476
477 Ok(())
478 }
479
480 #[corresponds(EVP_CIPHER_CTX_ctrl)]
482 pub fn set_tag(&mut self, tag: &[u8]) -> Result<(), ErrorStack> {
483 let len = c_int::try_from(tag.len()).unwrap();
484
485 unsafe {
486 cvt(ffi::EVP_CIPHER_CTX_ctrl(
487 self.as_ptr(),
488 ffi::EVP_CTRL_GCM_SET_TAG,
489 len,
490 tag.as_ptr() as *mut _,
491 ))?;
492 }
493
494 Ok(())
495 }
496
497 #[corresponds(EVP_CIPHER_CTX_set_padding)]
501 pub fn set_padding(&mut self, padding: bool) {
502 unsafe {
503 ffi::EVP_CIPHER_CTX_set_padding(self.as_ptr(), padding as c_int);
504 }
505 }
506
507 #[corresponds(EVP_CipherUpdate)]
511 pub fn set_data_len(&mut self, len: usize) -> Result<(), ErrorStack> {
512 let len = c_int::try_from(len).unwrap();
513
514 unsafe {
515 cvt(ffi::EVP_CipherUpdate(
516 self.as_ptr(),
517 ptr::null_mut(),
518 &mut 0,
519 ptr::null(),
520 len,
521 ))?;
522 }
523
524 Ok(())
525 }
526
527 #[corresponds(EVP_CIPHER_CTX_set_flags)]
531 #[cfg(ossl102)]
532 pub fn set_flags(&mut self, flags: CipherCtxFlags) {
533 unsafe {
534 ffi::EVP_CIPHER_CTX_set_flags(self.as_ptr(), flags.bits());
535 }
536 }
537
538 #[corresponds(EVP_CipherUpdate)]
549 pub fn cipher_update(
550 &mut self,
551 input: &[u8],
552 output: Option<&mut [u8]>,
553 ) -> Result<usize, ErrorStack> {
554 if let Some(output) = &output {
555 let mut block_size = self.block_size();
556 if block_size == 1 {
557 block_size = 0;
558 }
559 let min_output_size = input.len() + block_size;
560 assert!(
561 output.len() >= min_output_size,
562 "Output buffer size should be at least {} bytes.",
563 min_output_size
564 );
565 }
566
567 unsafe { self.cipher_update_unchecked(input, output) }
568 }
569
570 #[corresponds(EVP_CipherUpdate)]
588 pub unsafe fn cipher_update_unchecked(
589 &mut self,
590 input: &[u8],
591 output: Option<&mut [u8]>,
592 ) -> Result<usize, ErrorStack> {
593 let inlen = c_int::try_from(input.len()).unwrap();
594
595 let mut outlen = 0;
596
597 cvt(ffi::EVP_CipherUpdate(
598 self.as_ptr(),
599 output.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
600 &mut outlen,
601 input.as_ptr(),
602 inlen,
603 ))?;
604
605 Ok(outlen as usize)
606 }
607
608 pub fn cipher_update_vec(
610 &mut self,
611 input: &[u8],
612 output: &mut Vec<u8>,
613 ) -> Result<usize, ErrorStack> {
614 let base = output.len();
615 output.resize(base + input.len() + self.block_size(), 0);
616 let len = self.cipher_update(input, Some(&mut output[base..]))?;
617 output.truncate(base + len);
618
619 Ok(len)
620 }
621
622 #[corresponds(EVP_CipherUpdate)]
636 pub fn cipher_update_inplace(
637 &mut self,
638 data: &mut [u8],
639 inlen: usize,
640 ) -> Result<usize, ErrorStack> {
641 assert!(inlen <= data.len(), "Input size may not exceed buffer size");
642 let block_size = self.block_size();
643 if block_size != 1 {
644 assert!(
645 data.len() >= inlen + block_size,
646 "Output buffer size must be at least {} bytes.",
647 inlen + block_size
648 );
649 }
650
651 let inlen = c_int::try_from(inlen).unwrap();
652 let mut outlen = 0;
653 unsafe {
654 cvt(ffi::EVP_CipherUpdate(
655 self.as_ptr(),
656 data.as_mut_ptr(),
657 &mut outlen,
658 data.as_ptr(),
659 inlen,
660 ))
661 }?;
662
663 Ok(outlen as usize)
664 }
665
666 #[corresponds(EVP_CipherFinal)]
676 pub fn cipher_final(&mut self, output: &mut [u8]) -> Result<usize, ErrorStack> {
677 let block_size = self.block_size();
678 if block_size > 1 {
679 assert!(output.len() >= block_size);
680 }
681
682 unsafe { self.cipher_final_unchecked(output) }
683 }
684
685 #[corresponds(EVP_CipherFinal)]
701 pub unsafe fn cipher_final_unchecked(
702 &mut self,
703 output: &mut [u8],
704 ) -> Result<usize, ErrorStack> {
705 let mut outl = 0;
706
707 cvt(ffi::EVP_CipherFinal(
708 self.as_ptr(),
709 output.as_mut_ptr(),
710 &mut outl,
711 ))?;
712
713 Ok(outl as usize)
714 }
715
716 pub fn cipher_final_vec(&mut self, output: &mut Vec<u8>) -> Result<usize, ErrorStack> {
718 let base = output.len();
719 output.resize(base + self.block_size(), 0);
720 let len = self.cipher_final(&mut output[base..])?;
721 output.truncate(base + len);
722
723 Ok(len)
724 }
725}
726
727#[cfg(test)]
728mod test {
729 use super::*;
730 use crate::{cipher::Cipher, rand::rand_bytes};
731 #[cfg(not(any(boringssl, awslc)))]
732 use std::slice;
733
734 #[test]
735 #[cfg(not(any(boringssl, awslc)))]
736 fn seal_open() {
737 let private_pem = include_bytes!("../test/rsa.pem");
738 let public_pem = include_bytes!("../test/rsa.pem.pub");
739 let private_key = PKey::private_key_from_pem(private_pem).unwrap();
740 let public_key = PKey::public_key_from_pem(public_pem).unwrap();
741 let cipher = Cipher::aes_256_cbc();
742 let secret = b"My secret message";
743
744 let mut ctx = CipherCtx::new().unwrap();
745 let mut encrypted_key = vec![];
746 let mut iv = vec![0; cipher.iv_length()];
747 let mut encrypted = vec![];
748 ctx.seal_init(
749 Some(cipher),
750 &[public_key],
751 slice::from_mut(&mut encrypted_key),
752 Some(&mut iv),
753 )
754 .unwrap();
755 ctx.cipher_update_vec(secret, &mut encrypted).unwrap();
756 ctx.cipher_final_vec(&mut encrypted).unwrap();
757
758 let mut decrypted = vec![];
759 ctx.open_init(Some(cipher), &encrypted_key, Some(&iv), Some(&private_key))
760 .unwrap();
761 ctx.cipher_update_vec(&encrypted, &mut decrypted).unwrap();
762 ctx.cipher_final_vec(&mut decrypted).unwrap();
763
764 assert_eq!(secret, &decrypted[..]);
765 }
766
767 fn aes_128_cbc(cipher: &CipherRef) {
768 let key = hex::decode("2b7e151628aed2a6abf7158809cf4f3c").unwrap();
770 let iv = hex::decode("000102030405060708090a0b0c0d0e0f").unwrap();
771 let pt = hex::decode("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51")
772 .unwrap();
773 let ct = hex::decode("7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b2")
774 .unwrap();
775
776 let mut ctx = CipherCtx::new().unwrap();
777
778 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
779 .unwrap();
780 ctx.set_padding(false);
781
782 let mut buf = vec![];
783 ctx.cipher_update_vec(&pt, &mut buf).unwrap();
784 ctx.cipher_final_vec(&mut buf).unwrap();
785
786 assert_eq!(buf, ct);
787
788 ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv))
789 .unwrap();
790 ctx.set_padding(false);
791
792 let mut buf = vec![];
793 ctx.cipher_update_vec(&ct, &mut buf).unwrap();
794 ctx.cipher_final_vec(&mut buf).unwrap();
795
796 assert_eq!(buf, pt);
797 }
798
799 #[test]
800 #[cfg(ossl300)]
801 fn fetched_aes_128_cbc() {
802 let cipher = Cipher::fetch(None, "AES-128-CBC", None).unwrap();
803 aes_128_cbc(&cipher);
804 }
805
806 #[test]
807 fn default_aes_128_cbc() {
808 let cipher = Cipher::aes_128_cbc();
809 aes_128_cbc(cipher);
810 }
811
812 #[cfg(not(boringssl))]
813 #[test]
814 fn default_aes_128_ccm() {
815 let cipher = Cipher::aes_128_ccm();
817 aes_ccm(
818 cipher,
819 "26511fb51fcfa75cb4b44da75a6e5a0e",
820 "ea98ec44f5a86715014783172e",
821 "4da40b80579c1d9a5309f7efecb7c059a2f914511ca5fc10",
822 "e4692b9f06b666c7451b146c8aeb07a6e30c629d28065c3dde5940325b14b810",
823 "1bf0ba0ebb20d8edba59f29a9371750c9c714078f73c335d",
824 "2f1322ac69b848b001476323aed84c47",
825 );
826 }
827
828 #[cfg(not(boringssl))]
829 #[test]
830 fn default_aes_192_ccm() {
831 let cipher = Cipher::aes_192_ccm();
833 aes_ccm(
834 cipher,
835 "26511fb51fcfa75cb4b44da75a6e5a0eb8d9c8f3b906f886",
836 "ea98ec44f5a86715014783172e",
837 "4da40b80579c1d9a5309f7efecb7c059a2f914511ca5fc10",
838 "e4692b9f06b666c7451b146c8aeb07a6e30c629d28065c3dde5940325b14b810",
839 "30c154c616946eccc2e241d336ad33720953e449a0e6b0f0",
840 "dbf8e9464909bdf337e48093c082a10b",
841 );
842 }
843
844 #[cfg(not(boringssl))]
845 #[test]
846 fn default_aes_256_ccm() {
847 let cipher = Cipher::aes_256_ccm();
849 aes_ccm(
850 cipher,
851 "314a202f836f9f257e22d8c11757832ae5131d357a72df88f3eff0ffcee0da4e",
852 "3542fbe0f59a6d5f3abf619b7d",
853 "c5b3d71312ea14f2f8fae5bd1a453192b6604a45db75c5ed",
854 "dd4531f158a2fa3bc8a339f770595048f4a42bc1b03f2e824efc6ba4985119d8",
855 "39c2e8f6edfe663b90963b98eb79e2d4f7f28a5053ae8881",
856 "567a6b4426f1667136bed4a5e32a2bc1",
857 );
858 }
859
860 #[cfg(not(boringssl))]
861 fn aes_ccm(
862 cipher: &CipherRef,
863 key: &'static str,
864 iv: &'static str,
865 pt: &'static str,
866 aad: &'static str,
867 ct: &'static str,
868 tag: &'static str,
869 ) {
870 let key = hex::decode(key).unwrap();
871 let iv = hex::decode(iv).unwrap();
872 let pt = hex::decode(pt).unwrap();
873 let ct = hex::decode(ct).unwrap();
874 let aad = hex::decode(aad).unwrap();
875 let tag = hex::decode(tag).unwrap();
876
877 let mut ctx = CipherCtx::new().unwrap();
878
879 ctx.encrypt_init(Some(cipher), None, None).unwrap();
880 ctx.set_iv_length(iv.len()).unwrap();
881 ctx.set_tag_length(tag.len()).unwrap();
882 ctx.encrypt_init(None, Some(&key), Some(&iv)).unwrap();
883 ctx.set_data_len(pt.len()).unwrap();
884
885 let mut buf = vec![];
886 ctx.cipher_update(&aad, None).unwrap();
887 ctx.cipher_update_vec(&pt, &mut buf).unwrap();
888 ctx.cipher_final_vec(&mut buf).unwrap();
889 assert_eq!(buf, ct);
890
891 let mut out_tag = vec![0u8; tag.len()];
892 ctx.tag(&mut out_tag).unwrap();
893 assert_eq!(tag, out_tag);
894
895 ctx.decrypt_init(Some(cipher), None, None).unwrap();
896 ctx.set_iv_length(iv.len()).unwrap();
897 ctx.set_tag(&tag).unwrap();
898 ctx.decrypt_init(None, Some(&key), Some(&iv)).unwrap();
899 ctx.set_data_len(pt.len()).unwrap();
900
901 let mut buf = vec![];
902 ctx.cipher_update(&aad, None).unwrap();
903 ctx.cipher_update_vec(&ct, &mut buf).unwrap();
904 #[cfg(any(ossl111, awslc, boringssl))]
907 ctx.cipher_final_vec(&mut buf).unwrap();
908
909 assert_eq!(buf, pt);
910 }
911
912 #[cfg(not(any(boringssl, awslc)))]
913 #[test]
914 fn default_aes_128_xts() {
915 let cipher = Cipher::aes_128_xts();
917 aes_xts(
918 cipher,
919 "a1b90cba3f06ac353b2c343876081762090923026e91771815f29dab01932f2f",
920 "4faef7117cda59c66e4b92013e768ad5",
921 "ebabce95b14d3c8d6fb350390790311c",
922 "778ae8b43cb98d5a825081d5be471c63",
923 );
924 }
925
926 #[cfg(not(boringssl))]
927 #[test]
928 fn default_aes_256_xts() {
929 let cipher = Cipher::aes_256_xts();
931 aes_xts(cipher, "1ea661c58d943a0e4801e42f4b0947149e7f9f8e3e68d0c7505210bd311a0e7cd6e13ffdf2418d8d1911c004cda58da3d619b7e2b9141e58318eea392cf41b08", "adf8d92627464ad2f0428e84a9f87564", "2eedea52cd8215e1acc647e810bbc3642e87287f8d2e57e36c0a24fbc12a202e", "cbaad0e2f6cea3f50b37f934d46a9b130b9d54f07e34f36af793e86f73c6d7db");
932 }
933
934 #[cfg(not(boringssl))]
935 fn aes_xts(
936 cipher: &CipherRef,
937 key: &'static str,
938 i: &'static str,
939 pt: &'static str,
940 ct: &'static str,
941 ) {
942 let key = hex::decode(key).unwrap();
943 let i = hex::decode(i).unwrap();
944 let pt = hex::decode(pt).unwrap();
945 let ct = hex::decode(ct).unwrap();
946
947 let mut ctx = CipherCtx::new().unwrap();
948 ctx.encrypt_init(Some(cipher), Some(&key), Some(&i))
949 .unwrap();
950 let mut buf = vec![];
951 ctx.cipher_update_vec(&pt, &mut buf).unwrap();
952 ctx.cipher_final_vec(&mut buf).unwrap();
953
954 assert_eq!(ct, buf);
955
956 ctx.decrypt_init(Some(cipher), Some(&key), Some(&i))
957 .unwrap();
958 let mut buf = vec![];
959 ctx.cipher_update_vec(&ct, &mut buf).unwrap();
960 ctx.cipher_final_vec(&mut buf).unwrap();
961
962 assert_eq!(pt, buf);
963 }
964
965 #[test]
966 fn test_stream_ciphers() {
967 #[cfg(not(boringssl))]
968 {
969 test_stream_cipher(Cipher::aes_128_cfb1());
970 test_stream_cipher(Cipher::aes_128_cfb8());
971 test_stream_cipher(Cipher::aes_128_cfb128());
972 test_stream_cipher(Cipher::aes_192_cfb1());
973 test_stream_cipher(Cipher::aes_192_cfb8());
974 test_stream_cipher(Cipher::aes_192_cfb128());
975 test_stream_cipher(Cipher::aes_256_cfb1());
976 test_stream_cipher(Cipher::aes_256_cfb8());
977 test_stream_cipher(Cipher::aes_256_cfb128());
978 }
979 test_stream_cipher(Cipher::aes_192_ctr());
980 test_stream_cipher(Cipher::aes_256_ctr());
981 }
982
983 fn test_stream_cipher(cipher: &'static CipherRef) {
984 let mut key = vec![0; cipher.key_length()];
985 rand_bytes(&mut key).unwrap();
986 let mut iv = vec![0; cipher.iv_length()];
987 rand_bytes(&mut iv).unwrap();
988
989 let mut ctx = CipherCtx::new().unwrap();
990
991 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
992 .unwrap();
993 ctx.set_padding(false);
994
995 assert_eq!(
996 1,
997 cipher.block_size(),
998 "Need a stream cipher, not a block cipher"
999 );
1000
1001 let mut output = vec![0; 32];
1005 let outlen = ctx
1006 .cipher_update(&[1; 15], Some(&mut output[0..15]))
1007 .unwrap();
1008 assert_eq!(15, outlen);
1009
1010 let outlen = ctx
1014 .cipher_update(&[1; 17], Some(&mut output[15..]))
1015 .unwrap();
1016 assert_eq!(17, outlen);
1017
1018 ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
1019
1020 ctx.encrypt_init(None, None, Some(&iv)).unwrap();
1023 ctx.set_padding(false);
1024 let mut data_inplace: [u8; 32] = [1; 32];
1025 let outlen = ctx
1026 .cipher_update_inplace(&mut data_inplace[0..15], 15)
1027 .unwrap();
1028 assert_eq!(15, outlen);
1029
1030 let outlen = ctx
1031 .cipher_update_inplace(&mut data_inplace[15..32], 17)
1032 .unwrap();
1033 assert_eq!(17, outlen);
1034
1035 ctx.cipher_final(&mut [0u8; 0]).unwrap();
1036
1037 assert_eq!(data_inplace.as_slice(), output.as_slice());
1039
1040 ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv))
1042 .unwrap();
1043 ctx.set_padding(false);
1044
1045 let mut output_decrypted = vec![0; 32];
1049 let outlen = ctx
1050 .cipher_update(&output[0..15], Some(&mut output_decrypted[0..15]))
1051 .unwrap();
1052 assert_eq!(15, outlen);
1053
1054 let outlen = ctx
1055 .cipher_update(&output[15..], Some(&mut output_decrypted[15..]))
1056 .unwrap();
1057 assert_eq!(17, outlen);
1058
1059 ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
1060 assert_eq!(output_decrypted, vec![1; 32]);
1062
1063 ctx.decrypt_init(None, None, Some(&iv)).unwrap();
1065 ctx.set_padding(false);
1066
1067 let outlen = ctx.cipher_update_inplace(&mut output[0..15], 15).unwrap();
1068 assert_eq!(15, outlen);
1069
1070 let outlen = ctx.cipher_update_inplace(&mut output[15..], 17).unwrap();
1071 assert_eq!(17, outlen);
1072
1073 ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
1074 assert_eq!(output_decrypted, output);
1075 }
1076
1077 #[test]
1078 #[should_panic(expected = "Output buffer size should be at least 33 bytes.")]
1079 fn full_block_updates_aes_128() {
1080 output_buffer_too_small(Cipher::aes_128_cbc());
1081 }
1082
1083 #[test]
1084 #[should_panic(expected = "Output buffer size should be at least 33 bytes.")]
1085 fn full_block_updates_aes_256() {
1086 output_buffer_too_small(Cipher::aes_256_cbc());
1087 }
1088
1089 #[test]
1090 #[should_panic(expected = "Output buffer size should be at least 17 bytes.")]
1091 fn full_block_updates_3des() {
1092 output_buffer_too_small(Cipher::des_ede3_cbc());
1093 }
1094
1095 fn output_buffer_too_small(cipher: &'static CipherRef) {
1096 let mut key = vec![0; cipher.key_length()];
1097 rand_bytes(&mut key).unwrap();
1098 let mut iv = vec![0; cipher.iv_length()];
1099 rand_bytes(&mut iv).unwrap();
1100
1101 let mut ctx = CipherCtx::new().unwrap();
1102
1103 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
1104 .unwrap();
1105 ctx.set_padding(false);
1106
1107 let block_size = cipher.block_size();
1108 assert!(block_size > 1, "Need a block cipher, not a stream cipher");
1109
1110 ctx.cipher_update(&vec![0; block_size + 1], Some(&mut vec![0; block_size - 1]))
1111 .unwrap();
1112 }
1113
1114 #[cfg(ossl102)]
1115 fn cipher_wrap_test(cipher: &CipherRef, pt: &str, ct: &str, key: &str, iv: Option<&str>) {
1116 let pt = hex::decode(pt).unwrap();
1117 let key = hex::decode(key).unwrap();
1118 let expected = hex::decode(ct).unwrap();
1119 let iv = iv.map(|v| hex::decode(v).unwrap());
1120 let padding = 8 - pt.len() % 8;
1121 let mut computed = vec![0; pt.len() + padding + cipher.block_size() * 2];
1122 let mut ctx = CipherCtx::new().unwrap();
1123
1124 ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW);
1125 ctx.encrypt_init(Some(cipher), Some(&key), iv.as_deref())
1126 .unwrap();
1127
1128 let count = ctx.cipher_update(&pt, Some(&mut computed)).unwrap();
1129 let rest = ctx.cipher_final(&mut computed[count..]).unwrap();
1130 computed.truncate(count + rest);
1131
1132 if computed != expected {
1133 println!("Computed: {}", hex::encode(&computed));
1134 println!("Expected: {}", hex::encode(&expected));
1135 if computed.len() != expected.len() {
1136 println!(
1137 "Lengths differ: {} in computed vs {} expected",
1138 computed.len(),
1139 expected.len()
1140 );
1141 }
1142 panic!("test failure");
1143 }
1144 }
1145
1146 #[test]
1147 #[cfg(ossl102)]
1148 fn test_aes128_wrap() {
1149 let pt = "00112233445566778899aabbccddeeff";
1150 let ct = "7940ff694448b5bb5139c959a4896832e55d69aa04daa27e";
1151 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1152 let iv = "0001020304050607";
1153
1154 cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, Some(iv));
1155 }
1156
1157 #[test]
1158 #[cfg(ossl102)]
1159 fn test_aes128_wrap_default_iv() {
1160 let pt = "00112233445566778899aabbccddeeff";
1161 let ct = "38f1215f0212526f8a70b51955b9fbdc9fe3041d9832306e";
1162 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1163
1164 cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, None);
1165 }
1166
1167 #[test]
1168 #[cfg(ossl110)]
1169 fn test_aes128_wrap_pad() {
1170 let pt = "00112233445566778899aabbccddee";
1171 let ct = "f13998f5ab32ef82a1bdbcbe585e1d837385b529572a1e1b";
1172 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1173 let iv = "00010203";
1174
1175 cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, Some(iv));
1176 }
1177
1178 #[test]
1179 #[cfg(ossl110)]
1180 fn test_aes128_wrap_pad_default_iv() {
1181 let pt = "00112233445566778899aabbccddee";
1182 let ct = "3a501085fb8cf66f4186b7df851914d471ed823411598add";
1183 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1184
1185 cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, None);
1186 }
1187
1188 #[test]
1189 #[cfg(ossl102)]
1190 fn test_aes192_wrap() {
1191 let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b";
1192 let ct = "83b89142dfeeb4871e078bfb81134d33e23fedc19b03a1cf689973d3831b6813";
1193 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1194 let iv = "0001020304050607";
1195
1196 cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, Some(iv));
1197 }
1198
1199 #[test]
1200 #[cfg(ossl102)]
1201 fn test_aes192_wrap_default_iv() {
1202 let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b";
1203 let ct = "c02c2cf11505d3e4851030d5534cbf5a1d7eca7ba8839adbf239756daf1b43e6";
1204 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1205
1206 cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, None);
1207 }
1208
1209 #[test]
1210 #[cfg(ossl110)]
1211 fn test_aes192_wrap_pad() {
1212 let pt = "00112233445566778899aabbccddee";
1213 let ct = "b4f6bb167ef7caf061a74da82b36ad038ca057ab51e98d3a";
1214 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1215 let iv = "00010203";
1216
1217 cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, Some(iv));
1218 }
1219
1220 #[test]
1221 #[cfg(ossl110)]
1222 fn test_aes192_wrap_pad_default_iv() {
1223 let pt = "00112233445566778899aabbccddee";
1224 let ct = "b2c37a28cc602753a7c944a4c2555a2df9c98b2eded5312e";
1225 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1226
1227 cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, None);
1228 }
1229
1230 #[test]
1231 #[cfg(ossl102)]
1232 fn test_aes256_wrap() {
1233 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51";
1234 let ct = "cc05da2a7f56f7dd0c144231f90bce58648fa20a8278f5a6b7d13bba6aa57a33229d4333866b7fd6";
1235 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1236 let iv = "0001020304050607";
1237
1238 cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, Some(iv));
1239 }
1240
1241 #[test]
1242 #[cfg(ossl102)]
1243 fn test_aes256_wrap_default_iv() {
1244 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51";
1245 let ct = "0b24f068b50e52bc6987868411c36e1b03900866ed12af81eb87cef70a8d1911731c1d7abf789d88";
1246 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1247
1248 cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, None);
1249 }
1250
1251 #[test]
1252 #[cfg(ossl110)]
1253 fn test_aes256_wrap_pad() {
1254 let pt = "00112233445566778899aabbccddee";
1255 let ct = "91594e044ccc06130d60e6c84a996aa4f96a9faff8c5f6e7";
1256 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1257 let iv = "00010203";
1258
1259 cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, Some(iv));
1260 }
1261
1262 #[test]
1263 #[cfg(ossl110)]
1264 fn test_aes256_wrap_pad_default_iv() {
1265 let pt = "00112233445566778899aabbccddee";
1266 let ct = "dc3c166a854afd68aea624a4272693554bf2e4fcbae602cd";
1267 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1268
1269 cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, None);
1270 }
1271}