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