diff --git a/lib/libavb/avb_slot_verify.c b/lib/libavb/avb_slot_verify.c
new file mode 100644
index 0000000..66ac6f0
--- /dev/null
+++ b/lib/libavb/avb_slot_verify.c
@@ -0,0 +1,1367 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * SPDX-License-Identifier:	MIT
+ */
+
+#include "avb_slot_verify.h"
+#include "avb_chain_partition_descriptor.h"
+#include "avb_cmdline.h"
+#include "avb_footer.h"
+#include "avb_hash_descriptor.h"
+#include "avb_hashtree_descriptor.h"
+#include "avb_kernel_cmdline_descriptor.h"
+#include "avb_sha.h"
+#include "avb_util.h"
+#include "avb_vbmeta_image.h"
+#include "avb_version.h"
+
+/* Maximum number of partitions that can be loaded with avb_slot_verify(). */
+#define MAX_NUMBER_OF_LOADED_PARTITIONS 32
+
+/* Maximum number of vbmeta images that can be loaded with avb_slot_verify(). */
+#define MAX_NUMBER_OF_VBMETA_IMAGES 32
+
+/* Maximum size of a vbmeta image - 64 KiB. */
+#define VBMETA_MAX_SIZE (64 * 1024)
+
+/* Helper function to see if we should continue with verification in
+ * allow_verification_error=true mode if something goes wrong. See the
+ * comments for the avb_slot_verify() function for more information.
+ */
+static inline bool result_should_continue(AvbSlotVerifyResult result) {
+  switch (result) {
+    case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
+    case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
+    case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
+    case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
+    case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
+      return false;
+
+    case AVB_SLOT_VERIFY_RESULT_OK:
+    case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
+    case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
+    case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
+      return true;
+  }
+
+  return false;
+}
+
+static AvbSlotVerifyResult load_full_partition(AvbOps* ops,
+                                               const char* part_name,
+                                               uint64_t image_size,
+                                               uint8_t** out_image_buf,
+                                               bool* out_image_preloaded) {
+  size_t part_num_read;
+  AvbIOResult io_ret;
+
+  /* Make sure that we do not overwrite existing data. */
+  avb_assert(*out_image_buf == NULL);
+  avb_assert(!*out_image_preloaded);
+
+  /* We are going to implicitly cast image_size from uint64_t to size_t in the
+   * following code, so we need to make sure that the cast is safe. */
+  if (image_size != (size_t)(image_size)) {
+    avb_errorv(part_name, ": Partition size too large to load.\n", NULL);
+    return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+  }
+
+  /* Try use a preloaded one. */
+  if (ops->get_preloaded_partition != NULL) {
+    io_ret = ops->get_preloaded_partition(
+        ops, part_name, image_size, out_image_buf, &part_num_read);
+    if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
+      return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+    } else if (io_ret != AVB_IO_RESULT_OK) {
+      avb_errorv(part_name, ": Error loading data from partition.\n", NULL);
+      return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
+    }
+
+    if (*out_image_buf != NULL) {
+      if (part_num_read != image_size) {
+        avb_errorv(part_name, ": Read incorrect number of bytes.\n", NULL);
+        return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
+      }
+      *out_image_preloaded = true;
+    }
+  }
+
+  /* Allocate and copy the partition. */
+  if (!*out_image_preloaded) {
+    *out_image_buf = avb_malloc(image_size);
+    if (*out_image_buf == NULL) {
+      return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+    }
+
+    io_ret = ops->read_from_partition(ops,
+                                      part_name,
+                                      0 /* offset */,
+                                      image_size,
+                                      *out_image_buf,
+                                      &part_num_read);
+    if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
+      return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+    } else if (io_ret != AVB_IO_RESULT_OK) {
+      avb_errorv(part_name, ": Error loading data from partition.\n", NULL);
+      return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
+    }
+    if (part_num_read != image_size) {
+      avb_errorv(part_name, ": Read incorrect number of bytes.\n", NULL);
+      return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
+    }
+  }
+
+  return AVB_SLOT_VERIFY_RESULT_OK;
+}
+
+static AvbSlotVerifyResult read_persistent_digest(AvbOps* ops,
+                                                  const char* part_name,
+                                                  size_t expected_digest_size,
+                                                  uint8_t* out_digest) {
+  char* persistent_value_name = NULL;
+  AvbIOResult io_ret = AVB_IO_RESULT_OK;
+  size_t stored_digest_size = 0;
+
+  if (ops->read_persistent_value == NULL) {
+    avb_errorv(part_name, ": Persistent values are not implemented.\n", NULL);
+    return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+  }
+  persistent_value_name =
+      avb_strdupv(AVB_NPV_PERSISTENT_DIGEST_PREFIX, part_name, NULL);
+  if (persistent_value_name == NULL) {
+    return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+  }
+  io_ret = ops->read_persistent_value(ops,
+                                      persistent_value_name,
+                                      expected_digest_size,
+                                      out_digest,
+                                      &stored_digest_size);
+  avb_free(persistent_value_name);
+  if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
+    return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+  } else if (io_ret == AVB_IO_RESULT_ERROR_NO_SUCH_VALUE) {
+    avb_errorv(part_name, ": Persistent digest does not exist.\n", NULL);
+    return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+  } else if (io_ret == AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE ||
+             io_ret == AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE ||
+             expected_digest_size != stored_digest_size) {
+    avb_errorv(
+        part_name, ": Persistent digest is not of expected size.\n", NULL);
+    return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+  } else if (io_ret != AVB_IO_RESULT_OK) {
+    avb_errorv(part_name, ": Error reading persistent digest.\n", NULL);
+    return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
+  }
+  return AVB_SLOT_VERIFY_RESULT_OK;
+}
+
+static AvbSlotVerifyResult load_and_verify_hash_partition(
+    AvbOps* ops,
+    const char* const* requested_partitions,
+    const char* ab_suffix,
+    bool allow_verification_error,
+    const AvbDescriptor* descriptor,
+    AvbSlotVerifyData* slot_data) {
+  AvbHashDescriptor hash_desc;
+  const uint8_t* desc_partition_name = NULL;
+  const uint8_t* desc_salt;
+  const uint8_t* desc_digest;
+  char part_name[AVB_PART_NAME_MAX_SIZE];
+  AvbSlotVerifyResult ret;
+  AvbIOResult io_ret;
+  uint8_t* image_buf = NULL;
+  bool image_preloaded = false;
+  uint8_t* digest;
+  size_t digest_len;
+  const char* found;
+  uint64_t image_size;
+  size_t expected_digest_len = 0;
+  uint8_t expected_digest_buf[AVB_SHA512_DIGEST_SIZE];
+  const uint8_t* expected_digest = NULL;
+
+  if (!avb_hash_descriptor_validate_and_byteswap(
+          (const AvbHashDescriptor*)descriptor, &hash_desc)) {
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+    goto out;
+  }
+
+  desc_partition_name =
+      ((const uint8_t*)descriptor) + sizeof(AvbHashDescriptor);
+  desc_salt = desc_partition_name + hash_desc.partition_name_len;
+  desc_digest = desc_salt + hash_desc.salt_len;
+
+  if (!avb_validate_utf8(desc_partition_name, hash_desc.partition_name_len)) {
+    avb_error("Partition name is not valid UTF-8.\n");
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+    goto out;
+  }
+
+  /* Don't bother loading or validating unless the partition was
+   * requested in the first place.
+   */
+  found = avb_strv_find_str(requested_partitions,
+                            (const char*)desc_partition_name,
+                            hash_desc.partition_name_len);
+  if (found == NULL) {
+    ret = AVB_SLOT_VERIFY_RESULT_OK;
+    goto out;
+  }
+
+  if ((hash_desc.flags & AVB_HASH_DESCRIPTOR_FLAGS_DO_NOT_USE_AB) != 0) {
+    /* No ab_suffix, just copy the partition name as is. */
+    if (hash_desc.partition_name_len >= AVB_PART_NAME_MAX_SIZE) {
+      avb_error("Partition name does not fit.\n");
+      ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+      goto out;
+    }
+    avb_memcpy(part_name, desc_partition_name, hash_desc.partition_name_len);
+    part_name[hash_desc.partition_name_len] = '\0';
+  } else if (hash_desc.digest_len == 0 && avb_strlen(ab_suffix) != 0) {
+    /* No ab_suffix allowed for partitions without a digest in the descriptor
+     * because these partitions hold data unique to this device and are not
+     * updated using an A/B scheme.
+     */
+    avb_error("Cannot use A/B with a persistent digest.\n");
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+    goto out;
+  } else {
+    /* Add ab_suffix to the partition name. */
+    if (!avb_str_concat(part_name,
+                        sizeof part_name,
+                        (const char*)desc_partition_name,
+                        hash_desc.partition_name_len,
+                        ab_suffix,
+                        avb_strlen(ab_suffix))) {
+      avb_error("Partition name and suffix does not fit.\n");
+      ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+      goto out;
+    }
+  }
+
+  /* If we're allowing verification errors then hash_desc.image_size
+   * may no longer match what's in the partition... so in this case
+   * just load the entire partition.
+   *
+   * For example, this can happen if a developer does 'fastboot flash
+   * boot /path/to/new/and/bigger/boot.img'. We want this to work
+   * since it's such a common workflow.
+   */
+  image_size = hash_desc.image_size;
+  if (allow_verification_error) {
+    if (ops->get_size_of_partition == NULL) {
+      avb_errorv(part_name,
+                 ": The get_size_of_partition() operation is "
+                 "not implemented so we may not load the entire partition. "
+                 "Please implement.",
+                 NULL);
+    } else {
+      io_ret = ops->get_size_of_partition(ops, part_name, &image_size);
+      if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
+        ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+        goto out;
+      } else if (io_ret != AVB_IO_RESULT_OK) {
+        avb_errorv(part_name, ": Error determining partition size.\n", NULL);
+        ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
+        goto out;
+      }
+      avb_debugv(part_name, ": Loading entire partition.\n", NULL);
+    }
+  }
+
+  ret = load_full_partition(
+      ops, part_name, image_size, &image_buf, &image_preloaded);
+  if (ret != AVB_SLOT_VERIFY_RESULT_OK) {
+    goto out;
+  }
+
+  if (avb_strcmp((const char*)hash_desc.hash_algorithm, "sha256") == 0) {
+    AvbSHA256Ctx sha256_ctx;
+    avb_sha256_init(&sha256_ctx);
+    avb_sha256_update(&sha256_ctx, desc_salt, hash_desc.salt_len);
+    avb_sha256_update(&sha256_ctx, image_buf, hash_desc.image_size);
+    digest = avb_sha256_final(&sha256_ctx);
+    digest_len = AVB_SHA256_DIGEST_SIZE;
+  } else if (avb_strcmp((const char*)hash_desc.hash_algorithm, "sha512") == 0) {
+    AvbSHA512Ctx sha512_ctx;
+    avb_sha512_init(&sha512_ctx);
+    avb_sha512_update(&sha512_ctx, desc_salt, hash_desc.salt_len);
+    avb_sha512_update(&sha512_ctx, image_buf, hash_desc.image_size);
+    digest = avb_sha512_final(&sha512_ctx);
+    digest_len = AVB_SHA512_DIGEST_SIZE;
+  } else {
+    avb_errorv(part_name, ": Unsupported hash algorithm.\n", NULL);
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+    goto out;
+  }
+
+  if (hash_desc.digest_len == 0) {
+    // Expect a match to a persistent digest.
+    avb_debugv(part_name, ": No digest, using persistent digest.\n", NULL);
+    expected_digest_len = digest_len;
+    expected_digest = expected_digest_buf;
+    avb_assert(expected_digest_len <= sizeof(expected_digest_buf));
+    ret =
+        read_persistent_digest(ops, part_name, digest_len, expected_digest_buf);
+    if (ret != AVB_SLOT_VERIFY_RESULT_OK) {
+      goto out;
+    }
+  } else {
+    // Expect a match to the digest in the descriptor.
+    expected_digest_len = hash_desc.digest_len;
+    expected_digest = desc_digest;
+  }
+
+  if (digest_len != expected_digest_len) {
+    avb_errorv(
+        part_name, ": Digest in descriptor not of expected size.\n", NULL);
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+    goto out;
+  }
+
+  if (avb_safe_memcmp(digest, expected_digest, digest_len) != 0) {
+    avb_errorv(part_name,
+               ": Hash of data does not match digest in descriptor.\n",
+               NULL);
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
+    goto out;
+  }
+
+  ret = AVB_SLOT_VERIFY_RESULT_OK;
+
+out:
+
+  /* If it worked and something was loaded, copy to slot_data. */
+  if ((ret == AVB_SLOT_VERIFY_RESULT_OK || result_should_continue(ret)) &&
+      image_buf != NULL) {
+    AvbPartitionData* loaded_partition;
+    if (slot_data->num_loaded_partitions == MAX_NUMBER_OF_LOADED_PARTITIONS) {
+      avb_errorv(part_name, ": Too many loaded partitions.\n", NULL);
+      ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+      goto fail;
+    }
+    loaded_partition =
+        &slot_data->loaded_partitions[slot_data->num_loaded_partitions++];
+    loaded_partition->partition_name = avb_strdup(found);
+    loaded_partition->data_size = image_size;
+    loaded_partition->data = image_buf;
+    loaded_partition->preloaded = image_preloaded;
+    image_buf = NULL;
+  }
+
+fail:
+  if (image_buf != NULL && !image_preloaded) {
+    avb_free(image_buf);
+  }
+  return ret;
+}
+
+static AvbSlotVerifyResult load_requested_partitions(
+    AvbOps* ops,
+    const char* const* requested_partitions,
+    const char* ab_suffix,
+    AvbSlotVerifyData* slot_data) {
+  AvbSlotVerifyResult ret;
+  uint8_t* image_buf = NULL;
+  bool image_preloaded = false;
+  size_t n;
+
+  if (ops->get_size_of_partition == NULL) {
+    avb_error("get_size_of_partition() not implemented.\n");
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT;
+    goto out;
+  }
+
+  for (n = 0; requested_partitions[n] != NULL; n++) {
+    char part_name[AVB_PART_NAME_MAX_SIZE];
+    AvbIOResult io_ret;
+    uint64_t image_size;
+    AvbPartitionData* loaded_partition;
+
+    if (!avb_str_concat(part_name,
+                        sizeof part_name,
+                        requested_partitions[n],
+                        avb_strlen(requested_partitions[n]),
+                        ab_suffix,
+                        avb_strlen(ab_suffix))) {
+      avb_error("Partition name and suffix does not fit.\n");
+      ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+      goto out;
+    }
+
+    io_ret = ops->get_size_of_partition(ops, part_name, &image_size);
+    if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
+      ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+      goto out;
+    } else if (io_ret != AVB_IO_RESULT_OK) {
+      avb_errorv(part_name, ": Error determining partition size.\n", NULL);
+      ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
+      goto out;
+    }
+    avb_debugv(part_name, ": Loading entire partition.\n", NULL);
+
+    ret = load_full_partition(
+        ops, part_name, image_size, &image_buf, &image_preloaded);
+    if (ret != AVB_SLOT_VERIFY_RESULT_OK) {
+      goto out;
+    }
+
+    /* Move to slot_data. */
+    if (slot_data->num_loaded_partitions == MAX_NUMBER_OF_LOADED_PARTITIONS) {
+      avb_errorv(part_name, ": Too many loaded partitions.\n", NULL);
+      ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+      goto out;
+    }
+    loaded_partition =
+        &slot_data->loaded_partitions[slot_data->num_loaded_partitions++];
+    loaded_partition->partition_name = avb_strdup(requested_partitions[n]);
+    if (loaded_partition->partition_name == NULL) {
+      ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+      goto out;
+    }
+    loaded_partition->data_size = image_size;
+    loaded_partition->data = image_buf; /* Transferring the owner. */
+    loaded_partition->preloaded = image_preloaded;
+    image_buf = NULL;
+    image_preloaded = false;
+  }
+
+  ret = AVB_SLOT_VERIFY_RESULT_OK;
+
+out:
+  /* Free the current buffer if any. */
+  if (image_buf != NULL && !image_preloaded) {
+    avb_free(image_buf);
+  }
+  /* Buffers that are already saved in slot_data will be handled by the caller
+   * even on failure. */
+  return ret;
+}
+
+static AvbSlotVerifyResult load_and_verify_vbmeta(
+    AvbOps* ops,
+    const char* const* requested_partitions,
+    const char* ab_suffix,
+    bool allow_verification_error,
+    AvbVBMetaImageFlags toplevel_vbmeta_flags,
+    int rollback_index_location,
+    const char* partition_name,
+    size_t partition_name_len,
+    const uint8_t* expected_public_key,
+    size_t expected_public_key_length,
+    AvbSlotVerifyData* slot_data,
+    AvbAlgorithmType* out_algorithm_type,
+    AvbCmdlineSubstList* out_additional_cmdline_subst) {
+  char full_partition_name[AVB_PART_NAME_MAX_SIZE];
+  AvbSlotVerifyResult ret;
+  AvbIOResult io_ret;
+  size_t vbmeta_offset;
+  size_t vbmeta_size;
+  uint8_t* vbmeta_buf = NULL;
+  size_t vbmeta_num_read;
+  AvbVBMetaVerifyResult vbmeta_ret;
+  const uint8_t* pk_data;
+  size_t pk_len;
+  AvbVBMetaImageHeader vbmeta_header;
+  uint64_t stored_rollback_index;
+  const AvbDescriptor** descriptors = NULL;
+  size_t num_descriptors;
+  size_t n;
+  bool is_main_vbmeta;
+  bool is_vbmeta_partition;
+  AvbVBMetaData* vbmeta_image_data = NULL;
+
+  ret = AVB_SLOT_VERIFY_RESULT_OK;
+
+  avb_assert(slot_data != NULL);
+
+  /* Since we allow top-level vbmeta in 'boot', use
+   * rollback_index_location to determine whether we're the main
+   * vbmeta struct.
+   */
+  is_main_vbmeta = (rollback_index_location == 0);
+  is_vbmeta_partition = (avb_strcmp(partition_name, "vbmeta") == 0);
+
+  if (!avb_validate_utf8((const uint8_t*)partition_name, partition_name_len)) {
+    avb_error("Partition name is not valid UTF-8.\n");
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+    goto out;
+  }
+
+  /* Construct full partition name. */
+  if (!avb_str_concat(full_partition_name,
+                      sizeof full_partition_name,
+                      partition_name,
+                      partition_name_len,
+                      ab_suffix,
+                      avb_strlen(ab_suffix))) {
+    avb_error("Partition name and suffix does not fit.\n");
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+    goto out;
+  }
+
+  avb_debugv("Loading vbmeta struct from partition '",
+             full_partition_name,
+             "'.\n",
+             NULL);
+
+  /* If we're loading from the main vbmeta partition, the vbmeta
+   * struct is in the beginning. Otherwise we have to locate it via a
+   * footer.
+   */
+  if (is_vbmeta_partition) {
+    vbmeta_offset = 0;
+    vbmeta_size = VBMETA_MAX_SIZE;
+  } else {
+    uint8_t footer_buf[AVB_FOOTER_SIZE];
+    size_t footer_num_read;
+    AvbFooter footer;
+
+    io_ret = ops->read_from_partition(ops,
+                                      full_partition_name,
+                                      -AVB_FOOTER_SIZE,
+                                      AVB_FOOTER_SIZE,
+                                      footer_buf,
+                                      &footer_num_read);
+    if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
+      ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+      goto out;
+    } else if (io_ret != AVB_IO_RESULT_OK) {
+      avb_errorv(full_partition_name, ": Error loading footer.\n", NULL);
+      ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
+      goto out;
+    }
+    avb_assert(footer_num_read == AVB_FOOTER_SIZE);
+
+    if (!avb_footer_validate_and_byteswap((const AvbFooter*)footer_buf,
+                                          &footer)) {
+      avb_errorv(full_partition_name, ": Error validating footer.\n", NULL);
+      ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+      goto out;
+    }
+
+    /* Basic footer sanity check since the data is untrusted. */
+    if (footer.vbmeta_size > VBMETA_MAX_SIZE) {
+      avb_errorv(
+          full_partition_name, ": Invalid vbmeta size in footer.\n", NULL);
+      ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+      goto out;
+    }
+
+    vbmeta_offset = footer.vbmeta_offset;
+    vbmeta_size = footer.vbmeta_size;
+  }
+
+  vbmeta_buf = avb_malloc(vbmeta_size);
+  if (vbmeta_buf == NULL) {
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+    goto out;
+  }
+
+  io_ret = ops->read_from_partition(ops,
+                                    full_partition_name,
+                                    vbmeta_offset,
+                                    vbmeta_size,
+                                    vbmeta_buf,
+                                    &vbmeta_num_read);
+  if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+    goto out;
+  } else if (io_ret != AVB_IO_RESULT_OK) {
+    /* If we're looking for 'vbmeta' but there is no such partition,
+     * go try to get it from the boot partition instead.
+     */
+    if (is_main_vbmeta && io_ret == AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION &&
+        is_vbmeta_partition) {
+      avb_debugv(full_partition_name,
+                 ": No such partition. Trying 'boot' instead.\n",
+                 NULL);
+      ret = load_and_verify_vbmeta(ops,
+                                   requested_partitions,
+                                   ab_suffix,
+                                   allow_verification_error,
+                                   0 /* toplevel_vbmeta_flags */,
+                                   0 /* rollback_index_location */,
+                                   "boot",
+                                   avb_strlen("boot"),
+                                   NULL /* expected_public_key */,
+                                   0 /* expected_public_key_length */,
+                                   slot_data,
+                                   out_algorithm_type,
+                                   out_additional_cmdline_subst);
+      goto out;
+    } else {
+      avb_errorv(full_partition_name, ": Error loading vbmeta data.\n", NULL);
+      ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
+      goto out;
+    }
+  }
+  avb_assert(vbmeta_num_read <= vbmeta_size);
+
+  /* Check if the image is properly signed and get the public key used
+   * to sign the image.
+   */
+  vbmeta_ret =
+      avb_vbmeta_image_verify(vbmeta_buf, vbmeta_num_read, &pk_data, &pk_len);
+  switch (vbmeta_ret) {
+    case AVB_VBMETA_VERIFY_RESULT_OK:
+      avb_assert(pk_data != NULL && pk_len > 0);
+      break;
+
+    case AVB_VBMETA_VERIFY_RESULT_OK_NOT_SIGNED:
+    case AVB_VBMETA_VERIFY_RESULT_HASH_MISMATCH:
+    case AVB_VBMETA_VERIFY_RESULT_SIGNATURE_MISMATCH:
+      ret = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
+      avb_errorv(full_partition_name,
+                 ": Error verifying vbmeta image: ",
+                 avb_vbmeta_verify_result_to_string(vbmeta_ret),
+                 "\n",
+                 NULL);
+      if (!allow_verification_error) {
+        goto out;
+      }
+      break;
+
+    case AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER:
+      /* No way to continue this case. */
+      ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+      avb_errorv(full_partition_name,
+                 ": Error verifying vbmeta image: invalid vbmeta header\n",
+                 NULL);
+      goto out;
+
+    case AVB_VBMETA_VERIFY_RESULT_UNSUPPORTED_VERSION:
+      /* No way to continue this case. */
+      ret = AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION;
+      avb_errorv(full_partition_name,
+                 ": Error verifying vbmeta image: unsupported AVB version\n",
+                 NULL);
+      goto out;
+  }
+
+  /* Byteswap the header. */
+  avb_vbmeta_image_header_to_host_byte_order((AvbVBMetaImageHeader*)vbmeta_buf,
+                                             &vbmeta_header);
+
+  /* If we're the toplevel, assign flags so they'll be passed down. */
+  if (is_main_vbmeta) {
+    toplevel_vbmeta_flags = (AvbVBMetaImageFlags)vbmeta_header.flags;
+  } else {
+    if (vbmeta_header.flags != 0) {
+      ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+      avb_errorv(full_partition_name,
+                 ": chained vbmeta image has non-zero flags\n",
+                 NULL);
+      goto out;
+    }
+  }
+
+  /* Check if key used to make signature matches what is expected. */
+  if (pk_data != NULL) {
+    if (expected_public_key != NULL) {
+      avb_assert(!is_main_vbmeta);
+      if (expected_public_key_length != pk_len ||
+          avb_safe_memcmp(expected_public_key, pk_data, pk_len) != 0) {
+        avb_errorv(full_partition_name,
+                   ": Public key used to sign data does not match key in chain "
+                   "partition descriptor.\n",
+                   NULL);
+        ret = AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED;
+        if (!allow_verification_error) {
+          goto out;
+        }
+      }
+    } else {
+      bool key_is_trusted = false;
+      const uint8_t* pk_metadata = NULL;
+      size_t pk_metadata_len = 0;
+
+      if (vbmeta_header.public_key_metadata_size > 0) {
+        pk_metadata = vbmeta_buf + sizeof(AvbVBMetaImageHeader) +
+                      vbmeta_header.authentication_data_block_size +
+                      vbmeta_header.public_key_metadata_offset;
+        pk_metadata_len = vbmeta_header.public_key_metadata_size;
+      }
+
+      avb_assert(is_main_vbmeta);
+      io_ret = ops->validate_vbmeta_public_key(
+          ops, pk_data, pk_len, pk_metadata, pk_metadata_len, &key_is_trusted);
+      if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
+        ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+        goto out;
+      } else if (io_ret != AVB_IO_RESULT_OK) {
+        avb_errorv(full_partition_name,
+                   ": Error while checking public key used to sign data.\n",
+                   NULL);
+        ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
+        goto out;
+      }
+      if (!key_is_trusted) {
+        avb_errorv(full_partition_name,
+                   ": Public key used to sign data rejected.\n",
+                   NULL);
+        ret = AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED;
+        if (!allow_verification_error) {
+          goto out;
+        }
+      }
+    }
+  }
+
+  /* Check rollback index. */
+  io_ret = ops->read_rollback_index(
+      ops, rollback_index_location, &stored_rollback_index);
+  if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+    goto out;
+  } else if (io_ret != AVB_IO_RESULT_OK) {
+    avb_errorv(full_partition_name,
+               ": Error getting rollback index for location.\n",
+               NULL);
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
+    goto out;
+  }
+  if (vbmeta_header.rollback_index < stored_rollback_index) {
+    avb_errorv(
+        full_partition_name,
+        ": Image rollback index is less than the stored rollback index.\n",
+        NULL);
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX;
+    if (!allow_verification_error) {
+      goto out;
+    }
+  }
+
+  /* Copy vbmeta to vbmeta_images before recursing. */
+  if (is_main_vbmeta) {
+    avb_assert(slot_data->num_vbmeta_images == 0);
+  } else {
+    avb_assert(slot_data->num_vbmeta_images > 0);
+  }
+  if (slot_data->num_vbmeta_images == MAX_NUMBER_OF_VBMETA_IMAGES) {
+    avb_errorv(full_partition_name, ": Too many vbmeta images.\n", NULL);
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+    goto out;
+  }
+  vbmeta_image_data = &slot_data->vbmeta_images[slot_data->num_vbmeta_images++];
+  vbmeta_image_data->partition_name = avb_strdup(partition_name);
+  vbmeta_image_data->vbmeta_data = vbmeta_buf;
+  /* Note that |vbmeta_buf| is actually |vbmeta_num_read| bytes long
+   * and this includes data past the end of the image. Pass the
+   * actual size of the vbmeta image. Also, no need to use
+   * avb_safe_add() since the header has already been verified.
+   */
+  vbmeta_image_data->vbmeta_size =
+      sizeof(AvbVBMetaImageHeader) +
+      vbmeta_header.authentication_data_block_size +
+      vbmeta_header.auxiliary_data_block_size;
+  vbmeta_image_data->verify_result = vbmeta_ret;
+
+  /* If verification has been disabled by setting a bit in the image,
+   * we're done... except that we need to load the entirety of the
+   * requested partitions.
+   */
+  if (vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED) {
+    AvbSlotVerifyResult sub_ret;
+    avb_debugv(
+        full_partition_name, ": VERIFICATION_DISABLED bit is set.\n", NULL);
+    /* If load_requested_partitions() fail it is always a fatal
+     * failure (e.g. ERROR_INVALID_ARGUMENT, ERROR_OOM, etc.) rather
+     * than recoverable (e.g. one where result_should_continue()
+     * returns true) and we want to convey that error.
+     */
+    sub_ret = load_requested_partitions(
+        ops, requested_partitions, ab_suffix, slot_data);
+    if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) {
+      ret = sub_ret;
+    }
+    goto out;
+  }
+
+  /* Now go through all descriptors and take the appropriate action:
+   *
+   * - hash descriptor: Load data from partition, calculate hash, and
+   *   checks that it matches what's in the hash descriptor.
+   *
+   * - hashtree descriptor: Do nothing since verification happens
+   *   on-the-fly from within the OS. (Unless the descriptor uses a
+   *   persistent digest, in which case we need to find it).
+   *
+   * - chained partition descriptor: Load the footer, load the vbmeta
+   *   image, verify vbmeta image (includes rollback checks, hash
+   *   checks, bail on chained partitions).
+   */
+  descriptors =
+      avb_descriptor_get_all(vbmeta_buf, vbmeta_num_read, &num_descriptors);
+  for (n = 0; n < num_descriptors; n++) {
+    AvbDescriptor desc;
+
+    if (!avb_descriptor_validate_and_byteswap(descriptors[n], &desc)) {
+      avb_errorv(full_partition_name, ": Descriptor is invalid.\n", NULL);
+      ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+      goto out;
+    }
+
+    switch (desc.tag) {
+      case AVB_DESCRIPTOR_TAG_HASH: {
+        AvbSlotVerifyResult sub_ret;
+        sub_ret = load_and_verify_hash_partition(ops,
+                                                 requested_partitions,
+                                                 ab_suffix,
+                                                 allow_verification_error,
+                                                 descriptors[n],
+                                                 slot_data);
+        if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) {
+          ret = sub_ret;
+          if (!allow_verification_error || !result_should_continue(ret)) {
+            goto out;
+          }
+        }
+      } break;
+
+      case AVB_DESCRIPTOR_TAG_CHAIN_PARTITION: {
+        AvbSlotVerifyResult sub_ret;
+        AvbChainPartitionDescriptor chain_desc;
+        const uint8_t* chain_partition_name;
+        const uint8_t* chain_public_key;
+
+        /* Only allow CHAIN_PARTITION descriptors in the main vbmeta image. */
+        if (!is_main_vbmeta) {
+          avb_errorv(full_partition_name,
+                     ": Encountered chain descriptor not in main image.\n",
+                     NULL);
+          ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+          goto out;
+        }
+
+        if (!avb_chain_partition_descriptor_validate_and_byteswap(
+                (AvbChainPartitionDescriptor*)descriptors[n], &chain_desc)) {
+          avb_errorv(full_partition_name,
+                     ": Chain partition descriptor is invalid.\n",
+                     NULL);
+          ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+          goto out;
+        }
+
+        if (chain_desc.rollback_index_location == 0) {
+          avb_errorv(full_partition_name,
+                     ": Chain partition has invalid "
+                     "rollback_index_location field.\n",
+                     NULL);
+          ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+          goto out;
+        }
+
+        chain_partition_name = ((const uint8_t*)descriptors[n]) +
+                               sizeof(AvbChainPartitionDescriptor);
+        chain_public_key = chain_partition_name + chain_desc.partition_name_len;
+
+        sub_ret =
+            load_and_verify_vbmeta(ops,
+                                   requested_partitions,
+                                   ab_suffix,
+                                   allow_verification_error,
+                                   toplevel_vbmeta_flags,
+                                   chain_desc.rollback_index_location,
+                                   (const char*)chain_partition_name,
+                                   chain_desc.partition_name_len,
+                                   chain_public_key,
+                                   chain_desc.public_key_len,
+                                   slot_data,
+                                   NULL, /* out_algorithm_type */
+                                   NULL /* out_additional_cmdline_subst */);
+        if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) {
+          ret = sub_ret;
+          if (!result_should_continue(ret)) {
+            goto out;
+          }
+        }
+      } break;
+
+      case AVB_DESCRIPTOR_TAG_KERNEL_CMDLINE: {
+        const uint8_t* kernel_cmdline;
+        AvbKernelCmdlineDescriptor kernel_cmdline_desc;
+        bool apply_cmdline;
+
+        if (!avb_kernel_cmdline_descriptor_validate_and_byteswap(
+                (AvbKernelCmdlineDescriptor*)descriptors[n],
+                &kernel_cmdline_desc)) {
+          avb_errorv(full_partition_name,
+                     ": Kernel cmdline descriptor is invalid.\n",
+                     NULL);
+          ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+          goto out;
+        }
+
+        kernel_cmdline = ((const uint8_t*)descriptors[n]) +
+                         sizeof(AvbKernelCmdlineDescriptor);
+
+        if (!avb_validate_utf8(kernel_cmdline,
+                               kernel_cmdline_desc.kernel_cmdline_length)) {
+          avb_errorv(full_partition_name,
+                     ": Kernel cmdline is not valid UTF-8.\n",
+                     NULL);
+          ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+          goto out;
+        }
+
+        /* Compare the flags for top-level VBMeta struct with flags in
+         * the command-line descriptor so command-line snippets only
+         * intended for a certain mode (dm-verity enabled/disabled)
+         * are skipped if applicable.
+         */
+        apply_cmdline = true;
+        if (toplevel_vbmeta_flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED) {
+          if (kernel_cmdline_desc.flags &
+              AVB_KERNEL_CMDLINE_FLAGS_USE_ONLY_IF_HASHTREE_NOT_DISABLED) {
+            apply_cmdline = false;
+          }
+        } else {
+          if (kernel_cmdline_desc.flags &
+              AVB_KERNEL_CMDLINE_FLAGS_USE_ONLY_IF_HASHTREE_DISABLED) {
+            apply_cmdline = false;
+          }
+        }
+
+        if (apply_cmdline) {
+          if (slot_data->cmdline == NULL) {
+            slot_data->cmdline =
+                avb_calloc(kernel_cmdline_desc.kernel_cmdline_length + 1);
+            if (slot_data->cmdline == NULL) {
+              ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+              goto out;
+            }
+            avb_memcpy(slot_data->cmdline,
+                       kernel_cmdline,
+                       kernel_cmdline_desc.kernel_cmdline_length);
+          } else {
+            /* new cmdline is: <existing_cmdline> + ' ' + <newcmdline> + '\0' */
+            size_t orig_size = avb_strlen(slot_data->cmdline);
+            size_t new_size =
+                orig_size + 1 + kernel_cmdline_desc.kernel_cmdline_length + 1;
+            char* new_cmdline = avb_calloc(new_size);
+            if (new_cmdline == NULL) {
+              ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+              goto out;
+            }
+            avb_memcpy(new_cmdline, slot_data->cmdline, orig_size);
+            new_cmdline[orig_size] = ' ';
+            avb_memcpy(new_cmdline + orig_size + 1,
+                       kernel_cmdline,
+                       kernel_cmdline_desc.kernel_cmdline_length);
+            avb_free(slot_data->cmdline);
+            slot_data->cmdline = new_cmdline;
+          }
+        }
+      } break;
+
+      case AVB_DESCRIPTOR_TAG_HASHTREE: {
+        AvbHashtreeDescriptor hashtree_desc;
+
+        if (!avb_hashtree_descriptor_validate_and_byteswap(
+                (AvbHashtreeDescriptor*)descriptors[n], &hashtree_desc)) {
+          avb_errorv(
+              full_partition_name, ": Hashtree descriptor is invalid.\n", NULL);
+          ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+          goto out;
+        }
+
+        /* We only need to continue when there is no digest in the descriptor.
+         * This is because the only processing here is to find the digest and
+         * make it available on the kernel command line.
+         */
+        if (hashtree_desc.root_digest_len == 0) {
+          char part_name[AVB_PART_NAME_MAX_SIZE];
+          size_t digest_len = 0;
+          uint8_t digest_buf[AVB_SHA512_DIGEST_SIZE];
+          const uint8_t* desc_partition_name =
+              ((const uint8_t*)descriptors[n]) + sizeof(AvbHashtreeDescriptor);
+
+          if (!avb_validate_utf8(desc_partition_name,
+                                 hashtree_desc.partition_name_len)) {
+            avb_error("Partition name is not valid UTF-8.\n");
+            ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+            goto out;
+          }
+
+          /* No ab_suffix for partitions without a digest in the descriptor
+           * because these partitions hold data unique to this device and are
+           * not updated using an A/B scheme.
+           */
+          if ((hashtree_desc.flags &
+               AVB_HASHTREE_DESCRIPTOR_FLAGS_DO_NOT_USE_AB) == 0 &&
+              avb_strlen(ab_suffix) != 0) {
+            avb_error("Cannot use A/B with a persistent root digest.\n");
+            ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+            goto out;
+          }
+          if (hashtree_desc.partition_name_len >= AVB_PART_NAME_MAX_SIZE) {
+            avb_error("Partition name does not fit.\n");
+            ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+            goto out;
+          }
+          avb_memcpy(
+              part_name, desc_partition_name, hashtree_desc.partition_name_len);
+          part_name[hashtree_desc.partition_name_len] = '\0';
+
+          /* Determine the expected digest size from the hash algorithm. */
+          if (avb_strcmp((const char*)hashtree_desc.hash_algorithm, "sha1") ==
+              0) {
+            digest_len = AVB_SHA1_DIGEST_SIZE;
+          } else if (avb_strcmp((const char*)hashtree_desc.hash_algorithm,
+                                "sha256") == 0) {
+            digest_len = AVB_SHA256_DIGEST_SIZE;
+          } else if (avb_strcmp((const char*)hashtree_desc.hash_algorithm,
+                                "sha512") == 0) {
+            digest_len = AVB_SHA512_DIGEST_SIZE;
+          } else {
+            avb_errorv(part_name, ": Unsupported hash algorithm.\n", NULL);
+            ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+            goto out;
+          }
+
+          ret = read_persistent_digest(ops, part_name, digest_len, digest_buf);
+          if (ret != AVB_SLOT_VERIFY_RESULT_OK) {
+            goto out;
+          }
+
+          if (out_additional_cmdline_subst) {
+            ret =
+                avb_add_root_digest_substitution(part_name,
+                                                 digest_buf,
+                                                 digest_len,
+                                                 out_additional_cmdline_subst);
+            if (ret != AVB_SLOT_VERIFY_RESULT_OK) {
+              goto out;
+            }
+          }
+        }
+      } break;
+
+      case AVB_DESCRIPTOR_TAG_PROPERTY:
+        /* Do nothing. */
+        break;
+    }
+  }
+
+  if (rollback_index_location >= AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS) {
+    avb_errorv(
+        full_partition_name, ": Invalid rollback_index_location.\n", NULL);
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
+    goto out;
+  }
+
+  slot_data->rollback_indexes[rollback_index_location] =
+      vbmeta_header.rollback_index;
+
+  if (out_algorithm_type != NULL) {
+    *out_algorithm_type = (AvbAlgorithmType)vbmeta_header.algorithm_type;
+  }
+
+out:
+  /* If |vbmeta_image_data| isn't NULL it means that it adopted
+   * |vbmeta_buf| so in that case don't free it here.
+   */
+  if (vbmeta_image_data == NULL) {
+    if (vbmeta_buf != NULL) {
+      avb_free(vbmeta_buf);
+    }
+  }
+  if (descriptors != NULL) {
+    avb_free(descriptors);
+  }
+  return ret;
+}
+
+AvbSlotVerifyResult avb_slot_verify(AvbOps* ops,
+                                    const char* const* requested_partitions,
+                                    const char* ab_suffix,
+                                    AvbSlotVerifyFlags flags,
+                                    AvbHashtreeErrorMode hashtree_error_mode,
+                                    AvbSlotVerifyData** out_data) {
+  AvbSlotVerifyResult ret;
+  AvbSlotVerifyData* slot_data = NULL;
+  AvbAlgorithmType algorithm_type = AVB_ALGORITHM_TYPE_NONE;
+  bool using_boot_for_vbmeta = false;
+  AvbVBMetaImageHeader toplevel_vbmeta;
+  bool allow_verification_error =
+      (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR);
+  AvbCmdlineSubstList* additional_cmdline_subst = NULL;
+
+  /* Fail early if we're missing the AvbOps needed for slot verification.
+   *
+   * For now, handle get_size_of_partition() not being implemented. In
+   * a later release we may change that.
+   */
+  avb_assert(ops->read_is_device_unlocked != NULL);
+  avb_assert(ops->read_from_partition != NULL);
+  avb_assert(ops->validate_vbmeta_public_key != NULL);
+  avb_assert(ops->read_rollback_index != NULL);
+  avb_assert(ops->get_unique_guid_for_partition != NULL);
+
+  if (out_data != NULL) {
+    *out_data = NULL;
+  }
+
+  /* Allowing dm-verity errors defeats the purpose of verified boot so
+   * only allow this if set up to allow verification errors
+   * (e.g. typically only UNLOCKED mode).
+   */
+  if (hashtree_error_mode == AVB_HASHTREE_ERROR_MODE_LOGGING &&
+      !allow_verification_error) {
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT;
+    goto fail;
+  }
+
+  slot_data = avb_calloc(sizeof(AvbSlotVerifyData));
+  if (slot_data == NULL) {
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+    goto fail;
+  }
+  slot_data->vbmeta_images =
+      avb_calloc(sizeof(AvbVBMetaData) * MAX_NUMBER_OF_VBMETA_IMAGES);
+  if (slot_data->vbmeta_images == NULL) {
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+    goto fail;
+  }
+  slot_data->loaded_partitions =
+      avb_calloc(sizeof(AvbPartitionData) * MAX_NUMBER_OF_LOADED_PARTITIONS);
+  if (slot_data->loaded_partitions == NULL) {
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+    goto fail;
+  }
+
+  additional_cmdline_subst = avb_new_cmdline_subst_list();
+  if (additional_cmdline_subst == NULL) {
+    ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+    goto fail;
+  }
+
+  ret = load_and_verify_vbmeta(ops,
+                               requested_partitions,
+                               ab_suffix,
+                               allow_verification_error,
+                               0 /* toplevel_vbmeta_flags */,
+                               0 /* rollback_index_location */,
+                               "vbmeta",
+                               avb_strlen("vbmeta"),
+                               NULL /* expected_public_key */,
+                               0 /* expected_public_key_length */,
+                               slot_data,
+                               &algorithm_type,
+                               additional_cmdline_subst);
+  if (!allow_verification_error && ret != AVB_SLOT_VERIFY_RESULT_OK) {
+    goto fail;
+  }
+
+  /* If things check out, mangle the kernel command-line as needed. */
+  if (result_should_continue(ret)) {
+    if (avb_strcmp(slot_data->vbmeta_images[0].partition_name, "vbmeta") != 0) {
+      avb_assert(
+          avb_strcmp(slot_data->vbmeta_images[0].partition_name, "boot") == 0);
+      using_boot_for_vbmeta = true;
+    }
+
+    /* Byteswap top-level vbmeta header since we'll need it below. */
+    avb_vbmeta_image_header_to_host_byte_order(
+        (const AvbVBMetaImageHeader*)slot_data->vbmeta_images[0].vbmeta_data,
+        &toplevel_vbmeta);
+
+    /* Fill in |ab_suffix| field. */
+    slot_data->ab_suffix = avb_strdup(ab_suffix);
+    if (slot_data->ab_suffix == NULL) {
+      ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+      goto fail;
+    }
+
+    /* If verification is disabled, we are done ... we specifically
+     * don't want to add any androidboot.* options since verification
+     * is disabled.
+     */
+    if (toplevel_vbmeta.flags & AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED) {
+      /* Since verification is disabled we didn't process any
+       * descriptors and thus there's no cmdline... so set root= such
+       * that the system partition is mounted.
+       */
+      avb_assert(slot_data->cmdline == NULL);
+      slot_data->cmdline =
+          avb_strdup("root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)");
+      if (slot_data->cmdline == NULL) {
+        ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+        goto fail;
+      }
+    } else {
+      /* Add options - any failure in avb_append_options() is either an
+       * I/O or OOM error.
+       */
+      AvbSlotVerifyResult sub_ret = avb_append_options(ops,
+                                                       slot_data,
+                                                       &toplevel_vbmeta,
+                                                       algorithm_type,
+                                                       hashtree_error_mode);
+      if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) {
+        ret = sub_ret;
+        goto fail;
+      }
+    }
+
+    /* Substitute $(ANDROID_SYSTEM_PARTUUID) and friends. */
+    if (slot_data->cmdline != NULL) {
+      char* new_cmdline;
+      new_cmdline = avb_sub_cmdline(ops,
+                                    slot_data->cmdline,
+                                    ab_suffix,
+                                    using_boot_for_vbmeta,
+                                    additional_cmdline_subst);
+      if (new_cmdline != slot_data->cmdline) {
+        if (new_cmdline == NULL) {
+          ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
+          goto fail;
+        }
+        avb_free(slot_data->cmdline);
+        slot_data->cmdline = new_cmdline;
+      }
+    }
+
+    if (out_data != NULL) {
+      *out_data = slot_data;
+    } else {
+      avb_slot_verify_data_free(slot_data);
+    }
+  }
+
+  avb_free_cmdline_subst_list(additional_cmdline_subst);
+  additional_cmdline_subst = NULL;
+
+  if (!allow_verification_error) {
+    avb_assert(ret == AVB_SLOT_VERIFY_RESULT_OK);
+  }
+
+  return ret;
+
+fail:
+  if (slot_data != NULL) {
+    avb_slot_verify_data_free(slot_data);
+  }
+  if (additional_cmdline_subst != NULL) {
+    avb_free_cmdline_subst_list(additional_cmdline_subst);
+  }
+  return ret;
+}
+
+void avb_slot_verify_data_free(AvbSlotVerifyData* data) {
+  if (data->ab_suffix != NULL) {
+    avb_free(data->ab_suffix);
+  }
+  if (data->cmdline != NULL) {
+    avb_free(data->cmdline);
+  }
+  if (data->vbmeta_images != NULL) {
+    size_t n;
+    for (n = 0; n < data->num_vbmeta_images; n++) {
+      AvbVBMetaData* vbmeta_image = &data->vbmeta_images[n];
+      if (vbmeta_image->partition_name != NULL) {
+        avb_free(vbmeta_image->partition_name);
+      }
+      if (vbmeta_image->vbmeta_data != NULL) {
+        avb_free(vbmeta_image->vbmeta_data);
+      }
+    }
+    avb_free(data->vbmeta_images);
+  }
+  if (data->loaded_partitions != NULL) {
+    size_t n;
+    for (n = 0; n < data->num_loaded_partitions; n++) {
+      AvbPartitionData* loaded_partition = &data->loaded_partitions[n];
+      if (loaded_partition->partition_name != NULL) {
+        avb_free(loaded_partition->partition_name);
+      }
+      if (loaded_partition->data != NULL && !loaded_partition->preloaded) {
+        avb_free(loaded_partition->data);
+      }
+    }
+    avb_free(data->loaded_partitions);
+  }
+  avb_free(data);
+}
+
+const char* avb_slot_verify_result_to_string(AvbSlotVerifyResult result) {
+  const char* ret = NULL;
+
+  switch (result) {
+    case AVB_SLOT_VERIFY_RESULT_OK:
+      ret = "OK";
+      break;
+    case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
+      ret = "ERROR_OOM";
+      break;
+    case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
+      ret = "ERROR_IO";
+      break;
+    case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
+      ret = "ERROR_VERIFICATION";
+      break;
+    case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
+      ret = "ERROR_ROLLBACK_INDEX";
+      break;
+    case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
+      ret = "ERROR_PUBLIC_KEY_REJECTED";
+      break;
+    case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
+      ret = "ERROR_INVALID_METADATA";
+      break;
+    case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
+      ret = "ERROR_UNSUPPORTED_VERSION";
+      break;
+    case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
+      ret = "ERROR_INVALID_ARGUMENT";
+      break;
+      /* Do not add a 'default:' case here because of -Wswitch. */
+  }
+
+  if (ret == NULL) {
+    avb_error("Unknown AvbSlotVerifyResult value.\n");
+    ret = "(unknown)";
+  }
+
+  return ret;
+}
+
+void avb_slot_verify_data_calculate_vbmeta_digest(AvbSlotVerifyData* data,
+                                                  AvbDigestType digest_type,
+                                                  uint8_t* out_digest) {
+  bool ret = false;
+  size_t n;
+
+  switch (digest_type) {
+    case AVB_DIGEST_TYPE_SHA256: {
+      AvbSHA256Ctx ctx;
+      avb_sha256_init(&ctx);
+      for (n = 0; n < data->num_vbmeta_images; n++) {
+        avb_sha256_update(&ctx,
+                          data->vbmeta_images[n].vbmeta_data,
+                          data->vbmeta_images[n].vbmeta_size);
+      }
+      avb_memcpy(out_digest, avb_sha256_final(&ctx), AVB_SHA256_DIGEST_SIZE);
+      ret = true;
+    } break;
+
+    case AVB_DIGEST_TYPE_SHA512: {
+      AvbSHA512Ctx ctx;
+      avb_sha512_init(&ctx);
+      for (n = 0; n < data->num_vbmeta_images; n++) {
+        avb_sha512_update(&ctx,
+                          data->vbmeta_images[n].vbmeta_data,
+                          data->vbmeta_images[n].vbmeta_size);
+      }
+      avb_memcpy(out_digest, avb_sha512_final(&ctx), AVB_SHA512_DIGEST_SIZE);
+      ret = true;
+    } break;
+
+      /* Do not add a 'default:' case here because of -Wswitch. */
+  }
+
+  if (!ret) {
+    avb_fatal("Unknown digest type");
+  }
+}
