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