xref: /aosp_15_r20/external/vboot_reference/tests/vb2_misc_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 misc library
6  */
7 
8 #include "2api.h"
9 #include "2common.h"
10 #include "2misc.h"
11 #include "2nvstorage.h"
12 #include "2secdata.h"
13 #include "2sysincludes.h"
14 #include "common/boot_mode.h"
15 #include "common/tests.h"
16 
17 /* Common context for tests */
18 static uint8_t workbuf[VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE]
19 	__attribute__((aligned(VB2_WORKBUF_ALIGN)));
20 static uint8_t workbuf2[VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE]
21 	__attribute__((aligned(VB2_WORKBUF_ALIGN)));
22 static struct vb2_context *ctx;
23 static struct vb2_shared_data *sd;
24 static struct vb2_gbb_header gbb;
25 static struct vb2_secdata_fwmp *fwmp;
26 
27 /* Mocked function data */
28 static enum vb2_resource_index mock_resource_index;
29 static void *mock_resource_ptr;
30 static uint32_t mock_resource_size;
31 static int mock_tpm_clear_called;
32 static int mock_tpm_clear_retval;
33 
reset_common_data(void)34 static void reset_common_data(void)
35 {
36 	memset(workbuf, 0xaa, sizeof(workbuf));
37 	memset(workbuf2, 0xbb, sizeof(workbuf2));
38 
39 	TEST_SUCC(vb2api_init(workbuf, sizeof(workbuf), &ctx),
40 		  "vb2api_init failed");
41 
42 	sd = vb2_get_sd(ctx);
43 	sd->status |= VB2_SD_STATUS_SECDATA_FWMP_INIT;
44 
45 	memset(&gbb, 0, sizeof(gbb));
46 
47 	vb2_nv_init(ctx);
48 
49 	vb2api_secdata_firmware_create(ctx);
50 	vb2_secdata_firmware_init(ctx);
51 
52 	fwmp = (struct vb2_secdata_fwmp *)&ctx->secdata_fwmp;
53 
54 	mock_tpm_clear_called = 0;
55 	mock_tpm_clear_retval = VB2_SUCCESS;
56 
57 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_NORMAL);
58 };
59 
60 /* Mocked functions */
61 
vb2_get_gbb(struct vb2_context * c)62 struct vb2_gbb_header *vb2_get_gbb(struct vb2_context *c)
63 {
64 	return &gbb;
65 }
66 
vb2ex_read_resource(struct vb2_context * c,enum vb2_resource_index index,uint32_t offset,void * buf,uint32_t size)67 vb2_error_t vb2ex_read_resource(struct vb2_context *c,
68 				enum vb2_resource_index index, uint32_t offset,
69 				void *buf, uint32_t size)
70 {
71 	if (index != mock_resource_index)
72 		return VB2_ERROR_EX_READ_RESOURCE_INDEX;
73 
74 	if (offset > mock_resource_size || offset + size > mock_resource_size)
75 		return VB2_ERROR_EX_READ_RESOURCE_SIZE;
76 
77 	memcpy(buf, (uint8_t *)mock_resource_ptr + offset, size);
78 	return VB2_SUCCESS;
79 }
80 
vb2ex_tpm_clear_owner(struct vb2_context * c)81 vb2_error_t vb2ex_tpm_clear_owner(struct vb2_context *c)
82 {
83 	mock_tpm_clear_called++;
84 
85 	return mock_tpm_clear_retval;
86 }
87 
88 /* Tests */
init_workbuf_tests(void)89 static void init_workbuf_tests(void)
90 {
91 	struct vb2_context *orig_ctx;
92 
93 	/* check constants */
94 	TEST_TRUE(sizeof(struct vb2_context) < VB2_CONTEXT_MAX_SIZE,
95 		  "vb2_context max size constant");
96 
97 	/* vb2api_init() - misaligned */
98 	TEST_EQ(vb2api_init(workbuf + 1, sizeof(workbuf) - 1, &ctx),
99 		VB2_ERROR_WORKBUF_ALIGN, "vb2api_init - misaligned");
100 
101 	/* vb2api_init() - size too small */
102 	TEST_EQ(vb2api_init(workbuf, sizeof(struct vb2_shared_data) - 1,
103 			      &ctx), VB2_ERROR_WORKBUF_SMALL,
104 		"vb2api_init - size too small");
105 
106 	/* vb2api_init() - success */
107 	TEST_SUCC(vb2api_init(workbuf, sizeof(workbuf), &ctx),
108 		  "vb2api_init - success");
109 	TEST_TRUE((uintptr_t)workbuf < (uintptr_t)ctx &&
110 		  (uintptr_t)ctx < (uintptr_t)workbuf + sizeof(workbuf),
111 		  "  return proper pointer");
112 	struct vb2_context zero_ctx = {0};
113 	TEST_SUCC(memcmp(ctx, &zero_ctx, sizeof(struct vb2_context)),
114 		  "  vb2_context set to zero");
115 	sd = vb2_get_sd(ctx);
116 	TEST_EQ(sd->magic, VB2_SHARED_DATA_MAGIC, "  set magic");
117 	TEST_EQ(sd->struct_version_major, VB2_SHARED_DATA_VERSION_MAJOR,
118 		"  set major version");
119 	TEST_EQ(sd->struct_version_minor, VB2_SHARED_DATA_VERSION_MINOR,
120 		"  set minor version");
121 	TEST_EQ(sd->workbuf_size, sizeof(workbuf), "  set workbuf size");
122 	TEST_TRUE(sd->workbuf_used - sizeof(struct vb2_shared_data)
123 		  < VB2_WORKBUF_ALIGN, "  set workbuf used");
124 
125 	/* vb2api_relocate() - misaligned source */
126 	reset_common_data();
127 	memmove(workbuf + 1, workbuf, sizeof(workbuf) - 1);
128 	TEST_SUCC(vb2api_relocate(workbuf2, workbuf + 1, sizeof(workbuf) - 1,
129 				  &ctx), "vb2api_relocate - misaligned source");
130 
131 	/* vb2api_relocate() - misaligned target */
132 	reset_common_data();
133 	TEST_EQ(vb2api_relocate(workbuf2 + 1, workbuf, sizeof(workbuf) - 1,
134 				&ctx),
135 		VB2_ERROR_WORKBUF_ALIGN, "vb2api_relocate - misaligned target");
136 
137 	/* vb2api_relocate() - bad magic */
138 	reset_common_data();
139 	sd->magic = 0;
140 	TEST_EQ(vb2api_relocate(workbuf2, workbuf, sizeof(workbuf), &ctx),
141 		VB2_ERROR_SHARED_DATA_MAGIC, "vb2api_relocate - bad magic");
142 
143 	/* vb2api_relocate() - small major version */
144 	reset_common_data();
145 	sd->struct_version_major--;
146 	TEST_EQ(vb2api_relocate(workbuf2, workbuf, sizeof(workbuf), &ctx),
147 		VB2_ERROR_SHARED_DATA_VERSION,
148 		"vb2api_relocate - small major version");
149 
150 	/* vb2api_relocate() - big major version */
151 	reset_common_data();
152 	sd->struct_version_major++;
153 	TEST_EQ(vb2api_relocate(workbuf2, workbuf, sizeof(workbuf), &ctx),
154 		VB2_ERROR_SHARED_DATA_VERSION,
155 		"vb2api_relocate - big major version");
156 
157 	/* vb2api_relocate() - small minor version */
158 	if (VB2_SHARED_DATA_VERSION_MINOR > 0) {
159 		reset_common_data();
160 		sd->struct_version_minor--;
161 		TEST_EQ(vb2api_relocate(workbuf2, workbuf, sizeof(workbuf),
162 					&ctx),
163 			VB2_ERROR_SHARED_DATA_VERSION,
164 			  "vb2api_relocate - small minor version");
165 	}
166 
167 	/* vb2api_relocate() - big minor version */
168 	reset_common_data();
169 	sd->struct_version_minor++;
170 	TEST_SUCC(vb2api_relocate(workbuf2, workbuf, sizeof(workbuf), &ctx),
171 		  "vb2api_relocate - big minor version");
172 
173 	/* vb2api_relocate() - small workbuf_used */
174 	reset_common_data();
175 	sd->workbuf_used = sizeof(struct vb2_shared_data) - 1;
176 	TEST_EQ(vb2api_relocate(workbuf2, workbuf, sizeof(workbuf), &ctx),
177 		VB2_ERROR_WORKBUF_INVALID,
178 		"vb2api_relocate - small workbuf_used");
179 
180 	/* vb2api_relocate() - workbuf_size < workbuf_used */
181 	reset_common_data();
182 	sd->workbuf_used = sd->workbuf_size;
183 	sd->workbuf_size--;
184 	TEST_EQ(vb2api_relocate(workbuf2, workbuf, sizeof(workbuf), &ctx),
185 		VB2_ERROR_WORKBUF_INVALID,
186 		"vb2api_relocate - workbuf_size < workbuf_used");
187 
188 	/* vb2api_relocate() - target workbuf too small */
189 	reset_common_data();
190 	sd->workbuf_used = sd->workbuf_size - 1;
191 	TEST_EQ(vb2api_relocate(workbuf2, workbuf, sd->workbuf_used - 1, &ctx),
192 		VB2_ERROR_WORKBUF_SMALL,
193 		"vb2api_relocate - target workbuf too small");
194 
195 	/* vb2api_relocate() - success (same size) */
196 	reset_common_data();
197 	orig_ctx = ctx;
198 	TEST_SUCC(vb2api_relocate(workbuf2, workbuf, sizeof(workbuf), &ctx),
199 		  "vb2api_relocate - success (same size)");
200 	sd = vb2_get_sd(ctx);
201 	TEST_EQ((uintptr_t)orig_ctx - (uintptr_t)workbuf,
202 		(uintptr_t)ctx - (uintptr_t)workbuf2,
203 		"  same context pointer");
204 	TEST_SUCC(memcmp(workbuf2, workbuf, sd->workbuf_used),
205 		  "  same workbuf");
206 
207 	/* vb2api_relocate() - success (smaller size) */
208 	reset_common_data();
209 	TEST_SUCC(vb2api_relocate(workbuf2, workbuf, sizeof(workbuf) - 1, &ctx),
210 		  "vb2api_relocate - success (smaller size)");
211 	sd = vb2_get_sd(ctx);
212 	TEST_EQ(sd->workbuf_size, sizeof(workbuf) - 1, "  set workbuf size");
213 
214 	/* vb2api_relocate() - success (larger size) */
215 	reset_common_data();
216 	sd->workbuf_size--;
217 	TEST_SUCC(vb2api_relocate(workbuf2, workbuf, sizeof(workbuf), &ctx),
218 		  "vb2api_relocate - success (larger size)");
219 	sd = vb2_get_sd(ctx);
220 	TEST_EQ(sd->workbuf_size, sizeof(workbuf), "  set workbuf size");
221 
222 	/* vb2api_relocate() - success (overlapping) */
223 	reset_common_data();
224 	orig_ctx = ctx;
225 	sd->workbuf_size -= VB2_WORKBUF_ALIGN;
226 	memcpy(workbuf2, workbuf, sd->workbuf_used);
227 	TEST_SUCC(vb2api_relocate(workbuf + VB2_WORKBUF_ALIGN, workbuf,
228 				  sizeof(workbuf) - VB2_WORKBUF_ALIGN, &ctx),
229 		  "vb2api_relocate - success (overlapping)");
230 	sd = vb2_get_sd(ctx);
231 	TEST_EQ((uintptr_t)ctx - (uintptr_t)orig_ctx,
232 		VB2_WORKBUF_ALIGN,
233 		"  context pointer moved");
234 	TEST_SUCC(memcmp(workbuf2, workbuf + VB2_WORKBUF_ALIGN,
235 			 sd->workbuf_used), "  same workbuf");
236 
237 	/* vb2api_reinit() - workbuf_size < workbuf_used */
238 	reset_common_data();
239 	sd->workbuf_size = sd->workbuf_used - 1;
240 	TEST_EQ(vb2api_reinit(workbuf, &ctx), VB2_ERROR_WORKBUF_INVALID,
241 		"vb2api_reinit - workbuf_size < workbuf_used");
242 
243 	/* vb2api_reinit() - success */
244 	reset_common_data();
245 	orig_ctx = ctx;
246 	TEST_SUCC(vb2api_reinit(workbuf, &ctx),
247 		  "vb2api_reinit - success");
248 	TEST_EQ((uintptr_t)ctx, (uintptr_t)orig_ctx,
249 		"  context pointer unchanged");
250 }
251 
misc_tests(void)252 static void misc_tests(void)
253 {
254 	struct vb2_workbuf wb;
255 
256 	reset_common_data();
257 	sd->workbuf_used = VB2_WORKBUF_ALIGN;
258 
259 	vb2_workbuf_from_ctx(ctx, &wb);
260 
261 	TEST_PTR_EQ(wb.buf, workbuf + VB2_WORKBUF_ALIGN,
262 		    "vb_workbuf_from_ctx() buf");
263 	TEST_EQ(wb.size, sd->workbuf_size - VB2_WORKBUF_ALIGN,
264 		"vb_workbuf_from_ctx() size");
265 
266 	reset_common_data();
267 	sd->status |= VB2_SD_STATUS_RECOVERY_DECIDED;
268 	TEST_ABORT(VB2_REC_OR_DIE(ctx, "die\n"), "REC_OR_DIE in normal mode");
269 
270 	reset_common_data();
271 	sd->status |= VB2_SD_STATUS_RECOVERY_DECIDED;
272 	ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
273 	VB2_REC_OR_DIE(ctx, "VB2_REC_OR_DIE() test in recovery mode\n");
274 	/* Would exit here if it didn't work as intended. */
275 
276 	reset_common_data();
277 	VB2_REC_OR_DIE(ctx, "VB2_REC_OR_DIE() test in fw_phase1\n");
278 }
279 
gbb_tests(void)280 static void gbb_tests(void)
281 {
282 	struct vb2_gbb_header gbbsrc = {
283 		.signature = {'$', 'G', 'B', 'B'},
284 		.major_version = VB2_GBB_MAJOR_VER,
285 		.minor_version = VB2_GBB_MINOR_VER,
286 		.header_size = sizeof(struct vb2_gbb_header),
287 		.flags = 0x1234,
288 		.rootkey_offset = 240,
289 		.rootkey_size = 1040,
290 	};
291 
292 	struct vb2_gbb_header gbbdest;
293 
294 	TEST_EQ(sizeof(struct vb2_gbb_header),
295 		EXPECTED_VB2_GBB_HEADER_SIZE,
296 		"sizeof(struct vb2_gbb_header)");
297 
298 	reset_common_data();
299 
300 	/* Good contents */
301 	mock_resource_index = VB2_RES_GBB;
302 	mock_resource_ptr = &gbbsrc;
303 	mock_resource_size = sizeof(gbbsrc);
304 	TEST_SUCC(vb2_read_gbb_header(ctx, &gbbdest), "read gbb header good");
305 	TEST_SUCC(memcmp(&gbbsrc, &gbbdest, sizeof(gbbsrc)),
306 		  "read gbb contents");
307 
308 	mock_resource_index = VB2_RES_GBB + 1;
309 	TEST_EQ(vb2_read_gbb_header(ctx, &gbbdest),
310 		VB2_ERROR_EX_READ_RESOURCE_INDEX, "read gbb header missing");
311 	mock_resource_index = VB2_RES_GBB;
312 
313 	gbbsrc.signature[0]++;
314 	TEST_EQ(vb2_read_gbb_header(ctx, &gbbdest),
315 		VB2_ERROR_GBB_MAGIC, "read gbb header bad magic");
316 	gbbsrc.signature[0]--;
317 
318 	gbbsrc.major_version = VB2_GBB_MAJOR_VER + 1;
319 	TEST_EQ(vb2_read_gbb_header(ctx, &gbbdest),
320 		VB2_ERROR_GBB_VERSION, "read gbb header major version");
321 	gbbsrc.major_version = VB2_GBB_MAJOR_VER;
322 
323 	gbbsrc.minor_version = VB2_GBB_MINOR_VER + 1;
324 	TEST_SUCC(vb2_read_gbb_header(ctx, &gbbdest),
325 		  "read gbb header minor++");
326 	gbbsrc.minor_version = 1;
327 	TEST_EQ(vb2_read_gbb_header(ctx, &gbbdest),
328 		VB2_ERROR_GBB_TOO_OLD, "read gbb header 1.1 fails");
329 	gbbsrc.minor_version = 0;
330 	TEST_EQ(vb2_read_gbb_header(ctx, &gbbdest),
331 		VB2_ERROR_GBB_TOO_OLD, "read gbb header 1.0 fails");
332 	gbbsrc.minor_version = VB2_GBB_MINOR_VER;
333 
334 	gbbsrc.header_size--;
335 	TEST_EQ(vb2_read_gbb_header(ctx, &gbbdest),
336 		VB2_ERROR_GBB_HEADER_SIZE, "read gbb header size");
337 	TEST_EQ(vb2_fw_init_gbb(ctx),
338 		VB2_ERROR_GBB_HEADER_SIZE, "init gbb failure");
339 	gbbsrc.header_size++;
340 
341 	/* Init GBB */
342 	int used_before = sd->workbuf_used;
343 	TEST_SUCC(vb2_fw_init_gbb(ctx), "init gbb");
344 	/* Manually calculate the location of GBB since we have mocked out the
345 	   original definition of vb2_get_gbb. */
346 	struct vb2_gbb_header *current_gbb = vb2_member_of(sd, sd->gbb_offset);
347 	TEST_SUCC(memcmp(&gbbsrc, current_gbb, sizeof(gbbsrc)),
348 		  "  copy gbb contents");
349 	TEST_TRUE(sd->workbuf_used - sizeof(gbbsrc) - used_before
350 		  < VB2_WORKBUF_ALIGN, "  unexpected workbuf size");
351 
352 	/* Workbuf failure */
353 	reset_common_data();
354 	sd->workbuf_used = sd->workbuf_size - 4;
355 	TEST_EQ(vb2_fw_init_gbb(ctx),
356 		VB2_ERROR_GBB_WORKBUF, "init gbb no workbuf");
357 
358 	/* Check for setting NO_SECDATA_FWMP context flag */
359 	reset_common_data();
360 	TEST_SUCC(vb2_fw_init_gbb(ctx), "init gbb");
361 	TEST_EQ(ctx->flags & VB2_CONTEXT_NO_SECDATA_FWMP, 0,
362 		"without DISABLE_FWMP: NO_SECDATA_FWMP shouldn't be set");
363 	reset_common_data();
364 	gbbsrc.flags |= VB2_GBB_FLAG_DISABLE_FWMP;
365 	TEST_SUCC(vb2_fw_init_gbb(ctx), "init gbb");
366 	TEST_NEQ(ctx->flags & VB2_CONTEXT_NO_SECDATA_FWMP, 0,
367 		 "with DISABLE_FWMP: NO_SECDATA_FWMP should be set");
368 }
369 
fail_tests(void)370 static void fail_tests(void)
371 {
372 	/* Early fail (before even NV init) */
373 	reset_common_data();
374 	sd->status &= ~VB2_SD_STATUS_NV_INIT;
375 	vb2api_fail(ctx, 1, 2);
376 	TEST_NEQ(sd->status & VB2_SD_STATUS_NV_INIT, 0, "vb2api_fail inits NV");
377 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
378 		1, "vb2api_fail request");
379 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_SUBCODE),
380 		2, "vb2api_fail subcode");
381 
382 	/* Repeated fail doesn't overwrite the error code */
383 	vb2api_fail(ctx, 3, 4);
384 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
385 		1, "vb2api_fail repeat");
386 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_SUBCODE),
387 		2, "vb2api_fail repeat2");
388 
389 	/* Fail with other slot good doesn't trigger recovery */
390 	reset_common_data();
391 	vb2_nv_set(ctx, VB2_NV_TRY_COUNT, 3);
392 	vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_UNKNOWN);
393 	vb2_nv_set(ctx, VB2_NV_FW_TRIED, 0);
394 	vb2_nv_set(ctx, VB2_NV_FW_PREV_TRIED, 1);
395 	vb2_nv_set(ctx, VB2_NV_FW_PREV_RESULT, VB2_FW_RESULT_UNKNOWN);
396 	sd->status |= VB2_SD_STATUS_CHOSE_SLOT;
397 	vb2api_fail(ctx, 5, 6);
398 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST), 0, "vb2_failover");
399 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_RESULT),
400 		VB2_FW_RESULT_FAILURE, "vb2api_fail this fw");
401 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_COUNT), 0,
402 		"vb2api_fail use up tries");
403 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_NEXT), 1,
404 		"vb2api_fail try other slot");
405 
406 	/* Fail with other slot already failing triggers recovery */
407 	reset_common_data();
408 	vb2_nv_set(ctx, VB2_NV_FW_PREV_TRIED, 0);
409 	vb2_nv_set(ctx, VB2_NV_FW_PREV_RESULT, VB2_FW_RESULT_FAILURE);
410 	vb2_nv_set(ctx, VB2_NV_FW_TRIED, 1);
411 	sd->status |= VB2_SD_STATUS_CHOSE_SLOT;
412 	vb2api_fail(ctx, 7, 8);
413 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST), 7,
414 		"vb2api_fail both slots bad");
415 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_RESULT),
416 		VB2_FW_RESULT_FAILURE, "vb2api_fail this fw");
417 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_NEXT), 0,
418 		"vb2api_fail try other slot");
419 
420 	/* Fail with single slot already failing triggers recovery */
421 	reset_common_data();
422 	vb2_nv_set(ctx, VB2_NV_FW_PREV_TRIED, 0);
423 	vb2_nv_set(ctx, VB2_NV_FW_TRIED, 0);
424 	vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_TRYING);
425 	ctx->flags |= VB2_CONTEXT_SLOT_A_ONLY;
426 	sd->status |= VB2_SD_STATUS_CHOSE_SLOT;
427 	vb2api_fail(ctx, 9, 10);
428 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST), 9,
429 		"vb2api_fail single slot fail");
430 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_RESULT),
431 		VB2_FW_RESULT_FAILURE, "vb2api_fail this fw");
432 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_NEXT), 0,
433 		"vb2api_fail did not try other slot");
434 }
435 
previous_boot_fail_tests(void)436 static void previous_boot_fail_tests(void)
437 {
438 	/* Previous boot fail (before even NV init) */
439 	/* Fail with other slot good doesn't trigger recovery */
440 	reset_common_data();
441 	vb2_nv_set(ctx, VB2_NV_FW_TRIED, VB2_FW_SLOT_A);
442 	vb2_nv_set(ctx, VB2_NV_TRY_COUNT, 3);
443 	vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_UNKNOWN);
444 	sd->status &= ~VB2_SD_STATUS_NV_INIT;
445 	vb2api_previous_boot_fail(ctx, 1, 2);
446 	TEST_NEQ(sd->status & VB2_SD_STATUS_NV_INIT,
447 		 0, "vb2api_previous_boot_fail inits NV");
448 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
449 		0, "vb2_previous_boot_fail over");
450 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_RESULT),
451 		VB2_FW_RESULT_FAILURE, "vb2api_previous_boot_fail result");
452 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_COUNT),
453 		0, "vb2api_previous_boot_fail try count");
454 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_NEXT),
455 		1, "vb2api_previous_boot_fail FW tried");
456 
457 	/* Fail with other slot already failing triggers recovery */
458 	reset_common_data();
459 	vb2_nv_set(ctx, VB2_NV_FW_PREV_TRIED, VB2_FW_SLOT_A);
460 	vb2_nv_set(ctx, VB2_NV_FW_PREV_RESULT, VB2_FW_RESULT_FAILURE);
461 	vb2_nv_set(ctx, VB2_NV_FW_TRIED, VB2_FW_SLOT_B);
462 	vb2_nv_set(ctx, VB2_NV_TRY_COUNT, 3);
463 	vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_UNKNOWN);
464 	sd->status &= ~VB2_SD_STATUS_NV_INIT;
465 	vb2api_previous_boot_fail(ctx, 3, 4);
466 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
467 		3, "vb2api_previous_boot_fail both slots bad");
468 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_RESULT),
469 		VB2_FW_RESULT_FAILURE, "vb2api_previous_boot_fail result");
470 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_COUNT),
471 		0, "vb2api_previous_boot_fail try count");
472 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_NEXT),
473 		0, "vb2api_previous_boot_fail FW tried");
474 
475 	/* Repeated fail doesn't overwrite the error code */
476 	reset_common_data();
477 	vb2_nv_set(ctx, VB2_NV_TRY_NEXT, VB2_FW_SLOT_A);
478 	vb2_nv_set(ctx, VB2_NV_TRY_COUNT, 3);
479 	vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_FAILURE);
480 	sd->status &= ~VB2_SD_STATUS_NV_INIT;
481 	vb2api_previous_boot_fail(ctx, 5, 6);
482 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_RESULT),
483 		VB2_FW_RESULT_FAILURE, "vb2api_previous_boot_fail result");
484 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_COUNT),
485 		3, "vb2api_previous_boot_fail try count");
486 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_NEXT),
487 		VB2_FW_SLOT_A, "vb2api_previous_boot_fail try next");
488 }
489 
recovery_tests(void)490 static void recovery_tests(void)
491 {
492 	/* No recovery */
493 	reset_common_data();
494 	TEST_EQ(sd->status & VB2_SD_STATUS_RECOVERY_DECIDED,
495 		0, "recovery not yet decided before testing check_recovery()");
496 	vb2_check_recovery(ctx);
497 	TEST_EQ(sd->recovery_reason, 0, "No recovery reason");
498 	TEST_EQ(ctx->flags & VB2_CONTEXT_RECOVERY_MODE,
499 		0, "Not recovery mode");
500 	TEST_NEQ(sd->status & VB2_SD_STATUS_RECOVERY_DECIDED,
501 		 0, "Recovery decided");
502 
503 	/* From request */
504 	reset_common_data();
505 	vb2_nv_set(ctx, VB2_NV_RECOVERY_REQUEST, 3);
506 	vb2_check_recovery(ctx);
507 	TEST_EQ(sd->recovery_reason, 3, "Recovery reason from request");
508 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST), 3, "NV not cleared");
509 	TEST_NEQ(ctx->flags & VB2_CONTEXT_RECOVERY_MODE,
510 		 0, "Recovery mode");
511 	TEST_NEQ(sd->status & VB2_SD_STATUS_RECOVERY_DECIDED,
512 		 0, "Recovery decided");
513 
514 	/* From request, but already failed */
515 	reset_common_data();
516 	vb2_nv_set(ctx, VB2_NV_RECOVERY_REQUEST, 4);
517 	sd->recovery_reason = 5;
518 	vb2_check_recovery(ctx);
519 	TEST_EQ(sd->recovery_reason, 5, "Recovery reason already failed");
520 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
521 		4, "NV not cleared");
522 	TEST_NEQ(sd->status & VB2_SD_STATUS_RECOVERY_DECIDED,
523 		 0, "Recovery decided");
524 
525 	/* Override */
526 	reset_common_data();
527 	sd->recovery_reason = 6;
528 	ctx->flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
529 	vb2_check_recovery(ctx);
530 	TEST_EQ(sd->recovery_reason, VB2_RECOVERY_RO_MANUAL,
531 		"Recovery reason forced");
532 	TEST_NEQ(sd->status & VB2_SD_STATUS_RECOVERY_DECIDED,
533 		 0, "Recovery decided");
534 
535 	/* Override subcode TRAIN_AND_REBOOT */
536 	reset_common_data();
537 	vb2_nv_set(ctx, VB2_NV_RECOVERY_SUBCODE, VB2_RECOVERY_TRAIN_AND_REBOOT);
538 	ctx->flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
539 	vb2_check_recovery(ctx);
540 	TEST_EQ(sd->recovery_reason, VB2_RECOVERY_RO_MANUAL,
541 		"Recovery reason forced");
542 	TEST_NEQ(sd->status & VB2_SD_STATUS_RECOVERY_DECIDED,
543 		 0, "Recovery decided");
544 
545 	/* Promote subcode from BROKEN screen*/
546 	reset_common_data();
547 	vb2_nv_set(ctx, VB2_NV_RECOVERY_SUBCODE, VB2_RECOVERY_US_TEST);
548 	ctx->flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
549 	vb2_check_recovery(ctx);
550 	TEST_EQ(sd->recovery_reason, VB2_RECOVERY_US_TEST,
551 		"Recovery reason forced from BROKEN");
552 	TEST_NEQ(sd->status & VB2_SD_STATUS_RECOVERY_DECIDED,
553 		 0, "Recovery decided");
554 }
555 
dev_switch_tests(void)556 static void dev_switch_tests(void)
557 {
558 	uint32_t v;
559 
560 	/* Normal mode */
561 	reset_common_data();
562 	TEST_SUCC(vb2_check_dev_switch(ctx), "dev mode off");
563 	TEST_EQ(sd->flags & VB2_SD_FLAG_DEV_MODE_ENABLED, 0, "  sd not in dev");
564 	TEST_EQ(ctx->flags & VB2_CONTEXT_DEVELOPER_MODE, 0, "  ctx not in dev");
565 	TEST_EQ(mock_tpm_clear_called, 0, "  no tpm clear");
566 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_REQ_WIPEOUT), 0, "  no nv wipeout");
567 
568 	/* Dev mode */
569 	reset_common_data();
570 	vb2_secdata_firmware_set(
571 		ctx, VB2_SECDATA_FIRMWARE_FLAGS,
572 		(VB2_SECDATA_FIRMWARE_FLAG_DEV_MODE |
573 		 VB2_SECDATA_FIRMWARE_FLAG_LAST_BOOT_DEVELOPER));
574 	TEST_SUCC(vb2_check_dev_switch(ctx), "dev mode on");
575 	TEST_NEQ(sd->flags & VB2_SD_FLAG_DEV_MODE_ENABLED, 0, "  sd in dev");
576 	TEST_NEQ(ctx->flags & VB2_CONTEXT_DEVELOPER_MODE, 0, "  ctx in dev");
577 	TEST_EQ(mock_tpm_clear_called, 0, "  no tpm clear");
578 
579 	/* Any normal mode boot clears dev boot flags */
580 	reset_common_data();
581 	vb2_nv_set(ctx, VB2_NV_DEV_BOOT_EXTERNAL, 1);
582 	vb2_nv_set(ctx, VB2_NV_DEV_BOOT_ALTFW, 1);
583 	vb2_nv_set(ctx, VB2_NV_DEV_BOOT_SIGNED_ONLY, 1);
584 	vb2_nv_set(ctx, VB2_NV_DEV_DEFAULT_BOOT, 1);
585 	TEST_SUCC(vb2_check_dev_switch(ctx), "dev mode off");
586 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_DEV_BOOT_EXTERNAL),
587 		0, "  cleared dev boot external");
588 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_DEV_BOOT_ALTFW),
589 		0, "  cleared dev boot altfw");
590 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_DEV_BOOT_SIGNED_ONLY),
591 		0, "  cleared dev boot signed only");
592 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_DEV_DEFAULT_BOOT),
593 		0, "  cleared dev default boot");
594 
595 	/* Normal-dev transition clears TPM */
596 	reset_common_data();
597 	vb2_secdata_firmware_set(ctx, VB2_SECDATA_FIRMWARE_FLAGS,
598 				 VB2_SECDATA_FIRMWARE_FLAG_DEV_MODE);
599 	TEST_SUCC(vb2_check_dev_switch(ctx), "to dev mode");
600 	TEST_EQ(mock_tpm_clear_called, 1, "  tpm clear");
601 	v = vb2_secdata_firmware_get(ctx, VB2_SECDATA_FIRMWARE_FLAGS);
602 	TEST_EQ(v, (VB2_SECDATA_FIRMWARE_FLAG_DEV_MODE |
603 		    VB2_SECDATA_FIRMWARE_FLAG_LAST_BOOT_DEVELOPER),
604 		"  last boot developer now");
605 
606 	/* Dev-normal transition clears TPM too */
607 	reset_common_data();
608 	vb2_secdata_firmware_set(ctx, VB2_SECDATA_FIRMWARE_FLAGS,
609 				 VB2_SECDATA_FIRMWARE_FLAG_LAST_BOOT_DEVELOPER);
610 	TEST_SUCC(vb2_check_dev_switch(ctx), "from dev mode");
611 	TEST_EQ(mock_tpm_clear_called, 1, "  tpm clear");
612 	v = vb2_secdata_firmware_get(ctx, VB2_SECDATA_FIRMWARE_FLAGS);
613 	TEST_EQ(v, 0, "  last boot not developer now");
614 
615 	/* Disable dev mode */
616 	reset_common_data();
617 	vb2_secdata_firmware_set(
618 		ctx, VB2_SECDATA_FIRMWARE_FLAGS,
619 		(VB2_SECDATA_FIRMWARE_FLAG_DEV_MODE |
620 		 VB2_SECDATA_FIRMWARE_FLAG_LAST_BOOT_DEVELOPER));
621 	vb2_nv_set(ctx, VB2_NV_DISABLE_DEV_REQUEST, 1);
622 	TEST_SUCC(vb2_check_dev_switch(ctx), "disable dev request");
623 	TEST_EQ(sd->flags & VB2_SD_FLAG_DEV_MODE_ENABLED, 0, "  sd not in dev");
624 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_DISABLE_DEV_REQUEST),
625 		0, "  request cleared");
626 
627 	/* Force enabled by GBB */
628 	reset_common_data();
629 	gbb.flags |= VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON;
630 	TEST_SUCC(vb2_check_dev_switch(ctx), "dev on via gbb");
631 	TEST_NEQ(sd->flags & VB2_SD_FLAG_DEV_MODE_ENABLED, 0, "  sd in dev");
632 	v = vb2_secdata_firmware_get(ctx, VB2_SECDATA_FIRMWARE_FLAGS);
633 	TEST_EQ(v, VB2_SECDATA_FIRMWARE_FLAG_LAST_BOOT_DEVELOPER,
634 		"  doesn't set dev on in secdata_firmware "
635 		"but does set last boot dev");
636 	TEST_EQ(mock_tpm_clear_called, 1, "  tpm clear");
637 
638 	/* Request disable by ctx flag */
639 	reset_common_data();
640 	vb2_secdata_firmware_set(
641 		ctx, VB2_SECDATA_FIRMWARE_FLAGS,
642 		(VB2_SECDATA_FIRMWARE_FLAG_DEV_MODE |
643 		 VB2_SECDATA_FIRMWARE_FLAG_LAST_BOOT_DEVELOPER));
644 	ctx->flags |= VB2_CONTEXT_DISABLE_DEVELOPER_MODE;
645 	TEST_SUCC(vb2_check_dev_switch(ctx), "disable dev on ctx request");
646 	TEST_EQ(sd->flags & VB2_SD_FLAG_DEV_MODE_ENABLED, 0, "  sd not in dev");
647 
648 	/* Simulate clear owner failure */
649 	reset_common_data();
650 	vb2_secdata_firmware_set(ctx, VB2_SECDATA_FIRMWARE_FLAGS,
651 				 VB2_SECDATA_FIRMWARE_FLAG_LAST_BOOT_DEVELOPER);
652 	mock_tpm_clear_retval = VB2_ERROR_EX_TPM_CLEAR_OWNER;
653 	TEST_EQ(vb2_check_dev_switch(ctx),
654 		VB2_ERROR_EX_TPM_CLEAR_OWNER, "tpm clear fail");
655 	TEST_EQ(mock_tpm_clear_called, 1, "  tpm clear");
656 	v = vb2_secdata_firmware_get(ctx, VB2_SECDATA_FIRMWARE_FLAGS);
657 	TEST_EQ(v, VB2_SECDATA_FIRMWARE_FLAG_LAST_BOOT_DEVELOPER,
658 		"  last boot still developer");
659 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
660 		VB2_RECOVERY_TPM_CLEAR_OWNER, "  requests recovery");
661 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_SUBCODE),
662 		(uint8_t)VB2_ERROR_EX_TPM_CLEAR_OWNER, "  recovery subcode");
663 
664 	/*
665 	 * secdata_firmware failure in normal mode fails and shows dev=0 even
666 	 * if dev mode was on in the (inaccessible) secdata_firmware. Since this
667 	 * happens in fw_phase1, we do not abort -- we know that when secdata
668 	 * is uninitialized here, we must be headed for recovery mode.
669 	 */
670 	reset_common_data();
671 	vb2_secdata_firmware_set(ctx, VB2_SECDATA_FIRMWARE_FLAGS,
672 				 VB2_SECDATA_FIRMWARE_FLAG_DEV_MODE);
673 	sd->status &= ~VB2_SD_STATUS_SECDATA_FIRMWARE_INIT;
674 	TEST_SUCC(vb2_check_dev_switch(ctx), "secdata_firmware fail normal");
675 	TEST_EQ(sd->flags & VB2_SD_FLAG_DEV_MODE_ENABLED, 0, "  sd not in dev");
676 	TEST_EQ(ctx->flags & VB2_CONTEXT_DEVELOPER_MODE, 0, "  ctx not in dev");
677 
678 	/* secdata_firmware failure in recovery mode continues */
679 	reset_common_data();
680 	ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
681 	sd->status &= ~VB2_SD_STATUS_SECDATA_FIRMWARE_INIT;
682 	TEST_SUCC(vb2_check_dev_switch(ctx), "secdata_firmware fail recovery");
683 	TEST_EQ(sd->flags & VB2_SD_FLAG_DEV_MODE_ENABLED, 0, "  sd not in dev");
684 	TEST_EQ(ctx->flags & VB2_CONTEXT_DEVELOPER_MODE, 0, "  ctx not in dev");
685 
686 	/* And doesn't check or clear dev disable request */
687 	reset_common_data();
688 	ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
689 	sd->status &= ~VB2_SD_STATUS_SECDATA_FIRMWARE_INIT;
690 	vb2_nv_set(ctx, VB2_NV_DISABLE_DEV_REQUEST, 1);
691 	TEST_SUCC(vb2_check_dev_switch(ctx),
692 		  "secdata_firmware fail recovery disable");
693 	TEST_EQ(sd->flags & VB2_SD_FLAG_DEV_MODE_ENABLED, 0, "  sd not in dev");
694 	TEST_EQ(ctx->flags & VB2_CONTEXT_DEVELOPER_MODE, 0, "  ctx not in dev");
695 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_DISABLE_DEV_REQUEST),
696 		1, "  request not cleared");
697 
698 	/* Can still override with GBB flag */
699 	reset_common_data();
700 	ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
701 	sd->status &= ~VB2_SD_STATUS_SECDATA_FIRMWARE_INIT;
702 	gbb.flags |= VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON;
703 	TEST_SUCC(vb2_check_dev_switch(ctx),
704 		  "secdata_firmware fail recovery gbb");
705 	TEST_NEQ(sd->flags & VB2_SD_FLAG_DEV_MODE_ENABLED, 0, "  sd in dev");
706 	TEST_NEQ(ctx->flags & VB2_CONTEXT_DEVELOPER_MODE, 0, "  ctx in dev");
707 	TEST_EQ(mock_tpm_clear_called, 1, "  tpm clear");
708 
709 	/* Force wipeout by ctx flag */
710 	reset_common_data();
711 	ctx->flags |= VB2_CONTEXT_FORCE_WIPEOUT_MODE;
712 	TEST_SUCC(vb2_check_dev_switch(ctx), "wipeout on ctx flag");
713 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_REQ_WIPEOUT), 1, "  nv wipeout");
714 }
715 
enable_dev_tests(void)716 static void enable_dev_tests(void)
717 {
718 	reset_common_data();
719 	TEST_FAIL(vb2api_enable_developer_mode(ctx),
720 		 "vb2api_enable_developer_mode - failed");
721 	TEST_EQ(vb2_secdata_firmware_get(ctx, VB2_SECDATA_FIRMWARE_FLAGS) &
722 		VB2_SECDATA_FIRMWARE_FLAG_DEV_MODE, 0,
723 		"  dev mode flag not set");
724 
725 	reset_common_data();
726 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_MANUAL_RECOVERY,
727 		      VB2_RECOVERY_RO_MANUAL);
728 	TEST_SUCC(vb2api_enable_developer_mode(ctx),
729 		  "vb2api_enable_developer_mode - success");
730 	TEST_NEQ(vb2_secdata_firmware_get(ctx, VB2_SECDATA_FIRMWARE_FLAGS) &
731 	         VB2_SECDATA_FIRMWARE_FLAG_DEV_MODE, 0,
732 		 "  dev mode flag set");
733 
734 	/* secdata_firmware not initialized, aborts */
735 	reset_common_data();
736 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_MANUAL_RECOVERY,
737 		      VB2_RECOVERY_RO_MANUAL);
738 	sd->status &= ~VB2_SD_STATUS_SECDATA_FIRMWARE_INIT;
739 	sd->status |= VB2_SD_STATUS_RECOVERY_DECIDED;
740 	TEST_SUCC(vb2api_enable_developer_mode(ctx),
741 		  "secdata_firmware no init, enable dev mode ignored");
742 	sd->status |= VB2_SD_STATUS_SECDATA_FIRMWARE_INIT;
743 	TEST_EQ(vb2_secdata_firmware_get(ctx, VB2_SECDATA_FIRMWARE_FLAGS) &
744 	        VB2_SECDATA_FIRMWARE_FLAG_DEV_MODE, 0,
745 		"  dev mode flag not set");
746 }
747 
tpm_clear_tests(void)748 static void tpm_clear_tests(void)
749 {
750 	/* No clear request */
751 	reset_common_data();
752 	TEST_SUCC(vb2_check_tpm_clear(ctx), "no clear request");
753 	TEST_EQ(mock_tpm_clear_called, 0, "tpm not cleared");
754 
755 	/* Successful request */
756 	reset_common_data();
757 	vb2_nv_set(ctx, VB2_NV_CLEAR_TPM_OWNER_REQUEST, 1);
758 	TEST_SUCC(vb2_check_tpm_clear(ctx), "clear request");
759 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_CLEAR_TPM_OWNER_REQUEST),
760 		0, "request cleared");
761 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_CLEAR_TPM_OWNER_DONE),
762 		1, "done set");
763 	TEST_EQ(mock_tpm_clear_called, 1, "tpm cleared");
764 
765 	/* Failed request */
766 	reset_common_data();
767 	mock_tpm_clear_retval = VB2_ERROR_EX_TPM_CLEAR_OWNER;
768 	vb2_nv_set(ctx, VB2_NV_CLEAR_TPM_OWNER_REQUEST, 1);
769 	TEST_EQ(vb2_check_tpm_clear(ctx),
770 		VB2_ERROR_EX_TPM_CLEAR_OWNER, "clear failure");
771 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_CLEAR_TPM_OWNER_REQUEST),
772 		0, "request cleared");
773 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_CLEAR_TPM_OWNER_DONE),
774 		0, "done not set");
775 }
776 
select_slot_tests(void)777 static void select_slot_tests(void)
778 {
779 	/* Slot A */
780 	reset_common_data();
781 	TEST_SUCC(vb2_select_fw_slot(ctx), "select slot A");
782 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_RESULT),
783 		VB2_FW_RESULT_UNKNOWN, "result unknown");
784 	TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
785 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_TRIED), 0, "tried A");
786 	TEST_EQ(sd->fw_slot, 0, "selected A");
787 	TEST_EQ(ctx->flags & VB2_CONTEXT_FW_SLOT_B, 0, "didn't choose B");
788 
789 	/* Slot B */
790 	reset_common_data();
791 	vb2_nv_set(ctx, VB2_NV_TRY_NEXT, 1);
792 	TEST_SUCC(vb2_select_fw_slot(ctx), "select slot B");
793 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_RESULT),
794 		VB2_FW_RESULT_UNKNOWN, "result unknown");
795 	TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
796 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_TRIED), 1, "tried B");
797 	TEST_EQ(sd->fw_slot, 1, "selected B");
798 	TEST_NEQ(ctx->flags & VB2_CONTEXT_FW_SLOT_B, 0, "ctx says choose B");
799 
800 	/* Slot A ran out of tries */
801 	reset_common_data();
802 	vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_TRYING);
803 	TEST_SUCC(vb2_select_fw_slot(ctx), "select slot A out of tries");
804 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_NEXT), 1, "try B next");
805 	TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
806 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_TRIED), 1, "tried B");
807 	TEST_EQ(sd->fw_slot, 1, "selected B");
808 	TEST_NEQ(ctx->flags & VB2_CONTEXT_FW_SLOT_B, 0, "ctx says choose B");
809 
810 	/* Slot A ran out of tries, but slot B not present */
811 	reset_common_data();
812 	ctx->flags |= VB2_CONTEXT_SLOT_A_ONLY;
813 	vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_TRYING);
814 	TEST_EQ(vb2_select_fw_slot(ctx), VB2_ERROR_API_NEXT_SLOT_UNAVAILABLE,
815 		"don't try slot B if only one slot present");
816 	TEST_EQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "didn't choose slot");
817 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_TRIED), 0, "tried A");
818 	TEST_EQ(sd->fw_slot, 0, "selected A");
819 	TEST_EQ(ctx->flags & VB2_CONTEXT_FW_SLOT_B, 0, "didn't choose B");
820 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_NEXT), 0, "didn't try B next");
821 
822 	/* Slot A ran out of tries, even with nofail active */
823 	reset_common_data();
824 	ctx->flags |= VB2_CONTEXT_NOFAIL_BOOT;
825 	vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_TRYING);
826 	TEST_SUCC(vb2_select_fw_slot(ctx), "select slot A out of tries");
827 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_NEXT), 1, "try B next");
828 	TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
829 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_TRIED), 1, "tried B");
830 	TEST_EQ(sd->fw_slot, 1, "selected B");
831 	TEST_NEQ(ctx->flags & VB2_CONTEXT_FW_SLOT_B, 0, "ctx says choose B");
832 
833 	/* Slot A used up a try */
834 	reset_common_data();
835 	vb2_nv_set(ctx, VB2_NV_TRY_COUNT, 3);
836 	TEST_SUCC(vb2_select_fw_slot(ctx), "try slot A");
837 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_RESULT),
838 		VB2_FW_RESULT_TRYING, "result trying");
839 	TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
840 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_TRIED), 0, "tried A");
841 	TEST_EQ(sd->fw_slot, 0, "selected A");
842 	TEST_EQ(ctx->flags & VB2_CONTEXT_FW_SLOT_B, 0, "didn't choose B");
843 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_COUNT), 2, "tries decremented");
844 
845 	/* Slot A failed, but nofail active */
846 	reset_common_data();
847 	ctx->flags |= VB2_CONTEXT_NOFAIL_BOOT;
848 	vb2_nv_set(ctx, VB2_NV_TRY_COUNT, 3);
849 	TEST_SUCC(vb2_select_fw_slot(ctx), "try slot A");
850 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_RESULT),
851 		VB2_FW_RESULT_TRYING, "result trying");
852 	TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
853 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_TRIED), 0, "tried A");
854 	TEST_EQ(sd->fw_slot, 0, "selected A");
855 	TEST_EQ(ctx->flags & VB2_CONTEXT_FW_SLOT_B, 0, "didn't choose B");
856 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_TRY_COUNT), 3, "tries not decremented");
857 
858 	/* Tried/result get copied to the previous fields */
859 	reset_common_data();
860 	vb2_nv_set(ctx, VB2_NV_FW_TRIED, 0);
861 	vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_SUCCESS);
862 	vb2_select_fw_slot(ctx);
863 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_PREV_TRIED), 0, "prev A");
864 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_PREV_RESULT),	VB2_FW_RESULT_SUCCESS,
865 		"prev success");
866 
867 	reset_common_data();
868 	vb2_nv_set(ctx, VB2_NV_FW_TRIED, 1);
869 	vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_FAILURE);
870 	vb2_select_fw_slot(ctx);
871 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_PREV_TRIED), 1, "prev B");
872 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_FW_PREV_RESULT),	VB2_FW_RESULT_FAILURE,
873 		"prev failure");
874 }
875 
need_reboot_for_display_tests(void)876 static void need_reboot_for_display_tests(void)
877 {
878 	/* Display not available, reboot required */
879 	reset_common_data();
880 	TEST_EQ(vb2api_need_reboot_for_display(ctx), 1,
881 		"need_reboot_for_display: need reboot");
882 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_DISPLAY_REQUEST), 1,
883 		"  set display request");
884 
885 	/* Display available, don't need reboot */
886 	reset_common_data();
887 	sd->flags |= VB2_SD_FLAG_DISPLAY_AVAILABLE;
888 	TEST_EQ(vb2api_need_reboot_for_display(ctx), 0,
889 		"need_reboot_for_display: don't need reboot");
890 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_DISPLAY_REQUEST), 0,
891 		"  not set display request");
892 }
893 
clear_recovery_tests(void)894 static void clear_recovery_tests(void)
895 {
896 
897 	/* Manual recovery */
898 	reset_common_data();
899 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_MANUAL_RECOVERY, 4);
900 	vb2_nv_set(ctx, VB2_NV_RECOVERY_REQUEST, 5);
901 	vb2_nv_set(ctx, VB2_NV_RECOVERY_SUBCODE, 13);
902 	vb2api_clear_recovery(ctx);
903 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
904 		0, "  request cleared");
905 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_SUBCODE),
906 		0, "  subcode cleared");
907 
908 	/* Broken screen */
909 	reset_common_data();
910 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_BROKEN_SCREEN, 4);
911 	vb2_nv_set(ctx, VB2_NV_RECOVERY_REQUEST, 5);
912 	vb2_nv_set(ctx, VB2_NV_RECOVERY_SUBCODE, 13);
913 	vb2api_clear_recovery(ctx);
914 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
915 		0, "  request cleared");
916 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_SUBCODE),
917 		4, "  subcode shifted");
918 }
919 
get_recovery_reason_tests(void)920 static void get_recovery_reason_tests(void)
921 {
922 	reset_common_data();
923 	sd->recovery_reason = 4;
924 	TEST_EQ(vb2api_get_recovery_reason(ctx), 4, "correct recovery reason");
925 }
926 
diagnostic_ui_enabled_tests(void)927 static void diagnostic_ui_enabled_tests(void)
928 {
929 	reset_common_data();
930 	vb2api_secdata_kernel_create(ctx);
931 	vb2_secdata_kernel_init(ctx);
932 	TEST_EQ(vb2api_diagnostic_ui_enabled(ctx), 1,
933 		"diagnostic UI enabled");
934 
935 	reset_common_data();
936 	vb2api_secdata_kernel_create(ctx);
937 	vb2_secdata_kernel_init(ctx);
938 	vb2_secdata_kernel_set(
939 		ctx, VB2_SECDATA_KERNEL_FLAGS,
940 		VB2_SECDATA_KERNEL_FLAG_DIAGNOSTIC_UI_DISABLED);
941 	TEST_EQ(vb2api_diagnostic_ui_enabled(ctx), 0,
942 		"diagnostic UI disabled");
943 }
944 
dev_default_boot_tests(void)945 static void dev_default_boot_tests(void)
946 {
947 	/* No default boot */
948 	reset_common_data();
949 	TEST_EQ(vb2api_get_dev_default_boot_target(ctx),
950 		VB2_DEV_DEFAULT_BOOT_TARGET_INTERNAL,
951 		"no default boot, boot disk");
952 
953 	/* Set boot altfw by GBB */
954 	reset_common_data();
955 	gbb.flags |= VB2_GBB_FLAG_DEFAULT_DEV_BOOT_ALTFW;
956 	vb2_nv_set(ctx, VB2_NV_DEV_DEFAULT_BOOT,
957 		   VB2_DEV_DEFAULT_BOOT_TARGET_EXTERNAL);
958 	TEST_EQ(vb2api_get_dev_default_boot_target(ctx),
959 		VB2_DEV_DEFAULT_BOOT_TARGET_ALTFW,
960 		"GBB set default boot altfw");
961 
962 	/* Boot from internal disk */
963 	reset_common_data();
964 	vb2_nv_set(ctx, VB2_NV_DEV_DEFAULT_BOOT,
965 		   VB2_DEV_DEFAULT_BOOT_TARGET_INTERNAL);
966 	TEST_EQ(vb2api_get_dev_default_boot_target(ctx),
967 		VB2_DEV_DEFAULT_BOOT_TARGET_INTERNAL,
968 		"set default boot internal disk");
969 
970 	/* Boot from external disk */
971 	reset_common_data();
972 	ctx->flags |= VB2_CONTEXT_DEV_BOOT_EXTERNAL_ALLOWED;
973 	vb2_nv_set(ctx, VB2_NV_DEV_DEFAULT_BOOT,
974 		   VB2_DEV_DEFAULT_BOOT_TARGET_EXTERNAL);
975 	TEST_EQ(vb2api_get_dev_default_boot_target(ctx),
976 		VB2_DEV_DEFAULT_BOOT_TARGET_EXTERNAL,
977 		"set default boot external disk");
978 
979 	/* Boot from external disk not allowed */
980 	reset_common_data();
981 	vb2_nv_set(ctx, VB2_NV_DEV_DEFAULT_BOOT,
982 		   VB2_DEV_DEFAULT_BOOT_TARGET_EXTERNAL);
983 	TEST_EQ(vb2api_get_dev_default_boot_target(ctx),
984 		VB2_DEV_DEFAULT_BOOT_TARGET_INTERNAL,
985 		"default boot external not allowed");
986 	reset_common_data();
987 	ctx->flags |= VB2_CONTEXT_DEV_BOOT_ALTFW_ALLOWED;
988 	vb2_nv_set(ctx, VB2_NV_DEV_DEFAULT_BOOT,
989 		   VB2_DEV_DEFAULT_BOOT_TARGET_EXTERNAL);
990 	TEST_EQ(vb2api_get_dev_default_boot_target(ctx),
991 		VB2_DEV_DEFAULT_BOOT_TARGET_INTERNAL,
992 		"default boot external not allowed");
993 
994 	/* Boot altfw */
995 	reset_common_data();
996 	ctx->flags |= VB2_CONTEXT_DEV_BOOT_ALTFW_ALLOWED;
997 	vb2_nv_set(ctx, VB2_NV_DEV_DEFAULT_BOOT,
998 		   VB2_DEV_DEFAULT_BOOT_TARGET_ALTFW);
999 	TEST_EQ(vb2api_get_dev_default_boot_target(ctx),
1000 		VB2_DEV_DEFAULT_BOOT_TARGET_ALTFW,
1001 		"set default boot altfw");
1002 
1003 	/* Boot altfw not allowed */
1004 	reset_common_data();
1005 	vb2_nv_set(ctx, VB2_NV_DEV_DEFAULT_BOOT,
1006 		   VB2_DEV_DEFAULT_BOOT_TARGET_ALTFW);
1007 	TEST_EQ(vb2api_get_dev_default_boot_target(ctx),
1008 		VB2_DEV_DEFAULT_BOOT_TARGET_INTERNAL,
1009 		"default boot altfw not allowed");
1010 	reset_common_data();
1011 	ctx->flags |= VB2_CONTEXT_DEV_BOOT_EXTERNAL_ALLOWED;
1012 	vb2_nv_set(ctx, VB2_NV_DEV_DEFAULT_BOOT,
1013 		   VB2_DEV_DEFAULT_BOOT_TARGET_ALTFW);
1014 	TEST_EQ(vb2api_get_dev_default_boot_target(ctx),
1015 		VB2_DEV_DEFAULT_BOOT_TARGET_INTERNAL,
1016 		"default boot altfw not allowed");
1017 }
1018 
fill_dev_boot_flags_tests(void)1019 static void fill_dev_boot_flags_tests(void)
1020 {
1021 	/* Dev boot - allowed by default */
1022 	reset_common_data();
1023 	vb2_fill_dev_boot_flags(ctx);
1024 	TEST_TRUE(ctx->flags & VB2_CONTEXT_DEV_BOOT_ALLOWED,
1025 		  "dev boot - allowed by default");
1026 
1027 	/* Dev boot - disabled by FWMP */
1028 	reset_common_data();
1029 	fwmp->flags |= VB2_SECDATA_FWMP_DEV_DISABLE_BOOT;
1030 	vb2_fill_dev_boot_flags(ctx);
1031 	TEST_FALSE(ctx->flags & VB2_CONTEXT_DEV_BOOT_ALLOWED,
1032 		   "dev boot - FWMP disabled");
1033 
1034 	/* Dev boot - force enabled by GBB */
1035 	reset_common_data();
1036 	fwmp->flags |= VB2_SECDATA_FWMP_DEV_DISABLE_BOOT;
1037 	gbb.flags |= VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON;
1038 	vb2_fill_dev_boot_flags(ctx);
1039 	TEST_TRUE(ctx->flags & VB2_CONTEXT_DEV_BOOT_ALLOWED,
1040 		  "dev boot - GBB force dev on");
1041 
1042 	/* External boot - not allowed by default */
1043 	reset_common_data();
1044 	vb2_fill_dev_boot_flags(ctx);
1045 	TEST_FALSE(ctx->flags & VB2_CONTEXT_DEV_BOOT_EXTERNAL_ALLOWED,
1046 		   "dev boot external - not allowed by default");
1047 
1048 	/* External boot - enabled by nvdata */
1049 	reset_common_data();
1050 	vb2_nv_set(ctx, VB2_NV_DEV_BOOT_EXTERNAL, 1);
1051 	vb2_fill_dev_boot_flags(ctx);
1052 	TEST_TRUE(ctx->flags & VB2_CONTEXT_DEV_BOOT_EXTERNAL_ALLOWED,
1053 		  "dev boot external - nvdata enabled");
1054 
1055 	/* External boot - enabled by FWMP */
1056 	reset_common_data();
1057 	fwmp->flags |= VB2_SECDATA_FWMP_DEV_ENABLE_EXTERNAL;
1058 	vb2_fill_dev_boot_flags(ctx);
1059 	TEST_TRUE(ctx->flags & VB2_CONTEXT_DEV_BOOT_EXTERNAL_ALLOWED,
1060 		  "dev boot external - secdata enabled");
1061 
1062 	/* External boot - force enabled by GBB */
1063 	reset_common_data();
1064 	gbb.flags |= VB2_GBB_FLAG_FORCE_DEV_BOOT_USB;
1065 	vb2_fill_dev_boot_flags(ctx);
1066 	TEST_TRUE(ctx->flags & VB2_CONTEXT_DEV_BOOT_EXTERNAL_ALLOWED,
1067 		  "dev boot external - GBB force enabled");
1068 
1069 	/* External boot - set all flags */
1070 	reset_common_data();
1071 	vb2_nv_set(ctx, VB2_NV_DEV_BOOT_EXTERNAL, 1);
1072 	fwmp->flags |= VB2_SECDATA_FWMP_DEV_ENABLE_EXTERNAL;
1073 	gbb.flags |= VB2_GBB_FLAG_FORCE_DEV_BOOT_USB;
1074 	vb2_fill_dev_boot_flags(ctx);
1075 	TEST_TRUE(ctx->flags & VB2_CONTEXT_DEV_BOOT_EXTERNAL_ALLOWED,
1076 		  "dev boot external - all flags set");
1077 
1078 	/* Alternate boot - not allowed by default */
1079 	reset_common_data();
1080 	vb2_fill_dev_boot_flags(ctx);
1081 	TEST_FALSE(ctx->flags & VB2_CONTEXT_DEV_BOOT_ALTFW_ALLOWED,
1082 		   "dev boot altfw - not allowed by default");
1083 
1084 	/* Alternate boot - enabled by nvdata */
1085 	reset_common_data();
1086 	vb2_nv_set(ctx, VB2_NV_DEV_BOOT_ALTFW, 1);
1087 	vb2_fill_dev_boot_flags(ctx);
1088 	TEST_TRUE(ctx->flags & VB2_CONTEXT_DEV_BOOT_ALTFW_ALLOWED,
1089 		  "dev boot altfw - nvdata enabled");
1090 
1091 	/* Alternate boot - enabled by FWMP */
1092 	reset_common_data();
1093 	fwmp->flags |= VB2_SECDATA_FWMP_DEV_ENABLE_ALTFW;
1094 	vb2_fill_dev_boot_flags(ctx);
1095 	TEST_TRUE(ctx->flags & VB2_CONTEXT_DEV_BOOT_ALTFW_ALLOWED,
1096 		  "dev boot altfw - secdata enabled");
1097 
1098 	/* Alternate boot - force enabled by GBB */
1099 	reset_common_data();
1100 	gbb.flags |= VB2_GBB_FLAG_FORCE_DEV_BOOT_ALTFW;
1101 	vb2_fill_dev_boot_flags(ctx);
1102 	TEST_TRUE(ctx->flags & VB2_CONTEXT_DEV_BOOT_ALTFW_ALLOWED,
1103 		  "dev boot altfw - GBB force enabled");
1104 
1105 	/* Alternate boot - set all flags */
1106 	reset_common_data();
1107 	vb2_nv_set(ctx, VB2_NV_DEV_BOOT_ALTFW, 1);
1108 	fwmp->flags |= VB2_SECDATA_FWMP_DEV_ENABLE_ALTFW;
1109 	gbb.flags |= VB2_GBB_FLAG_FORCE_DEV_BOOT_ALTFW;
1110 	vb2_fill_dev_boot_flags(ctx);
1111 	TEST_TRUE(ctx->flags & VB2_CONTEXT_DEV_BOOT_ALTFW_ALLOWED,
1112 		  "dev boot altfw - all flags set");
1113 }
1114 
use_dev_screen_short_delay_tests(void)1115 static void use_dev_screen_short_delay_tests(void)
1116 {
1117 	/* Normal delay */
1118 	reset_common_data();
1119 	TEST_EQ(vb2api_use_short_dev_screen_delay(ctx), 0,
1120 		"short delay: no");
1121 
1122 	/* Short delay */
1123 	gbb.flags |= VB2_GBB_FLAG_DEV_SCREEN_SHORT_DELAY;
1124 	TEST_EQ(vb2api_use_short_dev_screen_delay(ctx), 1,
1125 		"short delay: yes");
1126 }
1127 
main(int argc,char * argv[])1128 int main(int argc, char* argv[])
1129 {
1130 	init_workbuf_tests();
1131 	misc_tests();
1132 	gbb_tests();
1133 	fail_tests();
1134 	previous_boot_fail_tests();
1135 	recovery_tests();
1136 	dev_switch_tests();
1137 	enable_dev_tests();
1138 	tpm_clear_tests();
1139 	select_slot_tests();
1140 	need_reboot_for_display_tests();
1141 	clear_recovery_tests();
1142 	get_recovery_reason_tests();
1143 	diagnostic_ui_enabled_tests();
1144 	dev_default_boot_tests();
1145 	fill_dev_boot_flags_tests();
1146 	use_dev_screen_short_delay_tests();
1147 
1148 	return gTestSuccess ? 0 : 255;
1149 }
1150