1use capsules_core::test::capsule_test::{CapsuleTest, CapsuleTestClient};
8use core::cell::Cell;
9use kernel::debug;
10use kernel::hil;
11use kernel::hil::symmetric_encryption::{
12 AES128Ctr, AES128, AES128CBC, AES128ECB, AES128_BLOCK_SIZE, AES128_KEY_SIZE,
13};
14use kernel::utilities::cells::OptionalCell;
15use kernel::utilities::cells::TakeCell;
16
17pub struct TestAes128Ctr<'a, A: 'a> {
18 aes: &'a A,
19
20 key: TakeCell<'a, [u8]>,
21 iv: TakeCell<'a, [u8]>,
22 source: TakeCell<'static, [u8]>,
23 data: TakeCell<'static, [u8]>,
24 test_decrypt: bool,
25
26 encrypting: Cell<bool>,
27 use_source: Cell<bool>,
28
29 client: OptionalCell<&'static dyn CapsuleTestClient>,
30}
31
32pub struct TestAes128Cbc<'a, A: 'a> {
33 aes: &'a A,
34
35 key: TakeCell<'a, [u8]>,
36 iv: TakeCell<'a, [u8]>,
37 source: TakeCell<'static, [u8]>,
38 data: TakeCell<'static, [u8]>,
39 test_decrypt: bool,
40
41 encrypting: Cell<bool>,
42 use_source: Cell<bool>,
43
44 client: OptionalCell<&'static dyn CapsuleTestClient>,
45}
46
47pub struct TestAes128Ecb<'a, A: 'a> {
48 aes: &'a A,
49
50 key: TakeCell<'a, [u8]>,
51 source: TakeCell<'static, [u8]>,
52 data: TakeCell<'static, [u8]>,
53 test_decrypt: bool,
54
55 encrypting: Cell<bool>,
56 use_source: Cell<bool>,
57
58 client: OptionalCell<&'static dyn CapsuleTestClient>,
59}
60
61const DATA_OFFSET: usize = AES128_BLOCK_SIZE;
62const DATA_LEN: usize = 4 * AES128_BLOCK_SIZE;
63
64impl<'a, A: AES128<'a> + AES128ECB> TestAes128Ecb<'a, A> {
65 pub fn new(
66 aes: &'a A,
67 key: &'a mut [u8],
68 source: &'static mut [u8],
69 data: &'static mut [u8],
70 test_decrypt: bool,
71 ) -> Self {
72 TestAes128Ecb {
73 aes,
74
75 key: TakeCell::new(key),
76 source: TakeCell::new(source),
77 data: TakeCell::new(data),
78 test_decrypt,
79
80 encrypting: Cell::new(true),
81 use_source: Cell::new(true),
82
83 client: OptionalCell::empty(),
84 }
85 }
86
87 pub fn run(&self) {
88 self.aes.enable();
89
90 self.aes.set_mode_aes128ecb(self.encrypting.get()).unwrap();
91
92 self.key.map(|key| {
94 for (i, b) in KEY.iter().enumerate() {
95 key[i] = *b;
96 }
97
98 assert!(self.aes.set_key(key) == Ok(()));
99 });
100
101 let source_mode = if self.encrypting.get() {
103 &PTXT
104 } else {
105 &CTXT_ECB
106 };
107 self.source.map(|source| {
108 for (i, b) in source_mode.iter().enumerate() {
109 source[i] = *b;
110 }
111 });
112
113 if !self.use_source.get() {
114 self.source.map_or_else(
116 || panic!("No source"),
117 |source| {
118 self.data.map_or_else(
119 || panic!("No data"),
120 |data| {
121 for (i, b) in source.iter().enumerate() {
122 data[DATA_OFFSET + i] = *b;
123 }
124 },
125 );
126 },
127 );
128 }
129
130 self.aes.start_message();
131
132 let start = DATA_OFFSET;
133 let stop = DATA_OFFSET + DATA_LEN;
134
135 match self.aes.crypt(
136 if self.use_source.get() {
137 self.source.take()
138 } else {
139 None
140 },
141 self.data.take().unwrap(),
142 start,
143 stop,
144 ) {
145 None => {
146 }
148 Some((result, source, dest)) => {
149 self.source.put(source);
150 self.data.put(Some(dest));
151 panic!("crypt() failed: {:?}", result);
152 }
153 }
154 }
155}
156
157impl<'a, A: AES128<'a> + AES128ECB> CapsuleTest for TestAes128Ecb<'a, A> {
158 fn set_client(&self, client: &'static dyn CapsuleTestClient) {
159 self.client.set(client);
160 }
161}
162
163impl<'a, A: AES128<'a> + AES128Ctr> TestAes128Ctr<'a, A> {
164 pub fn new(
165 aes: &'a A,
166 key: &'a mut [u8],
167 iv: &'a mut [u8],
168 source: &'static mut [u8],
169 data: &'static mut [u8],
170 test_decrypt: bool,
171 ) -> Self {
172 TestAes128Ctr {
173 aes,
174
175 key: TakeCell::new(key),
176 iv: TakeCell::new(iv),
177 source: TakeCell::new(source),
178 data: TakeCell::new(data),
179 test_decrypt,
180
181 encrypting: Cell::new(true),
182 use_source: Cell::new(true),
183
184 client: OptionalCell::empty(),
185 }
186 }
187
188 pub fn run(&self) {
189 self.aes.enable();
190
191 self.aes.set_mode_aes128ctr(self.encrypting.get()).unwrap();
192
193 self.key.map(|key| {
195 for (i, b) in KEY.iter().enumerate() {
196 key[i] = *b;
197 }
198
199 assert!(self.aes.set_key(key) == Ok(()));
200 });
201
202 self.iv.map(|iv| {
204 let iv_mode = &IV_CTR;
205 for (i, b) in iv_mode.iter().enumerate() {
206 iv[i] = *b;
207 }
208
209 assert!(self.aes.set_iv(iv) == Ok(()));
210 });
211
212 let source_mode = if self.encrypting.get() {
214 &PTXT
215 } else {
216 &CTXT_CTR
217 };
218 self.source.map(|source| {
219 for (i, b) in source_mode.iter().enumerate() {
220 source[i] = *b;
221 }
222 });
223
224 if !self.use_source.get() {
225 self.source.map_or_else(
227 || panic!("No source"),
228 |source| {
229 self.data.map_or_else(
230 || panic!("No data"),
231 |data| {
232 for (i, b) in source.iter().enumerate() {
233 data[DATA_OFFSET + i] = *b;
234 }
235 },
236 );
237 },
238 );
239 }
240
241 self.aes.start_message();
242
243 let start = DATA_OFFSET;
244 let stop = DATA_OFFSET + DATA_LEN;
245
246 match self.aes.crypt(
247 if self.use_source.get() {
248 self.source.take()
249 } else {
250 None
251 },
252 self.data.take().unwrap(),
253 start,
254 stop,
255 ) {
256 None => {
257 }
259 Some((result, source, dest)) => {
260 self.source.put(source);
261 self.data.put(Some(dest));
262 panic!("crypt() failed: {:?}", result);
263 }
264 }
265 }
266}
267
268impl<'a, A: AES128<'a> + AES128Ctr> hil::symmetric_encryption::Client<'a> for TestAes128Ctr<'a, A> {
269 fn crypt_done(&'a self, source: Option<&'static mut [u8]>, dest: &'static mut [u8]) {
270 if self.use_source.get() {
271 self.source.put(source);
273 }
274
275 self.data.replace(dest);
277
278 let expected = if self.encrypting.get() {
279 &CTXT_CTR
280 } else {
281 &PTXT
282 };
283
284 if self.data.map_or(false, |data| {
285 &data[DATA_OFFSET..DATA_OFFSET + DATA_LEN] == expected.as_ref()
286 }) {
287 debug!(
288 "aes_test CTR passed: (CTR {} {} {})",
289 if self.encrypting.get() { "Enc" } else { "Dec" },
290 "Ctr",
291 if self.use_source.get() {
292 "Src/Dst"
293 } else {
294 "In-place"
295 }
296 );
297 } else {
298 panic!(
299 "aes_test failed: (CTR {} {} {})",
300 if self.encrypting.get() { "Enc" } else { "Dec" },
301 "Ctr",
302 if self.use_source.get() {
303 "Src/Dst"
304 } else {
305 "In-place"
306 }
307 );
308 }
309 self.aes.disable();
310
311 if self.use_source.get() {
313 self.use_source.set(false);
314 self.run();
315 } else {
316 if self.encrypting.get() && self.test_decrypt {
317 self.encrypting.set(false);
318 self.use_source.set(true);
319 self.run();
320 } else {
321 self.client.map(|client| {
322 client.done(Ok(()));
323 });
324 }
325 }
326 }
327}
328
329impl<'a, A: AES128<'a> + AES128Ctr> CapsuleTest for TestAes128Ctr<'a, A> {
330 fn set_client(&self, client: &'static dyn CapsuleTestClient) {
331 self.client.set(client);
332 }
333}
334
335impl<'a, A: AES128<'a> + AES128CBC> TestAes128Cbc<'a, A> {
336 pub fn new(
337 aes: &'a A,
338 key: &'a mut [u8],
339 iv: &'a mut [u8],
340 source: &'static mut [u8],
341 data: &'static mut [u8],
342 test_decrypt: bool,
343 ) -> Self {
344 TestAes128Cbc {
345 aes,
346
347 key: TakeCell::new(key),
348 iv: TakeCell::new(iv),
349 source: TakeCell::new(source),
350 data: TakeCell::new(data),
351 test_decrypt,
352
353 encrypting: Cell::new(true),
354 use_source: Cell::new(true),
355
356 client: OptionalCell::empty(),
357 }
358 }
359
360 pub fn run(&self) {
361 self.aes.enable();
362
363 self.aes.set_mode_aes128cbc(self.encrypting.get()).unwrap();
364
365 self.key.map(|key| {
367 for (i, b) in KEY.iter().enumerate() {
368 key[i] = *b;
369 }
370
371 assert!(self.aes.set_key(key) == Ok(()));
372 });
373
374 self.iv.map(|iv| {
376 let iv_mode = &IV_CBC;
377
378 for (i, b) in iv_mode.iter().enumerate() {
379 iv[i] = *b;
380 }
381
382 assert!(self.aes.set_iv(iv) == Ok(()));
383 });
384
385 let source_mode = if self.encrypting.get() {
387 &PTXT
388 } else {
389 &CTXT_CBC
390 };
391 self.source.map(|source| {
392 for (i, b) in source_mode.iter().enumerate() {
393 source[i] = *b;
394 }
395 });
396
397 if !self.use_source.get() {
398 self.source.map_or_else(
400 || panic!("aes_test: no source"),
401 |source| {
402 self.data.map_or_else(
403 || panic!("aes_test: no data"),
404 |data| {
405 for (i, b) in source.iter().enumerate() {
406 data[DATA_OFFSET + i] = *b;
407 }
408 },
409 );
410 },
411 );
412 }
413
414 self.aes.start_message();
415
416 let start = DATA_OFFSET;
417 let stop = DATA_OFFSET + DATA_LEN;
418
419 match self.aes.crypt(
420 if self.use_source.get() {
421 self.source.take()
422 } else {
423 None
424 },
425 self.data.take().unwrap(),
426 start,
427 stop,
428 ) {
429 None => {
430 }
432 Some((result, source, dest)) => {
433 self.source.put(source);
434 self.data.put(Some(dest));
435 panic!("crypt() failed: {:?}", result);
436 }
437 }
438 }
439}
440
441impl<'a, A: AES128<'a> + AES128CBC> hil::symmetric_encryption::Client<'a> for TestAes128Cbc<'a, A> {
442 fn crypt_done(&'a self, source: Option<&'static mut [u8]>, dest: &'static mut [u8]) {
443 if self.use_source.get() {
444 self.source.put(source);
446 }
447
448 self.data.replace(dest);
450
451 let expected = if self.encrypting.get() {
452 &CTXT_CBC
453 } else {
454 &PTXT
455 };
456
457 if self.data.map_or(false, |data| {
458 &data[DATA_OFFSET..DATA_OFFSET + DATA_LEN] == expected.as_ref()
459 }) {
460 debug!(
461 "aes_test passed (CBC {} {})",
462 if self.encrypting.get() { "Enc" } else { "Dec" },
463 if self.use_source.get() {
464 "Src/Dst"
465 } else {
466 "In-place"
467 }
468 );
469 } else {
470 panic!(
471 "aes_test failed: (CBC {} {})",
472 if self.encrypting.get() { "Enc" } else { "Dec" },
473 if self.use_source.get() {
474 "Src/Dst"
475 } else {
476 "In-place"
477 }
478 );
479 }
480 self.aes.disable();
481
482 if self.use_source.get() {
484 self.use_source.set(false);
485 self.run();
486 } else {
487 if self.encrypting.get() && self.test_decrypt {
488 self.encrypting.set(false);
489 self.use_source.set(true);
490 self.run();
491 } else {
492 self.client.map(|client| {
493 client.done(Ok(()));
494 });
495 }
496 }
497 }
498}
499
500impl<'a, A: AES128<'a> + AES128CBC> CapsuleTest for TestAes128Cbc<'a, A> {
501 fn set_client(&self, client: &'static dyn CapsuleTestClient) {
502 self.client.set(client);
503 }
504}
505
506impl<'a, A: AES128<'a> + AES128ECB> hil::symmetric_encryption::Client<'a> for TestAes128Ecb<'a, A> {
507 fn crypt_done(&'a self, source: Option<&'static mut [u8]>, dest: &'static mut [u8]) {
508 if self.use_source.get() {
509 self.source.put(source);
511 }
512
513 self.data.replace(dest);
515
516 let expected = if self.encrypting.get() {
517 &CTXT_ECB
518 } else {
519 &PTXT
520 };
521
522 if self.data.map_or(false, |data| {
523 &data[DATA_OFFSET..DATA_OFFSET + DATA_LEN] == expected.as_ref()
524 }) {
525 debug!(
526 "aes_test passed (ECB {} {})",
527 if self.encrypting.get() { "Enc" } else { "Dec" },
528 if self.use_source.get() {
529 "Src/Dst"
530 } else {
531 "In-place"
532 }
533 );
534 } else {
535 panic!(
536 "aes_test failed: (ECB {} {})",
537 if self.encrypting.get() { "Enc" } else { "Dec" },
538 if self.use_source.get() {
539 "Src/Dst"
540 } else {
541 "In-place"
542 }
543 );
544 }
545 self.aes.disable();
546
547 if self.use_source.get() {
549 self.use_source.set(false);
550 self.run();
551 } else {
552 if self.encrypting.get() && self.test_decrypt {
553 self.encrypting.set(false);
554 self.use_source.set(true);
555 self.run();
556 } else {
557 self.client.map(|client| {
558 client.done(Ok(()));
559 });
560 }
561 }
562 }
563}
564
565#[rustfmt::skip]
566const KEY: [u8; AES128_KEY_SIZE] = [
567 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
568 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
569];
570
571#[rustfmt::skip]
572const IV_CTR: [u8; AES128_BLOCK_SIZE] = [
573 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
574 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
575];
576
577#[rustfmt::skip]
578const IV_CBC: [u8; AES128_BLOCK_SIZE] = [
579 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
580 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
581];
582
583#[rustfmt::skip]
584const PTXT: [u8; 4 * AES128_BLOCK_SIZE] = [
585 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
586 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
587 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
588 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
589 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
590 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
591 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
592 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
593];
594
595#[rustfmt::skip]
596const CTXT_CTR: [u8; 4 * AES128_BLOCK_SIZE] = [
597 0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26,
598 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce,
599 0x98, 0x06, 0xf6, 0x6b, 0x79, 0x70, 0xfd, 0xff,
600 0x86, 0x17, 0x18, 0x7b, 0xb9, 0xff, 0xfd, 0xff,
601 0x5a, 0xe4, 0xdf, 0x3e, 0xdb, 0xd5, 0xd3, 0x5e,
602 0x5b, 0x4f, 0x09, 0x02, 0x0d, 0xb0, 0x3e, 0xab,
603 0x1e, 0x03, 0x1d, 0xda, 0x2f, 0xbe, 0x03, 0xd1,
604 0x79, 0x21, 0x70, 0xa0, 0xf3, 0x00, 0x9c, 0xee
605];
606
607#[rustfmt::skip]
608const CTXT_CBC: [u8; 4 * AES128_BLOCK_SIZE] = [
609 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46,
610 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,
611 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee,
612 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2,
613 0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b,
614 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16,
615 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09,
616 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7
617];
618
619#[rustfmt::skip]
620const CTXT_ECB: [u8; 4 * AES128_BLOCK_SIZE] = [
621 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
622 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
623 0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d,
624 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf,
625 0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23,
626 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88,
627 0x7b, 0x0c, 0x78, 0x5e, 0x27, 0xe8, 0xad, 0x3f,
628 0x82, 0x23, 0x20, 0x71, 0x04, 0x72, 0x5d, 0xd4
629];