1use core::cell::Cell;
8use kernel::debug;
9use kernel::hil::symmetric_encryption::{GCMClient, AES128GCM, AES128_KEY_SIZE};
10use kernel::utilities::cells::TakeCell;
11use kernel::ErrorCode;
12
13pub struct Test<'a, A: AES128GCM<'a>> {
14 aes_gcm: &'a A,
15
16 buf: TakeCell<'static, [u8]>,
17 current_test: Cell<usize>,
18 encrypting: Cell<bool>,
19
20 tests: [(
22 &'static [u8],
23 &'static [u8],
24 &'static [u8],
25 &'static [u8],
26 &'static [u8],
27 &'static [u8],
28 ); 2],
29}
30
31impl<'a, A: AES128GCM<'a>> Test<'a, A> {
32 pub fn new(aes_gcm: &'a A, buf: &'static mut [u8]) -> Test<'a, A> {
33 Test {
34 aes_gcm,
35 buf: TakeCell::new(buf),
36 current_test: Cell::new(0),
37 encrypting: Cell::new(true),
38 tests: [
39 (
40 &KEY_128_TWELVE,
41 &IV_128_TWELVE,
42 &[],
43 &AAD_128_TWELVE,
44 &[],
45 &TAG_128_TWELVE,
46 ),
47 (
48 &KEY_128_THIRTEEN,
49 &IV_128_THIRTEEN,
50 &PT_128_THIRTEEN,
51 &[],
52 &CT_128_THIRTEEN,
53 &TAG_128_THIRTEEN,
54 ),
55 ],
56 }
57 }
58
59 pub fn run(&self) {
60 debug!("AES GCM* encryption/decryption tests");
61 self.trigger_test();
62 }
63
64 fn next_test(&self) -> bool {
65 if self.encrypting.get() {
66 self.encrypting.set(false);
67 } else {
68 self.encrypting.set(true);
69 self.current_test.set(self.current_test.get() + 1);
70 if self.current_test.get() >= self.tests.len() {
71 return false;
72 }
73 }
74 true
75 }
76
77 fn trigger_test(&self) {
78 let (key, iv, pt, aad, ct, tag) = self.tests[self.current_test.get()];
79 let (aad_off, pt_off, pt_len) = (0, aad.len(), pt.len());
80 let encrypting = self.encrypting.get();
81
82 let buf = match self.buf.take() {
83 None => panic!("aes_gcm_test failed: buffer is not present in trigger_test."),
84 Some(buf) => buf,
85 };
86
87 if encrypting {
88 buf[aad_off..pt_off].copy_from_slice(aad);
89 buf[pt_off..pt_off + pt_len].copy_from_slice(pt);
90 } else {
91 buf[aad_off..pt_off].copy_from_slice(aad);
92 buf[pt_off..pt_off + pt_len].copy_from_slice(ct);
93 buf[pt_off + pt_len..(pt_off + pt_len + tag.len())].copy_from_slice(tag);
94 }
95
96 if self.aes_gcm.set_key(key) != Ok(()) {
97 panic!("aes_gcm_test failed: cannot set key.");
98 }
99
100 if self.aes_gcm.set_iv(iv) != Ok(()) {
101 panic!("aes_gcm_test failed: cannot set IV.");
102 }
103
104 let _ = self
105 .aes_gcm
106 .crypt(buf, aad_off, pt_off, pt_len, encrypting)
107 .map_err(|(_code, buf)| {
108 self.buf.replace(buf);
109 panic!("Failed to start test.");
110 });
111 }
112
113 fn check_test(&self, tag_is_valid: bool) {
114 let (_key, _iv, pt, aad, ct, tag) = self.tests[self.current_test.get()];
115 let (_aad_off, pt_off, pt_len) = (0, aad.len(), pt.len());
116 let encrypting = self.encrypting.get();
117
118 let buf = match self.buf.take() {
119 None => panic!("aes_gcm_test failed: buffer is not present in check_test."),
120 Some(buf) => buf,
121 };
122
123 if encrypting {
124 let ct_matches = buf[pt_off..(pt_off + pt_len)]
125 .iter()
126 .zip(ct.iter())
127 .all(|(a, b)| *a == *b);
128 let tag_matches = buf[(pt_off + pt_len)..(pt_off + pt_len + tag.len())]
129 .iter()
130 .zip(tag.iter())
131 .all(|(a, b)| *a == *b);
132
133 if ct_matches && tag_matches && tag_is_valid {
134 debug!(
135 "aes_gcm_test passed: (current_test={}, encrypting={}, tag_is_valid={})",
136 self.current_test.get(),
137 self.encrypting.get(),
138 tag_is_valid
139 );
140 } else {
141 panic!("aes_gcm_test failed: ct_matches={}, tag_matches={}, (current_test={}, encrypting={}, tag_is_valid={}",
142 ct_matches,
143 tag_matches,
144 self.current_test.get(),
145 self.encrypting.get(),
146 tag_is_valid);
147 }
148 } else {
149 let pt_matches = buf[pt_off..(pt_off + pt_len)]
150 .iter()
151 .zip(pt.iter())
152 .all(|(a, b)| *a == *b);
153 let tag_matches = buf[(pt_off + pt_len)..(pt_off + pt_len + tag.len())]
154 .iter()
155 .zip(tag.iter())
156 .all(|(a, b)| *a == *b);
157
158 if pt_matches && tag_matches && tag_is_valid {
159 debug!(
160 "aes_gcm_test passed: (current_test={}, encrypting={}, tag_is_valid={})",
161 self.current_test.get(),
162 self.encrypting.get(),
163 tag_is_valid
164 );
165 } else {
166 panic!("aes_gcm_test failed: pt_matches={}, tag_matches={}, (current_test={}, encrypting={}, tag_is_valid={}",
167 pt_matches,
168 tag_matches,
169 self.current_test.get(),
170 self.encrypting.get(),
171 tag_is_valid);
172 }
173 }
174
175 self.buf.replace(buf);
176 }
177}
178
179impl<'a, A: AES128GCM<'a>> GCMClient for Test<'a, A> {
180 fn crypt_done(&self, buf: &'static mut [u8], res: Result<(), ErrorCode>, tag_is_valid: bool) {
181 self.buf.replace(buf);
182 if res != Ok(()) {
183 panic!("aes_gcm_test failed: crypt_done returned {:?}", res);
184 } else {
185 self.check_test(tag_is_valid);
186 if self.next_test() {
187 self.trigger_test()
188 }
189 }
190 }
191}
192
193static KEY_128_TWELVE: [u8; AES128_KEY_SIZE] = [
194 0x26, 0x73, 0x0f, 0x1a, 0xd2, 0x4b, 0x76, 0xd6, 0x6f, 0x7a, 0xb8, 0x45, 0x9d, 0xdc, 0xd1, 0x17,
195];
196
197static IV_128_TWELVE: [u8; 12] = [
198 0x1f, 0xfb, 0x3e, 0x75, 0x71, 0xcb, 0x70, 0x14, 0x5e, 0xa5, 0x16, 0x53,
199];
200
201static AAD_128_TWELVE: [u8; 90] = [
202 0xbf, 0xc3, 0xa8, 0x08, 0xc0, 0x60, 0xcd, 0xfd, 0x2a, 0xb7, 0x69, 0x1b, 0x32, 0x4a, 0xb3, 0x59,
203 0x29, 0xe8, 0x0f, 0x26, 0x2b, 0xf3, 0xb9, 0x4c, 0xc2, 0xf4, 0x5c, 0x62, 0xbb, 0x0f, 0x32, 0xbc,
204 0x4e, 0x4b, 0x96, 0x73, 0x69, 0x11, 0x0a, 0x7b, 0x4c, 0x47, 0x82, 0x7e, 0x93, 0xa9, 0xec, 0xd7,
205 0xfc, 0xda, 0x5e, 0x6a, 0x97, 0x39, 0xa0, 0xd1, 0x78, 0x6d, 0x6d, 0xc7, 0xa4, 0x5c, 0x9c, 0x1e,
206 0x8e, 0xcc, 0x8f, 0x90, 0xdc, 0x70, 0xbc, 0x5a, 0x5a, 0xe1, 0xa0, 0x31, 0x3f, 0xd6, 0xef, 0x87,
207 0xd7, 0xb3, 0x6e, 0x3d, 0x48, 0xc4, 0x44, 0x8f, 0x70, 0x3e,
208];
209
210static TAG_128_TWELVE: [u8; 14] = [
211 0x45, 0xa9, 0xbe, 0x4c, 0x84, 0x9e, 0xcb, 0x25, 0x85, 0x42, 0x1a, 0x1f, 0x08, 0xe6,
212];
213
214static KEY_128_THIRTEEN: [u8; AES128_KEY_SIZE] = [
215 0x8f, 0x85, 0xd3, 0x66, 0x16, 0xa9, 0x5f, 0xc1, 0x05, 0x86, 0xc3, 0x16, 0xb3, 0x05, 0x37, 0x70,
216];
217
218static IV_128_THIRTEEN: [u8; 12] = [
219 0xd3, 0x20, 0xb5, 0x00, 0x26, 0x96, 0x09, 0xac, 0xe1, 0xbe, 0x67, 0xce,
220];
221
222static PT_128_THIRTEEN: [u8; 32] = [
223 0x3a, 0x75, 0x8e, 0xe0, 0x72, 0xfc, 0x70, 0xa6, 0x42, 0x75, 0xb5, 0x6e, 0x72, 0xcb, 0x23, 0xa1,
224 0x59, 0x04, 0x58, 0x9c, 0xef, 0xbe, 0xeb, 0x58, 0x48, 0xec, 0x53, 0xff, 0xc0, 0x6c, 0x7a, 0x5d,
225];
226
227static CT_128_THIRTEEN: [u8; 32] = [
228 0xfb, 0x2f, 0xe3, 0xeb, 0x40, 0xed, 0xfb, 0xd2, 0x2a, 0x51, 0x6b, 0xec, 0x35, 0x9d, 0x4b, 0xb4,
229 0x23, 0x8a, 0x07, 0x00, 0xa4, 0x6f, 0xee, 0x11, 0x36, 0xa0, 0x61, 0x85, 0x40, 0x22, 0x9c, 0x41,
230];
231
232static TAG_128_THIRTEEN: [u8; 16] = [
233 0x42, 0x26, 0x93, 0x16, 0xce, 0xce, 0x7d, 0x88, 0x2c, 0xc6, 0x8c, 0x3e, 0xd9, 0xd2, 0xf0, 0xae,
234];