1 /* Copyright (c) 2012 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 vboot_firmware library. 6 */ 7 8 #include <stdint.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 13 #include "gbb_header.h" 14 #include "host_common.h" 15 #include "load_firmware_fw.h" 16 #include "test_common.h" 17 #include "vboot_common.h" 18 #include "vboot_nvstorage.h" 19 #include "vboot_struct.h" 20 21 /* Mock data */ 22 static VbCommonParams cparams; 23 static VbSelectFirmwareParams fparams; 24 static VbKeyBlockHeader vblock[2]; 25 static VbFirmwarePreambleHeader mpreamble[2]; 26 static VbNvContext vnc; 27 static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE]; 28 static VbSharedDataHeader* shared = (VbSharedDataHeader*)shared_data; 29 static uint8_t gbb_data[sizeof(GoogleBinaryBlockHeader) + 2048]; 30 static GoogleBinaryBlockHeader* gbb = (GoogleBinaryBlockHeader*)gbb_data; 31 static RSAPublicKey data_key; 32 static uint32_t digest_size; 33 static uint8_t* digest_returned; 34 static uint8_t* digest_expect_ptr; 35 static int hash_fw_index; 36 37 #define TEST_KEY_DATA \ 38 "Test contents for the root key this should be 64 chars long." 39 40 /* Reset mock data (for use before each test) */ 41 static void ResetMocks(void) { 42 VbPublicKey *root_key; 43 uint8_t *root_key_data; 44 int i; 45 46 Memset(&cparams, 0, sizeof(cparams)); 47 cparams.shared_data_blob = shared_data; 48 cparams.gbb_data = gbb_data; 49 cparams.gbb_size = sizeof(gbb_data); 50 cparams.gbb = gbb; 51 52 Memset(&fparams, 0, sizeof(fparams)); 53 fparams.verification_block_A = vblock; 54 fparams.verification_size_A = sizeof(VbKeyBlockHeader); 55 fparams.verification_block_B = vblock + 1; 56 fparams.verification_size_B = sizeof(VbKeyBlockHeader); 57 58 Memset(vblock, 0, sizeof(vblock)); 59 Memset(mpreamble, 0, sizeof(mpreamble)); 60 for (i = 0; i < 2; i++) { 61 /* Default verification blocks to working in all modes */ 62 vblock[i].key_block_flags = 0x0F; 63 vblock[i].data_key.key_version = 2; 64 /* Fix up offsets to preambles */ 65 vblock[i].key_block_size = 66 (uint8_t*)(mpreamble + i) - (uint8_t*)(vblock + i); 67 68 mpreamble[i].header_version_minor = 1; /* Supports preamble flags */ 69 mpreamble[i].firmware_version = 4; 70 /* Point kernel subkey to some data following the key header */ 71 PublicKeyInit(&mpreamble[i].kernel_subkey, 72 (uint8_t*)&mpreamble[i].body_signature, 20); 73 mpreamble[i].kernel_subkey.algorithm = 7 + i; 74 mpreamble[i].body_signature.data_size = 20000 + 1000 * i; 75 } 76 77 Memset(&vnc, 0, sizeof(vnc)); 78 VbNvSetup(&vnc); 79 80 Memset(&shared_data, 0, sizeof(shared_data)); 81 VbSharedDataInit(shared, sizeof(shared_data)); 82 shared->fw_version_tpm = 0x00020004; 83 84 Memset(&gbb_data, 0, sizeof(gbb_data)); 85 gbb->rootkey_offset = sizeof(GoogleBinaryBlockHeader); 86 root_key = (VbPublicKey *)(gbb_data + gbb->rootkey_offset); 87 root_key_data = (uint8_t *)(root_key + 1); 88 strcpy((char *)root_key_data, TEST_KEY_DATA); 89 PublicKeyInit(root_key, (uint8_t *)root_key_data, sizeof(TEST_KEY_DATA)); 90 91 gbb->major_version = GBB_MAJOR_VER; 92 gbb->minor_version = GBB_MINOR_VER; 93 gbb->flags = 0; 94 95 Memset(&data_key, 0, sizeof(data_key)); 96 97 digest_size = 1234; 98 digest_returned = NULL; 99 digest_expect_ptr = NULL; 100 hash_fw_index = -1; 101 } 102 103 /****************************************************************************/ 104 /* Mocked verification functions */ 105 106 int KeyBlockVerify(const VbKeyBlockHeader* block, uint64_t size, 107 const VbPublicKey *key, int hash_only) { 108 109 TEST_EQ(hash_only, 0, " Don't verify firmware with hash"); 110 111 /* 112 * We cannot check the address of key, since it will be allocated. We 113 * check the contents instead. 114 */ 115 TEST_STR_EQ((char *)GetPublicKeyDataC(key), TEST_KEY_DATA, 116 " Verify with root key"); 117 TEST_NEQ(block==vblock || block==vblock+1, 0, " Verify a valid key block"); 118 119 /* Mock uses header_version_major to hold return value */ 120 return block->header_version_major; 121 } 122 123 int VerifyFirmwarePreamble(const VbFirmwarePreambleHeader* preamble, 124 uint64_t size, const RSAPublicKey* key) { 125 TEST_PTR_EQ(key, &data_key, " Verify preamble data key"); 126 TEST_NEQ(preamble==mpreamble || preamble==mpreamble+1, 0, 127 " Verify a valid preamble"); 128 129 /* Mock uses header_version_major to hold return value */ 130 return preamble->header_version_major; 131 } 132 133 RSAPublicKey* PublicKeyToRSA(const VbPublicKey* key) { 134 /* Mock uses algorithm!0 to mean invalid key */ 135 if (key->algorithm) 136 return NULL; 137 /* Mock uses data key len to hold number of alloc'd keys */ 138 data_key.len++; 139 return &data_key; 140 } 141 142 void RSAPublicKeyFree(RSAPublicKey* key) { 143 TEST_PTR_EQ(key, &data_key, " RSA data key"); 144 data_key.len--; 145 } 146 147 void DigestInit(DigestContext* ctx, int sig_algorithm) { 148 digest_size = 0; 149 } 150 151 void DigestUpdate(DigestContext* ctx, const uint8_t* data, uint32_t len) { 152 TEST_PTR_EQ(data, digest_expect_ptr, " Digesting expected data"); 153 digest_size += len; 154 } 155 156 uint8_t* DigestFinal(DigestContext* ctx) { 157 digest_returned = (uint8_t*)VbExMalloc(4); 158 return digest_returned; 159 } 160 161 VbError_t VbExHashFirmwareBody(VbCommonParams* cparams, 162 uint32_t firmware_index) { 163 if (VB_SELECT_FIRMWARE_A == firmware_index) 164 hash_fw_index = 0; 165 else if (VB_SELECT_FIRMWARE_B == firmware_index) 166 hash_fw_index = 1; 167 else 168 return VBERROR_INVALID_PARAMETER; 169 170 digest_expect_ptr = (uint8_t*)(vblock + hash_fw_index) + 5; 171 VbUpdateFirmwareBodyHash( 172 cparams, digest_expect_ptr, 173 mpreamble[hash_fw_index].body_signature.data_size - 1024); 174 VbUpdateFirmwareBodyHash(cparams, digest_expect_ptr, 1024); 175 176 /* If signature offset is 42, hash the wrong amount and return success */ 177 if (42 == mpreamble[hash_fw_index].body_signature.sig_offset) { 178 VbUpdateFirmwareBodyHash(cparams, digest_expect_ptr, 4); 179 return VBERROR_SUCCESS; 180 } 181 182 /* Otherwise, mocked function uses body signature offset as returned value */ 183 return mpreamble[hash_fw_index].body_signature.sig_offset; 184 } 185 186 int VerifyDigest(const uint8_t* digest, const VbSignature *sig, 187 const RSAPublicKey* key) { 188 TEST_PTR_EQ(digest, digest_returned, "Verifying expected digest"); 189 TEST_PTR_EQ(key, &data_key, "Verifying using data key"); 190 TEST_PTR_EQ(sig, &mpreamble[hash_fw_index].body_signature, "Verifying sig"); 191 /* Mocked function uses sig size as return value for verifying digest */ 192 return sig->sig_size; 193 } 194 195 /****************************************************************************/ 196 /* Test LoadFirmware() and check expected return value and recovery reason */ 197 static void TestLoadFirmware(VbError_t expected_retval, 198 uint8_t expected_recovery, const char* desc) { 199 uint32_t rr = 256; 200 201 TEST_EQ(LoadFirmware(&cparams, &fparams, &vnc), expected_retval, desc); 202 VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &rr); 203 TEST_EQ(rr, expected_recovery, " recovery request"); 204 TEST_EQ(data_key.len, 0, " Data key free must be paired with alloc"); 205 } 206 207 /****************************************************************************/ 208 209 static void LoadFirmwareTest(void) { 210 uint32_t u; 211 212 /* Require GBB */ 213 ResetMocks(); 214 cparams.gbb_data = NULL; 215 TestLoadFirmware(VBERROR_INVALID_GBB, VBNV_RECOVERY_RO_UNSPECIFIED, 216 "No GBB"); 217 218 /* Key block flags must match */ 219 /* Normal boot */ 220 ResetMocks(); 221 vblock[0].key_block_flags = KEY_BLOCK_FLAG_DEVELOPER_1; 222 vblock[1].key_block_flags = 223 KEY_BLOCK_FLAG_DEVELOPER_0 | KEY_BLOCK_FLAG_RECOVERY_1; 224 TestLoadFirmware(VBERROR_LOAD_FIRMWARE, 225 (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + 226 VBSD_LF_CHECK_REC_MISMATCH), 227 "Flags mismatch dev=0"); 228 TEST_EQ(shared->flags & VBSD_LF_DEV_SWITCH_ON, 0, 229 "Dev flag in shared.flags dev=0"); 230 TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_DEV_MISMATCH, 231 "Key block flag mismatch for dev=0"); 232 TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_REC_MISMATCH, 233 "Key block flag mismatch for rec=0"); 234 /* Developer boot */ 235 ResetMocks(); 236 shared->flags |= VBSD_BOOT_DEV_SWITCH_ON; 237 vblock[0].key_block_flags = KEY_BLOCK_FLAG_DEVELOPER_0; 238 vblock[1].key_block_flags = 239 KEY_BLOCK_FLAG_DEVELOPER_1 | KEY_BLOCK_FLAG_RECOVERY_1; 240 TestLoadFirmware(VBERROR_LOAD_FIRMWARE, 241 (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + 242 VBSD_LF_CHECK_REC_MISMATCH), 243 "Flags mismatch dev=1"); 244 TEST_NEQ(shared->flags & VBSD_LF_DEV_SWITCH_ON, 0, 245 "Dev flag in shared.flags dev=1"); 246 TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_DEV_MISMATCH, 247 "Key block flag mismatch for dev=1"); 248 TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_REC_MISMATCH, 249 "Key block flag mismatch for rec=1"); 250 251 /* Test key block verification with A and key version rollback with B */ 252 ResetMocks(); 253 vblock[0].header_version_major = 1; /* Simulate failure */ 254 vblock[1].data_key.key_version = 1; /* Simulate rollback */ 255 TestLoadFirmware(VBERROR_LOAD_FIRMWARE, 256 (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + 257 VBSD_LF_CHECK_KEY_ROLLBACK), 258 "Key block invalid / key version rollback"); 259 TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VERIFY_KEYBLOCK, 260 "Key block invalid"); 261 TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_KEY_ROLLBACK, 262 "Key version rollback "); 263 TEST_EQ(shared->fw_version_lowest, 0, "Lowest valid version"); 264 TEST_EQ(shared->fw_version_tpm, 0x20004, "TPM version"); 265 266 /* Test invalid key version with A and bad data key with B */ 267 ResetMocks(); 268 vblock[0].data_key.key_version = 0x10003; /* Version > 0xFFFF is invalid */ 269 vblock[1].data_key.algorithm = 1; /* Simulate invalid data key */ 270 TestLoadFirmware(VBERROR_LOAD_FIRMWARE, 271 (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + 272 VBSD_LF_CHECK_DATA_KEY_PARSE), 273 "Key version overflow / invalid data key"); 274 TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_KEY_ROLLBACK, 275 "Key version overflow"); 276 TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_DATA_KEY_PARSE, 277 "Data key invalid"); 278 279 /* Test invalid key version with GBB bypass-rollback flag */ 280 ResetMocks(); 281 vblock[0].data_key.key_version = 1; /* Simulate rollback */ 282 gbb->flags = GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK; 283 TestLoadFirmware(VBERROR_SUCCESS, 0, "Key version check + GBB override"); 284 TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID, 285 "Key version rollback + GBB override"); 286 287 /* Test invalid preamble with A */ 288 ResetMocks(); 289 mpreamble[0].header_version_major = 1; /* Simulate failure */ 290 vblock[1].key_block_flags = 0; /* Invalid */ 291 TestLoadFirmware(VBERROR_LOAD_FIRMWARE, 292 (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + 293 VBSD_LF_CHECK_VERIFY_PREAMBLE), 294 "Preamble invalid"); 295 TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VERIFY_PREAMBLE, 296 "Preamble invalid A"); 297 298 /* Test invalid firmware versions */ 299 ResetMocks(); 300 mpreamble[0].firmware_version = 3; /* Simulate rollback */ 301 mpreamble[1].firmware_version = 0x10001; /* Check overflow */ 302 TestLoadFirmware(VBERROR_LOAD_FIRMWARE, 303 (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + 304 VBSD_LF_CHECK_FW_ROLLBACK), 305 "Firmware version check"); 306 TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_FW_ROLLBACK, 307 "Firmware version rollback"); 308 TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_FW_ROLLBACK, 309 "Firmware version overflow"); 310 311 /* Test invalid firmware versions with GBB bypass-rollback flag */ 312 ResetMocks(); 313 mpreamble[0].firmware_version = 3; /* Simulate rollback */ 314 mpreamble[1].firmware_version = 0x10001; /* Check overflow */ 315 gbb->flags = GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK; 316 TestLoadFirmware(VBERROR_SUCCESS, 0, "Firmware version check + GBB bypass"); 317 TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID, 318 "Firmware version rollback + GBB override"); 319 TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_HEADER_VALID, 320 "Firmware version overflow + GBB override"); 321 322 /* Test RO normal with A */ 323 ResetMocks(); 324 mpreamble[0].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL; 325 vblock[1].key_block_flags = 0; /* Invalid */ 326 TestLoadFirmware(VBERROR_LOAD_FIRMWARE, 327 (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + 328 VBSD_LF_CHECK_NO_RO_NORMAL), 329 "Preamble asked for RO normal but fw doesn't support it"); 330 TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_NO_RO_NORMAL, 331 "No RO normal A"); 332 333 /* If RO normal is supported, don't need to verify the firmware body */ 334 ResetMocks(); 335 mpreamble[0].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL; 336 /* Mock bad sig, to ensure we didn't use it */ 337 mpreamble[0].body_signature.sig_size = 1; 338 shared->flags |= VBSD_BOOT_RO_NORMAL_SUPPORT; 339 vblock[1].key_block_flags = 0; /* Invalid */ 340 TestLoadFirmware(VBERROR_SUCCESS, 0, "RO normal A"); 341 TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID, "RO normal A valid"); 342 TEST_EQ(shared->firmware_index, 0, "Boot A shared index"); 343 TEST_EQ(shared->fw_keyblock_flags, vblock[0].key_block_flags, 344 "Copy key block flags"); 345 TEST_EQ(shared->kernel_subkey.algorithm, 7, "Copy kernel subkey"); 346 347 /* If both A and B are valid and same version as TPM, A is selected 348 * and B isn't attempted. */ 349 ResetMocks(); 350 mpreamble[0].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL; 351 mpreamble[1].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL; 352 shared->flags |= VBSD_BOOT_RO_NORMAL_SUPPORT; 353 TestLoadFirmware(VBERROR_SUCCESS, 0, "Check A then B"); 354 TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID, "RO normal A valid"); 355 TEST_EQ(shared->check_fw_b_result, 0, "RO normal B not checked "); 356 TEST_EQ(shared->firmware_index, 0, "Boot A"); 357 TEST_EQ(shared->flags & VBSD_FWB_TRIED, 0, "Didn't try firmware B"); 358 TEST_EQ(shared->kernel_subkey.algorithm, 7, "Copy kernel subkey"); 359 /* But if try B flag is set, B is selected and A not attempted */ 360 ResetMocks(); 361 mpreamble[0].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL; 362 mpreamble[1].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL; 363 shared->flags |= VBSD_BOOT_RO_NORMAL_SUPPORT; 364 VbNvSet(&vnc, VBNV_TRY_B_COUNT, 5); 365 TestLoadFirmware(VBERROR_SUCCESS, 0, "Check B then A"); 366 TEST_EQ(shared->check_fw_a_result, 0, "RO normal A not checked "); 367 TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_VALID, "RO normal B valid"); 368 TEST_EQ(shared->firmware_index, 1, "Boot B"); 369 TEST_NEQ(shared->flags & VBSD_FWB_TRIED, 0, "Tried firmware B"); 370 TEST_EQ(shared->kernel_subkey.algorithm, 8, "Copy kernel subkey"); 371 VbNvGet(&vnc, VBNV_TRY_B_COUNT, &u); 372 TEST_EQ(u, 4, "Used up a try"); 373 374 /* If both A and B are valid and grater version than TPM, A is 375 * selected and B preamble (but not body) is verified. */ 376 ResetMocks(); 377 mpreamble[0].flags = VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL; 378 mpreamble[1].flags = 0; 379 mpreamble[0].firmware_version = 5; 380 mpreamble[1].firmware_version = 6; 381 shared->flags |= VBSD_BOOT_RO_NORMAL_SUPPORT; 382 TestLoadFirmware(VBERROR_SUCCESS, 0, "Check A then B advancing version"); 383 TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID, "RO normal A valid"); 384 TEST_EQ(shared->check_fw_b_result, VBSD_LF_CHECK_HEADER_VALID, 385 "RO normal B header valid"); 386 TEST_EQ(shared->firmware_index, 0, "Boot A"); 387 TEST_EQ(shared->fw_keyblock_flags, vblock[0].key_block_flags, "Key block A"); 388 TEST_EQ(shared->kernel_subkey.algorithm, 7, "Copy kernel subkey"); 389 TEST_EQ(shared->fw_version_lowest, 0x20005, "Lowest valid version"); 390 TEST_EQ(shared->fw_version_tpm, 0x20005, "TPM version advanced"); 391 392 /* Verify firmware data */ 393 ResetMocks(); 394 vblock[1].key_block_flags = 0; /* Invalid */ 395 TestLoadFirmware(VBERROR_SUCCESS, 0, "Verify firmware body"); 396 TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID, 397 "Firmware body A valid"); 398 TEST_EQ(shared->firmware_index, 0, "Boot A shared index"); 399 TEST_EQ(hash_fw_index, 0, "Hash firmware data A"); 400 TEST_EQ(digest_size, mpreamble[0].body_signature.data_size, 401 "Verified all data expected"); 402 403 /* Test error getting firmware body */ 404 ResetMocks(); 405 mpreamble[0].body_signature.sig_offset = VBERROR_UNKNOWN; 406 vblock[1].key_block_flags = 0; /* Invalid */ 407 TestLoadFirmware(VBERROR_LOAD_FIRMWARE, 408 (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + 409 VBSD_LF_CHECK_GET_FW_BODY), 410 "Error getting firmware body"); 411 TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_GET_FW_BODY, 412 "Firmware body A"); 413 414 /* Test digesting the wrong amount */ 415 ResetMocks(); 416 mpreamble[0].body_signature.sig_offset = 42; /* Mock hashing wrong amount */ 417 vblock[1].key_block_flags = 0; /* Invalid */ 418 TestLoadFirmware(VBERROR_LOAD_FIRMWARE, 419 (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + 420 VBSD_LF_CHECK_HASH_WRONG_SIZE), 421 "Hash wrong size"); 422 TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_HASH_WRONG_SIZE, 423 "Firmware hash wrong size A"); 424 425 /* Test bad signature */ 426 ResetMocks(); 427 mpreamble[0].body_signature.sig_size = 1; /* Mock bad sig */ 428 vblock[1].key_block_flags = 0; /* Invalid */ 429 TestLoadFirmware(VBERROR_LOAD_FIRMWARE, 430 (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + 431 VBSD_LF_CHECK_VERIFY_BODY), 432 "Bad signature"); 433 TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VERIFY_BODY, 434 "Bad signature A"); 435 436 /* Test unable to store kernel data key */ 437 ResetMocks(); 438 mpreamble[0].kernel_subkey.key_size = VB_SHARED_DATA_MIN_SIZE + 1; 439 vblock[1].key_block_flags = 0; /* Invalid */ 440 TestLoadFirmware(VBERROR_LOAD_FIRMWARE, 441 (VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + 442 VBSD_LF_CHECK_VALID), 443 "Kernel key too big"); 444 TEST_EQ(shared->check_fw_a_result, VBSD_LF_CHECK_VALID, 445 "Kernel key too big"); 446 } 447 448 449 int main(int argc, char* argv[]) { 450 int error_code = 0; 451 452 LoadFirmwareTest(); 453 454 if (vboot_api_stub_check_memory()) 455 error_code = 255; 456 if (!gTestSuccess) 457 error_code = 255; 458 459 return error_code; 460 } 461