1use crate::aws_lc::{
5 EVP_CIPHER_CTX_new, EVP_CIPHER_iv_length, EVP_CIPHER_key_length, EVP_DecryptFinal_ex,
6 EVP_DecryptInit_ex, EVP_DecryptUpdate, EVP_EncryptFinal_ex, EVP_EncryptInit_ex,
7 EVP_EncryptUpdate, EVP_CIPHER, EVP_CIPHER_CTX,
8};
9use crate::cipher::{
10 Algorithm, DecryptionContext, EncryptionContext, OperatingMode, UnboundCipherKey,
11};
12use crate::error::Unspecified;
13use crate::fips::indicator_check;
14use crate::ptr::LcPtr;
15use std::ptr::{null, null_mut};
16
17use super::ConstPointer;
18
19pub struct StreamingEncryptingKey {
21 algorithm: &'static Algorithm,
22 mode: OperatingMode,
23 cipher_ctx: LcPtr<EVP_CIPHER_CTX>,
24 context: EncryptionContext,
25}
26
27pub struct BufferUpdate<'a> {
30 written: &'a [u8],
31 remainder: &'a mut [u8],
32}
33
34impl<'a> BufferUpdate<'a> {
35 fn new(out_buffer: &'a mut [u8], written_len: usize) -> Self {
36 let (written, remainder) = out_buffer.split_at_mut(written_len);
37 Self { written, remainder }
38 }
39}
40
41impl BufferUpdate<'_> {
42 #[must_use]
44 pub fn written(&self) -> &[u8] {
45 self.written
46 }
47
48 #[must_use]
50 pub fn remainder(&self) -> &[u8] {
51 self.remainder
52 }
53
54 #[must_use]
56 pub fn remainder_mut(&mut self) -> &mut [u8] {
57 self.remainder
58 }
59}
60
61fn evp_encrypt_init(
62 cipher_ctx: &mut LcPtr<EVP_CIPHER_CTX>,
63 cipher: &ConstPointer<EVP_CIPHER>,
64 key: &[u8],
65 iv: Option<&[u8]>,
66) -> Result<(), Unspecified> {
67 let iv_ptr: *const u8 = if let Some(iv) = iv {
68 iv.as_ptr()
69 } else {
70 null()
71 };
72
73 if 1 != unsafe {
75 EVP_EncryptInit_ex(
76 cipher_ctx.as_mut_ptr(),
77 cipher.as_const_ptr(),
78 null_mut(),
79 key.as_ptr(),
80 iv_ptr,
81 )
82 } {
83 return Err(Unspecified);
84 }
85
86 Ok(())
87}
88
89fn evp_decrypt_init(
90 cipher_ctx: &mut LcPtr<EVP_CIPHER_CTX>,
91 cipher: &ConstPointer<EVP_CIPHER>,
92 key: &[u8],
93 iv: Option<&[u8]>,
94) -> Result<(), Unspecified> {
95 let iv_ptr: *const u8 = if let Some(iv) = iv {
96 iv.as_ptr()
97 } else {
98 null()
99 };
100
101 if 1 != unsafe {
103 EVP_DecryptInit_ex(
104 cipher_ctx.as_mut_ptr(),
105 cipher.as_const_ptr(),
106 null_mut(),
107 key.as_ptr(),
108 iv_ptr,
109 )
110 } {
111 return Err(Unspecified);
112 }
113
114 Ok(())
115}
116
117impl StreamingEncryptingKey {
118 #[allow(clippy::needless_pass_by_value)]
119 fn new(
120 key: UnboundCipherKey,
121 mode: OperatingMode,
122 context: EncryptionContext,
123 ) -> Result<Self, Unspecified> {
124 let algorithm = key.algorithm();
125 let mut cipher_ctx = LcPtr::new(unsafe { EVP_CIPHER_CTX_new() })?;
126 let cipher = mode.evp_cipher(key.algorithm);
127 let key_bytes = key.key_bytes.as_ref();
128 debug_assert_eq!(
129 key_bytes.len(),
130 <usize>::try_from(unsafe { EVP_CIPHER_key_length(cipher.as_const_ptr()) }).unwrap()
131 );
132
133 match &context {
134 ctx @ EncryptionContext::Iv128(..) => {
135 let iv = <&[u8]>::try_from(ctx)?;
136 debug_assert_eq!(
137 iv.len(),
138 <usize>::try_from(unsafe { EVP_CIPHER_iv_length(cipher.as_const_ptr()) })
139 .unwrap()
140 );
141 evp_encrypt_init(&mut cipher_ctx, &cipher, key_bytes, Some(iv))?;
142 }
143 EncryptionContext::None => {
144 evp_encrypt_init(&mut cipher_ctx, &cipher, key_bytes, None)?;
145 }
146 }
147
148 Ok(Self {
149 algorithm,
150 mode,
151 cipher_ctx,
152 context,
153 })
154 }
155
156 pub fn update<'a>(
167 &mut self,
168 input: &[u8],
169 output: &'a mut [u8],
170 ) -> Result<BufferUpdate<'a>, Unspecified> {
171 let min_outsize = input
172 .len()
173 .checked_add(self.algorithm().block_len())
174 .ok_or(Unspecified)?
175 - 1;
176 if output.len() < min_outsize {
177 return Err(Unspecified);
178 }
179 let mut outlen: i32 = 0;
180 let inlen: i32 = input.len().try_into()?;
181
182 if 1 != unsafe {
183 EVP_EncryptUpdate(
184 self.cipher_ctx.as_mut_ptr(),
185 output.as_mut_ptr(),
186 &mut outlen,
187 input.as_ptr(),
188 inlen,
189 )
190 } {
191 return Err(Unspecified);
192 }
193 let outlen: usize = outlen.try_into()?;
194 debug_assert!(outlen <= min_outsize);
195 Ok(BufferUpdate::new(output, outlen))
196 }
197
198 pub fn finish(
208 mut self,
209 output: &mut [u8],
210 ) -> Result<(DecryptionContext, BufferUpdate<'_>), Unspecified> {
211 if output.len() < self.algorithm().block_len() {
212 return Err(Unspecified);
213 }
214 let mut outlen: i32 = 0;
215
216 if 1 != indicator_check!(unsafe {
217 EVP_EncryptFinal_ex(
218 self.cipher_ctx.as_mut_ptr(),
219 output.as_mut_ptr(),
220 &mut outlen,
221 )
222 }) {
223 return Err(Unspecified);
224 }
225 let outlen: usize = outlen.try_into()?;
226 debug_assert!(outlen <= self.algorithm().block_len());
227 Ok((self.context.into(), BufferUpdate::new(output, outlen)))
228 }
229
230 #[must_use]
232 pub fn mode(&self) -> OperatingMode {
233 self.mode
234 }
235
236 #[must_use]
238 pub fn algorithm(&self) -> &'static Algorithm {
239 self.algorithm
240 }
241
242 pub fn ctr(key: UnboundCipherKey) -> Result<Self, Unspecified> {
248 let context = key.algorithm().new_encryption_context(OperatingMode::CTR)?;
249 Self::less_safe_ctr(key, context)
250 }
251
252 pub fn less_safe_ctr(
261 key: UnboundCipherKey,
262 context: EncryptionContext,
263 ) -> Result<Self, Unspecified> {
264 Self::new(key, OperatingMode::CTR, context)
265 }
266
267 pub fn cbc_pkcs7(key: UnboundCipherKey) -> Result<Self, Unspecified> {
275 let context = key.algorithm().new_encryption_context(OperatingMode::CBC)?;
276 Self::less_safe_cbc_pkcs7(key, context)
277 }
278
279 pub fn cfb128(key: UnboundCipherKey) -> Result<Self, Unspecified> {
285 let context = key
286 .algorithm()
287 .new_encryption_context(OperatingMode::CFB128)?;
288 Self::less_safe_cfb128(key, context)
289 }
290
291 pub fn ecb_pkcs7(key: UnboundCipherKey) -> Result<Self, Unspecified> {
301 let context = key.algorithm().new_encryption_context(OperatingMode::ECB)?;
302 Self::new(key, OperatingMode::ECB, context)
303 }
304
305 pub fn less_safe_cfb128(
314 key: UnboundCipherKey,
315 context: EncryptionContext,
316 ) -> Result<Self, Unspecified> {
317 Self::new(key, OperatingMode::CFB128, context)
318 }
319
320 pub fn less_safe_cbc_pkcs7(
331 key: UnboundCipherKey,
332 context: EncryptionContext,
333 ) -> Result<Self, Unspecified> {
334 Self::new(key, OperatingMode::CBC, context)
335 }
336}
337
338pub struct StreamingDecryptingKey {
340 algorithm: &'static Algorithm,
341 mode: OperatingMode,
342 cipher_ctx: LcPtr<EVP_CIPHER_CTX>,
343}
344impl StreamingDecryptingKey {
345 #[allow(clippy::needless_pass_by_value)]
346 fn new(
347 key: UnboundCipherKey,
348 mode: OperatingMode,
349 context: DecryptionContext,
350 ) -> Result<Self, Unspecified> {
351 let mut cipher_ctx = LcPtr::new(unsafe { EVP_CIPHER_CTX_new() })?;
352 let algorithm = key.algorithm();
353 let cipher = mode.evp_cipher(key.algorithm);
354 let key_bytes = key.key_bytes.as_ref();
355 debug_assert_eq!(
356 key_bytes.len(),
357 <usize>::try_from(unsafe { EVP_CIPHER_key_length(cipher.as_const_ptr()) }).unwrap()
358 );
359
360 match &context {
361 ctx @ DecryptionContext::Iv128(..) => {
362 let iv = <&[u8]>::try_from(ctx)?;
363 debug_assert_eq!(
364 iv.len(),
365 <usize>::try_from(unsafe { EVP_CIPHER_iv_length(cipher.as_const_ptr()) })
366 .unwrap()
367 );
368 evp_decrypt_init(&mut cipher_ctx, &cipher, key_bytes, Some(iv))?;
369 }
370 DecryptionContext::None => {
371 evp_decrypt_init(&mut cipher_ctx, &cipher, key_bytes, None)?;
372 }
373 }
374
375 Ok(Self {
376 algorithm,
377 mode,
378 cipher_ctx,
379 })
380 }
381
382 pub fn update<'a>(
393 &mut self,
394 input: &[u8],
395 output: &'a mut [u8],
396 ) -> Result<BufferUpdate<'a>, Unspecified> {
397 let mut outlen: i32 = 0;
398 let inlen: i32 = input.len().try_into()?;
399
400 let min_outsize = input
401 .len()
402 .checked_add(self.algorithm().block_len())
403 .ok_or(Unspecified)?;
404 if output.len() < min_outsize {
405 return Err(Unspecified);
406 }
407
408 if 1 != unsafe {
409 EVP_DecryptUpdate(
410 self.cipher_ctx.as_mut_ptr(),
411 output.as_mut_ptr(),
412 &mut outlen,
413 input.as_ptr(),
414 inlen,
415 )
416 } {
417 return Err(Unspecified);
418 }
419 let outlen: usize = outlen.try_into()?;
420 debug_assert!(outlen <= min_outsize);
421 Ok(BufferUpdate::new(output, outlen))
422 }
423
424 pub fn finish(mut self, output: &mut [u8]) -> Result<BufferUpdate<'_>, Unspecified> {
433 if output.len() < self.algorithm().block_len() {
434 return Err(Unspecified);
435 }
436 let mut outlen: i32 = 0;
437
438 if 1 != indicator_check!(unsafe {
439 EVP_DecryptFinal_ex(
440 self.cipher_ctx.as_mut_ptr(),
441 output.as_mut_ptr(),
442 &mut outlen,
443 )
444 }) {
445 return Err(Unspecified);
446 }
447 let outlen: usize = outlen.try_into()?;
448 debug_assert!(outlen <= self.algorithm().block_len());
449 Ok(BufferUpdate::new(output, outlen))
450 }
451
452 #[must_use]
454 pub fn mode(&self) -> OperatingMode {
455 self.mode
456 }
457
458 #[must_use]
460 pub fn algorithm(&self) -> &'static Algorithm {
461 self.algorithm
462 }
463
464 pub fn ctr(key: UnboundCipherKey, context: DecryptionContext) -> Result<Self, Unspecified> {
470 Self::new(key, OperatingMode::CTR, context)
471 }
472
473 pub fn cbc_pkcs7(
479 key: UnboundCipherKey,
480 context: DecryptionContext,
481 ) -> Result<Self, Unspecified> {
482 Self::new(key, OperatingMode::CBC, context)
483 }
484
485 pub fn cfb128(key: UnboundCipherKey, context: DecryptionContext) -> Result<Self, Unspecified> {
491 Self::new(key, OperatingMode::CFB128, context)
492 }
493
494 pub fn ecb_pkcs7(
504 key: UnboundCipherKey,
505 context: DecryptionContext,
506 ) -> Result<Self, Unspecified> {
507 Self::new(key, OperatingMode::ECB, context)
508 }
509}
510
511#[cfg(test)]
512mod tests {
513 use crate::cipher::{
514 DecryptionContext, EncryptionContext, OperatingMode, StreamingDecryptingKey,
515 StreamingEncryptingKey, UnboundCipherKey, AES_128, AES_256, AES_256_KEY_LEN,
516 };
517 use crate::iv::{FixedLength, IV_LEN_128_BIT};
518 use crate::rand::{SecureRandom, SystemRandom};
519 use crate::test::from_hex;
520 use paste::*;
521
522 fn step_encrypt(
523 mut encrypting_key: StreamingEncryptingKey,
524 plaintext: &[u8],
525 step: usize,
526 ) -> (Box<[u8]>, DecryptionContext) {
527 let alg = encrypting_key.algorithm();
528 let mode = encrypting_key.mode();
529 let n = plaintext.len();
530 let mut ciphertext = vec![0u8; n + alg.block_len()];
531
532 let mut in_idx: usize = 0;
533 let mut out_idx: usize = 0;
534 loop {
535 let mut in_end = in_idx + step;
536 if in_end > n {
537 in_end = n;
538 }
539 let out_end = out_idx + (in_end - in_idx) + alg.block_len();
540 let output = encrypting_key
541 .update(
542 &plaintext[in_idx..in_end],
543 &mut ciphertext[out_idx..out_end],
544 )
545 .unwrap();
546 in_idx += step;
547 out_idx += output.written().len();
548 if in_idx >= n {
549 break;
550 }
551 }
552 let out_end = out_idx + alg.block_len();
553 let (decrypt_iv, output) = encrypting_key
554 .finish(&mut ciphertext[out_idx..out_end])
555 .unwrap();
556 let outlen = output.written().len();
557 ciphertext.truncate(out_idx + outlen);
558 match mode {
559 OperatingMode::CBC | OperatingMode::ECB => {
560 assert!(ciphertext.len() > plaintext.len());
561 assert!(ciphertext.len() <= plaintext.len() + alg.block_len());
562 }
563 _ => {
564 assert_eq!(ciphertext.len(), plaintext.len());
565 }
566 }
567
568 (ciphertext.into_boxed_slice(), decrypt_iv)
569 }
570
571 fn step_decrypt(
572 mut decrypting_key: StreamingDecryptingKey,
573 ciphertext: &[u8],
574 step: usize,
575 ) -> Box<[u8]> {
576 let alg = decrypting_key.algorithm();
577 let mode = decrypting_key.mode();
578 let n = ciphertext.len();
579 let mut plaintext = vec![0u8; n + alg.block_len()];
580
581 let mut in_idx: usize = 0;
582 let mut out_idx: usize = 0;
583 loop {
584 let mut in_end = in_idx + step;
585 if in_end > n {
586 in_end = n;
587 }
588 let out_end = out_idx + (in_end - in_idx) + alg.block_len();
589 let output = decrypting_key
590 .update(
591 &ciphertext[in_idx..in_end],
592 &mut plaintext[out_idx..out_end],
593 )
594 .unwrap();
595 in_idx += step;
596 out_idx += output.written().len();
597 if in_idx >= n {
598 break;
599 }
600 }
601 let out_end = out_idx + alg.block_len();
602 let output = decrypting_key
603 .finish(&mut plaintext[out_idx..out_end])
604 .unwrap();
605 let outlen = output.written().len();
606 plaintext.truncate(out_idx + outlen);
607 match mode {
608 OperatingMode::CBC | OperatingMode::ECB => {
609 assert!(ciphertext.len() > plaintext.len());
610 assert!(ciphertext.len() <= plaintext.len() + alg.block_len());
611 }
612 _ => {
613 assert_eq!(ciphertext.len(), plaintext.len());
614 }
615 }
616 plaintext.into_boxed_slice()
617 }
618
619 macro_rules! helper_stream_step_encrypt_test {
620 ($mode:ident) => {
621 paste! {
622 fn [<helper_test_ $mode _stream_encrypt_step_n_bytes>](
623 encrypting_key_creator: impl Fn() -> StreamingEncryptingKey,
624 decrypting_key_creator: impl Fn(DecryptionContext) -> StreamingDecryptingKey,
625 n: usize,
626 step: usize,
627 ) {
628 let mut input = vec![0u8; n];
629 let random = SystemRandom::new();
630 random.fill(&mut input).unwrap();
631
632 let encrypting_key = encrypting_key_creator();
633
634 let (ciphertext, decrypt_iv) = step_encrypt(encrypting_key, &input, step);
635
636 let decrypting_key = decrypting_key_creator(decrypt_iv);
637
638 let plaintext = step_decrypt(decrypting_key, &ciphertext, step);
639
640 assert_eq!(input.as_slice(), &*plaintext);
641 }
642 }
643 };
644 }
645
646 helper_stream_step_encrypt_test!(cbc_pkcs7);
647 helper_stream_step_encrypt_test!(ctr);
648 helper_stream_step_encrypt_test!(cfb128);
649 helper_stream_step_encrypt_test!(ecb_pkcs7);
650
651 #[test]
652 fn test_step_cbc() {
653 let random = SystemRandom::new();
654 let mut key = [0u8; AES_256_KEY_LEN];
655 random.fill(&mut key).unwrap();
656 let key = key;
657
658 let encrypting_key_creator = || {
659 let key = UnboundCipherKey::new(&AES_256, &key.clone()).unwrap();
660 StreamingEncryptingKey::cbc_pkcs7(key).unwrap()
661 };
662 let decrypting_key_creator = |decryption_ctx: DecryptionContext| {
663 let key = UnboundCipherKey::new(&AES_256, &key.clone()).unwrap();
664 StreamingDecryptingKey::cbc_pkcs7(key, decryption_ctx).unwrap()
665 };
666
667 for i in 13..=21 {
668 for j in 124..=131 {
669 helper_test_cbc_pkcs7_stream_encrypt_step_n_bytes(
670 encrypting_key_creator,
671 decrypting_key_creator,
672 j,
673 i,
674 );
675 }
676 for j in 124..=131 {
677 helper_test_cbc_pkcs7_stream_encrypt_step_n_bytes(
678 encrypting_key_creator,
679 decrypting_key_creator,
680 j,
681 j - i,
682 );
683 }
684 }
685 for j in 124..=131 {
686 helper_test_cbc_pkcs7_stream_encrypt_step_n_bytes(
687 encrypting_key_creator,
688 decrypting_key_creator,
689 j,
690 j,
691 );
692 helper_test_cbc_pkcs7_stream_encrypt_step_n_bytes(
693 encrypting_key_creator,
694 decrypting_key_creator,
695 j,
696 256,
697 );
698 helper_test_cbc_pkcs7_stream_encrypt_step_n_bytes(
699 encrypting_key_creator,
700 decrypting_key_creator,
701 j,
702 1,
703 );
704 }
705 }
706
707 #[test]
708 fn test_step_ctr() {
709 let random = SystemRandom::new();
710 let mut key = [0u8; AES_256_KEY_LEN];
711 random.fill(&mut key).unwrap();
712
713 let encrypting_key_creator = || {
714 let key = UnboundCipherKey::new(&AES_256, &key.clone()).unwrap();
715 StreamingEncryptingKey::ctr(key).unwrap()
716 };
717 let decrypting_key_creator = |decryption_ctx: DecryptionContext| {
718 let key = UnboundCipherKey::new(&AES_256, &key.clone()).unwrap();
719 StreamingDecryptingKey::ctr(key, decryption_ctx).unwrap()
720 };
721
722 for i in 13..=21 {
723 for j in 124..=131 {
724 helper_test_ctr_stream_encrypt_step_n_bytes(
725 encrypting_key_creator,
726 decrypting_key_creator,
727 j,
728 i,
729 );
730 }
731 for j in 124..=131 {
732 helper_test_ctr_stream_encrypt_step_n_bytes(
733 encrypting_key_creator,
734 decrypting_key_creator,
735 j,
736 j - i,
737 );
738 }
739 }
740 for j in 124..=131 {
741 helper_test_ctr_stream_encrypt_step_n_bytes(
742 encrypting_key_creator,
743 decrypting_key_creator,
744 j,
745 j,
746 );
747 helper_test_ctr_stream_encrypt_step_n_bytes(
748 encrypting_key_creator,
749 decrypting_key_creator,
750 j,
751 256,
752 );
753 helper_test_ctr_stream_encrypt_step_n_bytes(
754 encrypting_key_creator,
755 decrypting_key_creator,
756 j,
757 1,
758 );
759 }
760 }
761
762 #[test]
763 fn test_step_cfb128() {
764 let random = SystemRandom::new();
765 let mut key = [0u8; AES_256_KEY_LEN];
766 random.fill(&mut key).unwrap();
767
768 let encrypting_key_creator = || {
769 let key = UnboundCipherKey::new(&AES_256, &key.clone()).unwrap();
770 StreamingEncryptingKey::cfb128(key).unwrap()
771 };
772 let decrypting_key_creator = |decryption_ctx: DecryptionContext| {
773 let key = UnboundCipherKey::new(&AES_256, &key.clone()).unwrap();
774 StreamingDecryptingKey::cfb128(key, decryption_ctx).unwrap()
775 };
776
777 for i in 13..=21 {
778 for j in 124..=131 {
779 helper_test_cfb128_stream_encrypt_step_n_bytes(
780 encrypting_key_creator,
781 decrypting_key_creator,
782 j,
783 i,
784 );
785 }
786 for j in 124..=131 {
787 helper_test_cfb128_stream_encrypt_step_n_bytes(
788 encrypting_key_creator,
789 decrypting_key_creator,
790 j,
791 j - i,
792 );
793 }
794 }
795 for j in 124..=131 {
796 helper_test_cfb128_stream_encrypt_step_n_bytes(
797 encrypting_key_creator,
798 decrypting_key_creator,
799 j,
800 j,
801 );
802 helper_test_cfb128_stream_encrypt_step_n_bytes(
803 encrypting_key_creator,
804 decrypting_key_creator,
805 j,
806 256,
807 );
808 helper_test_cfb128_stream_encrypt_step_n_bytes(
809 encrypting_key_creator,
810 decrypting_key_creator,
811 j,
812 1,
813 );
814 }
815 }
816
817 #[test]
818 fn test_step_ecb_pkcs7() {
819 let random = SystemRandom::new();
820 let mut key = [0u8; AES_256_KEY_LEN];
821 random.fill(&mut key).unwrap();
822
823 let encrypting_key_creator = || {
824 let key = UnboundCipherKey::new(&AES_256, &key.clone()).unwrap();
825 StreamingEncryptingKey::ecb_pkcs7(key).unwrap()
826 };
827 let decrypting_key_creator = |decryption_ctx: DecryptionContext| {
828 let key = UnboundCipherKey::new(&AES_256, &key.clone()).unwrap();
829 StreamingDecryptingKey::ecb_pkcs7(key, decryption_ctx).unwrap()
830 };
831
832 for i in 13..=21 {
833 for j in 124..=131 {
834 helper_test_ecb_pkcs7_stream_encrypt_step_n_bytes(
835 encrypting_key_creator,
836 decrypting_key_creator,
837 j,
838 i,
839 );
840 }
841 for j in 124..=131 {
842 helper_test_ecb_pkcs7_stream_encrypt_step_n_bytes(
843 encrypting_key_creator,
844 decrypting_key_creator,
845 j,
846 j - i,
847 );
848 }
849 }
850 for j in 124..=131 {
851 helper_test_ecb_pkcs7_stream_encrypt_step_n_bytes(
852 encrypting_key_creator,
853 decrypting_key_creator,
854 j,
855 j,
856 );
857 helper_test_ecb_pkcs7_stream_encrypt_step_n_bytes(
858 encrypting_key_creator,
859 decrypting_key_creator,
860 j,
861 256,
862 );
863 helper_test_ecb_pkcs7_stream_encrypt_step_n_bytes(
864 encrypting_key_creator,
865 decrypting_key_creator,
866 j,
867 1,
868 );
869 }
870 }
871
872 macro_rules! streaming_cipher_kat {
873 ($name:ident, $alg:expr, $mode:expr, $key:literal, $iv: literal, $plaintext:literal, $ciphertext:literal, $from_step:literal, $to_step:literal) => {
874 #[test]
875 fn $name() {
876 let key = from_hex($key).unwrap();
877 let input = from_hex($plaintext).unwrap();
878 let expected_ciphertext = from_hex($ciphertext).unwrap();
879 let iv = from_hex($iv).unwrap();
880
881 for step in ($from_step..=$to_step) {
882 let ec = EncryptionContext::Iv128(
883 FixedLength::<IV_LEN_128_BIT>::try_from(iv.as_slice()).unwrap(),
884 );
885
886 let unbound_key = UnboundCipherKey::new($alg, &key).unwrap();
887
888 let encrypting_key =
889 StreamingEncryptingKey::new(unbound_key, $mode, ec).unwrap();
890
891 let (ciphertext, decrypt_ctx) = step_encrypt(encrypting_key, &input, step);
892
893 assert_eq!(expected_ciphertext.as_slice(), ciphertext.as_ref());
894
895 let unbound_key2 = UnboundCipherKey::new($alg, &key).unwrap();
896 let decrypting_key =
897 StreamingDecryptingKey::new(unbound_key2, $mode, decrypt_ctx).unwrap();
898
899 let plaintext = step_decrypt(decrypting_key, &ciphertext, step);
900 assert_eq!(input.as_slice(), plaintext.as_ref());
901 }
902 }
903 };
904 ($name:ident, $alg:expr, $mode:expr, $key:literal, $plaintext:literal, $ciphertext:literal, $from_step:literal, $to_step:literal) => {
905 #[test]
906 fn $name() {
907 let key = from_hex($key).unwrap();
908 let input = from_hex($plaintext).unwrap();
909 let expected_ciphertext = from_hex($ciphertext).unwrap();
910
911 for step in ($from_step..=$to_step) {
912 let unbound_key = UnboundCipherKey::new($alg, &key).unwrap();
913
914 let encrypting_key =
915 StreamingEncryptingKey::new(unbound_key, $mode, EncryptionContext::None)
916 .unwrap();
917
918 let (ciphertext, decrypt_ctx) = step_encrypt(encrypting_key, &input, step);
919
920 assert_eq!(expected_ciphertext.as_slice(), ciphertext.as_ref());
921
922 let unbound_key2 = UnboundCipherKey::new($alg, &key).unwrap();
923 let decrypting_key =
924 StreamingDecryptingKey::new(unbound_key2, $mode, decrypt_ctx).unwrap();
925
926 let plaintext = step_decrypt(decrypting_key, &ciphertext, step);
927 assert_eq!(input.as_slice(), plaintext.as_ref());
928 }
929 }
930 };
931 }
932
933 streaming_cipher_kat!(
934 test_iv_aes_128_ctr_16_bytes,
935 &AES_128,
936 OperatingMode::CTR,
937 "000102030405060708090a0b0c0d0e0f",
938 "00000000000000000000000000000000",
939 "00112233445566778899aabbccddeeff",
940 "c6b01904c3da3df5e7d62bd96d153686",
941 2,
942 9
943 );
944 streaming_cipher_kat!(
945 test_iv_aes_256_ctr_15_bytes,
946 &AES_256,
947 OperatingMode::CTR,
948 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
949 "00000000000000000000000000000000",
950 "00112233445566778899aabbccddee",
951 "f28122856e1cf9a7216a30d111f399",
952 2,
953 9
954 );
955
956 streaming_cipher_kat!(
957 test_openssl_aes_128_ctr_15_bytes,
958 &AES_128,
959 OperatingMode::CTR,
960 "244828580821c1652582c76e34d299f5",
961 "093145d5af233f46072a5eb5adc11aa1",
962 "3ee38cec171e6cf466bf0df98aa0e1",
963 "bd7d928f60e3422d96b3f8cd614eb2",
964 2,
965 9
966 );
967
968 streaming_cipher_kat!(
969 test_openssl_aes_256_ctr_15_bytes,
970 &AES_256,
971 OperatingMode::CTR,
972 "0857db8240ea459bdf660b4cced66d1f2d3734ff2de7b81e92740e65e7cc6a1d",
973 "f028ecb053f801102d11fccc9d303a27",
974 "eca7285d19f3c20e295378460e8729",
975 "b5098e5e788de6ac2f2098eb2fc6f8",
976 2,
977 9
978 );
979
980 streaming_cipher_kat!(
981 test_iv_aes_128_cbc_16_bytes,
982 &AES_128,
983 OperatingMode::CBC,
984 "000102030405060708090a0b0c0d0e0f",
985 "00000000000000000000000000000000",
986 "00112233445566778899aabbccddeeff",
987 "69c4e0d86a7b0430d8cdb78070b4c55a9e978e6d16b086570ef794ef97984232",
988 2,
989 9
990 );
991
992 streaming_cipher_kat!(
993 test_iv_aes_256_cbc_15_bytes,
994 &AES_256,
995 OperatingMode::CBC,
996 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
997 "00000000000000000000000000000000",
998 "00112233445566778899aabbccddee",
999 "2ddfb635a651a43f582997966840ca0c",
1000 2,
1001 9
1002 );
1003
1004 streaming_cipher_kat!(
1005 test_openssl_aes_128_cbc_15_bytes,
1006 &AES_128,
1007 OperatingMode::CBC,
1008 "053304bb3899e1d99db9d29343ea782d",
1009 "b5313560244a4822c46c2a0c9d0cf7fd",
1010 "a3e4c990356c01f320043c3d8d6f43",
1011 "ad96993f248bd6a29760ec7ccda95ee1",
1012 2,
1013 9
1014 );
1015
1016 streaming_cipher_kat!(
1017 test_openssl_aes_128_cbc_16_bytes,
1018 &AES_128,
1019 OperatingMode::CBC,
1020 "95af71f1c63e4a1d0b0b1a27fb978283",
1021 "89e40797dca70197ff87d3dbb0ef2802",
1022 "aece7b5e3c3df1ffc9802d2dfe296dc7",
1023 "301b5dab49fb11e919d0d39970d06739301919743304f23f3cbc67d28564b25b",
1024 2,
1025 9
1026 );
1027
1028 streaming_cipher_kat!(
1029 test_openssl_aes_256_cbc_15_bytes,
1030 &AES_256,
1031 OperatingMode::CBC,
1032 "d369e03e9752784917cc7bac1db7399598d9555e691861d9dd7b3292a693ef57",
1033 "1399bb66b2f6ad99a7f064140eaaa885",
1034 "7385f5784b85bf0a97768ddd896d6d",
1035 "4351082bac9b4593ae8848cc9dfb5a01",
1036 2,
1037 9
1038 );
1039
1040 streaming_cipher_kat!(
1041 test_openssl_aes_256_cbc_16_bytes,
1042 &AES_256,
1043 OperatingMode::CBC,
1044 "d4a8206dcae01242f9db79a4ecfe277d0f7bb8ccbafd8f9809adb39f35aa9b41",
1045 "24f6076548fb9d93c8f7ed9f6e661ef9",
1046 "a39c1fdf77ea3e1f18178c0ec237c70a",
1047 "f1af484830a149ee0387b854d65fe87ca0e62efc1c8e6909d4b9ab8666470453",
1048 2,
1049 9
1050 );
1051
1052 streaming_cipher_kat!(
1053 test_openssl_aes_128_cfb128_16_bytes,
1054 &AES_128,
1055 OperatingMode::CFB128,
1056 "5c353f739429bbd48b7e3f9a76facf4d",
1057 "7b2c7ce17a9b6a59a9e64253b98c8cd1",
1058 "add1bcebeaabe9423d4e916400e877c5",
1059 "8440ec442e4135a613ddb2ce26107e10",
1060 2,
1061 9
1062 );
1063
1064 streaming_cipher_kat!(
1065 test_openssl_aes_128_cfb128_15_bytes,
1066 &AES_128,
1067 OperatingMode::CFB128,
1068 "e1f39d70ad378efc1ac318aa8ac4489f",
1069 "ec78c3d54fff2fe09678c7883024ddce",
1070 "b8c905004b2a92a323769f1b8dc1b2",
1071 "964c3e9bf8bf2a3cca02d8e2e75608",
1072 2,
1073 9
1074 );
1075
1076 streaming_cipher_kat!(
1077 test_openssl_aes_256_cfb128_16_bytes,
1078 &AES_256,
1079 OperatingMode::CFB128,
1080 "0e8117d0984d6acb957a5d6ca526a12fa612ce5de2daadebd42c14d28a0a192e",
1081 "09147a153b230a40cd7bf4197ad0e825",
1082 "13f4540a4e06394148ade31a6f678787",
1083 "250e590e47b7613b7d0a53f684e970d6",
1084 2,
1085 9
1086 );
1087
1088 streaming_cipher_kat!(
1089 test_openssl_aes_256_cfb128_15_bytes,
1090 &AES_256,
1091 OperatingMode::CFB128,
1092 "5cb17d8d5b9dbd81e4f1e0a2c82ebf36cf61156388fb7abf99d4526622858225",
1093 "13c77415ec24f3e2f784f228478a85be",
1094 "3efa583df4405aab61e18155aa7e0d",
1095 "c1f2ffe8aa5064199e8f4f1b388303",
1096 2,
1097 9
1098 );
1099
1100 streaming_cipher_kat!(
1101 test_openssl_aes_128_ecb_pkcs7_16_bytes,
1102 &AES_128,
1103 OperatingMode::ECB,
1104 "a1b7cd124f9824a1532d8440f8136788",
1105 "388118e6848b0cea97401707a754d7a1",
1106 "19b7c7f5d9c2bda3f957e9e7d20847828d5eb5624bcbf221014063a87b38d133",
1107 2,
1108 9
1109 );
1110
1111 streaming_cipher_kat!(
1112 test_openssl_aes_128_ecb_pkcs7_15_bytes,
1113 &AES_128,
1114 OperatingMode::ECB,
1115 "d10e12accb837aaffbb284448e53138c",
1116 "b21cfd1c9e6e7e6e912c82c7dd1aa8",
1117 "3d1168e61df34b51c6ab6745c20ee881",
1118 2,
1119 9
1120 );
1121
1122 streaming_cipher_kat!(
1123 test_openssl_aes_256_ecb_pkcs7_16_bytes,
1124 &AES_256,
1125 OperatingMode::ECB,
1126 "0600f4ad4eda4bc8e3e99592abdfce7eb08fee0ccc801c5ccee26134bcaafbbd",
1127 "516b45cb1342239a549bd8c1d5998f98",
1128 "854c593555a213e4a862c6f66aa4a79631faca131eba6f163e5cd3940e9c0a57",
1129 2,
1130 9
1131 );
1132
1133 streaming_cipher_kat!(
1134 test_openssl_aes_256_ecb_pkcs7_15_bytes,
1135 &AES_256,
1136 OperatingMode::ECB,
1137 "80f235756c8f70094ae1f99a95a599c27c4452a4b8412fd934e2b253f7098508",
1138 "2235590b90190d7a1dc2464a0205ad",
1139 "8547d8ac8dc6d9cebb2dc77a7034bb67",
1140 2,
1141 9
1142 );
1143}