aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-nrf')
-rw-r--r--embassy-nrf/src/chips/nrf54l15_app.rs2
-rw-r--r--embassy-nrf/src/cracen.rs161
-rw-r--r--embassy-nrf/src/lib.rs4
3 files changed, 166 insertions, 1 deletions
diff --git a/embassy-nrf/src/chips/nrf54l15_app.rs b/embassy-nrf/src/chips/nrf54l15_app.rs
index d0068eb20..285cdec07 100644
--- a/embassy-nrf/src/chips/nrf54l15_app.rs
+++ b/embassy-nrf/src/chips/nrf54l15_app.rs
@@ -682,6 +682,8 @@ impl_saadc_input!(P1_12, 1, 12);
682impl_saadc_input!(P1_13, 1, 13); 682impl_saadc_input!(P1_13, 1, 13);
683impl_saadc_input!(P1_14, 1, 14); 683impl_saadc_input!(P1_14, 1, 14);
684 684
685impl_cracen!(CRACEN, CRACEN, CRACEN);
686
685embassy_hal_internal::interrupt_mod!( 687embassy_hal_internal::interrupt_mod!(
686 SWI00, 688 SWI00,
687 SWI01, 689 SWI01,
diff --git a/embassy-nrf/src/cracen.rs b/embassy-nrf/src/cracen.rs
new file mode 100644
index 000000000..ddc592689
--- /dev/null
+++ b/embassy-nrf/src/cracen.rs
@@ -0,0 +1,161 @@
1//! CRACEN - Cryptographic Accelerator Engine driver.
2
3#![macro_use]
4
5use crate::mode::{Async, Blocking, Mode};
6use crate::{Peri, interrupt, pac, peripherals};
7use core::marker::PhantomData;
8
9pub struct Cracen<'d, M: Mode> {
10 _peri: Peri<'d, peripherals::CRACEN>,
11 _p: PhantomData<M>,
12}
13
14impl<'d> Cracen<'d, Blocking> {
15 /// Create a new CRACEN driver.
16 pub fn new_blocking(_peri: Peri<'d, peripherals::CRACEN>) -> Self {
17 let r = pac::CRACEN;
18
19 let me = Self { _peri, _p: PhantomData };
20
21 me.stop();
22 me
23 }
24}
25
26impl<'d, M: Mode> Cracen<'d, M> {
27 fn regs() -> pac::cracen::Cracen {
28 pac::CRACEN
29 }
30
31 fn core() -> pac::cracencore::Cracencore {
32 pac::CRACENCORE
33 }
34
35 fn start_rng(&self) {
36 let r = Self::regs();
37 r.enable().write(|w| {
38 w.set_rng(true);
39 });
40
41 let r = Self::core();
42 r.rngcontrol().control().write(|w| {
43 w.set_enable(true);
44 });
45
46 while r.rngcontrol().status().read().state() == pac::cracencore::vals::State::STARTUP {}
47 }
48
49 fn stop(&self) {
50 let r = Self::regs();
51 r.enable().write(|w| {
52 w.set_cryptomaster(false);
53 w.set_rng(false);
54 w.set_pkeikg(false);
55 });
56 }
57
58 /// Fill the buffer with random bytes, blocking version.
59 pub fn blocking_fill_bytes(&mut self, dest: &mut [u8]) {
60 self.start_rng();
61
62 let r = Self::core();
63 for chunk in dest.chunks_mut(4) {
64 while r.rngcontrol().fifolevel().read() == 0 {}
65 let word = r.rngcontrol().fifo(0).read().to_ne_bytes();
66 let to_copy = word.len().min(chunk.len());
67 chunk[..to_copy].copy_from_slice(&word[..to_copy]);
68 }
69
70 self.stop();
71 }
72
73 /// Generate a random u32
74 pub fn blocking_next_u32(&mut self) -> u32 {
75 let mut bytes = [0; 4];
76 self.blocking_fill_bytes(&mut bytes);
77 // We don't care about the endianness, so just use the native one.
78 u32::from_ne_bytes(bytes)
79 }
80
81 /// Generate a random u64
82 pub fn blocking_next_u64(&mut self) -> u64 {
83 let mut bytes = [0; 8];
84 self.blocking_fill_bytes(&mut bytes);
85 u64::from_ne_bytes(bytes)
86 }
87}
88
89impl<'d, M: Mode> Drop for Cracen<'d, M> {
90 fn drop(&mut self) {
91 let r = Self::core();
92 r.rngcontrol().control().write(|w| {
93 w.set_enable(false);
94 });
95
96 while r.rngcontrol().status().read().state() != pac::cracencore::vals::State::RESET {}
97
98 let r = Self::regs();
99 r.enable().write(|w| {
100 w.set_cryptomaster(false);
101 w.set_rng(false);
102 w.set_pkeikg(false);
103 });
104 }
105}
106
107impl<'d, M: Mode> rand_core_06::RngCore for Cracen<'d, M> {
108 fn fill_bytes(&mut self, dest: &mut [u8]) {
109 self.blocking_fill_bytes(dest);
110 }
111 fn next_u32(&mut self) -> u32 {
112 self.blocking_next_u32()
113 }
114 fn next_u64(&mut self) -> u64 {
115 self.blocking_next_u64()
116 }
117 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core_06::Error> {
118 self.blocking_fill_bytes(dest);
119 Ok(())
120 }
121}
122
123impl<'d, M: Mode> rand_core_06::CryptoRng for Cracen<'d, M> {}
124
125impl<'d, M: Mode> rand_core_09::RngCore for Cracen<'d, M> {
126 fn fill_bytes(&mut self, dest: &mut [u8]) {
127 self.blocking_fill_bytes(dest);
128 }
129 fn next_u32(&mut self) -> u32 {
130 self.blocking_next_u32()
131 }
132 fn next_u64(&mut self) -> u64 {
133 self.blocking_next_u64()
134 }
135}
136
137impl<'d, M: Mode> rand_core_09::CryptoRng for Cracen<'d, M> {}
138
139pub(crate) trait SealedInstance {
140 fn regs() -> pac::cracen::Cracen;
141}
142
143/// CRACEN peripheral instance.
144#[allow(private_bounds)]
145pub trait Instance: SealedInstance + 'static + Send {
146 /// Interrupt for this peripheral.
147 type Interrupt: interrupt::typelevel::Interrupt;
148}
149
150macro_rules! impl_cracen {
151 ($type:ident, $pac_type:ident, $irq:ident) => {
152 impl crate::cracen::SealedInstance for peripherals::$type {
153 fn regs() -> crate::pac::cracen::Cracen {
154 pac::$pac_type
155 }
156 }
157 impl crate::cracen::Instance for peripherals::$type {
158 type Interrupt = crate::interrupt::typelevel::$irq;
159 }
160 };
161}
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs
index 4c3b92a83..530964107 100644
--- a/embassy-nrf/src/lib.rs
+++ b/embassy-nrf/src/lib.rs
@@ -145,10 +145,12 @@ pub mod radio;
145#[cfg(feature = "_net-driver")] 145#[cfg(feature = "_net-driver")]
146pub mod embassy_net_802154_driver; 146pub mod embassy_net_802154_driver;
147 147
148#[cfg(feature = "_nrf54l")]
149pub mod cracen;
148#[cfg(not(feature = "_nrf54l"))] // TODO 150#[cfg(not(feature = "_nrf54l"))] // TODO
149#[cfg(feature = "_nrf5340")] 151#[cfg(feature = "_nrf5340")]
150pub mod reset; 152pub mod reset;
151#[cfg(not(feature = "_nrf54l"))] // TODO 153#[cfg(not(feature = "_nrf54l"))]
152#[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))] 154#[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))]
153pub mod rng; 155pub mod rng;
154pub mod rtc; 156pub mod rtc;