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(ossl110)]
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(ossl110)]
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 #[cfg(not(any(boringssl, awslc)))]
300 fn is_wrap_mode(&self) -> bool {
301 unsafe {
302 let cipher = EVP_CIPHER_CTX_get0_cipher(self.as_ptr());
303 if cipher.is_null() {
304 return false;
305 }
306 ffi::EVP_CIPHER_flags(cipher) & ffi::EVP_CIPH_MODE == ffi::EVP_CIPH_WRAP_MODE
307 }
308 }
309
310 #[cfg(any(boringssl, awslc))]
311 fn is_wrap_mode(&self) -> bool {
312 false
313 }
314
315 fn cipher_update_output_size(&self, input_len: usize) -> usize {
316 if self.is_wrap_mode() {
322 return input_len.saturating_add(7) / 8 * 8 + 8;
323 }
324 let mut block_size = self.block_size();
325 if block_size == 1 {
326 block_size = 0;
327 }
328 input_len + block_size
329 }
330
331 #[corresponds(EVP_CIPHER_CTX_block_size)]
339 pub fn block_size(&self) -> usize {
340 self.assert_cipher();
341
342 unsafe { ffi::EVP_CIPHER_CTX_block_size(self.as_ptr()) as usize }
343 }
344
345 #[corresponds(EVP_CIPHER_CTX_key_length)]
351 pub fn key_length(&self) -> usize {
352 self.assert_cipher();
353
354 unsafe { ffi::EVP_CIPHER_CTX_key_length(self.as_ptr()) as usize }
355 }
356
357 #[corresponds(EVP_CIPHER_CTX_rand_key)]
364 #[cfg(not(any(boringssl, awslc)))]
365 pub fn rand_key(&self, buf: &mut [u8]) -> Result<(), ErrorStack> {
366 assert!(buf.len() >= self.key_length());
367
368 unsafe {
369 cvt(ffi::EVP_CIPHER_CTX_rand_key(
370 self.as_ptr(),
371 buf.as_mut_ptr(),
372 ))?;
373 }
374
375 Ok(())
376 }
377
378 #[corresponds(EVP_CIPHER_CTX_set_key_length)]
386 pub fn set_key_length(&mut self, len: usize) -> Result<(), ErrorStack> {
387 self.assert_cipher();
388
389 unsafe {
390 cvt(ffi::EVP_CIPHER_CTX_set_key_length(
391 self.as_ptr(),
392 len.try_into().unwrap(),
393 ))?;
394 }
395
396 Ok(())
397 }
398
399 #[corresponds(EVP_CIPHER_CTX_iv_length)]
407 pub fn iv_length(&self) -> usize {
408 self.assert_cipher();
409
410 unsafe { ffi::EVP_CIPHER_CTX_iv_length(self.as_ptr()) as usize }
411 }
412
413 #[corresponds(EVP_CIPHER_CTX_num)]
422 #[cfg(ossl110)]
423 pub fn num(&self) -> usize {
424 self.assert_cipher();
425
426 unsafe { ffi::EVP_CIPHER_CTX_num(self.as_ptr()) as usize }
427 }
428
429 #[corresponds(EVP_CIPHER_CTX_ctrl)]
437 pub fn set_iv_length(&mut self, len: usize) -> Result<(), ErrorStack> {
438 self.assert_cipher();
439
440 let len = c_int::try_from(len).unwrap();
441
442 unsafe {
443 cvt(ffi::EVP_CIPHER_CTX_ctrl(
444 self.as_ptr(),
445 ffi::EVP_CTRL_GCM_SET_IVLEN,
446 len,
447 ptr::null_mut(),
448 ))?;
449 }
450
451 Ok(())
452 }
453
454 #[corresponds(EVP_CIPHER_CTX_get_tag_length)]
464 #[cfg(ossl300)]
465 pub fn tag_length(&self) -> usize {
466 self.assert_cipher();
467
468 unsafe { ffi::EVP_CIPHER_CTX_get_tag_length(self.as_ptr()) as usize }
469 }
470
471 #[corresponds(EVP_CIPHER_CTX_ctrl)]
478 pub fn tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> {
479 let len = c_int::try_from(tag.len()).unwrap();
480
481 unsafe {
482 cvt(ffi::EVP_CIPHER_CTX_ctrl(
483 self.as_ptr(),
484 ffi::EVP_CTRL_GCM_GET_TAG,
485 len,
486 tag.as_mut_ptr() as *mut _,
487 ))?;
488 }
489
490 Ok(())
491 }
492
493 #[corresponds(EVP_CIPHER_CTX_ctrl)]
497 pub fn set_tag_length(&mut self, len: usize) -> Result<(), ErrorStack> {
498 let len = c_int::try_from(len).unwrap();
499
500 unsafe {
501 cvt(ffi::EVP_CIPHER_CTX_ctrl(
502 self.as_ptr(),
503 ffi::EVP_CTRL_GCM_SET_TAG,
504 len,
505 ptr::null_mut(),
506 ))?;
507 }
508
509 Ok(())
510 }
511
512 #[corresponds(EVP_CIPHER_CTX_ctrl)]
514 pub fn set_tag(&mut self, tag: &[u8]) -> Result<(), ErrorStack> {
515 let len = c_int::try_from(tag.len()).unwrap();
516
517 unsafe {
518 cvt(ffi::EVP_CIPHER_CTX_ctrl(
519 self.as_ptr(),
520 ffi::EVP_CTRL_GCM_SET_TAG,
521 len,
522 tag.as_ptr() as *mut _,
523 ))?;
524 }
525
526 Ok(())
527 }
528
529 #[corresponds(EVP_CIPHER_CTX_set_padding)]
533 pub fn set_padding(&mut self, padding: bool) {
534 unsafe {
535 ffi::EVP_CIPHER_CTX_set_padding(self.as_ptr(), padding as c_int);
536 }
537 }
538
539 #[corresponds(EVP_CipherUpdate)]
543 pub fn set_data_len(&mut self, len: usize) -> Result<(), ErrorStack> {
544 let len = c_int::try_from(len).unwrap();
545
546 unsafe {
547 cvt(ffi::EVP_CipherUpdate(
548 self.as_ptr(),
549 ptr::null_mut(),
550 &mut 0,
551 ptr::null(),
552 len,
553 ))?;
554 }
555
556 Ok(())
557 }
558
559 #[corresponds(EVP_CIPHER_CTX_set_flags)]
563 #[cfg(ossl110)]
564 pub fn set_flags(&mut self, flags: CipherCtxFlags) {
565 unsafe {
566 ffi::EVP_CIPHER_CTX_set_flags(self.as_ptr(), flags.bits());
567 }
568 }
569
570 #[corresponds(EVP_CipherUpdate)]
581 pub fn cipher_update(
582 &mut self,
583 input: &[u8],
584 output: Option<&mut [u8]>,
585 ) -> Result<usize, ErrorStack> {
586 if let Some(output) = &output {
587 let min_output_size = self.cipher_update_output_size(input.len());
588 assert!(
589 output.len() >= min_output_size,
590 "Output buffer size should be at least {} bytes.",
591 min_output_size
592 );
593 }
594
595 unsafe { self.cipher_update_unchecked(input, output) }
596 }
597
598 #[corresponds(EVP_CipherUpdate)]
616 pub unsafe fn cipher_update_unchecked(
617 &mut self,
618 input: &[u8],
619 output: Option<&mut [u8]>,
620 ) -> Result<usize, ErrorStack> {
621 let inlen = c_int::try_from(input.len()).unwrap();
622
623 let mut outlen = 0;
624
625 cvt(ffi::EVP_CipherUpdate(
626 self.as_ptr(),
627 output.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
628 &mut outlen,
629 input.as_ptr(),
630 inlen,
631 ))?;
632
633 Ok(outlen as usize)
634 }
635
636 pub fn cipher_update_vec(
638 &mut self,
639 input: &[u8],
640 output: &mut Vec<u8>,
641 ) -> Result<usize, ErrorStack> {
642 let base = output.len();
643 output.resize(base + self.cipher_update_output_size(input.len()), 0);
644 let len = self.cipher_update(input, Some(&mut output[base..]))?;
645 output.truncate(base + len);
646
647 Ok(len)
648 }
649
650 #[corresponds(EVP_CipherUpdate)]
664 pub fn cipher_update_inplace(
665 &mut self,
666 data: &mut [u8],
667 inlen: usize,
668 ) -> Result<usize, ErrorStack> {
669 assert!(inlen <= data.len(), "Input size may not exceed buffer size");
670 let min_output_size = self.cipher_update_output_size(inlen);
671 assert!(
672 data.len() >= min_output_size,
673 "Output buffer size must be at least {} bytes.",
674 min_output_size
675 );
676
677 let inlen = c_int::try_from(inlen).unwrap();
678 let mut outlen = 0;
679 unsafe {
680 cvt(ffi::EVP_CipherUpdate(
681 self.as_ptr(),
682 data.as_mut_ptr(),
683 &mut outlen,
684 data.as_ptr(),
685 inlen,
686 ))
687 }?;
688
689 Ok(outlen as usize)
690 }
691
692 #[corresponds(EVP_CipherFinal)]
702 pub fn cipher_final(&mut self, output: &mut [u8]) -> Result<usize, ErrorStack> {
703 let block_size = self.block_size();
704 if block_size > 1 {
705 assert!(output.len() >= block_size);
706 }
707
708 unsafe { self.cipher_final_unchecked(output) }
709 }
710
711 #[corresponds(EVP_CipherFinal)]
727 pub unsafe fn cipher_final_unchecked(
728 &mut self,
729 output: &mut [u8],
730 ) -> Result<usize, ErrorStack> {
731 let mut outl = 0;
732
733 cvt(ffi::EVP_CipherFinal(
734 self.as_ptr(),
735 output.as_mut_ptr(),
736 &mut outl,
737 ))?;
738
739 Ok(outl as usize)
740 }
741
742 pub fn cipher_final_vec(&mut self, output: &mut Vec<u8>) -> Result<usize, ErrorStack> {
744 let base = output.len();
745 output.resize(base + self.block_size(), 0);
746 let len = self.cipher_final(&mut output[base..])?;
747 output.truncate(base + len);
748
749 Ok(len)
750 }
751}
752
753#[cfg(test)]
754mod test {
755 use super::*;
756 use crate::{cipher::Cipher, rand::rand_bytes};
757 #[cfg(not(any(boringssl, awslc)))]
758 use std::slice;
759
760 #[test]
761 #[cfg(not(any(boringssl, awslc)))]
762 fn seal_open() {
763 let private_pem = include_bytes!("../test/rsa.pem");
764 let public_pem = include_bytes!("../test/rsa.pem.pub");
765 let private_key = PKey::private_key_from_pem(private_pem).unwrap();
766 let public_key = PKey::public_key_from_pem(public_pem).unwrap();
767 let cipher = Cipher::aes_256_cbc();
768 let secret = b"My secret message";
769
770 let mut ctx = CipherCtx::new().unwrap();
771 let mut encrypted_key = vec![];
772 let mut iv = vec![0; cipher.iv_length()];
773 let mut encrypted = vec![];
774 ctx.seal_init(
775 Some(cipher),
776 &[public_key],
777 slice::from_mut(&mut encrypted_key),
778 Some(&mut iv),
779 )
780 .unwrap();
781 ctx.cipher_update_vec(secret, &mut encrypted).unwrap();
782 ctx.cipher_final_vec(&mut encrypted).unwrap();
783
784 let mut decrypted = vec![];
785 ctx.open_init(Some(cipher), &encrypted_key, Some(&iv), Some(&private_key))
786 .unwrap();
787 ctx.cipher_update_vec(&encrypted, &mut decrypted).unwrap();
788 ctx.cipher_final_vec(&mut decrypted).unwrap();
789
790 assert_eq!(secret, &decrypted[..]);
791 }
792
793 fn aes_128_cbc(cipher: &CipherRef) {
794 let key = hex::decode("2b7e151628aed2a6abf7158809cf4f3c").unwrap();
796 let iv = hex::decode("000102030405060708090a0b0c0d0e0f").unwrap();
797 let pt = hex::decode("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51")
798 .unwrap();
799 let ct = hex::decode("7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b2")
800 .unwrap();
801
802 let mut ctx = CipherCtx::new().unwrap();
803
804 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
805 .unwrap();
806 ctx.set_padding(false);
807
808 let mut buf = vec![];
809 ctx.cipher_update_vec(&pt, &mut buf).unwrap();
810 ctx.cipher_final_vec(&mut buf).unwrap();
811
812 assert_eq!(buf, ct);
813
814 ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv))
815 .unwrap();
816 ctx.set_padding(false);
817
818 let mut buf = vec![];
819 ctx.cipher_update_vec(&ct, &mut buf).unwrap();
820 ctx.cipher_final_vec(&mut buf).unwrap();
821
822 assert_eq!(buf, pt);
823 }
824
825 #[test]
826 #[cfg(ossl300)]
827 fn fetched_aes_128_cbc() {
828 let cipher = Cipher::fetch(None, "AES-128-CBC", None).unwrap();
829 aes_128_cbc(&cipher);
830 }
831
832 #[test]
833 fn default_aes_128_cbc() {
834 let cipher = Cipher::aes_128_cbc();
835 aes_128_cbc(cipher);
836 }
837
838 #[cfg(not(boringssl))]
839 #[test]
840 fn default_aes_128_ccm() {
841 let cipher = Cipher::aes_128_ccm();
843 aes_ccm(
844 cipher,
845 "26511fb51fcfa75cb4b44da75a6e5a0e",
846 "ea98ec44f5a86715014783172e",
847 "4da40b80579c1d9a5309f7efecb7c059a2f914511ca5fc10",
848 "e4692b9f06b666c7451b146c8aeb07a6e30c629d28065c3dde5940325b14b810",
849 "1bf0ba0ebb20d8edba59f29a9371750c9c714078f73c335d",
850 "2f1322ac69b848b001476323aed84c47",
851 );
852 }
853
854 #[cfg(not(boringssl))]
855 #[test]
856 fn default_aes_192_ccm() {
857 let cipher = Cipher::aes_192_ccm();
859 aes_ccm(
860 cipher,
861 "26511fb51fcfa75cb4b44da75a6e5a0eb8d9c8f3b906f886",
862 "ea98ec44f5a86715014783172e",
863 "4da40b80579c1d9a5309f7efecb7c059a2f914511ca5fc10",
864 "e4692b9f06b666c7451b146c8aeb07a6e30c629d28065c3dde5940325b14b810",
865 "30c154c616946eccc2e241d336ad33720953e449a0e6b0f0",
866 "dbf8e9464909bdf337e48093c082a10b",
867 );
868 }
869
870 #[cfg(not(boringssl))]
871 #[test]
872 fn default_aes_256_ccm() {
873 let cipher = Cipher::aes_256_ccm();
875 aes_ccm(
876 cipher,
877 "314a202f836f9f257e22d8c11757832ae5131d357a72df88f3eff0ffcee0da4e",
878 "3542fbe0f59a6d5f3abf619b7d",
879 "c5b3d71312ea14f2f8fae5bd1a453192b6604a45db75c5ed",
880 "dd4531f158a2fa3bc8a339f770595048f4a42bc1b03f2e824efc6ba4985119d8",
881 "39c2e8f6edfe663b90963b98eb79e2d4f7f28a5053ae8881",
882 "567a6b4426f1667136bed4a5e32a2bc1",
883 );
884 }
885
886 #[cfg(not(boringssl))]
887 fn aes_ccm(
888 cipher: &CipherRef,
889 key: &'static str,
890 iv: &'static str,
891 pt: &'static str,
892 aad: &'static str,
893 ct: &'static str,
894 tag: &'static str,
895 ) {
896 let key = hex::decode(key).unwrap();
897 let iv = hex::decode(iv).unwrap();
898 let pt = hex::decode(pt).unwrap();
899 let ct = hex::decode(ct).unwrap();
900 let aad = hex::decode(aad).unwrap();
901 let tag = hex::decode(tag).unwrap();
902
903 let mut ctx = CipherCtx::new().unwrap();
904
905 ctx.encrypt_init(Some(cipher), None, None).unwrap();
906 ctx.set_iv_length(iv.len()).unwrap();
907 ctx.set_tag_length(tag.len()).unwrap();
908 ctx.encrypt_init(None, Some(&key), Some(&iv)).unwrap();
909 ctx.set_data_len(pt.len()).unwrap();
910
911 let mut buf = vec![];
912 ctx.cipher_update(&aad, None).unwrap();
913 ctx.cipher_update_vec(&pt, &mut buf).unwrap();
914 ctx.cipher_final_vec(&mut buf).unwrap();
915 assert_eq!(buf, ct);
916
917 let mut out_tag = vec![0u8; tag.len()];
918 ctx.tag(&mut out_tag).unwrap();
919 assert_eq!(tag, out_tag);
920
921 ctx.decrypt_init(Some(cipher), None, None).unwrap();
922 ctx.set_iv_length(iv.len()).unwrap();
923 ctx.set_tag(&tag).unwrap();
924 ctx.decrypt_init(None, Some(&key), Some(&iv)).unwrap();
925 ctx.set_data_len(pt.len()).unwrap();
926
927 let mut buf = vec![];
928 ctx.cipher_update(&aad, None).unwrap();
929 ctx.cipher_update_vec(&ct, &mut buf).unwrap();
930 #[cfg(any(ossl111, awslc, boringssl))]
933 ctx.cipher_final_vec(&mut buf).unwrap();
934
935 assert_eq!(buf, pt);
936 }
937
938 #[cfg(not(any(boringssl, awslc)))]
939 #[test]
940 fn default_aes_128_xts() {
941 let cipher = Cipher::aes_128_xts();
943 aes_xts(
944 cipher,
945 "a1b90cba3f06ac353b2c343876081762090923026e91771815f29dab01932f2f",
946 "4faef7117cda59c66e4b92013e768ad5",
947 "ebabce95b14d3c8d6fb350390790311c",
948 "778ae8b43cb98d5a825081d5be471c63",
949 );
950 }
951
952 #[cfg(not(boringssl))]
953 #[test]
954 fn default_aes_256_xts() {
955 let cipher = Cipher::aes_256_xts();
957 aes_xts(cipher, "1ea661c58d943a0e4801e42f4b0947149e7f9f8e3e68d0c7505210bd311a0e7cd6e13ffdf2418d8d1911c004cda58da3d619b7e2b9141e58318eea392cf41b08", "adf8d92627464ad2f0428e84a9f87564", "2eedea52cd8215e1acc647e810bbc3642e87287f8d2e57e36c0a24fbc12a202e", "cbaad0e2f6cea3f50b37f934d46a9b130b9d54f07e34f36af793e86f73c6d7db");
958 }
959
960 #[cfg(not(boringssl))]
961 fn aes_xts(
962 cipher: &CipherRef,
963 key: &'static str,
964 i: &'static str,
965 pt: &'static str,
966 ct: &'static str,
967 ) {
968 let key = hex::decode(key).unwrap();
969 let i = hex::decode(i).unwrap();
970 let pt = hex::decode(pt).unwrap();
971 let ct = hex::decode(ct).unwrap();
972
973 let mut ctx = CipherCtx::new().unwrap();
974 ctx.encrypt_init(Some(cipher), Some(&key), Some(&i))
975 .unwrap();
976 let mut buf = vec![];
977 ctx.cipher_update_vec(&pt, &mut buf).unwrap();
978 ctx.cipher_final_vec(&mut buf).unwrap();
979
980 assert_eq!(ct, buf);
981
982 ctx.decrypt_init(Some(cipher), Some(&key), Some(&i))
983 .unwrap();
984 let mut buf = vec![];
985 ctx.cipher_update_vec(&ct, &mut buf).unwrap();
986 ctx.cipher_final_vec(&mut buf).unwrap();
987
988 assert_eq!(pt, buf);
989 }
990
991 #[test]
992 fn test_stream_ciphers() {
993 #[cfg(not(boringssl))]
994 {
995 test_stream_cipher(Cipher::aes_128_cfb1());
996 test_stream_cipher(Cipher::aes_128_cfb8());
997 test_stream_cipher(Cipher::aes_128_cfb128());
998 test_stream_cipher(Cipher::aes_192_cfb1());
999 test_stream_cipher(Cipher::aes_192_cfb8());
1000 test_stream_cipher(Cipher::aes_192_cfb128());
1001 test_stream_cipher(Cipher::aes_256_cfb1());
1002 test_stream_cipher(Cipher::aes_256_cfb8());
1003 test_stream_cipher(Cipher::aes_256_cfb128());
1004 }
1005 test_stream_cipher(Cipher::aes_192_ctr());
1006 test_stream_cipher(Cipher::aes_256_ctr());
1007 }
1008
1009 fn test_stream_cipher(cipher: &'static CipherRef) {
1010 let mut key = vec![0; cipher.key_length()];
1011 rand_bytes(&mut key).unwrap();
1012 let mut iv = vec![0; cipher.iv_length()];
1013 rand_bytes(&mut iv).unwrap();
1014
1015 let mut ctx = CipherCtx::new().unwrap();
1016
1017 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
1018 .unwrap();
1019 ctx.set_padding(false);
1020
1021 assert_eq!(
1022 1,
1023 cipher.block_size(),
1024 "Need a stream cipher, not a block cipher"
1025 );
1026
1027 let mut output = vec![0; 32];
1031 let outlen = ctx
1032 .cipher_update(&[1; 15], Some(&mut output[0..15]))
1033 .unwrap();
1034 assert_eq!(15, outlen);
1035
1036 let outlen = ctx
1040 .cipher_update(&[1; 17], Some(&mut output[15..]))
1041 .unwrap();
1042 assert_eq!(17, outlen);
1043
1044 ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
1045
1046 ctx.encrypt_init(None, None, Some(&iv)).unwrap();
1049 ctx.set_padding(false);
1050 let mut data_inplace: [u8; 32] = [1; 32];
1051 let outlen = ctx
1052 .cipher_update_inplace(&mut data_inplace[0..15], 15)
1053 .unwrap();
1054 assert_eq!(15, outlen);
1055
1056 let outlen = ctx
1057 .cipher_update_inplace(&mut data_inplace[15..32], 17)
1058 .unwrap();
1059 assert_eq!(17, outlen);
1060
1061 ctx.cipher_final(&mut [0u8; 0]).unwrap();
1062
1063 assert_eq!(data_inplace.as_slice(), output.as_slice());
1065
1066 ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv))
1068 .unwrap();
1069 ctx.set_padding(false);
1070
1071 let mut output_decrypted = vec![0; 32];
1075 let outlen = ctx
1076 .cipher_update(&output[0..15], Some(&mut output_decrypted[0..15]))
1077 .unwrap();
1078 assert_eq!(15, outlen);
1079
1080 let outlen = ctx
1081 .cipher_update(&output[15..], Some(&mut output_decrypted[15..]))
1082 .unwrap();
1083 assert_eq!(17, outlen);
1084
1085 ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
1086 assert_eq!(output_decrypted, vec![1; 32]);
1088
1089 ctx.decrypt_init(None, None, Some(&iv)).unwrap();
1091 ctx.set_padding(false);
1092
1093 let outlen = ctx.cipher_update_inplace(&mut output[0..15], 15).unwrap();
1094 assert_eq!(15, outlen);
1095
1096 let outlen = ctx.cipher_update_inplace(&mut output[15..], 17).unwrap();
1097 assert_eq!(17, outlen);
1098
1099 ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
1100 assert_eq!(output_decrypted, output);
1101 }
1102
1103 #[test]
1104 #[should_panic(expected = "Output buffer size should be at least 33 bytes.")]
1105 fn full_block_updates_aes_128() {
1106 output_buffer_too_small(Cipher::aes_128_cbc());
1107 }
1108
1109 #[test]
1110 #[should_panic(expected = "Output buffer size should be at least 33 bytes.")]
1111 fn full_block_updates_aes_256() {
1112 output_buffer_too_small(Cipher::aes_256_cbc());
1113 }
1114
1115 #[test]
1116 #[should_panic(expected = "Output buffer size should be at least 17 bytes.")]
1117 fn full_block_updates_3des() {
1118 output_buffer_too_small(Cipher::des_ede3_cbc());
1119 }
1120
1121 fn output_buffer_too_small(cipher: &'static CipherRef) {
1122 let mut key = vec![0; cipher.key_length()];
1123 rand_bytes(&mut key).unwrap();
1124 let mut iv = vec![0; cipher.iv_length()];
1125 rand_bytes(&mut iv).unwrap();
1126
1127 let mut ctx = CipherCtx::new().unwrap();
1128
1129 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
1130 .unwrap();
1131 ctx.set_padding(false);
1132
1133 let block_size = cipher.block_size();
1134 assert!(block_size > 1, "Need a block cipher, not a stream cipher");
1135
1136 ctx.cipher_update(&vec![0; block_size + 1], Some(&mut vec![0; block_size - 1]))
1137 .unwrap();
1138 }
1139
1140 #[cfg(ossl110)]
1141 fn cipher_wrap_test(cipher: &CipherRef, pt: &str, ct: &str, key: &str, iv: Option<&str>) {
1142 let pt = hex::decode(pt).unwrap();
1143 let key = hex::decode(key).unwrap();
1144 let expected = hex::decode(ct).unwrap();
1145 let iv = iv.map(|v| hex::decode(v).unwrap());
1146 let padding = 8 - pt.len() % 8;
1147 let mut computed = vec![0; pt.len() + padding + cipher.block_size() * 2];
1148 let mut ctx = CipherCtx::new().unwrap();
1149
1150 ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW);
1151 ctx.encrypt_init(Some(cipher), Some(&key), iv.as_deref())
1152 .unwrap();
1153
1154 let count = ctx.cipher_update(&pt, Some(&mut computed)).unwrap();
1155 let rest = ctx.cipher_final(&mut computed[count..]).unwrap();
1156 computed.truncate(count + rest);
1157
1158 if computed != expected {
1159 println!("Computed: {}", hex::encode(&computed));
1160 println!("Expected: {}", hex::encode(&expected));
1161 if computed.len() != expected.len() {
1162 println!(
1163 "Lengths differ: {} in computed vs {} expected",
1164 computed.len(),
1165 expected.len()
1166 );
1167 }
1168 panic!("test failure");
1169 }
1170 }
1171
1172 #[test]
1173 #[cfg(ossl110)]
1174 fn test_aes128_wrap() {
1175 let pt = "00112233445566778899aabbccddeeff";
1176 let ct = "7940ff694448b5bb5139c959a4896832e55d69aa04daa27e";
1177 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1178 let iv = "0001020304050607";
1179
1180 cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, Some(iv));
1181 }
1182
1183 #[test]
1184 #[cfg(ossl110)]
1185 fn test_aes128_wrap_default_iv() {
1186 let pt = "00112233445566778899aabbccddeeff";
1187 let ct = "38f1215f0212526f8a70b51955b9fbdc9fe3041d9832306e";
1188 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1189
1190 cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, None);
1191 }
1192
1193 #[test]
1194 #[cfg(ossl110)]
1195 fn test_aes128_wrap_pad() {
1196 let pt = "00112233445566778899aabbccddee";
1197 let ct = "f13998f5ab32ef82a1bdbcbe585e1d837385b529572a1e1b";
1198 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1199 let iv = "00010203";
1200
1201 cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, Some(iv));
1202 }
1203
1204 #[test]
1205 #[cfg(ossl110)]
1206 fn test_aes128_wrap_pad_default_iv() {
1207 let pt = "00112233445566778899aabbccddee";
1208 let ct = "3a501085fb8cf66f4186b7df851914d471ed823411598add";
1209 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1210
1211 cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, None);
1212 }
1213
1214 #[test]
1215 #[cfg(ossl110)]
1216 fn test_aes192_wrap() {
1217 let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b";
1218 let ct = "83b89142dfeeb4871e078bfb81134d33e23fedc19b03a1cf689973d3831b6813";
1219 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1220 let iv = "0001020304050607";
1221
1222 cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, Some(iv));
1223 }
1224
1225 #[test]
1226 #[cfg(ossl110)]
1227 fn test_aes192_wrap_default_iv() {
1228 let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b";
1229 let ct = "c02c2cf11505d3e4851030d5534cbf5a1d7eca7ba8839adbf239756daf1b43e6";
1230 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1231
1232 cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, None);
1233 }
1234
1235 #[test]
1236 #[cfg(ossl110)]
1237 fn test_aes192_wrap_pad() {
1238 let pt = "00112233445566778899aabbccddee";
1239 let ct = "b4f6bb167ef7caf061a74da82b36ad038ca057ab51e98d3a";
1240 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1241 let iv = "00010203";
1242
1243 cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, Some(iv));
1244 }
1245
1246 #[test]
1247 #[cfg(ossl110)]
1248 fn test_aes192_wrap_pad_default_iv() {
1249 let pt = "00112233445566778899aabbccddee";
1250 let ct = "b2c37a28cc602753a7c944a4c2555a2df9c98b2eded5312e";
1251 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1252
1253 cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, None);
1254 }
1255
1256 #[test]
1257 #[cfg(ossl110)]
1258 fn test_aes256_wrap() {
1259 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51";
1260 let ct = "cc05da2a7f56f7dd0c144231f90bce58648fa20a8278f5a6b7d13bba6aa57a33229d4333866b7fd6";
1261 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1262 let iv = "0001020304050607";
1263
1264 cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, Some(iv));
1265 }
1266
1267 #[test]
1268 #[cfg(ossl110)]
1269 fn test_aes256_wrap_default_iv() {
1270 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51";
1271 let ct = "0b24f068b50e52bc6987868411c36e1b03900866ed12af81eb87cef70a8d1911731c1d7abf789d88";
1272 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1273
1274 cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, None);
1275 }
1276
1277 #[test]
1278 #[cfg(ossl110)]
1279 fn test_aes256_wrap_pad() {
1280 let pt = "00112233445566778899aabbccddee";
1281 let ct = "91594e044ccc06130d60e6c84a996aa4f96a9faff8c5f6e7";
1282 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1283 let iv = "00010203";
1284
1285 cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, Some(iv));
1286 }
1287
1288 #[test]
1289 #[cfg(ossl110)]
1290 fn test_aes256_wrap_pad_default_iv() {
1291 let pt = "00112233445566778899aabbccddee";
1292 let ct = "dc3c166a854afd68aea624a4272693554bf2e4fcbae602cd";
1293 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1294
1295 cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, None);
1296 }
1297
1298 #[test]
1299 #[cfg(ossl110)]
1300 fn test_aes_wrap_pad_cipher_update_vec_buffer_size() {
1301 let cipher = Cipher::aes_256_wrap_pad();
1302 let key = [0u8; 32];
1303 let iv = [0u8; 4];
1304 let pt = [0u8; 9];
1305
1306 let mut ctx = CipherCtx::new().unwrap();
1307 ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW);
1308 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
1309 .unwrap();
1310
1311 let mut out = vec![];
1312 let len = ctx.cipher_update_vec(&pt, &mut out).unwrap();
1313 assert!(out.capacity() >= len);
1315 assert_eq!(len, 24);
1316 }
1317
1318 #[test]
1319 #[cfg(ossl110)]
1320 #[should_panic(expected = "Output buffer size must be at least 24 bytes.")]
1321 fn test_aes_wrap_pad_cipher_update_inplace_buffer_size() {
1322 let cipher = Cipher::aes_256_wrap_pad();
1323 let key = [0u8; 32];
1324 let iv = [0u8; 4];
1325
1326 let mut ctx = CipherCtx::new().unwrap();
1327 ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW);
1328 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
1329 .unwrap();
1330
1331 let mut buf = [0u8; 17];
1335 let _ = ctx.cipher_update_inplace(&mut buf, 9);
1336 }
1337}