• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
18 static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]
19 	__attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
20 static struct vb2_context cc;
21 static struct vb2_shared_data *sd;
22 
23 /* Mocked function data */
24 enum vb2_resource_index mock_resource_index;
25 void *mock_resource_ptr;
26 uint32_t mock_resource_size;
27 int mock_tpm_clear_called;
28 int mock_tpm_clear_retval;
29 
30 
reset_common_data(void)31 static 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 
vb2ex_read_resource(struct vb2_context * ctx,enum vb2_resource_index index,uint32_t offset,void * buf,uint32_t size)53 int 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 
vb2ex_tpm_clear_owner(struct vb2_context * ctx)69 int 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 
init_context_tests(void)78 static 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 
misc_tests(void)110 static 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 
gbb_tests(void)123 static 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 
fail_tests(void)196 static 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 
recovery_tests(void)244 static 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 
dev_switch_tests(void)286 static 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 
tpm_clear_tests(void)387 static 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 
select_slot_tests(void)416 static 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 
main(int argc,char * argv[])479 int 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