1use core::cell::Cell;
24use kernel::ErrorCode;
25use kernel::debug;
26use kernel::hil::symmetric_encryption::{AES256, AES256_KEY_SIZE, AESCCM, CCMClient};
27use kernel::utilities::cells::TakeCell;
28
29const BUF_LEN: usize = 128;
30
31pub struct TestAES256Ccm<'a, A: AESCCM<'a, AES256>> {
32 aes_ccm: &'a A,
33 buf: TakeCell<'static, [u8]>,
34 current_test: Cell<usize>,
35 encrypting: Cell<bool>,
36}
37
38struct Vector {
39 key: &'static [u8],
40 nonce: &'static [u8],
41 a_data: &'static [u8],
42 m_data: &'static [u8],
43 c_data: &'static [u8], mic_len: usize,
45 confidential: bool,
46 expect_tag_invalid: bool,
47}
48
49impl<'a, A: AESCCM<'a, AES256>> TestAES256Ccm<'a, A> {
50 pub fn new(aes_ccm: &'a A, buf: &'static mut [u8]) -> Self {
51 assert!(buf.len() >= BUF_LEN, "buffer too small for CCM-256 tests");
52 TestAES256Ccm {
53 aes_ccm,
54 buf: TakeCell::new(buf),
55 current_test: Cell::new(0),
56 encrypting: Cell::new(true),
57 }
58 }
59
60 pub fn run(&self) {
61 debug!(
62 "AES-256-CCM test suite starting ({} vectors)",
63 VECTORS.len()
64 );
65 self.trigger();
66 }
67
68 fn vector(&self) -> &'static Vector {
69 &VECTORS[self.current_test.get()]
70 }
71
72 fn trigger(&self) {
73 let v = self.vector();
74 let encrypting = self.encrypting.get();
75 let a_off = 0;
76 let m_off = v.a_data.len();
77 let m_len = v.m_data.len();
78
79 let buf = self
80 .buf
81 .take()
82 .expect("aes256ccm_test: buffer missing in trigger");
83
84 buf[..BUF_LEN].fill(0);
85 buf[a_off..m_off].copy_from_slice(v.a_data);
86
87 if encrypting {
88 buf[m_off..m_off + m_len].copy_from_slice(v.m_data);
89 } else {
90 if v.expect_tag_invalid {
91 buf[m_off..m_off + m_len + v.mic_len]
93 .copy_from_slice(&v.c_data[0..v.mic_len + m_len]);
94 buf[m_off + m_len] ^= 0xFF;
95 } else {
96 buf[m_off..m_off + v.mic_len + m_len]
97 .copy_from_slice(&v.c_data[0..v.mic_len + m_len]);
98 }
99 }
100
101 match self.aes_ccm.set_key(v.key) {
102 Ok(()) => {}
103 Err(e) => {
104 panic!(
105 "aes256ccm_test vec={} enc={} returned {:?}: set_key failed",
106 self.current_test.get(),
107 encrypting,
108 e,
109 );
110 }
111 }
112 match self.aes_ccm.set_nonce(v.nonce) {
113 Ok(()) => {}
114 Err(e) => {
115 panic!(
116 "aes256ccm_test vec={} enc={} returned {:?}: set_nonce failed",
117 self.current_test.get(),
118 encrypting,
119 e,
120 );
121 }
122 }
123
124 self.aes_ccm
125 .crypt(
126 buf,
127 a_off,
128 m_off,
129 m_len,
130 v.mic_len,
131 v.confidential,
132 encrypting,
133 )
134 .unwrap_or_else(|(code, buf)| {
135 self.buf.replace(buf);
136 panic!(
137 "aes256ccm_test vec={} enc={}: crypt() returned {:?}",
138 self.current_test.get(),
139 encrypting,
140 code
141 );
142 });
143 }
144
145 fn check_test(&self, tag_is_valid: bool) {
146 let v = self.vector();
147 let encrypting = self.encrypting.get();
148 let test_idx = self.current_test.get();
149 let a_off = 0;
150 let m_off = v.a_data.len();
151 let m_len = v.m_data.len();
152 let tag_len = v.mic_len;
153
154 let buf = self
155 .buf
156 .take()
157 .expect("aes256ccm_test: buffer missing in check_test");
158
159 let a_ok = &buf[a_off..m_off] == v.a_data;
161
162 if encrypting {
163 let c_ok = buf[m_off..m_off + m_len] == v.c_data[0..m_len];
165
166 let expected_tag = &v.c_data[m_len..m_len + tag_len];
168 let actual_tag = &buf[m_off + m_len..m_off + m_len + tag_len];
169 let tag_match = expected_tag == actual_tag;
170
171 if !a_ok || !c_ok || !tag_match || !tag_is_valid {
172 panic!(
173 "aes256ccm_test FAILED vec={} enc=true: \
174 a_ok={} c_ok={} tag_match={} tag_is_valid={}",
175 test_idx, a_ok, c_ok, tag_match, tag_is_valid
176 );
177 }
178 } else {
179 if v.expect_tag_invalid {
180 if tag_is_valid {
181 panic!(
182 "aes256ccm_test FAILED vec={} enc=false: \
183 expected tag_is_valid=false for corrupted MIC, got true",
184 test_idx
185 );
186 }
187 debug!(
188 "aes256ccm_test passed vec={} enc=false (corrupted MIC correctly rejected)",
189 test_idx
190 );
191 self.buf.replace(buf);
192 return;
193 }
194
195 let m_ok = &buf[m_off..m_off + m_len] == v.m_data;
196 if !a_ok || !m_ok || !tag_is_valid {
197 panic!(
198 "aes256ccm_test FAILED vec={} enc=false: \
199 a_ok={} m_ok={} tag_is_valid={}",
200 test_idx, a_ok, m_ok, tag_is_valid
201 );
202 }
203 }
204
205 debug!("aes256ccm_test passed vec={} enc={}", test_idx, encrypting);
206 self.buf.replace(buf);
207 }
208
209 fn advance(&self) -> bool {
210 if self.encrypting.get() {
211 self.encrypting.set(false);
212 true
213 } else {
214 self.encrypting.set(true);
215 let next = self.current_test.get() + 1;
216 self.current_test.set(next);
217 next < VECTORS.len()
218 }
219 }
220}
221
222impl<'a, A: AESCCM<'a, AES256>> CCMClient for TestAES256Ccm<'a, A> {
223 fn crypt_done(&self, buf: &'static mut [u8], res: Result<(), ErrorCode>, tag_is_valid: bool) {
224 self.buf.replace(buf);
225 if res != Ok(()) {
226 panic!(
227 "aes256ccm_test vec={} enc={}: crypt_done error {:?}",
228 self.current_test.get(),
229 self.encrypting.get(),
230 res
231 );
232 }
233 self.check_test(tag_is_valid);
234 if self.advance() {
235 self.trigger();
236 } else {
237 debug!("AES-256-CCM all tests passed");
238 }
239 }
240}
241
242static VECTORS: &[Vector] = &[
247 Vector {
248 key: &KEY_0,
249 nonce: &NONCE_0,
250 a_data: &A_DATA_0,
251 m_data: &[],
252 c_data: &MIC_0,
253 mic_len: 16,
254 confidential: false,
255 expect_tag_invalid: false,
256 },
257 Vector {
258 key: &KEY_1,
259 nonce: &NONCE_1,
260 a_data: &A_DATA_1,
261 m_data: &M_DATA_1,
262 c_data: &C_DATA_1,
263 mic_len: 16,
264 confidential: true,
265 expect_tag_invalid: false,
266 },
267 Vector {
268 key: &KEY_2,
269 nonce: &NONCE_2,
270 a_data: &A_DATA_2,
271 m_data: &M_DATA_2,
272 c_data: &C_DATA_2,
273 mic_len: 16,
274 confidential: true,
275 expect_tag_invalid: false,
276 },
277 Vector {
278 key: &KEY_3,
279 nonce: &NONCE_3,
280 a_data: &A_DATA_3,
281 m_data: &M_DATA_3,
282 c_data: &C_DATA_3,
283 mic_len: 16,
284 confidential: true,
285 expect_tag_invalid: false,
286 },
287 Vector {
288 key: &KEY_4,
289 nonce: &NONCE_4,
290 a_data: &A_DATA_4,
291 m_data: &M_DATA_4,
292 c_data: &C_DATA_4,
293 mic_len: 16,
294 confidential: true,
295 expect_tag_invalid: false,
296 },
297 Vector {
298 key: &KEY_5,
299 nonce: &NONCE_5,
300 a_data: &A_DATA_5,
301 m_data: &M_DATA_5,
302 c_data: &C_DATA_5,
303 mic_len: 16,
304 confidential: true,
305 expect_tag_invalid: true,
306 },
307 Vector {
308 key: &KEY_6,
309 nonce: &NONCE_6,
310 a_data: &A_DATA_6,
311 m_data: &M_DATA_6,
312 c_data: &C_DATA_6,
313 mic_len: 14,
314 confidential: true,
315 expect_tag_invalid: false,
316 },
317];
318
319#[rustfmt::skip]
323static KEY_0: [u8; AES256_KEY_SIZE] = [
324 0xa4, 0xbc, 0x10, 0xb1, 0xa6, 0x2c, 0x96, 0xd4,
325 0x59, 0xfb, 0xaf, 0x3a, 0x5a, 0xa3, 0xfa, 0xce,
326 0x73, 0x13, 0xbb, 0x9e, 0x12, 0x53, 0xe6, 0x96,
327 0xf9, 0x6a, 0x7a, 0x8e, 0x36, 0x80, 0x10, 0x88,
328];
329#[rustfmt::skip]
330static NONCE_0: [u8; 7] = [
331 0xa5, 0x44, 0x21, 0x8d, 0xad, 0xd3, 0xc1,
332];
333#[rustfmt::skip]
334static A_DATA_0: [u8; 32] = [
335 0xd3, 0xd5, 0x42, 0x4e, 0x20, 0xfb, 0xec, 0x43,
336 0xae, 0x49, 0x53, 0x53, 0xed, 0x83, 0x02, 0x71,
337 0x51, 0x5a, 0xb1, 0x04, 0xf8, 0x86, 0x0c, 0x98,
338 0x8d, 0x15, 0xb6, 0xd3, 0x6c, 0x03, 0x8e, 0xab,
339];
340#[rustfmt::skip]
341static MIC_0: [u8; 16] = [
342 0x93, 0xaf, 0x11, 0xa0, 0x83, 0x79, 0xeb, 0x37,
343 0xa1, 0x6a, 0xa2, 0x83, 0x7f, 0x09, 0xd6, 0x9d,
344];
345
346#[rustfmt::skip]
350static KEY_1: [u8; AES256_KEY_SIZE] = [
351 0x52, 0x09, 0x02, 0xaa, 0x27, 0xc1, 0x6d, 0xee,
352 0x11, 0x28, 0x12, 0xb2, 0xe6, 0x85, 0xaa, 0x20,
353 0x3a, 0xeb, 0x8b, 0x86, 0x33, 0xbd, 0x1b, 0xfc,
354 0x99, 0x72, 0x8a, 0x48, 0x2d, 0x96, 0xc1, 0xfe,
355];
356#[rustfmt::skip]
357static NONCE_1: [u8; 13] = [
358 0xdd, 0xf5, 0x05, 0x02, 0xf4, 0x14, 0xc1, 0xbf,
359 0x24, 0x88, 0x8f, 0x13, 0x28,
360];
361#[rustfmt::skip]
362static A_DATA_1: [u8; 15] = [
363 0x22, 0xb4, 0xf8, 0xf1, 0xaa, 0xc0, 0x2a, 0x9b,
364 0x2e, 0xf7, 0x85, 0xd0, 0xff, 0x6f, 0x93,
365];
366#[rustfmt::skip]
367static M_DATA_1: [u8; 24] = [
368 0x53, 0x3f, 0xee, 0x7d, 0x2c, 0x77, 0x40, 0xdb,
369 0x55, 0x77, 0x0e, 0x48, 0xcb, 0x1b, 0x54, 0x1d,
370 0x99, 0x0e, 0xa3, 0xf8, 0xf0, 0x8e, 0xd1, 0xa6,
371];
372#[rustfmt::skip]
373static C_DATA_1: [u8; 40] = [
374 0xfc, 0x86, 0x7b, 0x31, 0x9e, 0x0e, 0x4a, 0xb4,
375 0x5e, 0xc5, 0x18, 0xa1, 0xb5, 0xdc, 0xec, 0x4f,
376 0x29, 0x98, 0x21, 0x73, 0xf3, 0xab, 0xfd, 0x4d,
377 0x8a, 0x8f, 0x8d, 0x14, 0xd2, 0xbd, 0xac, 0x84,
378 0xc3, 0x73, 0x7c, 0xfb, 0xd7, 0x5b, 0x7c, 0x0b,
379];
380
381#[rustfmt::skip]
385static KEY_2: [u8; AES256_KEY_SIZE] = [
386 0x0e, 0xbd, 0xc6, 0xdd, 0xb4, 0xc5, 0x02, 0x72,
387 0x5d, 0xd6, 0xee, 0x8d, 0xa9, 0x5d, 0x56, 0xa0,
388 0xd1, 0x04, 0x4b, 0x46, 0x94, 0xd6, 0xba, 0x84,
389 0x75, 0xa4, 0x43, 0x4f, 0x23, 0xa8, 0x47, 0x4f,
390];
391#[rustfmt::skip]
392static NONCE_2: [u8; 13] = [
393 0xfb, 0x71, 0x7a, 0x8c, 0x82, 0x11, 0x44, 0x77,
394 0x25, 0x3a, 0xcc, 0x14, 0xf6,
395];
396#[rustfmt::skip]
397static A_DATA_2: [u8; 19] = [
398 0x41, 0xe9, 0xd6, 0x56, 0x32, 0xf7, 0x4f, 0x44,
399 0x9a, 0x68, 0x42, 0xd5, 0xe6, 0xc4, 0xa8, 0x6e,
400 0xf8, 0x37, 0x91,
401];
402#[rustfmt::skip]
403static M_DATA_2: [u8; 24] = [
404 0xc7, 0x36, 0x02, 0x82, 0xc8, 0x54, 0x84, 0xa5,
405 0xa3, 0x3a, 0xb1, 0xc6, 0x8d, 0xd7, 0x08, 0x73,
406 0xab, 0x4e, 0x74, 0xff, 0xd4, 0xa6, 0x2c, 0xd5,
407];
408#[rustfmt::skip]
409static C_DATA_2: [u8; 40] = [
410 0x2e, 0x96, 0x1b, 0x3a, 0x2f, 0xa1, 0x60, 0x9a,
411 0x4e, 0x6f, 0xd0, 0x4b, 0xff, 0x6a, 0xc5, 0xe3,
412 0x06, 0xae, 0x26, 0x38, 0x70, 0x6f, 0x99, 0x7b,
413 0x42, 0xbe, 0x2e, 0x2b, 0xa0, 0x5c, 0x54, 0xb6,
414 0x19, 0x85, 0x0d, 0xb5, 0xc9, 0xd6, 0x84, 0xfe,
415];
416
417#[rustfmt::skip]
421static KEY_3: [u8; AES256_KEY_SIZE] = [
422 0x4a, 0x75, 0xff, 0x2f, 0x66, 0xda, 0xe2, 0x93,
423 0x54, 0x03, 0xcc, 0xe2, 0x7e, 0x82, 0x9a, 0xd8,
424 0xbe, 0x98, 0x18, 0x5c, 0x73, 0xf8, 0xbc, 0x61,
425 0xd3, 0xce, 0x95, 0x0a, 0x83, 0x00, 0x7e, 0x11,
426];
427#[rustfmt::skip]
428static NONCE_3: [u8; 13] = [
429 0x46, 0xeb, 0x39, 0x0b, 0x17, 0x5e, 0x75, 0xda,
430 0x61, 0x93, 0xd7, 0xed, 0xb6,
431];
432#[rustfmt::skip]
433static A_DATA_3: [u8; 32] = [
434 0x28, 0x2f, 0x05, 0xf7, 0x34, 0xf2, 0x49, 0xc0,
435 0x53, 0x5e, 0xe3, 0x96, 0x28, 0x22, 0x18, 0xb7,
436 0xc4, 0x91, 0x3c, 0x39, 0xb5, 0x9a, 0xd2, 0xa0,
437 0x3f, 0xfa, 0xf5, 0xb0, 0xe9, 0xb0, 0xf7, 0x80,
438];
439#[rustfmt::skip]
440static M_DATA_3: [u8; 24] = [
441 0x20, 0x5f, 0x2a, 0x66, 0x4a, 0x85, 0x12, 0xe1,
442 0x83, 0x21, 0xa9, 0x1c, 0x13, 0xec, 0x13, 0xb9,
443 0xe6, 0xb6, 0x33, 0x22, 0x8c, 0x57, 0xcc, 0x1e,
444];
445#[rustfmt::skip]
446static C_DATA_3: [u8; 40] = [
447 0x58, 0xf1, 0x58, 0x4f, 0x76, 0x19, 0x83, 0xbe,
448 0xf4, 0xd0, 0x06, 0x07, 0x46, 0xb5, 0xd5, 0xee,
449 0x61, 0x0e, 0xcf, 0xda, 0x31, 0x10, 0x1a, 0x7f,
450 0x54, 0x60, 0xe9, 0xb7, 0x85, 0x6d, 0x60, 0xa5,
451 0xad, 0x98, 0x03, 0xc0, 0x76, 0x2f, 0x81, 0x76,
452];
453
454#[rustfmt::skip]
458static KEY_4: [u8; AES256_KEY_SIZE] = [
459 0x9c, 0xde, 0xba, 0xee, 0xe8, 0x69, 0x0b, 0x68,
460 0x75, 0x10, 0x70, 0x69, 0x1f, 0x49, 0x59, 0x36,
461 0x68, 0xa6, 0xde, 0x12, 0xd3, 0xa9, 0x48, 0xb3,
462 0x8d, 0xdb, 0xd3, 0xf7, 0x52, 0x18, 0xb2, 0xd4,
463];
464#[rustfmt::skip]
465static NONCE_4: [u8; 13] = [
466 0xaf, 0x1a, 0x97, 0xd4, 0x31, 0x51, 0xf5, 0xea,
467 0x9c, 0x48, 0xad, 0x36, 0xa3,
468];
469#[rustfmt::skip]
470static A_DATA_4: [u8; 32] = [
471 0xf5, 0x35, 0x3f, 0xb6, 0xbf, 0xc8, 0xf0, 0x9d,
472 0x55, 0x61, 0x58, 0x13, 0x2d, 0x6c, 0xbb, 0x97,
473 0xd9, 0x04, 0x5e, 0xac, 0xdc, 0x71, 0xf7, 0x82,
474 0xbc, 0xef, 0x62, 0xd2, 0x58, 0xb1, 0x95, 0x0a,
475];
476#[rustfmt::skip]
477static M_DATA_4: [u8; 22] = [
478 0x3c, 0xbb, 0x08, 0xf1, 0x33, 0x27, 0x0e, 0x44,
479 0x54, 0xbc, 0xaa, 0xa0, 0xf2, 0x0f, 0x6d, 0x63,
480 0xc3, 0x8b, 0x65, 0x72, 0xe7, 0x66,
481];
482#[rustfmt::skip]
483static C_DATA_4: [u8; 38] = [
484 0x39, 0x66, 0x93, 0x0a, 0x2a, 0xe8, 0xfd, 0xd8,
485 0xf4, 0x0e, 0x70, 0x07, 0xf3, 0xfd, 0xe0, 0xbd,
486 0x6e, 0xb4, 0x8a, 0x46, 0xe6, 0xd2, 0x6e, 0xef,
487 0x83, 0xda, 0x9f, 0x63, 0x84, 0xb1, 0xa2, 0xbd,
488 0xa1, 0x07, 0x90, 0xda, 0xdb, 0x3f,
489];
490
491#[rustfmt::skip]
495static KEY_5: [u8; AES256_KEY_SIZE] = [
496 0x60, 0x82, 0x3b, 0x64, 0xe0, 0xb2, 0xda, 0x3a,
497 0x7e, 0xb7, 0x72, 0xbd, 0x59, 0x41, 0xc5, 0x34,
498 0xe6, 0xff, 0x94, 0xea, 0x96, 0xb5, 0x64, 0xe2,
499 0xb3, 0x8f, 0x82, 0xc7, 0x8b, 0xb5, 0x45, 0x22,
500];
501#[rustfmt::skip]
502static NONCE_5: [u8; 13] = [
503 0x48, 0x52, 0x6f, 0x1b, 0xff, 0xc9, 0x7d, 0xd6,
504 0x5e, 0x42, 0x90, 0x69, 0x83,
505];
506#[rustfmt::skip]
507static A_DATA_5: [u8; 32] = [
508 0xfa, 0xb6, 0x2b, 0x3e, 0x5d, 0xed, 0xa7, 0xa9,
509 0xc1, 0x12, 0x86, 0x63, 0xcc, 0x81, 0xc4, 0x4b,
510 0x74, 0xab, 0x1b, 0xfe, 0x70, 0xbc, 0x1c, 0x9d,
511 0xec, 0x7c, 0x7f, 0xd0, 0x81, 0x73, 0xb8, 0x0a,
512];
513#[rustfmt::skip]
514static M_DATA_5: [u8; 24] = [
515 0xa8, 0xbe, 0x79, 0x46, 0x13, 0x83, 0x5c, 0x43,
516 0x66, 0xe7, 0x58, 0x17, 0xd2, 0x28, 0x43, 0x8f,
517 0x01, 0x1a, 0x2e, 0xc8, 0xa8, 0x6f, 0x97, 0x97,
518];
519#[rustfmt::skip]
520static C_DATA_5: [u8; 40] = [
521 0xcc, 0x3e, 0xfe, 0x04, 0xd8, 0x4a, 0x4e, 0xc5,
522 0xcb, 0x6a, 0x6c, 0x28, 0xdc, 0x2c, 0x2d, 0x38,
523 0x6a, 0x35, 0x9d, 0x95, 0x50, 0xdb, 0xde, 0xc9,
524 0x63, 0xdd, 0xd5, 0x64, 0x64, 0xae, 0xd6, 0xd0,
525 0x61, 0x31, 0x59, 0xd1, 0xaa, 0x18, 0x1d, 0xcb,
526];
527
528#[rustfmt::skip]
532static KEY_6: [u8; AES256_KEY_SIZE] = [
533 0x5c, 0x8b, 0x59, 0xd3, 0xe7, 0x98, 0x6c, 0x27,
534 0x7d, 0x5a, 0xd5, 0x1e, 0x4a, 0x22, 0x33, 0x25,
535 0x10, 0x76, 0x80, 0x9e, 0xbf, 0x59, 0x46, 0x3f,
536 0x47, 0xcd, 0x10, 0xb4, 0xaa, 0x95, 0x1f, 0x8c,
537];
538#[rustfmt::skip]
539static NONCE_6: [u8; 13] = [
540 0x21, 0xff, 0x89, 0x2b, 0x74, 0x3d, 0x66, 0x11,
541 0x89, 0xe2, 0x05, 0xc7, 0xf3,
542];
543#[rustfmt::skip]
544static A_DATA_6: [u8; 32] = [
545 0xf1, 0xe0, 0xaf, 0x18, 0x51, 0x80, 0xd2, 0xeb,
546 0x63, 0xe5, 0x0e, 0x37, 0xba, 0x69, 0x26, 0x47,
547 0xca, 0xc2, 0xc6, 0xa1, 0x49, 0xd7, 0x0c, 0x81,
548 0xdb, 0xd3, 0x46, 0x85, 0xed, 0x78, 0xfe, 0xaa,
549];
550#[rustfmt::skip]
551static M_DATA_6: [u8; 24] = [
552 0x13, 0x8e, 0xe5, 0x3b, 0x19, 0x14, 0xd3, 0x32,
553 0x2c, 0x2d, 0xd0, 0xa4, 0xe0, 0x2f, 0xaa, 0xb2,
554 0x23, 0x65, 0x55, 0x13, 0x1d, 0x5e, 0xea, 0x08,
555];
556#[rustfmt::skip]
557static C_DATA_6: [u8; 38] = [
558 0x5b, 0x2f, 0x30, 0x26, 0xf3, 0x0f, 0xdd, 0x50,
559 0xac, 0xcc, 0x40, 0xdd, 0xd0, 0x93, 0xb7, 0x99,
560 0x7f, 0x23, 0xd7, 0xc6, 0xd3, 0xc8, 0xbc, 0x42,
561 0x5f, 0x82, 0xc8, 0x28, 0x41, 0x36, 0x43, 0xb8,
562 0x79, 0x44, 0x94, 0xcb, 0x52, 0x36,
563];