1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * SPDX-License-Identifier: MIT 5 */ 6 7 #include "avb_slot_verify.h" 8 #include "avb_chain_partition_descriptor.h" 9 #include "avb_cmdline.h" 10 #include "avb_footer.h" 11 #include "avb_hash_descriptor.h" 12 #include "avb_hashtree_descriptor.h" 13 #include "avb_kernel_cmdline_descriptor.h" 14 #include "avb_sha.h" 15 #include "avb_util.h" 16 #include "avb_vbmeta_image.h" 17 #include "avb_version.h" 18 19 /* Maximum number of partitions that can be loaded with avb_slot_verify(). */ 20 #define MAX_NUMBER_OF_LOADED_PARTITIONS 32 21 22 /* Maximum number of vbmeta images that can be loaded with avb_slot_verify(). */ 23 #define MAX_NUMBER_OF_VBMETA_IMAGES 32 24 25 /* Maximum size of a vbmeta image - 64 KiB. */ 26 #define VBMETA_MAX_SIZE (64 * 1024) 27 28 /* Helper function to see if we should continue with verification in 29 * allow_verification_error=true mode if something goes wrong. See the 30 * comments for the avb_slot_verify() function for more information. 31 */ 32 static inline bool result_should_continue(AvbSlotVerifyResult result) { 33 switch (result) { 34 case AVB_SLOT_VERIFY_RESULT_ERROR_OOM: 35 case AVB_SLOT_VERIFY_RESULT_ERROR_IO: 36 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA: 37 case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION: 38 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT: 39 return false; 40 41 case AVB_SLOT_VERIFY_RESULT_OK: 42 case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION: 43 case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX: 44 case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED: 45 return true; 46 } 47 48 return false; 49 } 50 51 static AvbSlotVerifyResult load_full_partition(AvbOps* ops, 52 const char* part_name, 53 uint64_t image_size, 54 uint8_t** out_image_buf, 55 bool* out_image_preloaded) { 56 size_t part_num_read; 57 AvbIOResult io_ret; 58 59 /* Make sure that we do not overwrite existing data. */ 60 avb_assert(*out_image_buf == NULL); 61 avb_assert(!*out_image_preloaded); 62 63 /* We are going to implicitly cast image_size from uint64_t to size_t in the 64 * following code, so we need to make sure that the cast is safe. */ 65 if (image_size != (size_t)(image_size)) { 66 avb_errorv(part_name, ": Partition size too large to load.\n", NULL); 67 return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 68 } 69 70 /* Try use a preloaded one. */ 71 if (ops->get_preloaded_partition != NULL) { 72 io_ret = ops->get_preloaded_partition( 73 ops, part_name, image_size, out_image_buf, &part_num_read); 74 if (io_ret == AVB_IO_RESULT_ERROR_OOM) { 75 return AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 76 } else if (io_ret != AVB_IO_RESULT_OK) { 77 avb_errorv(part_name, ": Error loading data from partition.\n", NULL); 78 return AVB_SLOT_VERIFY_RESULT_ERROR_IO; 79 } 80 81 if (*out_image_buf != NULL) { 82 if (part_num_read != image_size) { 83 avb_errorv(part_name, ": Read incorrect number of bytes.\n", NULL); 84 return AVB_SLOT_VERIFY_RESULT_ERROR_IO; 85 } 86 *out_image_preloaded = true; 87 } 88 } 89 90 /* Allocate and copy the partition. */ 91 if (!*out_image_preloaded) { 92 *out_image_buf = avb_malloc(image_size); 93 if (*out_image_buf == NULL) { 94 return AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 95 } 96 97 io_ret = ops->read_from_partition(ops, 98 part_name, 99 0 /* offset */, 100 image_size, 101 *out_image_buf, 102 &part_num_read); 103 if (io_ret == AVB_IO_RESULT_ERROR_OOM) { 104 return AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 105 } else if (io_ret != AVB_IO_RESULT_OK) { 106 avb_errorv(part_name, ": Error loading data from partition.\n", NULL); 107 return AVB_SLOT_VERIFY_RESULT_ERROR_IO; 108 } 109 if (part_num_read != image_size) { 110 avb_errorv(part_name, ": Read incorrect number of bytes.\n", NULL); 111 return AVB_SLOT_VERIFY_RESULT_ERROR_IO; 112 } 113 } 114 115 return AVB_SLOT_VERIFY_RESULT_OK; 116 } 117 118 static AvbSlotVerifyResult read_persistent_digest(AvbOps* ops, 119 const char* part_name, 120 size_t expected_digest_size, 121 uint8_t* out_digest) { 122 char* persistent_value_name = NULL; 123 AvbIOResult io_ret = AVB_IO_RESULT_OK; 124 size_t stored_digest_size = 0; 125 126 if (ops->read_persistent_value == NULL) { 127 avb_errorv(part_name, ": Persistent values are not implemented.\n", NULL); 128 return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 129 } 130 persistent_value_name = 131 avb_strdupv(AVB_NPV_PERSISTENT_DIGEST_PREFIX, part_name, NULL); 132 if (persistent_value_name == NULL) { 133 return AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 134 } 135 io_ret = ops->read_persistent_value(ops, 136 persistent_value_name, 137 expected_digest_size, 138 out_digest, 139 &stored_digest_size); 140 avb_free(persistent_value_name); 141 if (io_ret == AVB_IO_RESULT_ERROR_OOM) { 142 return AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 143 } else if (io_ret == AVB_IO_RESULT_ERROR_NO_SUCH_VALUE) { 144 avb_errorv(part_name, ": Persistent digest does not exist.\n", NULL); 145 return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 146 } else if (io_ret == AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE || 147 io_ret == AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE || 148 expected_digest_size != stored_digest_size) { 149 avb_errorv( 150 part_name, ": Persistent digest is not of expected size.\n", NULL); 151 return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 152 } else if (io_ret != AVB_IO_RESULT_OK) { 153 avb_errorv(part_name, ": Error reading persistent digest.\n", NULL); 154 return AVB_SLOT_VERIFY_RESULT_ERROR_IO; 155 } 156 return AVB_SLOT_VERIFY_RESULT_OK; 157 } 158 159 static AvbSlotVerifyResult load_and_verify_hash_partition( 160 AvbOps* ops, 161 const char* const* requested_partitions, 162 const char* ab_suffix, 163 bool allow_verification_error, 164 const AvbDescriptor* descriptor, 165 AvbSlotVerifyData* slot_data) { 166 AvbHashDescriptor hash_desc; 167 const uint8_t* desc_partition_name = NULL; 168 const uint8_t* desc_salt; 169 const uint8_t* desc_digest; 170 char part_name[AVB_PART_NAME_MAX_SIZE]; 171 AvbSlotVerifyResult ret; 172 AvbIOResult io_ret; 173 uint8_t* image_buf = NULL; 174 bool image_preloaded = false; 175 uint8_t* digest; 176 size_t digest_len; 177 const char* found; 178 uint64_t image_size; 179 size_t expected_digest_len = 0; 180 uint8_t expected_digest_buf[AVB_SHA512_DIGEST_SIZE]; 181 const uint8_t* expected_digest = NULL; 182 183 if (!avb_hash_descriptor_validate_and_byteswap( 184 (const AvbHashDescriptor*)descriptor, &hash_desc)) { 185 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 186 goto out; 187 } 188 189 desc_partition_name = 190 ((const uint8_t*)descriptor) + sizeof(AvbHashDescriptor); 191 desc_salt = desc_partition_name + hash_desc.partition_name_len; 192 desc_digest = desc_salt + hash_desc.salt_len; 193 194 if (!avb_validate_utf8(desc_partition_name, hash_desc.partition_name_len)) { 195 avb_error("Partition name is not valid UTF-8.\n"); 196 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 197 goto out; 198 } 199 200 /* Don't bother loading or validating unless the partition was 201 * requested in the first place. 202 */ 203 found = avb_strv_find_str(requested_partitions, 204 (const char*)desc_partition_name, 205 hash_desc.partition_name_len); 206 if (found == NULL) { 207 ret = AVB_SLOT_VERIFY_RESULT_OK; 208 goto out; 209 } 210 211 if ((hash_desc.flags & AVB_HASH_DESCRIPTOR_FLAGS_DO_NOT_USE_AB) != 0) { 212 /* No ab_suffix, just copy the partition name as is. */ 213 if (hash_desc.partition_name_len >= AVB_PART_NAME_MAX_SIZE) { 214 avb_error("Partition name does not fit.\n"); 215 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 216 goto out; 217 } 218 avb_memcpy(part_name, desc_partition_name, hash_desc.partition_name_len); 219 part_name[hash_desc.partition_name_len] = '\0'; 220 } else if (hash_desc.digest_len == 0 && avb_strlen(ab_suffix) != 0) { 221 /* No ab_suffix allowed for partitions without a digest in the descriptor 222 * because these partitions hold data unique to this device and are not 223 * updated using an A/B scheme. 224 */ 225 avb_error("Cannot use A/B with a persistent digest.\n"); 226 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 227 goto out; 228 } else { 229 /* Add ab_suffix to the partition name. */ 230 if (!avb_str_concat(part_name, 231 sizeof part_name, 232 (const char*)desc_partition_name, 233 hash_desc.partition_name_len, 234 ab_suffix, 235 avb_strlen(ab_suffix))) { 236 avb_error("Partition name and suffix does not fit.\n"); 237 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 238 goto out; 239 } 240 } 241 242 /* If we're allowing verification errors then hash_desc.image_size 243 * may no longer match what's in the partition... so in this case 244 * just load the entire partition. 245 * 246 * For example, this can happen if a developer does 'fastboot flash 247 * boot /path/to/new/and/bigger/boot.img'. We want this to work 248 * since it's such a common workflow. 249 */ 250 image_size = hash_desc.image_size; 251 if (allow_verification_error) { 252 if (ops->get_size_of_partition == NULL) { 253 avb_errorv(part_name, 254 ": The get_size_of_partition() operation is " 255 "not implemented so we may not load the entire partition. " 256 "Please implement.", 257 NULL); 258 } else { 259 io_ret = ops->get_size_of_partition(ops, part_name, &image_size); 260 if (io_ret == AVB_IO_RESULT_ERROR_OOM) { 261 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 262 goto out; 263 } else if (io_ret != AVB_IO_RESULT_OK) { 264 avb_errorv(part_name, ": Error determining partition size.\n", NULL); 265 ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO; 266 goto out; 267 } 268 avb_debugv(part_name, ": Loading entire partition.\n", NULL); 269 } 270 } 271 272 ret = load_full_partition( 273 ops, part_name, image_size, &image_buf, &image_preloaded); 274 if (ret != AVB_SLOT_VERIFY_RESULT_OK) { 275 goto out; 276 } 277 278 if (avb_strcmp((const char*)hash_desc.hash_algorithm, "sha256") == 0) { 279 AvbSHA256Ctx sha256_ctx; 280 avb_sha256_init(&sha256_ctx); 281 avb_sha256_update(&sha256_ctx, desc_salt, hash_desc.salt_len); 282 avb_sha256_update(&sha256_ctx, image_buf, hash_desc.image_size); 283 digest = avb_sha256_final(&sha256_ctx); 284 digest_len = AVB_SHA256_DIGEST_SIZE; 285 } else if (avb_strcmp((const char*)hash_desc.hash_algorithm, "sha512") == 0) { 286 AvbSHA512Ctx sha512_ctx; 287 avb_sha512_init(&sha512_ctx); 288 avb_sha512_update(&sha512_ctx, desc_salt, hash_desc.salt_len); 289 avb_sha512_update(&sha512_ctx, image_buf, hash_desc.image_size); 290 digest = avb_sha512_final(&sha512_ctx); 291 digest_len = AVB_SHA512_DIGEST_SIZE; 292 } else { 293 avb_errorv(part_name, ": Unsupported hash algorithm.\n", NULL); 294 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 295 goto out; 296 } 297 298 if (hash_desc.digest_len == 0) { 299 // Expect a match to a persistent digest. 300 avb_debugv(part_name, ": No digest, using persistent digest.\n", NULL); 301 expected_digest_len = digest_len; 302 expected_digest = expected_digest_buf; 303 avb_assert(expected_digest_len <= sizeof(expected_digest_buf)); 304 ret = 305 read_persistent_digest(ops, part_name, digest_len, expected_digest_buf); 306 if (ret != AVB_SLOT_VERIFY_RESULT_OK) { 307 goto out; 308 } 309 } else { 310 // Expect a match to the digest in the descriptor. 311 expected_digest_len = hash_desc.digest_len; 312 expected_digest = desc_digest; 313 } 314 315 if (digest_len != expected_digest_len) { 316 avb_errorv( 317 part_name, ": Digest in descriptor not of expected size.\n", NULL); 318 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 319 goto out; 320 } 321 322 if (avb_safe_memcmp(digest, expected_digest, digest_len) != 0) { 323 avb_errorv(part_name, 324 ": Hash of data does not match digest in descriptor.\n", 325 NULL); 326 ret = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION; 327 goto out; 328 } 329 330 ret = AVB_SLOT_VERIFY_RESULT_OK; 331 332 out: 333 334 /* If it worked and something was loaded, copy to slot_data. */ 335 if ((ret == AVB_SLOT_VERIFY_RESULT_OK || result_should_continue(ret)) && 336 image_buf != NULL) { 337 AvbPartitionData* loaded_partition; 338 if (slot_data->num_loaded_partitions == MAX_NUMBER_OF_LOADED_PARTITIONS) { 339 avb_errorv(part_name, ": Too many loaded partitions.\n", NULL); 340 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 341 goto fail; 342 } 343 loaded_partition = 344 &slot_data->loaded_partitions[slot_data->num_loaded_partitions++]; 345 loaded_partition->partition_name = avb_strdup(found); 346 loaded_partition->data_size = image_size; 347 loaded_partition->data = image_buf; 348 loaded_partition->preloaded = image_preloaded; 349 image_buf = NULL; 350 } 351 352 fail: 353 if (image_buf != NULL && !image_preloaded) { 354 avb_free(image_buf); 355 } 356 return ret; 357 } 358 359 static AvbSlotVerifyResult load_requested_partitions( 360 AvbOps* ops, 361 const char* const* requested_partitions, 362 const char* ab_suffix, 363 AvbSlotVerifyData* slot_data) { 364 AvbSlotVerifyResult ret; 365 uint8_t* image_buf = NULL; 366 bool image_preloaded = false; 367 size_t n; 368 369 if (ops->get_size_of_partition == NULL) { 370 avb_error("get_size_of_partition() not implemented.\n"); 371 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT; 372 goto out; 373 } 374 375 for (n = 0; requested_partitions[n] != NULL; n++) { 376 char part_name[AVB_PART_NAME_MAX_SIZE]; 377 AvbIOResult io_ret; 378 uint64_t image_size; 379 AvbPartitionData* loaded_partition; 380 381 if (!avb_str_concat(part_name, 382 sizeof part_name, 383 requested_partitions[n], 384 avb_strlen(requested_partitions[n]), 385 ab_suffix, 386 avb_strlen(ab_suffix))) { 387 avb_error("Partition name and suffix does not fit.\n"); 388 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 389 goto out; 390 } 391 392 io_ret = ops->get_size_of_partition(ops, part_name, &image_size); 393 if (io_ret == AVB_IO_RESULT_ERROR_OOM) { 394 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 395 goto out; 396 } else if (io_ret != AVB_IO_RESULT_OK) { 397 avb_errorv(part_name, ": Error determining partition size.\n", NULL); 398 ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO; 399 goto out; 400 } 401 avb_debugv(part_name, ": Loading entire partition.\n", NULL); 402 403 ret = load_full_partition( 404 ops, part_name, image_size, &image_buf, &image_preloaded); 405 if (ret != AVB_SLOT_VERIFY_RESULT_OK) { 406 goto out; 407 } 408 409 /* Move to slot_data. */ 410 if (slot_data->num_loaded_partitions == MAX_NUMBER_OF_LOADED_PARTITIONS) { 411 avb_errorv(part_name, ": Too many loaded partitions.\n", NULL); 412 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 413 goto out; 414 } 415 loaded_partition = 416 &slot_data->loaded_partitions[slot_data->num_loaded_partitions++]; 417 loaded_partition->partition_name = avb_strdup(requested_partitions[n]); 418 if (loaded_partition->partition_name == NULL) { 419 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 420 goto out; 421 } 422 loaded_partition->data_size = image_size; 423 loaded_partition->data = image_buf; /* Transferring the owner. */ 424 loaded_partition->preloaded = image_preloaded; 425 image_buf = NULL; 426 image_preloaded = false; 427 } 428 429 ret = AVB_SLOT_VERIFY_RESULT_OK; 430 431 out: 432 /* Free the current buffer if any. */ 433 if (image_buf != NULL && !image_preloaded) { 434 avb_free(image_buf); 435 } 436 /* Buffers that are already saved in slot_data will be handled by the caller 437 * even on failure. */ 438 return ret; 439 } 440 441 static AvbSlotVerifyResult load_and_verify_vbmeta( 442 AvbOps* ops, 443 const char* const* requested_partitions, 444 const char* ab_suffix, 445 bool allow_verification_error, 446 AvbVBMetaImageFlags toplevel_vbmeta_flags, 447 int rollback_index_location, 448 const char* partition_name, 449 size_t partition_name_len, 450 const uint8_t* expected_public_key, 451 size_t expected_public_key_length, 452 AvbSlotVerifyData* slot_data, 453 AvbAlgorithmType* out_algorithm_type, 454 AvbCmdlineSubstList* out_additional_cmdline_subst) { 455 char full_partition_name[AVB_PART_NAME_MAX_SIZE]; 456 AvbSlotVerifyResult ret; 457 AvbIOResult io_ret; 458 size_t vbmeta_offset; 459 size_t vbmeta_size; 460 uint8_t* vbmeta_buf = NULL; 461 size_t vbmeta_num_read; 462 AvbVBMetaVerifyResult vbmeta_ret; 463 const uint8_t* pk_data; 464 size_t pk_len; 465 AvbVBMetaImageHeader vbmeta_header; 466 uint64_t stored_rollback_index; 467 const AvbDescriptor** descriptors = NULL; 468 size_t num_descriptors; 469 size_t n; 470 bool is_main_vbmeta; 471 bool is_vbmeta_partition; 472 AvbVBMetaData* vbmeta_image_data = NULL; 473 474 ret = AVB_SLOT_VERIFY_RESULT_OK; 475 476 avb_assert(slot_data != NULL); 477 478 /* Since we allow top-level vbmeta in 'boot', use 479 * rollback_index_location to determine whether we're the main 480 * vbmeta struct. 481 */ 482 is_main_vbmeta = (rollback_index_location == 0); 483 is_vbmeta_partition = (avb_strcmp(partition_name, "vbmeta") == 0); 484 485 if (!avb_validate_utf8((const uint8_t*)partition_name, partition_name_len)) { 486 avb_error("Partition name is not valid UTF-8.\n"); 487 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 488 goto out; 489 } 490 491 /* Construct full partition name. */ 492 if (!avb_str_concat(full_partition_name, 493 sizeof full_partition_name, 494 partition_name, 495 partition_name_len, 496 ab_suffix, 497 avb_strlen(ab_suffix))) { 498 avb_error("Partition name and suffix does not fit.\n"); 499 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 500 goto out; 501 } 502 503 avb_debugv("Loading vbmeta struct from partition '", 504 full_partition_name, 505 "'.\n", 506 NULL); 507 508 /* If we're loading from the main vbmeta partition, the vbmeta 509 * struct is in the beginning. Otherwise we have to locate it via a 510 * footer. 511 */ 512 if (is_vbmeta_partition) { 513 vbmeta_offset = 0; 514 vbmeta_size = VBMETA_MAX_SIZE; 515 } else { 516 uint8_t footer_buf[AVB_FOOTER_SIZE]; 517 size_t footer_num_read; 518 AvbFooter footer; 519 520 io_ret = ops->read_from_partition(ops, 521 full_partition_name, 522 -AVB_FOOTER_SIZE, 523 AVB_FOOTER_SIZE, 524 footer_buf, 525 &footer_num_read); 526 if (io_ret == AVB_IO_RESULT_ERROR_OOM) { 527 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 528 goto out; 529 } else if (io_ret != AVB_IO_RESULT_OK) { 530 avb_errorv(full_partition_name, ": Error loading footer.\n", NULL); 531 ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO; 532 goto out; 533 } 534 avb_assert(footer_num_read == AVB_FOOTER_SIZE); 535 536 if (!avb_footer_validate_and_byteswap((const AvbFooter*)footer_buf, 537 &footer)) { 538 avb_errorv(full_partition_name, ": Error validating footer.\n", NULL); 539 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 540 goto out; 541 } 542 543 /* Basic footer sanity check since the data is untrusted. */ 544 if (footer.vbmeta_size > VBMETA_MAX_SIZE) { 545 avb_errorv( 546 full_partition_name, ": Invalid vbmeta size in footer.\n", NULL); 547 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 548 goto out; 549 } 550 551 vbmeta_offset = footer.vbmeta_offset; 552 vbmeta_size = footer.vbmeta_size; 553 } 554 555 vbmeta_buf = avb_malloc(vbmeta_size); 556 if (vbmeta_buf == NULL) { 557 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 558 goto out; 559 } 560 561 io_ret = ops->read_from_partition(ops, 562 full_partition_name, 563 vbmeta_offset, 564 vbmeta_size, 565 vbmeta_buf, 566 &vbmeta_num_read); 567 if (io_ret == AVB_IO_RESULT_ERROR_OOM) { 568 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 569 goto out; 570 } else if (io_ret != AVB_IO_RESULT_OK) { 571 /* If we're looking for 'vbmeta' but there is no such partition, 572 * go try to get it from the boot partition instead. 573 */ 574 if (is_main_vbmeta && io_ret == AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION && 575 is_vbmeta_partition) { 576 avb_debugv(full_partition_name, 577 ": No such partition. Trying 'boot' instead.\n", 578 NULL); 579 ret = load_and_verify_vbmeta(ops, 580 requested_partitions, 581 ab_suffix, 582 allow_verification_error, 583 0 /* toplevel_vbmeta_flags */, 584 0 /* rollback_index_location */, 585 "boot", 586 avb_strlen("boot"), 587 NULL /* expected_public_key */, 588 0 /* expected_public_key_length */, 589 slot_data, 590 out_algorithm_type, 591 out_additional_cmdline_subst); 592 goto out; 593 } else { 594 avb_errorv(full_partition_name, ": Error loading vbmeta data.\n", NULL); 595 ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO; 596 goto out; 597 } 598 } 599 avb_assert(vbmeta_num_read <= vbmeta_size); 600 601 /* Check if the image is properly signed and get the public key used 602 * to sign the image. 603 */ 604 vbmeta_ret = 605 avb_vbmeta_image_verify(vbmeta_buf, vbmeta_num_read, &pk_data, &pk_len); 606 switch (vbmeta_ret) { 607 case AVB_VBMETA_VERIFY_RESULT_OK: 608 avb_assert(pk_data != NULL && pk_len > 0); 609 break; 610 611 case AVB_VBMETA_VERIFY_RESULT_OK_NOT_SIGNED: 612 case AVB_VBMETA_VERIFY_RESULT_HASH_MISMATCH: 613 case AVB_VBMETA_VERIFY_RESULT_SIGNATURE_MISMATCH: 614 ret = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION; 615 avb_errorv(full_partition_name, 616 ": Error verifying vbmeta image: ", 617 avb_vbmeta_verify_result_to_string(vbmeta_ret), 618 "\n", 619 NULL); 620 if (!allow_verification_error) { 621 goto out; 622 } 623 break; 624 625 case AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER: 626 /* No way to continue this case. */ 627 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 628 avb_errorv(full_partition_name, 629 ": Error verifying vbmeta image: invalid vbmeta header\n", 630 NULL); 631 goto out; 632 633 case AVB_VBMETA_VERIFY_RESULT_UNSUPPORTED_VERSION: 634 /* No way to continue this case. */ 635 ret = AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION; 636 avb_errorv(full_partition_name, 637 ": Error verifying vbmeta image: unsupported AVB version\n", 638 NULL); 639 goto out; 640 } 641 642 /* Byteswap the header. */ 643 avb_vbmeta_image_header_to_host_byte_order((AvbVBMetaImageHeader*)vbmeta_buf, 644 &vbmeta_header); 645 646 /* If we're the toplevel, assign flags so they'll be passed down. */ 647 if (is_main_vbmeta) { 648 toplevel_vbmeta_flags = (AvbVBMetaImageFlags)vbmeta_header.flags; 649 } else { 650 if (vbmeta_header.flags != 0) { 651 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 652 avb_errorv(full_partition_name, 653 ": chained vbmeta image has non-zero flags\n", 654 NULL); 655 goto out; 656 } 657 } 658 659 /* Check if key used to make signature matches what is expected. */ 660 if (pk_data != NULL) { 661 if (expected_public_key != NULL) { 662 avb_assert(!is_main_vbmeta); 663 if (expected_public_key_length != pk_len || 664 avb_safe_memcmp(expected_public_key, pk_data, pk_len) != 0) { 665 avb_errorv(full_partition_name, 666 ": Public key used to sign data does not match key in chain " 667 "partition descriptor.\n", 668 NULL); 669 ret = AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED; 670 if (!allow_verification_error) { 671 goto out; 672 } 673 } 674 } else { 675 bool key_is_trusted = false; 676 const uint8_t* pk_metadata = NULL; 677 size_t pk_metadata_len = 0; 678 679 if (vbmeta_header.public_key_metadata_size > 0) { 680 pk_metadata = vbmeta_buf + sizeof(AvbVBMetaImageHeader) + 681 vbmeta_header.authentication_data_block_size + 682 vbmeta_header.public_key_metadata_offset; 683 pk_metadata_len = vbmeta_header.public_key_metadata_size; 684 } 685 686 avb_assert(is_main_vbmeta); 687 io_ret = ops->validate_vbmeta_public_key( 688 ops, pk_data, pk_len, pk_metadata, pk_metadata_len, &key_is_trusted); 689 if (io_ret == AVB_IO_RESULT_ERROR_OOM) { 690 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 691 goto out; 692 } else if (io_ret != AVB_IO_RESULT_OK) { 693 avb_errorv(full_partition_name, 694 ": Error while checking public key used to sign data.\n", 695 NULL); 696 ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO; 697 goto out; 698 } 699 if (!key_is_trusted) { 700 avb_errorv(full_partition_name, 701 ": Public key used to sign data rejected.\n", 702 NULL); 703 ret = AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED; 704 if (!allow_verification_error) { 705 goto out; 706 } 707 } 708 } 709 } 710 711 /* Check rollback index. */ 712 io_ret = ops->read_rollback_index( 713 ops, rollback_index_location, &stored_rollback_index); 714 if (io_ret == AVB_IO_RESULT_ERROR_OOM) { 715 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 716 goto out; 717 } else if (io_ret != AVB_IO_RESULT_OK) { 718 avb_errorv(full_partition_name, 719 ": Error getting rollback index for location.\n", 720 NULL); 721 ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO; 722 goto out; 723 } 724 if (vbmeta_header.rollback_index < stored_rollback_index) { 725 avb_errorv( 726 full_partition_name, 727 ": Image rollback index is less than the stored rollback index.\n", 728 NULL); 729 ret = AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX; 730 if (!allow_verification_error) { 731 goto out; 732 } 733 } 734 735 /* Copy vbmeta to vbmeta_images before recursing. */ 736 if (is_main_vbmeta) { 737 avb_assert(slot_data->num_vbmeta_images == 0); 738 } else { 739 avb_assert(slot_data->num_vbmeta_images > 0); 740 } 741 if (slot_data->num_vbmeta_images == MAX_NUMBER_OF_VBMETA_IMAGES) { 742 avb_errorv(full_partition_name, ": Too many vbmeta images.\n", NULL); 743 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 744 goto out; 745 } 746 vbmeta_image_data = &slot_data->vbmeta_images[slot_data->num_vbmeta_images++]; 747 vbmeta_image_data->partition_name = avb_strdup(partition_name); 748 vbmeta_image_data->vbmeta_data = vbmeta_buf; 749 /* Note that |vbmeta_buf| is actually |vbmeta_num_read| bytes long 750 * and this includes data past the end of the image. Pass the 751 * actual size of the vbmeta image. Also, no need to use 752 * avb_safe_add() since the header has already been verified. 753 */ 754 vbmeta_image_data->vbmeta_size = 755 sizeof(AvbVBMetaImageHeader) + 756 vbmeta_header.authentication_data_block_size + 757 vbmeta_header.auxiliary_data_block_size; 758 vbmeta_image_data->verify_result = vbmeta_ret; 759 760 /* If verification has been disabled by setting a bit in the image, 761 * we're done... except that we need to load the entirety of the 762 * requested partitions. 763 */ 764 if (vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED) { 765 AvbSlotVerifyResult sub_ret; 766 avb_debugv( 767 full_partition_name, ": VERIFICATION_DISABLED bit is set.\n", NULL); 768 /* If load_requested_partitions() fail it is always a fatal 769 * failure (e.g. ERROR_INVALID_ARGUMENT, ERROR_OOM, etc.) rather 770 * than recoverable (e.g. one where result_should_continue() 771 * returns true) and we want to convey that error. 772 */ 773 sub_ret = load_requested_partitions( 774 ops, requested_partitions, ab_suffix, slot_data); 775 if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) { 776 ret = sub_ret; 777 } 778 goto out; 779 } 780 781 /* Now go through all descriptors and take the appropriate action: 782 * 783 * - hash descriptor: Load data from partition, calculate hash, and 784 * checks that it matches what's in the hash descriptor. 785 * 786 * - hashtree descriptor: Do nothing since verification happens 787 * on-the-fly from within the OS. (Unless the descriptor uses a 788 * persistent digest, in which case we need to find it). 789 * 790 * - chained partition descriptor: Load the footer, load the vbmeta 791 * image, verify vbmeta image (includes rollback checks, hash 792 * checks, bail on chained partitions). 793 */ 794 descriptors = 795 avb_descriptor_get_all(vbmeta_buf, vbmeta_num_read, &num_descriptors); 796 for (n = 0; n < num_descriptors; n++) { 797 AvbDescriptor desc; 798 799 if (!avb_descriptor_validate_and_byteswap(descriptors[n], &desc)) { 800 avb_errorv(full_partition_name, ": Descriptor is invalid.\n", NULL); 801 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 802 goto out; 803 } 804 805 switch (desc.tag) { 806 case AVB_DESCRIPTOR_TAG_HASH: { 807 AvbSlotVerifyResult sub_ret; 808 sub_ret = load_and_verify_hash_partition(ops, 809 requested_partitions, 810 ab_suffix, 811 allow_verification_error, 812 descriptors[n], 813 slot_data); 814 if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) { 815 ret = sub_ret; 816 if (!allow_verification_error || !result_should_continue(ret)) { 817 goto out; 818 } 819 } 820 } break; 821 822 case AVB_DESCRIPTOR_TAG_CHAIN_PARTITION: { 823 AvbSlotVerifyResult sub_ret; 824 AvbChainPartitionDescriptor chain_desc; 825 const uint8_t* chain_partition_name; 826 const uint8_t* chain_public_key; 827 828 /* Only allow CHAIN_PARTITION descriptors in the main vbmeta image. */ 829 if (!is_main_vbmeta) { 830 avb_errorv(full_partition_name, 831 ": Encountered chain descriptor not in main image.\n", 832 NULL); 833 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 834 goto out; 835 } 836 837 if (!avb_chain_partition_descriptor_validate_and_byteswap( 838 (AvbChainPartitionDescriptor*)descriptors[n], &chain_desc)) { 839 avb_errorv(full_partition_name, 840 ": Chain partition descriptor is invalid.\n", 841 NULL); 842 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 843 goto out; 844 } 845 846 if (chain_desc.rollback_index_location == 0) { 847 avb_errorv(full_partition_name, 848 ": Chain partition has invalid " 849 "rollback_index_location field.\n", 850 NULL); 851 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 852 goto out; 853 } 854 855 chain_partition_name = ((const uint8_t*)descriptors[n]) + 856 sizeof(AvbChainPartitionDescriptor); 857 chain_public_key = chain_partition_name + chain_desc.partition_name_len; 858 859 sub_ret = 860 load_and_verify_vbmeta(ops, 861 requested_partitions, 862 ab_suffix, 863 allow_verification_error, 864 toplevel_vbmeta_flags, 865 chain_desc.rollback_index_location, 866 (const char*)chain_partition_name, 867 chain_desc.partition_name_len, 868 chain_public_key, 869 chain_desc.public_key_len, 870 slot_data, 871 NULL, /* out_algorithm_type */ 872 NULL /* out_additional_cmdline_subst */); 873 if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) { 874 ret = sub_ret; 875 if (!result_should_continue(ret)) { 876 goto out; 877 } 878 } 879 } break; 880 881 case AVB_DESCRIPTOR_TAG_KERNEL_CMDLINE: { 882 const uint8_t* kernel_cmdline; 883 AvbKernelCmdlineDescriptor kernel_cmdline_desc; 884 bool apply_cmdline; 885 886 if (!avb_kernel_cmdline_descriptor_validate_and_byteswap( 887 (AvbKernelCmdlineDescriptor*)descriptors[n], 888 &kernel_cmdline_desc)) { 889 avb_errorv(full_partition_name, 890 ": Kernel cmdline descriptor is invalid.\n", 891 NULL); 892 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 893 goto out; 894 } 895 896 kernel_cmdline = ((const uint8_t*)descriptors[n]) + 897 sizeof(AvbKernelCmdlineDescriptor); 898 899 if (!avb_validate_utf8(kernel_cmdline, 900 kernel_cmdline_desc.kernel_cmdline_length)) { 901 avb_errorv(full_partition_name, 902 ": Kernel cmdline is not valid UTF-8.\n", 903 NULL); 904 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 905 goto out; 906 } 907 908 /* Compare the flags for top-level VBMeta struct with flags in 909 * the command-line descriptor so command-line snippets only 910 * intended for a certain mode (dm-verity enabled/disabled) 911 * are skipped if applicable. 912 */ 913 apply_cmdline = true; 914 if (toplevel_vbmeta_flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED) { 915 if (kernel_cmdline_desc.flags & 916 AVB_KERNEL_CMDLINE_FLAGS_USE_ONLY_IF_HASHTREE_NOT_DISABLED) { 917 apply_cmdline = false; 918 } 919 } else { 920 if (kernel_cmdline_desc.flags & 921 AVB_KERNEL_CMDLINE_FLAGS_USE_ONLY_IF_HASHTREE_DISABLED) { 922 apply_cmdline = false; 923 } 924 } 925 926 if (apply_cmdline) { 927 if (slot_data->cmdline == NULL) { 928 slot_data->cmdline = 929 avb_calloc(kernel_cmdline_desc.kernel_cmdline_length + 1); 930 if (slot_data->cmdline == NULL) { 931 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 932 goto out; 933 } 934 avb_memcpy(slot_data->cmdline, 935 kernel_cmdline, 936 kernel_cmdline_desc.kernel_cmdline_length); 937 } else { 938 /* new cmdline is: <existing_cmdline> + ' ' + <newcmdline> + '\0' */ 939 size_t orig_size = avb_strlen(slot_data->cmdline); 940 size_t new_size = 941 orig_size + 1 + kernel_cmdline_desc.kernel_cmdline_length + 1; 942 char* new_cmdline = avb_calloc(new_size); 943 if (new_cmdline == NULL) { 944 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 945 goto out; 946 } 947 avb_memcpy(new_cmdline, slot_data->cmdline, orig_size); 948 new_cmdline[orig_size] = ' '; 949 avb_memcpy(new_cmdline + orig_size + 1, 950 kernel_cmdline, 951 kernel_cmdline_desc.kernel_cmdline_length); 952 avb_free(slot_data->cmdline); 953 slot_data->cmdline = new_cmdline; 954 } 955 } 956 } break; 957 958 case AVB_DESCRIPTOR_TAG_HASHTREE: { 959 AvbHashtreeDescriptor hashtree_desc; 960 961 if (!avb_hashtree_descriptor_validate_and_byteswap( 962 (AvbHashtreeDescriptor*)descriptors[n], &hashtree_desc)) { 963 avb_errorv( 964 full_partition_name, ": Hashtree descriptor is invalid.\n", NULL); 965 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 966 goto out; 967 } 968 969 /* We only need to continue when there is no digest in the descriptor. 970 * This is because the only processing here is to find the digest and 971 * make it available on the kernel command line. 972 */ 973 if (hashtree_desc.root_digest_len == 0) { 974 char part_name[AVB_PART_NAME_MAX_SIZE]; 975 size_t digest_len = 0; 976 uint8_t digest_buf[AVB_SHA512_DIGEST_SIZE]; 977 const uint8_t* desc_partition_name = 978 ((const uint8_t*)descriptors[n]) + sizeof(AvbHashtreeDescriptor); 979 980 if (!avb_validate_utf8(desc_partition_name, 981 hashtree_desc.partition_name_len)) { 982 avb_error("Partition name is not valid UTF-8.\n"); 983 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 984 goto out; 985 } 986 987 /* No ab_suffix for partitions without a digest in the descriptor 988 * because these partitions hold data unique to this device and are 989 * not updated using an A/B scheme. 990 */ 991 if ((hashtree_desc.flags & 992 AVB_HASHTREE_DESCRIPTOR_FLAGS_DO_NOT_USE_AB) == 0 && 993 avb_strlen(ab_suffix) != 0) { 994 avb_error("Cannot use A/B with a persistent root digest.\n"); 995 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 996 goto out; 997 } 998 if (hashtree_desc.partition_name_len >= AVB_PART_NAME_MAX_SIZE) { 999 avb_error("Partition name does not fit.\n"); 1000 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 1001 goto out; 1002 } 1003 avb_memcpy( 1004 part_name, desc_partition_name, hashtree_desc.partition_name_len); 1005 part_name[hashtree_desc.partition_name_len] = '\0'; 1006 1007 /* Determine the expected digest size from the hash algorithm. */ 1008 if (avb_strcmp((const char*)hashtree_desc.hash_algorithm, "sha1") == 1009 0) { 1010 digest_len = AVB_SHA1_DIGEST_SIZE; 1011 } else if (avb_strcmp((const char*)hashtree_desc.hash_algorithm, 1012 "sha256") == 0) { 1013 digest_len = AVB_SHA256_DIGEST_SIZE; 1014 } else if (avb_strcmp((const char*)hashtree_desc.hash_algorithm, 1015 "sha512") == 0) { 1016 digest_len = AVB_SHA512_DIGEST_SIZE; 1017 } else { 1018 avb_errorv(part_name, ": Unsupported hash algorithm.\n", NULL); 1019 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 1020 goto out; 1021 } 1022 1023 ret = read_persistent_digest(ops, part_name, digest_len, digest_buf); 1024 if (ret != AVB_SLOT_VERIFY_RESULT_OK) { 1025 goto out; 1026 } 1027 1028 if (out_additional_cmdline_subst) { 1029 ret = 1030 avb_add_root_digest_substitution(part_name, 1031 digest_buf, 1032 digest_len, 1033 out_additional_cmdline_subst); 1034 if (ret != AVB_SLOT_VERIFY_RESULT_OK) { 1035 goto out; 1036 } 1037 } 1038 } 1039 } break; 1040 1041 case AVB_DESCRIPTOR_TAG_PROPERTY: 1042 /* Do nothing. */ 1043 break; 1044 } 1045 } 1046 1047 if (rollback_index_location >= AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS) { 1048 avb_errorv( 1049 full_partition_name, ": Invalid rollback_index_location.\n", NULL); 1050 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; 1051 goto out; 1052 } 1053 1054 slot_data->rollback_indexes[rollback_index_location] = 1055 vbmeta_header.rollback_index; 1056 1057 if (out_algorithm_type != NULL) { 1058 *out_algorithm_type = (AvbAlgorithmType)vbmeta_header.algorithm_type; 1059 } 1060 1061 out: 1062 /* If |vbmeta_image_data| isn't NULL it means that it adopted 1063 * |vbmeta_buf| so in that case don't free it here. 1064 */ 1065 if (vbmeta_image_data == NULL) { 1066 if (vbmeta_buf != NULL) { 1067 avb_free(vbmeta_buf); 1068 } 1069 } 1070 if (descriptors != NULL) { 1071 avb_free(descriptors); 1072 } 1073 return ret; 1074 } 1075 1076 AvbSlotVerifyResult avb_slot_verify(AvbOps* ops, 1077 const char* const* requested_partitions, 1078 const char* ab_suffix, 1079 AvbSlotVerifyFlags flags, 1080 AvbHashtreeErrorMode hashtree_error_mode, 1081 AvbSlotVerifyData** out_data) { 1082 AvbSlotVerifyResult ret; 1083 AvbSlotVerifyData* slot_data = NULL; 1084 AvbAlgorithmType algorithm_type = AVB_ALGORITHM_TYPE_NONE; 1085 bool using_boot_for_vbmeta = false; 1086 AvbVBMetaImageHeader toplevel_vbmeta; 1087 bool allow_verification_error = 1088 (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR); 1089 AvbCmdlineSubstList* additional_cmdline_subst = NULL; 1090 1091 /* Fail early if we're missing the AvbOps needed for slot verification. 1092 * 1093 * For now, handle get_size_of_partition() not being implemented. In 1094 * a later release we may change that. 1095 */ 1096 avb_assert(ops->read_is_device_unlocked != NULL); 1097 avb_assert(ops->read_from_partition != NULL); 1098 avb_assert(ops->validate_vbmeta_public_key != NULL); 1099 avb_assert(ops->read_rollback_index != NULL); 1100 avb_assert(ops->get_unique_guid_for_partition != NULL); 1101 1102 if (out_data != NULL) { 1103 *out_data = NULL; 1104 } 1105 1106 /* Allowing dm-verity errors defeats the purpose of verified boot so 1107 * only allow this if set up to allow verification errors 1108 * (e.g. typically only UNLOCKED mode). 1109 */ 1110 if (hashtree_error_mode == AVB_HASHTREE_ERROR_MODE_LOGGING && 1111 !allow_verification_error) { 1112 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT; 1113 goto fail; 1114 } 1115 1116 slot_data = avb_calloc(sizeof(AvbSlotVerifyData)); 1117 if (slot_data == NULL) { 1118 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 1119 goto fail; 1120 } 1121 slot_data->vbmeta_images = 1122 avb_calloc(sizeof(AvbVBMetaData) * MAX_NUMBER_OF_VBMETA_IMAGES); 1123 if (slot_data->vbmeta_images == NULL) { 1124 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 1125 goto fail; 1126 } 1127 slot_data->loaded_partitions = 1128 avb_calloc(sizeof(AvbPartitionData) * MAX_NUMBER_OF_LOADED_PARTITIONS); 1129 if (slot_data->loaded_partitions == NULL) { 1130 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 1131 goto fail; 1132 } 1133 1134 additional_cmdline_subst = avb_new_cmdline_subst_list(); 1135 if (additional_cmdline_subst == NULL) { 1136 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 1137 goto fail; 1138 } 1139 1140 ret = load_and_verify_vbmeta(ops, 1141 requested_partitions, 1142 ab_suffix, 1143 allow_verification_error, 1144 0 /* toplevel_vbmeta_flags */, 1145 0 /* rollback_index_location */, 1146 "vbmeta", 1147 avb_strlen("vbmeta"), 1148 NULL /* expected_public_key */, 1149 0 /* expected_public_key_length */, 1150 slot_data, 1151 &algorithm_type, 1152 additional_cmdline_subst); 1153 if (!allow_verification_error && ret != AVB_SLOT_VERIFY_RESULT_OK) { 1154 goto fail; 1155 } 1156 1157 /* If things check out, mangle the kernel command-line as needed. */ 1158 if (result_should_continue(ret)) { 1159 if (avb_strcmp(slot_data->vbmeta_images[0].partition_name, "vbmeta") != 0) { 1160 avb_assert( 1161 avb_strcmp(slot_data->vbmeta_images[0].partition_name, "boot") == 0); 1162 using_boot_for_vbmeta = true; 1163 } 1164 1165 /* Byteswap top-level vbmeta header since we'll need it below. */ 1166 avb_vbmeta_image_header_to_host_byte_order( 1167 (const AvbVBMetaImageHeader*)slot_data->vbmeta_images[0].vbmeta_data, 1168 &toplevel_vbmeta); 1169 1170 /* Fill in |ab_suffix| field. */ 1171 slot_data->ab_suffix = avb_strdup(ab_suffix); 1172 if (slot_data->ab_suffix == NULL) { 1173 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 1174 goto fail; 1175 } 1176 1177 /* If verification is disabled, we are done ... we specifically 1178 * don't want to add any androidboot.* options since verification 1179 * is disabled. 1180 */ 1181 if (toplevel_vbmeta.flags & AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED) { 1182 /* Since verification is disabled we didn't process any 1183 * descriptors and thus there's no cmdline... so set root= such 1184 * that the system partition is mounted. 1185 */ 1186 avb_assert(slot_data->cmdline == NULL); 1187 slot_data->cmdline = 1188 avb_strdup("root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)"); 1189 if (slot_data->cmdline == NULL) { 1190 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 1191 goto fail; 1192 } 1193 } else { 1194 /* Add options - any failure in avb_append_options() is either an 1195 * I/O or OOM error. 1196 */ 1197 AvbSlotVerifyResult sub_ret = avb_append_options(ops, 1198 slot_data, 1199 &toplevel_vbmeta, 1200 algorithm_type, 1201 hashtree_error_mode); 1202 if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) { 1203 ret = sub_ret; 1204 goto fail; 1205 } 1206 } 1207 1208 /* Substitute $(ANDROID_SYSTEM_PARTUUID) and friends. */ 1209 if (slot_data->cmdline != NULL) { 1210 char* new_cmdline; 1211 new_cmdline = avb_sub_cmdline(ops, 1212 slot_data->cmdline, 1213 ab_suffix, 1214 using_boot_for_vbmeta, 1215 additional_cmdline_subst); 1216 if (new_cmdline != slot_data->cmdline) { 1217 if (new_cmdline == NULL) { 1218 ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 1219 goto fail; 1220 } 1221 avb_free(slot_data->cmdline); 1222 slot_data->cmdline = new_cmdline; 1223 } 1224 } 1225 1226 if (out_data != NULL) { 1227 *out_data = slot_data; 1228 } else { 1229 avb_slot_verify_data_free(slot_data); 1230 } 1231 } 1232 1233 avb_free_cmdline_subst_list(additional_cmdline_subst); 1234 additional_cmdline_subst = NULL; 1235 1236 if (!allow_verification_error) { 1237 avb_assert(ret == AVB_SLOT_VERIFY_RESULT_OK); 1238 } 1239 1240 return ret; 1241 1242 fail: 1243 if (slot_data != NULL) { 1244 avb_slot_verify_data_free(slot_data); 1245 } 1246 if (additional_cmdline_subst != NULL) { 1247 avb_free_cmdline_subst_list(additional_cmdline_subst); 1248 } 1249 return ret; 1250 } 1251 1252 void avb_slot_verify_data_free(AvbSlotVerifyData* data) { 1253 if (data->ab_suffix != NULL) { 1254 avb_free(data->ab_suffix); 1255 } 1256 if (data->cmdline != NULL) { 1257 avb_free(data->cmdline); 1258 } 1259 if (data->vbmeta_images != NULL) { 1260 size_t n; 1261 for (n = 0; n < data->num_vbmeta_images; n++) { 1262 AvbVBMetaData* vbmeta_image = &data->vbmeta_images[n]; 1263 if (vbmeta_image->partition_name != NULL) { 1264 avb_free(vbmeta_image->partition_name); 1265 } 1266 if (vbmeta_image->vbmeta_data != NULL) { 1267 avb_free(vbmeta_image->vbmeta_data); 1268 } 1269 } 1270 avb_free(data->vbmeta_images); 1271 } 1272 if (data->loaded_partitions != NULL) { 1273 size_t n; 1274 for (n = 0; n < data->num_loaded_partitions; n++) { 1275 AvbPartitionData* loaded_partition = &data->loaded_partitions[n]; 1276 if (loaded_partition->partition_name != NULL) { 1277 avb_free(loaded_partition->partition_name); 1278 } 1279 if (loaded_partition->data != NULL && !loaded_partition->preloaded) { 1280 avb_free(loaded_partition->data); 1281 } 1282 } 1283 avb_free(data->loaded_partitions); 1284 } 1285 avb_free(data); 1286 } 1287 1288 const char* avb_slot_verify_result_to_string(AvbSlotVerifyResult result) { 1289 const char* ret = NULL; 1290 1291 switch (result) { 1292 case AVB_SLOT_VERIFY_RESULT_OK: 1293 ret = "OK"; 1294 break; 1295 case AVB_SLOT_VERIFY_RESULT_ERROR_OOM: 1296 ret = "ERROR_OOM"; 1297 break; 1298 case AVB_SLOT_VERIFY_RESULT_ERROR_IO: 1299 ret = "ERROR_IO"; 1300 break; 1301 case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION: 1302 ret = "ERROR_VERIFICATION"; 1303 break; 1304 case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX: 1305 ret = "ERROR_ROLLBACK_INDEX"; 1306 break; 1307 case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED: 1308 ret = "ERROR_PUBLIC_KEY_REJECTED"; 1309 break; 1310 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA: 1311 ret = "ERROR_INVALID_METADATA"; 1312 break; 1313 case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION: 1314 ret = "ERROR_UNSUPPORTED_VERSION"; 1315 break; 1316 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT: 1317 ret = "ERROR_INVALID_ARGUMENT"; 1318 break; 1319 /* Do not add a 'default:' case here because of -Wswitch. */ 1320 } 1321 1322 if (ret == NULL) { 1323 avb_error("Unknown AvbSlotVerifyResult value.\n"); 1324 ret = "(unknown)"; 1325 } 1326 1327 return ret; 1328 } 1329 1330 void avb_slot_verify_data_calculate_vbmeta_digest(AvbSlotVerifyData* data, 1331 AvbDigestType digest_type, 1332 uint8_t* out_digest) { 1333 bool ret = false; 1334 size_t n; 1335 1336 switch (digest_type) { 1337 case AVB_DIGEST_TYPE_SHA256: { 1338 AvbSHA256Ctx ctx; 1339 avb_sha256_init(&ctx); 1340 for (n = 0; n < data->num_vbmeta_images; n++) { 1341 avb_sha256_update(&ctx, 1342 data->vbmeta_images[n].vbmeta_data, 1343 data->vbmeta_images[n].vbmeta_size); 1344 } 1345 avb_memcpy(out_digest, avb_sha256_final(&ctx), AVB_SHA256_DIGEST_SIZE); 1346 ret = true; 1347 } break; 1348 1349 case AVB_DIGEST_TYPE_SHA512: { 1350 AvbSHA512Ctx ctx; 1351 avb_sha512_init(&ctx); 1352 for (n = 0; n < data->num_vbmeta_images; n++) { 1353 avb_sha512_update(&ctx, 1354 data->vbmeta_images[n].vbmeta_data, 1355 data->vbmeta_images[n].vbmeta_size); 1356 } 1357 avb_memcpy(out_digest, avb_sha512_final(&ctx), AVB_SHA512_DIGEST_SIZE); 1358 ret = true; 1359 } break; 1360 1361 /* Do not add a 'default:' case here because of -Wswitch. */ 1362 } 1363 1364 if (!ret) { 1365 avb_fatal("Unknown digest type"); 1366 } 1367 } 1368