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 let more =
307 self.write_index.get() + AES128_BLOCK_SIZE <= self.stop_index.get();
308 more
309 },
310 )
311 },
312 |source| {
313 let index = self.write_index.get();
314
315 let more = index + AES128_BLOCK_SIZE <= source.len();
316 if !more {
317 return false;
318 }
319
320 for i in 0..4 {
321 let mut v = source[index + (i * 4) + 0] as usize;
322 v |= (source[index + (i * 4) + 1] as usize) << 8;
323 v |= (source[index + (i * 4) + 2] as usize) << 16;
324 v |= (source[index + (i * 4) + 3] as usize) << 24;
325 self.registers.idata.set(v as u32);
326 }
327
328 self.write_index.set(index + AES128_BLOCK_SIZE);
329
330 let more = self.write_index.get() + AES128_BLOCK_SIZE <= source.len();
331 more
332 },
333 )
334 }
335
336 fn read_block(&self) -> bool {
340 self.dest.map_or_else(
341 || {
342 debug!("Called read_block() with no data");
343 false
344 },
345 |dest| {
346 let index = self.read_index.get();
347 let more = index + AES128_BLOCK_SIZE <= self.stop_index.get();
348 if !more {
349 return false;
350 }
351
352 for i in 0..4 {
353 let v = self.registers.odata.get();
354 dest[index + (i * 4) + 0] = (v >> 0) as u8;
355 dest[index + (i * 4) + 1] = (v >> 8) as u8;
356 dest[index + (i * 4) + 2] = (v >> 16) as u8;
357 dest[index + (i * 4) + 3] = (v >> 24) as u8;
358 }
359
360 self.read_index.set(index + AES128_BLOCK_SIZE);
361
362 let more = self.read_index.get() + AES128_BLOCK_SIZE <= self.stop_index.get();
363 more
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::AES128<'a> 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() != AES128_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::AES128Ctr for Aes<'_> {
505 fn set_mode_aes128ctr(&self, encrypting: bool) -> Result<(), ErrorCode> {
506 self.set_mode(encrypting, ConfidentialityMode::CTR);
507 Ok(())
508 }
509}
510
511impl hil::symmetric_encryption::AES128CBC for Aes<'_> {
512 fn set_mode_aes128cbc(&self, encrypting: bool) -> Result<(), ErrorCode> {
513 self.set_mode(encrypting, ConfidentialityMode::CBC);
514 Ok(())
515 }
516}
517
518impl kernel::hil::symmetric_encryption::AES128ECB for Aes<'_> {
519 fn set_mode_aes128ecb(&self, encrypting: bool) -> Result<(), ErrorCode> {
520 self.set_mode(encrypting, ConfidentialityMode::ECB);
521 Ok(())
522 }
523}