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