Home | History | Annotate | Download | only in libavb
      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