xref: /aosp_15_r20/external/vboot_reference/tests/vb2_kernel_tests.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
1 /* Copyright 2020 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 kernel selection, loading, verification, and booting.
6  */
7 
8 #include "2api.h"
9 #include "2common.h"
10 #include "2misc.h"
11 #include "2nvstorage.h"
12 #include "2rsa.h"
13 #include "2secdata.h"
14 #include "2sysincludes.h"
15 #include "common/boot_mode.h"
16 #include "common/tests.h"
17 
18 /* Common context for tests */
19 static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE]
20 	__attribute__((aligned(VB2_WORKBUF_ALIGN)));
21 static struct vb2_context *ctx;
22 static struct vb2_shared_data *sd;
23 static struct vb2_fw_preamble *fwpre;
24 static const char fw_kernel_key_data[36] = "Test kernel key data";
25 static struct vb2_kernel_params kparams;
26 
27 /* Mocked function data */
28 
29 static struct {
30 	struct vb2_gbb_header h;
31 	struct vb2_packed_key recovery_key;
32 	char recovery_key_data[32];
33 } mock_gbb;
34 
35 static int mock_read_res_fail_on_call;
36 static int mock_secdata_fwmp_check_retval;
37 static int mock_commit_data_called;
38 static int mock_ec_sync_called;
39 static int mock_ec_sync_retval;
40 static int mock_battery_cutoff_called;
41 static int mock_kernel_flag;
42 static int mock_kernel_flag_set;
43 static int mock_kernel_version_secdata;
44 
45 /* Type of test to reset for */
46 enum reset_type {
47 	FOR_PHASE1,
48 	FOR_PHASE2,
49 	FOR_FINALIZE,
50 };
51 
reset_common_data(enum reset_type t)52 static void reset_common_data(enum reset_type t)
53 {
54 	struct vb2_packed_key *k;
55 
56 	memset(workbuf, 0xaa, sizeof(workbuf));
57 
58 	memset(&kparams, 0, sizeof(kparams));
59 
60 	TEST_SUCC(vb2api_init(workbuf, sizeof(workbuf), &ctx),
61 		  "vb2api_init failed");
62 
63 	sd = vb2_get_sd(ctx);
64 	vb2_nv_init(ctx);
65 
66 	mock_read_res_fail_on_call = 0;
67 	mock_secdata_fwmp_check_retval = VB2_SUCCESS;
68 	mock_commit_data_called = 0;
69 	mock_ec_sync_called = 0;
70 	mock_ec_sync_retval = VB2_SUCCESS;
71 	mock_battery_cutoff_called = 0;
72 	mock_kernel_flag = 0;
73 	mock_kernel_flag_set = 0;
74 	mock_kernel_version_secdata = 0x10002;
75 
76 	/* Recovery key in mock GBB */
77 	memset(&mock_gbb, 0, sizeof(mock_gbb));
78 	mock_gbb.recovery_key.algorithm = 11;
79 	mock_gbb.recovery_key.key_offset =
80 		vb2_offset_of(&mock_gbb.recovery_key,
81 			      &mock_gbb.recovery_key_data);
82 	mock_gbb.recovery_key.key_size = sizeof(mock_gbb.recovery_key_data);
83 	strcpy(mock_gbb.recovery_key_data, "The recovery key");
84 	mock_gbb.h.recovery_key_offset =
85 		vb2_offset_of(&mock_gbb, &mock_gbb.recovery_key);
86 	mock_gbb.h.recovery_key_size =
87 		mock_gbb.recovery_key.key_offset +
88 		mock_gbb.recovery_key.key_size;
89 	mock_gbb.h.major_version = VB2_GBB_MAJOR_VER;
90 	mock_gbb.h.minor_version = VB2_GBB_MINOR_VER;
91 
92 	if (t == FOR_PHASE1) {
93 		uint8_t *kdata;
94 
95 		/* Create mock firmware preamble in the context */
96 		sd->preamble_offset = sd->workbuf_used;
97 		fwpre = (struct vb2_fw_preamble *)
98 			vb2_member_of(sd, sd->preamble_offset);
99 		k = &fwpre->kernel_subkey;
100 		kdata = (uint8_t *)fwpre + sizeof(*fwpre);
101 		memcpy(kdata, fw_kernel_key_data, sizeof(fw_kernel_key_data));
102 		k->algorithm = 7;
103 		k->key_offset = vb2_offset_of(k, kdata);
104 		k->key_size = sizeof(fw_kernel_key_data);
105 		sd->preamble_size = sizeof(*fwpre) + k->key_size;
106 		vb2_set_workbuf_used(ctx,
107 				     sd->preamble_offset + sd->preamble_size);
108 	} else if (t == FOR_FINALIZE) {
109 		SET_BOOT_MODE(ctx, VB2_BOOT_MODE_NORMAL);
110 		vb2_nv_set(ctx, VB2_NV_KERNEL_MAX_ROLLFORWARD, 0xffffffff);
111 		sd->kernel_version_secdata = mock_kernel_version_secdata;
112 	}
113 };
114 
115 /* Mocked functions */
116 
vb2api_secdata_fwmp_check(struct vb2_context * c,uint8_t * size)117 vb2_error_t vb2api_secdata_fwmp_check(struct vb2_context *c, uint8_t *size)
118 {
119 	return mock_secdata_fwmp_check_retval;
120 }
121 
vb2api_ec_sync(struct vb2_context * c)122 vb2_error_t vb2api_ec_sync(struct vb2_context *c)
123 {
124 	mock_ec_sync_called = 1;
125 	return mock_ec_sync_retval;
126 }
127 
vb2api_auxfw_sync(struct vb2_context * c)128 vb2_error_t vb2api_auxfw_sync(struct vb2_context *c)
129 {
130 	TEST_EQ(mock_ec_sync_called, 1,
131 		"  auxfw sync must happen after EC sync");
132 	return VB2_SUCCESS;
133 }
134 
vb2ex_ec_battery_cutoff(void)135 vb2_error_t vb2ex_ec_battery_cutoff(void)
136 {
137 	TEST_EQ(mock_ec_sync_called, 1,
138 		"  battery cutoff must happen after EC sync");
139 	mock_battery_cutoff_called = 1;
140 	return VB2_SUCCESS;
141 }
142 
vb2_secdata_kernel_get_ec_hash(struct vb2_context * c)143 const uint8_t *vb2_secdata_kernel_get_ec_hash(struct vb2_context *c)
144 {
145 	/*
146 	 * Return NULL to prevent EC reboot due to
147 	 * VB2_SD_FLAG_ECSYNC_HMIR_UPDATED.
148 	 */
149 	return NULL;
150 }
151 
vb2_get_gbb(struct vb2_context * c)152 struct vb2_gbb_header *vb2_get_gbb(struct vb2_context *c)
153 {
154 	return &mock_gbb.h;
155 }
156 
vb2ex_read_resource(struct vb2_context * c,enum vb2_resource_index index,uint32_t offset,void * buf,uint32_t size)157 vb2_error_t vb2ex_read_resource(struct vb2_context *c,
158 				enum vb2_resource_index index, uint32_t offset,
159 				void *buf, uint32_t size)
160 {
161 	uint8_t *rptr;
162 	uint32_t rsize;
163 
164 	if (--mock_read_res_fail_on_call == 0)
165 		return VB2_ERROR_MOCK;
166 
167 	switch(index) {
168 	case VB2_RES_GBB:
169 		rptr = (uint8_t *)&mock_gbb;
170 		rsize = sizeof(mock_gbb);
171 		break;
172 	default:
173 		return VB2_ERROR_EX_READ_RESOURCE_INDEX;
174 	}
175 
176 	if (offset > rsize || offset + size > rsize)
177 		return VB2_ERROR_EX_READ_RESOURCE_SIZE;
178 
179 	memcpy(buf, rptr + offset, size);
180 	return VB2_SUCCESS;
181 }
182 
vb2ex_commit_data(struct vb2_context * c)183 vb2_error_t vb2ex_commit_data(struct vb2_context *c)
184 {
185 	mock_commit_data_called = 1;
186 	return VB2_SUCCESS;
187 }
188 
vb2_secdata_kernel_set(struct vb2_context * c,enum vb2_secdata_kernel_param param,uint32_t value)189 void vb2_secdata_kernel_set(struct vb2_context *c,
190 			    enum vb2_secdata_kernel_param param,
191 			    uint32_t value)
192 {
193 	switch (param) {
194 	case VB2_SECDATA_KERNEL_FLAGS:
195 		mock_kernel_flag = value;
196 		mock_kernel_flag_set = 1;
197 		break;
198 	case VB2_SECDATA_KERNEL_VERSIONS:
199 		mock_kernel_version_secdata = value;
200 		break;
201 	default:
202 		vb2ex_abort();
203 	}
204 }
205 
vb2_secdata_kernel_get(struct vb2_context * c,enum vb2_secdata_kernel_param param)206 uint32_t vb2_secdata_kernel_get(struct vb2_context *c,
207 				enum vb2_secdata_kernel_param param)
208 {
209 	switch (param) {
210 	case VB2_SECDATA_KERNEL_FLAGS:
211 		return mock_kernel_flag;
212 	case VB2_SECDATA_KERNEL_VERSIONS:
213 		return mock_kernel_version_secdata;
214 	default:
215 		vb2ex_abort();
216 	}
217 	return 0;
218 }
219 
220 /* Tests */
221 
phase1_tests(void)222 static void phase1_tests(void)
223 {
224 	struct vb2_packed_key *k;
225 	uint32_t wb_used_before;
226 
227 	/* Test successful call */
228 	reset_common_data(FOR_PHASE1);
229 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_NORMAL);
230 	TEST_SUCC(vb2api_kernel_phase1(ctx), "phase1 good");
231 	/* Make sure normal key was loaded */
232 	TEST_EQ(sd->kernel_key_offset, sd->preamble_offset +
233 		offsetof(struct vb2_fw_preamble, kernel_subkey),
234 		"  workbuf key offset");
235 	k = vb2_member_of(sd, sd->kernel_key_offset);
236 	TEST_EQ(sd->kernel_key_size, k->key_offset + k->key_size,
237 		"  workbuf key size");
238 	TEST_EQ(sd->workbuf_used,
239 		vb2_wb_round_up(sd->kernel_key_offset +
240 				sd->kernel_key_size),
241 		"  workbuf used");
242 	TEST_EQ(k->algorithm, 7, "  key algorithm");
243 	TEST_EQ(k->key_size, sizeof(fw_kernel_key_data), "  key_size");
244 	TEST_EQ(memcmp((uint8_t *)k + k->key_offset, fw_kernel_key_data,
245 		       k->key_size), 0, "  key data");
246 	TEST_EQ(sd->kernel_version_secdata, 0x10002,
247 		"  secdata_kernel version");
248 
249 	/* Test successful call in recovery mode */
250 	reset_common_data(FOR_PHASE1);
251 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_BROKEN_SCREEN, 123);
252 	/* No preamble needed in recovery mode */
253 	sd->workbuf_used = sd->preamble_offset;
254 	sd->preamble_offset = sd->preamble_size = 0;
255 	wb_used_before = sd->workbuf_used;
256 	TEST_SUCC(vb2api_kernel_phase1(ctx), "phase1 rec good");
257 	/* Make sure recovery key was loaded */
258 	TEST_EQ(sd->kernel_key_offset, wb_used_before,
259 		"  workbuf key offset");
260 	k = vb2_member_of(sd, sd->kernel_key_offset);
261 	TEST_EQ(sd->kernel_key_size, k->key_offset + k->key_size,
262 		"  workbuf key size");
263 	TEST_EQ(sd->workbuf_used,
264 		vb2_wb_round_up(sd->kernel_key_offset +
265 				sd->kernel_key_size),
266 		"  workbuf used");
267 	TEST_EQ(k->algorithm, 11, "  key algorithm");
268 	TEST_EQ(k->key_size, sizeof(mock_gbb.recovery_key_data), "  key_size");
269 	TEST_EQ(memcmp((uint8_t *)k + k->key_offset,
270 		       mock_gbb.recovery_key_data, k->key_size), 0,
271 		"  key data");
272 	TEST_EQ(sd->kernel_version_secdata, 0x10002,
273 		"  secdata_kernel version");
274 
275 	/* Test flags for experimental features in non-recovery path */
276 	reset_common_data(FOR_PHASE1);
277 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_NORMAL);
278 	TEST_SUCC(vb2api_kernel_phase1(ctx), "phase1 non-rec good");
279 	/* Make sure diagnostic UI is enabled */
280 	TEST_EQ(vb2api_diagnostic_ui_enabled(ctx), 1,
281 		"  diagnostic ui enabled");
282 
283 	/*
284 	 * Test flags are unchanged for experimental features in recovery path
285 	 */
286 	reset_common_data(FOR_PHASE1);
287 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_BROKEN_SCREEN, 123);
288 	TEST_SUCC(vb2api_kernel_phase1(ctx), "phase1 rec good");
289 	TEST_EQ(mock_kernel_flag_set, 0,
290 		"VB2_SECDATA_KERNEL_FLAGS remains unchanged in recovery path");
291 
292 	/* Bad secdata_fwmp causes failure in normal mode only */
293 	reset_common_data(FOR_PHASE1);
294 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_NORMAL);
295 	mock_secdata_fwmp_check_retval = VB2_ERROR_SECDATA_FWMP_CRC;
296 	TEST_EQ(vb2api_kernel_phase1(ctx), mock_secdata_fwmp_check_retval,
297 		"phase1 bad secdata_fwmp");
298 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
299 		VB2_RECOVERY_SECDATA_FWMP_INIT, "  recovery reason");
300 
301 	reset_common_data(FOR_PHASE1);
302 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_BROKEN_SCREEN, 123);
303 	mock_secdata_fwmp_check_retval = VB2_ERROR_SECDATA_FWMP_CRC;
304 	TEST_SUCC(vb2api_kernel_phase1(ctx), "phase1 bad secdata_fwmp rec");
305 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
306 		VB2_RECOVERY_NOT_REQUESTED, "  no recovery");
307 
308 	/* Failures while reading recovery key */
309 	reset_common_data(FOR_PHASE1);
310 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_BROKEN_SCREEN, 123);
311 	mock_gbb.h.recovery_key_size = sd->workbuf_size - 1;
312 	mock_gbb.recovery_key.key_size =
313 		mock_gbb.h.recovery_key_size - sizeof(mock_gbb.recovery_key);
314 	TEST_EQ(vb2api_kernel_phase1(ctx), VB2_SUCCESS,
315 		"phase1 rec workbuf key");
316 	TEST_EQ(sd->kernel_key_offset, 0, "  workbuf key offset");
317 	TEST_EQ(sd->kernel_key_size, 0, "  workbuf key size");
318 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_MANUAL_RECOVERY,
319 		      VB2_RECOVERY_RO_MANUAL);
320 	TEST_ABORT(vb2api_kernel_phase1(ctx), "  fatal for manual recovery");
321 
322 	reset_common_data(FOR_PHASE1);
323 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_BROKEN_SCREEN, 123);
324 	mock_read_res_fail_on_call = 1;
325 	TEST_EQ(vb2api_kernel_phase1(ctx), VB2_SUCCESS,
326 		"phase1 rec gbb read key");
327 	TEST_EQ(sd->kernel_key_offset, 0, "  workbuf key offset");
328 	TEST_EQ(sd->kernel_key_size, 0, "  workbuf key size");
329 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_MANUAL_RECOVERY,
330 		      VB2_RECOVERY_RO_MANUAL);
331 	mock_read_res_fail_on_call = 1;
332 	TEST_ABORT(vb2api_kernel_phase1(ctx), "  fatal for manual recovery");
333 
334 	/* Failures while parsing subkey from firmware preamble */
335 	reset_common_data(FOR_PHASE1);
336 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_NORMAL);
337 	sd->preamble_size = 0;
338 	TEST_EQ(vb2api_kernel_phase1(ctx), VB2_ERROR_API_KPHASE1_PREAMBLE,
339 		"phase1 fw preamble");
340 }
341 
phase2_tests(void)342 static void phase2_tests(void)
343 {
344 	reset_common_data(FOR_PHASE2);
345 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_NORMAL);
346 	TEST_SUCC(vb2api_kernel_phase2(ctx), "Normal mode");
347 	TEST_EQ(mock_ec_sync_called, 1, "  EC sync");
348 
349 	reset_common_data(FOR_PHASE2);
350 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_NORMAL);
351 	vb2_nv_set(ctx, VB2_NV_DISPLAY_REQUEST, 1);
352 	TEST_EQ(vb2api_kernel_phase2(ctx), VB2_REQUEST_REBOOT,
353 		"Normal mode with display request: rebooting");
354 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_DISPLAY_REQUEST), 0,
355 		"  display request reset");
356 
357 	reset_common_data(FOR_PHASE2);
358 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
359 	TEST_SUCC(vb2api_kernel_phase2(ctx), "Developer mode");
360 	TEST_EQ(mock_ec_sync_called, 1, "  EC sync");
361 
362 	reset_common_data(FOR_PHASE2);
363 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DIAGNOSTICS);
364 	TEST_SUCC(vb2api_kernel_phase2(ctx), "Diagnostics mode");
365 	TEST_EQ(mock_ec_sync_called, 1, "  EC sync");
366 
367 	/* Commit data for recovery mode */
368 	reset_common_data(FOR_PHASE2);
369 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_MANUAL_RECOVERY,
370 		      VB2_RECOVERY_RO_MANUAL);
371 	TEST_SUCC(vb2api_kernel_phase2(ctx), "Manual recovery mode");
372 	TEST_EQ(mock_commit_data_called, 1, "  commit data");
373 	TEST_EQ(mock_ec_sync_called, 0, "  EC sync");
374 
375 	reset_common_data(FOR_PHASE2);
376 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_BROKEN_SCREEN, 123);
377 	TEST_SUCC(vb2api_kernel_phase2(ctx), "Broken screen mode");
378 	TEST_EQ(mock_commit_data_called, 1, "  commit data");
379 	TEST_EQ(mock_ec_sync_called, 0, "  EC sync");
380 
381 	/* Boot recovery - memory retraining */
382 	reset_common_data(FOR_PHASE2);
383 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_MANUAL_RECOVERY,
384 		      VB2_RECOVERY_TRAIN_AND_REBOOT);
385 	TEST_EQ(vb2api_kernel_phase2(ctx), VB2_REQUEST_REBOOT,
386 		"Recovery train and reboot");
387 
388 	/* Clear VB2_NV_DIAG_REQUEST */
389 	reset_common_data(FOR_PHASE2);
390 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_NORMAL);
391 	vb2_nv_set(ctx, VB2_NV_DIAG_REQUEST, 1);
392 	TEST_SUCC(vb2api_kernel_phase2(ctx), "Normal mode with DIAG_REQUEST");
393 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_DIAG_REQUEST), 0,
394 		"  clear VB2_NV_DIAG_REQUEST");
395 	TEST_EQ(mock_commit_data_called, 1, "  commit data");
396 
397 	reset_common_data(FOR_PHASE2);
398 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DIAGNOSTICS);
399 	vb2_nv_set(ctx, VB2_NV_DIAG_REQUEST, 1);
400 	TEST_SUCC(vb2api_kernel_phase2(ctx), "Diagnostics mode");
401 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_DIAG_REQUEST), 0,
402 		"  clear VB2_NV_DIAG_REQUEST");
403 	TEST_EQ(mock_commit_data_called, 1, "  commit data");
404 
405 	/* Battery cutoff called after EC sync */
406 	reset_common_data(FOR_PHASE2);
407 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_NORMAL);
408 	vb2_nv_set(ctx, VB2_NV_BATTERY_CUTOFF_REQUEST, 1);
409 	TEST_EQ(vb2api_kernel_phase2(ctx), VB2_REQUEST_SHUTDOWN,
410 		"Set VB2_NV_BATTERY_CUTOFF_REQUEST");
411 	TEST_EQ(mock_battery_cutoff_called, 1,
412 		"  battery_cutoff called after EC sync");
413 
414 	/* Return EC sync error */
415 	reset_common_data(FOR_PHASE2);
416 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_NORMAL);
417 	mock_ec_sync_retval = VB2_ERROR_MOCK;
418 	TEST_EQ(vb2api_kernel_phase2(ctx), VB2_ERROR_MOCK,
419 		"Return EC sync error");
420 
421 	/* Undefined boot mode */
422 	reset_common_data(FOR_PHASE2);
423 	TEST_EQ(vb2api_kernel_phase2(ctx), VB2_ERROR_ESCAPE_NO_BOOT,
424 		"Undefined boot mode");
425 }
426 
finalize_tests(void)427 static void finalize_tests(void)
428 {
429 	/* Kernel version roll forward */
430 	reset_common_data(FOR_FINALIZE);
431 	sd->kernel_version_secdata = 0x20003;
432 	TEST_EQ(vb2api_kernel_finalize(ctx), VB2_SUCCESS,
433 		"Kernel version roll forward");
434 	TEST_EQ(mock_kernel_version_secdata, 0x20003, "  kernel version");
435 
436 	reset_common_data(FOR_FINALIZE);
437 	vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_TRYING);
438 	sd->kernel_version_secdata = 0x20003;
439 	TEST_EQ(vb2api_kernel_finalize(ctx), VB2_SUCCESS,
440 		"Don't roll forward kernel when trying new FW");
441 	TEST_EQ(mock_kernel_version_secdata, 0x10002, "  kernel version");
442 
443 	reset_common_data(FOR_FINALIZE);
444 	vb2_nv_set(ctx, VB2_NV_KERNEL_MAX_ROLLFORWARD, 0x30005);
445 	sd->kernel_version_secdata = 0x40006;
446 	TEST_EQ(vb2api_kernel_finalize(ctx), VB2_SUCCESS,
447 		"Limit max roll forward");
448 	TEST_EQ(mock_kernel_version_secdata, 0x30005, "  kernel version");
449 
450 	reset_common_data(FOR_FINALIZE);
451 	vb2_nv_set(ctx, VB2_NV_KERNEL_MAX_ROLLFORWARD, 0x10001);
452 	sd->kernel_version_secdata = 0x40006;
453 	TEST_EQ(vb2api_kernel_finalize(ctx), VB2_SUCCESS,
454 		"Max roll forward can't rollback");
455 	TEST_EQ(mock_kernel_version_secdata, 0x10002, "  kernel version");
456 
457 	/* NO_BOOT with EC sync support */
458 	reset_common_data(FOR_FINALIZE);
459 	ctx->flags |= VB2_CONTEXT_NO_BOOT;
460 	ctx->flags |= VB2_CONTEXT_EC_SYNC_SUPPORTED;
461 	TEST_EQ(vb2api_kernel_finalize(ctx), VB2_ERROR_ESCAPE_NO_BOOT,
462 		"Recovery for NO_BOOT escape");
463 	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
464 		VB2_RECOVERY_ESCAPE_NO_BOOT, "  recovery_reason");
465 
466 	/* NO_BOOT with EC sync disabled */
467 	reset_common_data(FOR_FINALIZE);
468 	ctx->flags |= VB2_CONTEXT_NO_BOOT;
469 	ctx->flags |= VB2_CONTEXT_EC_SYNC_SUPPORTED;
470 	mock_gbb.h.flags |= VB2_GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC;
471 	TEST_SUCC(vb2api_kernel_finalize(ctx),
472 		  "NO_BOOT ignored with gbb DISABLE_EC_SOFTWARE_SYNC");
473 
474 	/* Normal case with EC sync support */
475 	reset_common_data(FOR_FINALIZE);
476 	ctx->flags |= VB2_CONTEXT_EC_SYNC_SUPPORTED;
477 	TEST_SUCC(vb2api_kernel_finalize(ctx), "Disable VB2_CONTEXT_NO_BOOT");
478 
479 	/* NO_BOOT without EC sync support */
480 	reset_common_data(FOR_FINALIZE);
481 	ctx->flags |= VB2_CONTEXT_NO_BOOT;
482 	TEST_SUCC(vb2api_kernel_finalize(ctx),
483 		  "Disable VB2_CONTEXT_EC_SYNC_SUPPORTED");
484 }
485 
main(int argc,char * argv[])486 int main(int argc, char* argv[])
487 {
488 	phase1_tests();
489 	phase2_tests();
490 	finalize_tests();
491 
492 	return gTestSuccess ? 0 : 255;
493 }
494