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::RSA,
29 system::{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 _guard: RsaGuard,
39}
40
41const WORDS_PER_INCREMENT: u32 = property!("rsa.size_increment") / 32;
50
51struct RsaGuard {
52 _guard: GenericPeripheralGuard<{ PeripheralEnable::Rsa as u8 }>,
53}
54
55impl RsaGuard {
56 fn new() -> Self {
57 let _guard = GenericPeripheralGuard::new();
58 #[cfg(not(esp32))]
59 crate::peripherals::SYSTEM::regs()
60 .rsa_pd_ctrl()
61 .modify(|_, w| {
62 w.rsa_mem_force_pd().clear_bit();
63 w.rsa_mem_force_pu().set_bit();
64 w.rsa_mem_pd().clear_bit()
65 });
66 Self { _guard }
67 }
68}
69
70impl Drop for RsaGuard {
71 fn drop(&mut self) {
72 unsafe {
73 crate::peripherals::RSA::steal().disable_peri_interrupt_on_all_cores();
78 }
79 #[cfg(not(esp32))]
80 crate::peripherals::SYSTEM::regs()
81 .rsa_pd_ctrl()
82 .modify(|_, w| {
83 w.rsa_mem_force_pd().clear_bit();
84 w.rsa_mem_force_pu().clear_bit();
85 w.rsa_mem_pd().set_bit()
86 });
87 }
88}
89
90impl<'d> Rsa<'d, Blocking> {
91 pub fn new(rsa: RSA<'d>) -> Self {
95 let this = Self {
96 rsa,
97 phantom: PhantomData,
98 _guard: RsaGuard::new(),
99 };
100
101 while !this.ready() {}
102
103 this
104 }
105
106 pub fn into_async(mut self) -> Rsa<'d, Async> {
108 self.set_interrupt_handler(rsa_interrupt_handler);
109 self.enable_disable_interrupt(true);
110
111 Rsa {
112 rsa: self.rsa,
113 phantom: PhantomData,
114 _guard: self._guard,
115 }
116 }
117
118 pub fn enable_disable_interrupt(&mut self, enable: bool) {
123 self.internal_enable_disable_interrupt(enable);
124 }
125
126 #[instability::unstable]
131 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
132 self.rsa.disable_peri_interrupt_on_all_cores();
133 self.rsa.bind_peri_interrupt(handler);
134 }
135}
136
137impl crate::private::Sealed for Rsa<'_, Blocking> {}
138
139#[instability::unstable]
140impl crate::interrupt::InterruptConfigurable for Rsa<'_, Blocking> {
141 fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
142 self.set_interrupt_handler(handler);
143 }
144}
145
146impl<'d> Rsa<'d, Async> {
147 pub fn into_blocking(self) -> Rsa<'d, Blocking> {
149 self.internal_enable_disable_interrupt(false);
150 self.rsa.disable_peri_interrupt_on_all_cores();
151
152 Rsa {
153 rsa: self.rsa,
154 phantom: PhantomData,
155 _guard: self._guard,
156 }
157 }
158}
159
160impl<'d, Dm: DriverMode> Rsa<'d, Dm> {
161 fn internal_enable_disable_interrupt(&self, enable: bool) {
162 cfg_if::cfg_if! {
163 if #[cfg(esp32)] {
164 self.regs().interrupt().write(|w| w.interrupt().bit(enable));
166 } else {
167 self.regs().int_ena().write(|w| w.int_ena().bit(enable));
168 }
169 }
170 }
171
172 fn regs(&self) -> &pac::rsa::RegisterBlock {
173 self.rsa.register_block()
174 }
175
176 fn ready(&self) -> bool {
181 cfg_if::cfg_if! {
182 if #[cfg(any(esp32, esp32s2, esp32s3))] {
183 self.regs().clean().read().clean().bit_is_set()
184 } else {
185 self.regs().query_clean().read().query_clean().bit_is_set()
186 }
187 }
188 }
189
190 fn start_modexp(&self) {
192 cfg_if::cfg_if! {
193 if #[cfg(any(esp32, esp32s2, esp32s3))] {
194 self.regs()
195 .modexp_start()
196 .write(|w| w.modexp_start().set_bit());
197 } else {
198 self.regs()
199 .set_start_modexp()
200 .write(|w| w.set_start_modexp().set_bit());
201 }
202 }
203 }
204
205 fn start_multi(&self) {
207 cfg_if::cfg_if! {
208 if #[cfg(any(esp32, esp32s2, esp32s3))] {
209 self.regs().mult_start().write(|w| w.mult_start().set_bit());
210 } else {
211 self.regs()
212 .set_start_mult()
213 .write(|w| w.set_start_mult().set_bit());
214 }
215 }
216 }
217
218 fn start_modmulti(&self) {
220 cfg_if::cfg_if! {
221 if #[cfg(esp32)] {
222 self.start_multi();
224 } else if #[cfg(any(esp32s2, esp32s3))] {
225 self.regs()
226 .modmult_start()
227 .write(|w| w.modmult_start().set_bit());
228 } else {
229 self.regs()
230 .set_start_modmult()
231 .write(|w| w.set_start_modmult().set_bit());
232 }
233 }
234 }
235
236 fn clear_interrupt(&mut self) {
238 cfg_if::cfg_if! {
239 if #[cfg(esp32)] {
240 self.regs().interrupt().write(|w| w.interrupt().set_bit());
241 } else {
242 self.regs().int_clr().write(|w| w.int_clr().set_bit());
243 }
244 }
245 }
246
247 fn is_idle(&self) -> bool {
249 cfg_if::cfg_if! {
250 if #[cfg(esp32)] {
251 self.regs().interrupt().read().interrupt().bit_is_set()
252 } else if #[cfg(any(esp32s2, esp32s3))] {
253 self.regs().idle().read().idle().bit_is_set()
254 } else {
255 self.regs().query_idle().read().query_idle().bit_is_set()
256 }
257 }
258 }
259
260 fn wait_for_idle(&mut self) {
261 while !self.is_idle() {}
262 self.clear_interrupt();
263 }
264
265 fn write_multi_mode(&mut self, mode: u32, modular: bool) {
267 let mode = if cfg!(esp32) && !modular {
268 const NON_MODULAR: u32 = 8;
269 mode | NON_MODULAR
270 } else {
271 mode
272 };
273
274 cfg_if::cfg_if! {
275 if #[cfg(esp32)] {
276 self.regs().mult_mode().write(|w| unsafe { w.bits(mode) });
277 } else {
278 self.regs().mode().write(|w| unsafe { w.bits(mode) });
279 }
280 }
281 }
282
283 fn write_modexp_mode(&mut self, mode: u32) {
285 cfg_if::cfg_if! {
286 if #[cfg(esp32)] {
287 self.regs().modexp_mode().write(|w| unsafe { w.bits(mode) });
288 } else {
289 self.regs().mode().write(|w| unsafe { w.bits(mode) });
290 }
291 }
292 }
293
294 fn write_operand_b(&mut self, operand: &[u32]) {
295 for (reg, op) in self.regs().y_mem_iter().zip(operand.iter().copied()) {
296 reg.write(|w| unsafe { w.bits(op) });
297 }
298 }
299
300 fn write_modulus(&mut self, modulus: &[u32]) {
301 for (reg, op) in self.regs().m_mem_iter().zip(modulus.iter().copied()) {
302 reg.write(|w| unsafe { w.bits(op) });
303 }
304 }
305
306 fn write_mprime(&mut self, m_prime: u32) {
307 self.regs().m_prime().write(|w| unsafe { w.bits(m_prime) });
308 }
309
310 fn write_operand_a(&mut self, operand: &[u32]) {
311 for (reg, op) in self.regs().x_mem_iter().zip(operand.iter().copied()) {
312 reg.write(|w| unsafe { w.bits(op) });
313 }
314 }
315
316 fn write_multi_operand_b(&mut self, operand: &[u32]) {
317 for (reg, op) in self
318 .regs()
319 .z_mem_iter()
320 .skip(operand.len())
321 .zip(operand.iter().copied())
322 {
323 reg.write(|w| unsafe { w.bits(op) });
324 }
325 }
326
327 fn write_r(&mut self, r: &[u32]) {
328 for (reg, op) in self.regs().z_mem_iter().zip(r.iter().copied()) {
329 reg.write(|w| unsafe { w.bits(op) });
330 }
331 }
332
333 fn read_out(&self, outbuf: &mut [u32]) {
334 for (reg, op) in self.regs().z_mem_iter().zip(outbuf.iter_mut()) {
335 *op = reg.read().bits();
336 }
337 }
338
339 fn read_results(&mut self, outbuf: &mut [u32]) {
340 self.wait_for_idle();
341 self.read_out(outbuf);
342 }
343
344 #[doc = trm_markdown_link!("rsa")]
355 #[cfg(not(esp32))]
356 pub fn disable_constant_time(&mut self, disable: bool) {
357 self.regs()
358 .constant_time()
359 .write(|w| w.constant_time().bit(disable));
360 }
361
362 #[doc = trm_markdown_link!("rsa")]
372 #[cfg(not(esp32))]
373 pub fn search_acceleration(&mut self, enable: bool) {
374 self.regs()
375 .search_enable()
376 .write(|w| w.search_enable().bit(enable));
377 }
378
379 #[cfg(not(esp32))]
381 fn is_search_enabled(&mut self) -> bool {
382 self.regs()
383 .search_enable()
384 .read()
385 .search_enable()
386 .bit_is_set()
387 }
388
389 #[cfg(not(esp32))]
391 fn write_search_position(&mut self, search_position: u32) {
392 self.regs()
393 .search_pos()
394 .write(|w| unsafe { w.bits(search_position) });
395 }
396}
397
398pub trait RsaMode: crate::private::Sealed {
400 type InputType: AsRef<[u32]> + AsMut<[u32]>;
402}
403
404pub trait Multi: RsaMode {
406 type OutputType: AsRef<[u32]> + AsMut<[u32]>;
408}
409
410pub mod operand_sizes {
412 for_each_rsa_exponentiation!(
413 ($x:literal) => {
414 paste::paste! {
415 #[doc = concat!(stringify!($x), "-bit RSA operation.")]
416 pub struct [<Op $x>];
417
418 impl crate::private::Sealed for [<Op $x>] {}
419 impl crate::rsa::RsaMode for [<Op $x>] {
420 type InputType = [u32; $x / 32];
421 }
422 }
423 };
424 );
425
426 for_each_rsa_multiplication!(
427 ($x:literal) => {
428 impl crate::rsa::Multi for paste::paste!( [<Op $x>] ) {
429 type OutputType = [u32; $x * 2 / 32];
430 }
431 };
432 );
433}
434
435pub struct RsaModularExponentiation<'a, 'd, T: RsaMode, Dm: DriverMode> {
440 rsa: &'a mut Rsa<'d, Dm>,
441 phantom: PhantomData<T>,
442}
443
444impl<'a, 'd, T: RsaMode, Dm: DriverMode, const N: usize> RsaModularExponentiation<'a, 'd, T, Dm>
445where
446 T: RsaMode<InputType = [u32; N]>,
447{
448 #[doc = trm_markdown_link!("rsa")]
455 pub fn new(
456 rsa: &'a mut Rsa<'d, Dm>,
457 exponent: &T::InputType,
458 modulus: &T::InputType,
459 m_prime: u32,
460 ) -> Self {
461 Self::write_mode(rsa);
462 rsa.write_operand_b(exponent);
463 rsa.write_modulus(modulus);
464 rsa.write_mprime(m_prime);
465
466 #[cfg(not(esp32))]
467 if rsa.is_search_enabled() {
468 rsa.write_search_position(Self::find_search_pos(exponent));
469 }
470
471 Self {
472 rsa,
473 phantom: PhantomData,
474 }
475 }
476
477 fn set_up_exponentiation(&mut self, base: &T::InputType, r: &T::InputType) {
478 self.rsa.write_operand_a(base);
479 self.rsa.write_r(r);
480 }
481
482 #[doc = trm_markdown_link!("rsa")]
488 pub fn start_exponentiation(&mut self, base: &T::InputType, r: &T::InputType) {
489 self.set_up_exponentiation(base, r);
490 self.rsa.start_modexp();
491 }
492
493 pub fn read_results(&mut self, outbuf: &mut T::InputType) {
499 self.rsa.read_results(outbuf);
500 }
501
502 #[cfg(not(esp32))]
503 fn find_search_pos(exponent: &T::InputType) -> u32 {
504 for (i, byte) in exponent.iter().rev().enumerate() {
505 if *byte == 0 {
506 continue;
507 }
508 return (exponent.len() * 32) as u32 - (byte.leading_zeros() + i as u32 * 32) - 1;
509 }
510 0
511 }
512
513 fn write_mode(rsa: &mut Rsa<'d, Dm>) {
515 rsa.write_modexp_mode(N as u32 / WORDS_PER_INCREMENT - 1);
516 }
517}
518
519pub struct RsaModularMultiplication<'a, 'd, T, Dm>
524where
525 T: RsaMode,
526 Dm: DriverMode,
527{
528 rsa: &'a mut Rsa<'d, Dm>,
529 phantom: PhantomData<T>,
530}
531
532impl<'a, 'd, T, Dm, const N: usize> RsaModularMultiplication<'a, 'd, T, Dm>
533where
534 T: RsaMode<InputType = [u32; N]>,
535 Dm: DriverMode,
536{
537 #[doc = trm_markdown_link!("rsa")]
544 pub fn new(
545 rsa: &'a mut Rsa<'d, Dm>,
546 operand_a: &T::InputType,
547 modulus: &T::InputType,
548 r: &T::InputType,
549 m_prime: u32,
550 ) -> Self {
551 rsa.write_multi_mode(N as u32 / WORDS_PER_INCREMENT - 1, true);
552
553 rsa.write_mprime(m_prime);
554 rsa.write_modulus(modulus);
555 rsa.write_operand_a(operand_a);
556 rsa.write_r(r);
557
558 Self {
559 rsa,
560 phantom: PhantomData,
561 }
562 }
563
564 #[doc = trm_markdown_link!("rsa")]
568 pub fn start_modular_multiplication(&mut self, operand_b: &T::InputType) {
569 self.set_up_modular_multiplication(operand_b);
570 self.rsa.start_modmulti();
571 }
572
573 pub fn read_results(&mut self, outbuf: &mut T::InputType) {
579 self.rsa.read_results(outbuf);
580 }
581
582 fn set_up_modular_multiplication(&mut self, operand_b: &T::InputType) {
583 if cfg!(esp32) {
584 self.rsa.start_multi();
585 self.rsa.wait_for_idle();
586
587 self.rsa.write_operand_a(operand_b);
588 } else {
589 self.rsa.write_operand_b(operand_b);
590 }
591 }
592}
593
594pub struct RsaMultiplication<'a, 'd, T, Dm>
599where
600 T: RsaMode + Multi,
601 Dm: DriverMode,
602{
603 rsa: &'a mut Rsa<'d, Dm>,
604 phantom: PhantomData<T>,
605}
606
607impl<'a, 'd, T, Dm, const N: usize> RsaMultiplication<'a, 'd, T, Dm>
608where
609 T: RsaMode<InputType = [u32; N]>,
610 T: Multi,
611 Dm: DriverMode,
612{
613 pub fn new(rsa: &'a mut Rsa<'d, Dm>, operand_a: &T::InputType) -> Self {
615 rsa.write_multi_mode(2 * N as u32 / WORDS_PER_INCREMENT - 1, false);
617 rsa.write_operand_a(operand_a);
618
619 Self {
620 rsa,
621 phantom: PhantomData,
622 }
623 }
624
625 pub fn start_multiplication(&mut self, operand_b: &T::InputType) {
627 self.set_up_multiplication(operand_b);
628 self.rsa.start_multi();
629 }
630
631 pub fn read_results<const O: usize>(&mut self, outbuf: &mut T::OutputType)
637 where
638 T: Multi<OutputType = [u32; O]>,
639 {
640 self.rsa.read_results(outbuf);
641 }
642
643 fn set_up_multiplication(&mut self, operand_b: &T::InputType) {
644 self.rsa.write_multi_operand_b(operand_b);
645 }
646}
647
648static WAKER: AtomicWaker = AtomicWaker::new();
649static SIGNALED: AtomicBool = AtomicBool::new(false);
651
652#[must_use = "futures do nothing unless you `.await` or poll them"]
654struct RsaFuture<'a, 'd> {
655 driver: &'a Rsa<'d, Async>,
656}
657
658impl<'a, 'd> RsaFuture<'a, 'd> {
659 fn new(driver: &'a Rsa<'d, Async>) -> Self {
660 SIGNALED.store(false, Ordering::Relaxed);
661
662 driver.internal_enable_disable_interrupt(true);
663
664 Self { driver }
665 }
666
667 fn is_done(&self) -> bool {
668 SIGNALED.load(Ordering::Acquire)
669 }
670}
671
672impl Drop for RsaFuture<'_, '_> {
673 fn drop(&mut self) {
674 self.driver.internal_enable_disable_interrupt(false);
675 }
676}
677
678impl core::future::Future for RsaFuture<'_, '_> {
679 type Output = ();
680
681 fn poll(
682 self: core::pin::Pin<&mut Self>,
683 cx: &mut core::task::Context<'_>,
684 ) -> core::task::Poll<Self::Output> {
685 WAKER.register(cx.waker());
686 if self.is_done() {
687 Poll::Ready(())
688 } else {
689 Poll::Pending
690 }
691 }
692}
693
694impl<T: RsaMode, const N: usize> RsaModularExponentiation<'_, '_, T, Async>
695where
696 T: RsaMode<InputType = [u32; N]>,
697{
698 pub async fn exponentiation(
700 &mut self,
701 base: &T::InputType,
702 r: &T::InputType,
703 outbuf: &mut T::InputType,
704 ) {
705 self.set_up_exponentiation(base, r);
706 let fut = RsaFuture::new(self.rsa);
707 self.rsa.start_modexp();
708 fut.await;
709 self.rsa.read_out(outbuf);
710 }
711}
712
713impl<T: RsaMode, const N: usize> RsaModularMultiplication<'_, '_, T, Async>
714where
715 T: RsaMode<InputType = [u32; N]>,
716{
717 pub async fn modular_multiplication(
719 &mut self,
720 operand_b: &T::InputType,
721 outbuf: &mut T::InputType,
722 ) {
723 if cfg!(esp32) {
724 let fut = RsaFuture::new(self.rsa);
725 self.rsa.start_multi();
726 fut.await;
727
728 self.rsa.write_operand_a(operand_b);
729 } else {
730 self.set_up_modular_multiplication(operand_b);
731 }
732
733 let fut = RsaFuture::new(self.rsa);
734 self.rsa.start_modmulti();
735 fut.await;
736 self.rsa.read_out(outbuf);
737 }
738}
739
740impl<T: RsaMode + Multi, const N: usize> RsaMultiplication<'_, '_, T, Async>
741where
742 T: RsaMode<InputType = [u32; N]>,
743{
744 pub async fn multiplication<const O: usize>(
746 &mut self,
747 operand_b: &T::InputType,
748 outbuf: &mut T::OutputType,
749 ) where
750 T: Multi<OutputType = [u32; O]>,
751 {
752 self.set_up_multiplication(operand_b);
753 let fut = RsaFuture::new(self.rsa);
754 self.rsa.start_multi();
755 fut.await;
756 self.rsa.read_out(outbuf);
757 }
758}
759
760#[handler]
761pub(super) fn rsa_interrupt_handler() {
763 let rsa = RSA::regs();
764 SIGNALED.store(true, Ordering::Release);
765 cfg_if::cfg_if! {
766 if #[cfg(esp32)] {
767 rsa.interrupt().write(|w| w.interrupt().set_bit());
768 } else {
769 rsa.int_clr().write(|w| w.int_clr().set_bit());
770 }
771 }
772
773 WAKER.wake();
774}
775
776static RSA_WORK_QUEUE: WorkQueue<RsaWorkItem> = WorkQueue::new();
777const RSA_VTABLE: VTable<RsaWorkItem> = VTable {
778 post: |driver, item| {
779 let driver = unsafe { RsaBackend::from_raw(driver) };
781 Some(driver.process_item(item))
782 },
783 poll: |driver, item| {
784 let driver = unsafe { RsaBackend::from_raw(driver) };
785 driver.process_item(item)
786 },
787 cancel: |driver, item| {
788 let driver = unsafe { RsaBackend::from_raw(driver) };
789 driver.cancel(item)
790 },
791 stop: |driver| {
792 let driver = unsafe { RsaBackend::from_raw(driver) };
793 driver.deinitialize()
794 },
795};
796
797#[derive(Default)]
798enum RsaBackendState<'d> {
799 #[default]
800 Idle,
801 Initializing(Rsa<'d, Blocking>),
802 Ready(Rsa<'d, Blocking>),
803 #[cfg(esp32)]
804 ModularMultiplicationRoundOne(Rsa<'d, Blocking>),
805 Processing(Rsa<'d, Blocking>),
806}
807
808#[procmacros::doc_replace]
809pub struct RsaBackend<'d> {
839 peri: RSA<'d>,
840 state: RsaBackendState<'d>,
841}
842
843impl<'d> RsaBackend<'d> {
844 #[procmacros::doc_replace]
845 pub fn new(rsa: RSA<'d>) -> Self {
857 Self {
858 peri: rsa,
859 state: RsaBackendState::Idle,
860 }
861 }
862
863 #[procmacros::doc_replace]
864 pub fn start(&mut self) -> RsaWorkQueueDriver<'_, 'd> {
880 RsaWorkQueueDriver {
881 inner: WorkQueueDriver::new(self, RSA_VTABLE, &RSA_WORK_QUEUE),
882 }
883 }
884
885 unsafe fn from_raw<'any>(ptr: NonNull<()>) -> &'any mut Self {
888 unsafe { ptr.cast::<RsaBackend<'_>>().as_mut() }
889 }
890
891 fn process_item(&mut self, item: &mut RsaWorkItem) -> work_queue::Poll {
892 match core::mem::take(&mut self.state) {
893 RsaBackendState::Idle => {
894 let driver = Rsa {
895 rsa: unsafe { self.peri.clone_unchecked() },
896 phantom: PhantomData,
897 _guard: RsaGuard::new(),
898 };
899 self.state = RsaBackendState::Initializing(driver);
900 work_queue::Poll::Pending(true)
901 }
902 RsaBackendState::Initializing(mut rsa) => {
903 self.state = if rsa.ready() {
906 rsa.set_interrupt_handler(rsa_work_queue_handler);
907 rsa.enable_disable_interrupt(true);
908 RsaBackendState::Ready(rsa)
909 } else {
910 RsaBackendState::Initializing(rsa)
911 };
912 work_queue::Poll::Pending(true)
913 }
914 RsaBackendState::Ready(mut rsa) => {
915 #[cfg(not(esp32))]
916 {
917 rsa.disable_constant_time(!item.constant_time);
918 rsa.search_acceleration(item.search_acceleration);
919 }
920
921 match item.operation {
922 RsaOperation::Multiplication { x, y } => {
923 let n = x.len() as u32;
924 rsa.write_operand_a(unsafe { x.as_ref() });
925
926 rsa.write_multi_mode(2 * n / WORDS_PER_INCREMENT - 1, false);
928 rsa.write_multi_operand_b(unsafe { y.as_ref() });
929 rsa.start_multi();
930 }
931
932 RsaOperation::ModularMultiplication {
933 x,
934 #[cfg(not(esp32))]
935 y,
936 m,
937 m_prime,
938 r: r_inv,
939 ..
940 } => {
941 let n = x.len() as u32;
942 rsa.write_operand_a(unsafe { x.as_ref() });
943
944 rsa.write_multi_mode(n / WORDS_PER_INCREMENT - 1, true);
945
946 #[cfg(not(esp32))]
947 rsa.write_operand_b(unsafe { y.as_ref() });
948
949 rsa.write_modulus(unsafe { m.as_ref() });
950 rsa.write_mprime(m_prime);
951 rsa.write_r(unsafe { r_inv.as_ref() });
952
953 rsa.start_modmulti();
954
955 #[cfg(esp32)]
956 {
957 self.state = RsaBackendState::ModularMultiplicationRoundOne(rsa);
960
961 return work_queue::Poll::Pending(false);
962 }
963 }
964 RsaOperation::ModularExponentiation {
965 x,
966 y,
967 m,
968 m_prime,
969 r_inv,
970 } => {
971 let n = x.len() as u32;
972 rsa.write_operand_a(unsafe { x.as_ref() });
973
974 rsa.write_modexp_mode(n / WORDS_PER_INCREMENT - 1);
975 rsa.write_operand_b(unsafe { y.as_ref() });
976 rsa.write_modulus(unsafe { m.as_ref() });
977 rsa.write_mprime(m_prime);
978 rsa.write_r(unsafe { r_inv.as_ref() });
979
980 #[cfg(not(esp32))]
981 if item.search_acceleration {
982 fn find_search_pos(exponent: &[u32]) -> u32 {
983 for (i, byte) in exponent.iter().rev().enumerate() {
984 if *byte == 0 {
985 continue;
986 }
987 return (exponent.len() * 32) as u32
988 - (byte.leading_zeros() + i as u32 * 32)
989 - 1;
990 }
991 0
992 }
993 rsa.write_search_position(find_search_pos(unsafe { y.as_ref() }));
994 }
995
996 rsa.start_modexp();
997 }
998 }
999
1000 self.state = RsaBackendState::Processing(rsa);
1001
1002 work_queue::Poll::Pending(false)
1003 }
1004
1005 #[cfg(esp32)]
1006 RsaBackendState::ModularMultiplicationRoundOne(mut rsa) => {
1007 if rsa.is_idle() {
1008 let RsaOperation::ModularMultiplication { y, .. } = item.operation else {
1009 unreachable!();
1010 };
1011
1012 rsa.write_operand_a(unsafe { y.as_ref() });
1014 rsa.start_modmulti();
1015
1016 self.state = RsaBackendState::Processing(rsa);
1017 } else {
1018 self.state = RsaBackendState::ModularMultiplicationRoundOne(rsa);
1020 }
1021 work_queue::Poll::Pending(false)
1022 }
1023
1024 RsaBackendState::Processing(rsa) => {
1025 if rsa.is_idle() {
1026 rsa.read_out(unsafe { item.result.as_mut() });
1027
1028 self.state = RsaBackendState::Ready(rsa);
1029 work_queue::Poll::Ready(Status::Completed)
1030 } else {
1031 self.state = RsaBackendState::Processing(rsa);
1032 work_queue::Poll::Pending(false)
1033 }
1034 }
1035 }
1036 }
1037
1038 fn cancel(&mut self, _item: &mut RsaWorkItem) {
1039 self.state = RsaBackendState::Idle;
1042 }
1043
1044 fn deinitialize(&mut self) {
1045 self.state = RsaBackendState::Idle;
1046 }
1047}
1048
1049pub struct RsaWorkQueueDriver<'t, 'd> {
1055 inner: WorkQueueDriver<'t, RsaBackend<'d>, RsaWorkItem>,
1056}
1057
1058impl<'t, 'd> RsaWorkQueueDriver<'t, 'd> {
1059 pub fn stop(self) -> impl Future<Output = ()> {
1061 self.inner.stop()
1062 }
1063}
1064
1065#[derive(Clone)]
1066struct RsaWorkItem {
1067 #[cfg(not(esp32))]
1069 search_acceleration: bool,
1070 #[cfg(not(esp32))]
1071 constant_time: bool,
1072
1073 operation: RsaOperation,
1075 result: NonNull<[u32]>,
1076}
1077
1078unsafe impl Sync for RsaWorkItem {}
1079unsafe impl Send for RsaWorkItem {}
1080
1081#[derive(Clone)]
1082enum RsaOperation {
1083 Multiplication {
1086 x: NonNull<[u32]>,
1087 y: NonNull<[u32]>,
1088 },
1089 ModularMultiplication {
1091 x: NonNull<[u32]>,
1092 y: NonNull<[u32]>,
1093 m: NonNull<[u32]>,
1094 r: NonNull<[u32]>,
1095 m_prime: u32,
1096 },
1097 ModularExponentiation {
1099 x: NonNull<[u32]>,
1100 y: NonNull<[u32]>,
1101 m: NonNull<[u32]>,
1102 r_inv: NonNull<[u32]>,
1103 m_prime: u32,
1104 },
1105}
1106
1107#[handler]
1108#[ram]
1109fn rsa_work_queue_handler() {
1110 if !RSA_WORK_QUEUE.process() {
1111 cfg_if::cfg_if! {
1114 if #[cfg(esp32)] {
1115 RSA::regs().interrupt().write(|w| w.interrupt().set_bit());
1116 } else {
1117 RSA::regs().int_clr().write(|w| w.int_clr().set_bit());
1118 }
1119 }
1120 }
1121}
1122
1123#[cfg_attr(
1130 not(esp32),
1131 doc = " \nThe context is created with a secure configuration by default. You can enable hardware acceleration
1132 options using [enable_search_acceleration][Self::enable_search_acceleration] and
1133 [enable_acceleration][Self::enable_acceleration] when appropriate."
1134)]
1135#[derive(Clone)]
1136pub struct RsaContext {
1137 frontend: WorkQueueFrontend<RsaWorkItem>,
1138}
1139
1140impl Default for RsaContext {
1141 fn default() -> Self {
1142 Self::new()
1143 }
1144}
1145
1146impl RsaContext {
1147 pub fn new() -> Self {
1149 Self {
1150 frontend: WorkQueueFrontend::new(RsaWorkItem {
1151 #[cfg(not(esp32))]
1152 search_acceleration: false,
1153 #[cfg(not(esp32))]
1154 constant_time: true,
1155 operation: RsaOperation::Multiplication {
1156 x: NonNull::from(&[]),
1157 y: NonNull::from(&[]),
1158 },
1159 result: NonNull::from(&mut []),
1160 }),
1161 }
1162 }
1163
1164 #[cfg(not(esp32))]
1165 #[doc = trm_markdown_link!("rsa")]
1175 pub fn enable_search_acceleration(&mut self) {
1176 self.frontend.data_mut().search_acceleration = true;
1177 }
1178
1179 #[cfg(not(esp32))]
1180 #[doc = trm_markdown_link!("rsa")]
1191 pub fn enable_acceleration(&mut self) {
1192 self.frontend.data_mut().constant_time = false;
1193 }
1194
1195 fn post(&mut self) -> RsaHandle<'_> {
1196 RsaHandle(self.frontend.post(&RSA_WORK_QUEUE))
1197 }
1198
1199 #[procmacros::doc_replace]
1200 pub fn modular_exponentiate<'t, OP>(
1265 &'t mut self,
1266 x: &'t OP::InputType,
1267 y: &'t OP::InputType,
1268 m: &'t OP::InputType,
1269 r: &'t OP::InputType,
1270 m_prime: u32,
1271 result: &'t mut OP::InputType,
1272 ) -> RsaHandle<'t>
1273 where
1274 OP: RsaMode,
1275 {
1276 self.frontend.data_mut().operation = RsaOperation::ModularExponentiation {
1277 x: NonNull::from(x.as_ref()),
1278 y: NonNull::from(y.as_ref()),
1279 m: NonNull::from(m.as_ref()),
1280 r_inv: NonNull::from(r.as_ref()),
1281 m_prime,
1282 };
1283 self.frontend.data_mut().result = NonNull::from(result.as_mut());
1284 self.post()
1285 }
1286
1287 pub fn modular_multiply<'t, OP>(
1303 &'t mut self,
1304 x: &'t OP::InputType,
1305 y: &'t OP::InputType,
1306 m: &'t OP::InputType,
1307 r: &'t OP::InputType,
1308 m_prime: u32,
1309 result: &'t mut OP::InputType,
1310 ) -> RsaHandle<'t>
1311 where
1312 OP: RsaMode,
1313 {
1314 self.frontend.data_mut().operation = RsaOperation::ModularMultiplication {
1315 x: NonNull::from(x.as_ref()),
1316 y: NonNull::from(y.as_ref()),
1317 m: NonNull::from(m.as_ref()),
1318 r: NonNull::from(r.as_ref()),
1319 m_prime,
1320 };
1321 self.frontend.data_mut().result = NonNull::from(result.as_mut());
1322 self.post()
1323 }
1324
1325 #[procmacros::doc_replace]
1326 pub fn multiply<'t, OP>(
1356 &'t mut self,
1357 x: &'t OP::InputType,
1358 y: &'t OP::InputType,
1359 result: &'t mut OP::OutputType,
1360 ) -> RsaHandle<'t>
1361 where
1362 OP: Multi,
1363 {
1364 self.frontend.data_mut().operation = RsaOperation::Multiplication {
1365 x: NonNull::from(x.as_ref()),
1366 y: NonNull::from(y.as_ref()),
1367 };
1368 self.frontend.data_mut().result = NonNull::from(result.as_mut());
1369 self.post()
1370 }
1371}
1372
1373pub struct RsaHandle<'t>(work_queue::Handle<'t, RsaWorkItem>);
1375
1376impl RsaHandle<'_> {
1377 #[inline]
1379 pub fn poll(&mut self) -> bool {
1380 self.0.poll()
1381 }
1382
1383 #[inline]
1385 pub fn wait_blocking(self) {
1386 self.0.wait_blocking();
1387 }
1388
1389 #[inline]
1391 pub fn wait(&mut self) -> impl Future<Output = Status> {
1392 self.0.wait()
1393 }
1394}