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 block_size = self.block_size();
671 if block_size != 1 {
672 assert!(
673 data.len() >= inlen + block_size,
674 "Output buffer size must be at least {} bytes.",
675 inlen + block_size
676 );
677 }
678
679 let inlen = c_int::try_from(inlen).unwrap();
680 let mut outlen = 0;
681 unsafe {
682 cvt(ffi::EVP_CipherUpdate(
683 self.as_ptr(),
684 data.as_mut_ptr(),
685 &mut outlen,
686 data.as_ptr(),
687 inlen,
688 ))
689 }?;
690
691 Ok(outlen as usize)
692 }
693
694 #[corresponds(EVP_CipherFinal)]
704 pub fn cipher_final(&mut self, output: &mut [u8]) -> Result<usize, ErrorStack> {
705 let block_size = self.block_size();
706 if block_size > 1 {
707 assert!(output.len() >= block_size);
708 }
709
710 unsafe { self.cipher_final_unchecked(output) }
711 }
712
713 #[corresponds(EVP_CipherFinal)]
729 pub unsafe fn cipher_final_unchecked(
730 &mut self,
731 output: &mut [u8],
732 ) -> Result<usize, ErrorStack> {
733 let mut outl = 0;
734
735 cvt(ffi::EVP_CipherFinal(
736 self.as_ptr(),
737 output.as_mut_ptr(),
738 &mut outl,
739 ))?;
740
741 Ok(outl as usize)
742 }
743
744 pub fn cipher_final_vec(&mut self, output: &mut Vec<u8>) -> Result<usize, ErrorStack> {
746 let base = output.len();
747 output.resize(base + self.block_size(), 0);
748 let len = self.cipher_final(&mut output[base..])?;
749 output.truncate(base + len);
750
751 Ok(len)
752 }
753}
754
755#[cfg(test)]
756mod test {
757 use super::*;
758 use crate::{cipher::Cipher, rand::rand_bytes};
759 #[cfg(not(any(boringssl, awslc)))]
760 use std::slice;
761
762 #[test]
763 #[cfg(not(any(boringssl, awslc)))]
764 fn seal_open() {
765 let private_pem = include_bytes!("../test/rsa.pem");
766 let public_pem = include_bytes!("../test/rsa.pem.pub");
767 let private_key = PKey::private_key_from_pem(private_pem).unwrap();
768 let public_key = PKey::public_key_from_pem(public_pem).unwrap();
769 let cipher = Cipher::aes_256_cbc();
770 let secret = b"My secret message";
771
772 let mut ctx = CipherCtx::new().unwrap();
773 let mut encrypted_key = vec![];
774 let mut iv = vec![0; cipher.iv_length()];
775 let mut encrypted = vec![];
776 ctx.seal_init(
777 Some(cipher),
778 &[public_key],
779 slice::from_mut(&mut encrypted_key),
780 Some(&mut iv),
781 )
782 .unwrap();
783 ctx.cipher_update_vec(secret, &mut encrypted).unwrap();
784 ctx.cipher_final_vec(&mut encrypted).unwrap();
785
786 let mut decrypted = vec![];
787 ctx.open_init(Some(cipher), &encrypted_key, Some(&iv), Some(&private_key))
788 .unwrap();
789 ctx.cipher_update_vec(&encrypted, &mut decrypted).unwrap();
790 ctx.cipher_final_vec(&mut decrypted).unwrap();
791
792 assert_eq!(secret, &decrypted[..]);
793 }
794
795 fn aes_128_cbc(cipher: &CipherRef) {
796 let key = hex::decode("2b7e151628aed2a6abf7158809cf4f3c").unwrap();
798 let iv = hex::decode("000102030405060708090a0b0c0d0e0f").unwrap();
799 let pt = hex::decode("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51")
800 .unwrap();
801 let ct = hex::decode("7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b2")
802 .unwrap();
803
804 let mut ctx = CipherCtx::new().unwrap();
805
806 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
807 .unwrap();
808 ctx.set_padding(false);
809
810 let mut buf = vec![];
811 ctx.cipher_update_vec(&pt, &mut buf).unwrap();
812 ctx.cipher_final_vec(&mut buf).unwrap();
813
814 assert_eq!(buf, ct);
815
816 ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv))
817 .unwrap();
818 ctx.set_padding(false);
819
820 let mut buf = vec![];
821 ctx.cipher_update_vec(&ct, &mut buf).unwrap();
822 ctx.cipher_final_vec(&mut buf).unwrap();
823
824 assert_eq!(buf, pt);
825 }
826
827 #[test]
828 #[cfg(ossl300)]
829 fn fetched_aes_128_cbc() {
830 let cipher = Cipher::fetch(None, "AES-128-CBC", None).unwrap();
831 aes_128_cbc(&cipher);
832 }
833
834 #[test]
835 fn default_aes_128_cbc() {
836 let cipher = Cipher::aes_128_cbc();
837 aes_128_cbc(cipher);
838 }
839
840 #[cfg(not(boringssl))]
841 #[test]
842 fn default_aes_128_ccm() {
843 let cipher = Cipher::aes_128_ccm();
845 aes_ccm(
846 cipher,
847 "26511fb51fcfa75cb4b44da75a6e5a0e",
848 "ea98ec44f5a86715014783172e",
849 "4da40b80579c1d9a5309f7efecb7c059a2f914511ca5fc10",
850 "e4692b9f06b666c7451b146c8aeb07a6e30c629d28065c3dde5940325b14b810",
851 "1bf0ba0ebb20d8edba59f29a9371750c9c714078f73c335d",
852 "2f1322ac69b848b001476323aed84c47",
853 );
854 }
855
856 #[cfg(not(boringssl))]
857 #[test]
858 fn default_aes_192_ccm() {
859 let cipher = Cipher::aes_192_ccm();
861 aes_ccm(
862 cipher,
863 "26511fb51fcfa75cb4b44da75a6e5a0eb8d9c8f3b906f886",
864 "ea98ec44f5a86715014783172e",
865 "4da40b80579c1d9a5309f7efecb7c059a2f914511ca5fc10",
866 "e4692b9f06b666c7451b146c8aeb07a6e30c629d28065c3dde5940325b14b810",
867 "30c154c616946eccc2e241d336ad33720953e449a0e6b0f0",
868 "dbf8e9464909bdf337e48093c082a10b",
869 );
870 }
871
872 #[cfg(not(boringssl))]
873 #[test]
874 fn default_aes_256_ccm() {
875 let cipher = Cipher::aes_256_ccm();
877 aes_ccm(
878 cipher,
879 "314a202f836f9f257e22d8c11757832ae5131d357a72df88f3eff0ffcee0da4e",
880 "3542fbe0f59a6d5f3abf619b7d",
881 "c5b3d71312ea14f2f8fae5bd1a453192b6604a45db75c5ed",
882 "dd4531f158a2fa3bc8a339f770595048f4a42bc1b03f2e824efc6ba4985119d8",
883 "39c2e8f6edfe663b90963b98eb79e2d4f7f28a5053ae8881",
884 "567a6b4426f1667136bed4a5e32a2bc1",
885 );
886 }
887
888 #[cfg(not(boringssl))]
889 fn aes_ccm(
890 cipher: &CipherRef,
891 key: &'static str,
892 iv: &'static str,
893 pt: &'static str,
894 aad: &'static str,
895 ct: &'static str,
896 tag: &'static str,
897 ) {
898 let key = hex::decode(key).unwrap();
899 let iv = hex::decode(iv).unwrap();
900 let pt = hex::decode(pt).unwrap();
901 let ct = hex::decode(ct).unwrap();
902 let aad = hex::decode(aad).unwrap();
903 let tag = hex::decode(tag).unwrap();
904
905 let mut ctx = CipherCtx::new().unwrap();
906
907 ctx.encrypt_init(Some(cipher), None, None).unwrap();
908 ctx.set_iv_length(iv.len()).unwrap();
909 ctx.set_tag_length(tag.len()).unwrap();
910 ctx.encrypt_init(None, Some(&key), Some(&iv)).unwrap();
911 ctx.set_data_len(pt.len()).unwrap();
912
913 let mut buf = vec![];
914 ctx.cipher_update(&aad, None).unwrap();
915 ctx.cipher_update_vec(&pt, &mut buf).unwrap();
916 ctx.cipher_final_vec(&mut buf).unwrap();
917 assert_eq!(buf, ct);
918
919 let mut out_tag = vec![0u8; tag.len()];
920 ctx.tag(&mut out_tag).unwrap();
921 assert_eq!(tag, out_tag);
922
923 ctx.decrypt_init(Some(cipher), None, None).unwrap();
924 ctx.set_iv_length(iv.len()).unwrap();
925 ctx.set_tag(&tag).unwrap();
926 ctx.decrypt_init(None, Some(&key), Some(&iv)).unwrap();
927 ctx.set_data_len(pt.len()).unwrap();
928
929 let mut buf = vec![];
930 ctx.cipher_update(&aad, None).unwrap();
931 ctx.cipher_update_vec(&ct, &mut buf).unwrap();
932 #[cfg(any(ossl111, awslc, boringssl))]
935 ctx.cipher_final_vec(&mut buf).unwrap();
936
937 assert_eq!(buf, pt);
938 }
939
940 #[cfg(not(any(boringssl, awslc)))]
941 #[test]
942 fn default_aes_128_xts() {
943 let cipher = Cipher::aes_128_xts();
945 aes_xts(
946 cipher,
947 "a1b90cba3f06ac353b2c343876081762090923026e91771815f29dab01932f2f",
948 "4faef7117cda59c66e4b92013e768ad5",
949 "ebabce95b14d3c8d6fb350390790311c",
950 "778ae8b43cb98d5a825081d5be471c63",
951 );
952 }
953
954 #[cfg(not(boringssl))]
955 #[test]
956 fn default_aes_256_xts() {
957 let cipher = Cipher::aes_256_xts();
959 aes_xts(cipher, "1ea661c58d943a0e4801e42f4b0947149e7f9f8e3e68d0c7505210bd311a0e7cd6e13ffdf2418d8d1911c004cda58da3d619b7e2b9141e58318eea392cf41b08", "adf8d92627464ad2f0428e84a9f87564", "2eedea52cd8215e1acc647e810bbc3642e87287f8d2e57e36c0a24fbc12a202e", "cbaad0e2f6cea3f50b37f934d46a9b130b9d54f07e34f36af793e86f73c6d7db");
960 }
961
962 #[cfg(not(boringssl))]
963 fn aes_xts(
964 cipher: &CipherRef,
965 key: &'static str,
966 i: &'static str,
967 pt: &'static str,
968 ct: &'static str,
969 ) {
970 let key = hex::decode(key).unwrap();
971 let i = hex::decode(i).unwrap();
972 let pt = hex::decode(pt).unwrap();
973 let ct = hex::decode(ct).unwrap();
974
975 let mut ctx = CipherCtx::new().unwrap();
976 ctx.encrypt_init(Some(cipher), Some(&key), Some(&i))
977 .unwrap();
978 let mut buf = vec![];
979 ctx.cipher_update_vec(&pt, &mut buf).unwrap();
980 ctx.cipher_final_vec(&mut buf).unwrap();
981
982 assert_eq!(ct, buf);
983
984 ctx.decrypt_init(Some(cipher), Some(&key), Some(&i))
985 .unwrap();
986 let mut buf = vec![];
987 ctx.cipher_update_vec(&ct, &mut buf).unwrap();
988 ctx.cipher_final_vec(&mut buf).unwrap();
989
990 assert_eq!(pt, buf);
991 }
992
993 #[test]
994 fn test_stream_ciphers() {
995 #[cfg(not(boringssl))]
996 {
997 test_stream_cipher(Cipher::aes_128_cfb1());
998 test_stream_cipher(Cipher::aes_128_cfb8());
999 test_stream_cipher(Cipher::aes_128_cfb128());
1000 test_stream_cipher(Cipher::aes_192_cfb1());
1001 test_stream_cipher(Cipher::aes_192_cfb8());
1002 test_stream_cipher(Cipher::aes_192_cfb128());
1003 test_stream_cipher(Cipher::aes_256_cfb1());
1004 test_stream_cipher(Cipher::aes_256_cfb8());
1005 test_stream_cipher(Cipher::aes_256_cfb128());
1006 }
1007 test_stream_cipher(Cipher::aes_192_ctr());
1008 test_stream_cipher(Cipher::aes_256_ctr());
1009 }
1010
1011 fn test_stream_cipher(cipher: &'static CipherRef) {
1012 let mut key = vec![0; cipher.key_length()];
1013 rand_bytes(&mut key).unwrap();
1014 let mut iv = vec![0; cipher.iv_length()];
1015 rand_bytes(&mut iv).unwrap();
1016
1017 let mut ctx = CipherCtx::new().unwrap();
1018
1019 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
1020 .unwrap();
1021 ctx.set_padding(false);
1022
1023 assert_eq!(
1024 1,
1025 cipher.block_size(),
1026 "Need a stream cipher, not a block cipher"
1027 );
1028
1029 let mut output = vec![0; 32];
1033 let outlen = ctx
1034 .cipher_update(&[1; 15], Some(&mut output[0..15]))
1035 .unwrap();
1036 assert_eq!(15, outlen);
1037
1038 let outlen = ctx
1042 .cipher_update(&[1; 17], Some(&mut output[15..]))
1043 .unwrap();
1044 assert_eq!(17, outlen);
1045
1046 ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
1047
1048 ctx.encrypt_init(None, None, Some(&iv)).unwrap();
1051 ctx.set_padding(false);
1052 let mut data_inplace: [u8; 32] = [1; 32];
1053 let outlen = ctx
1054 .cipher_update_inplace(&mut data_inplace[0..15], 15)
1055 .unwrap();
1056 assert_eq!(15, outlen);
1057
1058 let outlen = ctx
1059 .cipher_update_inplace(&mut data_inplace[15..32], 17)
1060 .unwrap();
1061 assert_eq!(17, outlen);
1062
1063 ctx.cipher_final(&mut [0u8; 0]).unwrap();
1064
1065 assert_eq!(data_inplace.as_slice(), output.as_slice());
1067
1068 ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv))
1070 .unwrap();
1071 ctx.set_padding(false);
1072
1073 let mut output_decrypted = vec![0; 32];
1077 let outlen = ctx
1078 .cipher_update(&output[0..15], Some(&mut output_decrypted[0..15]))
1079 .unwrap();
1080 assert_eq!(15, outlen);
1081
1082 let outlen = ctx
1083 .cipher_update(&output[15..], Some(&mut output_decrypted[15..]))
1084 .unwrap();
1085 assert_eq!(17, outlen);
1086
1087 ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
1088 assert_eq!(output_decrypted, vec![1; 32]);
1090
1091 ctx.decrypt_init(None, None, Some(&iv)).unwrap();
1093 ctx.set_padding(false);
1094
1095 let outlen = ctx.cipher_update_inplace(&mut output[0..15], 15).unwrap();
1096 assert_eq!(15, outlen);
1097
1098 let outlen = ctx.cipher_update_inplace(&mut output[15..], 17).unwrap();
1099 assert_eq!(17, outlen);
1100
1101 ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
1102 assert_eq!(output_decrypted, output);
1103 }
1104
1105 #[test]
1106 #[should_panic(expected = "Output buffer size should be at least 33 bytes.")]
1107 fn full_block_updates_aes_128() {
1108 output_buffer_too_small(Cipher::aes_128_cbc());
1109 }
1110
1111 #[test]
1112 #[should_panic(expected = "Output buffer size should be at least 33 bytes.")]
1113 fn full_block_updates_aes_256() {
1114 output_buffer_too_small(Cipher::aes_256_cbc());
1115 }
1116
1117 #[test]
1118 #[should_panic(expected = "Output buffer size should be at least 17 bytes.")]
1119 fn full_block_updates_3des() {
1120 output_buffer_too_small(Cipher::des_ede3_cbc());
1121 }
1122
1123 fn output_buffer_too_small(cipher: &'static CipherRef) {
1124 let mut key = vec![0; cipher.key_length()];
1125 rand_bytes(&mut key).unwrap();
1126 let mut iv = vec![0; cipher.iv_length()];
1127 rand_bytes(&mut iv).unwrap();
1128
1129 let mut ctx = CipherCtx::new().unwrap();
1130
1131 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
1132 .unwrap();
1133 ctx.set_padding(false);
1134
1135 let block_size = cipher.block_size();
1136 assert!(block_size > 1, "Need a block cipher, not a stream cipher");
1137
1138 ctx.cipher_update(&vec![0; block_size + 1], Some(&mut vec![0; block_size - 1]))
1139 .unwrap();
1140 }
1141
1142 #[cfg(ossl110)]
1143 fn cipher_wrap_test(cipher: &CipherRef, pt: &str, ct: &str, key: &str, iv: Option<&str>) {
1144 let pt = hex::decode(pt).unwrap();
1145 let key = hex::decode(key).unwrap();
1146 let expected = hex::decode(ct).unwrap();
1147 let iv = iv.map(|v| hex::decode(v).unwrap());
1148 let padding = 8 - pt.len() % 8;
1149 let mut computed = vec![0; pt.len() + padding + cipher.block_size() * 2];
1150 let mut ctx = CipherCtx::new().unwrap();
1151
1152 ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW);
1153 ctx.encrypt_init(Some(cipher), Some(&key), iv.as_deref())
1154 .unwrap();
1155
1156 let count = ctx.cipher_update(&pt, Some(&mut computed)).unwrap();
1157 let rest = ctx.cipher_final(&mut computed[count..]).unwrap();
1158 computed.truncate(count + rest);
1159
1160 if computed != expected {
1161 println!("Computed: {}", hex::encode(&computed));
1162 println!("Expected: {}", hex::encode(&expected));
1163 if computed.len() != expected.len() {
1164 println!(
1165 "Lengths differ: {} in computed vs {} expected",
1166 computed.len(),
1167 expected.len()
1168 );
1169 }
1170 panic!("test failure");
1171 }
1172 }
1173
1174 #[test]
1175 #[cfg(ossl110)]
1176 fn test_aes128_wrap() {
1177 let pt = "00112233445566778899aabbccddeeff";
1178 let ct = "7940ff694448b5bb5139c959a4896832e55d69aa04daa27e";
1179 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1180 let iv = "0001020304050607";
1181
1182 cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, Some(iv));
1183 }
1184
1185 #[test]
1186 #[cfg(ossl110)]
1187 fn test_aes128_wrap_default_iv() {
1188 let pt = "00112233445566778899aabbccddeeff";
1189 let ct = "38f1215f0212526f8a70b51955b9fbdc9fe3041d9832306e";
1190 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1191
1192 cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, None);
1193 }
1194
1195 #[test]
1196 #[cfg(ossl110)]
1197 fn test_aes128_wrap_pad() {
1198 let pt = "00112233445566778899aabbccddee";
1199 let ct = "f13998f5ab32ef82a1bdbcbe585e1d837385b529572a1e1b";
1200 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1201 let iv = "00010203";
1202
1203 cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, Some(iv));
1204 }
1205
1206 #[test]
1207 #[cfg(ossl110)]
1208 fn test_aes128_wrap_pad_default_iv() {
1209 let pt = "00112233445566778899aabbccddee";
1210 let ct = "3a501085fb8cf66f4186b7df851914d471ed823411598add";
1211 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1212
1213 cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, None);
1214 }
1215
1216 #[test]
1217 #[cfg(ossl110)]
1218 fn test_aes192_wrap() {
1219 let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b";
1220 let ct = "83b89142dfeeb4871e078bfb81134d33e23fedc19b03a1cf689973d3831b6813";
1221 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1222 let iv = "0001020304050607";
1223
1224 cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, Some(iv));
1225 }
1226
1227 #[test]
1228 #[cfg(ossl110)]
1229 fn test_aes192_wrap_default_iv() {
1230 let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b";
1231 let ct = "c02c2cf11505d3e4851030d5534cbf5a1d7eca7ba8839adbf239756daf1b43e6";
1232 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1233
1234 cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, None);
1235 }
1236
1237 #[test]
1238 #[cfg(ossl110)]
1239 fn test_aes192_wrap_pad() {
1240 let pt = "00112233445566778899aabbccddee";
1241 let ct = "b4f6bb167ef7caf061a74da82b36ad038ca057ab51e98d3a";
1242 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1243 let iv = "00010203";
1244
1245 cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, Some(iv));
1246 }
1247
1248 #[test]
1249 #[cfg(ossl110)]
1250 fn test_aes192_wrap_pad_default_iv() {
1251 let pt = "00112233445566778899aabbccddee";
1252 let ct = "b2c37a28cc602753a7c944a4c2555a2df9c98b2eded5312e";
1253 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1254
1255 cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, None);
1256 }
1257
1258 #[test]
1259 #[cfg(ossl110)]
1260 fn test_aes256_wrap() {
1261 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51";
1262 let ct = "cc05da2a7f56f7dd0c144231f90bce58648fa20a8278f5a6b7d13bba6aa57a33229d4333866b7fd6";
1263 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1264 let iv = "0001020304050607";
1265
1266 cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, Some(iv));
1267 }
1268
1269 #[test]
1270 #[cfg(ossl110)]
1271 fn test_aes256_wrap_default_iv() {
1272 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51";
1273 let ct = "0b24f068b50e52bc6987868411c36e1b03900866ed12af81eb87cef70a8d1911731c1d7abf789d88";
1274 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1275
1276 cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, None);
1277 }
1278
1279 #[test]
1280 #[cfg(ossl110)]
1281 fn test_aes256_wrap_pad() {
1282 let pt = "00112233445566778899aabbccddee";
1283 let ct = "91594e044ccc06130d60e6c84a996aa4f96a9faff8c5f6e7";
1284 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1285 let iv = "00010203";
1286
1287 cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, Some(iv));
1288 }
1289
1290 #[test]
1291 #[cfg(ossl110)]
1292 fn test_aes256_wrap_pad_default_iv() {
1293 let pt = "00112233445566778899aabbccddee";
1294 let ct = "dc3c166a854afd68aea624a4272693554bf2e4fcbae602cd";
1295 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1296
1297 cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, None);
1298 }
1299
1300 #[test]
1301 #[cfg(ossl110)]
1302 fn test_aes_wrap_pad_cipher_update_vec_buffer_size() {
1303 let cipher = Cipher::aes_256_wrap_pad();
1304 let key = [0u8; 32];
1305 let iv = [0u8; 4];
1306 let pt = [0u8; 9];
1307
1308 let mut ctx = CipherCtx::new().unwrap();
1309 ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW);
1310 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
1311 .unwrap();
1312
1313 let mut out = vec![];
1314 let len = ctx.cipher_update_vec(&pt, &mut out).unwrap();
1315 assert!(out.capacity() >= len);
1317 assert_eq!(len, 24);
1318 }
1319}