1use crate::pm;
16use crate::scif;
17use core::cell::Cell;
18use kernel::ErrorCode;
19use kernel::debug;
20use kernel::hil;
21use kernel::hil::symmetric_encryption::{AES_BLOCK_SIZE, AES128, AES128_KEY_SIZE};
22use kernel::utilities::StaticRef;
23use kernel::utilities::cells::{OptionalCell, TakeCell};
24use kernel::utilities::registers::interfaces::{Readable, Writeable};
25use kernel::utilities::registers::{
26 ReadOnly, ReadWrite, WriteOnly, register_bitfields, register_structs,
27};
28
29#[allow(dead_code)]
30#[derive(Copy, Clone)]
31enum ConfidentialityMode {
32 ECB = 0,
33 CBC = 1,
34 CFB = 2,
35 OFB = 3,
36 CTR = 4,
37}
38
39register_structs! {
40 AesRegisters {
42 (0x000 => ctrl: ReadWrite<u32, Control::Register>),
43 (0x004 => mode: ReadWrite<u32, Mode::Register>),
44 (0x008 => databufptr: ReadWrite<u32, DataBuf::Register>),
45 (0x00C => sr: ReadOnly<u32, Status::Register>),
46 (0x010 => ier: WriteOnly<u32, Interrupt::Register>),
47 (0x014 => idr: WriteOnly<u32, Interrupt::Register>),
48 (0x018 => imr: ReadOnly<u32, Interrupt::Register>),
49 (0x01C => _reserved0: [u32; 1]),
50 (0x020 => key0: WriteOnly<u32, Key::Register>),
51 (0x024 => key1: WriteOnly<u32, Key::Register>),
52 (0x028 => key2: WriteOnly<u32, Key::Register>),
53 (0x02C => key3: WriteOnly<u32, Key::Register>),
54 (0x030 => key4: WriteOnly<u32, Key::Register>),
55 (0x034 => key5: WriteOnly<u32, Key::Register>),
56 (0x038 => key6: WriteOnly<u32, Key::Register>),
57 (0x03C => key7: WriteOnly<u32, Key::Register>),
58 (0x040 => initvect0: WriteOnly<u32, InitVector::Register>),
59 (0x044 => initvect1: WriteOnly<u32, InitVector::Register>),
60 (0x048 => initvect2: WriteOnly<u32, InitVector::Register>),
61 (0x04C => initvect3: WriteOnly<u32, InitVector::Register>),
62 (0x050 => idata: WriteOnly<u32, Data::Register>),
63 (0x054 => _reserved1: [u32; 3]),
64 (0x060 => odata: ReadOnly<u32, Data::Register>),
65 (0x064 => _reserved2: [u32; 3]),
66 (0x070 => drngseed: WriteOnly<u32, DrngSeed::Register>),
67 (0x074 => parameter: ReadOnly<u32, Parameter::Register>),
68 (0x078 => version: ReadOnly<u32, Version::Register>),
69 (0x07C => @END),
70 }
71}
72
73register_bitfields![u32,
74 Control [
75 ENABLE 0,
76 DKEYGEN 1,
77 NEWMSG 2,
78 SWSRT 8
79 ],
80 Mode [
81 CTYPE4 OFFSET(19) NUMBITS(1) [],
82 CTYPE3 OFFSET(18) NUMBITS(1) [],
83 CTYPE2 OFFSET(17) NUMBITS(1) [],
84 CTYPE1 OFFSET(16) NUMBITS(1) [],
85 CFBS OFFSET(8) NUMBITS(3) [
86 Bits128 = 0,
87 Bits64 = 1,
88 Bits32 = 2,
89 Bits16 = 3,
90 Bits8 = 4
91 ],
92 OPMODE OFFSET(4) NUMBITS(3) [
93 ECB = 0,
94 CBC = 1,
95 CFB = 2,
96 OFB = 3,
97 CTR = 4
98 ],
99 DMA OFFSET(3) NUMBITS(1) [],
100 ENCRYPT OFFSET(0) NUMBITS(1) []
101 ],
102 DataBuf [
103 ODATAW OFFSET(4) NUMBITS(2) [],
104 IDATAW OFFSET(0) NUMBITS(2) []
105 ],
106 Status [
107 IBUFRDY 16,
108 ODATARDY 0
109 ],
110 Interrupt [
111 IBUFRDY 16,
112 ODATARDY 0
113 ],
114 Key [
115 KEY OFFSET(0) NUMBITS(32) []
116 ],
117 InitVector [
118 VECTOR OFFSET(0) NUMBITS(32) []
119 ],
120 Data [
121 DATA OFFSET(0) NUMBITS(32) []
122 ],
123 DrngSeed [
124 SEED OFFSET(0) NUMBITS(32) []
125 ],
126 Parameter [
127 CTRMEAS OFFSET(8) NUMBITS(1) [
128 Implemented = 0,
129 NotImplemented = 1
130 ],
131 OPMODE OFFSET(2) NUMBITS(3) [
132 ECB = 0,
133 ECB_CBC = 1,
134 ECB_CBC_CFB = 2,
135 ECB_CBC_CFB_OFB = 3,
136 ECB_CBC_CFB_OFB_CTR = 4
137 ],
138 MAXKEYSIZE OFFSET(0) NUMBITS(2) [
139 Bits128 = 0,
140 Bits192 = 1,
141 Bits256 = 2
142 ]
143 ],
144 Version [
145 VARIANT OFFSET(16) NUMBITS(4),
146 VERSION OFFSET(0) NUMBITS(12)
147 ]
148];
149
150const AES_BASE: StaticRef<AesRegisters> =
152 unsafe { StaticRef::new(0x400B0000 as *const AesRegisters) };
153
154pub struct Aes<'a> {
155 registers: StaticRef<AesRegisters>,
156
157 client: OptionalCell<&'a dyn hil::symmetric_encryption::Client<'a>>,
158 source: TakeCell<'static, [u8]>,
159 dest: TakeCell<'static, [u8]>,
160
161 write_index: Cell<usize>,
164
165 read_index: Cell<usize>,
167
168 stop_index: Cell<usize>,
170}
171
172impl<'a> Aes<'a> {
173 pub fn new() -> Aes<'a> {
174 Aes {
175 registers: AES_BASE,
176 client: OptionalCell::empty(),
177 source: TakeCell::empty(),
178 dest: TakeCell::empty(),
179 write_index: Cell::new(0),
180 read_index: Cell::new(0),
181 stop_index: Cell::new(0),
182 }
183 }
184
185 fn enable_clock(&self) {
186 pm::enable_clock(pm::Clock::HSB(pm::HSBClock::AESA));
187 scif::generic_clock_enable_divided(
188 scif::GenericClock::GCLK4,
189 scif::ClockSource::CLK_CPU,
190 1,
191 );
192 scif::generic_clock_enable(scif::GenericClock::GCLK4, scif::ClockSource::CLK_CPU);
193 }
194
195 fn disable_clock(&self) {
196 scif::generic_clock_disable(scif::GenericClock::GCLK4);
197 pm::disable_clock(pm::Clock::HSB(pm::HSBClock::AESA));
198 }
199
200 fn enable_interrupts(&self) {
201 self.registers
202 .ier
203 .write(Interrupt::IBUFRDY.val(1) + Interrupt::ODATARDY.val(1));
204 }
205
206 fn disable_interrupts(&self) {
207 self.registers
208 .idr
209 .write(Interrupt::IBUFRDY.val(1) + Interrupt::ODATARDY.val(1));
210 }
211
212 fn disable_input_interrupt(&self) {
213 self.registers.idr.write(Interrupt::IBUFRDY.val(1));
215 }
216
217 fn busy(&self) -> bool {
218 (self.registers.imr.read(Interrupt::IBUFRDY) | self.registers.imr.read(Interrupt::ODATARDY))
221 != 0
222 }
223
224 fn set_mode(&self, encrypting: bool, mode: ConfidentialityMode) {
225 let encrypt = u32::from(encrypting);
226 let dma = 0;
227 self.registers.mode.write(
228 Mode::ENCRYPT.val(encrypt)
229 + Mode::DMA.val(dma)
230 + Mode::OPMODE.val(mode as u32)
231 + Mode::CTYPE4.val(1)
232 + Mode::CTYPE3.val(1)
233 + Mode::CTYPE2.val(1)
234 + Mode::CTYPE1.val(1),
235 );
236 }
237
238 fn input_buffer_ready(&self) -> bool {
239 self.registers.sr.read(Status::IBUFRDY) != 0
240 }
241
242 fn output_data_ready(&self) -> bool {
243 self.registers.sr.read(Status::ODATARDY) != 0
244 }
245
246 fn try_set_indices(&self, start_index: usize, stop_index: usize) -> bool {
247 stop_index.checked_sub(start_index).is_some_and(|sublen| {
248 sublen % AES_BLOCK_SIZE == 0 && {
249 self.source.map_or_else(
250 || {
251 if self.dest.map_or(false, |dest| stop_index <= dest.len()) {
253 self.write_index.set(start_index);
254 self.read_index.set(start_index);
255 self.stop_index.set(stop_index);
256 true
257 } else {
258 false
259 }
260 },
261 |source| {
262 if sublen == source.len()
263 && self.dest.map_or(false, |dest| stop_index <= dest.len())
264 {
265 self.write_index.set(0);
268
269 self.read_index.set(start_index);
272 self.stop_index.set(stop_index);
273 true
274 } else {
275 false
276 }
277 },
278 )
279 }
280 })
281 }
282
283 fn write_block(&self) -> bool {
287 self.source.map_or_else(
288 || {
289 self.dest.map_or_else(
291 || {
292 debug!("Called write_block() with no data");
293 false
294 },
295 |dest| {
296 let index = self.write_index.get();
297 let more = index + AES_BLOCK_SIZE <= self.stop_index.get();
298 if !more {
299 return false;
300 }
301 for i in 0..4 {
302 let mut v = dest[index + (i * 4) + 0] as usize;
303 v |= (dest[index + (i * 4) + 1] as usize) << 8;
304 v |= (dest[index + (i * 4) + 2] as usize) << 16;
305 v |= (dest[index + (i * 4) + 3] as usize) << 24;
306 self.registers.idata.set(v as u32);
307 }
308 self.write_index.set(index + AES_BLOCK_SIZE);
309
310 self.write_index.get() + AES_BLOCK_SIZE <= self.stop_index.get()
311 },
312 )
313 },
314 |source| {
315 let index = self.write_index.get();
316
317 let more = index + AES_BLOCK_SIZE <= source.len();
318 if !more {
319 return false;
320 }
321
322 for i in 0..4 {
323 let mut v = source[index + (i * 4) + 0] as usize;
324 v |= (source[index + (i * 4) + 1] as usize) << 8;
325 v |= (source[index + (i * 4) + 2] as usize) << 16;
326 v |= (source[index + (i * 4) + 3] as usize) << 24;
327 self.registers.idata.set(v as u32);
328 }
329
330 self.write_index.set(index + AES_BLOCK_SIZE);
331
332 self.write_index.get() + AES_BLOCK_SIZE <= source.len()
333 },
334 )
335 }
336
337 fn read_block(&self) -> bool {
341 self.dest.map_or_else(
342 || {
343 debug!("Called read_block() with no data");
344 false
345 },
346 |dest| {
347 let index = self.read_index.get();
348 let more = index + AES_BLOCK_SIZE <= self.stop_index.get();
349 if !more {
350 return false;
351 }
352
353 for i in 0..4 {
354 let v = self.registers.odata.get();
355 dest[index + (i * 4) + 0] = (v >> 0) as u8;
356 dest[index + (i * 4) + 1] = (v >> 8) as u8;
357 dest[index + (i * 4) + 2] = (v >> 16) as u8;
358 dest[index + (i * 4) + 3] = (v >> 24) as u8;
359 }
360
361 self.read_index.set(index + AES_BLOCK_SIZE);
362
363 self.read_index.get() + AES_BLOCK_SIZE <= self.stop_index.get()
364 },
365 )
366 }
367
368 pub fn handle_interrupt(&self) {
372 if !self.busy() {
373 return;
376 }
377
378 if self.input_buffer_ready() {
379 if !self.write_block() {
382 self.disable_input_interrupt();
385 }
386 }
387
388 if self.output_data_ready() {
389 if !self.read_block() {
392 self.disable_interrupts();
395
396 self.client.map(|client| {
398 client.crypt_done(self.source.take(), self.dest.take().unwrap());
399 });
400 }
401 }
402 }
403}
404
405impl<'a> hil::symmetric_encryption::AES<'a, AES128> for Aes<'a> {
406 fn enable(&self) {
407 self.enable_clock();
408 self.registers.ctrl.write(Control::ENABLE.val(1));
409 }
410
411 fn disable(&self) {
412 self.registers.ctrl.set(0);
413 self.disable_clock();
414 }
415
416 fn set_client(&'a self, client: &'a dyn hil::symmetric_encryption::Client<'a>) {
417 self.client.set(client);
418 }
419
420 fn set_key(&self, key: &[u8]) -> Result<(), ErrorCode> {
421 if key.len() != AES128_KEY_SIZE {
422 return Err(ErrorCode::INVAL);
423 }
424
425 for i in 0..4 {
426 let mut k = key[i * 4 + 0] as usize;
427 k |= (key[i * 4 + 1] as usize) << 8;
428 k |= (key[i * 4 + 2] as usize) << 16;
429 k |= (key[i * 4 + 3] as usize) << 24;
430 match i {
431 0 => self.registers.key0.set(k as u32),
432 1 => self.registers.key1.set(k as u32),
433 2 => self.registers.key2.set(k as u32),
434 3 => self.registers.key3.set(k as u32),
435 _ => {}
436 }
437 }
438
439 Ok(())
440 }
441
442 fn set_iv(&self, iv: &[u8]) -> Result<(), ErrorCode> {
443 if iv.len() != AES_BLOCK_SIZE {
444 return Err(ErrorCode::INVAL);
445 }
446
447 for i in 0..4 {
449 let mut c = iv[i * 4 + 0] as usize;
450 c |= (iv[i * 4 + 1] as usize) << 8;
451 c |= (iv[i * 4 + 2] as usize) << 16;
452 c |= (iv[i * 4 + 3] as usize) << 24;
453 match i {
454 0 => self.registers.initvect0.set(c as u32),
455 1 => self.registers.initvect1.set(c as u32),
456 2 => self.registers.initvect2.set(c as u32),
457 3 => self.registers.initvect3.set(c as u32),
458 _ => {}
459 }
460 }
461
462 Ok(())
463 }
464
465 fn start_message(&self) {
466 if self.busy() {
467 return;
468 }
469 self.registers
470 .ctrl
471 .write(Control::NEWMSG.val(1) + Control::ENABLE.val(1));
472 }
473
474 fn crypt(
475 &self,
476 source: Option<&'static mut [u8]>,
477 dest: &'static mut [u8],
478 start_index: usize,
479 stop_index: usize,
480 ) -> Option<(
481 Result<(), ErrorCode>,
482 Option<&'static mut [u8]>,
483 &'static mut [u8],
484 )> {
485 if self.busy() {
486 Some((Err(ErrorCode::BUSY), source, dest))
487 } else {
488 self.source.put(source);
489 self.dest.replace(dest);
490 if self.try_set_indices(start_index, stop_index) {
491 self.enable_interrupts();
492 None
493 } else {
494 Some((
495 Err(ErrorCode::INVAL),
496 self.source.take(),
497 self.dest.take().unwrap(),
498 ))
499 }
500 }
501 }
502}
503
504impl hil::symmetric_encryption::AESCtr for Aes<'_> {
505 fn set_mode_aesctr(&self, encrypting: bool) -> Result<(), ErrorCode> {
506 self.set_mode(encrypting, ConfidentialityMode::CTR);
507 Ok(())
508 }
509}
510
511impl hil::symmetric_encryption::AESCBC for Aes<'_> {
512 fn set_mode_aescbc(&self, encrypting: bool) -> Result<(), ErrorCode> {
513 self.set_mode(encrypting, ConfidentialityMode::CBC);
514 Ok(())
515 }
516}
517
518impl kernel::hil::symmetric_encryption::AESECB for Aes<'_> {
519 fn set_mode_aesecb(&self, encrypting: bool) -> Result<(), ErrorCode> {
520 self.set_mode(encrypting, ConfidentialityMode::ECB);
521 Ok(())
522 }
523}