1/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
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 "2sysincludes.h"
9#include "2api.h"
10#include "2common.h"
11#include "2misc.h"
12#include "2nvstorage.h"
13#include "2secdata.h"
14
15#include "test_common.h"
16
17/* Common context for tests */
18static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]
19	__attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
20static struct vb2_context cc;
21static struct vb2_shared_data *sd;
22
23/* Mocked function data */
24enum vb2_resource_index mock_resource_index;
25void *mock_resource_ptr;
26uint32_t mock_resource_size;
27int mock_tpm_clear_called;
28int mock_tpm_clear_retval;
29
30
31static void reset_common_data(void)
32{
33	memset(workbuf, 0xaa, sizeof(workbuf));
34
35	memset(&cc, 0, sizeof(cc));
36	cc.workbuf = workbuf;
37	cc.workbuf_size = sizeof(workbuf);
38
39	vb2_init_context(&cc);
40	sd = vb2_get_sd(&cc);
41
42	vb2_nv_init(&cc);
43
44	vb2_secdata_create(&cc);
45	vb2_secdata_init(&cc);
46
47	mock_tpm_clear_called = 0;
48	mock_tpm_clear_retval = VB2_SUCCESS;
49};
50
51/* Mocked functions */
52
53int vb2ex_read_resource(struct vb2_context *ctx,
54			enum vb2_resource_index index,
55			uint32_t offset,
56			void *buf,
57			uint32_t size)
58{
59	if (index != mock_resource_index)
60		return VB2_ERROR_EX_READ_RESOURCE_INDEX;
61
62	if (offset > mock_resource_size || offset + size > mock_resource_size)
63		return VB2_ERROR_EX_READ_RESOURCE_SIZE;
64
65	memcpy(buf, (uint8_t *)mock_resource_ptr + offset, size);
66	return VB2_SUCCESS;
67}
68
69int vb2ex_tpm_clear_owner(struct vb2_context *ctx)
70{
71	mock_tpm_clear_called++;
72
73	return mock_tpm_clear_retval;
74}
75
76/* Tests */
77
78static void init_context_tests(void)
79{
80	/* Use our own context struct so we can re-init it */
81	struct vb2_context c = {
82		.workbuf = workbuf,
83		.workbuf_size = sizeof(workbuf),
84	};
85
86	reset_common_data();
87
88	TEST_SUCC(vb2_init_context(&c), "Init context good");
89	TEST_EQ(c.workbuf_used, sizeof(struct vb2_shared_data),
90		"Init vbsd");
91
92	/* Don't re-init if used is non-zero */
93	c.workbuf_used = 200;
94	TEST_SUCC(vb2_init_context(&c), "Re-init context good");
95	TEST_EQ(c.workbuf_used, 200, "Didn't re-init");
96
97	/* Handle workbuf errors */
98	c.workbuf_used = 0;
99	c.workbuf_size = sizeof(struct vb2_shared_data) - 1;
100	TEST_EQ(vb2_init_context(&c),
101		VB2_ERROR_INITCTX_WORKBUF_SMALL, "Init too small");
102	c.workbuf_size = sizeof(workbuf);
103
104	/* Handle workbuf unaligned */
105	c.workbuf++;
106	TEST_EQ(vb2_init_context(&c),
107		VB2_ERROR_INITCTX_WORKBUF_ALIGN, "Init unaligned");
108}
109
110static void misc_tests(void)
111{
112	struct vb2_workbuf wb;
113
114	reset_common_data();
115	cc.workbuf_used = 16;
116
117	vb2_workbuf_from_ctx(&cc, &wb);
118
119	TEST_PTR_EQ(wb.buf, workbuf + 16, "vb_workbuf_from_ctx() buf");
120	TEST_EQ(wb.size, cc.workbuf_size - 16, "vb_workbuf_from_ctx() size");
121}
122
123static void gbb_tests(void)
124{
125	struct vb2_gbb_header gbb = {
126		.signature = {'$', 'G', 'B', 'B'},
127		.major_version = VB2_GBB_MAJOR_VER,
128		.minor_version = VB2_GBB_MINOR_VER,
129		.header_size = sizeof(struct vb2_gbb_header),
130		.flags = 0x1234,
131		.rootkey_offset = 240,
132		.rootkey_size = 1040,
133	};
134
135	struct vb2_gbb_header gbbdest;
136
137	TEST_EQ(sizeof(struct vb2_gbb_header),
138		EXPECTED_VB2_GBB_HEADER_SIZE,
139		"sizeof(struct vb2_gbb_header)");
140
141	reset_common_data();
142
143	/* Good contents */
144	mock_resource_index = VB2_RES_GBB;
145	mock_resource_ptr = &gbb;
146	mock_resource_size = sizeof(gbb);
147	TEST_SUCC(vb2_read_gbb_header(&cc, &gbbdest), "read gbb header good");
148	TEST_SUCC(memcmp(&gbb, &gbbdest, sizeof(gbb)), "read gbb contents");
149
150	mock_resource_index = VB2_RES_GBB + 1;
151	TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
152		VB2_ERROR_EX_READ_RESOURCE_INDEX, "read gbb header missing");
153	mock_resource_index = VB2_RES_GBB;
154
155	gbb.signature[0]++;
156	TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
157		VB2_ERROR_GBB_MAGIC, "read gbb header bad magic");
158	gbb.signature[0]--;
159
160	gbb.major_version = VB2_GBB_MAJOR_VER + 1;
161	TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
162		VB2_ERROR_GBB_VERSION, "read gbb header major version");
163	gbb.major_version = VB2_GBB_MAJOR_VER;
164
165	gbb.minor_version = VB2_GBB_MINOR_VER + 1;
166	TEST_SUCC(vb2_read_gbb_header(&cc, &gbbdest),
167		  "read gbb header minor++");
168	gbb.minor_version = 1;
169	TEST_SUCC(vb2_read_gbb_header(&cc, &gbbdest),
170		  "read gbb header 1.1");
171	gbb.minor_version = 0;
172	TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
173		VB2_ERROR_GBB_TOO_OLD, "read gbb header 1.0 fails");
174	gbb.minor_version = VB2_GBB_MINOR_VER;
175
176	gbb.header_size--;
177	TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
178		VB2_ERROR_GBB_HEADER_SIZE, "read gbb header size");
179	TEST_EQ(vb2_fw_parse_gbb(&cc),
180		VB2_ERROR_GBB_HEADER_SIZE, "parse gbb failure");
181	gbb.header_size++;
182
183	/* Parse GBB */
184	TEST_SUCC(vb2_fw_parse_gbb(&cc), "parse gbb");
185	TEST_EQ(sd->gbb_flags, gbb.flags, "gbb flags");
186	TEST_EQ(sd->gbb_rootkey_offset, gbb.rootkey_offset, "rootkey offset");
187	TEST_EQ(sd->gbb_rootkey_size, gbb.rootkey_size, "rootkey size");
188
189	/* Workbuf failure */
190	reset_common_data();
191	cc.workbuf_used = cc.workbuf_size - 4;
192	TEST_EQ(vb2_fw_parse_gbb(&cc),
193		VB2_ERROR_GBB_WORKBUF, "parse gbb no workbuf");
194}
195
196static void fail_tests(void)
197{
198	/* Early fail (before even NV init) */
199	reset_common_data();
200	sd->status &= ~VB2_SD_STATUS_NV_INIT;
201	vb2_fail(&cc, 1, 2);
202	TEST_NEQ(sd->status & VB2_SD_STATUS_NV_INIT, 0, "vb2_fail inits NV");
203	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
204		1, "vb2_fail request");
205	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_SUBCODE),
206		2, "vb2_fail subcode");
207
208	/* Repeated fail doesn't overwrite the error code */
209	vb2_fail(&cc, 3, 4);
210	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
211		1, "vb2_fail repeat");
212	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_SUBCODE),
213		2, "vb2_fail repeat2");
214
215	/* Fail with other slot good doesn't trigger recovery */
216	reset_common_data();
217	vb2_nv_set(&cc, VB2_NV_TRY_COUNT, 3);
218	vb2_nv_set(&cc, VB2_NV_FW_RESULT, VB2_FW_RESULT_UNKNOWN);
219	sd->status |= VB2_SD_STATUS_CHOSE_SLOT;
220	sd->fw_slot = 0;
221	sd->last_fw_slot = 1;
222	sd->last_fw_result = VB2_FW_RESULT_UNKNOWN;
223	vb2_fail(&cc, 5, 6);
224	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST), 0, "vb2_failover");
225	TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_RESULT),
226		VB2_FW_RESULT_FAILURE, "vb2_fail this fw");
227	TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_COUNT), 0, "vb2_fail use up tries");
228	TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_NEXT), 1, "vb2_fail try other slot");
229
230	/* Fail with other slot already failing triggers recovery */
231	reset_common_data();
232	sd->status |= VB2_SD_STATUS_CHOSE_SLOT;
233	sd->fw_slot = 1;
234	sd->last_fw_slot = 0;
235	sd->last_fw_result = VB2_FW_RESULT_FAILURE;
236	vb2_fail(&cc, 7, 8);
237	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST), 7,
238		"vb2_fail both slots bad");
239	TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_RESULT),
240		VB2_FW_RESULT_FAILURE, "vb2_fail this fw");
241	TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_NEXT), 0, "vb2_fail try other slot");
242}
243
244static void recovery_tests(void)
245{
246	/* No recovery */
247	reset_common_data();
248	vb2_check_recovery(&cc);
249	TEST_EQ(sd->recovery_reason, 0, "No recovery reason");
250	TEST_EQ(sd->flags & VB2_SD_FLAG_MANUAL_RECOVERY,
251		0, "Not manual recovery");
252	TEST_EQ(cc.flags & VB2_CONTEXT_RECOVERY_MODE,
253		0, "Not recovery mode");
254
255	/* From request */
256	reset_common_data();
257	vb2_nv_set(&cc, VB2_NV_RECOVERY_REQUEST, 3);
258	vb2_check_recovery(&cc);
259	TEST_EQ(sd->recovery_reason, 3, "Recovery reason from request");
260	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST), 0, "NV cleared");
261	TEST_EQ(sd->flags & VB2_SD_FLAG_MANUAL_RECOVERY,
262		0, "Not manual recovery");
263	TEST_NEQ(cc.flags & VB2_CONTEXT_RECOVERY_MODE,
264		 0, "Recovery mode");
265
266	/* From request, but already failed */
267	reset_common_data();
268	vb2_nv_set(&cc, VB2_NV_RECOVERY_REQUEST, 4);
269	sd->recovery_reason = 5;
270	vb2_check_recovery(&cc);
271	TEST_EQ(sd->recovery_reason, 5, "Recovery reason already failed");
272	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
273		0, "NV still cleared");
274
275	/* Override */
276	reset_common_data();
277	sd->recovery_reason = 6;
278	cc.flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
279	vb2_check_recovery(&cc);
280	TEST_EQ(sd->recovery_reason, VB2_RECOVERY_RO_MANUAL,
281		"Recovery reason forced");
282	TEST_NEQ(sd->flags & VB2_SD_FLAG_MANUAL_RECOVERY,
283		 0, "SD flag set");
284}
285
286static void dev_switch_tests(void)
287{
288	uint32_t v;
289
290	/* Normal mode */
291	reset_common_data();
292	TEST_SUCC(vb2_check_dev_switch(&cc), "dev mode off");
293	TEST_EQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, "sd not in dev");
294	TEST_EQ(cc.flags & VB2_CONTEXT_DEVELOPER_MODE, 0, "ctx not in dev");
295	TEST_EQ(mock_tpm_clear_called, 0, "no tpm clear");
296
297	/* Dev mode */
298	reset_common_data();
299	vb2_secdata_set(&cc, VB2_SECDATA_FLAGS,
300			(VB2_SECDATA_FLAG_DEV_MODE |
301			 VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER));
302	TEST_SUCC(vb2_check_dev_switch(&cc), "dev mode on");
303	TEST_NEQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, "sd in dev");
304	TEST_NEQ(cc.flags & VB2_CONTEXT_DEVELOPER_MODE, 0, "ctx in dev");
305	TEST_EQ(mock_tpm_clear_called, 0, "no tpm clear");
306
307	/* Any normal mode boot clears dev boot flags */
308	reset_common_data();
309	vb2_nv_set(&cc, VB2_NV_DEV_BOOT_USB, 1);
310	vb2_nv_set(&cc, VB2_NV_DEV_BOOT_LEGACY, 1);
311	vb2_nv_set(&cc, VB2_NV_DEV_BOOT_SIGNED_ONLY, 1);
312	TEST_SUCC(vb2_check_dev_switch(&cc), "dev mode off");
313	TEST_EQ(vb2_nv_get(&cc, VB2_NV_DEV_BOOT_USB),
314		0, "cleared dev boot usb");
315	TEST_EQ(vb2_nv_get(&cc, VB2_NV_DEV_BOOT_LEGACY),
316		0, "cleared dev boot legacy");
317	TEST_EQ(vb2_nv_get(&cc, VB2_NV_DEV_BOOT_SIGNED_ONLY),
318		0, "cleared dev boot signed only");
319
320	/* Normal-dev transition clears TPM */
321	reset_common_data();
322	vb2_secdata_set(&cc, VB2_SECDATA_FLAGS, VB2_SECDATA_FLAG_DEV_MODE);
323	TEST_SUCC(vb2_check_dev_switch(&cc), "to dev mode");
324	TEST_EQ(mock_tpm_clear_called, 1, "tpm clear");
325	vb2_secdata_get(&cc, VB2_SECDATA_FLAGS, &v);
326	TEST_EQ(v, (VB2_SECDATA_FLAG_DEV_MODE |
327		    VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER),
328		"last boot developer now");
329
330	/* Dev-normal transition clears TPM too */
331	reset_common_data();
332	vb2_secdata_set(&cc, VB2_SECDATA_FLAGS,
333			VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER);
334	TEST_SUCC(vb2_check_dev_switch(&cc), "from dev mode");
335	TEST_EQ(mock_tpm_clear_called, 1, "tpm clear");
336	vb2_secdata_get(&cc, VB2_SECDATA_FLAGS, &v);
337	TEST_EQ(v, 0, "last boot not developer now");
338
339	/* Disable dev mode */
340	reset_common_data();
341	vb2_secdata_set(&cc, VB2_SECDATA_FLAGS,
342			(VB2_SECDATA_FLAG_DEV_MODE |
343			 VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER));
344	vb2_nv_set(&cc, VB2_NV_DISABLE_DEV_REQUEST, 1);
345	TEST_SUCC(vb2_check_dev_switch(&cc), "disable dev request");
346	TEST_EQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, "sd not in dev");
347	TEST_EQ(vb2_nv_get(&cc, VB2_NV_DISABLE_DEV_REQUEST),
348		0, "request cleared");
349
350	/* Force enabled by gbb */
351	reset_common_data();
352	sd->gbb_flags |= VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON;
353	TEST_SUCC(vb2_check_dev_switch(&cc), "dev on via gbb");
354	TEST_NEQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, "sd in dev");
355	vb2_secdata_get(&cc, VB2_SECDATA_FLAGS, &v);
356	TEST_EQ(v, VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER,
357		"doesn't set dev on in secdata but does set last boot dev");
358	TEST_EQ(mock_tpm_clear_called, 1, "tpm clear");
359
360	/* Force enabled by ctx flag */
361	reset_common_data();
362	cc.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;
363	TEST_SUCC(vb2_check_dev_switch(&cc), "dev on via ctx flag");
364	TEST_NEQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, "sd in dev");
365	vb2_secdata_get(&cc, VB2_SECDATA_FLAGS, &v);
366	TEST_EQ(v, VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER,
367		"doesn't set dev on in secdata but does set last boot dev");
368	TEST_EQ(mock_tpm_clear_called, 1, "tpm clear");
369
370	/* Simulate clear owner failure */
371	reset_common_data();
372	vb2_secdata_set(&cc, VB2_SECDATA_FLAGS,
373			VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER);
374	mock_tpm_clear_retval = VB2_ERROR_EX_TPM_CLEAR_OWNER;
375	TEST_EQ(vb2_check_dev_switch(&cc),
376		VB2_ERROR_EX_TPM_CLEAR_OWNER, "tpm clear fail");
377	TEST_EQ(mock_tpm_clear_called, 1, "tpm clear");
378	vb2_secdata_get(&cc, VB2_SECDATA_FLAGS, &v);
379	TEST_EQ(v, VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER,
380		"last boot still developer");
381	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
382		VB2_RECOVERY_TPM_CLEAR_OWNER, "requests recovery");
383	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_SUBCODE),
384		(uint8_t)VB2_ERROR_EX_TPM_CLEAR_OWNER, "recovery subcode");
385}
386
387static void tpm_clear_tests(void)
388{
389	/* No clear request */
390	reset_common_data();
391	TEST_SUCC(vb2_check_tpm_clear(&cc), "no clear request");
392	TEST_EQ(mock_tpm_clear_called, 0, "tpm not cleared");
393
394	/* Successful request */
395	reset_common_data();
396	vb2_nv_set(&cc, VB2_NV_CLEAR_TPM_OWNER_REQUEST, 1);
397	TEST_SUCC(vb2_check_tpm_clear(&cc), "clear request");
398	TEST_EQ(vb2_nv_get(&cc, VB2_NV_CLEAR_TPM_OWNER_REQUEST),
399		0, "request cleared");
400	TEST_EQ(vb2_nv_get(&cc, VB2_NV_CLEAR_TPM_OWNER_DONE),
401		1, "done set");
402	TEST_EQ(mock_tpm_clear_called, 1, "tpm cleared");
403
404	/* Failed request */
405	reset_common_data();
406	mock_tpm_clear_retval = VB2_ERROR_EX_TPM_CLEAR_OWNER;
407	vb2_nv_set(&cc, VB2_NV_CLEAR_TPM_OWNER_REQUEST, 1);
408	TEST_EQ(vb2_check_tpm_clear(&cc),
409		VB2_ERROR_EX_TPM_CLEAR_OWNER, "clear failure");
410	TEST_EQ(vb2_nv_get(&cc, VB2_NV_CLEAR_TPM_OWNER_REQUEST),
411		0, "request cleared");
412	TEST_EQ(vb2_nv_get(&cc, VB2_NV_CLEAR_TPM_OWNER_DONE),
413		0, "done not set");
414}
415
416static void select_slot_tests(void)
417{
418	/* Slot A */
419	reset_common_data();
420	TEST_SUCC(vb2_select_fw_slot(&cc), "select slot A");
421	TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_RESULT),
422		VB2_FW_RESULT_UNKNOWN, "result unknown");
423	TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
424	TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_TRIED), 0, "tried A");
425	TEST_EQ(sd->fw_slot, 0, "selected A");
426	TEST_EQ(cc.flags & VB2_CONTEXT_FW_SLOT_B, 0, "didn't choose B");
427
428	/* Slot B */
429	reset_common_data();
430	vb2_nv_set(&cc, VB2_NV_TRY_NEXT, 1);
431	TEST_SUCC(vb2_select_fw_slot(&cc), "select slot B");
432	TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_RESULT),
433		VB2_FW_RESULT_UNKNOWN, "result unknown");
434	TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
435	TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_TRIED), 1, "tried B");
436	TEST_EQ(sd->fw_slot, 1, "selected B");
437	TEST_NEQ(cc.flags & VB2_CONTEXT_FW_SLOT_B, 0, "ctx says choose B");
438
439	/* Slot A ran out of tries */
440	reset_common_data();
441	vb2_nv_set(&cc, VB2_NV_FW_RESULT, VB2_FW_RESULT_TRYING);
442	TEST_SUCC(vb2_select_fw_slot(&cc), "select slot A out of tries");
443	TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_NEXT), 1, "try B next");
444	TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
445	TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_TRIED), 1, "tried B");
446	TEST_EQ(sd->fw_slot, 1, "selected B");
447	TEST_NEQ(cc.flags & VB2_CONTEXT_FW_SLOT_B, 0, "ctx says choose B");
448
449	/* Slot A used up a try */
450	reset_common_data();
451	vb2_nv_set(&cc, VB2_NV_TRY_COUNT, 3);
452	TEST_SUCC(vb2_select_fw_slot(&cc), "try slot A");
453	TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_RESULT),
454		VB2_FW_RESULT_TRYING, "result trying");
455	TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
456	TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_TRIED), 0, "tried A");
457	TEST_EQ(sd->fw_slot, 0, "selected A");
458	TEST_EQ(cc.flags & VB2_CONTEXT_FW_SLOT_B, 0, "didn't choose B");
459	TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_COUNT), 2, "tries decremented");
460
461	/* Tried/result get copied to the previous fields */
462	reset_common_data();
463	vb2_nv_set(&cc, VB2_NV_FW_TRIED, 0);
464	vb2_nv_set(&cc, VB2_NV_FW_RESULT, VB2_FW_RESULT_SUCCESS);
465	vb2_select_fw_slot(&cc);
466	TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_PREV_TRIED), 0, "prev A");
467	TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_PREV_RESULT),	VB2_FW_RESULT_SUCCESS,
468		"prev success");
469
470	reset_common_data();
471	vb2_nv_set(&cc, VB2_NV_FW_TRIED, 1);
472	vb2_nv_set(&cc, VB2_NV_FW_RESULT, VB2_FW_RESULT_FAILURE);
473	vb2_select_fw_slot(&cc);
474	TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_PREV_TRIED), 1, "prev B");
475	TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_PREV_RESULT),	VB2_FW_RESULT_FAILURE,
476		"prev failure");
477}
478
479int main(int argc, char* argv[])
480{
481	init_context_tests();
482	misc_tests();
483	gbb_tests();
484	fail_tests();
485	recovery_tests();
486	dev_switch_tests();
487	tpm_clear_tests();
488	select_slot_tests();
489
490	return gTestSuccess ? 0 : 255;
491}
492