1use core::cell::Cell;
24use kernel::ErrorCode;
25use kernel::debug;
26use kernel::hil::symmetric_encryption::{AES256, AES256_KEY_SIZE, AESGCM, GCMClient};
27use kernel::utilities::cells::TakeCell;
28
29const BUF_LEN: usize = 128;
31
32pub struct TestAES256Gcm<'a, A: AESGCM<'a, AES256>> {
33 aes_gcm: &'a A,
34 buf: TakeCell<'static, [u8]>,
35 current_test: Cell<usize>,
36 encrypting: Cell<bool>,
37}
38
39struct Vector {
41 key: &'static [u8],
42 iv: &'static [u8],
43 aad: &'static [u8],
44 pt: &'static [u8],
45 ct: &'static [u8],
46 tag: &'static [u8],
47 expect_tag_invalid: bool,
50}
51
52impl<'a, A: AESGCM<'a, AES256>> TestAES256Gcm<'a, A> {
53 pub fn new(aes_gcm: &'a A, buf: &'static mut [u8]) -> Self {
54 assert!(buf.len() >= BUF_LEN, "buffer too small for GCM-256 tests");
55 TestAES256Gcm {
56 aes_gcm,
57 buf: TakeCell::new(buf),
58 current_test: Cell::new(0),
59 encrypting: Cell::new(true),
60 }
61 }
62
63 pub fn run(&self) {
64 debug!(
65 "AES-256-GCM test suite starting ({} vectors)",
66 VECTORS.len()
67 );
68 self.trigger();
69 }
70
71 fn vector(&self) -> &'static Vector {
72 &VECTORS[self.current_test.get()]
73 }
74
75 fn trigger(&self) {
76 let v = self.vector();
77 let encrypting = self.encrypting.get();
78
79 let aad_offset = 0;
80 let message_offset = v.aad.len();
81 let message_len = v.pt.len();
82 let tag_len = v.tag.len();
83
84 let buf = self
85 .buf
86 .take()
87 .expect("aes256gcm_test: buffer missing in trigger");
88
89 buf[..BUF_LEN].fill(0);
92
93 buf[aad_offset..message_offset].copy_from_slice(v.aad);
94
95 if encrypting {
96 buf[message_offset..message_offset + message_len].copy_from_slice(v.pt);
97 } else {
98 buf[message_offset..message_offset + message_len].copy_from_slice(v.ct);
99 if v.expect_tag_invalid {
100 let tag_start = message_offset + message_len;
102 buf[tag_start..tag_start + tag_len].copy_from_slice(v.tag);
103 buf[tag_start] ^= 0xFF;
104 } else {
105 buf[message_offset + message_len..message_offset + message_len + tag_len]
106 .copy_from_slice(v.tag);
107 }
108 }
109
110 match self.aes_gcm.set_key(v.key) {
111 Ok(()) => {}
112 Err(e) => {
113 panic!(
114 "aes256gcm_test vec={} enc={} returned {:?}: set_key failed",
115 self.current_test.get(),
116 encrypting,
117 e,
118 );
119 }
120 }
121 match self.aes_gcm.set_iv(v.iv) {
122 Ok(()) => {}
123 Err(e) => {
124 panic!(
125 "aes256gcm_test vec={} enc={} returned {:?}: set_iv failed",
126 self.current_test.get(),
127 encrypting,
128 e,
129 );
130 }
131 }
132
133 self.aes_gcm
134 .crypt(
135 buf,
136 aad_offset,
137 message_offset,
138 message_len,
139 tag_len,
140 encrypting,
141 )
142 .unwrap_or_else(|(code, buf)| {
143 self.buf.replace(buf);
144 panic!(
145 "aes256gcm_test vec={} enc={}: crypt() returned {:?}",
146 self.current_test.get(),
147 encrypting,
148 code
149 );
150 });
151 }
152
153 fn check(&self, tag_is_valid: bool) {
154 let v = self.vector();
155 let encrypting = self.encrypting.get();
156 let test_idx = self.current_test.get();
157
158 let message_offset = v.aad.len();
159 let message_len = v.pt.len();
160 let tag_len = v.tag.len();
161 let tag_start = message_offset + message_len;
162
163 let buf = self
164 .buf
165 .take()
166 .expect("aes256gcm_test: buffer missing in check");
167
168 if encrypting {
169 let ct_ok = &buf[message_offset..message_offset + message_len] == v.ct;
171 let tag_ok = &buf[tag_start..tag_start + tag_len] == v.tag;
173 if !ct_ok || !tag_ok || !tag_is_valid {
175 panic!(
176 "aes256gcm_test FAILED vec={} enc=true: \
177 ct_ok={} tag_ok={} tag_is_valid={}",
178 test_idx, ct_ok, tag_ok, tag_is_valid
179 );
180 }
181 } else {
182 if v.expect_tag_invalid {
183 if tag_is_valid {
186 panic!(
187 "aes256gcm_test FAILED vec={} enc=false: \
188 expected tag_is_valid=false for corrupted tag, got true",
189 test_idx
190 );
191 }
192 debug!(
193 "aes256gcm_test passed vec={} enc=false (corrupted tag explicitly rejected: tag_is_valid={})",
194 test_idx, tag_is_valid
195 );
196 self.buf.replace(buf);
197 return;
198 }
199
200 let pt_ok = &buf[message_offset..message_offset + message_len] == v.pt;
202 let tag_ok = &buf[tag_start..tag_start + tag_len] == v.tag;
204
205 if !pt_ok || !tag_ok || !tag_is_valid {
206 panic!(
207 "aes256gcm_test FAILED vec={} enc=false: \
208 pt_ok={} tag_ok={} tag_is_valid={}",
209 test_idx, pt_ok, tag_ok, tag_is_valid
210 );
211 }
212 }
213
214 debug!("aes256gcm_test passed vec={} enc={}", test_idx, encrypting);
215
216 self.buf.replace(buf);
217 }
218
219 fn advance(&self) -> bool {
222 if self.encrypting.get() {
223 self.encrypting.set(false);
225 true
226 } else {
227 self.encrypting.set(true);
229 let next = self.current_test.get() + 1;
230 self.current_test.set(next);
231 next < VECTORS.len()
232 }
233 }
234}
235
236impl<'a, A: AESGCM<'a, AES256>> GCMClient for TestAES256Gcm<'a, A> {
237 fn crypt_done(&self, buf: &'static mut [u8], res: Result<(), ErrorCode>, tag_is_valid: bool) {
238 self.buf.replace(buf);
239 if res != Ok(()) {
240 panic!(
241 "aes256gcm_test vec={} enc={}: crypt_done error {:?}",
242 self.current_test.get(),
243 self.encrypting.get(),
244 res
245 );
246 }
247 self.check(tag_is_valid);
248 if self.advance() {
249 self.trigger();
250 } else {
251 debug!("AES-256-GCM all tests passed");
252 }
253 }
254}
255
256static VECTORS: &[Vector] = &[
268 Vector {
272 key: &KEY_0,
273 iv: &IV_0,
274 aad: &AAD_0,
275 pt: &[],
276 ct: &[],
277 tag: &TAG_0,
278 expect_tag_invalid: false,
279 },
280 Vector {
284 key: &KEY_1,
285 iv: &IV_1,
286 aad: &[],
287 pt: &PT_1,
288 ct: &CT_1,
289 tag: &TAG_1,
290 expect_tag_invalid: false,
291 },
292 Vector {
296 key: &KEY_2,
297 iv: &IV_2,
298 aad: &AAD_2,
299 pt: &PT_2,
300 ct: &CT_2,
301 tag: &TAG_2,
302 expect_tag_invalid: false,
303 },
304 Vector {
308 key: &KEY_3,
309 iv: &IV_3,
310 aad: &[],
311 pt: &PT_3,
312 ct: &CT_3,
313 tag: &TAG_3,
314 expect_tag_invalid: false,
315 },
316 Vector {
320 key: &KEY_4,
321 iv: &IV_4,
322 aad: &AAD_4,
323 pt: &PT_4,
324 ct: &CT_4,
325 tag: &TAG_4,
326 expect_tag_invalid: false,
327 },
328 Vector {
332 key: &KEY_5,
333 iv: &IV_5,
334 aad: &AAD_5,
335 pt: &PT_5,
336 ct: &CT_5,
337 tag: &TAG_5,
338 expect_tag_invalid: false,
339 },
340 Vector {
346 key: &KEY_2,
347 iv: &IV_2,
348 aad: &AAD_2,
349 pt: &PT_2,
350 ct: &CT_2,
351 tag: &TAG_2,
352 expect_tag_invalid: true, },
354];
355
356#[rustfmt::skip]
362static KEY_0: [u8; AES256_KEY_SIZE] = [
363 0x78, 0xdc, 0x4e, 0x0a, 0xaf, 0x52, 0xd9, 0x35,
364 0xc3, 0xc0, 0x1e, 0xea, 0x57, 0x42, 0x8f, 0x00,
365 0xca, 0x1f, 0xd4, 0x75, 0xf5, 0xda, 0x86, 0xa4,
366 0x9c, 0x8d, 0xd7, 0x3d, 0x68, 0xc8, 0xe2, 0x23,
367];
368#[rustfmt::skip]
369static IV_0: [u8; 12] = [
370 0xd7, 0x9c, 0xf2, 0x2d, 0x50, 0x4c, 0xc7, 0x93,
371 0xc3, 0xfb, 0x6c, 0x8a,
372];
373#[rustfmt::skip]
374static AAD_0: [u8; 16] = [
375 0xb9, 0x6b, 0xaa, 0x8c, 0x1c, 0x75, 0xa6, 0x71,
376 0xbf, 0xb2, 0xd0, 0x8d, 0x06, 0xbe, 0x5f, 0x36,
377];
378#[rustfmt::skip]
379static TAG_0: [u8; 16] = [
380 0x3e, 0x5d, 0x48, 0x6a, 0xa2, 0xe3, 0x0b, 0x22,
381 0xe0, 0x40, 0xb8, 0x57, 0x23, 0xa0, 0x6e, 0x76,
382];
383
384#[rustfmt::skip]
390static KEY_1: [u8; AES256_KEY_SIZE] = [
391 0x31, 0xbd, 0xad, 0xd9, 0x66, 0x98, 0xc2, 0x04,
392 0xaa, 0x9c, 0xe1, 0x44, 0x8e, 0xa9, 0x4a, 0xe1,
393 0xfb, 0x4a, 0x9a, 0x0b, 0x3c, 0x9d, 0x77, 0x3b,
394 0x51, 0xbb, 0x18, 0x22, 0x66, 0x6b, 0x8f, 0x22,
395];
396#[rustfmt::skip]
397static IV_1: [u8; 12] = [
398 0x0d, 0x18, 0xe0, 0x6c, 0x7c, 0x72, 0x5a, 0xc9,
399 0xe3, 0x62, 0xe1, 0xce,
400];
401#[rustfmt::skip]
402static PT_1: [u8; 16] = [
403 0x2d, 0xb5, 0x16, 0x8e, 0x93, 0x25, 0x56, 0xf8,
404 0x08, 0x9a, 0x06, 0x22, 0x98, 0x1d, 0x01, 0x7d,
405];
406#[rustfmt::skip]
407static CT_1: [u8; 16] = [
408 0xfa, 0x43, 0x62, 0x18, 0x96, 0x61, 0xd1, 0x63,
409 0xfc, 0xd6, 0xa5, 0x6d, 0x8b, 0xf0, 0x40, 0x5a,
410];
411#[rustfmt::skip]
412static TAG_1: [u8; 16] = [
413 0xd6, 0x36, 0xac, 0x1b, 0xbe, 0xdd, 0x5c, 0xc3,
414 0xee, 0x72, 0x7d, 0xc2, 0xab, 0x4a, 0x94, 0x89,
415];
416#[rustfmt::skip]
422static KEY_2: [u8; AES256_KEY_SIZE] = [
423 0x92, 0xe1, 0x1d, 0xcd, 0xaa, 0x86, 0x6f, 0x5c,
424 0xe7, 0x90, 0xfd, 0x24, 0x50, 0x1f, 0x92, 0x50,
425 0x9a, 0xac, 0xf4, 0xcb, 0x8b, 0x13, 0x39, 0xd5,
426 0x0c, 0x9c, 0x12, 0x40, 0x93, 0x5d, 0xd0, 0x8b,
427];
428#[rustfmt::skip]
429static IV_2: [u8; 12] = [
430 0xac, 0x93, 0xa1, 0xa6, 0x14, 0x52, 0x99, 0xbd,
431 0xe9, 0x02, 0xf2, 0x1a,
432];
433#[rustfmt::skip]
434static AAD_2: [u8; 16] = [
435 0x1e, 0x08, 0x89, 0x01, 0x6f, 0x67, 0x60, 0x1c,
436 0x8e, 0xbe, 0xa4, 0x94, 0x3b, 0xc2, 0x3a, 0xd6,
437];
438#[rustfmt::skip]
439static PT_2: [u8; 16] = [
440 0x2d, 0x71, 0xbc, 0xfa, 0x91, 0x4e, 0x4a, 0xc0,
441 0x45, 0xb2, 0xaa, 0x60, 0x95, 0x5f, 0xad, 0x24,
442];
443#[rustfmt::skip]
444static CT_2: [u8; 16] = [
445 0x89, 0x95, 0xae, 0x2e, 0x6d, 0xf3, 0xdb, 0xf9,
446 0x6f, 0xac, 0x7b, 0x71, 0x37, 0xba, 0xe6, 0x7f,
447];
448#[rustfmt::skip]
449static TAG_2: [u8; 16] = [
450 0xec, 0xa5, 0xaa, 0x77, 0xd5, 0x1d, 0x4a, 0x0a,
451 0x14, 0xd9, 0xc5, 0x1e, 0x1d, 0xa4, 0x74, 0xab,
452];
453
454static KEY_3: [u8; AES256_KEY_SIZE] = KEY_1;
460static IV_3: [u8; 12] = IV_1;
461static PT_3: [u8; 16] = PT_1;
462static CT_3: [u8; 16] = CT_1;
463static TAG_3: [u8; 16] = TAG_1;
464
465#[rustfmt::skip]
469static KEY_4: [u8; 32] = [
470 0xc2, 0x93, 0x26, 0x01, 0x79, 0x87, 0x5a, 0x2c,
471 0xc5, 0xd6, 0xa6, 0x60, 0xba, 0x41, 0x8f, 0xa0,
472 0xc1, 0xd1, 0xf9, 0xd0, 0xb1, 0xfc, 0x1d, 0xdf,
473 0x65, 0x01, 0x40, 0xd0, 0x18, 0xaa, 0xe3, 0x0b,
474];
475
476#[rustfmt::skip]
477static IV_4: [u8; 12] = [
478 0xbb, 0xc0, 0xde, 0x9d, 0x51, 0xb6, 0x46, 0xb2,
479 0xd7, 0x79, 0xd1, 0xa1,
480];
481
482#[rustfmt::skip]
483static AAD_4: [u8; 90] = [
484 0x21, 0x8b, 0x66, 0xe8, 0x88, 0x39, 0xbf, 0xec, 0xc9, 0xc4, 0x1a, 0x73, 0x7e, 0xbd, 0x1a, 0x58,
485 0xba, 0x41, 0x86, 0x85, 0x38, 0x47, 0x38, 0x95, 0x9a, 0x82, 0xe2, 0x4d, 0x81, 0xb7, 0x66, 0xb9,
486 0x18, 0x81, 0x95, 0x59, 0x9b, 0xd2, 0xe7, 0xad, 0x29, 0xfd, 0x53, 0x37, 0x96, 0x9b, 0x00, 0x50,
487 0x04, 0xf2, 0x21, 0xf5, 0x7e, 0x02, 0x24, 0xa5, 0xe2, 0xd8, 0x84, 0x42, 0x68, 0xe6, 0xe2, 0x50,
488 0x65, 0x99, 0xc0, 0x5e, 0x72, 0xdf, 0x54, 0x3d, 0x11, 0x41, 0x2f, 0xe8, 0x2a, 0xcd, 0x66, 0xa7,
489 0xca, 0xaa, 0xa1, 0x66, 0x08, 0x92, 0x6f, 0x77, 0xe3, 0x54,
490];
491
492#[rustfmt::skip]
493static PT_4: [u8; 16] = [
494 0xdf, 0xd5, 0x0a, 0xbb, 0xdf, 0xc4, 0x11, 0x44,
495 0xf3, 0x60, 0x06, 0x53, 0xe2, 0xf9, 0x67, 0x0d,
496];
497
498#[rustfmt::skip]
499static CT_4: [u8; 16] = [
500 0xad, 0xbd, 0xd3, 0x9a, 0xe6, 0x3c, 0x55, 0x31,
501 0x48, 0x82, 0x8b, 0x0f, 0xfc, 0xa6, 0x29, 0x17,
502];
503
504#[rustfmt::skip]
505static TAG_4: [u8; 12] = [
506 0xef, 0x51, 0x6b, 0xc6, 0xf1, 0xd2, 0xfb, 0x10,
507 0x20, 0xf9, 0x55, 0x31,
508];
509
510#[rustfmt::skip]
516static KEY_5: [u8; AES256_KEY_SIZE] = [
517 0x6e, 0x50, 0xfc, 0xc4, 0xb6, 0x9e, 0x96, 0x23,
518 0xf6, 0xd5, 0x58, 0x49, 0xc1, 0x44, 0x34, 0xbe,
519 0x8a, 0x1d, 0x38, 0xf9, 0x10, 0xf3, 0x83, 0x15,
520 0x30, 0x0a, 0x3c, 0xa3, 0xcb, 0x71, 0xc7, 0xd5,
521];
522
523#[rustfmt::skip]
524static IV_5: [u8; 12] = [
525 0xb6, 0xe8, 0x58, 0x01, 0xab, 0xd0, 0x72, 0xdb,
526 0x88, 0x52, 0x51, 0x4c,
527];
528
529#[rustfmt::skip]
530static AAD_5: [u8; 90] = [
531 0xa1, 0xfa, 0x6b, 0xf9, 0xf7, 0x52, 0x7c, 0xc4,
532 0x05, 0x31, 0x0e, 0x0c, 0xf2, 0xc6, 0x3b, 0x84,
533 0xdd, 0x4f, 0xef, 0x93, 0xb2, 0x02, 0x14, 0xd0,
534 0x03, 0x90, 0x26, 0x0a, 0xa4, 0x4b, 0xc7, 0xf3,
535 0x95, 0x36, 0x77, 0x7e, 0x8a, 0xc6, 0x9e, 0x33,
536 0xb8, 0xb7, 0xb6, 0x9b, 0x4f, 0xd8, 0x1a, 0xf2,
537 0xd8, 0x17, 0xbf, 0xcc, 0x8f, 0x6f, 0x8a, 0xab,
538 0xcf, 0x74, 0x8f, 0xc7, 0xe9, 0xfe, 0xb6, 0x75,
539 0x7d, 0x21, 0x89, 0x9c, 0x78, 0xd8, 0xa1, 0x34,
540 0xa5, 0x5b, 0x90, 0xea, 0xa9, 0xe8, 0x95, 0xb3,
541 0x1a, 0x9f, 0xb4, 0xd3, 0x7d, 0xaa, 0x84, 0xbc,
542 0x86, 0x42,
543];
544
545#[rustfmt::skip]
546static PT_5: [u8; 13] = [
547 0xe9, 0x99, 0x04, 0xb9, 0x21, 0x16, 0x8e, 0x0b,
548 0xa6, 0xa5, 0xcc, 0xef, 0x33,
549];
550
551#[rustfmt::skip]
552static CT_5: [u8; 13] = [
553 0x5b, 0x0e, 0xa5, 0xd1, 0x16, 0x71, 0x31, 0x92,
554 0x9f, 0x74, 0x29, 0x9a, 0x5f,
555];
556
557#[rustfmt::skip]
558static TAG_5: [u8; 15] = [
559 0x22, 0x23, 0x55, 0x11, 0x74, 0x3d, 0x0b, 0x83,
560 0xae, 0x5a, 0xb7, 0x6d, 0x9f, 0xa3, 0x15,
561];