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_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 #[cfg(not(any(boringssl, awslc)))]
326 fn is_wrap_mode(&self) -> bool {
327 unsafe {
328 let cipher = EVP_CIPHER_CTX_get0_cipher(self.as_ptr());
329 if cipher.is_null() {
330 return false;
331 }
332 ffi::EVP_CIPHER_flags(cipher) & ffi::EVP_CIPH_MODE == ffi::EVP_CIPH_WRAP_MODE
333 }
334 }
335
336 #[cfg(any(boringssl, awslc))]
337 fn is_wrap_mode(&self) -> bool {
338 false
339 }
340
341 fn cipher_update_output_size(&self, input_len: usize) -> usize {
342 if self.is_wrap_mode() {
348 return input_len.saturating_add(7) / 8 * 8 + 8;
349 }
350 let mut block_size = self.block_size();
351 if block_size == 1 {
352 block_size = 0;
353 }
354 input_len + block_size
355 }
356
357 #[corresponds(EVP_CIPHER_CTX_block_size)]
365 pub fn block_size(&self) -> usize {
366 self.assert_cipher();
367
368 unsafe { ffi::EVP_CIPHER_CTX_block_size(self.as_ptr()) as usize }
369 }
370
371 #[corresponds(EVP_CIPHER_CTX_key_length)]
377 pub fn key_length(&self) -> usize {
378 self.assert_cipher();
379
380 unsafe { ffi::EVP_CIPHER_CTX_key_length(self.as_ptr()) as usize }
381 }
382
383 #[corresponds(EVP_CIPHER_CTX_rand_key)]
390 #[cfg(not(any(boringssl, awslc)))]
391 pub fn rand_key(&self, buf: &mut [u8]) -> Result<(), ErrorStack> {
392 assert!(buf.len() >= self.key_length());
393
394 unsafe {
395 cvt(ffi::EVP_CIPHER_CTX_rand_key(
396 self.as_ptr(),
397 buf.as_mut_ptr(),
398 ))?;
399 }
400
401 Ok(())
402 }
403
404 #[corresponds(EVP_CIPHER_CTX_set_key_length)]
412 pub fn set_key_length(&mut self, len: usize) -> Result<(), ErrorStack> {
413 self.assert_cipher();
414
415 unsafe {
416 cvt(ffi::EVP_CIPHER_CTX_set_key_length(
417 self.as_ptr(),
418 len.try_into().unwrap(),
419 ))?;
420 }
421
422 Ok(())
423 }
424
425 #[corresponds(EVP_CIPHER_CTX_iv_length)]
433 pub fn iv_length(&self) -> usize {
434 self.assert_cipher();
435
436 unsafe { ffi::EVP_CIPHER_CTX_iv_length(self.as_ptr()) as usize }
437 }
438
439 #[corresponds(EVP_CIPHER_CTX_num)]
448 #[cfg(ossl110)]
449 pub fn num(&self) -> usize {
450 self.assert_cipher();
451
452 unsafe { ffi::EVP_CIPHER_CTX_num(self.as_ptr()) as usize }
453 }
454
455 #[corresponds(EVP_CIPHER_CTX_ctrl)]
463 pub fn set_iv_length(&mut self, len: usize) -> Result<(), ErrorStack> {
464 self.assert_cipher();
465
466 let len = c_int::try_from(len).unwrap();
467
468 unsafe {
469 cvt(ffi::EVP_CIPHER_CTX_ctrl(
470 self.as_ptr(),
471 ffi::EVP_CTRL_GCM_SET_IVLEN,
472 len,
473 ptr::null_mut(),
474 ))?;
475 }
476
477 Ok(())
478 }
479
480 #[corresponds(EVP_CIPHER_CTX_get_tag_length)]
490 #[cfg(ossl300)]
491 pub fn tag_length(&self) -> usize {
492 self.assert_cipher();
493
494 unsafe { ffi::EVP_CIPHER_CTX_get_tag_length(self.as_ptr()) as usize }
495 }
496
497 #[corresponds(EVP_CIPHER_CTX_ctrl)]
504 pub fn tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> {
505 let len = c_int::try_from(tag.len()).unwrap();
506
507 unsafe {
508 cvt(ffi::EVP_CIPHER_CTX_ctrl(
509 self.as_ptr(),
510 ffi::EVP_CTRL_GCM_GET_TAG,
511 len,
512 tag.as_mut_ptr() as *mut _,
513 ))?;
514 }
515
516 Ok(())
517 }
518
519 #[corresponds(EVP_CIPHER_CTX_ctrl)]
523 pub fn set_tag_length(&mut self, len: usize) -> Result<(), ErrorStack> {
524 let len = c_int::try_from(len).unwrap();
525
526 unsafe {
527 cvt(ffi::EVP_CIPHER_CTX_ctrl(
528 self.as_ptr(),
529 ffi::EVP_CTRL_GCM_SET_TAG,
530 len,
531 ptr::null_mut(),
532 ))?;
533 }
534
535 Ok(())
536 }
537
538 #[corresponds(EVP_CIPHER_CTX_ctrl)]
540 pub fn set_tag(&mut self, tag: &[u8]) -> Result<(), ErrorStack> {
541 let len = c_int::try_from(tag.len()).unwrap();
542
543 unsafe {
544 cvt(ffi::EVP_CIPHER_CTX_ctrl(
545 self.as_ptr(),
546 ffi::EVP_CTRL_GCM_SET_TAG,
547 len,
548 tag.as_ptr() as *mut _,
549 ))?;
550 }
551
552 Ok(())
553 }
554
555 #[corresponds(EVP_CIPHER_CTX_set_padding)]
559 pub fn set_padding(&mut self, padding: bool) {
560 unsafe {
561 ffi::EVP_CIPHER_CTX_set_padding(self.as_ptr(), padding as c_int);
562 }
563 }
564
565 #[corresponds(EVP_CipherUpdate)]
569 pub fn set_data_len(&mut self, len: usize) -> Result<(), ErrorStack> {
570 let len = c_int::try_from(len).unwrap();
571
572 unsafe {
573 cvt(ffi::EVP_CipherUpdate(
574 self.as_ptr(),
575 ptr::null_mut(),
576 &mut 0,
577 ptr::null(),
578 len,
579 ))?;
580 }
581
582 Ok(())
583 }
584
585 #[corresponds(EVP_CIPHER_CTX_set_flags)]
589 #[cfg(ossl110)]
590 pub fn set_flags(&mut self, flags: CipherCtxFlags) {
591 unsafe {
592 ffi::EVP_CIPHER_CTX_set_flags(self.as_ptr(), flags.bits());
593 }
594 }
595
596 #[corresponds(EVP_CipherUpdate)]
607 pub fn cipher_update(
608 &mut self,
609 input: &[u8],
610 output: Option<&mut [u8]>,
611 ) -> Result<usize, ErrorStack> {
612 if let Some(output) = &output {
613 let min_output_size = self.cipher_update_output_size(input.len());
614 assert!(
615 output.len() >= min_output_size,
616 "Output buffer size should be at least {} bytes.",
617 min_output_size
618 );
619 }
620
621 unsafe { self.cipher_update_unchecked(input, output) }
622 }
623
624 #[corresponds(EVP_CipherUpdate)]
642 pub unsafe fn cipher_update_unchecked(
643 &mut self,
644 input: &[u8],
645 output: Option<&mut [u8]>,
646 ) -> Result<usize, ErrorStack> {
647 let inlen = c_int::try_from(input.len()).unwrap();
648
649 let mut outlen = 0;
650
651 cvt(ffi::EVP_CipherUpdate(
652 self.as_ptr(),
653 output.map_or(ptr::null_mut(), |b| b.as_mut_ptr()),
654 &mut outlen,
655 input.as_ptr(),
656 inlen,
657 ))?;
658
659 Ok(outlen as usize)
660 }
661
662 pub fn cipher_update_vec(
664 &mut self,
665 input: &[u8],
666 output: &mut Vec<u8>,
667 ) -> Result<usize, ErrorStack> {
668 let base = output.len();
669 output.resize(base + self.cipher_update_output_size(input.len()), 0);
670 let len = self.cipher_update(input, Some(&mut output[base..]))?;
671 output.truncate(base + len);
672
673 Ok(len)
674 }
675
676 #[corresponds(EVP_CipherUpdate)]
690 pub fn cipher_update_inplace(
691 &mut self,
692 data: &mut [u8],
693 inlen: usize,
694 ) -> Result<usize, ErrorStack> {
695 assert!(inlen <= data.len(), "Input size may not exceed buffer size");
696 let block_size = self.block_size();
697 if block_size != 1 {
698 assert!(
699 data.len() >= inlen + block_size,
700 "Output buffer size must be at least {} bytes.",
701 inlen + block_size
702 );
703 }
704
705 let inlen = c_int::try_from(inlen).unwrap();
706 let mut outlen = 0;
707 unsafe {
708 cvt(ffi::EVP_CipherUpdate(
709 self.as_ptr(),
710 data.as_mut_ptr(),
711 &mut outlen,
712 data.as_ptr(),
713 inlen,
714 ))
715 }?;
716
717 Ok(outlen as usize)
718 }
719
720 #[corresponds(EVP_CipherFinal)]
730 pub fn cipher_final(&mut self, output: &mut [u8]) -> Result<usize, ErrorStack> {
731 let block_size = self.block_size();
732 if block_size > 1 {
733 assert!(output.len() >= block_size);
734 }
735
736 unsafe { self.cipher_final_unchecked(output) }
737 }
738
739 #[corresponds(EVP_CipherFinal)]
755 pub unsafe fn cipher_final_unchecked(
756 &mut self,
757 output: &mut [u8],
758 ) -> Result<usize, ErrorStack> {
759 let mut outl = 0;
760
761 cvt(ffi::EVP_CipherFinal(
762 self.as_ptr(),
763 output.as_mut_ptr(),
764 &mut outl,
765 ))?;
766
767 Ok(outl as usize)
768 }
769
770 pub fn cipher_final_vec(&mut self, output: &mut Vec<u8>) -> Result<usize, ErrorStack> {
772 let base = output.len();
773 output.resize(base + self.block_size(), 0);
774 let len = self.cipher_final(&mut output[base..])?;
775 output.truncate(base + len);
776
777 Ok(len)
778 }
779}
780
781#[cfg(test)]
782mod test {
783 use super::*;
784 use crate::{cipher::Cipher, rand::rand_bytes};
785 #[cfg(not(any(boringssl, awslc)))]
786 use std::slice;
787
788 #[test]
789 #[cfg(not(any(boringssl, awslc)))]
790 fn seal_open() {
791 let private_pem = include_bytes!("../test/rsa.pem");
792 let public_pem = include_bytes!("../test/rsa.pem.pub");
793 let private_key = PKey::private_key_from_pem(private_pem).unwrap();
794 let public_key = PKey::public_key_from_pem(public_pem).unwrap();
795 let cipher = Cipher::aes_256_cbc();
796 let secret = b"My secret message";
797
798 let mut ctx = CipherCtx::new().unwrap();
799 let mut encrypted_key = vec![];
800 let mut iv = vec![0; cipher.iv_length()];
801 let mut encrypted = vec![];
802 ctx.seal_init(
803 Some(cipher),
804 &[public_key],
805 slice::from_mut(&mut encrypted_key),
806 Some(&mut iv),
807 )
808 .unwrap();
809 ctx.cipher_update_vec(secret, &mut encrypted).unwrap();
810 ctx.cipher_final_vec(&mut encrypted).unwrap();
811
812 let mut decrypted = vec![];
813 ctx.open_init(Some(cipher), &encrypted_key, Some(&iv), Some(&private_key))
814 .unwrap();
815 ctx.cipher_update_vec(&encrypted, &mut decrypted).unwrap();
816 ctx.cipher_final_vec(&mut decrypted).unwrap();
817
818 assert_eq!(secret, &decrypted[..]);
819 }
820
821 fn aes_128_cbc(cipher: &CipherRef) {
822 let key = hex::decode("2b7e151628aed2a6abf7158809cf4f3c").unwrap();
824 let iv = hex::decode("000102030405060708090a0b0c0d0e0f").unwrap();
825 let pt = hex::decode("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51")
826 .unwrap();
827 let ct = hex::decode("7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b2")
828 .unwrap();
829
830 let mut ctx = CipherCtx::new().unwrap();
831
832 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
833 .unwrap();
834 ctx.set_padding(false);
835
836 let mut buf = vec![];
837 ctx.cipher_update_vec(&pt, &mut buf).unwrap();
838 ctx.cipher_final_vec(&mut buf).unwrap();
839
840 assert_eq!(buf, ct);
841
842 ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv))
843 .unwrap();
844 ctx.set_padding(false);
845
846 let mut buf = vec![];
847 ctx.cipher_update_vec(&ct, &mut buf).unwrap();
848 ctx.cipher_final_vec(&mut buf).unwrap();
849
850 assert_eq!(buf, pt);
851 }
852
853 #[test]
854 #[cfg(ossl300)]
855 fn fetched_aes_128_cbc() {
856 let cipher = Cipher::fetch(None, "AES-128-CBC", None).unwrap();
857 aes_128_cbc(&cipher);
858 }
859
860 #[test]
861 fn default_aes_128_cbc() {
862 let cipher = Cipher::aes_128_cbc();
863 aes_128_cbc(cipher);
864 }
865
866 #[cfg(not(boringssl))]
867 #[test]
868 fn default_aes_128_ccm() {
869 let cipher = Cipher::aes_128_ccm();
871 aes_ccm(
872 cipher,
873 "26511fb51fcfa75cb4b44da75a6e5a0e",
874 "ea98ec44f5a86715014783172e",
875 "4da40b80579c1d9a5309f7efecb7c059a2f914511ca5fc10",
876 "e4692b9f06b666c7451b146c8aeb07a6e30c629d28065c3dde5940325b14b810",
877 "1bf0ba0ebb20d8edba59f29a9371750c9c714078f73c335d",
878 "2f1322ac69b848b001476323aed84c47",
879 );
880 }
881
882 #[cfg(not(boringssl))]
883 #[test]
884 fn default_aes_192_ccm() {
885 let cipher = Cipher::aes_192_ccm();
887 aes_ccm(
888 cipher,
889 "26511fb51fcfa75cb4b44da75a6e5a0eb8d9c8f3b906f886",
890 "ea98ec44f5a86715014783172e",
891 "4da40b80579c1d9a5309f7efecb7c059a2f914511ca5fc10",
892 "e4692b9f06b666c7451b146c8aeb07a6e30c629d28065c3dde5940325b14b810",
893 "30c154c616946eccc2e241d336ad33720953e449a0e6b0f0",
894 "dbf8e9464909bdf337e48093c082a10b",
895 );
896 }
897
898 #[cfg(not(boringssl))]
899 #[test]
900 fn default_aes_256_ccm() {
901 let cipher = Cipher::aes_256_ccm();
903 aes_ccm(
904 cipher,
905 "314a202f836f9f257e22d8c11757832ae5131d357a72df88f3eff0ffcee0da4e",
906 "3542fbe0f59a6d5f3abf619b7d",
907 "c5b3d71312ea14f2f8fae5bd1a453192b6604a45db75c5ed",
908 "dd4531f158a2fa3bc8a339f770595048f4a42bc1b03f2e824efc6ba4985119d8",
909 "39c2e8f6edfe663b90963b98eb79e2d4f7f28a5053ae8881",
910 "567a6b4426f1667136bed4a5e32a2bc1",
911 );
912 }
913
914 #[cfg(not(boringssl))]
915 fn aes_ccm(
916 cipher: &CipherRef,
917 key: &'static str,
918 iv: &'static str,
919 pt: &'static str,
920 aad: &'static str,
921 ct: &'static str,
922 tag: &'static str,
923 ) {
924 let key = hex::decode(key).unwrap();
925 let iv = hex::decode(iv).unwrap();
926 let pt = hex::decode(pt).unwrap();
927 let ct = hex::decode(ct).unwrap();
928 let aad = hex::decode(aad).unwrap();
929 let tag = hex::decode(tag).unwrap();
930
931 let mut ctx = CipherCtx::new().unwrap();
932
933 ctx.encrypt_init(Some(cipher), None, None).unwrap();
934 ctx.set_iv_length(iv.len()).unwrap();
935 ctx.set_tag_length(tag.len()).unwrap();
936 ctx.encrypt_init(None, Some(&key), Some(&iv)).unwrap();
937 ctx.set_data_len(pt.len()).unwrap();
938
939 let mut buf = vec![];
940 ctx.cipher_update(&aad, None).unwrap();
941 ctx.cipher_update_vec(&pt, &mut buf).unwrap();
942 ctx.cipher_final_vec(&mut buf).unwrap();
943 assert_eq!(buf, ct);
944
945 let mut out_tag = vec![0u8; tag.len()];
946 ctx.tag(&mut out_tag).unwrap();
947 assert_eq!(tag, out_tag);
948
949 ctx.decrypt_init(Some(cipher), None, None).unwrap();
950 ctx.set_iv_length(iv.len()).unwrap();
951 ctx.set_tag(&tag).unwrap();
952 ctx.decrypt_init(None, Some(&key), Some(&iv)).unwrap();
953 ctx.set_data_len(pt.len()).unwrap();
954
955 let mut buf = vec![];
956 ctx.cipher_update(&aad, None).unwrap();
957 ctx.cipher_update_vec(&ct, &mut buf).unwrap();
958 #[cfg(any(ossl111, awslc, boringssl))]
961 ctx.cipher_final_vec(&mut buf).unwrap();
962
963 assert_eq!(buf, pt);
964 }
965
966 #[cfg(not(any(boringssl, awslc)))]
967 #[test]
968 fn default_aes_128_xts() {
969 let cipher = Cipher::aes_128_xts();
971 aes_xts(
972 cipher,
973 "a1b90cba3f06ac353b2c343876081762090923026e91771815f29dab01932f2f",
974 "4faef7117cda59c66e4b92013e768ad5",
975 "ebabce95b14d3c8d6fb350390790311c",
976 "778ae8b43cb98d5a825081d5be471c63",
977 );
978 }
979
980 #[cfg(not(boringssl))]
981 #[test]
982 fn default_aes_256_xts() {
983 let cipher = Cipher::aes_256_xts();
985 aes_xts(cipher, "1ea661c58d943a0e4801e42f4b0947149e7f9f8e3e68d0c7505210bd311a0e7cd6e13ffdf2418d8d1911c004cda58da3d619b7e2b9141e58318eea392cf41b08", "adf8d92627464ad2f0428e84a9f87564", "2eedea52cd8215e1acc647e810bbc3642e87287f8d2e57e36c0a24fbc12a202e", "cbaad0e2f6cea3f50b37f934d46a9b130b9d54f07e34f36af793e86f73c6d7db");
986 }
987
988 #[cfg(not(boringssl))]
989 fn aes_xts(
990 cipher: &CipherRef,
991 key: &'static str,
992 i: &'static str,
993 pt: &'static str,
994 ct: &'static str,
995 ) {
996 let key = hex::decode(key).unwrap();
997 let i = hex::decode(i).unwrap();
998 let pt = hex::decode(pt).unwrap();
999 let ct = hex::decode(ct).unwrap();
1000
1001 let mut ctx = CipherCtx::new().unwrap();
1002 ctx.encrypt_init(Some(cipher), Some(&key), Some(&i))
1003 .unwrap();
1004 let mut buf = vec![];
1005 ctx.cipher_update_vec(&pt, &mut buf).unwrap();
1006 ctx.cipher_final_vec(&mut buf).unwrap();
1007
1008 assert_eq!(ct, buf);
1009
1010 ctx.decrypt_init(Some(cipher), Some(&key), Some(&i))
1011 .unwrap();
1012 let mut buf = vec![];
1013 ctx.cipher_update_vec(&ct, &mut buf).unwrap();
1014 ctx.cipher_final_vec(&mut buf).unwrap();
1015
1016 assert_eq!(pt, buf);
1017 }
1018
1019 #[test]
1020 fn test_stream_ciphers() {
1021 #[cfg(not(boringssl))]
1022 {
1023 test_stream_cipher(Cipher::aes_128_cfb1());
1024 test_stream_cipher(Cipher::aes_128_cfb8());
1025 test_stream_cipher(Cipher::aes_128_cfb128());
1026 test_stream_cipher(Cipher::aes_192_cfb1());
1027 test_stream_cipher(Cipher::aes_192_cfb8());
1028 test_stream_cipher(Cipher::aes_192_cfb128());
1029 test_stream_cipher(Cipher::aes_256_cfb1());
1030 test_stream_cipher(Cipher::aes_256_cfb8());
1031 test_stream_cipher(Cipher::aes_256_cfb128());
1032 }
1033 test_stream_cipher(Cipher::aes_192_ctr());
1034 test_stream_cipher(Cipher::aes_256_ctr());
1035 }
1036
1037 fn test_stream_cipher(cipher: &'static CipherRef) {
1038 let mut key = vec![0; cipher.key_length()];
1039 rand_bytes(&mut key).unwrap();
1040 let mut iv = vec![0; cipher.iv_length()];
1041 rand_bytes(&mut iv).unwrap();
1042
1043 let mut ctx = CipherCtx::new().unwrap();
1044
1045 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
1046 .unwrap();
1047 ctx.set_padding(false);
1048
1049 assert_eq!(
1050 1,
1051 cipher.block_size(),
1052 "Need a stream cipher, not a block cipher"
1053 );
1054
1055 let mut output = vec![0; 32];
1059 let outlen = ctx
1060 .cipher_update(&[1; 15], Some(&mut output[0..15]))
1061 .unwrap();
1062 assert_eq!(15, outlen);
1063
1064 let outlen = ctx
1068 .cipher_update(&[1; 17], Some(&mut output[15..]))
1069 .unwrap();
1070 assert_eq!(17, outlen);
1071
1072 ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
1073
1074 ctx.encrypt_init(None, None, Some(&iv)).unwrap();
1077 ctx.set_padding(false);
1078 let mut data_inplace: [u8; 32] = [1; 32];
1079 let outlen = ctx
1080 .cipher_update_inplace(&mut data_inplace[0..15], 15)
1081 .unwrap();
1082 assert_eq!(15, outlen);
1083
1084 let outlen = ctx
1085 .cipher_update_inplace(&mut data_inplace[15..32], 17)
1086 .unwrap();
1087 assert_eq!(17, outlen);
1088
1089 ctx.cipher_final(&mut [0u8; 0]).unwrap();
1090
1091 assert_eq!(data_inplace.as_slice(), output.as_slice());
1093
1094 ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv))
1096 .unwrap();
1097 ctx.set_padding(false);
1098
1099 let mut output_decrypted = vec![0; 32];
1103 let outlen = ctx
1104 .cipher_update(&output[0..15], Some(&mut output_decrypted[0..15]))
1105 .unwrap();
1106 assert_eq!(15, outlen);
1107
1108 let outlen = ctx
1109 .cipher_update(&output[15..], Some(&mut output_decrypted[15..]))
1110 .unwrap();
1111 assert_eq!(17, outlen);
1112
1113 ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
1114 assert_eq!(output_decrypted, vec![1; 32]);
1116
1117 ctx.decrypt_init(None, None, Some(&iv)).unwrap();
1119 ctx.set_padding(false);
1120
1121 let outlen = ctx.cipher_update_inplace(&mut output[0..15], 15).unwrap();
1122 assert_eq!(15, outlen);
1123
1124 let outlen = ctx.cipher_update_inplace(&mut output[15..], 17).unwrap();
1125 assert_eq!(17, outlen);
1126
1127 ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
1128 assert_eq!(output_decrypted, output);
1129 }
1130
1131 #[test]
1132 #[should_panic(expected = "Output buffer size should be at least 33 bytes.")]
1133 fn full_block_updates_aes_128() {
1134 output_buffer_too_small(Cipher::aes_128_cbc());
1135 }
1136
1137 #[test]
1138 #[should_panic(expected = "Output buffer size should be at least 33 bytes.")]
1139 fn full_block_updates_aes_256() {
1140 output_buffer_too_small(Cipher::aes_256_cbc());
1141 }
1142
1143 #[test]
1144 #[should_panic(expected = "Output buffer size should be at least 17 bytes.")]
1145 fn full_block_updates_3des() {
1146 output_buffer_too_small(Cipher::des_ede3_cbc());
1147 }
1148
1149 fn output_buffer_too_small(cipher: &'static CipherRef) {
1150 let mut key = vec![0; cipher.key_length()];
1151 rand_bytes(&mut key).unwrap();
1152 let mut iv = vec![0; cipher.iv_length()];
1153 rand_bytes(&mut iv).unwrap();
1154
1155 let mut ctx = CipherCtx::new().unwrap();
1156
1157 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
1158 .unwrap();
1159 ctx.set_padding(false);
1160
1161 let block_size = cipher.block_size();
1162 assert!(block_size > 1, "Need a block cipher, not a stream cipher");
1163
1164 ctx.cipher_update(&vec![0; block_size + 1], Some(&mut vec![0; block_size - 1]))
1165 .unwrap();
1166 }
1167
1168 #[cfg(ossl110)]
1169 fn cipher_wrap_test(cipher: &CipherRef, pt: &str, ct: &str, key: &str, iv: Option<&str>) {
1170 let pt = hex::decode(pt).unwrap();
1171 let key = hex::decode(key).unwrap();
1172 let expected = hex::decode(ct).unwrap();
1173 let iv = iv.map(|v| hex::decode(v).unwrap());
1174 let padding = 8 - pt.len() % 8;
1175 let mut computed = vec![0; pt.len() + padding + cipher.block_size() * 2];
1176 let mut ctx = CipherCtx::new().unwrap();
1177
1178 ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW);
1179 ctx.encrypt_init(Some(cipher), Some(&key), iv.as_deref())
1180 .unwrap();
1181
1182 let count = ctx.cipher_update(&pt, Some(&mut computed)).unwrap();
1183 let rest = ctx.cipher_final(&mut computed[count..]).unwrap();
1184 computed.truncate(count + rest);
1185
1186 if computed != expected {
1187 println!("Computed: {}", hex::encode(&computed));
1188 println!("Expected: {}", hex::encode(&expected));
1189 if computed.len() != expected.len() {
1190 println!(
1191 "Lengths differ: {} in computed vs {} expected",
1192 computed.len(),
1193 expected.len()
1194 );
1195 }
1196 panic!("test failure");
1197 }
1198 }
1199
1200 #[test]
1201 #[cfg(ossl110)]
1202 fn test_aes128_wrap() {
1203 let pt = "00112233445566778899aabbccddeeff";
1204 let ct = "7940ff694448b5bb5139c959a4896832e55d69aa04daa27e";
1205 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1206 let iv = "0001020304050607";
1207
1208 cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, Some(iv));
1209 }
1210
1211 #[test]
1212 #[cfg(ossl110)]
1213 fn test_aes128_wrap_default_iv() {
1214 let pt = "00112233445566778899aabbccddeeff";
1215 let ct = "38f1215f0212526f8a70b51955b9fbdc9fe3041d9832306e";
1216 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1217
1218 cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, None);
1219 }
1220
1221 #[test]
1222 #[cfg(ossl110)]
1223 fn test_aes128_wrap_pad() {
1224 let pt = "00112233445566778899aabbccddee";
1225 let ct = "f13998f5ab32ef82a1bdbcbe585e1d837385b529572a1e1b";
1226 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1227 let iv = "00010203";
1228
1229 cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, Some(iv));
1230 }
1231
1232 #[test]
1233 #[cfg(ossl110)]
1234 fn test_aes128_wrap_pad_default_iv() {
1235 let pt = "00112233445566778899aabbccddee";
1236 let ct = "3a501085fb8cf66f4186b7df851914d471ed823411598add";
1237 let key = "2b7e151628aed2a6abf7158809cf4f3c";
1238
1239 cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, None);
1240 }
1241
1242 #[test]
1243 #[cfg(ossl110)]
1244 fn test_aes192_wrap() {
1245 let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b";
1246 let ct = "83b89142dfeeb4871e078bfb81134d33e23fedc19b03a1cf689973d3831b6813";
1247 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1248 let iv = "0001020304050607";
1249
1250 cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, Some(iv));
1251 }
1252
1253 #[test]
1254 #[cfg(ossl110)]
1255 fn test_aes192_wrap_default_iv() {
1256 let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b";
1257 let ct = "c02c2cf11505d3e4851030d5534cbf5a1d7eca7ba8839adbf239756daf1b43e6";
1258 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1259
1260 cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, None);
1261 }
1262
1263 #[test]
1264 #[cfg(ossl110)]
1265 fn test_aes192_wrap_pad() {
1266 let pt = "00112233445566778899aabbccddee";
1267 let ct = "b4f6bb167ef7caf061a74da82b36ad038ca057ab51e98d3a";
1268 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1269 let iv = "00010203";
1270
1271 cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, Some(iv));
1272 }
1273
1274 #[test]
1275 #[cfg(ossl110)]
1276 fn test_aes192_wrap_pad_default_iv() {
1277 let pt = "00112233445566778899aabbccddee";
1278 let ct = "b2c37a28cc602753a7c944a4c2555a2df9c98b2eded5312e";
1279 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
1280
1281 cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, None);
1282 }
1283
1284 #[test]
1285 #[cfg(ossl110)]
1286 fn test_aes256_wrap() {
1287 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51";
1288 let ct = "cc05da2a7f56f7dd0c144231f90bce58648fa20a8278f5a6b7d13bba6aa57a33229d4333866b7fd6";
1289 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1290 let iv = "0001020304050607";
1291
1292 cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, Some(iv));
1293 }
1294
1295 #[test]
1296 #[cfg(ossl110)]
1297 fn test_aes256_wrap_default_iv() {
1298 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51";
1299 let ct = "0b24f068b50e52bc6987868411c36e1b03900866ed12af81eb87cef70a8d1911731c1d7abf789d88";
1300 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1301
1302 cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, None);
1303 }
1304
1305 #[test]
1306 #[cfg(ossl110)]
1307 fn test_aes256_wrap_pad() {
1308 let pt = "00112233445566778899aabbccddee";
1309 let ct = "91594e044ccc06130d60e6c84a996aa4f96a9faff8c5f6e7";
1310 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1311 let iv = "00010203";
1312
1313 cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, Some(iv));
1314 }
1315
1316 #[test]
1317 #[cfg(ossl110)]
1318 fn test_aes256_wrap_pad_default_iv() {
1319 let pt = "00112233445566778899aabbccddee";
1320 let ct = "dc3c166a854afd68aea624a4272693554bf2e4fcbae602cd";
1321 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
1322
1323 cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, None);
1324 }
1325
1326 #[test]
1327 #[cfg(ossl110)]
1328 fn test_aes_wrap_pad_cipher_update_vec_buffer_size() {
1329 let cipher = Cipher::aes_256_wrap_pad();
1330 let key = [0u8; 32];
1331 let iv = [0u8; 4];
1332 let pt = [0u8; 9];
1333
1334 let mut ctx = CipherCtx::new().unwrap();
1335 ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW);
1336 ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv))
1337 .unwrap();
1338
1339 let mut out = vec![];
1340 let len = ctx.cipher_update_vec(&pt, &mut out).unwrap();
1341 assert!(out.capacity() >= len);
1343 assert_eq!(len, 24);
1344 }
1345}