aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-03-12 19:30:20 +0000
committerGitHub <[email protected]>2024-03-12 19:30:20 +0000
commit35f284ec22848d7085e00f377136fd66067ca756 (patch)
treefc86df7234ecca8ac8609b34cc907f5ab74f3cf0
parent9101b9eb012332888512982b943f6141adb15f06 (diff)
parentb1ba2729878a1553145f215dff40281c65b75983 (diff)
Merge pull request #2691 from caleb-garrett/cryp-dma
STM32 CRYP DMA
-rw-r--r--embassy-stm32/build.rs2
-rw-r--r--embassy-stm32/src/cryp/mod.rs875
-rw-r--r--examples/stm32f7/src/bin/cryp.rs28
-rw-r--r--tests/stm32/src/bin/cryp.rs30
-rw-r--r--tests/stm32/src/common.rs1
5 files changed, 758 insertions, 178 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 84e8be25d..70f4515db 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -1121,6 +1121,8 @@ fn main() {
1121 (("dac", "CH2"), quote!(crate::dac::DacDma2)), 1121 (("dac", "CH2"), quote!(crate::dac::DacDma2)),
1122 (("timer", "UP"), quote!(crate::timer::UpDma)), 1122 (("timer", "UP"), quote!(crate::timer::UpDma)),
1123 (("hash", "IN"), quote!(crate::hash::Dma)), 1123 (("hash", "IN"), quote!(crate::hash::Dma)),
1124 (("cryp", "IN"), quote!(crate::cryp::DmaIn)),
1125 (("cryp", "OUT"), quote!(crate::cryp::DmaOut)),
1124 (("timer", "CH1"), quote!(crate::timer::Ch1Dma)), 1126 (("timer", "CH1"), quote!(crate::timer::Ch1Dma)),
1125 (("timer", "CH2"), quote!(crate::timer::Ch2Dma)), 1127 (("timer", "CH2"), quote!(crate::timer::Ch2Dma)),
1126 (("timer", "CH3"), quote!(crate::timer::Ch3Dma)), 1128 (("timer", "CH3"), quote!(crate::timer::Ch3Dma)),
diff --git a/embassy-stm32/src/cryp/mod.rs b/embassy-stm32/src/cryp/mod.rs
index 8f259520a..74b095b6f 100644
--- a/embassy-stm32/src/cryp/mod.rs
+++ b/embassy-stm32/src/cryp/mod.rs
@@ -2,14 +2,39 @@
2#[cfg(any(cryp_v2, cryp_v3))] 2#[cfg(any(cryp_v2, cryp_v3))]
3use core::cmp::min; 3use core::cmp::min;
4use core::marker::PhantomData; 4use core::marker::PhantomData;
5use core::ptr;
5 6
6use embassy_hal_internal::{into_ref, PeripheralRef}; 7use embassy_hal_internal::{into_ref, PeripheralRef};
8use embassy_sync::waitqueue::AtomicWaker;
7 9
10use crate::dma::{NoDma, Priority, Transfer, TransferOptions};
11use crate::interrupt::typelevel::Interrupt;
8use crate::{interrupt, pac, peripherals, Peripheral}; 12use crate::{interrupt, pac, peripherals, Peripheral};
9 13
10const DES_BLOCK_SIZE: usize = 8; // 64 bits 14const DES_BLOCK_SIZE: usize = 8; // 64 bits
11const AES_BLOCK_SIZE: usize = 16; // 128 bits 15const AES_BLOCK_SIZE: usize = 16; // 128 bits
12 16
17static CRYP_WAKER: AtomicWaker = AtomicWaker::new();
18
19/// CRYP interrupt handler.
20pub struct InterruptHandler<T: Instance> {
21 _phantom: PhantomData<T>,
22}
23
24impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
25 unsafe fn on_interrupt() {
26 let bits = T::regs().misr().read();
27 if bits.inmis() {
28 T::regs().imscr().modify(|w| w.set_inim(false));
29 CRYP_WAKER.wake();
30 }
31 if bits.outmis() {
32 T::regs().imscr().modify(|w| w.set_outim(false));
33 CRYP_WAKER.wake();
34 }
35 }
36}
37
13/// This trait encapsulates all cipher-specific behavior/ 38/// This trait encapsulates all cipher-specific behavior/
14pub trait Cipher<'c> { 39pub trait Cipher<'c> {
15 /// Processing block size. Determined by the processor and the algorithm. 40 /// Processing block size. Determined by the processor and the algorithm.
@@ -32,17 +57,26 @@ pub trait Cipher<'c> {
32 fn prepare_key(&self, _p: &pac::cryp::Cryp) {} 57 fn prepare_key(&self, _p: &pac::cryp::Cryp) {}
33 58
34 /// Performs any cipher-specific initialization. 59 /// Performs any cipher-specific initialization.
35 fn init_phase(&self, _p: &pac::cryp::Cryp) {} 60 fn init_phase_blocking<T: Instance, DmaIn, DmaOut>(&self, _p: &pac::cryp::Cryp, _cryp: &Cryp<T, DmaIn, DmaOut>) {}
61
62 /// Performs any cipher-specific initialization.
63 async fn init_phase<T: Instance, DmaIn, DmaOut>(&self, _p: &pac::cryp::Cryp, _cryp: &mut Cryp<'_, T, DmaIn, DmaOut>)
64 where
65 DmaIn: crate::cryp::DmaIn<T>,
66 DmaOut: crate::cryp::DmaOut<T>,
67 {
68 }
36 69
37 /// Called prior to processing the last data block for cipher-specific operations. 70 /// Called prior to processing the last data block for cipher-specific operations.
38 fn pre_final_block(&self, _p: &pac::cryp::Cryp, _dir: Direction, _padding_len: usize) -> [u32; 4] { 71 fn pre_final(&self, _p: &pac::cryp::Cryp, _dir: Direction, _padding_len: usize) -> [u32; 4] {
39 return [0; 4]; 72 return [0; 4];
40 } 73 }
41 74
42 /// Called after processing the last data block for cipher-specific operations. 75 /// Called after processing the last data block for cipher-specific operations.
43 fn post_final_block( 76 fn post_final_blocking<T: Instance, DmaIn, DmaOut>(
44 &self, 77 &self,
45 _p: &pac::cryp::Cryp, 78 _p: &pac::cryp::Cryp,
79 _cryp: &Cryp<T, DmaIn, DmaOut>,
46 _dir: Direction, 80 _dir: Direction,
47 _int_data: &mut [u8; AES_BLOCK_SIZE], 81 _int_data: &mut [u8; AES_BLOCK_SIZE],
48 _temp1: [u32; 4], 82 _temp1: [u32; 4],
@@ -50,7 +84,22 @@ pub trait Cipher<'c> {
50 ) { 84 ) {
51 } 85 }
52 86
53 /// Called prior to processing the first associated data block for cipher-specific operations. 87 /// Called after processing the last data block for cipher-specific operations.
88 async fn post_final<T: Instance, DmaIn, DmaOut>(
89 &self,
90 _p: &pac::cryp::Cryp,
91 _cryp: &mut Cryp<'_, T, DmaIn, DmaOut>,
92 _dir: Direction,
93 _int_data: &mut [u8; AES_BLOCK_SIZE],
94 _temp1: [u32; 4],
95 _padding_mask: [u8; 16],
96 ) where
97 DmaIn: crate::cryp::DmaIn<T>,
98 DmaOut: crate::cryp::DmaOut<T>,
99 {
100 }
101
102 /// Returns the AAD header block as required by the cipher.
54 fn get_header_block(&self) -> &[u8] { 103 fn get_header_block(&self) -> &[u8] {
55 return [0; 0].as_slice(); 104 return [0; 0].as_slice();
56 } 105 }
@@ -425,14 +474,24 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGcm<'c, KEY_SIZE> {
425 p.cr().modify(|w| w.set_algomode3(true)); 474 p.cr().modify(|w| w.set_algomode3(true));
426 } 475 }
427 476
428 fn init_phase(&self, p: &pac::cryp::Cryp) { 477 fn init_phase_blocking<T: Instance, DmaIn, DmaOut>(&self, p: &pac::cryp::Cryp, _cryp: &Cryp<T, DmaIn, DmaOut>) {
478 p.cr().modify(|w| w.set_gcm_ccmph(0));
479 p.cr().modify(|w| w.set_crypen(true));
480 while p.cr().read().crypen() {}
481 }
482
483 async fn init_phase<T: Instance, DmaIn, DmaOut>(
484 &self,
485 p: &pac::cryp::Cryp,
486 _cryp: &mut Cryp<'_, T, DmaIn, DmaOut>,
487 ) {
429 p.cr().modify(|w| w.set_gcm_ccmph(0)); 488 p.cr().modify(|w| w.set_gcm_ccmph(0));
430 p.cr().modify(|w| w.set_crypen(true)); 489 p.cr().modify(|w| w.set_crypen(true));
431 while p.cr().read().crypen() {} 490 while p.cr().read().crypen() {}
432 } 491 }
433 492
434 #[cfg(cryp_v2)] 493 #[cfg(cryp_v2)]
435 fn pre_final_block(&self, p: &pac::cryp::Cryp, dir: Direction, _padding_len: usize) -> [u32; 4] { 494 fn pre_final(&self, p: &pac::cryp::Cryp, dir: Direction, _padding_len: usize) -> [u32; 4] {
436 //Handle special GCM partial block process. 495 //Handle special GCM partial block process.
437 if dir == Direction::Encrypt { 496 if dir == Direction::Encrypt {
438 p.cr().modify(|w| w.set_crypen(false)); 497 p.cr().modify(|w| w.set_crypen(false));
@@ -446,16 +505,17 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGcm<'c, KEY_SIZE> {
446 } 505 }
447 506
448 #[cfg(cryp_v3)] 507 #[cfg(cryp_v3)]
449 fn pre_final_block(&self, p: &pac::cryp::Cryp, _dir: Direction, padding_len: usize) -> [u32; 4] { 508 fn pre_final(&self, p: &pac::cryp::Cryp, _dir: Direction, padding_len: usize) -> [u32; 4] {
450 //Handle special GCM partial block process. 509 //Handle special GCM partial block process.
451 p.cr().modify(|w| w.set_npblb(padding_len as u8)); 510 p.cr().modify(|w| w.set_npblb(padding_len as u8));
452 [0; 4] 511 [0; 4]
453 } 512 }
454 513
455 #[cfg(cryp_v2)] 514 #[cfg(cryp_v2)]
456 fn post_final_block( 515 fn post_final_blocking<T: Instance, DmaIn, DmaOut>(
457 &self, 516 &self,
458 p: &pac::cryp::Cryp, 517 p: &pac::cryp::Cryp,
518 cryp: &Cryp<T, DmaIn, DmaOut>,
459 dir: Direction, 519 dir: Direction,
460 int_data: &mut [u8; AES_BLOCK_SIZE], 520 int_data: &mut [u8; AES_BLOCK_SIZE],
461 _temp1: [u32; 4], 521 _temp1: [u32; 4],
@@ -471,17 +531,44 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGcm<'c, KEY_SIZE> {
471 } 531 }
472 p.cr().modify(|w| w.set_crypen(true)); 532 p.cr().modify(|w| w.set_crypen(true));
473 p.cr().modify(|w| w.set_gcm_ccmph(3)); 533 p.cr().modify(|w| w.set_gcm_ccmph(3));
474 let mut index = 0; 534
475 let end_index = Self::BLOCK_SIZE; 535 cryp.write_bytes_blocking(Self::BLOCK_SIZE, int_data);
476 while index < end_index { 536 cryp.read_bytes_blocking(Self::BLOCK_SIZE, int_data);
477 let mut in_word: [u8; 4] = [0; 4]; 537 }
478 in_word.copy_from_slice(&int_data[index..index + 4]); 538 }
479 p.din().write_value(u32::from_ne_bytes(in_word)); 539
480 index += 4; 540 #[cfg(cryp_v2)]
481 } 541 async fn post_final<T: Instance, DmaIn, DmaOut>(
482 for _ in 0..4 { 542 &self,
483 p.dout().read(); 543 p: &pac::cryp::Cryp,
544 cryp: &mut Cryp<'_, T, DmaIn, DmaOut>,
545 dir: Direction,
546 int_data: &mut [u8; AES_BLOCK_SIZE],
547 _temp1: [u32; 4],
548 padding_mask: [u8; AES_BLOCK_SIZE],
549 ) where
550 DmaIn: crate::cryp::DmaIn<T>,
551 DmaOut: crate::cryp::DmaOut<T>,
552 {
553 if dir == Direction::Encrypt {
554 // Handle special GCM partial block process.
555 p.cr().modify(|w| w.set_crypen(false));
556 p.cr().modify(|w| w.set_algomode3(true));
557 p.cr().modify(|w| w.set_algomode0(0));
558 for i in 0..AES_BLOCK_SIZE {
559 int_data[i] = int_data[i] & padding_mask[i];
484 } 560 }
561 p.cr().modify(|w| w.set_crypen(true));
562 p.cr().modify(|w| w.set_gcm_ccmph(3));
563
564 let mut out_data: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE];
565
566 let read = Cryp::<T, DmaIn, DmaOut>::read_bytes(&mut cryp.outdma, Self::BLOCK_SIZE, &mut out_data);
567 let write = Cryp::<T, DmaIn, DmaOut>::write_bytes(&mut cryp.indma, Self::BLOCK_SIZE, int_data);
568
569 embassy_futures::join::join(read, write).await;
570
571 int_data.copy_from_slice(&out_data);
485 } 572 }
486 } 573 }
487} 574}
@@ -532,14 +619,24 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGmac<'c, KEY_SIZE> {
532 p.cr().modify(|w| w.set_algomode3(true)); 619 p.cr().modify(|w| w.set_algomode3(true));
533 } 620 }
534 621
535 fn init_phase(&self, p: &pac::cryp::Cryp) { 622 fn init_phase_blocking<T: Instance, DmaIn, DmaOut>(&self, p: &pac::cryp::Cryp, _cryp: &Cryp<T, DmaIn, DmaOut>) {
623 p.cr().modify(|w| w.set_gcm_ccmph(0));
624 p.cr().modify(|w| w.set_crypen(true));
625 while p.cr().read().crypen() {}
626 }
627
628 async fn init_phase<T: Instance, DmaIn, DmaOut>(
629 &self,
630 p: &pac::cryp::Cryp,
631 _cryp: &mut Cryp<'_, T, DmaIn, DmaOut>,
632 ) {
536 p.cr().modify(|w| w.set_gcm_ccmph(0)); 633 p.cr().modify(|w| w.set_gcm_ccmph(0));
537 p.cr().modify(|w| w.set_crypen(true)); 634 p.cr().modify(|w| w.set_crypen(true));
538 while p.cr().read().crypen() {} 635 while p.cr().read().crypen() {}
539 } 636 }
540 637
541 #[cfg(cryp_v2)] 638 #[cfg(cryp_v2)]
542 fn pre_final_block(&self, p: &pac::cryp::Cryp, dir: Direction, _padding_len: usize) -> [u32; 4] { 639 fn pre_final(&self, p: &pac::cryp::Cryp, dir: Direction, _padding_len: usize) -> [u32; 4] {
543 //Handle special GCM partial block process. 640 //Handle special GCM partial block process.
544 if dir == Direction::Encrypt { 641 if dir == Direction::Encrypt {
545 p.cr().modify(|w| w.set_crypen(false)); 642 p.cr().modify(|w| w.set_crypen(false));
@@ -553,16 +650,17 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGmac<'c, KEY_SIZE> {
553 } 650 }
554 651
555 #[cfg(cryp_v3)] 652 #[cfg(cryp_v3)]
556 fn pre_final_block(&self, p: &pac::cryp::Cryp, _dir: Direction, padding_len: usize) -> [u32; 4] { 653 fn pre_final(&self, p: &pac::cryp::Cryp, _dir: Direction, padding_len: usize) -> [u32; 4] {
557 //Handle special GCM partial block process. 654 //Handle special GCM partial block process.
558 p.cr().modify(|w| w.set_npblb(padding_len as u8)); 655 p.cr().modify(|w| w.set_npblb(padding_len as u8));
559 [0; 4] 656 [0; 4]
560 } 657 }
561 658
562 #[cfg(cryp_v2)] 659 #[cfg(cryp_v2)]
563 fn post_final_block( 660 fn post_final_blocking<T: Instance, DmaIn, DmaOut>(
564 &self, 661 &self,
565 p: &pac::cryp::Cryp, 662 p: &pac::cryp::Cryp,
663 cryp: &Cryp<T, DmaIn, DmaOut>,
566 dir: Direction, 664 dir: Direction,
567 int_data: &mut [u8; AES_BLOCK_SIZE], 665 int_data: &mut [u8; AES_BLOCK_SIZE],
568 _temp1: [u32; 4], 666 _temp1: [u32; 4],
@@ -578,17 +676,42 @@ impl<'c, const KEY_SIZE: usize> Cipher<'c> for AesGmac<'c, KEY_SIZE> {
578 } 676 }
579 p.cr().modify(|w| w.set_crypen(true)); 677 p.cr().modify(|w| w.set_crypen(true));
580 p.cr().modify(|w| w.set_gcm_ccmph(3)); 678 p.cr().modify(|w| w.set_gcm_ccmph(3));
581 let mut index = 0; 679
582 let end_index = Self::BLOCK_SIZE; 680 cryp.write_bytes_blocking(Self::BLOCK_SIZE, int_data);
583 while index < end_index { 681 cryp.read_bytes_blocking(Self::BLOCK_SIZE, int_data);
584 let mut in_word: [u8; 4] = [0; 4]; 682 }
585 in_word.copy_from_slice(&int_data[index..index + 4]); 683 }
586 p.din().write_value(u32::from_ne_bytes(in_word)); 684
587 index += 4; 685 #[cfg(cryp_v2)]
588 } 686 async fn post_final<T: Instance, DmaIn, DmaOut>(
589 for _ in 0..4 { 687 &self,
590 p.dout().read(); 688 p: &pac::cryp::Cryp,
689 cryp: &mut Cryp<'_, T, DmaIn, DmaOut>,
690 dir: Direction,
691 int_data: &mut [u8; AES_BLOCK_SIZE],
692 _temp1: [u32; 4],
693 padding_mask: [u8; AES_BLOCK_SIZE],
694 ) where
695 DmaIn: crate::cryp::DmaIn<T>,
696 DmaOut: crate::cryp::DmaOut<T>,
697 {
698 if dir == Direction::Encrypt {
699 // Handle special GCM partial block process.
700 p.cr().modify(|w| w.set_crypen(false));
701 p.cr().modify(|w| w.set_algomode3(true));
702 p.cr().modify(|w| w.set_algomode0(0));
703 for i in 0..AES_BLOCK_SIZE {
704 int_data[i] = int_data[i] & padding_mask[i];
591 } 705 }
706 p.cr().modify(|w| w.set_crypen(true));
707 p.cr().modify(|w| w.set_gcm_ccmph(3));
708
709 let mut out_data: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE];
710
711 let read = Cryp::<T, DmaIn, DmaOut>::read_bytes(&mut cryp.outdma, Self::BLOCK_SIZE, &mut out_data);
712 let write = Cryp::<T, DmaIn, DmaOut>::write_bytes(&mut cryp.indma, Self::BLOCK_SIZE, int_data);
713
714 embassy_futures::join::join(read, write).await;
592 } 715 }
593 } 716 }
594} 717}
@@ -697,18 +820,24 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cip
697 p.cr().modify(|w| w.set_algomode3(true)); 820 p.cr().modify(|w| w.set_algomode3(true));
698 } 821 }
699 822
700 fn init_phase(&self, p: &pac::cryp::Cryp) { 823 fn init_phase_blocking<T: Instance, DmaIn, DmaOut>(&self, p: &pac::cryp::Cryp, cryp: &Cryp<T, DmaIn, DmaOut>) {
701 p.cr().modify(|w| w.set_gcm_ccmph(0)); 824 p.cr().modify(|w| w.set_gcm_ccmph(0));
702 825
703 let mut index = 0; 826 cryp.write_bytes_blocking(Self::BLOCK_SIZE, &self.block0);
704 let end_index = index + Self::BLOCK_SIZE; 827
705 // Write block in 828 p.cr().modify(|w| w.set_crypen(true));
706 while index < end_index { 829 while p.cr().read().crypen() {}
707 let mut in_word: [u8; 4] = [0; 4]; 830 }
708 in_word.copy_from_slice(&self.block0[index..index + 4]); 831
709 p.din().write_value(u32::from_ne_bytes(in_word)); 832 async fn init_phase<T: Instance, DmaIn, DmaOut>(&self, p: &pac::cryp::Cryp, cryp: &mut Cryp<'_, T, DmaIn, DmaOut>)
710 index += 4; 833 where
711 } 834 DmaIn: crate::cryp::DmaIn<T>,
835 DmaOut: crate::cryp::DmaOut<T>,
836 {
837 p.cr().modify(|w| w.set_gcm_ccmph(0));
838
839 Cryp::<T, DmaIn, DmaOut>::write_bytes(&mut cryp.indma, Self::BLOCK_SIZE, &self.block0).await;
840
712 p.cr().modify(|w| w.set_crypen(true)); 841 p.cr().modify(|w| w.set_crypen(true));
713 while p.cr().read().crypen() {} 842 while p.cr().read().crypen() {}
714 } 843 }
@@ -718,7 +847,7 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cip
718 } 847 }
719 848
720 #[cfg(cryp_v2)] 849 #[cfg(cryp_v2)]
721 fn pre_final_block(&self, p: &pac::cryp::Cryp, dir: Direction, _padding_len: usize) -> [u32; 4] { 850 fn pre_final(&self, p: &pac::cryp::Cryp, dir: Direction, _padding_len: usize) -> [u32; 4] {
722 //Handle special CCM partial block process. 851 //Handle special CCM partial block process.
723 let mut temp1 = [0; 4]; 852 let mut temp1 = [0; 4];
724 if dir == Direction::Decrypt { 853 if dir == Direction::Decrypt {
@@ -737,16 +866,17 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cip
737 } 866 }
738 867
739 #[cfg(cryp_v3)] 868 #[cfg(cryp_v3)]
740 fn pre_final_block(&self, p: &pac::cryp::Cryp, _dir: Direction, padding_len: usize) -> [u32; 4] { 869 fn pre_final(&self, p: &pac::cryp::Cryp, _dir: Direction, padding_len: usize) -> [u32; 4] {
741 //Handle special GCM partial block process. 870 //Handle special GCM partial block process.
742 p.cr().modify(|w| w.set_npblb(padding_len as u8)); 871 p.cr().modify(|w| w.set_npblb(padding_len as u8));
743 [0; 4] 872 [0; 4]
744 } 873 }
745 874
746 #[cfg(cryp_v2)] 875 #[cfg(cryp_v2)]
747 fn post_final_block( 876 fn post_final_blocking<T: Instance, DmaIn, DmaOut>(
748 &self, 877 &self,
749 p: &pac::cryp::Cryp, 878 p: &pac::cryp::Cryp,
879 cryp: &Cryp<T, DmaIn, DmaOut>,
750 dir: Direction, 880 dir: Direction,
751 int_data: &mut [u8; AES_BLOCK_SIZE], 881 int_data: &mut [u8; AES_BLOCK_SIZE],
752 temp1: [u32; 4], 882 temp1: [u32; 4],
@@ -774,8 +904,48 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Cip
774 let int_word = u32::from_le_bytes(int_bytes); 904 let int_word = u32::from_le_bytes(int_bytes);
775 in_data[i] = int_word; 905 in_data[i] = int_word;
776 in_data[i] = in_data[i] ^ temp1[i] ^ temp2[i]; 906 in_data[i] = in_data[i] ^ temp1[i] ^ temp2[i];
777 p.din().write_value(in_data[i]);
778 } 907 }
908 cryp.write_words_blocking(Self::BLOCK_SIZE, &in_data);
909 }
910 }
911
912 #[cfg(cryp_v2)]
913 async fn post_final<T: Instance, DmaIn, DmaOut>(
914 &self,
915 p: &pac::cryp::Cryp,
916 cryp: &mut Cryp<'_, T, DmaIn, DmaOut>,
917 dir: Direction,
918 int_data: &mut [u8; AES_BLOCK_SIZE],
919 temp1: [u32; 4],
920 padding_mask: [u8; 16],
921 ) where
922 DmaIn: crate::cryp::DmaIn<T>,
923 DmaOut: crate::cryp::DmaOut<T>,
924 {
925 if dir == Direction::Decrypt {
926 //Handle special CCM partial block process.
927 let mut temp2 = [0; 4];
928 temp2[0] = p.csgcmccmr(0).read().swap_bytes();
929 temp2[1] = p.csgcmccmr(1).read().swap_bytes();
930 temp2[2] = p.csgcmccmr(2).read().swap_bytes();
931 temp2[3] = p.csgcmccmr(3).read().swap_bytes();
932 p.cr().modify(|w| w.set_algomode3(true));
933 p.cr().modify(|w| w.set_algomode0(1));
934 p.cr().modify(|w| w.set_gcm_ccmph(3));
935 // Header phase
936 p.cr().modify(|w| w.set_gcm_ccmph(1));
937 for i in 0..AES_BLOCK_SIZE {
938 int_data[i] = int_data[i] & padding_mask[i];
939 }
940 let mut in_data: [u32; 4] = [0; 4];
941 for i in 0..in_data.len() {
942 let mut int_bytes: [u8; 4] = [0; 4];
943 int_bytes.copy_from_slice(&int_data[(i * 4)..(i * 4) + 4]);
944 let int_word = u32::from_le_bytes(int_bytes);
945 in_data[i] = int_word;
946 in_data[i] = in_data[i] ^ temp1[i] ^ temp2[i];
947 }
948 Cryp::<T, DmaIn, DmaOut>::write_words(&mut cryp.indma, Self::BLOCK_SIZE, &in_data).await;
779 } 949 }
780 } 950 }
781} 951}
@@ -845,24 +1015,40 @@ pub enum Direction {
845} 1015}
846 1016
847/// Crypto Accelerator Driver 1017/// Crypto Accelerator Driver
848pub struct Cryp<'d, T: Instance> { 1018pub struct Cryp<'d, T: Instance, DmaIn = NoDma, DmaOut = NoDma> {
849 _peripheral: PeripheralRef<'d, T>, 1019 _peripheral: PeripheralRef<'d, T>,
1020 indma: PeripheralRef<'d, DmaIn>,
1021 outdma: PeripheralRef<'d, DmaOut>,
850} 1022}
851 1023
852impl<'d, T: Instance> Cryp<'d, T> { 1024impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
853 /// Create a new CRYP driver. 1025 /// Create a new CRYP driver.
854 pub fn new(peri: impl Peripheral<P = T> + 'd) -> Self { 1026 pub fn new(
1027 peri: impl Peripheral<P = T> + 'd,
1028 indma: impl Peripheral<P = DmaIn> + 'd,
1029 outdma: impl Peripheral<P = DmaOut> + 'd,
1030 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
1031 ) -> Self {
855 T::enable_and_reset(); 1032 T::enable_and_reset();
856 into_ref!(peri); 1033 into_ref!(peri, indma, outdma);
857 let instance = Self { _peripheral: peri }; 1034 let instance = Self {
1035 _peripheral: peri,
1036 indma: indma,
1037 outdma: outdma,
1038 };
1039
1040 T::Interrupt::unpend();
1041 unsafe { T::Interrupt::enable() };
1042
858 instance 1043 instance
859 } 1044 }
860 1045
861 /// Start a new cipher operation. 1046 /// Start a new encrypt or decrypt operation for the given cipher.
862 /// Key size must be 128, 192, or 256 bits. 1047 pub fn start_blocking<'c, C: Cipher<'c> + CipherSized + IVSized>(
863 /// Initialization vector must only be supplied if necessary. 1048 &self,
864 /// Panics if there is any mismatch in parameters, such as an incorrect IV length or invalid mode. 1049 cipher: &'c C,
865 pub fn start<'c, C: Cipher<'c> + CipherSized + IVSized>(&self, cipher: &'c C, dir: Direction) -> Context<'c, C> { 1050 dir: Direction,
1051 ) -> Context<'c, C> {
866 let mut ctx: Context<'c, C> = Context { 1052 let mut ctx: Context<'c, C> = Context {
867 dir, 1053 dir,
868 last_block_processed: false, 1054 last_block_processed: false,
@@ -929,7 +1115,90 @@ impl<'d, T: Instance> Cryp<'d, T> {
929 // Flush in/out FIFOs 1115 // Flush in/out FIFOs
930 T::regs().cr().modify(|w| w.fflush()); 1116 T::regs().cr().modify(|w| w.fflush());
931 1117
932 ctx.cipher.init_phase(&T::regs()); 1118 ctx.cipher.init_phase_blocking(&T::regs(), self);
1119
1120 self.store_context(&mut ctx);
1121
1122 ctx
1123 }
1124
1125 /// Start a new encrypt or decrypt operation for the given cipher.
1126 pub async fn start<'c, C: Cipher<'c> + CipherSized + IVSized>(
1127 &mut self,
1128 cipher: &'c C,
1129 dir: Direction,
1130 ) -> Context<'c, C>
1131 where
1132 DmaIn: crate::cryp::DmaIn<T>,
1133 DmaOut: crate::cryp::DmaOut<T>,
1134 {
1135 let mut ctx: Context<'c, C> = Context {
1136 dir,
1137 last_block_processed: false,
1138 cr: 0,
1139 iv: [0; 4],
1140 csgcmccm: [0; 8],
1141 csgcm: [0; 8],
1142 aad_complete: false,
1143 header_len: 0,
1144 payload_len: 0,
1145 cipher: cipher,
1146 phantom_data: PhantomData,
1147 header_processed: false,
1148 aad_buffer: [0; 16],
1149 aad_buffer_len: 0,
1150 };
1151
1152 T::regs().cr().modify(|w| w.set_crypen(false));
1153
1154 let key = ctx.cipher.key();
1155
1156 if key.len() == (128 / 8) {
1157 T::regs().cr().modify(|w| w.set_keysize(0));
1158 } else if key.len() == (192 / 8) {
1159 T::regs().cr().modify(|w| w.set_keysize(1));
1160 } else if key.len() == (256 / 8) {
1161 T::regs().cr().modify(|w| w.set_keysize(2));
1162 }
1163
1164 self.load_key(key);
1165
1166 // Set data type to 8-bit. This will match software implementations.
1167 T::regs().cr().modify(|w| w.set_datatype(2));
1168
1169 ctx.cipher.prepare_key(&T::regs());
1170
1171 ctx.cipher.set_algomode(&T::regs());
1172
1173 // Set encrypt/decrypt
1174 if dir == Direction::Encrypt {
1175 T::regs().cr().modify(|w| w.set_algodir(false));
1176 } else {
1177 T::regs().cr().modify(|w| w.set_algodir(true));
1178 }
1179
1180 // Load the IV into the registers.
1181 let iv = ctx.cipher.iv();
1182 let mut full_iv: [u8; 16] = [0; 16];
1183 full_iv[0..iv.len()].copy_from_slice(iv);
1184 let mut iv_idx = 0;
1185 let mut iv_word: [u8; 4] = [0; 4];
1186 iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]);
1187 iv_idx += 4;
1188 T::regs().init(0).ivlr().write_value(u32::from_be_bytes(iv_word));
1189 iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]);
1190 iv_idx += 4;
1191 T::regs().init(0).ivrr().write_value(u32::from_be_bytes(iv_word));
1192 iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]);
1193 iv_idx += 4;
1194 T::regs().init(1).ivlr().write_value(u32::from_be_bytes(iv_word));
1195 iv_word.copy_from_slice(&full_iv[iv_idx..iv_idx + 4]);
1196 T::regs().init(1).ivrr().write_value(u32::from_be_bytes(iv_word));
1197
1198 // Flush in/out FIFOs
1199 T::regs().cr().modify(|w| w.fflush());
1200
1201 ctx.cipher.init_phase(&T::regs(), self).await;
933 1202
934 self.store_context(&mut ctx); 1203 self.store_context(&mut ctx);
935 1204
@@ -938,10 +1207,9 @@ impl<'d, T: Instance> Cryp<'d, T> {
938 1207
939 #[cfg(any(cryp_v2, cryp_v3))] 1208 #[cfg(any(cryp_v2, cryp_v3))]
940 /// Controls the header phase of cipher processing. 1209 /// Controls the header phase of cipher processing.
941 /// This function is only valid for GCM, CCM, and GMAC modes. 1210 /// This function is only valid for authenticated ciphers including GCM, CCM, and GMAC.
942 /// It only needs to be called if using one of these modes and there is associated data. 1211 /// All additional associated data (AAD) must be supplied to this function prior to starting the payload phase with `payload_blocking`.
943 /// All AAD must be supplied to this function prior to starting the payload phase with `payload_blocking`. 1212 /// The AAD must be supplied in multiples of the block size (128-bits for AES, 64-bits for DES), except when supplying the last block.
944 /// The AAD must be supplied in multiples of the block size (128 bits), except when supplying the last block.
945 /// When supplying the last block of AAD, `last_aad_block` must be `true`. 1213 /// When supplying the last block of AAD, `last_aad_block` must be `true`.
946 pub fn aad_blocking< 1214 pub fn aad_blocking<
947 'c, 1215 'c,
@@ -985,15 +1253,7 @@ impl<'d, T: Instance> Cryp<'d, T> {
985 if ctx.aad_buffer_len < C::BLOCK_SIZE { 1253 if ctx.aad_buffer_len < C::BLOCK_SIZE {
986 // The buffer isn't full and this is the last buffer, so process it as is (already padded). 1254 // The buffer isn't full and this is the last buffer, so process it as is (already padded).
987 if last_aad_block { 1255 if last_aad_block {
988 let mut index = 0; 1256 self.write_bytes_blocking(C::BLOCK_SIZE, &ctx.aad_buffer);
989 let end_index = C::BLOCK_SIZE;
990 // Write block in
991 while index < end_index {
992 let mut in_word: [u8; 4] = [0; 4];
993 in_word.copy_from_slice(&ctx.aad_buffer[index..index + 4]);
994 T::regs().din().write_value(u32::from_ne_bytes(in_word));
995 index += 4;
996 }
997 // Block until input FIFO is empty. 1257 // Block until input FIFO is empty.
998 while !T::regs().sr().read().ifem() {} 1258 while !T::regs().sr().read().ifem() {}
999 1259
@@ -1008,15 +1268,7 @@ impl<'d, T: Instance> Cryp<'d, T> {
1008 } 1268 }
1009 } else { 1269 } else {
1010 // Load the full block from the buffer. 1270 // Load the full block from the buffer.
1011 let mut index = 0; 1271 self.write_bytes_blocking(C::BLOCK_SIZE, &ctx.aad_buffer);
1012 let end_index = C::BLOCK_SIZE;
1013 // Write block in
1014 while index < end_index {
1015 let mut in_word: [u8; 4] = [0; 4];
1016 in_word.copy_from_slice(&ctx.aad_buffer[index..index + 4]);
1017 T::regs().din().write_value(u32::from_ne_bytes(in_word));
1018 index += 4;
1019 }
1020 // Block until input FIFO is empty. 1272 // Block until input FIFO is empty.
1021 while !T::regs().sr().read().ifem() {} 1273 while !T::regs().sr().read().ifem() {}
1022 } 1274 }
@@ -1032,33 +1284,108 @@ impl<'d, T: Instance> Cryp<'d, T> {
1032 1284
1033 // Load full data blocks into core. 1285 // Load full data blocks into core.
1034 let num_full_blocks = aad_len_remaining / C::BLOCK_SIZE; 1286 let num_full_blocks = aad_len_remaining / C::BLOCK_SIZE;
1035 for block in 0..num_full_blocks { 1287 let start_index = len_to_copy;
1036 let mut index = len_to_copy + (block * C::BLOCK_SIZE); 1288 let end_index = start_index + (C::BLOCK_SIZE * num_full_blocks);
1037 let end_index = index + C::BLOCK_SIZE; 1289 self.write_bytes_blocking(C::BLOCK_SIZE, &aad[start_index..end_index]);
1038 // Write block in 1290
1039 while index < end_index { 1291 if last_aad_block {
1040 let mut in_word: [u8; 4] = [0; 4]; 1292 if leftovers > 0 {
1041 in_word.copy_from_slice(&aad[index..index + 4]); 1293 self.write_bytes_blocking(C::BLOCK_SIZE, &ctx.aad_buffer);
1042 T::regs().din().write_value(u32::from_ne_bytes(in_word));
1043 index += 4;
1044 } 1294 }
1045 // Block until input FIFO is empty. 1295 // Switch to payload phase.
1046 while !T::regs().sr().read().ifem() {} 1296 ctx.aad_complete = true;
1297 T::regs().cr().modify(|w| w.set_crypen(false));
1298 T::regs().cr().modify(|w| w.set_gcm_ccmph(2));
1299 T::regs().cr().modify(|w| w.fflush());
1300 }
1301
1302 self.store_context(ctx);
1303 }
1304
1305 #[cfg(any(cryp_v2, cryp_v3))]
1306 /// Controls the header phase of cipher processing.
1307 /// This function is only valid for authenticated ciphers including GCM, CCM, and GMAC.
1308 /// All additional associated data (AAD) must be supplied to this function prior to starting the payload phase with `payload`.
1309 /// The AAD must be supplied in multiples of the block size (128-bits for AES, 64-bits for DES), except when supplying the last block.
1310 /// When supplying the last block of AAD, `last_aad_block` must be `true`.
1311 pub async fn aad<'c, const TAG_SIZE: usize, C: Cipher<'c> + CipherSized + IVSized + CipherAuthenticated<TAG_SIZE>>(
1312 &mut self,
1313 ctx: &mut Context<'c, C>,
1314 aad: &[u8],
1315 last_aad_block: bool,
1316 ) where
1317 DmaIn: crate::cryp::DmaIn<T>,
1318 DmaOut: crate::cryp::DmaOut<T>,
1319 {
1320 self.load_context(ctx);
1321
1322 // Perform checks for correctness.
1323 if ctx.aad_complete {
1324 panic!("Cannot update AAD after starting payload!")
1325 }
1326
1327 ctx.header_len += aad.len() as u64;
1328
1329 // Header phase
1330 T::regs().cr().modify(|w| w.set_crypen(false));
1331 T::regs().cr().modify(|w| w.set_gcm_ccmph(1));
1332 T::regs().cr().modify(|w| w.set_crypen(true));
1333
1334 // First write the header B1 block if not yet written.
1335 if !ctx.header_processed {
1336 ctx.header_processed = true;
1337 let header = ctx.cipher.get_header_block();
1338 ctx.aad_buffer[0..header.len()].copy_from_slice(header);
1339 ctx.aad_buffer_len += header.len();
1340 }
1341
1342 // Fill the header block to make a full block.
1343 let len_to_copy = min(aad.len(), C::BLOCK_SIZE - ctx.aad_buffer_len);
1344 ctx.aad_buffer[ctx.aad_buffer_len..ctx.aad_buffer_len + len_to_copy].copy_from_slice(&aad[..len_to_copy]);
1345 ctx.aad_buffer_len += len_to_copy;
1346 ctx.aad_buffer[ctx.aad_buffer_len..].fill(0);
1347 let mut aad_len_remaining = aad.len() - len_to_copy;
1348
1349 if ctx.aad_buffer_len < C::BLOCK_SIZE {
1350 // The buffer isn't full and this is the last buffer, so process it as is (already padded).
1351 if last_aad_block {
1352 Self::write_bytes(&mut self.indma, C::BLOCK_SIZE, &ctx.aad_buffer).await;
1353 assert_eq!(T::regs().sr().read().ifem(), true);
1354
1355 // Switch to payload phase.
1356 ctx.aad_complete = true;
1357 T::regs().cr().modify(|w| w.set_crypen(false));
1358 T::regs().cr().modify(|w| w.set_gcm_ccmph(2));
1359 T::regs().cr().modify(|w| w.fflush());
1360 } else {
1361 // Just return because we don't yet have a full block to process.
1362 return;
1363 }
1364 } else {
1365 // Load the full block from the buffer.
1366 Self::write_bytes(&mut self.indma, C::BLOCK_SIZE, &ctx.aad_buffer).await;
1367 assert_eq!(T::regs().sr().read().ifem(), true);
1047 } 1368 }
1048 1369
1370 // Handle a partial block that is passed in.
1371 ctx.aad_buffer_len = 0;
1372 let leftovers = aad_len_remaining % C::BLOCK_SIZE;
1373 ctx.aad_buffer[..leftovers].copy_from_slice(&aad[aad.len() - leftovers..aad.len()]);
1374 ctx.aad_buffer_len += leftovers;
1375 ctx.aad_buffer[ctx.aad_buffer_len..].fill(0);
1376 aad_len_remaining -= leftovers;
1377 assert_eq!(aad_len_remaining % C::BLOCK_SIZE, 0);
1378
1379 // Load full data blocks into core.
1380 let num_full_blocks = aad_len_remaining / C::BLOCK_SIZE;
1381 let start_index = len_to_copy;
1382 let end_index = start_index + (C::BLOCK_SIZE * num_full_blocks);
1383 Self::write_bytes(&mut self.indma, C::BLOCK_SIZE, &aad[start_index..end_index]).await;
1384
1049 if last_aad_block { 1385 if last_aad_block {
1050 if leftovers > 0 { 1386 if leftovers > 0 {
1051 let mut index = 0; 1387 Self::write_bytes(&mut self.indma, C::BLOCK_SIZE, &ctx.aad_buffer).await;
1052 let end_index = C::BLOCK_SIZE; 1388 assert_eq!(T::regs().sr().read().ifem(), true);
1053 // Write block in
1054 while index < end_index {
1055 let mut in_word: [u8; 4] = [0; 4];
1056 in_word.copy_from_slice(&ctx.aad_buffer[index..index + 4]);
1057 T::regs().din().write_value(u32::from_ne_bytes(in_word));
1058 index += 4;
1059 }
1060 // Block until input FIFO is empty.
1061 while !T::regs().sr().read().ifem() {}
1062 } 1389 }
1063 // Switch to payload phase. 1390 // Switch to payload phase.
1064 ctx.aad_complete = true; 1391 ctx.aad_complete = true;
@@ -1074,7 +1401,7 @@ impl<'d, T: Instance> Cryp<'d, T> {
1074 /// The context determines algorithm, mode, and state of the crypto accelerator. 1401 /// The context determines algorithm, mode, and state of the crypto accelerator.
1075 /// When the last piece of data is supplied, `last_block` should be `true`. 1402 /// When the last piece of data is supplied, `last_block` should be `true`.
1076 /// This function panics under various mismatches of parameters. 1403 /// This function panics under various mismatches of parameters.
1077 /// Input and output buffer lengths must match. 1404 /// Output buffer must be at least as long as the input buffer.
1078 /// Data must be a multiple of block size (128-bits for AES, 64-bits for DES) for CBC and ECB modes. 1405 /// Data must be a multiple of block size (128-bits for AES, 64-bits for DES) for CBC and ECB modes.
1079 /// Padding or ciphertext stealing must be managed by the application for these modes. 1406 /// Padding or ciphertext stealing must be managed by the application for these modes.
1080 /// Data must also be a multiple of block size unless `last_block` is `true`. 1407 /// Data must also be a multiple of block size unless `last_block` is `true`.
@@ -1125,54 +1452,121 @@ impl<'d, T: Instance> Cryp<'d, T> {
1125 // Load data into core, block by block. 1452 // Load data into core, block by block.
1126 let num_full_blocks = input.len() / C::BLOCK_SIZE; 1453 let num_full_blocks = input.len() / C::BLOCK_SIZE;
1127 for block in 0..num_full_blocks { 1454 for block in 0..num_full_blocks {
1128 let mut index = block * C::BLOCK_SIZE; 1455 let index = block * C::BLOCK_SIZE;
1129 let end_index = index + C::BLOCK_SIZE;
1130 // Write block in 1456 // Write block in
1131 while index < end_index { 1457 self.write_bytes_blocking(C::BLOCK_SIZE, &input[index..index + C::BLOCK_SIZE]);
1132 let mut in_word: [u8; 4] = [0; 4];
1133 in_word.copy_from_slice(&input[index..index + 4]);
1134 T::regs().din().write_value(u32::from_ne_bytes(in_word));
1135 index += 4;
1136 }
1137 let mut index = block * C::BLOCK_SIZE;
1138 let end_index = index + C::BLOCK_SIZE;
1139 // Block until there is output to read.
1140 while !T::regs().sr().read().ofne() {}
1141 // Read block out 1458 // Read block out
1142 while index < end_index { 1459 self.read_bytes_blocking(C::BLOCK_SIZE, &mut output[index..index + C::BLOCK_SIZE]);
1143 let out_word: u32 = T::regs().dout().read();
1144 output[index..index + 4].copy_from_slice(u32::to_ne_bytes(out_word).as_slice());
1145 index += 4;
1146 }
1147 } 1460 }
1148 1461
1149 // Handle the final block, which is incomplete. 1462 // Handle the final block, which is incomplete.
1150 if last_block_remainder > 0 { 1463 if last_block_remainder > 0 {
1151 let padding_len = C::BLOCK_SIZE - last_block_remainder; 1464 let padding_len = C::BLOCK_SIZE - last_block_remainder;
1152 let temp1 = ctx.cipher.pre_final_block(&T::regs(), ctx.dir, padding_len); 1465 let temp1 = ctx.cipher.pre_final(&T::regs(), ctx.dir, padding_len);
1153 1466
1154 let mut intermediate_data: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE]; 1467 let mut intermediate_data: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE];
1155 let mut last_block: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE]; 1468 let mut last_block: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE];
1156 last_block[..last_block_remainder].copy_from_slice(&input[input.len() - last_block_remainder..input.len()]); 1469 last_block[..last_block_remainder].copy_from_slice(&input[input.len() - last_block_remainder..input.len()]);
1157 let mut index = 0; 1470 self.write_bytes_blocking(C::BLOCK_SIZE, &last_block);
1158 let end_index = C::BLOCK_SIZE; 1471 self.read_bytes_blocking(C::BLOCK_SIZE, &mut intermediate_data);
1159 // Write block in 1472
1160 while index < end_index { 1473 // Handle the last block depending on mode.
1161 let mut in_word: [u8; 4] = [0; 4]; 1474 let output_len = output.len();
1162 in_word.copy_from_slice(&last_block[index..index + 4]); 1475 output[output_len - last_block_remainder..output_len]
1163 T::regs().din().write_value(u32::from_ne_bytes(in_word)); 1476 .copy_from_slice(&intermediate_data[0..last_block_remainder]);
1164 index += 4; 1477
1478 let mut mask: [u8; 16] = [0; 16];
1479 mask[..last_block_remainder].fill(0xFF);
1480 ctx.cipher
1481 .post_final_blocking(&T::regs(), self, ctx.dir, &mut intermediate_data, temp1, mask);
1482 }
1483
1484 ctx.payload_len += input.len() as u64;
1485
1486 self.store_context(ctx);
1487 }
1488
1489 /// Performs encryption/decryption on the provided context.
1490 /// The context determines algorithm, mode, and state of the crypto accelerator.
1491 /// When the last piece of data is supplied, `last_block` should be `true`.
1492 /// This function panics under various mismatches of parameters.
1493 /// Output buffer must be at least as long as the input buffer.
1494 /// Data must be a multiple of block size (128-bits for AES, 64-bits for DES) for CBC and ECB modes.
1495 /// Padding or ciphertext stealing must be managed by the application for these modes.
1496 /// Data must also be a multiple of block size unless `last_block` is `true`.
1497 pub async fn payload<'c, C: Cipher<'c> + CipherSized + IVSized>(
1498 &mut self,
1499 ctx: &mut Context<'c, C>,
1500 input: &[u8],
1501 output: &mut [u8],
1502 last_block: bool,
1503 ) where
1504 DmaIn: crate::cryp::DmaIn<T>,
1505 DmaOut: crate::cryp::DmaOut<T>,
1506 {
1507 self.load_context(ctx);
1508
1509 let last_block_remainder = input.len() % C::BLOCK_SIZE;
1510
1511 // Perform checks for correctness.
1512 if !ctx.aad_complete && ctx.header_len > 0 {
1513 panic!("Additional associated data must be processed first!");
1514 } else if !ctx.aad_complete {
1515 #[cfg(any(cryp_v2, cryp_v3))]
1516 {
1517 ctx.aad_complete = true;
1518 T::regs().cr().modify(|w| w.set_crypen(false));
1519 T::regs().cr().modify(|w| w.set_gcm_ccmph(2));
1520 T::regs().cr().modify(|w| w.fflush());
1521 T::regs().cr().modify(|w| w.set_crypen(true));
1165 } 1522 }
1166 let mut index = 0; 1523 }
1167 let end_index = C::BLOCK_SIZE; 1524 if ctx.last_block_processed {
1168 // Block until there is output to read. 1525 panic!("The last block has already been processed!");
1169 while !T::regs().sr().read().ofne() {} 1526 }
1170 // Read block out 1527 if input.len() > output.len() {
1171 while index < end_index { 1528 panic!("Output buffer length must match input length.");
1172 let out_word: u32 = T::regs().dout().read(); 1529 }
1173 intermediate_data[index..index + 4].copy_from_slice(u32::to_ne_bytes(out_word).as_slice()); 1530 if !last_block {
1174 index += 4; 1531 if last_block_remainder != 0 {
1532 panic!("Input length must be a multiple of {} bytes.", C::BLOCK_SIZE);
1533 }
1534 }
1535 if C::REQUIRES_PADDING {
1536 if last_block_remainder != 0 {
1537 panic!("Input must be a multiple of {} bytes in ECB and CBC modes. Consider padding or ciphertext stealing.", C::BLOCK_SIZE);
1175 } 1538 }
1539 }
1540 if last_block {
1541 ctx.last_block_processed = true;
1542 }
1543
1544 // Load data into core, block by block.
1545 let num_full_blocks = input.len() / C::BLOCK_SIZE;
1546 for block in 0..num_full_blocks {
1547 let index = block * C::BLOCK_SIZE;
1548 // Read block out
1549 let read = Self::read_bytes(
1550 &mut self.outdma,
1551 C::BLOCK_SIZE,
1552 &mut output[index..index + C::BLOCK_SIZE],
1553 );
1554 // Write block in
1555 let write = Self::write_bytes(&mut self.indma, C::BLOCK_SIZE, &input[index..index + C::BLOCK_SIZE]);
1556 embassy_futures::join::join(read, write).await;
1557 }
1558
1559 // Handle the final block, which is incomplete.
1560 if last_block_remainder > 0 {
1561 let padding_len = C::BLOCK_SIZE - last_block_remainder;
1562 let temp1 = ctx.cipher.pre_final(&T::regs(), ctx.dir, padding_len);
1563
1564 let mut intermediate_data: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE];
1565 let mut last_block: [u8; AES_BLOCK_SIZE] = [0; AES_BLOCK_SIZE];
1566 last_block[..last_block_remainder].copy_from_slice(&input[input.len() - last_block_remainder..input.len()]);
1567 let read = Self::read_bytes(&mut self.outdma, C::BLOCK_SIZE, &mut intermediate_data);
1568 let write = Self::write_bytes(&mut self.indma, C::BLOCK_SIZE, &last_block);
1569 embassy_futures::join::join(read, write).await;
1176 1570
1177 // Handle the last block depending on mode. 1571 // Handle the last block depending on mode.
1178 let output_len = output.len(); 1572 let output_len = output.len();
@@ -1182,7 +1576,8 @@ impl<'d, T: Instance> Cryp<'d, T> {
1182 let mut mask: [u8; 16] = [0; 16]; 1576 let mut mask: [u8; 16] = [0; 16];
1183 mask[..last_block_remainder].fill(0xFF); 1577 mask[..last_block_remainder].fill(0xFF);
1184 ctx.cipher 1578 ctx.cipher
1185 .post_final_block(&T::regs(), ctx.dir, &mut intermediate_data, temp1, mask); 1579 .post_final(&T::regs(), self, ctx.dir, &mut intermediate_data, temp1, mask)
1580 .await;
1186 } 1581 }
1187 1582
1188 ctx.payload_len += input.len() as u64; 1583 ctx.payload_len += input.len() as u64;
@@ -1191,8 +1586,8 @@ impl<'d, T: Instance> Cryp<'d, T> {
1191 } 1586 }
1192 1587
1193 #[cfg(any(cryp_v2, cryp_v3))] 1588 #[cfg(any(cryp_v2, cryp_v3))]
1194 /// This function only needs to be called for GCM, CCM, and GMAC modes to 1589 /// Generates an authentication tag for authenticated ciphers including GCM, CCM, and GMAC.
1195 /// generate an authentication tag. 1590 /// Called after the all data has been encrypted/decrypted by `payload`.
1196 pub fn finish_blocking< 1591 pub fn finish_blocking<
1197 'c, 1592 'c,
1198 const TAG_SIZE: usize, 1593 const TAG_SIZE: usize,
@@ -1213,28 +1608,72 @@ impl<'d, T: Instance> Cryp<'d, T> {
1213 let payloadlen2: u32 = (ctx.payload_len * 8) as u32; 1608 let payloadlen2: u32 = (ctx.payload_len * 8) as u32;
1214 1609
1215 #[cfg(cryp_v2)] 1610 #[cfg(cryp_v2)]
1216 { 1611 let footer: [u32; 4] = [
1217 T::regs().din().write_value(headerlen1.swap_bytes()); 1612 headerlen1.swap_bytes(),
1218 T::regs().din().write_value(headerlen2.swap_bytes()); 1613 headerlen2.swap_bytes(),
1219 T::regs().din().write_value(payloadlen1.swap_bytes()); 1614 payloadlen1.swap_bytes(),
1220 T::regs().din().write_value(payloadlen2.swap_bytes()); 1615 payloadlen2.swap_bytes(),
1221 } 1616 ];
1222
1223 #[cfg(cryp_v3)] 1617 #[cfg(cryp_v3)]
1224 { 1618 let footer: [u32; 4] = [headerlen1, headerlen2, payloadlen1, payloadlen2];
1225 T::regs().din().write_value(headerlen1); 1619
1226 T::regs().din().write_value(headerlen2); 1620 self.write_words_blocking(C::BLOCK_SIZE, &footer);
1227 T::regs().din().write_value(payloadlen1);
1228 T::regs().din().write_value(payloadlen2);
1229 }
1230 1621
1231 while !T::regs().sr().read().ofne() {} 1622 while !T::regs().sr().read().ofne() {}
1232 1623
1233 let mut full_tag: [u8; 16] = [0; 16]; 1624 let mut full_tag: [u8; 16] = [0; 16];
1234 full_tag[0..4].copy_from_slice(T::regs().dout().read().to_ne_bytes().as_slice()); 1625 self.read_bytes_blocking(C::BLOCK_SIZE, &mut full_tag);
1235 full_tag[4..8].copy_from_slice(T::regs().dout().read().to_ne_bytes().as_slice()); 1626 let mut tag: [u8; TAG_SIZE] = [0; TAG_SIZE];
1236 full_tag[8..12].copy_from_slice(T::regs().dout().read().to_ne_bytes().as_slice()); 1627 tag.copy_from_slice(&full_tag[0..TAG_SIZE]);
1237 full_tag[12..16].copy_from_slice(T::regs().dout().read().to_ne_bytes().as_slice()); 1628
1629 T::regs().cr().modify(|w| w.set_crypen(false));
1630
1631 tag
1632 }
1633
1634 #[cfg(any(cryp_v2, cryp_v3))]
1635 // Generates an authentication tag for authenticated ciphers including GCM, CCM, and GMAC.
1636 /// Called after the all data has been encrypted/decrypted by `payload`.
1637 pub async fn finish<
1638 'c,
1639 const TAG_SIZE: usize,
1640 C: Cipher<'c> + CipherSized + IVSized + CipherAuthenticated<TAG_SIZE>,
1641 >(
1642 &mut self,
1643 mut ctx: Context<'c, C>,
1644 ) -> [u8; TAG_SIZE]
1645 where
1646 DmaIn: crate::cryp::DmaIn<T>,
1647 DmaOut: crate::cryp::DmaOut<T>,
1648 {
1649 self.load_context(&mut ctx);
1650
1651 T::regs().cr().modify(|w| w.set_crypen(false));
1652 T::regs().cr().modify(|w| w.set_gcm_ccmph(3));
1653 T::regs().cr().modify(|w| w.set_crypen(true));
1654
1655 let headerlen1: u32 = ((ctx.header_len * 8) >> 32) as u32;
1656 let headerlen2: u32 = (ctx.header_len * 8) as u32;
1657 let payloadlen1: u32 = ((ctx.payload_len * 8) >> 32) as u32;
1658 let payloadlen2: u32 = (ctx.payload_len * 8) as u32;
1659
1660 #[cfg(cryp_v2)]
1661 let footer: [u32; 4] = [
1662 headerlen1.swap_bytes(),
1663 headerlen2.swap_bytes(),
1664 payloadlen1.swap_bytes(),
1665 payloadlen2.swap_bytes(),
1666 ];
1667 #[cfg(cryp_v3)]
1668 let footer: [u32; 4] = [headerlen1, headerlen2, payloadlen1, payloadlen2];
1669
1670 let write = Self::write_words(&mut self.indma, C::BLOCK_SIZE, &footer);
1671
1672 let mut full_tag: [u8; 16] = [0; 16];
1673 let read = Self::read_bytes(&mut self.outdma, C::BLOCK_SIZE, &mut full_tag);
1674
1675 embassy_futures::join::join(read, write).await;
1676
1238 let mut tag: [u8; TAG_SIZE] = [0; TAG_SIZE]; 1677 let mut tag: [u8; TAG_SIZE] = [0; TAG_SIZE];
1239 tag.copy_from_slice(&full_tag[0..TAG_SIZE]); 1678 tag.copy_from_slice(&full_tag[0..TAG_SIZE]);
1240 1679
@@ -1325,6 +1764,125 @@ impl<'d, T: Instance> Cryp<'d, T> {
1325 // Enable crypto processor. 1764 // Enable crypto processor.
1326 T::regs().cr().modify(|w| w.set_crypen(true)); 1765 T::regs().cr().modify(|w| w.set_crypen(true));
1327 } 1766 }
1767
1768 fn write_bytes_blocking(&self, block_size: usize, blocks: &[u8]) {
1769 // Ensure input is a multiple of block size.
1770 assert_eq!(blocks.len() % block_size, 0);
1771 let mut index = 0;
1772 let end_index = blocks.len();
1773 while index < end_index {
1774 let mut in_word: [u8; 4] = [0; 4];
1775 in_word.copy_from_slice(&blocks[index..index + 4]);
1776 T::regs().din().write_value(u32::from_ne_bytes(in_word));
1777 index += 4;
1778 if index % block_size == 0 {
1779 // Block until input FIFO is empty.
1780 while !T::regs().sr().read().ifem() {}
1781 }
1782 }
1783 }
1784
1785 async fn write_bytes(dma: &mut PeripheralRef<'_, DmaIn>, block_size: usize, blocks: &[u8])
1786 where
1787 DmaIn: crate::cryp::DmaIn<T>,
1788 {
1789 if blocks.len() == 0 {
1790 return;
1791 }
1792 // Ensure input is a multiple of block size.
1793 assert_eq!(blocks.len() % block_size, 0);
1794 // Configure DMA to transfer input to crypto core.
1795 let dma_request = dma.request();
1796 let dst_ptr = T::regs().din().as_ptr();
1797 let num_words = blocks.len() / 4;
1798 let src_ptr = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words);
1799 let options = TransferOptions {
1800 priority: Priority::High,
1801 ..Default::default()
1802 };
1803 let dma_transfer = unsafe { Transfer::new_write_raw(dma, dma_request, src_ptr, dst_ptr, options) };
1804 T::regs().dmacr().modify(|w| w.set_dien(true));
1805 // Wait for the transfer to complete.
1806 dma_transfer.await;
1807 }
1808
1809 #[cfg(any(cryp_v2, cryp_v3))]
1810 fn write_words_blocking(&self, block_size: usize, blocks: &[u32]) {
1811 assert_eq!((blocks.len() * 4) % block_size, 0);
1812 let mut byte_counter: usize = 0;
1813 for word in blocks {
1814 T::regs().din().write_value(*word);
1815 byte_counter += 4;
1816 if byte_counter % block_size == 0 {
1817 // Block until input FIFO is empty.
1818 while !T::regs().sr().read().ifem() {}
1819 }
1820 }
1821 }
1822
1823 #[cfg(any(cryp_v2, cryp_v3))]
1824 async fn write_words(dma: &mut PeripheralRef<'_, DmaIn>, block_size: usize, blocks: &[u32])
1825 where
1826 DmaIn: crate::cryp::DmaIn<T>,
1827 {
1828 if blocks.len() == 0 {
1829 return;
1830 }
1831 // Ensure input is a multiple of block size.
1832 assert_eq!((blocks.len() * 4) % block_size, 0);
1833 // Configure DMA to transfer input to crypto core.
1834 let dma_request = dma.request();
1835 let dst_ptr = T::regs().din().as_ptr();
1836 let num_words = blocks.len();
1837 let src_ptr = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words);
1838 let options = TransferOptions {
1839 priority: Priority::High,
1840 ..Default::default()
1841 };
1842 let dma_transfer = unsafe { Transfer::new_write_raw(dma, dma_request, src_ptr, dst_ptr, options) };
1843 T::regs().dmacr().modify(|w| w.set_dien(true));
1844 // Wait for the transfer to complete.
1845 dma_transfer.await;
1846 }
1847
1848 fn read_bytes_blocking(&self, block_size: usize, blocks: &mut [u8]) {
1849 // Block until there is output to read.
1850 while !T::regs().sr().read().ofne() {}
1851 // Ensure input is a multiple of block size.
1852 assert_eq!(blocks.len() % block_size, 0);
1853 // Read block out
1854 let mut index = 0;
1855 let end_index = blocks.len();
1856 while index < end_index {
1857 let out_word: u32 = T::regs().dout().read();
1858 blocks[index..index + 4].copy_from_slice(u32::to_ne_bytes(out_word).as_slice());
1859 index += 4;
1860 }
1861 }
1862
1863 async fn read_bytes(dma: &mut PeripheralRef<'_, DmaOut>, block_size: usize, blocks: &mut [u8])
1864 where
1865 DmaOut: crate::cryp::DmaOut<T>,
1866 {
1867 if blocks.len() == 0 {
1868 return;
1869 }
1870 // Ensure input is a multiple of block size.
1871 assert_eq!(blocks.len() % block_size, 0);
1872 // Configure DMA to get output from crypto core.
1873 let dma_request = dma.request();
1874 let src_ptr = T::regs().dout().as_ptr();
1875 let num_words = blocks.len() / 4;
1876 let dst_ptr = ptr::slice_from_raw_parts_mut(blocks.as_mut_ptr().cast(), num_words);
1877 let options = TransferOptions {
1878 priority: Priority::VeryHigh,
1879 ..Default::default()
1880 };
1881 let dma_transfer = unsafe { Transfer::new_read_raw(dma, dma_request, src_ptr, dst_ptr, options) };
1882 T::regs().dmacr().modify(|w| w.set_doen(true));
1883 // Wait for the transfer to complete.
1884 dma_transfer.await;
1885 }
1328} 1886}
1329 1887
1330pub(crate) mod sealed { 1888pub(crate) mod sealed {
@@ -1354,3 +1912,6 @@ foreach_interrupt!(
1354 } 1912 }
1355 }; 1913 };
1356); 1914);
1915
1916dma_trait!(DmaIn, Instance);
1917dma_trait!(DmaOut, Instance);
diff --git a/examples/stm32f7/src/bin/cryp.rs b/examples/stm32f7/src/bin/cryp.rs
index 04927841a..235853cb9 100644
--- a/examples/stm32f7/src/bin/cryp.rs
+++ b/examples/stm32f7/src/bin/cryp.rs
@@ -6,11 +6,15 @@ use aes_gcm::aead::{AeadInPlace, KeyInit};
6use aes_gcm::Aes128Gcm; 6use aes_gcm::Aes128Gcm;
7use defmt::info; 7use defmt::info;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_stm32::cryp::*; 9use embassy_stm32::cryp::{self, *};
10use embassy_stm32::Config; 10use embassy_stm32::{bind_interrupts, peripherals, Config};
11use embassy_time::Instant; 11use embassy_time::Instant;
12use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
13 13
14bind_interrupts!(struct Irqs {
15 CRYP => cryp::InterruptHandler<peripherals::CRYP>;
16});
17
14#[embassy_executor::main] 18#[embassy_executor::main]
15async fn main(_spawner: Spawner) -> ! { 19async fn main(_spawner: Spawner) -> ! {
16 let config = Config::default(); 20 let config = Config::default();
@@ -19,7 +23,7 @@ async fn main(_spawner: Spawner) -> ! {
19 let payload: &[u8] = b"hello world"; 23 let payload: &[u8] = b"hello world";
20 let aad: &[u8] = b"additional data"; 24 let aad: &[u8] = b"additional data";
21 25
22 let hw_cryp = Cryp::new(p.CRYP); 26 let mut hw_cryp = Cryp::new(p.CRYP, p.DMA2_CH6, p.DMA2_CH5, Irqs);
23 let key: [u8; 16] = [0; 16]; 27 let key: [u8; 16] = [0; 16];
24 let mut ciphertext: [u8; 11] = [0; 11]; 28 let mut ciphertext: [u8; 11] = [0; 11];
25 let mut plaintext: [u8; 11] = [0; 11]; 29 let mut plaintext: [u8; 11] = [0; 11];
@@ -29,16 +33,18 @@ async fn main(_spawner: Spawner) -> ! {
29 33
30 // Encrypt in hardware using AES-GCM 128-bit 34 // Encrypt in hardware using AES-GCM 128-bit
31 let aes_gcm = AesGcm::new(&key, &iv); 35 let aes_gcm = AesGcm::new(&key, &iv);
32 let mut gcm_encrypt = hw_cryp.start(&aes_gcm, Direction::Encrypt); 36 let mut gcm_encrypt = hw_cryp.start(&aes_gcm, Direction::Encrypt).await;
33 hw_cryp.aad_blocking(&mut gcm_encrypt, aad, true); 37 hw_cryp.aad(&mut gcm_encrypt, aad, true).await;
34 hw_cryp.payload_blocking(&mut gcm_encrypt, payload, &mut ciphertext, true); 38 hw_cryp.payload(&mut gcm_encrypt, payload, &mut ciphertext, true).await;
35 let encrypt_tag = hw_cryp.finish_blocking(gcm_encrypt); 39 let encrypt_tag = hw_cryp.finish(gcm_encrypt).await;
36 40
37 // Decrypt in hardware using AES-GCM 128-bit 41 // Decrypt in hardware using AES-GCM 128-bit
38 let mut gcm_decrypt = hw_cryp.start(&aes_gcm, Direction::Decrypt); 42 let mut gcm_decrypt = hw_cryp.start(&aes_gcm, Direction::Decrypt).await;
39 hw_cryp.aad_blocking(&mut gcm_decrypt, aad, true); 43 hw_cryp.aad(&mut gcm_decrypt, aad, true).await;
40 hw_cryp.payload_blocking(&mut gcm_decrypt, &ciphertext, &mut plaintext, true); 44 hw_cryp
41 let decrypt_tag = hw_cryp.finish_blocking(gcm_decrypt); 45 .payload(&mut gcm_decrypt, &ciphertext, &mut plaintext, true)
46 .await;
47 let decrypt_tag = hw_cryp.finish(gcm_decrypt).await;
42 48
43 let hw_end_time = Instant::now(); 49 let hw_end_time = Instant::now();
44 let hw_execution_time = hw_end_time - hw_start_time; 50 let hw_execution_time = hw_end_time - hw_start_time;
diff --git a/tests/stm32/src/bin/cryp.rs b/tests/stm32/src/bin/cryp.rs
index f105abf26..60778bdaa 100644
--- a/tests/stm32/src/bin/cryp.rs
+++ b/tests/stm32/src/bin/cryp.rs
@@ -10,9 +10,14 @@ use aes_gcm::aead::{AeadInPlace, KeyInit};
10use aes_gcm::Aes128Gcm; 10use aes_gcm::Aes128Gcm;
11use common::*; 11use common::*;
12use embassy_executor::Spawner; 12use embassy_executor::Spawner;
13use embassy_stm32::cryp::*; 13use embassy_stm32::cryp::{self, *};
14use embassy_stm32::{bind_interrupts, peripherals};
14use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
15 16
17bind_interrupts!(struct Irqs {
18 CRYP => cryp::InterruptHandler<peripherals::CRYP>;
19});
20
16#[embassy_executor::main] 21#[embassy_executor::main]
17async fn main(_spawner: Spawner) { 22async fn main(_spawner: Spawner) {
18 let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); 23 let p: embassy_stm32::Peripherals = embassy_stm32::init(config());
@@ -22,27 +27,32 @@ async fn main(_spawner: Spawner) {
22 const AAD1: &[u8] = b"additional data 1 stdargadrhaethaethjatjatjaetjartjstrjsfkk;'jopofyuisrteytweTASTUIKFUKIXTRDTEREharhaeryhaterjartjarthaethjrtjarthaetrhartjatejatrjsrtjartjyt1"; 27 const AAD1: &[u8] = b"additional data 1 stdargadrhaethaethjatjatjaetjartjstrjsfkk;'jopofyuisrteytweTASTUIKFUKIXTRDTEREharhaeryhaterjartjarthaethjrtjarthaetrhartjatejatrjsrtjartjyt1";
23 const AAD2: &[u8] = b"additional data 2 stdhthsthsthsrthsrthsrtjdykjdukdyuldadfhsdghsdghsdghsadghjk'hioethjrtjarthaetrhartjatecfgjhzdfhgzdfhzdfghzdfhzdfhzfhjatrjsrtjartjytjfytjfyg"; 28 const AAD2: &[u8] = b"additional data 2 stdhthsthsthsrthsrthsrtjdykjdukdyuldadfhsdghsdghsdghsadghjk'hioethjrtjarthaetrhartjatecfgjhzdfhgzdfhzdfghzdfhzdfhzfhjatrjsrtjartjytjfytjfyg";
24 29
25 let hw_cryp = Cryp::new(p.CRYP); 30 let in_dma = peri!(p, CRYP_IN_DMA);
31 let out_dma = peri!(p, CRYP_OUT_DMA);
32
33 let mut hw_cryp = Cryp::new(p.CRYP, in_dma, out_dma, Irqs);
26 let key: [u8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; 34 let key: [u8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
27 let mut ciphertext: [u8; PAYLOAD1.len() + PAYLOAD2.len()] = [0; PAYLOAD1.len() + PAYLOAD2.len()]; 35 let mut ciphertext: [u8; PAYLOAD1.len() + PAYLOAD2.len()] = [0; PAYLOAD1.len() + PAYLOAD2.len()];
28 let mut plaintext: [u8; PAYLOAD1.len() + PAYLOAD2.len()] = [0; PAYLOAD1.len() + PAYLOAD2.len()]; 36 let mut plaintext: [u8; PAYLOAD1.len() + PAYLOAD2.len()] = [0; PAYLOAD1.len() + PAYLOAD2.len()];
29 let iv: [u8; 12] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; 37 let iv: [u8; 12] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
30 38
31 // Encrypt in hardware using AES-GCM 128-bit 39 // Encrypt in hardware using AES-GCM 128-bit in blocking mode.
32 let aes_gcm = AesGcm::new(&key, &iv); 40 let aes_gcm = AesGcm::new(&key, &iv);
33 let mut gcm_encrypt = hw_cryp.start(&aes_gcm, Direction::Encrypt); 41 let mut gcm_encrypt = hw_cryp.start_blocking(&aes_gcm, Direction::Encrypt);
34 hw_cryp.aad_blocking(&mut gcm_encrypt, AAD1, false); 42 hw_cryp.aad_blocking(&mut gcm_encrypt, AAD1, false);
35 hw_cryp.aad_blocking(&mut gcm_encrypt, AAD2, true); 43 hw_cryp.aad_blocking(&mut gcm_encrypt, AAD2, true);
36 hw_cryp.payload_blocking(&mut gcm_encrypt, PAYLOAD1, &mut ciphertext[..PAYLOAD1.len()], false); 44 hw_cryp.payload_blocking(&mut gcm_encrypt, PAYLOAD1, &mut ciphertext[..PAYLOAD1.len()], false);
37 hw_cryp.payload_blocking(&mut gcm_encrypt, PAYLOAD2, &mut ciphertext[PAYLOAD1.len()..], true); 45 hw_cryp.payload_blocking(&mut gcm_encrypt, PAYLOAD2, &mut ciphertext[PAYLOAD1.len()..], true);
38 let encrypt_tag = hw_cryp.finish_blocking(gcm_encrypt); 46 let encrypt_tag = hw_cryp.finish_blocking(gcm_encrypt);
39 47
40 // Decrypt in hardware using AES-GCM 128-bit 48 // Decrypt in hardware using AES-GCM 128-bit in async (DMA) mode.
41 let mut gcm_decrypt = hw_cryp.start(&aes_gcm, Direction::Decrypt); 49 let mut gcm_decrypt = hw_cryp.start(&aes_gcm, Direction::Decrypt).await;
42 hw_cryp.aad_blocking(&mut gcm_decrypt, AAD1, false); 50 hw_cryp.aad(&mut gcm_decrypt, AAD1, false).await;
43 hw_cryp.aad_blocking(&mut gcm_decrypt, AAD2, true); 51 hw_cryp.aad(&mut gcm_decrypt, AAD2, true).await;
44 hw_cryp.payload_blocking(&mut gcm_decrypt, &ciphertext, &mut plaintext, true); 52 hw_cryp
45 let decrypt_tag = hw_cryp.finish_blocking(gcm_decrypt); 53 .payload(&mut gcm_decrypt, &ciphertext, &mut plaintext, true)
54 .await;
55 let decrypt_tag = hw_cryp.finish(gcm_decrypt).await;
46 56
47 info!("AES-GCM Ciphertext: {:?}", ciphertext); 57 info!("AES-GCM Ciphertext: {:?}", ciphertext);
48 info!("AES-GCM Plaintext: {:?}", plaintext); 58 info!("AES-GCM Plaintext: {:?}", plaintext);
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs
index 3297ea7e2..c379863a8 100644
--- a/tests/stm32/src/common.rs
+++ b/tests/stm32/src/common.rs
@@ -140,6 +140,7 @@ define_peris!(
140); 140);
141#[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))] 141#[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))]
142define_peris!( 142define_peris!(
143 CRYP_IN_DMA = DMA1_CH0, CRYP_OUT_DMA = DMA1_CH1,
143 UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH0, UART_RX_DMA = DMA1_CH1, 144 UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH0, UART_RX_DMA = DMA1_CH1,
144 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PB5, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH0, SPI_RX_DMA = DMA1_CH1, 145 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PB5, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH0, SPI_RX_DMA = DMA1_CH1,
145 ADC = ADC1, DAC = DAC1, DAC_PIN = PA4, 146 ADC = ADC1, DAC = DAC1, DAC_PIN = PA4,