1 /* Copyright 2014 The ChromiumOS Authors
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Tests for firmware 2common.c
6 */
7
8 #include "2common.h"
9 #include "2sysincludes.h"
10 #include "common/tests.h"
11 #include "vboot_struct.h" /* For old struct sizes */
12
13 /* Mock data */
14 static int counter_calls_left = 0;
15
16 /* Mock functions */
counter(void)17 static int counter(void)
18 {
19 counter_calls_left--;
20 return 0;
21 }
22
23 /*
24 * Test arithmetic-related macros and operators.
25 */
test_arithmetic(void)26 static void test_arithmetic(void)
27 {
28 int64_t a = -10, b = -20;
29 uint64_t u = (0xabcd00000000ULL);
30 uint64_t v = (0xabcd000000ULL);
31
32 TEST_EQ(VB2_MIN(1, 2), 1, "MIN 1");
33 TEST_EQ(VB2_MIN(4, 3), 3, "MIN 3");
34 TEST_EQ(VB2_MIN(5, 5), 5, "MIN 5");
35 TEST_EQ(VB2_MIN(a, b), b, "MIN uint64 1");
36 TEST_EQ(VB2_MIN(b, a), b, "MIN uint64 2");
37 TEST_EQ(VB2_MIN(b, b), b, "MIN uint64 same");
38
39 counter_calls_left = 2;
40 VB2_MIN(counter(), counter());
41 TEST_EQ(counter_calls_left, 0, "MIN double-evaluation");
42
43 TEST_EQ(VB2_MAX(1, 2), 2, "MAX 2");
44 TEST_EQ(VB2_MAX(4, 3), 4, "MAX 4");
45 TEST_EQ(VB2_MAX(5, 5), 5, "MAX 5");
46 TEST_EQ(VB2_MAX(a, b), a, "MAX uint64 1");
47 TEST_EQ(VB2_MAX(b, a), a, "MAX uint64 2");
48 TEST_EQ(VB2_MAX(b, b), b, "MAX uint64 same");
49
50 counter_calls_left = 2;
51 VB2_MAX(counter(), counter());
52 TEST_EQ(counter_calls_left, 0, "MAX double-evaluation");
53
54 TEST_EQ(u >> 8, v, "uint64_t >> 8");
55 TEST_EQ(u >> 0, u, "uint64_t >> 0");
56 TEST_EQ(u >> 36, (uint64_t)0xabc, "uint64_t >> 36");
57
58 TEST_EQ(v * (uint32_t)0, 0, "uint64_t * uint32_t 0");
59 TEST_EQ(v * (uint32_t)1, v, "uint64_t * uint32_t 1");
60 TEST_EQ(v * (uint32_t)256, u, "uint64_t * uint32_t 256");
61 }
62
63 /*
64 * Test array size macro.
65 */
test_array_size(void)66 static void test_array_size(void)
67 {
68 uint8_t arr1[12];
69 uint32_t arr2[7];
70 uint64_t arr3[9];
71
72 TEST_EQ(ARRAY_SIZE(arr1), 12, "ARRAYSIZE(uint8_t)");
73 TEST_EQ(ARRAY_SIZE(arr2), 7, "ARRAYSIZE(uint32_t)");
74 TEST_EQ(ARRAY_SIZE(arr3), 9, "ARRAYSIZE(uint64_t)");
75 }
76
77 /*
78 * Test struct packing for vboot_struct.h structs which are passed between
79 * firmware and OS, or passed between different phases of firmware.
80 */
test_struct_packing(void)81 static void test_struct_packing(void)
82 {
83 TEST_EQ(EXPECTED_VB2_PACKED_KEY_SIZE,
84 sizeof(struct vb2_packed_key),
85 "sizeof(vb2_packed_key)");
86 TEST_EQ(EXPECTED_VB2_GBB_HEADER_SIZE,
87 sizeof(struct vb2_gbb_header),
88 "sizeof(vb2_gbb_header)");
89 TEST_EQ(EXPECTED_VB2_SIGNATURE_SIZE,
90 sizeof(struct vb2_signature),
91 "sizeof(vb2_signature)");
92 TEST_EQ(EXPECTED_VB2_KEYBLOCK_SIZE,
93 sizeof(struct vb2_keyblock),
94 "sizeof(vb2_keyblock)");
95 }
96
97 /**
98 * Test memory compare functions
99 */
test_memcmp(void)100 static void test_memcmp(void)
101 {
102 TEST_EQ(vb2_safe_memcmp("foo", "foo", 3), 0, "memcmp equal");
103 TEST_NEQ(vb2_safe_memcmp("foo1", "foo2", 4), 0, "memcmp different");
104 TEST_EQ(vb2_safe_memcmp("foo1", "foo2", 0), 0, "memcmp 0-size");
105 }
106
107 /**
108 * Test alignment functions
109 */
test_align(void)110 static void test_align(void)
111 {
112 uint64_t buf[4];
113 uint8_t *p0, *ptr;
114 uint32_t size;
115
116 /* Already aligned */
117 p0 = (uint8_t *)buf;
118 ptr = p0;
119 size = 16;
120 TEST_SUCC(vb2_align(&ptr, &size, 4, 16), "vb2_align() aligned");
121 TEST_EQ(vb2_offset_of(p0, ptr), 0, "ptr");
122 TEST_EQ(size, 16, " size");
123 TEST_EQ(vb2_align(&ptr, &size, 4, 17),
124 VB2_ERROR_ALIGN_SIZE, "vb2_align() small");
125
126 /* Offset */
127 ptr = p0 + 1;
128 size = 15;
129 TEST_SUCC(vb2_align(&ptr, &size, 4, 12), "vb2_align() offset");
130 TEST_EQ(vb2_offset_of(p0, ptr), 4, "ptr");
131 TEST_EQ(size, 12, " size");
132
133 /* Offset, now too small */
134 ptr = p0 + 1;
135 size = 15;
136 TEST_EQ(vb2_align(&ptr, &size, 4, 15),
137 VB2_ERROR_ALIGN_SIZE, "vb2_align() offset small");
138
139 /* Offset, too small even to align */
140 ptr = p0 + 1;
141 size = 1;
142 TEST_EQ(vb2_align(&ptr, &size, 4, 1),
143 VB2_ERROR_ALIGN_BIGGER_THAN_SIZE, "vb2_align() offset tiny");
144 }
145
146 /**
147 * Test work buffer functions
148 */
test_workbuf(void)149 static void test_workbuf(void)
150 {
151 uint64_t buf[8] __attribute__((aligned(VB2_WORKBUF_ALIGN)));
152 uint8_t *p0 = (uint8_t *)buf, *ptr;
153 struct vb2_workbuf wb;
154
155 /* Init */
156 vb2_workbuf_init(&wb, p0, VB2_WORKBUF_ALIGN * 2);
157 TEST_EQ(vb2_offset_of(p0, wb.buf), 0, "Workbuf init aligned");
158 TEST_EQ(wb.size, VB2_WORKBUF_ALIGN * 2, " size");
159
160 /* Unaligned init */
161 vb2_workbuf_init(&wb, p0 + 1, VB2_WORKBUF_ALIGN * 2);
162 TEST_EQ(vb2_offset_of(p0, wb.buf), VB2_WORKBUF_ALIGN,
163 "Workbuf init unaligned");
164 TEST_EQ(wb.size, VB2_WORKBUF_ALIGN + 1, " size");
165
166 /* No size left after align */
167 vb2_workbuf_init(&wb, p0 + 1, VB2_WORKBUF_ALIGN - 1);
168 TEST_EQ(wb.size, 0, "Workbuf init size=0 after align");
169 vb2_workbuf_init(&wb, p0 + 1, VB2_WORKBUF_ALIGN - 2);
170 TEST_EQ(wb.size, 0, "Workbuf init size=-1 after align");
171
172 /* Alloc rounds up */
173 vb2_workbuf_init(&wb, p0, VB2_WORKBUF_ALIGN * 2);
174 ptr = vb2_workbuf_alloc(&wb, VB2_WORKBUF_ALIGN - 1);
175 TEST_EQ(vb2_offset_of(p0, ptr), 0, "Workbuf alloc");
176 TEST_EQ(vb2_offset_of(p0, wb.buf), VB2_WORKBUF_ALIGN, " buf");
177 TEST_EQ(wb.size, VB2_WORKBUF_ALIGN, " size");
178
179 /* Alloc doesn't fit */
180 vb2_workbuf_init(&wb, p0, VB2_WORKBUF_ALIGN);
181 TEST_PTR_EQ(vb2_workbuf_alloc(&wb, VB2_WORKBUF_ALIGN + 1), NULL,
182 "Workbuf alloc too big");
183
184 /* Free reverses alloc */
185 vb2_workbuf_init(&wb, p0, VB2_WORKBUF_ALIGN * 2);
186 vb2_workbuf_alloc(&wb, VB2_WORKBUF_ALIGN + 1);
187 vb2_workbuf_free(&wb, VB2_WORKBUF_ALIGN + 1);
188 TEST_EQ(vb2_offset_of(p0, wb.buf), 0, "Workbuf free buf");
189 TEST_EQ(wb.size, VB2_WORKBUF_ALIGN * 2, " size");
190
191 /* Realloc keeps same pointer as alloc */
192 vb2_workbuf_init(&wb, p0, VB2_WORKBUF_ALIGN * 3);
193 vb2_workbuf_alloc(&wb, VB2_WORKBUF_ALIGN - 1);
194 ptr = vb2_workbuf_realloc(&wb, VB2_WORKBUF_ALIGN - 1,
195 VB2_WORKBUF_ALIGN + 1);
196 TEST_EQ(vb2_offset_of(p0, ptr), 0, "Workbuf realloc");
197 TEST_EQ(vb2_offset_of(p0, wb.buf), VB2_WORKBUF_ALIGN * 2, " buf");
198 TEST_EQ(wb.size, VB2_WORKBUF_ALIGN, " size");
199 }
200
201 /**
202 * Helper functions not dependent on specific key sizes
203 */
test_helper_functions(void)204 static void test_helper_functions(void)
205 {
206 {
207 struct vb2_packed_key k = {.key_offset = sizeof(k)};
208 TEST_EQ((int)vb2_offset_of(&k, vb2_packed_key_data(&k)),
209 sizeof(k), "vb2_packed_key_data() adjacent");
210 }
211
212 {
213 struct vb2_packed_key k = {.key_offset = 123};
214 TEST_EQ((int)vb2_offset_of(&k, vb2_packed_key_data(&k)), 123,
215 "vb2_packed_key_data() spaced");
216 }
217 {
218 struct vb2_signature s = {.sig_offset = sizeof(s)};
219 TEST_EQ((int)vb2_offset_of(&s, vb2_signature_data(&s)),
220 sizeof(s), "vb2_signature_data() adjacent");
221 }
222
223 {
224 struct vb2_signature s = {.sig_offset = 123};
225 TEST_EQ((int)vb2_offset_of(&s, vb2_signature_data(&s)), 123,
226 "vb2_signature_data() spaced");
227 }
228
229 {
230 uint8_t *p = (uint8_t *)test_helper_functions;
231 TEST_EQ((int)vb2_offset_of(p, p), 0, "vb2_offset_of() equal");
232 TEST_EQ((int)vb2_offset_of(p, p+10), 10,
233 "vb2_offset_of() positive");
234 TEST_EQ((int)vb2_offset_of(p, p+0x12345678), 0x12345678,
235 "vb2_offset_of() large");
236 }
237
238 {
239 uint8_t *p = (uint8_t *)test_helper_functions;
240 TEST_SUCC(vb2_verify_member_inside(p, 20, p, 6, 11, 3),
241 "vb2_verify_member_inside() ok 1");
242 TEST_SUCC(vb2_verify_member_inside(p, 20, p+4, 4, 8, 4),
243 "vb2_verify_member_inside() ok 2");
244 TEST_EQ(vb2_verify_member_inside(p, 20, p-4, 4, 8, 4),
245 VB2_ERROR_INSIDE_MEMBER_OUTSIDE,
246 "vb2_verify_member_inside() member before parent");
247 TEST_EQ(vb2_verify_member_inside(p, 20, p+20, 4, 8, 4),
248 VB2_ERROR_INSIDE_MEMBER_OUTSIDE,
249 "vb2_verify_member_inside() member after parent");
250 TEST_EQ(vb2_verify_member_inside(p, 20, p, 21, 0, 0),
251 VB2_ERROR_INSIDE_MEMBER_OUTSIDE,
252 "vb2_verify_member_inside() member too big");
253 TEST_EQ(vb2_verify_member_inside(p, 20, p, 4, 21, 0),
254 VB2_ERROR_INSIDE_DATA_OUTSIDE,
255 "vb2_verify_member_inside() data after parent");
256 TEST_EQ(vb2_verify_member_inside(p, 20, p, 4, SIZE_MAX, 0),
257 VB2_ERROR_INSIDE_DATA_OUTSIDE,
258 "vb2_verify_member_inside() data before parent");
259 TEST_EQ(vb2_verify_member_inside(p, 20, p, 4, 4, 17),
260 VB2_ERROR_INSIDE_DATA_OUTSIDE,
261 "vb2_verify_member_inside() data too big");
262 TEST_EQ(vb2_verify_member_inside(p, 20, p, 8, 4, 8),
263 VB2_ERROR_INSIDE_DATA_OVERLAP,
264 "vb2_verify_member_inside() data overlaps member");
265 TEST_EQ(vb2_verify_member_inside(p, -8, p, 12, 0, 0),
266 VB2_ERROR_INSIDE_PARENT_WRAPS,
267 "vb2_verify_member_inside() wraparound 1");
268 TEST_EQ(vb2_verify_member_inside(p, 20, p, -8, 0, 0),
269 VB2_ERROR_INSIDE_MEMBER_WRAPS,
270 "vb2_verify_member_inside() wraparound 2");
271 TEST_EQ(vb2_verify_member_inside(p, 20, p, 4, 4, -12),
272 VB2_ERROR_INSIDE_DATA_WRAPS,
273 "vb2_verify_member_inside() wraparound 3");
274 }
275
276 {
277 struct vb2_packed_key k = {.key_offset = sizeof(k),
278 .key_size = 128};
279 const void *lower_base;
280 TEST_SUCC(vb2_verify_packed_key_inside(&k, sizeof(k)+128, &k),
281 "vb2_packed_key_inside() ok 1");
282 lower_base = (const void *)((uintptr_t)&k - sizeof(k));
283 TEST_SUCC(vb2_verify_packed_key_inside(lower_base,
284 2*sizeof(k)+128, &k),
285 "vb2_packed_key_inside() ok 2");
286 TEST_EQ(vb2_verify_packed_key_inside(&k, 128, &k),
287 VB2_ERROR_INSIDE_DATA_OUTSIDE,
288 "vb2_packed_key_inside() key too big");
289 }
290
291 {
292 struct vb2_packed_key k = {.key_offset = 100,
293 .key_size = 4};
294 TEST_EQ(vb2_verify_packed_key_inside(&k, 99, &k),
295 VB2_ERROR_INSIDE_DATA_OUTSIDE,
296 "vb2_packed_key_inside() offset too big");
297 }
298
299 {
300 struct vb2_signature s = {.sig_offset = sizeof(s),
301 .sig_size = 128};
302 const void *lower_base;
303 TEST_SUCC(vb2_verify_signature_inside(&s, sizeof(s)+128, &s),
304 "vb2_verify_signature_inside() ok 1");
305 lower_base = (const void *)((uintptr_t)&s - sizeof(s));
306 TEST_SUCC(vb2_verify_signature_inside(lower_base,
307 2*sizeof(s)+128, &s),
308 "vb2_verify_signature_inside() ok 2");
309 TEST_EQ(vb2_verify_signature_inside(&s, 128, &s),
310 VB2_ERROR_INSIDE_DATA_OUTSIDE,
311 "vb2_verify_signature_inside() sig too big");
312 }
313
314 {
315 struct vb2_signature s = {.sig_offset = 100,
316 .sig_size = 4};
317 TEST_EQ(vb2_verify_signature_inside(&s, 99, &s),
318 VB2_ERROR_INSIDE_DATA_OUTSIDE,
319 "vb2_verify_signature_inside() offset too big");
320 }
321 }
322
323 /* Helper for test_assert_die() below */
_true_assertion_helper(void)324 static int _true_assertion_helper(void)
325 {
326 VB2_ASSERT(2 + 2 == 4);
327 return 1;
328 }
329
330 /**
331 * Test VB2_ASSERT and VB2_DIE macros
332 */
test_assert_die(void)333 static void test_assert_die(void)
334 {
335 TEST_ABORT(VB2_DIE("die"), "DIE should abort");
336 TEST_ABORT(VB2_ASSERT(2 + 2 == 5), "ASSERT false should abort");
337 TEST_TRUE(_true_assertion_helper(), "ASSERT true should continue");
338 }
339
main(int argc,char * argv[])340 int main(int argc, char* argv[])
341 {
342 test_arithmetic();
343 test_array_size();
344 test_struct_packing();
345 test_memcmp();
346 test_align();
347 test_workbuf();
348 test_helper_functions();
349 test_assert_die();
350
351 return gTestSuccess ? 0 : 255;
352 }
353