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