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_reset)]
112 #[cfg(any(ossl110, libressl350))]
113 #[inline]
114 pub fn reset(&mut self) -> Result<(), ErrorStack> {
115 unsafe {
116 let _ = cvt(ffi::EVP_CIPHER_CTX_reset(self.as_ptr()))?;
117 Ok(())
118 }
119 }
120
121 #[corresponds(EVP_CIPHER_CTX_reset)]
125 #[cfg(any(boringssl, awslc))]
126 #[inline]
127 pub fn reset(&mut self) -> Result<(), ErrorStack> {
128 unsafe {
129 ffi::EVP_CIPHER_CTX_reset(self.as_ptr());
130 Ok(())
131 }
132 }
133
134 #[corresponds(EVP_CIPHER_CTX_copy)]
135 pub fn copy(&mut self, src: &CipherCtxRef) -> Result<(), ErrorStack> {
136 unsafe {
137 cvt(ffi::EVP_CIPHER_CTX_copy(self.as_ptr(), src.as_ptr()))?;
138 Ok(())
139 }
140 }
141
142 #[corresponds(EVP_EncryptInit_ex)]
153 pub fn encrypt_init(
154 &mut self,
155 type_: Option<&CipherRef>,
156 key: Option<&[u8]>,
157 iv: Option<&[u8]>,
158 ) -> Result<(), ErrorStack> {
159 self.cipher_init(type_, key, iv, ffi::EVP_EncryptInit_ex)
160 }
161
162 #[corresponds(EVP_DecryptInit_ex)]
173 pub fn decrypt_init(
174 &mut self,
175 type_: Option<&CipherRef>,
176 key: Option<&[u8]>,
177 iv: Option<&[u8]>,
178 ) -> Result<(), ErrorStack> {
179 self.cipher_init(type_, key, iv, ffi::EVP_DecryptInit_ex)
180 }
181
182 fn cipher_init(
183 &mut self,
184 type_: Option<&CipherRef>,
185 key: Option<&[u8]>,
186 iv: Option<&[u8]>,
187 f: unsafe extern "C" fn(
188 *mut ffi::EVP_CIPHER_CTX,
189 *const ffi::EVP_CIPHER,
190 *mut ffi::ENGINE,
191 *const c_uchar,
192 *const c_uchar,
193 ) -> c_int,
194 ) -> Result<(), ErrorStack> {
195 if let Some(key) = key {
196 let key_len = type_.map_or_else(|| self.key_length(), |c| c.key_length());
197 assert!(key_len <= key.len());
198 }
199
200 if let Some(iv) = iv {
201 let iv_len = type_.map_or_else(|| self.iv_length(), |c| c.iv_length());
202 assert!(iv_len <= iv.len());
203 }
204
205 unsafe {
206 cvt(f(
207 self.as_ptr(),
208 type_.map_or(ptr::null(), |p| p.as_ptr()),
209 ptr::null_mut(),
210 key.map_or(ptr::null(), |k| k.as_ptr()),
211 iv.map_or(ptr::null(), |iv| iv.as_ptr()),
212 ))?;
213 }
214
215 Ok(())
216 }
217
218 #[corresponds(EVP_SealInit)]
231 #[cfg(not(any(boringssl, awslc)))]
232 pub fn seal_init<T>(
233 &mut self,
234 type_: Option<&CipherRef>,
235 pub_keys: &[PKey<T>],
236 encrypted_keys: &mut [Vec<u8>],
237 iv: Option<&mut [u8]>,
238 ) -> Result<(), ErrorStack>
239 where
240 T: HasPublic,
241 {
242 assert_eq!(pub_keys.len(), encrypted_keys.len());
243 if !pub_keys.is_empty() {
244 let iv_len = type_.map_or_else(|| self.iv_length(), |c| c.iv_length());
245 assert!(iv.as_ref().map_or(0, |b| b.len()) >= iv_len);
246 }
247
248 for (pub_key, buf) in pub_keys.iter().zip(&mut *encrypted_keys) {
249 buf.resize(pub_key.size(), 0);
250 }
251
252 let mut keys = encrypted_keys
253 .iter_mut()
254 .map(|b| b.as_mut_ptr())
255 .collect::<Vec<_>>();
256 let mut key_lengths = vec![0; pub_keys.len()];
257 let pub_keys_len = i32::try_from(pub_keys.len()).unwrap();
258
259 unsafe {
260 cvt(ffi::EVP_SealInit(
261 self.as_ptr(),
262 type_.map_or(ptr::null(), |p| p.as_ptr()),
263 keys.as_mut_ptr(),
264 key_lengths.as_mut_ptr(),
265 iv.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
266 pub_keys.as_ptr() as *mut _,
267 pub_keys_len,
268 ))?;
269 }
270
271 for (buf, len) in encrypted_keys.iter_mut().zip(key_lengths) {
272 buf.truncate(len as usize);
273 }
274
275 Ok(())
276 }
277
278 #[corresponds(EVP_OpenInit)]
288 #[cfg(not(any(boringssl, awslc)))]
289 pub fn open_init<T>(
290 &mut self,
291 type_: Option<&CipherRef>,
292 encrypted_key: &[u8],
293 iv: Option<&[u8]>,
294 priv_key: Option<&PKeyRef<T>>,
295 ) -> Result<(), ErrorStack>
296 where
297 T: HasPrivate,
298 {
299 if priv_key.is_some() {
300 let iv_len = type_.map_or_else(|| self.iv_length(), |c| c.iv_length());
301 assert!(iv.map_or(0, |b| b.len()) >= iv_len);
302 }
303
304 let len = c_int::try_from(encrypted_key.len()).unwrap();
305 unsafe {
306 cvt(ffi::EVP_OpenInit(
307 self.as_ptr(),
308 type_.map_or(ptr::null(), |p| p.as_ptr()),
309 encrypted_key.as_ptr(),
310 len,
311 iv.map_or(ptr::null(), |b| b.as_ptr()),
312 priv_key.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr),
313 ))?;
314 }
315
316 Ok(())
317 }
318
319 fn assert_cipher(&self) {
320 unsafe {
321 assert!(!EVP_CIPHER_CTX_get0_cipher(self.as_ptr()).is_null());
322 }
323 }
324
325 #[corresponds(EVP_CIPHER_CTX_block_size)]
333 pub fn block_size(&self) -> usize {
334 self.assert_cipher();
335
336 unsafe { ffi::EVP_CIPHER_CTX_block_size(self.as_ptr()) as usize }
337 }
338
339 #[corresponds(EVP_CIPHER_CTX_key_length)]
345 pub fn key_length(&self) -> usize {
346 self.assert_cipher();
347
348 unsafe { ffi::EVP_CIPHER_CTX_key_length(self.as_ptr()) as usize }
349 }
350
351 #[corresponds(EVP_CIPHER_CTX_rand_key)]
358 #[cfg(not(any(boringssl, awslc)))]
359 pub fn rand_key(&self, buf: &mut [u8]) -> Result<(), ErrorStack> {
360 assert!(buf.len() >= self.key_length());
361
362 unsafe {
363 cvt(ffi::EVP_CIPHER_CTX_rand_key(
364 self.as_ptr(),
365 buf.as_mut_ptr(),
366 ))?;
367 }
368
369 Ok(())
370 }
371
372 #[corresponds(EVP_CIPHER_CTX_set_key_length)]
380 pub fn set_key_length(&mut self, len: usize) -> Result<(), ErrorStack> {
381 self.assert_cipher();
382
383 unsafe {
384 cvt(ffi::EVP_CIPHER_CTX_set_key_length(
385 self.as_ptr(),
386 len.try_into().unwrap(),
387 ))?;
388 }
389
390 Ok(())
391 }
392
393 #[corresponds(EVP_CIPHER_CTX_iv_length)]
401 pub fn iv_length(&self) -> usize {
402 self.assert_cipher();
403
404 unsafe { ffi::EVP_CIPHER_CTX_iv_length(self.as_ptr()) as usize }
405 }
406
407 #[corresponds(EVP_CIPHER_CTX_num)]
416 #[cfg(ossl110)]
417 pub fn num(&self) -> usize {
418 self.assert_cipher();
419
420 unsafe { ffi::EVP_CIPHER_CTX_num(self.as_ptr()) as usize }
421 }
422
423 #[corresponds(EVP_CIPHER_CTX_ctrl)]
431 pub fn set_iv_length(&mut self, len: usize) -> Result<(), ErrorStack> {
432 self.assert_cipher();
433
434 let len = c_int::try_from(len).unwrap();
435
436 unsafe {
437 cvt(ffi::EVP_CIPHER_CTX_ctrl(
438 self.as_ptr(),
439 ffi::EVP_CTRL_GCM_SET_IVLEN,
440 len,
441 ptr::null_mut(),
442 ))?;
443 }
444
445 Ok(())
446 }
447
448 #[corresponds(EVP_CIPHER_CTX_get_tag_length)]
458 #[cfg(ossl300)]
459 pub fn tag_length(&self) -> usize {
460 self.assert_cipher();
461
462 unsafe { ffi::EVP_CIPHER_CTX_get_tag_length(self.as_ptr()) as usize }
463 }
464
465 #[corresponds(EVP_CIPHER_CTX_ctrl)]
472 pub fn tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> {
473 let len = c_int::try_from(tag.len()).unwrap();
474
475 unsafe {
476 cvt(ffi::EVP_CIPHER_CTX_ctrl(
477 self.as_ptr(),
478 ffi::EVP_CTRL_GCM_GET_TAG,
479 len,
480 tag.as_mut_ptr() as *mut _,
481 ))?;
482 }
483
484 Ok(())
485 }
486
487 #[corresponds(EVP_CIPHER_CTX_ctrl)]
491 pub fn set_tag_length(&mut self, len: usize) -> Result<(), ErrorStack> {
492 let len = c_int::try_from(len).unwrap();
493
494 unsafe {
495 cvt(ffi::EVP_CIPHER_CTX_ctrl(
496 self.as_ptr(),
497 ffi::EVP_CTRL_GCM_SET_TAG,
498 len,
499 ptr::null_mut(),
500 ))?;
501 }
502
503 Ok(())
504 }
505
506 #[corresponds(EVP_CIPHER_CTX_ctrl)]
508 pub fn set_tag(&mut self, tag: &[u8]) -> Result<(), ErrorStack> {
509 let len = c_int::try_from(tag.len()).unwrap();
510
511 unsafe {
512 cvt(ffi::EVP_CIPHER_CTX_ctrl(
513 self.as_ptr(),
514 ffi::EVP_CTRL_GCM_SET_TAG,
515 len,
516 tag.as_ptr() as *mut _,
517 ))?;
518 }
519
520 Ok(())
521 }
522
523 #[corresponds(EVP_CIPHER_CTX_set_padding)]
527 pub fn set_padding(&mut self, padding: bool) {
528 unsafe {
529 ffi::EVP_CIPHER_CTX_set_padding(self.as_ptr(), padding as c_int);
530 }
531 }
532
533 #[corresponds(EVP_CipherUpdate)]
537 pub fn set_data_len(&mut self, len: usize) -> Result<(), ErrorStack> {
538 let len = c_int::try_from(len).unwrap();
539
540 unsafe {
541 cvt(ffi::EVP_CipherUpdate(
542 self.as_ptr(),
543 ptr::null_mut(),
544 &mut 0,
545 ptr::null(),
546 len,
547 ))?;
548 }
549
550 Ok(())
551 }
552
553 #[corresponds(EVP_CIPHER_CTX_set_flags)]
557 #[cfg(ossl102)]
558 pub fn set_flags(&mut self, flags: CipherCtxFlags) {
559 unsafe {
560 ffi::EVP_CIPHER_CTX_set_flags(self.as_ptr(), flags.bits());
561 }
562 }
563
564 #[corresponds(EVP_CipherUpdate)]
575 pub fn cipher_update(
576 &mut self,
577 input: &[u8],
578 output: Option<&mut [u8]>,
579 ) -> Result<usize, ErrorStack> {
580 if let Some(output) = &output {
581 let mut block_size = self.block_size();
582 if block_size == 1 {
583 block_size = 0;
584 }
585 let min_output_size = input.len() + block_size;
586 assert!(
587 output.len() >= min_output_size,
588 "Output buffer size should be at least {} bytes.",
589 min_output_size
590 );
591 }
592
593 unsafe { self.cipher_update_unchecked(input, output) }
594 }
595
596 #[corresponds(EVP_CipherUpdate)]
614 pub unsafe fn cipher_update_unchecked(
615 &mut self,
616 input: &[u8],
617 output: Option<&mut [u8]>,
618 ) -> Result<usize, ErrorStack> {
619 let inlen = c_int::try_from(input.len()).unwrap();
620
621 let mut outlen = 0;
622
623 cvt(ffi::EVP_CipherUpdate(
624 self.as_ptr(),
625 output.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
626 &mut outlen,
627 input.as_ptr(),
628 inlen,
629 ))?;
630
631 Ok(outlen as usize)
632 }
633
634 pub fn cipher_update_vec(
636 &mut self,
637 input: &[u8],
638 output: &mut Vec<u8>,
639 ) -> Result<usize, ErrorStack> {
640 let base = output.len();
641 output.resize(base + input.len() + self.block_size(), 0);
642 let len = self.cipher_update(input, Some(&mut output[base..]))?;
643 output.truncate(base + len);
644
645 Ok(len)
646 }
647
648 #[corresponds(EVP_CipherUpdate)]
662 pub fn cipher_update_inplace(
663 &mut self,
664 data: &mut [u8],
665 inlen: usize,
666 ) -> Result<usize, ErrorStack> {
667 assert!(inlen <= data.len(), "Input size may not exceed buffer size");
668 let block_size = self.block_size();
669 if block_size != 1 {
670 assert!(
671 data.len() >= inlen + block_size,
672 "Output buffer size must be at least {} bytes.",
673 inlen + block_size
674 );
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(ossl102)]
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(ossl102)]
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(ossl102)]
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(ossl102)]
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(ossl102)]
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(ossl102)]
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(ossl102)]
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}