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: &[u8]) -> Result<usize, ErrorStack> {
316 if self.is_wrap_mode() {
323 let inlen = c_int::try_from(input.len()).unwrap();
324 let mut outlen = 0;
325 unsafe {
326 cvt(ffi::EVP_CipherUpdate(
327 self.as_ptr(),
328 ptr::null_mut(),
329 &mut outlen,
330 input.as_ptr(),
331 inlen,
332 ))?;
333 }
334 return Ok(outlen as usize);
335 }
336 let mut block_size = self.block_size();
337 if block_size == 1 {
338 block_size = 0;
339 }
340 Ok(input.len() + block_size)
341 }
342
343 #[corresponds(EVP_CIPHER_CTX_block_size)]
351 pub fn block_size(&self) -> usize {
352 self.assert_cipher();
353
354 unsafe { ffi::EVP_CIPHER_CTX_block_size(self.as_ptr()) as usize }
355 }
356
357 #[corresponds(EVP_CIPHER_CTX_key_length)]
363 pub fn key_length(&self) -> usize {
364 self.assert_cipher();
365
366 unsafe { ffi::EVP_CIPHER_CTX_key_length(self.as_ptr()) as usize }
367 }
368
369 #[corresponds(EVP_CIPHER_CTX_rand_key)]
376 #[cfg(not(any(boringssl, awslc)))]
377 pub fn rand_key(&self, buf: &mut [u8]) -> Result<(), ErrorStack> {
378 assert!(buf.len() >= self.key_length());
379
380 unsafe {
381 cvt(ffi::EVP_CIPHER_CTX_rand_key(
382 self.as_ptr(),
383 buf.as_mut_ptr(),
384 ))?;
385 }
386
387 Ok(())
388 }
389
390 #[corresponds(EVP_CIPHER_CTX_set_key_length)]
398 pub fn set_key_length(&mut self, len: usize) -> Result<(), ErrorStack> {
399 self.assert_cipher();
400
401 unsafe {
402 cvt(ffi::EVP_CIPHER_CTX_set_key_length(
403 self.as_ptr(),
404 len.try_into().unwrap(),
405 ))?;
406 }
407
408 Ok(())
409 }
410
411 #[corresponds(EVP_CIPHER_CTX_iv_length)]
419 pub fn iv_length(&self) -> usize {
420 self.assert_cipher();
421
422 unsafe { ffi::EVP_CIPHER_CTX_iv_length(self.as_ptr()) as usize }
423 }
424
425 #[corresponds(EVP_CIPHER_CTX_num)]
434 #[cfg(ossl110)]
435 pub fn num(&self) -> usize {
436 self.assert_cipher();
437
438 unsafe { ffi::EVP_CIPHER_CTX_num(self.as_ptr()) as usize }
439 }
440
441 #[corresponds(EVP_CIPHER_CTX_ctrl)]
449 pub fn set_iv_length(&mut self, len: usize) -> Result<(), ErrorStack> {
450 self.assert_cipher();
451
452 let len = c_int::try_from(len).unwrap();
453
454 unsafe {
455 cvt(ffi::EVP_CIPHER_CTX_ctrl(
456 self.as_ptr(),
457 ffi::EVP_CTRL_GCM_SET_IVLEN,
458 len,
459 ptr::null_mut(),
460 ))?;
461 }
462
463 Ok(())
464 }
465
466 #[corresponds(EVP_CIPHER_CTX_get_tag_length)]
476 #[cfg(ossl300)]
477 pub fn tag_length(&self) -> usize {
478 self.assert_cipher();
479
480 unsafe { ffi::EVP_CIPHER_CTX_get_tag_length(self.as_ptr()) as usize }
481 }
482
483 #[corresponds(EVP_CIPHER_CTX_ctrl)]
490 pub fn tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> {
491 let len = c_int::try_from(tag.len()).unwrap();
492
493 unsafe {
494 cvt(ffi::EVP_CIPHER_CTX_ctrl(
495 self.as_ptr(),
496 ffi::EVP_CTRL_GCM_GET_TAG,
497 len,
498 tag.as_mut_ptr() as *mut _,
499 ))?;
500 }
501
502 Ok(())
503 }
504
505 #[corresponds(EVP_CIPHER_CTX_ctrl)]
509 pub fn set_tag_length(&mut self, len: usize) -> Result<(), ErrorStack> {
510 let len = c_int::try_from(len).unwrap();
511
512 unsafe {
513 cvt(ffi::EVP_CIPHER_CTX_ctrl(
514 self.as_ptr(),
515 ffi::EVP_CTRL_GCM_SET_TAG,
516 len,
517 ptr::null_mut(),
518 ))?;
519 }
520
521 Ok(())
522 }
523
524 #[corresponds(EVP_CIPHER_CTX_ctrl)]
526 pub fn set_tag(&mut self, tag: &[u8]) -> Result<(), ErrorStack> {
527 let len = c_int::try_from(tag.len()).unwrap();
528
529 unsafe {
530 cvt(ffi::EVP_CIPHER_CTX_ctrl(
531 self.as_ptr(),
532 ffi::EVP_CTRL_GCM_SET_TAG,
533 len,
534 tag.as_ptr() as *mut _,
535 ))?;
536 }
537
538 Ok(())
539 }
540
541 #[corresponds(EVP_CIPHER_CTX_set_padding)]
545 pub fn set_padding(&mut self, padding: bool) {
546 unsafe {
547 ffi::EVP_CIPHER_CTX_set_padding(self.as_ptr(), padding as c_int);
548 }
549 }
550
551 #[corresponds(EVP_CipherUpdate)]
555 pub fn set_data_len(&mut self, len: usize) -> Result<(), ErrorStack> {
556 let len = c_int::try_from(len).unwrap();
557
558 unsafe {
559 cvt(ffi::EVP_CipherUpdate(
560 self.as_ptr(),
561 ptr::null_mut(),
562 &mut 0,
563 ptr::null(),
564 len,
565 ))?;
566 }
567
568 Ok(())
569 }
570
571 #[corresponds(EVP_CIPHER_CTX_set_flags)]
575 #[cfg(ossl110)]
576 pub fn set_flags(&mut self, flags: CipherCtxFlags) {
577 unsafe {
578 ffi::EVP_CIPHER_CTX_set_flags(self.as_ptr(), flags.bits());
579 }
580 }
581
582 #[corresponds(EVP_CipherUpdate)]
593 pub fn cipher_update(
594 &mut self,
595 input: &[u8],
596 output: Option<&mut [u8]>,
597 ) -> Result<usize, ErrorStack> {
598 if let Some(output) = &output {
599 let min_output_size = self.cipher_update_output_size(input)?;
600 assert!(
601 output.len() >= min_output_size,
602 "Output buffer size should be at least {} bytes.",
603 min_output_size
604 );
605 }
606
607 unsafe { self.cipher_update_unchecked(input, output) }
608 }
609
610 #[corresponds(EVP_CipherUpdate)]
628 pub unsafe fn cipher_update_unchecked(
629 &mut self,
630 input: &[u8],
631 output: Option<&mut [u8]>,
632 ) -> Result<usize, ErrorStack> {
633 let inlen = c_int::try_from(input.len()).unwrap();
634
635 let mut outlen = 0;
636
637 cvt(ffi::EVP_CipherUpdate(
638 self.as_ptr(),
639 output.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
640 &mut outlen,
641 input.as_ptr(),
642 inlen,
643 ))?;
644
645 Ok(outlen as usize)
646 }
647
648 pub fn cipher_update_vec(
650 &mut self,
651 input: &[u8],
652 output: &mut Vec<u8>,
653 ) -> Result<usize, ErrorStack> {
654 let base = output.len();
655 output.resize(base + self.cipher_update_output_size(input)?, 0);
656 let len = self.cipher_update(input, Some(&mut output[base..]))?;
657 output.truncate(base + len);
658
659 Ok(len)
660 }
661
662 #[corresponds(EVP_CipherUpdate)]
676 pub fn cipher_update_inplace(
677 &mut self,
678 data: &mut [u8],
679 inlen: usize,
680 ) -> Result<usize, ErrorStack> {
681 assert!(inlen <= data.len(), "Input size may not exceed buffer size");
682 let min_output_size = self.cipher_update_output_size(&data[..inlen])?;
683 assert!(
684 data.len() >= min_output_size,
685 "Output buffer size must be at least {} bytes.",
686 min_output_size
687 );
688
689 let inlen = c_int::try_from(inlen).unwrap();
690 let mut outlen = 0;
691 unsafe {
692 cvt(ffi::EVP_CipherUpdate(
693 self.as_ptr(),
694 data.as_mut_ptr(),
695 &mut outlen,
696 data.as_ptr(),
697 inlen,
698 ))
699 }?;
700
701 Ok(outlen as usize)
702 }
703
704 #[corresponds(EVP_CipherFinal)]
714 pub fn cipher_final(&mut self, output: &mut [u8]) -> Result<usize, ErrorStack> {
715 let block_size = self.block_size();
716 if block_size > 1 {
717 assert!(output.len() >= block_size);
718 }
719
720 unsafe { self.cipher_final_unchecked(output) }
721 }
722
723 #[corresponds(EVP_CipherFinal)]
739 pub unsafe fn cipher_final_unchecked(
740 &mut self,
741 output: &mut [u8],
742 ) -> Result<usize, ErrorStack> {
743 let mut outl = 0;
744
745 cvt(ffi::EVP_CipherFinal(
746 self.as_ptr(),
747 output.as_mut_ptr(),
748 &mut outl,
749 ))?;
750
751 Ok(outl as usize)
752 }
753
754 pub fn cipher_final_vec(&mut self, output: &mut Vec<u8>) -> Result<usize, ErrorStack> {
756 let base = output.len();
757 output.resize(base + self.block_size(), 0);
758 let len = self.cipher_final(&mut output[base..])?;
759 output.truncate(base + len);
760
761 Ok(len)
762 }
763}
764
765#[cfg(test)]
766mod test {
767 use super::*;
768 #[cfg(ossl110)]
769 use crate::nid::Nid;
770 use crate::{cipher::Cipher, rand::rand_bytes};
771 #[cfg(not(any(boringssl, awslc)))]
772 use std::slice;
773
774 #[test]
775 #[cfg(not(any(boringssl, awslc)))]
776 fn seal_open() {
777 let private_pem = include_bytes!("../test/rsa.pem");
778 let public_pem = include_bytes!("../test/rsa.pem.pub");
779 let private_key = PKey::private_key_from_pem(private_pem).unwrap();
780 let public_key = PKey::public_key_from_pem(public_pem).unwrap();
781 let cipher = Cipher::aes_256_cbc();
782 let secret = b"My secret message";
783
784 let mut ctx = CipherCtx::new().unwrap();
785 let mut encrypted_key = vec![];
786 let mut iv = vec![0; cipher.iv_length()];
787 let mut encrypted = vec![];
788 ctx.seal_init(
789 Some(cipher),
790 &[public_key],
791 slice::from_mut(&mut encrypted_key),
792 Some(&mut iv),
793 )
794 .unwrap();
795 ctx.cipher_update_vec(secret, &mut encrypted).unwrap();
796 ctx.cipher_final_vec(&mut encrypted).unwrap();
797
798 let mut decrypted = vec![];
799 ctx.open_init(Some(cipher), &encrypted_key, Some(&iv), Some(&private_key))
800 .unwrap();
801 ctx.cipher_update_vec(&encrypted, &mut decrypted).unwrap();
802 ctx.cipher_final_vec(&mut decrypted).unwrap();
803
804 assert_eq!(secret, &decrypted[..]);
805 }
806
807 fn aes_128_cbc(cipher: &CipherRef) {
808 let key = hex::decode("2b7e151628aed2a6abf7158809cf4f3c").unwrap();
810 let iv = hex::decode("000102030405060708090a0b0c0d0e0f").unwrap();
811 let pt = hex::decode("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51")
812 .unwrap();
813 let ct = hex::decode("7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b2")
814 .unwrap();
815
816 let mut ctx = CipherCtx::new().unwrap();
817
818 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
819 .unwrap();
820 ctx.set_padding(false);
821
822 let mut buf = vec![];
823 ctx.cipher_update_vec(&pt, &mut buf).unwrap();
824 ctx.cipher_final_vec(&mut buf).unwrap();
825
826 assert_eq!(buf, ct);
827
828 ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv))
829 .unwrap();
830 ctx.set_padding(false);
831
832 let mut buf = vec![];
833 ctx.cipher_update_vec(&ct, &mut buf).unwrap();
834 ctx.cipher_final_vec(&mut buf).unwrap();
835
836 assert_eq!(buf, pt);
837 }
838
839 #[test]
840 #[cfg(ossl300)]
841 fn fetched_aes_128_cbc() {
842 let cipher = Cipher::fetch(None, "AES-128-CBC", None).unwrap();
843 aes_128_cbc(&cipher);
844 }
845
846 #[test]
847 fn default_aes_128_cbc() {
848 let cipher = Cipher::aes_128_cbc();
849 aes_128_cbc(cipher);
850 }
851
852 #[cfg(not(boringssl))]
853 #[test]
854 fn default_aes_128_ccm() {
855 let cipher = Cipher::aes_128_ccm();
857 aes_ccm(
858 cipher,
859 "26511fb51fcfa75cb4b44da75a6e5a0e",
860 "ea98ec44f5a86715014783172e",
861 "4da40b80579c1d9a5309f7efecb7c059a2f914511ca5fc10",
862 "e4692b9f06b666c7451b146c8aeb07a6e30c629d28065c3dde5940325b14b810",
863 "1bf0ba0ebb20d8edba59f29a9371750c9c714078f73c335d",
864 "2f1322ac69b848b001476323aed84c47",
865 );
866 }
867
868 #[cfg(not(boringssl))]
869 #[test]
870 fn default_aes_192_ccm() {
871 let cipher = Cipher::aes_192_ccm();
873 aes_ccm(
874 cipher,
875 "26511fb51fcfa75cb4b44da75a6e5a0eb8d9c8f3b906f886",
876 "ea98ec44f5a86715014783172e",
877 "4da40b80579c1d9a5309f7efecb7c059a2f914511ca5fc10",
878 "e4692b9f06b666c7451b146c8aeb07a6e30c629d28065c3dde5940325b14b810",
879 "30c154c616946eccc2e241d336ad33720953e449a0e6b0f0",
880 "dbf8e9464909bdf337e48093c082a10b",
881 );
882 }
883
884 #[cfg(not(boringssl))]
885 #[test]
886 fn default_aes_256_ccm() {
887 let cipher = Cipher::aes_256_ccm();
889 aes_ccm(
890 cipher,
891 "314a202f836f9f257e22d8c11757832ae5131d357a72df88f3eff0ffcee0da4e",
892 "3542fbe0f59a6d5f3abf619b7d",
893 "c5b3d71312ea14f2f8fae5bd1a453192b6604a45db75c5ed",
894 "dd4531f158a2fa3bc8a339f770595048f4a42bc1b03f2e824efc6ba4985119d8",
895 "39c2e8f6edfe663b90963b98eb79e2d4f7f28a5053ae8881",
896 "567a6b4426f1667136bed4a5e32a2bc1",
897 );
898 }
899
900 #[cfg(not(boringssl))]
901 fn aes_ccm(
902 cipher: &CipherRef,
903 key: &'static str,
904 iv: &'static str,
905 pt: &'static str,
906 aad: &'static str,
907 ct: &'static str,
908 tag: &'static str,
909 ) {
910 let key = hex::decode(key).unwrap();
911 let iv = hex::decode(iv).unwrap();
912 let pt = hex::decode(pt).unwrap();
913 let ct = hex::decode(ct).unwrap();
914 let aad = hex::decode(aad).unwrap();
915 let tag = hex::decode(tag).unwrap();
916
917 let mut ctx = CipherCtx::new().unwrap();
918
919 ctx.encrypt_init(Some(cipher), None, None).unwrap();
920 ctx.set_iv_length(iv.len()).unwrap();
921 ctx.set_tag_length(tag.len()).unwrap();
922 ctx.encrypt_init(None, Some(&key), Some(&iv)).unwrap();
923 ctx.set_data_len(pt.len()).unwrap();
924
925 let mut buf = vec![];
926 ctx.cipher_update(&aad, None).unwrap();
927 ctx.cipher_update_vec(&pt, &mut buf).unwrap();
928 ctx.cipher_final_vec(&mut buf).unwrap();
929 assert_eq!(buf, ct);
930
931 let mut out_tag = vec![0u8; tag.len()];
932 ctx.tag(&mut out_tag).unwrap();
933 assert_eq!(tag, out_tag);
934
935 ctx.decrypt_init(Some(cipher), None, None).unwrap();
936 ctx.set_iv_length(iv.len()).unwrap();
937 ctx.set_tag(&tag).unwrap();
938 ctx.decrypt_init(None, Some(&key), Some(&iv)).unwrap();
939 ctx.set_data_len(pt.len()).unwrap();
940
941 let mut buf = vec![];
942 ctx.cipher_update(&aad, None).unwrap();
943 ctx.cipher_update_vec(&ct, &mut buf).unwrap();
944 #[cfg(any(ossl111, awslc, boringssl))]
947 ctx.cipher_final_vec(&mut buf).unwrap();
948
949 assert_eq!(buf, pt);
950 }
951
952 #[cfg(not(any(boringssl, awslc)))]
953 #[test]
954 fn default_aes_128_xts() {
955 let cipher = Cipher::aes_128_xts();
957 aes_xts(
958 cipher,
959 "a1b90cba3f06ac353b2c343876081762090923026e91771815f29dab01932f2f",
960 "4faef7117cda59c66e4b92013e768ad5",
961 "ebabce95b14d3c8d6fb350390790311c",
962 "778ae8b43cb98d5a825081d5be471c63",
963 );
964 }
965
966 #[cfg(not(boringssl))]
967 #[test]
968 fn default_aes_256_xts() {
969 let cipher = Cipher::aes_256_xts();
971 aes_xts(cipher, "1ea661c58d943a0e4801e42f4b0947149e7f9f8e3e68d0c7505210bd311a0e7cd6e13ffdf2418d8d1911c004cda58da3d619b7e2b9141e58318eea392cf41b08", "adf8d92627464ad2f0428e84a9f87564", "2eedea52cd8215e1acc647e810bbc3642e87287f8d2e57e36c0a24fbc12a202e", "cbaad0e2f6cea3f50b37f934d46a9b130b9d54f07e34f36af793e86f73c6d7db");
972 }
973
974 #[cfg(not(boringssl))]
975 fn aes_xts(
976 cipher: &CipherRef,
977 key: &'static str,
978 i: &'static str,
979 pt: &'static str,
980 ct: &'static str,
981 ) {
982 let key = hex::decode(key).unwrap();
983 let i = hex::decode(i).unwrap();
984 let pt = hex::decode(pt).unwrap();
985 let ct = hex::decode(ct).unwrap();
986
987 let mut ctx = CipherCtx::new().unwrap();
988 ctx.encrypt_init(Some(cipher), Some(&key), Some(&i))
989 .unwrap();
990 let mut buf = vec![];
991 ctx.cipher_update_vec(&pt, &mut buf).unwrap();
992 ctx.cipher_final_vec(&mut buf).unwrap();
993
994 assert_eq!(ct, buf);
995
996 ctx.decrypt_init(Some(cipher), Some(&key), Some(&i))
997 .unwrap();
998 let mut buf = vec![];
999 ctx.cipher_update_vec(&ct, &mut buf).unwrap();
1000 ctx.cipher_final_vec(&mut buf).unwrap();
1001
1002 assert_eq!(pt, buf);
1003 }
1004
1005 #[test]
1006 fn test_stream_ciphers() {
1007 #[cfg(not(boringssl))]
1008 {
1009 test_stream_cipher(Cipher::aes_128_cfb1());
1010 test_stream_cipher(Cipher::aes_128_cfb8());
1011 test_stream_cipher(Cipher::aes_128_cfb128());
1012 test_stream_cipher(Cipher::aes_192_cfb1());
1013 test_stream_cipher(Cipher::aes_192_cfb8());
1014 test_stream_cipher(Cipher::aes_192_cfb128());
1015 test_stream_cipher(Cipher::aes_256_cfb1());
1016 test_stream_cipher(Cipher::aes_256_cfb8());
1017 test_stream_cipher(Cipher::aes_256_cfb128());
1018 }
1019 test_stream_cipher(Cipher::aes_192_ctr());
1020 test_stream_cipher(Cipher::aes_256_ctr());
1021 }
1022
1023 fn test_stream_cipher(cipher: &'static CipherRef) {
1024 let mut key = vec![0; cipher.key_length()];
1025 rand_bytes(&mut key).unwrap();
1026 let mut iv = vec![0; cipher.iv_length()];
1027 rand_bytes(&mut iv).unwrap();
1028
1029 let mut ctx = CipherCtx::new().unwrap();
1030
1031 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
1032 .unwrap();
1033 ctx.set_padding(false);
1034
1035 assert_eq!(
1036 1,
1037 cipher.block_size(),
1038 "Need a stream cipher, not a block cipher"
1039 );
1040
1041 let mut output = vec![0; 32];
1045 let outlen = ctx
1046 .cipher_update(&[1; 15], Some(&mut output[0..15]))
1047 .unwrap();
1048 assert_eq!(15, outlen);
1049
1050 let outlen = ctx
1054 .cipher_update(&[1; 17], Some(&mut output[15..]))
1055 .unwrap();
1056 assert_eq!(17, outlen);
1057
1058 ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
1059
1060 ctx.encrypt_init(None, None, Some(&iv)).unwrap();
1063 ctx.set_padding(false);
1064 let mut data_inplace: [u8; 32] = [1; 32];
1065 let outlen = ctx
1066 .cipher_update_inplace(&mut data_inplace[0..15], 15)
1067 .unwrap();
1068 assert_eq!(15, outlen);
1069
1070 let outlen = ctx
1071 .cipher_update_inplace(&mut data_inplace[15..32], 17)
1072 .unwrap();
1073 assert_eq!(17, outlen);
1074
1075 ctx.cipher_final(&mut [0u8; 0]).unwrap();
1076
1077 assert_eq!(data_inplace.as_slice(), output.as_slice());
1079
1080 ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv))
1082 .unwrap();
1083 ctx.set_padding(false);
1084
1085 let mut output_decrypted = vec![0; 32];
1089 let outlen = ctx
1090 .cipher_update(&output[0..15], Some(&mut output_decrypted[0..15]))
1091 .unwrap();
1092 assert_eq!(15, outlen);
1093
1094 let outlen = ctx
1095 .cipher_update(&output[15..], Some(&mut output_decrypted[15..]))
1096 .unwrap();
1097 assert_eq!(17, outlen);
1098
1099 ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
1100 assert_eq!(output_decrypted, vec![1; 32]);
1102
1103 ctx.decrypt_init(None, None, Some(&iv)).unwrap();
1105 ctx.set_padding(false);
1106
1107 let outlen = ctx.cipher_update_inplace(&mut output[0..15], 15).unwrap();
1108 assert_eq!(15, outlen);
1109
1110 let outlen = ctx.cipher_update_inplace(&mut output[15..], 17).unwrap();
1111 assert_eq!(17, outlen);
1112
1113 ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
1114 assert_eq!(output_decrypted, output);
1115 }
1116
1117 #[test]
1118 #[should_panic(expected = "Output buffer size should be at least 33 bytes.")]
1119 fn full_block_updates_aes_128() {
1120 output_buffer_too_small(Cipher::aes_128_cbc());
1121 }
1122
1123 #[test]
1124 #[should_panic(expected = "Output buffer size should be at least 33 bytes.")]
1125 fn full_block_updates_aes_256() {
1126 output_buffer_too_small(Cipher::aes_256_cbc());
1127 }
1128
1129 #[test]
1130 #[should_panic(expected = "Output buffer size should be at least 17 bytes.")]
1131 fn full_block_updates_3des() {
1132 output_buffer_too_small(Cipher::des_ede3_cbc());
1133 }
1134
1135 fn output_buffer_too_small(cipher: &'static CipherRef) {
1136 let mut key = vec![0; cipher.key_length()];
1137 rand_bytes(&mut key).unwrap();
1138 let mut iv = vec![0; cipher.iv_length()];
1139 rand_bytes(&mut iv).unwrap();
1140
1141 let mut ctx = CipherCtx::new().unwrap();
1142
1143 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
1144 .unwrap();
1145 ctx.set_padding(false);
1146
1147 let block_size = cipher.block_size();
1148 assert!(block_size > 1, "Need a block cipher, not a stream cipher");
1149
1150 ctx.cipher_update(&vec![0; block_size + 1], Some(&mut vec![0; block_size - 1]))
1151 .unwrap();
1152 }
1153
1154 #[cfg(ossl110)]
1155 fn cipher_wrap_test(cipher: &CipherRef, pt: &str, ct: &str, key: &str, iv: Option<&str>) {
1156 let pt = hex::decode(pt).unwrap();
1157 let key = hex::decode(key).unwrap();
1158 let expected = hex::decode(ct).unwrap();
1159 let iv = iv.map(|v| hex::decode(v).unwrap());
1160 let padding = 8 - pt.len() % 8;
1161 let mut computed = vec![0; pt.len() + padding + cipher.block_size() * 2];
1162 let mut ctx = CipherCtx::new().unwrap();
1163
1164 ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW);
1165 ctx.encrypt_init(Some(cipher), Some(&key), iv.as_deref())
1166 .unwrap();
1167
1168 let count = ctx.cipher_update(&pt, Some(&mut computed)).unwrap();
1169 let rest = ctx.cipher_final(&mut computed[count..]).unwrap();
1170 computed.truncate(count + rest);
1171
1172 if computed != expected {
1173 println!("Computed: {}", hex::encode(&computed));
1174 println!("Expected: {}", hex::encode(&expected));
1175 if computed.len() != expected.len() {
1176 println!(
1177 "Lengths differ: {} in computed vs {} expected",
1178 computed.len(),
1179 expected.len()
1180 );
1181 }
1182 panic!("test failure");
1183 }
1184 }
1185
1186 #[test]
1187 #[cfg(ossl110)]
1188 fn test_aes128_wrap() {
1189 let pt = "00112233445566778899aabbccddeeff";
1190 let ct = "7940ff694448b5bb5139c959a4896832e55d69aa04daa27e";
1191 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1192 let iv = "0001020304050607";
1193
1194 cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, Some(iv));
1195 }
1196
1197 #[test]
1198 #[cfg(ossl110)]
1199 fn test_aes128_wrap_default_iv() {
1200 let pt = "00112233445566778899aabbccddeeff";
1201 let ct = "38f1215f0212526f8a70b51955b9fbdc9fe3041d9832306e";
1202 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1203
1204 cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, None);
1205 }
1206
1207 #[test]
1208 #[cfg(ossl110)]
1209 fn test_aes128_wrap_pad() {
1210 let pt = "00112233445566778899aabbccddee";
1211 let ct = "f13998f5ab32ef82a1bdbcbe585e1d837385b529572a1e1b";
1212 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1213 let iv = "00010203";
1214
1215 cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, Some(iv));
1216 }
1217
1218 #[test]
1219 #[cfg(ossl110)]
1220 fn test_aes128_wrap_pad_default_iv() {
1221 let pt = "00112233445566778899aabbccddee";
1222 let ct = "3a501085fb8cf66f4186b7df851914d471ed823411598add";
1223 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1224
1225 cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, None);
1226 }
1227
1228 #[test]
1229 #[cfg(ossl110)]
1230 fn test_aes192_wrap() {
1231 let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b";
1232 let ct = "83b89142dfeeb4871e078bfb81134d33e23fedc19b03a1cf689973d3831b6813";
1233 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1234 let iv = "0001020304050607";
1235
1236 cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, Some(iv));
1237 }
1238
1239 #[test]
1240 #[cfg(ossl110)]
1241 fn test_aes192_wrap_default_iv() {
1242 let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b";
1243 let ct = "c02c2cf11505d3e4851030d5534cbf5a1d7eca7ba8839adbf239756daf1b43e6";
1244 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1245
1246 cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, None);
1247 }
1248
1249 #[test]
1250 #[cfg(ossl110)]
1251 fn test_aes192_wrap_pad() {
1252 let pt = "00112233445566778899aabbccddee";
1253 let ct = "b4f6bb167ef7caf061a74da82b36ad038ca057ab51e98d3a";
1254 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1255 let iv = "00010203";
1256
1257 cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, Some(iv));
1258 }
1259
1260 #[test]
1261 #[cfg(ossl110)]
1262 fn test_aes192_wrap_pad_default_iv() {
1263 let pt = "00112233445566778899aabbccddee";
1264 let ct = "b2c37a28cc602753a7c944a4c2555a2df9c98b2eded5312e";
1265 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1266
1267 cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, None);
1268 }
1269
1270 #[test]
1271 #[cfg(ossl110)]
1272 fn test_aes256_wrap() {
1273 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51";
1274 let ct = "cc05da2a7f56f7dd0c144231f90bce58648fa20a8278f5a6b7d13bba6aa57a33229d4333866b7fd6";
1275 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1276 let iv = "0001020304050607";
1277
1278 cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, Some(iv));
1279 }
1280
1281 #[test]
1282 #[cfg(ossl110)]
1283 fn test_aes256_wrap_default_iv() {
1284 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51";
1285 let ct = "0b24f068b50e52bc6987868411c36e1b03900866ed12af81eb87cef70a8d1911731c1d7abf789d88";
1286 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1287
1288 cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, None);
1289 }
1290
1291 #[test]
1292 #[cfg(ossl110)]
1293 fn test_aes256_wrap_pad() {
1294 let pt = "00112233445566778899aabbccddee";
1295 let ct = "91594e044ccc06130d60e6c84a996aa4f96a9faff8c5f6e7";
1296 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1297 let iv = "00010203";
1298
1299 cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, Some(iv));
1300 }
1301
1302 #[test]
1303 #[cfg(ossl110)]
1304 fn test_aes256_wrap_pad_default_iv() {
1305 let pt = "00112233445566778899aabbccddee";
1306 let ct = "dc3c166a854afd68aea624a4272693554bf2e4fcbae602cd";
1307 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1308
1309 cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, None);
1310 }
1311
1312 #[test]
1313 #[cfg(ossl110)]
1314 fn test_aes_wrap_pad_cipher_update_vec_buffer_size() {
1315 let cipher = Cipher::aes_256_wrap_pad();
1316 let key = [0u8; 32];
1317 let iv = [0u8; 4];
1318 let pt = [0u8; 9];
1319
1320 let mut ctx = CipherCtx::new().unwrap();
1321 ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW);
1322 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
1323 .unwrap();
1324
1325 let mut out = vec![];
1326 let len = ctx.cipher_update_vec(&pt, &mut out).unwrap();
1327 assert!(out.capacity() >= len);
1329 assert_eq!(len, 24);
1330 }
1331
1332 #[test]
1333 #[cfg(ossl110)]
1334 #[should_panic(expected = "Output buffer size must be at least 24 bytes.")]
1335 fn test_aes_wrap_pad_cipher_update_inplace_buffer_size() {
1336 let cipher = Cipher::aes_256_wrap_pad();
1337 let key = [0u8; 32];
1338 let iv = [0u8; 4];
1339
1340 let mut ctx = CipherCtx::new().unwrap();
1341 ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW);
1342 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
1343 .unwrap();
1344
1345 let mut buf = [0u8; 17];
1349 let _ = ctx.cipher_update_inplace(&mut buf, 9);
1350 }
1351
1352 #[test]
1353 #[cfg(ossl110)]
1354 fn test_aes_wrap_cipher_update_exact_buffer_size() {
1355 let cipher = Cipher::aes_128_wrap();
1356 let key = [0u8; 16];
1357 let pt = [0u8; 16];
1358
1359 let mut ctx = CipherCtx::new().unwrap();
1360 ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW);
1361 ctx.encrypt_init(Some(cipher), Some(&key), None).unwrap();
1362
1363 let mut out = [0u8; 24];
1366 assert_eq!(ctx.cipher_update(&pt, Some(&mut out)).unwrap(), 24);
1367 }
1368
1369 #[test]
1370 #[cfg(ossl110)]
1371 fn test_des3_wrap_cipher_update_vec_buffer_size() {
1372 let cipher = Cipher::from_nid(Nid::ID_SMIME_ALG_CMS3DESWRAP).unwrap();
1373 let key = [0x11u8; 24];
1374 let pt = [0x33u8; 16];
1375
1376 let mut ctx = CipherCtx::new().unwrap();
1377 ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW);
1378 ctx.encrypt_init(Some(cipher), Some(&key), None).unwrap();
1379
1380 let mut out = vec![];
1381 let len = ctx.cipher_update_vec(&pt, &mut out).unwrap();
1382 assert!(out.capacity() >= len);
1384 assert_eq!(len, 32);
1385 }
1386
1387 #[test]
1388 #[cfg(ossl110)]
1389 fn test_des3_wrap_unwrap() {
1390 let cipher = Cipher::from_nid(Nid::ID_SMIME_ALG_CMS3DESWRAP).unwrap();
1391 let key = [0x11u8; 24];
1392 let pt = [0x33u8; 16];
1393
1394 let mut ctx = CipherCtx::new().unwrap();
1395 ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW);
1396 ctx.encrypt_init(Some(cipher), Some(&key), None).unwrap();
1397 let mut wrapped = vec![];
1398 ctx.cipher_update_vec(&pt, &mut wrapped).unwrap();
1399 assert_eq!(wrapped.len(), 32);
1400
1401 let mut ctx = CipherCtx::new().unwrap();
1402 ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW);
1403 ctx.decrypt_init(Some(cipher), Some(&key), None).unwrap();
1404 let mut unwrapped = vec![];
1405 ctx.cipher_update_vec(&wrapped, &mut unwrapped).unwrap();
1406 assert_eq!(unwrapped, pt);
1407 }
1408
1409 #[test]
1410 #[cfg(ossl110)]
1411 #[should_panic(expected = "Output buffer size should be at least 32 bytes.")]
1412 fn test_des3_wrap_cipher_update_buffer_size() {
1413 let cipher = Cipher::from_nid(Nid::ID_SMIME_ALG_CMS3DESWRAP).unwrap();
1414 let key = [0x11u8; 24];
1415 let pt = [0x33u8; 16];
1416
1417 let mut ctx = CipherCtx::new().unwrap();
1418 ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW);
1419 ctx.encrypt_init(Some(cipher), Some(&key), None).unwrap();
1420
1421 let mut out = [0u8; 24];
1424 let _ = ctx.cipher_update(&pt, Some(&mut out));
1425 }
1426}