feat: add display UI with splash screen, dashboard, and RSSI sparkline
Implement full SSD1306 OLED display support: - Splash screen on boot (1.5s) with project name, version, board - Dashboard showing radio state, config, counters, RSSI/SNR - RSSI history sparkline (64-sample ring buffer, 2px-wide bars) - DisplayOn/DisplayOff host commands routed via dedicated channel - Pure render functions against generic DrawTarget (no hardware coupling) - Display on/off control bypasses radio task entirely Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
17624 files changed
+4564928
-38
No files matched your search
Vendored
+123
@@ -0,0 +1,123 @@
|
||||
use core::convert::Infallible;
|
||||
|
||||
use crate::rsa::{
|
||||
implement_op,
|
||||
Multi,
|
||||
Rsa,
|
||||
RsaMode,
|
||||
RsaModularExponentiation,
|
||||
RsaModularMultiplication,
|
||||
RsaMultiplication,
|
||||
};
|
||||
|
||||
impl<'d, DM: crate::Mode> Rsa<'d, DM> {
|
||||
/// After the RSA Accelerator is released from reset, the memory blocks
|
||||
/// needs to be initialized, only after that peripheral should be used.
|
||||
/// This function would return without an error if the memory is initialized
|
||||
pub fn ready(&mut self) -> nb::Result<(), Infallible> {
|
||||
if self.rsa.clean().read().clean().bit_is_clear() {
|
||||
return Err(nb::Error::WouldBlock);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Writes the multi-mode configuration to the RSA hardware.
|
||||
pub(super) fn write_multi_mode(&mut self, mode: u32) {
|
||||
self.rsa.mult_mode().write(|w| unsafe { w.bits(mode) });
|
||||
}
|
||||
|
||||
/// Writes the modular exponentiation mode configuration to the RSA
|
||||
/// hardware.
|
||||
pub(super) fn write_modexp_mode(&mut self, mode: u32) {
|
||||
self.rsa.modexp_mode().write(|w| unsafe { w.bits(mode) });
|
||||
}
|
||||
|
||||
/// Starts the modular exponentiation operation.
|
||||
pub(super) fn write_modexp_start(&self) {
|
||||
self.rsa
|
||||
.modexp_start()
|
||||
.write(|w| w.modexp_start().set_bit());
|
||||
}
|
||||
|
||||
/// Starts the multiplication operation.
|
||||
pub(super) fn write_multi_start(&self) {
|
||||
self.rsa.mult_start().write(|w| w.mult_start().set_bit());
|
||||
}
|
||||
|
||||
/// Starts the modular multiplication operation.
|
||||
pub(super) fn write_modmulti_start(&self) {
|
||||
self.write_multi_start();
|
||||
}
|
||||
|
||||
/// Clears the RSA interrupt flag.
|
||||
pub(super) fn clear_interrupt(&mut self) {
|
||||
self.rsa.interrupt().write(|w| w.interrupt().set_bit());
|
||||
}
|
||||
|
||||
/// Checks if the RSA peripheral is idle.
|
||||
pub(super) fn is_idle(&self) -> bool {
|
||||
self.rsa.interrupt().read().interrupt().bit_is_set()
|
||||
}
|
||||
}
|
||||
|
||||
/// Module defining marker types for various RSA operand sizes.
|
||||
pub mod operand_sizes {
|
||||
//! Marker types for the operand sizes
|
||||
use paste::paste;
|
||||
|
||||
use super::{implement_op, Multi, RsaMode};
|
||||
|
||||
implement_op!(
|
||||
(512, multi),
|
||||
(1024, multi),
|
||||
(1536, multi),
|
||||
(2048, multi),
|
||||
(2560),
|
||||
(3072),
|
||||
(3584),
|
||||
(4096)
|
||||
);
|
||||
}
|
||||
|
||||
impl<'a, 'd, T: RsaMode, DM: crate::Mode, const N: usize> RsaModularMultiplication<'a, 'd, T, DM>
|
||||
where
|
||||
T: RsaMode<InputType = [u32; N]>,
|
||||
{
|
||||
pub(super) fn write_mode(rsa: &mut Rsa<'d, DM>) {
|
||||
rsa.write_multi_mode((N / 16 - 1) as u32)
|
||||
}
|
||||
|
||||
/// Starts the modular multiplication operation.
|
||||
///
|
||||
/// For more information refer to 24.3.2 of <https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf>.
|
||||
pub(super) fn set_up_modular_multiplication(&mut self, operand_b: &T::InputType) {
|
||||
self.rsa.write_multi_start();
|
||||
self.rsa.wait_for_idle();
|
||||
|
||||
self.rsa.write_operand_a(operand_b);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'd, T: RsaMode, DM: crate::Mode, const N: usize> RsaModularExponentiation<'a, 'd, T, DM>
|
||||
where
|
||||
T: RsaMode<InputType = [u32; N]>,
|
||||
{
|
||||
/// Sets the modular exponentiation mode for the RSA hardware.
|
||||
pub(super) fn write_mode(rsa: &mut Rsa<'d, DM>) {
|
||||
rsa.write_modexp_mode((N / 16 - 1) as u32)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'd, T: RsaMode + Multi, DM: crate::Mode, const N: usize> RsaMultiplication<'a, 'd, T, DM>
|
||||
where
|
||||
T: RsaMode<InputType = [u32; N]>,
|
||||
{
|
||||
/// Sets the multiplication mode for the RSA hardware.
|
||||
pub(super) fn write_mode(rsa: &mut Rsa<'d, DM>) {
|
||||
rsa.write_multi_mode(((N * 2) / 16 + 7) as u32)
|
||||
}
|
||||
|
||||
pub(super) fn set_up_multiplication(&mut self, operand_b: &T::InputType) {
|
||||
self.rsa.write_multi_operand_b(operand_b);
|
||||
}
|
||||
}
|
||||
Vendored
+277
@@ -0,0 +1,277 @@
|
||||
use core::convert::Infallible;
|
||||
|
||||
use crate::rsa::{
|
||||
implement_op,
|
||||
Multi,
|
||||
Rsa,
|
||||
RsaMode,
|
||||
RsaModularExponentiation,
|
||||
RsaModularMultiplication,
|
||||
RsaMultiplication,
|
||||
};
|
||||
|
||||
impl<DM: crate::Mode> Rsa<'_, DM> {
|
||||
/// After the RSA Accelerator is released from reset, the memory blocks
|
||||
/// needs to be initialized, only after that peripheral should be used.
|
||||
/// This function would return without an error if the memory is initialized
|
||||
pub fn ready(&mut self) -> nb::Result<(), Infallible> {
|
||||
if self.rsa.query_clean().read().query_clean().bit_is_clear() {
|
||||
return Err(nb::Error::WouldBlock);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Enables/disables rsa interrupt.
|
||||
///
|
||||
/// When enabled rsa peripheral would generate an interrupt when a operation
|
||||
/// is finished.
|
||||
pub fn enable_disable_interrupt(&mut self, enable: bool) {
|
||||
self.rsa.int_ena().write(|w| w.int_ena().bit(enable));
|
||||
}
|
||||
|
||||
fn write_mode(&mut self, mode: u32) {
|
||||
self.rsa.mode().write(|w| unsafe { w.bits(mode) });
|
||||
}
|
||||
|
||||
/// Enables/disables search acceleration.
|
||||
///
|
||||
/// When enabled it would increases the performance of modular
|
||||
/// exponentiation by discarding the exponent's bits before the most
|
||||
/// significant set bit.
|
||||
///
|
||||
/// Note: this might decrease security.
|
||||
///
|
||||
/// For more information refer to 18.3.4 of <https://www.espressif.com/sites/default/files/documentation/esp32-c6_technical_reference_manual_en.pdf>
|
||||
pub fn enable_disable_search_acceleration(&mut self, enable: bool) {
|
||||
match enable {
|
||||
true => self
|
||||
.rsa
|
||||
.search_enable()
|
||||
.write(|w| w.search_enable().set_bit()),
|
||||
false => self
|
||||
.rsa
|
||||
.search_enable()
|
||||
.write(|w| w.search_enable().clear_bit()),
|
||||
};
|
||||
}
|
||||
|
||||
/// Checks if the search functionality is enabled in the RSA hardware.
|
||||
pub(super) fn is_search_enabled(&mut self) -> bool {
|
||||
self.rsa.search_enable().read().search_enable().bit_is_set()
|
||||
}
|
||||
|
||||
/// Sets the search position in the RSA hardware.
|
||||
pub(super) fn write_search_position(&mut self, search_position: u32) {
|
||||
self.rsa
|
||||
.search_pos()
|
||||
.write(|w| unsafe { w.bits(search_position) });
|
||||
}
|
||||
|
||||
/// Enables/disables constant time acceleration.
|
||||
///
|
||||
/// When enabled it would increases the performance of modular
|
||||
/// exponentiation by simplifying the calculation concerning the 0 bits
|
||||
/// of the exponent. I.e. lesser the hamming weight, greater the
|
||||
/// performance.
|
||||
///
|
||||
/// Note: this might decrease security.
|
||||
///
|
||||
/// For more information refer to 18.3.4 of <https://www.espressif.com/sites/default/files/documentation/esp32-c6_technical_reference_manual_en.pdf>.
|
||||
pub fn enable_disable_constant_time_acceleration(&mut self, enable: bool) {
|
||||
match enable {
|
||||
true => self
|
||||
.rsa
|
||||
.constant_time()
|
||||
.write(|w| w.constant_time().clear_bit()),
|
||||
false => self
|
||||
.rsa
|
||||
.constant_time()
|
||||
.write(|w| w.constant_time().set_bit()),
|
||||
};
|
||||
}
|
||||
|
||||
/// Starts the modular exponentiation operation.
|
||||
pub(super) fn write_modexp_start(&self) {
|
||||
self.rsa
|
||||
.set_start_modexp()
|
||||
.write(|w| w.set_start_modexp().set_bit());
|
||||
}
|
||||
|
||||
/// Starts the multiplication operation.
|
||||
pub(super) fn write_multi_start(&self) {
|
||||
self.rsa
|
||||
.set_start_mult()
|
||||
.write(|w| w.set_start_mult().set_bit());
|
||||
}
|
||||
|
||||
/// Starts the modular multiplication operation.
|
||||
pub(super) fn write_modmulti_start(&self) {
|
||||
self.rsa
|
||||
.set_start_modmult()
|
||||
.write(|w| w.set_start_modmult().set_bit());
|
||||
}
|
||||
|
||||
/// Clears the RSA interrupt flag.
|
||||
pub(super) fn clear_interrupt(&mut self) {
|
||||
self.rsa.int_clr().write(|w| w.int_clr().set_bit());
|
||||
}
|
||||
|
||||
/// Checks if the RSA peripheral is idle.
|
||||
pub(super) fn is_idle(&self) -> bool {
|
||||
self.rsa.query_idle().read().query_idle().bit_is_set()
|
||||
}
|
||||
}
|
||||
|
||||
/// Module defining marker types for various RSA operand sizes.
|
||||
pub mod operand_sizes {
|
||||
//! Marker types for the operand sizes
|
||||
use paste::paste;
|
||||
|
||||
use super::{implement_op, Multi, RsaMode};
|
||||
|
||||
implement_op!(
|
||||
(32, multi),
|
||||
(64, multi),
|
||||
(96, multi),
|
||||
(128, multi),
|
||||
(160, multi),
|
||||
(192, multi),
|
||||
(224, multi),
|
||||
(256, multi),
|
||||
(288, multi),
|
||||
(320, multi),
|
||||
(352, multi),
|
||||
(384, multi),
|
||||
(416, multi),
|
||||
(448, multi),
|
||||
(480, multi),
|
||||
(512, multi),
|
||||
(544, multi),
|
||||
(576, multi),
|
||||
(608, multi),
|
||||
(640, multi),
|
||||
(672, multi),
|
||||
(704, multi),
|
||||
(736, multi),
|
||||
(768, multi),
|
||||
(800, multi),
|
||||
(832, multi),
|
||||
(864, multi),
|
||||
(896, multi),
|
||||
(928, multi),
|
||||
(960, multi),
|
||||
(992, multi),
|
||||
(1024, multi),
|
||||
(1056, multi),
|
||||
(1088, multi),
|
||||
(1120, multi),
|
||||
(1152, multi),
|
||||
(1184, multi),
|
||||
(1216, multi),
|
||||
(1248, multi),
|
||||
(1280, multi),
|
||||
(1312, multi),
|
||||
(1344, multi),
|
||||
(1376, multi),
|
||||
(1408, multi),
|
||||
(1440, multi),
|
||||
(1472, multi),
|
||||
(1504, multi),
|
||||
(1536, multi),
|
||||
(1568),
|
||||
(1600),
|
||||
(1632),
|
||||
(1664),
|
||||
(1696),
|
||||
(1728),
|
||||
(1760),
|
||||
(1792),
|
||||
(1824),
|
||||
(1856),
|
||||
(1888),
|
||||
(1920),
|
||||
(1952),
|
||||
(1984),
|
||||
(2016),
|
||||
(2048),
|
||||
(2080),
|
||||
(2112),
|
||||
(2144),
|
||||
(2176),
|
||||
(2208),
|
||||
(2240),
|
||||
(2272),
|
||||
(2304),
|
||||
(2336),
|
||||
(2368),
|
||||
(2400),
|
||||
(2432),
|
||||
(2464),
|
||||
(2496),
|
||||
(2528),
|
||||
(2560),
|
||||
(2592),
|
||||
(2624),
|
||||
(2656),
|
||||
(2688),
|
||||
(2720),
|
||||
(2752),
|
||||
(2784),
|
||||
(2816),
|
||||
(2848),
|
||||
(2880),
|
||||
(2912),
|
||||
(2944),
|
||||
(2976),
|
||||
(3008),
|
||||
(3040),
|
||||
(3072)
|
||||
);
|
||||
}
|
||||
|
||||
impl<'d, T: RsaMode, DM: crate::Mode, const N: usize> RsaModularExponentiation<'_, 'd, T, DM>
|
||||
where
|
||||
T: RsaMode<InputType = [u32; N]>,
|
||||
{
|
||||
pub(super) fn find_search_pos(exponent: &T::InputType) -> u32 {
|
||||
for (i, byte) in exponent.iter().rev().enumerate() {
|
||||
if *byte == 0 {
|
||||
continue;
|
||||
}
|
||||
return (exponent.len() * 32) as u32 - (byte.leading_zeros() + i as u32 * 32) - 1;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// Sets the modular exponentiation mode for the RSA hardware.
|
||||
pub(super) fn write_mode(rsa: &mut Rsa<'d, DM>) {
|
||||
rsa.write_mode((N - 1) as u32)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: RsaMode, DM: crate::Mode, const N: usize> RsaModularMultiplication<'_, 'd, T, DM>
|
||||
where
|
||||
T: RsaMode<InputType = [u32; N]>,
|
||||
{
|
||||
pub(super) fn write_mode(rsa: &mut Rsa<'d, DM>) {
|
||||
rsa.write_mode((N - 1) as u32)
|
||||
}
|
||||
|
||||
pub(super) fn set_up_modular_multiplication(&mut self, operand_b: &T::InputType) {
|
||||
self.rsa.write_operand_b(operand_b);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: RsaMode + Multi, DM: crate::Mode, const N: usize> RsaMultiplication<'_, 'd, T, DM>
|
||||
where
|
||||
T: RsaMode<InputType = [u32; N]>,
|
||||
{
|
||||
pub(super) fn set_up_multiplication(&mut self, operand_b: &T::InputType) {
|
||||
self.rsa.write_multi_operand_b(operand_b);
|
||||
}
|
||||
|
||||
/// Sets the multiplication mode for the RSA hardware.
|
||||
pub(super) fn write_mode(rsa: &mut Rsa<'d, DM>) {
|
||||
rsa.write_mode((N * 2 - 1) as u32)
|
||||
}
|
||||
}
|
||||
Vendored
+310
@@ -0,0 +1,310 @@
|
||||
use core::convert::Infallible;
|
||||
|
||||
use crate::rsa::{
|
||||
implement_op,
|
||||
Multi,
|
||||
Rsa,
|
||||
RsaMode,
|
||||
RsaModularExponentiation,
|
||||
RsaModularMultiplication,
|
||||
RsaMultiplication,
|
||||
};
|
||||
|
||||
impl<'d, DM: crate::Mode> Rsa<'d, DM> {
|
||||
/// After the RSA accelerator is released from reset, the memory blocks
|
||||
/// needs to be initialized, only after that peripheral should be used.
|
||||
/// This function would return without an error if the memory is
|
||||
/// initialized.
|
||||
pub fn ready(&mut self) -> nb::Result<(), Infallible> {
|
||||
if self.rsa.clean().read().clean().bit_is_clear() {
|
||||
return Err(nb::Error::WouldBlock);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Enables/disables rsa interrupt.
|
||||
///
|
||||
/// When enabled rsa peripheral would generate an interrupt when a operation
|
||||
/// is finished.
|
||||
pub fn enable_disable_interrupt(&mut self, enable: bool) {
|
||||
self.rsa.int_ena().write(|w| w.int_ena().bit(enable));
|
||||
}
|
||||
|
||||
fn write_mode(&mut self, mode: u32) {
|
||||
self.rsa.mode().write(|w| unsafe { w.bits(mode) });
|
||||
}
|
||||
|
||||
/// Enables/disables search acceleration.
|
||||
///
|
||||
/// When enabled it would increases the performance of modular
|
||||
/// exponentiation by discarding the exponent's bits before the most
|
||||
/// significant set bit.
|
||||
///
|
||||
/// Note: this might decrease security.
|
||||
///
|
||||
/// For more information refer to 20.3.4 of <https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf>.
|
||||
pub fn enable_disable_search_acceleration(&mut self, enable: bool) {
|
||||
match enable {
|
||||
true => self
|
||||
.rsa
|
||||
.search_enable()
|
||||
.write(|w| w.search_enable().set_bit()),
|
||||
false => self
|
||||
.rsa
|
||||
.search_enable()
|
||||
.write(|w| w.search_enable().clear_bit()),
|
||||
};
|
||||
}
|
||||
|
||||
/// Checks if the search functionality is enabled in the RSA hardware.
|
||||
pub(super) fn is_search_enabled(&mut self) -> bool {
|
||||
self.rsa.search_enable().read().search_enable().bit_is_set()
|
||||
}
|
||||
|
||||
/// Sets the search position in the RSA hardware.
|
||||
pub(super) fn write_search_position(&mut self, search_position: u32) {
|
||||
self.rsa
|
||||
.search_pos()
|
||||
.write(|w| unsafe { w.bits(search_position) });
|
||||
}
|
||||
|
||||
/// Enables/disables constant time acceleration.
|
||||
///
|
||||
/// When enabled it would increases the performance of modular
|
||||
/// exponentiation by simplifying the calculation concerning the 0 bits
|
||||
/// of the exponent. I.e. lesser the hamming weight, greater the
|
||||
/// performance.
|
||||
///
|
||||
/// Note: this might decrease security.
|
||||
///
|
||||
/// For more information refer to 20.3.4 of <https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf>.
|
||||
pub fn enable_disable_constant_time_acceleration(&mut self, enable: bool) {
|
||||
match enable {
|
||||
true => self
|
||||
.rsa
|
||||
.constant_time()
|
||||
.write(|w| w.constant_time().clear_bit()),
|
||||
false => self
|
||||
.rsa
|
||||
.constant_time()
|
||||
.write(|w| w.constant_time().set_bit()),
|
||||
};
|
||||
}
|
||||
|
||||
/// Starts the modular exponentiation operation.
|
||||
pub(super) fn write_modexp_start(&self) {
|
||||
self.rsa
|
||||
.modexp_start()
|
||||
.write(|w| w.modexp_start().set_bit());
|
||||
}
|
||||
|
||||
/// Starts the multiplication operation.
|
||||
pub(super) fn write_multi_start(&self) {
|
||||
self.rsa.mult_start().write(|w| w.mult_start().set_bit());
|
||||
}
|
||||
|
||||
/// Starts the modular multiplication operation.
|
||||
pub(super) fn write_modmulti_start(&self) {
|
||||
self.rsa
|
||||
.modmult_start()
|
||||
.write(|w| w.modmult_start().set_bit());
|
||||
}
|
||||
|
||||
/// Clears the RSA interrupt flag.
|
||||
pub(super) fn clear_interrupt(&mut self) {
|
||||
self.rsa.int_clr().write(|w| w.int_clr().set_bit());
|
||||
}
|
||||
|
||||
/// Checks if the RSA peripheral is idle.
|
||||
pub(super) fn is_idle(&self) -> bool {
|
||||
self.rsa.idle().read().idle().bit_is_set()
|
||||
}
|
||||
}
|
||||
|
||||
pub mod operand_sizes {
|
||||
//! Marker types for the operand sizes
|
||||
use paste::paste;
|
||||
|
||||
use super::{implement_op, Multi, RsaMode};
|
||||
|
||||
implement_op!(
|
||||
(32, multi),
|
||||
(64, multi),
|
||||
(96, multi),
|
||||
(128, multi),
|
||||
(160, multi),
|
||||
(192, multi),
|
||||
(224, multi),
|
||||
(256, multi),
|
||||
(288, multi),
|
||||
(320, multi),
|
||||
(352, multi),
|
||||
(384, multi),
|
||||
(416, multi),
|
||||
(448, multi),
|
||||
(480, multi),
|
||||
(512, multi),
|
||||
(544, multi),
|
||||
(576, multi),
|
||||
(608, multi),
|
||||
(640, multi),
|
||||
(672, multi),
|
||||
(704, multi),
|
||||
(736, multi),
|
||||
(768, multi),
|
||||
(800, multi),
|
||||
(832, multi),
|
||||
(864, multi),
|
||||
(896, multi),
|
||||
(928, multi),
|
||||
(960, multi),
|
||||
(992, multi),
|
||||
(1024, multi),
|
||||
(1056, multi),
|
||||
(1088, multi),
|
||||
(1120, multi),
|
||||
(1152, multi),
|
||||
(1184, multi),
|
||||
(1216, multi),
|
||||
(1248, multi),
|
||||
(1280, multi),
|
||||
(1312, multi),
|
||||
(1344, multi),
|
||||
(1376, multi),
|
||||
(1408, multi),
|
||||
(1440, multi),
|
||||
(1472, multi),
|
||||
(1504, multi),
|
||||
(1536, multi),
|
||||
(1568, multi),
|
||||
(1600, multi),
|
||||
(1632, multi),
|
||||
(1664, multi),
|
||||
(1696, multi),
|
||||
(1728, multi),
|
||||
(1760, multi),
|
||||
(1792, multi),
|
||||
(1824, multi),
|
||||
(1856, multi),
|
||||
(1888, multi),
|
||||
(1920, multi),
|
||||
(1952, multi),
|
||||
(1984, multi),
|
||||
(2016, multi),
|
||||
(2048, multi)
|
||||
);
|
||||
|
||||
implement_op!(
|
||||
(2080),
|
||||
(2112),
|
||||
(2144),
|
||||
(2176),
|
||||
(2208),
|
||||
(2240),
|
||||
(2272),
|
||||
(2304),
|
||||
(2336),
|
||||
(2368),
|
||||
(2400),
|
||||
(2432),
|
||||
(2464),
|
||||
(2496),
|
||||
(2528),
|
||||
(2560),
|
||||
(2592),
|
||||
(2624),
|
||||
(2656),
|
||||
(2688),
|
||||
(2720),
|
||||
(2752),
|
||||
(2784),
|
||||
(2816),
|
||||
(2848),
|
||||
(2880),
|
||||
(2912),
|
||||
(2944),
|
||||
(2976),
|
||||
(3008),
|
||||
(3040),
|
||||
(3072),
|
||||
(3104),
|
||||
(3136),
|
||||
(3168),
|
||||
(3200),
|
||||
(3232),
|
||||
(3264),
|
||||
(3296),
|
||||
(3328),
|
||||
(3360),
|
||||
(3392),
|
||||
(3424),
|
||||
(3456),
|
||||
(3488),
|
||||
(3520),
|
||||
(3552),
|
||||
(3584),
|
||||
(3616),
|
||||
(3648),
|
||||
(3680),
|
||||
(3712),
|
||||
(3744),
|
||||
(3776),
|
||||
(3808),
|
||||
(3840),
|
||||
(3872),
|
||||
(3904),
|
||||
(3936),
|
||||
(3968),
|
||||
(4000),
|
||||
(4032),
|
||||
(4064),
|
||||
(4096)
|
||||
);
|
||||
}
|
||||
|
||||
impl<'a, 'd, T: RsaMode, DM: crate::Mode, const N: usize> RsaModularExponentiation<'a, 'd, T, DM>
|
||||
where
|
||||
T: RsaMode<InputType = [u32; N]>,
|
||||
{
|
||||
pub(super) fn find_search_pos(exponent: &T::InputType) -> u32 {
|
||||
for (i, byte) in exponent.iter().rev().enumerate() {
|
||||
if *byte == 0 {
|
||||
continue;
|
||||
}
|
||||
return (exponent.len() * 32) as u32 - (byte.leading_zeros() + i as u32 * 32) - 1;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// Sets the modular exponentiation mode for the RSA hardware.
|
||||
pub(super) fn write_mode(rsa: &mut Rsa<'d, DM>) {
|
||||
rsa.write_mode((N - 1) as u32)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'd, T: RsaMode, DM: crate::Mode, const N: usize> RsaModularMultiplication<'a, 'd, T, DM>
|
||||
where
|
||||
T: RsaMode<InputType = [u32; N]>,
|
||||
{
|
||||
pub(super) fn write_mode(rsa: &mut Rsa<'d, DM>) {
|
||||
rsa.write_mode((N - 1) as u32)
|
||||
}
|
||||
|
||||
pub(super) fn set_up_modular_multiplication(&mut self, operand_b: &T::InputType) {
|
||||
self.rsa.write_operand_b(operand_b);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'd, T: RsaMode + Multi, DM: crate::Mode, const N: usize> RsaMultiplication<'a, 'd, T, DM>
|
||||
where
|
||||
T: RsaMode<InputType = [u32; N]>,
|
||||
{
|
||||
/// Sets the multiplication mode for the RSA hardware.
|
||||
pub(super) fn write_mode(rsa: &mut Rsa<'d, DM>) {
|
||||
rsa.write_mode((N * 2 - 1) as u32)
|
||||
}
|
||||
|
||||
pub(super) fn set_up_multiplication(&mut self, operand_b: &T::InputType) {
|
||||
self.rsa.write_multi_operand_b(operand_b);
|
||||
}
|
||||
}
|
||||
Vendored
+530
@@ -0,0 +1,530 @@
|
||||
//! # RSA (Rivest–Shamir–Adleman) accelerator.
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The RSA accelerator provides hardware support for high precision computation
|
||||
//! used in various RSA asymmetric cipher algorithms by significantly reducing
|
||||
//! their software complexity. Compared with RSA algorithms implemented solely
|
||||
//! in software, this hardware accelerator can speed up RSA algorithms
|
||||
//! significantly.
|
||||
//!
|
||||
//! ## Configuration
|
||||
//!
|
||||
//! The RSA accelerator also supports operands of different lengths, which
|
||||
//! provides more flexibility during the computation.
|
||||
//!
|
||||
//! ## Examples
|
||||
//!
|
||||
//! ### Modular Exponentiation, Modular Multiplication, and Multiplication
|
||||
//! Visit the [RSA test suite] for an example of using the peripheral.
|
||||
//!
|
||||
//! [nb]: https://docs.rs/nb/1.1.0/nb/
|
||||
//! [RSA test suite]: https://github.com/esp-rs/esp-hal/blob/main/hil-test/tests/rsa.rs
|
||||
|
||||
use core::{marker::PhantomData, ptr::copy_nonoverlapping};
|
||||
|
||||
use crate::{
|
||||
interrupt::InterruptHandler,
|
||||
peripheral::{Peripheral, PeripheralRef},
|
||||
peripherals::{Interrupt, RSA},
|
||||
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
|
||||
Async,
|
||||
Blocking,
|
||||
Cpu,
|
||||
InterruptConfigurable,
|
||||
};
|
||||
|
||||
#[cfg_attr(esp32s2, path = "esp32sX.rs")]
|
||||
#[cfg_attr(esp32s3, path = "esp32sX.rs")]
|
||||
#[cfg_attr(esp32c3, path = "esp32cX.rs")]
|
||||
#[cfg_attr(esp32c6, path = "esp32cX.rs")]
|
||||
#[cfg_attr(esp32h2, path = "esp32cX.rs")]
|
||||
#[cfg_attr(esp32, path = "esp32.rs")]
|
||||
mod rsa_spec_impl;
|
||||
|
||||
pub use rsa_spec_impl::operand_sizes;
|
||||
|
||||
/// RSA peripheral container
|
||||
pub struct Rsa<'d, DM: crate::Mode> {
|
||||
rsa: PeripheralRef<'d, RSA>,
|
||||
phantom: PhantomData<DM>,
|
||||
}
|
||||
|
||||
impl<'d> Rsa<'d, Blocking> {
|
||||
/// Create a new instance in [crate::Blocking] mode.
|
||||
///
|
||||
/// Optionally an interrupt handler can be bound.
|
||||
pub fn new(rsa: impl Peripheral<P = RSA> + 'd) -> Self {
|
||||
Self::new_internal(rsa)
|
||||
}
|
||||
|
||||
/// Reconfigures the RSA driver to operate in asynchronous mode.
|
||||
pub fn into_async(mut self) -> Rsa<'d, Async> {
|
||||
self.set_interrupt_handler(asynch::rsa_interrupt_handler);
|
||||
Rsa {
|
||||
rsa: self.rsa,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::private::Sealed for Rsa<'_, Blocking> {}
|
||||
|
||||
impl InterruptConfigurable for Rsa<'_, Blocking> {
|
||||
fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
|
||||
for core in crate::Cpu::other() {
|
||||
crate::interrupt::disable(core, Interrupt::RSA);
|
||||
}
|
||||
unsafe { crate::interrupt::bind_interrupt(Interrupt::RSA, handler.handler()) };
|
||||
unwrap!(crate::interrupt::enable(Interrupt::RSA, handler.priority()));
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d> Rsa<'d, Async> {
|
||||
/// Create a new instance in [crate::Blocking] mode.
|
||||
pub fn into_blocking(self) -> Rsa<'d, Blocking> {
|
||||
crate::interrupt::disable(Cpu::current(), Interrupt::RSA);
|
||||
Rsa {
|
||||
rsa: self.rsa,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, DM: crate::Mode> Rsa<'d, DM> {
|
||||
fn new_internal(rsa: impl Peripheral<P = RSA> + 'd) -> Self {
|
||||
crate::into_ref!(rsa);
|
||||
|
||||
PeripheralClockControl::reset(PeripheralEnable::Rsa);
|
||||
PeripheralClockControl::enable(PeripheralEnable::Rsa);
|
||||
|
||||
Self {
|
||||
rsa,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
fn write_operand_b<const N: usize>(&mut self, operand_b: &[u32; N]) {
|
||||
unsafe {
|
||||
copy_nonoverlapping(operand_b.as_ptr(), self.rsa.y_mem(0).as_ptr(), N);
|
||||
}
|
||||
}
|
||||
|
||||
fn write_modulus<const N: usize>(&mut self, modulus: &[u32; N]) {
|
||||
unsafe {
|
||||
copy_nonoverlapping(modulus.as_ptr(), self.rsa.m_mem(0).as_ptr(), N);
|
||||
}
|
||||
}
|
||||
|
||||
fn write_mprime(&mut self, m_prime: u32) {
|
||||
self.rsa.m_prime().write(|w| unsafe { w.bits(m_prime) });
|
||||
}
|
||||
|
||||
fn write_operand_a<const N: usize>(&mut self, operand_a: &[u32; N]) {
|
||||
unsafe {
|
||||
copy_nonoverlapping(operand_a.as_ptr(), self.rsa.x_mem(0).as_ptr(), N);
|
||||
}
|
||||
}
|
||||
|
||||
fn write_multi_operand_b<const N: usize>(&mut self, operand_b: &[u32; N]) {
|
||||
unsafe {
|
||||
copy_nonoverlapping(operand_b.as_ptr(), self.rsa.z_mem(0).as_ptr().add(N), N);
|
||||
}
|
||||
}
|
||||
|
||||
fn write_r<const N: usize>(&mut self, r: &[u32; N]) {
|
||||
unsafe {
|
||||
copy_nonoverlapping(r.as_ptr(), self.rsa.z_mem(0).as_ptr(), N);
|
||||
}
|
||||
}
|
||||
|
||||
fn read_out<const N: usize>(&self, outbuf: &mut [u32; N]) {
|
||||
unsafe {
|
||||
copy_nonoverlapping(
|
||||
self.rsa.z_mem(0).as_ptr() as *const u32,
|
||||
outbuf.as_ptr() as *mut u32,
|
||||
N,
|
||||
);
|
||||
}
|
||||
}
|
||||
fn wait_for_idle(&mut self) {
|
||||
while !self.is_idle() {}
|
||||
self.clear_interrupt();
|
||||
}
|
||||
|
||||
fn read_results<const N: usize>(&mut self, outbuf: &mut [u32; N]) {
|
||||
self.wait_for_idle();
|
||||
self.read_out(outbuf);
|
||||
}
|
||||
}
|
||||
|
||||
/// Defines the input size of an RSA operation.
|
||||
pub trait RsaMode: crate::private::Sealed {
|
||||
/// The input data type used for the operation.
|
||||
type InputType;
|
||||
}
|
||||
|
||||
/// Defines the output type of RSA multiplications.
|
||||
pub trait Multi: RsaMode {
|
||||
/// The type of the output produced by the operation.
|
||||
type OutputType;
|
||||
}
|
||||
|
||||
macro_rules! implement_op {
|
||||
(($x:literal, multi)) => {
|
||||
paste! {
|
||||
#[doc = concat!($x, "-bit RSA operation.")]
|
||||
pub struct [<Op $x>];
|
||||
|
||||
impl Multi for [<Op $x>] {
|
||||
type OutputType = [u32; $x * 2 / 32];
|
||||
}
|
||||
|
||||
impl crate::private::Sealed for [<Op $x>] {}
|
||||
|
||||
impl RsaMode for [<Op $x>] {
|
||||
type InputType = [u32; $x / 32];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
(($x:literal)) => {
|
||||
paste! {
|
||||
/// Represents an RSA operation for the given bit size.
|
||||
pub struct [<Op $x>];
|
||||
|
||||
impl crate::private::Sealed for [<Op $x>] {}
|
||||
|
||||
impl RsaMode for [<Op $x>] {
|
||||
type InputType = [u32; $x / 32];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
($x:tt, $($y:tt),+) => {
|
||||
implement_op!($x);
|
||||
implement_op!($($y),+);
|
||||
};
|
||||
}
|
||||
|
||||
use implement_op;
|
||||
|
||||
/// Support for RSA peripheral's modular exponentiation feature that could be
|
||||
/// used to find the `(base ^ exponent) mod modulus`.
|
||||
///
|
||||
/// Each operand is a little endian byte array of the same size
|
||||
pub struct RsaModularExponentiation<'a, 'd, T: RsaMode, DM: crate::Mode> {
|
||||
rsa: &'a mut Rsa<'d, DM>,
|
||||
phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<'a, 'd, T: RsaMode, DM: crate::Mode, const N: usize> RsaModularExponentiation<'a, 'd, T, DM>
|
||||
where
|
||||
T: RsaMode<InputType = [u32; N]>,
|
||||
{
|
||||
/// Creates an instance of `RsaModularExponentiation`.
|
||||
///
|
||||
/// `m_prime` could be calculated using `-(modular multiplicative inverse of
|
||||
/// modulus) mod 2^32`.
|
||||
///
|
||||
/// For more information refer to 24.3.2 of <https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf>.
|
||||
pub fn new(
|
||||
rsa: &'a mut Rsa<'d, DM>,
|
||||
exponent: &T::InputType,
|
||||
modulus: &T::InputType,
|
||||
m_prime: u32,
|
||||
) -> Self {
|
||||
Self::write_mode(rsa);
|
||||
rsa.write_operand_b(exponent);
|
||||
rsa.write_modulus(modulus);
|
||||
rsa.write_mprime(m_prime);
|
||||
|
||||
#[cfg(not(esp32))]
|
||||
if rsa.is_search_enabled() {
|
||||
rsa.write_search_position(Self::find_search_pos(exponent));
|
||||
}
|
||||
|
||||
Self {
|
||||
rsa,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_up_exponentiation(&mut self, base: &T::InputType, r: &T::InputType) {
|
||||
self.rsa.write_operand_a(base);
|
||||
self.rsa.write_r(r);
|
||||
}
|
||||
|
||||
/// Starts the modular exponentiation operation.
|
||||
///
|
||||
/// `r` can be calculated using `2 ^ ( bitlength * 2 ) mod modulus`.
|
||||
///
|
||||
/// For more information refer to 24.3.2 of <https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf>.
|
||||
pub fn start_exponentiation(&mut self, base: &T::InputType, r: &T::InputType) {
|
||||
self.set_up_exponentiation(base, r);
|
||||
self.rsa.write_modexp_start();
|
||||
}
|
||||
|
||||
/// Reads the result to the given buffer.
|
||||
///
|
||||
/// This is a non blocking function that returns without an error if
|
||||
/// operation is completed successfully. `start_exponentiation` must be
|
||||
/// called before calling this function.
|
||||
pub fn read_results(&mut self, outbuf: &mut T::InputType) {
|
||||
self.rsa.read_results(outbuf);
|
||||
}
|
||||
}
|
||||
|
||||
/// Support for RSA peripheral's modular multiplication feature that could be
|
||||
/// used to find the `(operand a * operand b) mod modulus`.
|
||||
///
|
||||
/// Each operand is a little endian byte array of the same size
|
||||
pub struct RsaModularMultiplication<'a, 'd, T: RsaMode, DM: crate::Mode> {
|
||||
rsa: &'a mut Rsa<'d, DM>,
|
||||
phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<'a, 'd, T: RsaMode, DM: crate::Mode, const N: usize> RsaModularMultiplication<'a, 'd, T, DM>
|
||||
where
|
||||
T: RsaMode<InputType = [u32; N]>,
|
||||
{
|
||||
/// Creates an instance of `RsaModularMultiplication`.
|
||||
///
|
||||
/// - `r` can be calculated using `2 ^ ( bitlength * 2 ) mod modulus`.
|
||||
/// - `m_prime` can be calculated using `-(modular multiplicative inverse of
|
||||
/// modulus) mod 2^32`.
|
||||
///
|
||||
/// For more information refer to 20.3.1 of <https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf>.
|
||||
pub fn new(
|
||||
rsa: &'a mut Rsa<'d, DM>,
|
||||
operand_a: &T::InputType,
|
||||
modulus: &T::InputType,
|
||||
r: &T::InputType,
|
||||
m_prime: u32,
|
||||
) -> Self {
|
||||
Self::write_mode(rsa);
|
||||
rsa.write_mprime(m_prime);
|
||||
rsa.write_modulus(modulus);
|
||||
rsa.write_operand_a(operand_a);
|
||||
rsa.write_r(r);
|
||||
|
||||
Self {
|
||||
rsa,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Starts the modular multiplication operation.
|
||||
///
|
||||
/// For more information refer to 19.3.1 of <https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf>.
|
||||
pub fn start_modular_multiplication(&mut self, operand_b: &T::InputType) {
|
||||
self.set_up_modular_multiplication(operand_b);
|
||||
self.rsa.write_modmulti_start();
|
||||
}
|
||||
|
||||
/// Reads the result to the given buffer.
|
||||
/// This is a non blocking function that returns without an error if
|
||||
/// operation is completed successfully.
|
||||
pub fn read_results(&mut self, outbuf: &mut T::InputType) {
|
||||
self.rsa.read_results(outbuf);
|
||||
}
|
||||
}
|
||||
|
||||
/// Support for RSA peripheral's large number multiplication feature that could
|
||||
/// be used to find the `operand a * operand b`.
|
||||
///
|
||||
/// Each operand is a little endian byte array of the same size
|
||||
pub struct RsaMultiplication<'a, 'd, T: RsaMode + Multi, DM: crate::Mode> {
|
||||
rsa: &'a mut Rsa<'d, DM>,
|
||||
phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<'a, 'd, T: RsaMode + Multi, DM: crate::Mode, const N: usize> RsaMultiplication<'a, 'd, T, DM>
|
||||
where
|
||||
T: RsaMode<InputType = [u32; N]>,
|
||||
{
|
||||
/// Creates an instance of `RsaMultiplication`.
|
||||
pub fn new(rsa: &'a mut Rsa<'d, DM>, operand_a: &T::InputType) -> Self {
|
||||
Self::write_mode(rsa);
|
||||
rsa.write_operand_a(operand_a);
|
||||
|
||||
Self {
|
||||
rsa,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Starts the multiplication operation.
|
||||
pub fn start_multiplication(&mut self, operand_b: &T::InputType) {
|
||||
self.set_up_multiplication(operand_b);
|
||||
self.rsa.write_multi_start();
|
||||
}
|
||||
|
||||
/// Reads the result to the given buffer.
|
||||
/// This is a non blocking function that returns without an error if
|
||||
/// operation is completed successfully. `start_multiplication` must be
|
||||
/// called before calling this function.
|
||||
pub fn read_results<const O: usize>(&mut self, outbuf: &mut T::OutputType)
|
||||
where
|
||||
T: Multi<OutputType = [u32; O]>,
|
||||
{
|
||||
self.rsa.read_results(outbuf);
|
||||
}
|
||||
}
|
||||
|
||||
/// Async functionality
|
||||
pub(crate) mod asynch {
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
use portable_atomic::{AtomicBool, Ordering};
|
||||
use procmacros::handler;
|
||||
|
||||
use crate::{
|
||||
rsa::{
|
||||
Multi,
|
||||
Rsa,
|
||||
RsaMode,
|
||||
RsaModularExponentiation,
|
||||
RsaModularMultiplication,
|
||||
RsaMultiplication,
|
||||
},
|
||||
Async,
|
||||
};
|
||||
|
||||
static WAKER: AtomicWaker = AtomicWaker::new();
|
||||
|
||||
static SIGNALED: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
/// `Future` that waits for the RSA operation to complete.
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
struct RsaFuture<'a, 'd> {
|
||||
#[cfg_attr(esp32, allow(dead_code))]
|
||||
instance: &'a Rsa<'d, Async>,
|
||||
}
|
||||
|
||||
impl<'a, 'd> RsaFuture<'a, 'd> {
|
||||
fn new(instance: &'a Rsa<'d, Async>) -> Self {
|
||||
SIGNALED.store(false, Ordering::Relaxed);
|
||||
|
||||
#[cfg(not(esp32))]
|
||||
instance.rsa.int_ena().write(|w| w.int_ena().set_bit());
|
||||
|
||||
Self { instance }
|
||||
}
|
||||
|
||||
fn is_done(&self) -> bool {
|
||||
SIGNALED.load(Ordering::Acquire)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for RsaFuture<'_, '_> {
|
||||
fn drop(&mut self) {
|
||||
#[cfg(not(esp32))]
|
||||
self.instance
|
||||
.rsa
|
||||
.int_ena()
|
||||
.write(|w| w.int_ena().clear_bit());
|
||||
}
|
||||
}
|
||||
|
||||
impl core::future::Future for RsaFuture<'_, '_> {
|
||||
type Output = ();
|
||||
|
||||
fn poll(
|
||||
self: core::pin::Pin<&mut Self>,
|
||||
cx: &mut core::task::Context<'_>,
|
||||
) -> core::task::Poll<Self::Output> {
|
||||
WAKER.register(cx.waker());
|
||||
if self.is_done() {
|
||||
Poll::Ready(())
|
||||
} else {
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RsaMode, const N: usize> RsaModularExponentiation<'_, '_, T, Async>
|
||||
where
|
||||
T: RsaMode<InputType = [u32; N]>,
|
||||
{
|
||||
/// Asynchronously performs an RSA modular exponentiation operation.
|
||||
pub async fn exponentiation(
|
||||
&mut self,
|
||||
base: &T::InputType,
|
||||
r: &T::InputType,
|
||||
outbuf: &mut T::InputType,
|
||||
) {
|
||||
self.set_up_exponentiation(base, r);
|
||||
let fut = RsaFuture::new(self.rsa);
|
||||
self.rsa.write_modexp_start();
|
||||
fut.await;
|
||||
self.rsa.read_out(outbuf);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RsaMode, const N: usize> RsaModularMultiplication<'_, '_, T, Async>
|
||||
where
|
||||
T: RsaMode<InputType = [u32; N]>,
|
||||
{
|
||||
/// Asynchronously performs an RSA modular multiplication operation.
|
||||
pub async fn modular_multiplication(
|
||||
&mut self,
|
||||
operand_b: &T::InputType,
|
||||
outbuf: &mut T::InputType,
|
||||
) {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(esp32)] {
|
||||
let fut = RsaFuture::new(self.rsa);
|
||||
self.rsa.write_multi_start();
|
||||
fut.await;
|
||||
|
||||
self.rsa.write_operand_a(operand_b);
|
||||
} else {
|
||||
self.set_up_modular_multiplication(operand_b);
|
||||
}
|
||||
}
|
||||
|
||||
let fut = RsaFuture::new(self.rsa);
|
||||
self.rsa.write_modmulti_start();
|
||||
fut.await;
|
||||
self.rsa.read_out(outbuf);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RsaMode + Multi, const N: usize> RsaMultiplication<'_, '_, T, Async>
|
||||
where
|
||||
T: RsaMode<InputType = [u32; N]>,
|
||||
{
|
||||
/// Asynchronously performs an RSA multiplication operation.
|
||||
pub async fn multiplication<const O: usize>(
|
||||
&mut self,
|
||||
operand_b: &T::InputType,
|
||||
outbuf: &mut T::OutputType,
|
||||
) where
|
||||
T: Multi<OutputType = [u32; O]>,
|
||||
{
|
||||
self.set_up_multiplication(operand_b);
|
||||
let fut = RsaFuture::new(self.rsa);
|
||||
self.rsa.write_multi_start();
|
||||
fut.await;
|
||||
self.rsa.read_out(outbuf);
|
||||
}
|
||||
}
|
||||
|
||||
#[handler]
|
||||
/// Interrupt handler for RSA.
|
||||
pub(super) fn rsa_interrupt_handler() {
|
||||
let rsa = unsafe { &*crate::peripherals::RSA::ptr() };
|
||||
SIGNALED.store(true, Ordering::Release);
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(esp32)] {
|
||||
rsa.interrupt().write(|w| w.interrupt().set_bit());
|
||||
} else {
|
||||
rsa.int_clr().write(|w| w.int_clr().set_bit());
|
||||
}
|
||||
}
|
||||
|
||||
WAKER.wake();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user