1use core::{marker::PhantomData, ptr::NonNull, task::Poll};
17
18use portable_atomic::{AtomicBool, Ordering};
19use procmacros::{handler, ram};
20
21use crate::{
22 Async,
23 Blocking,
24 DriverMode,
25 asynch::AtomicWaker,
26 interrupt::InterruptHandler,
27 pac,
28 peripherals::{Interrupt, RSA},
29 system::{Cpu, GenericPeripheralGuard, Peripheral as PeripheralEnable},
30 trm_markdown_link,
31 work_queue::{self, Status, VTable, WorkQueue, WorkQueueDriver, WorkQueueFrontend},
32};
33
34pub struct Rsa<'d, Dm: DriverMode> {
36 rsa: RSA<'d>,
37 phantom: PhantomData<Dm>,
38 #[cfg(not(esp32))]
39 _memory_guard: RsaMemoryPowerGuard,
40 _guard: GenericPeripheralGuard<{ PeripheralEnable::Rsa as u8 }>,
41}
42
43const WORDS_PER_INCREMENT: u32 = property!("rsa.size_increment") / 32;
52
53#[cfg(not(esp32))]
54struct RsaMemoryPowerGuard;
55
56#[cfg(not(esp32))]
57impl RsaMemoryPowerGuard {
58 fn new() -> Self {
59 crate::peripherals::SYSTEM::regs()
60 .rsa_pd_ctrl()
61 .modify(|_, w| w.rsa_mem_pd().clear_bit());
62 Self
63 }
64}
65
66#[cfg(not(esp32))]
67impl Drop for RsaMemoryPowerGuard {
68 fn drop(&mut self) {
69 crate::peripherals::SYSTEM::regs()
70 .rsa_pd_ctrl()
71 .modify(|_, w| w.rsa_mem_pd().set_bit());
72 }
73}
74
75impl<'d> Rsa<'d, Blocking> {
76 pub fn new(rsa: RSA<'d>) -> Self {
80 let guard = GenericPeripheralGuard::new();
81
82 let this = Self {
83 rsa,
84 phantom: PhantomData,
85 #[cfg(not(esp32))]
86 _memory_guard: RsaMemoryPowerGuard::new(),
87 _guard: guard,
88 };
89
90 while !this.ready() {}
91
92 this
93 }
94
95 pub fn into_async(mut self) -> Rsa<'d, Async> {
97 self.set_interrupt_handler(rsa_interrupt_handler);
98 self.enable_disable_interrupt(true);
99
100 Rsa {
101 rsa: self.rsa,
102 phantom: PhantomData,
103 #[cfg(not(esp32))]
104 _memory_guard: self._memory_guard,
105 _guard: self._guard,
106 }
107 }
108
109 pub fn enable_disable_interrupt(&mut self, enable: bool) {
114 self.internal_enable_disable_interrupt(enable);
115 }
116
117 #[instability::unstable]
122 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
123 self.rsa.disable_peri_interrupt();
124
125 self.rsa.bind_peri_interrupt(handler.handler());
126 self.rsa.enable_peri_interrupt(handler.priority());
127 }
128}
129
130impl crate::private::Sealed for Rsa<'_, Blocking> {}
131
132#[instability::unstable]
133impl crate::interrupt::InterruptConfigurable for Rsa<'_, Blocking> {
134 fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
135 self.set_interrupt_handler(handler);
136 }
137}
138
139impl<'d> Rsa<'d, Async> {
140 pub fn into_blocking(self) -> Rsa<'d, Blocking> {
142 self.internal_enable_disable_interrupt(false);
143 self.rsa.disable_peri_interrupt();
144
145 crate::interrupt::disable(Cpu::current(), Interrupt::RSA);
146 Rsa {
147 rsa: self.rsa,
148 phantom: PhantomData,
149 #[cfg(not(esp32))]
150 _memory_guard: self._memory_guard,
151 _guard: self._guard,
152 }
153 }
154}
155
156impl<'d, Dm: DriverMode> Rsa<'d, Dm> {
157 fn internal_enable_disable_interrupt(&self, enable: bool) {
158 cfg_if::cfg_if! {
159 if #[cfg(esp32)] {
160 self.regs().interrupt().write(|w| w.interrupt().bit(enable));
162 } else {
163 self.regs().int_ena().write(|w| w.int_ena().bit(enable));
164 }
165 }
166 }
167
168 fn regs(&self) -> &pac::rsa::RegisterBlock {
169 self.rsa.register_block()
170 }
171
172 fn ready(&self) -> bool {
177 cfg_if::cfg_if! {
178 if #[cfg(any(esp32, esp32s2, esp32s3))] {
179 self.regs().clean().read().clean().bit_is_set()
180 } else {
181 self.regs().query_clean().read().query_clean().bit_is_set()
182 }
183 }
184 }
185
186 fn start_modexp(&self) {
188 cfg_if::cfg_if! {
189 if #[cfg(any(esp32, esp32s2, esp32s3))] {
190 self.regs()
191 .modexp_start()
192 .write(|w| w.modexp_start().set_bit());
193 } else {
194 self.regs()
195 .set_start_modexp()
196 .write(|w| w.set_start_modexp().set_bit());
197 }
198 }
199 }
200
201 fn start_multi(&self) {
203 cfg_if::cfg_if! {
204 if #[cfg(any(esp32, esp32s2, esp32s3))] {
205 self.regs().mult_start().write(|w| w.mult_start().set_bit());
206 } else {
207 self.regs()
208 .set_start_mult()
209 .write(|w| w.set_start_mult().set_bit());
210 }
211 }
212 }
213
214 fn start_modmulti(&self) {
216 cfg_if::cfg_if! {
217 if #[cfg(esp32)] {
218 self.start_multi();
220 } else if #[cfg(any(esp32s2, esp32s3))] {
221 self.regs()
222 .modmult_start()
223 .write(|w| w.modmult_start().set_bit());
224 } else {
225 self.regs()
226 .set_start_modmult()
227 .write(|w| w.set_start_modmult().set_bit());
228 }
229 }
230 }
231
232 fn clear_interrupt(&mut self) {
234 cfg_if::cfg_if! {
235 if #[cfg(esp32)] {
236 self.regs().interrupt().write(|w| w.interrupt().set_bit());
237 } else {
238 self.regs().int_clr().write(|w| w.int_clr().set_bit());
239 }
240 }
241 }
242
243 fn is_idle(&self) -> bool {
245 cfg_if::cfg_if! {
246 if #[cfg(esp32)] {
247 self.regs().interrupt().read().interrupt().bit_is_set()
248 } else if #[cfg(any(esp32s2, esp32s3))] {
249 self.regs().idle().read().idle().bit_is_set()
250 } else {
251 self.regs().query_idle().read().query_idle().bit_is_set()
252 }
253 }
254 }
255
256 fn wait_for_idle(&mut self) {
257 while !self.is_idle() {}
258 self.clear_interrupt();
259 }
260
261 fn write_multi_mode(&mut self, mode: u32, modular: bool) {
263 let mode = if cfg!(esp32) && !modular {
264 const NON_MODULAR: u32 = 8;
265 mode | NON_MODULAR
266 } else {
267 mode
268 };
269
270 cfg_if::cfg_if! {
271 if #[cfg(esp32)] {
272 self.regs().mult_mode().write(|w| unsafe { w.bits(mode) });
273 } else {
274 self.regs().mode().write(|w| unsafe { w.bits(mode) });
275 }
276 }
277 }
278
279 fn write_modexp_mode(&mut self, mode: u32) {
281 cfg_if::cfg_if! {
282 if #[cfg(esp32)] {
283 self.regs().modexp_mode().write(|w| unsafe { w.bits(mode) });
284 } else {
285 self.regs().mode().write(|w| unsafe { w.bits(mode) });
286 }
287 }
288 }
289
290 fn write_operand_b(&mut self, operand: &[u32]) {
291 for (reg, op) in self.regs().y_mem_iter().zip(operand.iter().copied()) {
292 reg.write(|w| unsafe { w.bits(op) });
293 }
294 }
295
296 fn write_modulus(&mut self, modulus: &[u32]) {
297 for (reg, op) in self.regs().m_mem_iter().zip(modulus.iter().copied()) {
298 reg.write(|w| unsafe { w.bits(op) });
299 }
300 }
301
302 fn write_mprime(&mut self, m_prime: u32) {
303 self.regs().m_prime().write(|w| unsafe { w.bits(m_prime) });
304 }
305
306 fn write_operand_a(&mut self, operand: &[u32]) {
307 for (reg, op) in self.regs().x_mem_iter().zip(operand.iter().copied()) {
308 reg.write(|w| unsafe { w.bits(op) });
309 }
310 }
311
312 fn write_multi_operand_b(&mut self, operand: &[u32]) {
313 for (reg, op) in self
314 .regs()
315 .z_mem_iter()
316 .skip(operand.len())
317 .zip(operand.iter().copied())
318 {
319 reg.write(|w| unsafe { w.bits(op) });
320 }
321 }
322
323 fn write_r(&mut self, r: &[u32]) {
324 for (reg, op) in self.regs().z_mem_iter().zip(r.iter().copied()) {
325 reg.write(|w| unsafe { w.bits(op) });
326 }
327 }
328
329 fn read_out(&self, outbuf: &mut [u32]) {
330 for (reg, op) in self.regs().z_mem_iter().zip(outbuf.iter_mut()) {
331 *op = reg.read().bits();
332 }
333 }
334
335 fn read_results(&mut self, outbuf: &mut [u32]) {
336 self.wait_for_idle();
337 self.read_out(outbuf);
338 }
339
340 #[doc = trm_markdown_link!("rsa")]
351 #[cfg(not(esp32))]
352 pub fn disable_constant_time(&mut self, disable: bool) {
353 self.regs()
354 .constant_time()
355 .write(|w| w.constant_time().bit(disable));
356 }
357
358 #[doc = trm_markdown_link!("rsa")]
368 #[cfg(not(esp32))]
369 pub fn search_acceleration(&mut self, enable: bool) {
370 self.regs()
371 .search_enable()
372 .write(|w| w.search_enable().bit(enable));
373 }
374
375 #[cfg(not(esp32))]
377 fn is_search_enabled(&mut self) -> bool {
378 self.regs()
379 .search_enable()
380 .read()
381 .search_enable()
382 .bit_is_set()
383 }
384
385 #[cfg(not(esp32))]
387 fn write_search_position(&mut self, search_position: u32) {
388 self.regs()
389 .search_pos()
390 .write(|w| unsafe { w.bits(search_position) });
391 }
392}
393
394pub trait RsaMode: crate::private::Sealed {
396 type InputType: AsRef<[u32]> + AsMut<[u32]>;
398}
399
400pub trait Multi: RsaMode {
402 type OutputType: AsRef<[u32]> + AsMut<[u32]>;
404}
405
406pub mod operand_sizes {
408 for_each_rsa_exponentiation!(
409 ($x:literal) => {
410 paste::paste! {
411 #[doc = concat!(stringify!($x), "-bit RSA operation.")]
412 pub struct [<Op $x>];
413
414 impl crate::private::Sealed for [<Op $x>] {}
415 impl crate::rsa::RsaMode for [<Op $x>] {
416 type InputType = [u32; $x / 32];
417 }
418 }
419 };
420 );
421
422 for_each_rsa_multiplication!(
423 ($x:literal) => {
424 impl crate::rsa::Multi for paste::paste!( [<Op $x>] ) {
425 type OutputType = [u32; $x * 2 / 32];
426 }
427 };
428 );
429}
430
431pub struct RsaModularExponentiation<'a, 'd, T: RsaMode, Dm: DriverMode> {
436 rsa: &'a mut Rsa<'d, Dm>,
437 phantom: PhantomData<T>,
438}
439
440impl<'a, 'd, T: RsaMode, Dm: DriverMode, const N: usize> RsaModularExponentiation<'a, 'd, T, Dm>
441where
442 T: RsaMode<InputType = [u32; N]>,
443{
444 #[doc = trm_markdown_link!("rsa")]
451 pub fn new(
452 rsa: &'a mut Rsa<'d, Dm>,
453 exponent: &T::InputType,
454 modulus: &T::InputType,
455 m_prime: u32,
456 ) -> Self {
457 Self::write_mode(rsa);
458 rsa.write_operand_b(exponent);
459 rsa.write_modulus(modulus);
460 rsa.write_mprime(m_prime);
461
462 #[cfg(not(esp32))]
463 if rsa.is_search_enabled() {
464 rsa.write_search_position(Self::find_search_pos(exponent));
465 }
466
467 Self {
468 rsa,
469 phantom: PhantomData,
470 }
471 }
472
473 fn set_up_exponentiation(&mut self, base: &T::InputType, r: &T::InputType) {
474 self.rsa.write_operand_a(base);
475 self.rsa.write_r(r);
476 }
477
478 #[doc = trm_markdown_link!("rsa")]
484 pub fn start_exponentiation(&mut self, base: &T::InputType, r: &T::InputType) {
485 self.set_up_exponentiation(base, r);
486 self.rsa.start_modexp();
487 }
488
489 pub fn read_results(&mut self, outbuf: &mut T::InputType) {
495 self.rsa.read_results(outbuf);
496 }
497
498 #[cfg(not(esp32))]
499 fn find_search_pos(exponent: &T::InputType) -> u32 {
500 for (i, byte) in exponent.iter().rev().enumerate() {
501 if *byte == 0 {
502 continue;
503 }
504 return (exponent.len() * 32) as u32 - (byte.leading_zeros() + i as u32 * 32) - 1;
505 }
506 0
507 }
508
509 fn write_mode(rsa: &mut Rsa<'d, Dm>) {
511 rsa.write_modexp_mode(N as u32 / WORDS_PER_INCREMENT - 1);
512 }
513}
514
515pub struct RsaModularMultiplication<'a, 'd, T, Dm>
520where
521 T: RsaMode,
522 Dm: DriverMode,
523{
524 rsa: &'a mut Rsa<'d, Dm>,
525 phantom: PhantomData<T>,
526}
527
528impl<'a, 'd, T, Dm, const N: usize> RsaModularMultiplication<'a, 'd, T, Dm>
529where
530 T: RsaMode<InputType = [u32; N]>,
531 Dm: DriverMode,
532{
533 #[doc = trm_markdown_link!("rsa")]
540 pub fn new(
541 rsa: &'a mut Rsa<'d, Dm>,
542 operand_a: &T::InputType,
543 modulus: &T::InputType,
544 r: &T::InputType,
545 m_prime: u32,
546 ) -> Self {
547 rsa.write_multi_mode(N as u32 / WORDS_PER_INCREMENT - 1, true);
548
549 rsa.write_mprime(m_prime);
550 rsa.write_modulus(modulus);
551 rsa.write_operand_a(operand_a);
552 rsa.write_r(r);
553
554 Self {
555 rsa,
556 phantom: PhantomData,
557 }
558 }
559
560 #[doc = trm_markdown_link!("rsa")]
564 pub fn start_modular_multiplication(&mut self, operand_b: &T::InputType) {
565 self.set_up_modular_multiplication(operand_b);
566 self.rsa.start_modmulti();
567 }
568
569 pub fn read_results(&mut self, outbuf: &mut T::InputType) {
575 self.rsa.read_results(outbuf);
576 }
577
578 fn set_up_modular_multiplication(&mut self, operand_b: &T::InputType) {
579 if cfg!(esp32) {
580 self.rsa.start_multi();
581 self.rsa.wait_for_idle();
582
583 self.rsa.write_operand_a(operand_b);
584 } else {
585 self.rsa.write_operand_b(operand_b);
586 }
587 }
588}
589
590pub struct RsaMultiplication<'a, 'd, T, Dm>
595where
596 T: RsaMode + Multi,
597 Dm: DriverMode,
598{
599 rsa: &'a mut Rsa<'d, Dm>,
600 phantom: PhantomData<T>,
601}
602
603impl<'a, 'd, T, Dm, const N: usize> RsaMultiplication<'a, 'd, T, Dm>
604where
605 T: RsaMode<InputType = [u32; N]>,
606 T: Multi,
607 Dm: DriverMode,
608{
609 pub fn new(rsa: &'a mut Rsa<'d, Dm>, operand_a: &T::InputType) -> Self {
611 rsa.write_multi_mode(2 * N as u32 / WORDS_PER_INCREMENT - 1, false);
613 rsa.write_operand_a(operand_a);
614
615 Self {
616 rsa,
617 phantom: PhantomData,
618 }
619 }
620
621 pub fn start_multiplication(&mut self, operand_b: &T::InputType) {
623 self.set_up_multiplication(operand_b);
624 self.rsa.start_multi();
625 }
626
627 pub fn read_results<const O: usize>(&mut self, outbuf: &mut T::OutputType)
633 where
634 T: Multi<OutputType = [u32; O]>,
635 {
636 self.rsa.read_results(outbuf);
637 }
638
639 fn set_up_multiplication(&mut self, operand_b: &T::InputType) {
640 self.rsa.write_multi_operand_b(operand_b);
641 }
642}
643
644static WAKER: AtomicWaker = AtomicWaker::new();
645static SIGNALED: AtomicBool = AtomicBool::new(false);
647
648#[must_use = "futures do nothing unless you `.await` or poll them"]
650struct RsaFuture<'a, 'd> {
651 driver: &'a Rsa<'d, Async>,
652}
653
654impl<'a, 'd> RsaFuture<'a, 'd> {
655 fn new(driver: &'a Rsa<'d, Async>) -> Self {
656 SIGNALED.store(false, Ordering::Relaxed);
657
658 driver.internal_enable_disable_interrupt(true);
659
660 Self { driver }
661 }
662
663 fn is_done(&self) -> bool {
664 SIGNALED.load(Ordering::Acquire)
665 }
666}
667
668impl Drop for RsaFuture<'_, '_> {
669 fn drop(&mut self) {
670 self.driver.internal_enable_disable_interrupt(false);
671 }
672}
673
674impl core::future::Future for RsaFuture<'_, '_> {
675 type Output = ();
676
677 fn poll(
678 self: core::pin::Pin<&mut Self>,
679 cx: &mut core::task::Context<'_>,
680 ) -> core::task::Poll<Self::Output> {
681 WAKER.register(cx.waker());
682 if self.is_done() {
683 Poll::Ready(())
684 } else {
685 Poll::Pending
686 }
687 }
688}
689
690impl<T: RsaMode, const N: usize> RsaModularExponentiation<'_, '_, T, Async>
691where
692 T: RsaMode<InputType = [u32; N]>,
693{
694 pub async fn exponentiation(
696 &mut self,
697 base: &T::InputType,
698 r: &T::InputType,
699 outbuf: &mut T::InputType,
700 ) {
701 self.set_up_exponentiation(base, r);
702 let fut = RsaFuture::new(self.rsa);
703 self.rsa.start_modexp();
704 fut.await;
705 self.rsa.read_out(outbuf);
706 }
707}
708
709impl<T: RsaMode, const N: usize> RsaModularMultiplication<'_, '_, T, Async>
710where
711 T: RsaMode<InputType = [u32; N]>,
712{
713 pub async fn modular_multiplication(
715 &mut self,
716 operand_b: &T::InputType,
717 outbuf: &mut T::InputType,
718 ) {
719 if cfg!(esp32) {
720 let fut = RsaFuture::new(self.rsa);
721 self.rsa.start_multi();
722 fut.await;
723
724 self.rsa.write_operand_a(operand_b);
725 } else {
726 self.set_up_modular_multiplication(operand_b);
727 }
728
729 let fut = RsaFuture::new(self.rsa);
730 self.rsa.start_modmulti();
731 fut.await;
732 self.rsa.read_out(outbuf);
733 }
734}
735
736impl<T: RsaMode + Multi, const N: usize> RsaMultiplication<'_, '_, T, Async>
737where
738 T: RsaMode<InputType = [u32; N]>,
739{
740 pub async fn multiplication<const O: usize>(
742 &mut self,
743 operand_b: &T::InputType,
744 outbuf: &mut T::OutputType,
745 ) where
746 T: Multi<OutputType = [u32; O]>,
747 {
748 self.set_up_multiplication(operand_b);
749 let fut = RsaFuture::new(self.rsa);
750 self.rsa.start_multi();
751 fut.await;
752 self.rsa.read_out(outbuf);
753 }
754}
755
756#[handler]
757pub(super) fn rsa_interrupt_handler() {
759 let rsa = RSA::regs();
760 SIGNALED.store(true, Ordering::Release);
761 cfg_if::cfg_if! {
762 if #[cfg(esp32)] {
763 rsa.interrupt().write(|w| w.interrupt().set_bit());
764 } else {
765 rsa.int_clr().write(|w| w.int_clr().set_bit());
766 }
767 }
768
769 WAKER.wake();
770}
771
772static RSA_WORK_QUEUE: WorkQueue<RsaWorkItem> = WorkQueue::new();
773const RSA_VTABLE: VTable<RsaWorkItem> = VTable {
774 post: |driver, item| {
775 let driver = unsafe { RsaBackend::from_raw(driver) };
777 Some(driver.process_item(item))
778 },
779 poll: |driver, item| {
780 let driver = unsafe { RsaBackend::from_raw(driver) };
781 driver.process_item(item)
782 },
783 cancel: |driver, item| {
784 let driver = unsafe { RsaBackend::from_raw(driver) };
785 driver.cancel(item)
786 },
787 stop: |driver| {
788 let driver = unsafe { RsaBackend::from_raw(driver) };
789 driver.deinitialize()
790 },
791};
792
793#[derive(Default)]
794enum RsaBackendState<'d> {
795 #[default]
796 Idle,
797 Initializing(Rsa<'d, Blocking>),
798 Ready(Rsa<'d, Blocking>),
799 #[cfg(esp32)]
800 ModularMultiplicationRoundOne(Rsa<'d, Blocking>),
801 Processing(Rsa<'d, Blocking>),
802}
803
804#[procmacros::doc_replace]
805pub struct RsaBackend<'d> {
835 peri: RSA<'d>,
836 state: RsaBackendState<'d>,
837}
838
839impl<'d> RsaBackend<'d> {
840 #[procmacros::doc_replace]
841 pub fn new(rsa: RSA<'d>) -> Self {
853 Self {
854 peri: rsa,
855 state: RsaBackendState::Idle,
856 }
857 }
858
859 #[procmacros::doc_replace]
860 pub fn start(&mut self) -> RsaWorkQueueDriver<'_, 'd> {
876 RsaWorkQueueDriver {
877 inner: WorkQueueDriver::new(self, RSA_VTABLE, &RSA_WORK_QUEUE),
878 }
879 }
880
881 unsafe fn from_raw<'any>(ptr: NonNull<()>) -> &'any mut Self {
884 unsafe { ptr.cast::<RsaBackend<'_>>().as_mut() }
885 }
886
887 fn process_item(&mut self, item: &mut RsaWorkItem) -> work_queue::Poll {
888 match core::mem::take(&mut self.state) {
889 RsaBackendState::Idle => {
890 let driver = Rsa {
891 rsa: unsafe { self.peri.clone_unchecked() },
892 phantom: PhantomData,
893 #[cfg(not(esp32))]
894 _memory_guard: RsaMemoryPowerGuard::new(),
895 _guard: GenericPeripheralGuard::new(),
896 };
897 self.state = RsaBackendState::Initializing(driver);
898 work_queue::Poll::Pending(true)
899 }
900 RsaBackendState::Initializing(mut rsa) => {
901 self.state = if rsa.ready() {
904 rsa.set_interrupt_handler(rsa_work_queue_handler);
905 rsa.enable_disable_interrupt(true);
906 RsaBackendState::Ready(rsa)
907 } else {
908 RsaBackendState::Initializing(rsa)
909 };
910 work_queue::Poll::Pending(true)
911 }
912 RsaBackendState::Ready(mut rsa) => {
913 #[cfg(not(esp32))]
914 {
915 rsa.disable_constant_time(!item.constant_time);
916 rsa.search_acceleration(item.search_acceleration);
917 }
918
919 match item.operation {
920 RsaOperation::Multiplication { x, y } => {
921 let n = x.len() as u32;
922 rsa.write_operand_a(unsafe { x.as_ref() });
923
924 rsa.write_multi_mode(2 * n / WORDS_PER_INCREMENT - 1, false);
926 rsa.write_multi_operand_b(unsafe { y.as_ref() });
927 rsa.start_multi();
928 }
929
930 RsaOperation::ModularMultiplication {
931 x,
932 #[cfg(not(esp32))]
933 y,
934 m,
935 m_prime,
936 r: r_inv,
937 ..
938 } => {
939 let n = x.len() as u32;
940 rsa.write_operand_a(unsafe { x.as_ref() });
941
942 rsa.write_multi_mode(n / WORDS_PER_INCREMENT - 1, true);
943
944 #[cfg(not(esp32))]
945 rsa.write_operand_b(unsafe { y.as_ref() });
946
947 rsa.write_modulus(unsafe { m.as_ref() });
948 rsa.write_mprime(m_prime);
949 rsa.write_r(unsafe { r_inv.as_ref() });
950
951 rsa.start_modmulti();
952
953 #[cfg(esp32)]
954 {
955 self.state = RsaBackendState::ModularMultiplicationRoundOne(rsa);
958
959 return work_queue::Poll::Pending(false);
960 }
961 }
962 RsaOperation::ModularExponentiation {
963 x,
964 y,
965 m,
966 m_prime,
967 r_inv,
968 } => {
969 let n = x.len() as u32;
970 rsa.write_operand_a(unsafe { x.as_ref() });
971
972 rsa.write_modexp_mode(n / WORDS_PER_INCREMENT - 1);
973 rsa.write_operand_b(unsafe { y.as_ref() });
974 rsa.write_modulus(unsafe { m.as_ref() });
975 rsa.write_mprime(m_prime);
976 rsa.write_r(unsafe { r_inv.as_ref() });
977
978 #[cfg(not(esp32))]
979 if item.search_acceleration {
980 fn find_search_pos(exponent: &[u32]) -> u32 {
981 for (i, byte) in exponent.iter().rev().enumerate() {
982 if *byte == 0 {
983 continue;
984 }
985 return (exponent.len() * 32) as u32
986 - (byte.leading_zeros() + i as u32 * 32)
987 - 1;
988 }
989 0
990 }
991 rsa.write_search_position(find_search_pos(unsafe { y.as_ref() }));
992 }
993
994 rsa.start_modexp();
995 }
996 }
997
998 self.state = RsaBackendState::Processing(rsa);
999
1000 work_queue::Poll::Pending(false)
1001 }
1002
1003 #[cfg(esp32)]
1004 RsaBackendState::ModularMultiplicationRoundOne(mut rsa) => {
1005 if rsa.is_idle() {
1006 let RsaOperation::ModularMultiplication { y, .. } = item.operation else {
1007 unreachable!();
1008 };
1009
1010 rsa.write_operand_a(unsafe { y.as_ref() });
1012 rsa.start_modmulti();
1013
1014 self.state = RsaBackendState::Processing(rsa);
1015 } else {
1016 self.state = RsaBackendState::ModularMultiplicationRoundOne(rsa);
1018 }
1019 work_queue::Poll::Pending(false)
1020 }
1021
1022 RsaBackendState::Processing(rsa) => {
1023 if rsa.is_idle() {
1024 rsa.read_out(unsafe { item.result.as_mut() });
1025
1026 self.state = RsaBackendState::Ready(rsa);
1027 work_queue::Poll::Ready(Status::Completed)
1028 } else {
1029 self.state = RsaBackendState::Processing(rsa);
1030 work_queue::Poll::Pending(false)
1031 }
1032 }
1033 }
1034 }
1035
1036 fn cancel(&mut self, _item: &mut RsaWorkItem) {
1037 self.state = RsaBackendState::Idle;
1040 }
1041
1042 fn deinitialize(&mut self) {
1043 self.state = RsaBackendState::Idle;
1044 }
1045}
1046
1047pub struct RsaWorkQueueDriver<'t, 'd> {
1053 inner: WorkQueueDriver<'t, RsaBackend<'d>, RsaWorkItem>,
1054}
1055
1056impl<'t, 'd> RsaWorkQueueDriver<'t, 'd> {
1057 pub fn stop(self) -> impl Future<Output = ()> {
1059 self.inner.stop()
1060 }
1061}
1062
1063struct RsaWorkItem {
1064 #[cfg(not(esp32))]
1066 search_acceleration: bool,
1067 #[cfg(not(esp32))]
1068 constant_time: bool,
1069
1070 operation: RsaOperation,
1072 result: NonNull<[u32]>,
1073}
1074
1075unsafe impl Sync for RsaWorkItem {}
1076unsafe impl Send for RsaWorkItem {}
1077
1078enum RsaOperation {
1079 Multiplication {
1082 x: NonNull<[u32]>,
1083 y: NonNull<[u32]>,
1084 },
1085 ModularMultiplication {
1087 x: NonNull<[u32]>,
1088 y: NonNull<[u32]>,
1089 m: NonNull<[u32]>,
1090 r: NonNull<[u32]>,
1091 m_prime: u32,
1092 },
1093 ModularExponentiation {
1095 x: NonNull<[u32]>,
1096 y: NonNull<[u32]>,
1097 m: NonNull<[u32]>,
1098 r_inv: NonNull<[u32]>,
1099 m_prime: u32,
1100 },
1101}
1102
1103#[handler]
1104#[ram]
1105fn rsa_work_queue_handler() {
1106 if !RSA_WORK_QUEUE.process() {
1107 cfg_if::cfg_if! {
1110 if #[cfg(esp32)] {
1111 RSA::regs().interrupt().write(|w| w.interrupt().set_bit());
1112 } else {
1113 RSA::regs().int_clr().write(|w| w.int_clr().set_bit());
1114 }
1115 }
1116 }
1117}
1118
1119#[cfg_attr(
1126 not(esp32),
1127 doc = " \nThe context is created with a secure configuration by default. You can enable hardware acceleration
1128 options using [enable_search_acceleration][Self::enable_search_acceleration] and
1129 [enable_acceleration][Self::enable_acceleration] when appropriate."
1130)]
1131pub struct RsaContext {
1132 frontend: WorkQueueFrontend<RsaWorkItem>,
1133}
1134
1135impl Default for RsaContext {
1136 fn default() -> Self {
1137 Self::new()
1138 }
1139}
1140
1141impl RsaContext {
1142 pub fn new() -> Self {
1144 Self {
1145 frontend: WorkQueueFrontend::new(RsaWorkItem {
1146 #[cfg(not(esp32))]
1147 search_acceleration: false,
1148 #[cfg(not(esp32))]
1149 constant_time: true,
1150 operation: RsaOperation::Multiplication {
1151 x: NonNull::from(&[]),
1152 y: NonNull::from(&[]),
1153 },
1154 result: NonNull::from(&mut []),
1155 }),
1156 }
1157 }
1158
1159 #[cfg(not(esp32))]
1160 #[doc = trm_markdown_link!("rsa")]
1170 pub fn enable_search_acceleration(&mut self) {
1171 self.frontend.data_mut().search_acceleration = true;
1172 }
1173
1174 #[cfg(not(esp32))]
1175 #[doc = trm_markdown_link!("rsa")]
1186 pub fn enable_acceleration(&mut self) {
1187 self.frontend.data_mut().constant_time = false;
1188 }
1189
1190 fn post(&mut self) -> RsaHandle<'_> {
1191 RsaHandle(self.frontend.post(&RSA_WORK_QUEUE))
1192 }
1193
1194 #[procmacros::doc_replace]
1195 pub fn modular_exponentiate<'t, OP>(
1260 &'t mut self,
1261 x: &'t OP::InputType,
1262 y: &'t OP::InputType,
1263 m: &'t OP::InputType,
1264 r: &'t OP::InputType,
1265 m_prime: u32,
1266 result: &'t mut OP::InputType,
1267 ) -> RsaHandle<'t>
1268 where
1269 OP: RsaMode,
1270 {
1271 self.frontend.data_mut().operation = RsaOperation::ModularExponentiation {
1272 x: NonNull::from(x.as_ref()),
1273 y: NonNull::from(y.as_ref()),
1274 m: NonNull::from(m.as_ref()),
1275 r_inv: NonNull::from(r.as_ref()),
1276 m_prime,
1277 };
1278 self.frontend.data_mut().result = NonNull::from(result.as_mut());
1279 self.post()
1280 }
1281
1282 pub fn modular_multiply<'t, OP>(
1298 &'t mut self,
1299 x: &'t OP::InputType,
1300 y: &'t OP::InputType,
1301 m: &'t OP::InputType,
1302 r: &'t OP::InputType,
1303 m_prime: u32,
1304 result: &'t mut OP::InputType,
1305 ) -> RsaHandle<'t>
1306 where
1307 OP: RsaMode,
1308 {
1309 self.frontend.data_mut().operation = RsaOperation::ModularMultiplication {
1310 x: NonNull::from(x.as_ref()),
1311 y: NonNull::from(y.as_ref()),
1312 m: NonNull::from(m.as_ref()),
1313 r: NonNull::from(r.as_ref()),
1314 m_prime,
1315 };
1316 self.frontend.data_mut().result = NonNull::from(result.as_mut());
1317 self.post()
1318 }
1319
1320 #[procmacros::doc_replace]
1321 pub fn multiply<'t, OP>(
1351 &'t mut self,
1352 x: &'t OP::InputType,
1353 y: &'t OP::InputType,
1354 result: &'t mut OP::OutputType,
1355 ) -> RsaHandle<'t>
1356 where
1357 OP: Multi,
1358 {
1359 self.frontend.data_mut().operation = RsaOperation::Multiplication {
1360 x: NonNull::from(x.as_ref()),
1361 y: NonNull::from(y.as_ref()),
1362 };
1363 self.frontend.data_mut().result = NonNull::from(result.as_mut());
1364 self.post()
1365 }
1366}
1367
1368pub struct RsaHandle<'t>(work_queue::Handle<'t, RsaWorkItem>);
1370
1371impl RsaHandle<'_> {
1372 #[inline]
1374 pub fn poll(&mut self) -> bool {
1375 self.0.poll()
1376 }
1377
1378 #[inline]
1380 pub fn wait_blocking(mut self) {
1381 while !self.poll() {}
1382 }
1383
1384 #[inline]
1386 pub fn wait(&mut self) -> impl Future<Output = Status> {
1387 self.0.wait()
1388 }
1389}