xref: /aosp_15_r20/external/vboot_reference/tests/vb2_common_tests.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
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