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