Home | History | Annotate | Download | only in tests
      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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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