diff options
Diffstat (limited to 'lib/avb/libavb')
-rw-r--r-- | lib/avb/libavb/avb_crc32.c | 9 | ||||
-rw-r--r-- | lib/avb/libavb/avb_ops.h | 14 | ||||
-rw-r--r-- | lib/avb/libavb/avb_rsa.c | 30 | ||||
-rw-r--r-- | lib/avb/libavb/avb_slot_verify.c | 612 | ||||
-rw-r--r-- | lib/avb/libavb/avb_slot_verify.h | 148 | ||||
-rw-r--r-- | lib/avb/libavb/avb_sysdeps.h | 2 | ||||
-rw-r--r-- | lib/avb/libavb/avb_vbmeta_image.h | 10 | ||||
-rw-r--r-- | lib/avb/libavb/avb_version.h | 4 |
8 files changed, 643 insertions, 186 deletions
diff --git a/lib/avb/libavb/avb_crc32.c b/lib/avb/libavb/avb_crc32.c index a6b806d358..7d4cb09035 100644 --- a/lib/avb/libavb/avb_crc32.c +++ b/lib/avb/libavb/avb_crc32.c @@ -43,10 +43,11 @@ */ #include "avb_sysdeps.h" +#include "avb_util.h" /* Code taken from FreeBSD 8 */ -static uint32_t crc32_tab[] = { +static uint32_t iavb_crc32_tab[] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, @@ -98,16 +99,16 @@ static uint32_t crc32_tab[] = { * in sys/libkern.h, where it can be inlined. */ -static uint32_t _crc32(uint32_t crc_in, const uint8_t* buf, int size) { +static uint32_t iavb_crc32(uint32_t crc_in, const uint8_t* buf, int size) { const uint8_t* p = buf; uint32_t crc; crc = crc_in ^ ~0U; while (size--) - crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8); + crc = iavb_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8); return crc ^ ~0U; } uint32_t avb_crc32(const uint8_t* buf, size_t size) { - return _crc32(0, buf, size); + return iavb_crc32(0, buf, size); } diff --git a/lib/avb/libavb/avb_ops.h b/lib/avb/libavb/avb_ops.h index 908c66c2ff..de36b599c0 100644 --- a/lib/avb/libavb/avb_ops.h +++ b/lib/avb/libavb/avb_ops.h @@ -71,6 +71,10 @@ struct AvbAtxOps; /* High-level operations/functions/methods that are platform * dependent. + * + * Operations may be added in the future so when implementing it + * always make sure to zero out sizeof(AvbOps) bytes of the struct to + * ensure that unimplemented operations are set to NULL. */ struct AvbOps { /* This pointer can be used by the application/bootloader using @@ -205,6 +209,16 @@ struct AvbOps { const char* partition, char* guid_buf, size_t guid_buf_size); + + /* Gets the size of a partition with the name in |partition| + * (NUL-terminated UTF-8 string). Returns the value in + * |out_size_num_bytes|. + * + * Returns AVB_IO_RESULT_OK on success, otherwise an error code. + */ + AvbIOResult (*get_size_of_partition)(AvbOps* ops, + const char* partition, + uint64_t* out_size_num_bytes); }; #ifdef __cplusplus diff --git a/lib/avb/libavb/avb_rsa.c b/lib/avb/libavb/avb_rsa.c index dcecc16973..f4cb322b9e 100644 --- a/lib/avb/libavb/avb_rsa.c +++ b/lib/avb/libavb/avb_rsa.c @@ -37,16 +37,16 @@ #include "avb_util.h" #include "avb_vbmeta_image.h" -typedef struct Key { +typedef struct IAvbKey { unsigned int len; /* Length of n[] in number of uint32_t */ uint32_t n0inv; /* -1 / n[0] mod 2^32 */ uint32_t* n; /* modulus as array (host-byte order) */ uint32_t* rr; /* R^2 as array (host-byte order) */ -} Key; +} IAvbKey; -Key* parse_key_data(const uint8_t* data, size_t length) { +static IAvbKey* iavb_parse_key_data(const uint8_t* data, size_t length) { AvbRSAPublicKeyHeader h; - Key* key = NULL; + IAvbKey* key = NULL; size_t expected_length; unsigned int i; const uint8_t* n; @@ -76,14 +76,14 @@ Key* parse_key_data(const uint8_t* data, size_t length) { /* Store n and rr following the key header so we only have to do one * allocation. */ - key = (Key*)(avb_malloc(sizeof(Key) + 2 * h.key_num_bits / 8)); + key = (IAvbKey*)(avb_malloc(sizeof(IAvbKey) + 2 * h.key_num_bits / 8)); if (key == NULL) { goto fail; } key->len = h.key_num_bits / 32; key->n0inv = h.n0inv; - key->n = (uint32_t*)(key + 1); /* Skip ahead sizeof(Key) bytes. */ + key->n = (uint32_t*)(key + 1); /* Skip ahead sizeof(IAvbKey) bytes. */ key->rr = key->n + key->len; /* Crypto-code below (modpowF4() and friends) expects the key in @@ -103,12 +103,12 @@ fail: return NULL; } -void free_parsed_key(Key* key) { +static void iavb_free_parsed_key(IAvbKey* key) { avb_free(key); } /* a[] -= mod */ -static void subM(const Key* key, uint32_t* a) { +static void subM(const IAvbKey* key, uint32_t* a) { int64_t A = 0; uint32_t i; for (i = 0; i < key->len; ++i) { @@ -119,7 +119,7 @@ static void subM(const Key* key, uint32_t* a) { } /* return a[] >= mod */ -static int geM(const Key* key, uint32_t* a) { +static int geM(const IAvbKey* key, uint32_t* a) { uint32_t i; for (i = key->len; i;) { --i; @@ -134,7 +134,7 @@ static int geM(const Key* key, uint32_t* a) { } /* montgomery c[] += a * b[] / R % mod */ -static void montMulAdd(const Key* key, +static void montMulAdd(const IAvbKey* key, uint32_t* c, const uint32_t a, const uint32_t* b) { @@ -159,7 +159,7 @@ static void montMulAdd(const Key* key, } /* montgomery c[] = a[] * b[] / R % mod */ -static void montMul(const Key* key, uint32_t* c, uint32_t* a, uint32_t* b) { +static void montMul(const IAvbKey* key, uint32_t* c, uint32_t* a, uint32_t* b) { uint32_t i; for (i = 0; i < key->len; ++i) { c[i] = 0; @@ -172,7 +172,7 @@ static void montMul(const Key* key, uint32_t* c, uint32_t* a, uint32_t* b) { /* In-place public exponentiation. (65537} * Input and output big-endian byte array in inout. */ -static void modpowF4(const Key* key, uint8_t* inout) { +static void modpowF4(const IAvbKey* key, uint8_t* inout) { uint32_t* a = (uint32_t*)avb_malloc(key->len * sizeof(uint32_t)); uint32_t* aR = (uint32_t*)avb_malloc(key->len * sizeof(uint32_t)); uint32_t* aaR = (uint32_t*)avb_malloc(key->len * sizeof(uint32_t)); @@ -237,7 +237,7 @@ bool avb_rsa_verify(const uint8_t* key, const uint8_t* padding, size_t padding_num_bytes) { uint8_t* buf = NULL; - Key* parsed_key = NULL; + IAvbKey* parsed_key = NULL; bool success = false; if (key == NULL || sig == NULL || hash == NULL || padding == NULL) { @@ -245,7 +245,7 @@ bool avb_rsa_verify(const uint8_t* key, goto out; } - parsed_key = parse_key_data(key, key_num_bytes); + parsed_key = iavb_parse_key_data(key, key_num_bytes); if (parsed_key == NULL) { avb_error("Error parsing key.\n"); goto out; @@ -290,7 +290,7 @@ bool avb_rsa_verify(const uint8_t* key, out: if (parsed_key != NULL) { - free_parsed_key(parsed_key); + iavb_free_parsed_key(parsed_key); } if (buf != NULL) { avb_free(buf); diff --git a/lib/avb/libavb/avb_slot_verify.c b/lib/avb/libavb/avb_slot_verify.c index d00b9b9404..0cec5cb7a7 100644 --- a/lib/avb/libavb/avb_slot_verify.c +++ b/lib/avb/libavb/avb_slot_verify.c @@ -32,6 +32,7 @@ #include "avb_vbmeta_image.h" #include "avb_version.h" #include <common.h> +#include "android_image.h" /* Maximum allow length (in bytes) of a partition name, including * ab_suffix. @@ -57,6 +58,7 @@ static inline bool result_should_continue(AvbSlotVerifyResult result) { 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: @@ -69,6 +71,8 @@ static inline bool result_should_continue(AvbSlotVerifyResult result) { return false; } +static struct andr_img_hdr boothdr __aligned(ARCH_DMA_MINALIGN); + static AvbSlotVerifyResult load_and_verify_hash_partition( AvbOps* ops, const char* const* requested_partitions, @@ -88,6 +92,7 @@ static AvbSlotVerifyResult load_and_verify_hash_partition( uint8_t* digest; size_t digest_len; const char* found; + uint64_t image_size; if (!avb_hash_descriptor_validate_and_byteswap( (const AvbHashDescriptor*)descriptor, &hash_desc)) { @@ -106,6 +111,17 @@ static AvbSlotVerifyResult load_and_verify_hash_partition( 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 (!avb_str_concat(part_name, sizeof part_name, (const char*)desc_partition_name, @@ -117,18 +133,70 @@ static AvbSlotVerifyResult load_and_verify_hash_partition( goto out; } - image_buf = avb_malloc(hash_desc.image_size); - if (image_buf == NULL) { + /* 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); + } + } + + /* If we are going to load bootimage, load it to + * hdr->kernel_addr - hdr->page_size address directly, + * so we don't need to copy it again!*/ + if (strstr(part_name, "boot") != NULL) { + struct andr_img_hdr *hdr = &boothdr; + /* read boot header first so we can get the address */ + if (ops->read_from_partition(ops, part_name, + 0, sizeof(boothdr), hdr, &part_num_read) != AVB_IO_RESULT_OK && + part_num_read != sizeof(boothdr)) { + printf("Error! read bootimage head error\n"); + ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO; + goto out; + } + /* check bootimg header to make sure we have a vaild bootimage */ + if (android_image_check_header(hdr)) { + printf("Error! bad boot image magic\n"); + /* bad boot image magic is critical so we will return + * AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA here, + * it will make this slot be marked as unbootable.*/ + ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; + goto out; + } + + image_buf = (uint8_t*)(unsigned long)(hdr->kernel_addr - hdr->page_size); + } else { + image_buf = avb_malloc(hash_desc.image_size); + if (image_buf == NULL) { ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; goto out; + } } - io_ret = ops->read_from_partition(ops, - part_name, - 0 /* offset */, - hash_desc.image_size, - image_buf, - &part_num_read); + io_ret = ops->read_from_partition( + ops, part_name, 0 /* offset */, image_size, image_buf, &part_num_read); if (io_ret == AVB_IO_RESULT_ERROR_OOM) { ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; goto out; @@ -137,7 +205,7 @@ static AvbSlotVerifyResult load_and_verify_hash_partition( ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO; goto out; } - if (part_num_read != hash_desc.image_size) { + if (part_num_read != image_size) { avb_errorv(part_name, ": Read fewer than requested bytes.\n", NULL); ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO; goto out; @@ -182,25 +250,21 @@ static AvbSlotVerifyResult load_and_verify_hash_partition( out: - if (ret == AVB_SLOT_VERIFY_RESULT_OK || result_should_continue(ret)) { - /* If this is the requested partition, copy to slot_data. */ - found = avb_strv_find_str(requested_partitions, - (const char*)desc_partition_name, - hash_desc.partition_name_len); - if (found != 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 = hash_desc.image_size; - loaded_partition->data = image_buf; - image_buf = NULL; + /* 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; + image_buf = NULL; } fail: @@ -210,6 +274,99 @@ fail: 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; + 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[PART_NAME_MAX_SIZE]; + AvbIOResult io_ret; + uint64_t image_size; + size_t part_num_read; + 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); + + image_buf = avb_malloc(image_size); + if (image_buf == NULL) { + ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; + goto out; + } + + io_ret = ops->read_from_partition( + ops, part_name, 0 /* offset */, image_size, image_buf, &part_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(part_name, ": Error loading data from partition.\n", NULL); + ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO; + goto out; + } + if (part_num_read != image_size) { + avb_errorv(part_name, ": Read fewer than requested bytes.\n", NULL); + ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO; + 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; + image_buf = NULL; + } + + ret = AVB_SLOT_VERIFY_RESULT_OK; + +out: + if (image_buf != NULL) { + avb_free(image_buf); + } + return ret; +} + static AvbSlotVerifyResult load_and_verify_vbmeta( AvbOps* ops, const char* const* requested_partitions, @@ -442,7 +599,7 @@ static AvbSlotVerifyResult load_and_verify_vbmeta( } } } else { - bool key_is_trusted = true; + bool key_is_trusted = false; const uint8_t* pk_metadata = NULL; size_t pk_metadata_len = 0; @@ -527,6 +684,27 @@ static AvbSlotVerifyResult load_and_verify_vbmeta( 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 @@ -920,21 +1098,208 @@ static int cmdline_append_hex(AvbSlotVerifyData* slot_data, return ret; } +static AvbSlotVerifyResult append_options( + AvbOps* ops, + AvbSlotVerifyData* slot_data, + AvbVBMetaImageHeader* toplevel_vbmeta, + AvbAlgorithmType algorithm_type, + AvbHashtreeErrorMode hashtree_error_mode) { + AvbSlotVerifyResult ret; + const char* verity_mode = "enforcing"; + bool is_device_unlocked; + AvbIOResult io_ret; + + /* Add androidboot.vbmeta.device option. */ + if (!cmdline_append_option(slot_data, + "androidboot.vbmeta.device", + "PARTUUID=$(ANDROID_VBMETA_PARTUUID)")) { + ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; + goto out; + } + + /* Add androidboot.vbmeta.avb_version option. */ + if (!cmdline_append_version(slot_data, + "androidboot.vbmeta.avb_version", + AVB_VERSION_MAJOR, + AVB_VERSION_MINOR)) { + ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; + goto out; + } + + /* Set androidboot.avb.device_state to "locked" or "unlocked". */ + io_ret = ops->read_is_device_unlocked(ops, &is_device_unlocked); + 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_error("Error getting device state.\n"); + ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO; + goto out; + } + if (!cmdline_append_option(slot_data, + "androidboot.vbmeta.device_state", + is_device_unlocked ? "unlocked" : "locked")) { + ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; + goto out; + } + + /* Set androidboot.vbmeta.{hash_alg, size, digest} - use same hash + * function as is used to sign vbmeta. + */ + switch (algorithm_type) { + /* Explicit fallthrough. */ + case AVB_ALGORITHM_TYPE_NONE: + case AVB_ALGORITHM_TYPE_SHA256_RSA2048: + case AVB_ALGORITHM_TYPE_SHA256_RSA4096: + case AVB_ALGORITHM_TYPE_SHA256_RSA8192: { + AvbSHA256Ctx ctx; + size_t n, total_size = 0; + avb_sha256_init(&ctx); + for (n = 0; n < slot_data->num_vbmeta_images; n++) { + avb_sha256_update(&ctx, + slot_data->vbmeta_images[n].vbmeta_data, + slot_data->vbmeta_images[n].vbmeta_size); + total_size += slot_data->vbmeta_images[n].vbmeta_size; + } + if (!cmdline_append_option( + slot_data, "androidboot.vbmeta.hash_alg", "sha256") || + !cmdline_append_uint64_base10( + slot_data, "androidboot.vbmeta.size", total_size) || + !cmdline_append_hex(slot_data, + "androidboot.vbmeta.digest", + avb_sha256_final(&ctx), + AVB_SHA256_DIGEST_SIZE)) { + ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; + goto out; + } + } break; + /* Explicit fallthrough. */ + case AVB_ALGORITHM_TYPE_SHA512_RSA2048: + case AVB_ALGORITHM_TYPE_SHA512_RSA4096: + case AVB_ALGORITHM_TYPE_SHA512_RSA8192: { + AvbSHA512Ctx ctx; + size_t n, total_size = 0; + avb_sha512_init(&ctx); + for (n = 0; n < slot_data->num_vbmeta_images; n++) { + avb_sha512_update(&ctx, + slot_data->vbmeta_images[n].vbmeta_data, + slot_data->vbmeta_images[n].vbmeta_size); + total_size += slot_data->vbmeta_images[n].vbmeta_size; + } + if (!cmdline_append_option( + slot_data, "androidboot.vbmeta.hash_alg", "sha512") || + !cmdline_append_uint64_base10( + slot_data, "androidboot.vbmeta.size", total_size) || + !cmdline_append_hex(slot_data, + "androidboot.vbmeta.digest", + avb_sha512_final(&ctx), + AVB_SHA512_DIGEST_SIZE)) { + ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; + goto out; + } + } break; + case _AVB_ALGORITHM_NUM_TYPES: + avb_assert_not_reached(); + break; + } + + /* Set androidboot.veritymode and androidboot.vbmeta.invalidate_on_error */ + if (toplevel_vbmeta->flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED) { + verity_mode = "disabled"; + } else { + const char* dm_verity_mode = "restart_on_corruption"; + char* new_ret; + + switch (hashtree_error_mode) { + case AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE: + if (!cmdline_append_option( + slot_data, "androidboot.vbmeta.invalidate_on_error", "yes")) { + ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; + goto out; + } + verity_mode = "enforcing"; + dm_verity_mode = "restart_on_corruption"; + break; + case AVB_HASHTREE_ERROR_MODE_RESTART: + verity_mode = "enforcing"; + dm_verity_mode = "restart_on_corruption"; + break; + case AVB_HASHTREE_ERROR_MODE_EIO: + verity_mode = "eio"; + /* For now there's no option to specify the EIO mode. So + * just use 'ignore_zero_blocks' since that's already set + * and dm-verity-target.c supports specifying this multiple + * times. + */ + dm_verity_mode = "ignore_zero_blocks"; + break; + case AVB_HASHTREE_ERROR_MODE_LOGGING: + verity_mode = "logging"; + dm_verity_mode = "ignore_corruption"; + break; + } + new_ret = avb_replace( + slot_data->cmdline, "$(ANDROID_VERITY_MODE)", dm_verity_mode); + avb_free(slot_data->cmdline); + slot_data->cmdline = new_ret; + if (slot_data->cmdline == NULL) { + ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; + goto out; + } + } + if (!cmdline_append_option( + slot_data, "androidboot.veritymode", verity_mode)) { + ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; + goto out; + } + + ret = AVB_SLOT_VERIFY_RESULT_OK; + +out: + + return ret; +} + AvbSlotVerifyResult avb_slot_verify(AvbOps* ops, const char* const* requested_partitions, const char* ab_suffix, - bool allow_verification_error, + AvbSlotVerifyFlags flags, + AvbHashtreeErrorMode hashtree_error_mode, AvbSlotVerifyData** out_data) { AvbSlotVerifyResult ret; AvbSlotVerifyData* slot_data = NULL; AvbAlgorithmType algorithm_type = AVB_ALGORITHM_TYPE_NONE; - AvbIOResult io_ret; bool using_boot_for_vbmeta = false; + AvbVBMetaImageHeader toplevel_vbmeta; + bool allow_verification_error = + (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR); + + /* 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); + /* avb_assert(ops->get_size_of_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; @@ -969,14 +1334,19 @@ AvbSlotVerifyResult avb_slot_verify(AvbOps* ops, goto fail; } - 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; - } - /* 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) { @@ -984,21 +1354,35 @@ AvbSlotVerifyResult avb_slot_verify(AvbOps* ops, goto fail; } - /* Add androidboot.vbmeta.device option. */ - if (!cmdline_append_option(slot_data, - "androidboot.vbmeta.device", - "PARTUUID=$(ANDROID_VBMETA_PARTUUID)")) { - ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; - goto fail; - } - - /* Add androidboot.vbmeta.avb_version option. */ - if (!cmdline_append_version(slot_data, - "androidboot.vbmeta.avb_version", - AVB_VERSION_MAJOR, - AVB_VERSION_MINOR)) { - 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 append_options() is either an + * I/O or OOM error. + */ + AvbSlotVerifyResult sub_ret = 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. */ @@ -1014,84 +1398,6 @@ AvbSlotVerifyResult avb_slot_verify(AvbOps* ops, slot_data->cmdline = new_cmdline; } - /* Set androidboot.avb.device_state to "locked" or "unlocked". */ - bool is_device_unlocked; - io_ret = ops->read_is_device_unlocked(ops, &is_device_unlocked); - if (io_ret == AVB_IO_RESULT_ERROR_OOM) { - ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; - goto fail; - } else if (io_ret != AVB_IO_RESULT_OK) { - avb_error("Error getting device state.\n"); - ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO; - goto fail; - } - if (!cmdline_append_option(slot_data, - "androidboot.vbmeta.device_state", - is_device_unlocked ? "unlocked" : "locked")) { - ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; - goto fail; - } - - /* Set androidboot.vbmeta.{hash_alg, size, digest} - use same hash - * function as is used to sign vbmeta. - */ - switch (algorithm_type) { - /* Explicit fallthrough. */ - case AVB_ALGORITHM_TYPE_NONE: - case AVB_ALGORITHM_TYPE_SHA256_RSA2048: - case AVB_ALGORITHM_TYPE_SHA256_RSA4096: - case AVB_ALGORITHM_TYPE_SHA256_RSA8192: { - AvbSHA256Ctx ctx; - size_t n, total_size = 0; - avb_sha256_init(&ctx); - for (n = 0; n < slot_data->num_vbmeta_images; n++) { - avb_sha256_update(&ctx, - slot_data->vbmeta_images[n].vbmeta_data, - slot_data->vbmeta_images[n].vbmeta_size); - total_size += slot_data->vbmeta_images[n].vbmeta_size; - } - if (!cmdline_append_option( - slot_data, "androidboot.vbmeta.hash_alg", "sha256") || - !cmdline_append_uint64_base10( - slot_data, "androidboot.vbmeta.size", total_size) || - !cmdline_append_hex(slot_data, - "androidboot.vbmeta.digest", - avb_sha256_final(&ctx), - AVB_SHA256_DIGEST_SIZE)) { - ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; - goto fail; - } - } break; - /* Explicit fallthrough. */ - case AVB_ALGORITHM_TYPE_SHA512_RSA2048: - case AVB_ALGORITHM_TYPE_SHA512_RSA4096: - case AVB_ALGORITHM_TYPE_SHA512_RSA8192: { - AvbSHA512Ctx ctx; - size_t n, total_size = 0; - avb_sha512_init(&ctx); - for (n = 0; n < slot_data->num_vbmeta_images; n++) { - avb_sha512_update(&ctx, - slot_data->vbmeta_images[n].vbmeta_data, - slot_data->vbmeta_images[n].vbmeta_size); - total_size += slot_data->vbmeta_images[n].vbmeta_size; - } - if (!cmdline_append_option( - slot_data, "androidboot.vbmeta.hash_alg", "sha512") || - !cmdline_append_uint64_base10( - slot_data, "androidboot.vbmeta.size", total_size) || - !cmdline_append_hex(slot_data, - "androidboot.vbmeta.digest", - avb_sha512_final(&ctx), - AVB_SHA512_DIGEST_SIZE)) { - ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; - goto fail; - } - } break; - case _AVB_ALGORITHM_NUM_TYPES: - avb_assert_not_reached(); - break; - } - if (out_data != NULL) { *out_data = slot_data; } else { @@ -1107,11 +1413,54 @@ AvbSlotVerifyResult avb_slot_verify(AvbOps* ops, fail: if (slot_data != NULL) { - avb_slot_verify_data_free(slot_data); + /* the address of bootimage isn't alloced by malloc, + * we should not free it. */ + avb_slot_verify_data_free_fast(slot_data); } return ret; } +void avb_slot_verify_data_free_fast(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) { + /* the address of bootimage isn't alloced by malloc, we don't + * need to free it. */ + if (strstr(loaded_partition->partition_name, "boot") != NULL) + continue; + else + avb_free(loaded_partition->partition_name); + } + if (loaded_partition->data != NULL) { + avb_free(loaded_partition->data); + } + } + avb_free(data->loaded_partitions); + } + avb_free(data); +} + void avb_slot_verify_data_free(AvbSlotVerifyData* data) { if (data->ab_suffix != NULL) { avb_free(data->ab_suffix); @@ -1176,6 +1525,9 @@ const char* avb_slot_verify_result_to_string(AvbSlotVerifyResult result) { 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. */ } diff --git a/lib/avb/libavb/avb_slot_verify.h b/lib/avb/libavb/avb_slot_verify.h index 08b11fcf1a..60033cfbe3 100644 --- a/lib/avb/libavb/avb_slot_verify.h +++ b/lib/avb/libavb/avb_slot_verify.h @@ -50,9 +50,61 @@ typedef enum { AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX, AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED, AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA, - AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION + AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION, + AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT } AvbSlotVerifyResult; +/* Various error handling modes for when verification fails using a + * hashtree at runtime inside the HLOS. + * + * AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE means that the OS + * will invalidate the current slot and restart. + * + * AVB_HASHTREE_ERROR_MODE_RESTART means that the OS will restart. + * + * AVB_HASHTREE_ERROR_MODE_EIO means that an EIO error will be + * returned to applications. + * + * AVB_HASHTREE_ERROR_MODE_LOGGING means that errors will be logged + * and corrupt data may be returned to applications. This mode should + * be used ONLY for diagnostics and debugging. It cannot be used + * unless AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR is also + * used. + */ +typedef enum { + AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, + AVB_HASHTREE_ERROR_MODE_RESTART, + AVB_HASHTREE_ERROR_MODE_EIO, + AVB_HASHTREE_ERROR_MODE_LOGGING +} AvbHashtreeErrorMode; + +/* Flags that influence how avb_slot_verify() works. + * + * If AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR is NOT set then + * avb_slot_verify() will bail out as soon as an error is encountered + * and |out_data| is set only if AVB_SLOT_VERIFY_RESULT_OK is + * returned. + * + * Otherwise if AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR is set + * avb_slot_verify() will continue verification efforts and |out_data| + * is also set if AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED, + * AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION, or + * AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX is returned. It is + * undefined which error is returned if more than one distinct error + * is encountered. It is guaranteed that AVB_SLOT_VERIFY_RESULT_OK is + * returned if, and only if, there are no errors. This mode is needed + * to boot valid but unverified slots when the device is unlocked. + * + * Also, if AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR is set the + * contents loaded from |requested_partition| will be the contents of + * the entire partition instead of just the size specified in the hash + * descriptor. + */ +typedef enum { + AVB_SLOT_VERIFY_FLAGS_NONE = 0, + AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR = (1 << 0) +} AvbSlotVerifyFlags; + /* Get a textual representation of |result|. */ const char* avb_slot_verify_result_to_string(AvbSlotVerifyResult result); @@ -103,7 +155,10 @@ typedef struct { * avb_slot_verify_data_free() function is called. * * The |ab_suffix| field is the copy of the of |ab_suffix| field - * passed to avb_slot_verify(). It is the A/B suffix of the slot. + * passed to avb_slot_verify(). It is the A/B suffix of the slot. This + * value includes the leading underscore - typical values are "" (if + * no slots are in use), "_a" (for the first slot), and "_b" (for the + * second slot). * * The VBMeta images that were checked are available in the * |vbmeta_images| field. The field |num_vbmeta_images| contains the @@ -132,10 +187,25 @@ typedef struct { * performing proper substitution of the variables * $(ANDROID_SYSTEM_PARTUUID), $(ANDROID_BOOT_PARTUUID), and * $(ANDROID_VBMETA_PARTUUID) using the - * get_unique_guid_for_partition() operation in |AvbOps|. + * get_unique_guid_for_partition() operation in |AvbOps|. Additionally + * $(ANDROID_VERITY_MODE) will be replaced with the proper dm-verity + * option depending on the value of |hashtree_error_mode|. * * Additionally, the |cmdline| field will have the following kernel - * command-line options set: + * command-line options set (unless verification is disabled, see + * below): + * + * androidboot.veritymode: This is set to 'disabled' if the + * AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED flag is set in top-level + * vbmeta struct. Otherwise it is set to 'enforcing' if the + * passed-in hashtree error mode is AVB_HASHTREE_ERROR_MODE_RESTART + * or AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 'eio' if it's + * set to AVB_HASHTREE_ERROR_MODE_EIO, and 'logging' if it's set to + * AVB_HASHTREE_ERROR_MODE_LOGGING. + * + * androidboot.vbmeta.invalidate_on_error: This is set to 'yes' only + * if hashtree validation isn't disabled and the passed-in hashtree + * error mode is AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE. * * androidboot.vbmeta.device_state: set to "locked" or "unlocked" * depending on the result of the result of AvbOps's @@ -158,8 +228,20 @@ typedef struct { * necessarily the same version number of the on-disk metadata for * the slot that was verified. * - * Note that androidboot.slot_suffix is not set in |cmdline| - you - * will have to pass this command-line option yourself. + * Note that androidboot.slot_suffix is not set in the |cmdline| field + * in |AvbSlotVerifyData| - you will have to set this yourself. + * + * If the |AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED| flag is set + * in the top-level vbmeta struct then only the top-level vbmeta + * struct is verified and descriptors will not processed. The return + * value will be set accordingly (if this flag is set via 'avbctl + * disable-verification' then the return value will be + * |AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION|) and + * |AvbSlotVerifyData| is returned. Additionally all partitions in the + * |requested_partitions| are loaded and the |cmdline| field is set to + * "root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)" and the GUID for the + * appropriate system partition is substituted in. Note that none of + * the androidboot.* options mentioned above will be set. * * This struct may grow in the future without it being considered an * ABI break. @@ -174,23 +256,28 @@ typedef struct { uint64_t rollback_indexes[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS]; } AvbSlotVerifyData; +/* Fast version of avb_slot_verify_data_free, this method will not + * free bootimage */ +void avb_slot_verify_data_free_fast(AvbSlotVerifyData* data); /* Frees a |AvbSlotVerifyData| including all data it points to. */ void avb_slot_verify_data_free(AvbSlotVerifyData* data); /* Performs a full verification of the slot identified by |ab_suffix| - * and load the contents of the partitions whose name is in the - * NULL-terminated string array |requested_partitions| (each partition - * must use hash verification). If not using A/B, pass an empty string - * (e.g. "", not NULL) for |ab_suffix|. + * and load and verify the contents of the partitions whose name is in + * the NULL-terminated string array |requested_partitions| (each + * partition must use hash verification). If not using A/B, pass an + * empty string (e.g. "", not NULL) for |ab_suffix|. This parameter + * must include the leading underscore, for example "_a" should be + * used to refer to the first slot. * * Typically the |requested_partitions| array only contains a single * item for the boot partition, 'boot'. * - * Verification includes loading data from the 'vbmeta', all hash - * partitions, and possibly other partitions (with |ab_suffix| - * appended), inspecting rollback indexes, and checking if the public - * key used to sign the data is acceptable. The functions in |ops| - * will be used to do this. + * Verification includes loading and verifying data from the 'vbmeta', + * the requested hash partitions, and possibly other partitions (with + * |ab_suffix| appended), inspecting rollback indexes, and checking if + * the public key used to sign the data is acceptable. The functions + * in |ops| will be used to do this. * * If |out_data| is not NULL, it will be set to a newly allocated * |AvbSlotVerifyData| struct containing all the data needed to @@ -198,19 +285,18 @@ void avb_slot_verify_data_free(AvbSlotVerifyData* data); * avb_slot_verify_data_free() when you are done with it. See below * for when this is returned. * - * If |allow_verification_error| is false this function will bail out - * as soon as an error is encountered and |out_data| is set only if - * AVB_SLOT_VERIFY_RESULT_OK is returned. + * The |flags| parameter is used to influence the semantics of + * avb_slot_verify() - for example the + * AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR flag can be used to + * ignore verification errors which is something needed in the + * UNLOCKED state. See the AvbSlotVerifyFlags enumeration for details. * - * Otherwise if |allow_verification_error| is true the function will - * continue verification efforts and |out_data| is also set if - * AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED, - * AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION, or - * AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX is returned. It is - * undefined which error is returned if more than one distinct error - * is encountered. It is guaranteed that AVB_SLOT_VERIFY_RESULT_OK is - * returned if, and only if, there are no errors. This mode is needed - * to boot valid but unverified slots when the device is unlocked. + * The |hashtree_error_mode| parameter should be set to the desired + * error handling mode when hashtree validation fails inside the + * HLOS. This value isn't used by libavb per se - it is forwarded to + * the HLOS through the androidboot.veritymode and + * androidboot.vbmeta.invalidate_on_error cmdline parameters. See the + * AvbHashtreeErrorMode enumeration for details. * * Also note that |out_data| is never set if * AVB_SLOT_VERIFY_RESULT_ERROR_OOM, AVB_SLOT_VERIFY_RESULT_ERROR_IO, @@ -243,11 +329,17 @@ void avb_slot_verify_data_free(AvbSlotVerifyData* data); * AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION is returned if * some of the metadata requires a newer version of libavb than what * is in use. + * + * AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT is returned if the + * caller passed invalid parameters, for example trying to use + * AVB_HASHTREE_ERROR_MODE_LOGGING without + * AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR. */ AvbSlotVerifyResult avb_slot_verify(AvbOps* ops, const char* const* requested_partitions, const char* ab_suffix, - bool allow_verification_error, + AvbSlotVerifyFlags flags, + AvbHashtreeErrorMode hashtree_error_mode, AvbSlotVerifyData** out_data); #ifdef __cplusplus diff --git a/lib/avb/libavb/avb_sysdeps.h b/lib/avb/libavb/avb_sysdeps.h index dfad04f808..34556e22c8 100644 --- a/lib/avb/libavb/avb_sysdeps.h +++ b/lib/avb/libavb/avb_sysdeps.h @@ -38,8 +38,6 @@ extern "C" { * like uint8_t, uint64_t, and bool (with |false|, |true| keywords) * must be present. */ - -//#define bool int #include <common.h> /* If you don't have gcc or clang, these attribute macros may need to diff --git a/lib/avb/libavb/avb_vbmeta_image.h b/lib/avb/libavb/avb_vbmeta_image.h index 0df7126390..d0c9f15376 100644 --- a/lib/avb/libavb/avb_vbmeta_image.h +++ b/lib/avb/libavb/avb_vbmeta_image.h @@ -52,9 +52,13 @@ extern "C" { * * AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED: If this flag is set, * hashtree image verification will be disabled. + * + * AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED: If this flag is set, + * verification will be disabled and descriptors will not be parsed. */ typedef enum { - AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED = (1 << 0) + AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED = (1 << 0), + AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED = (1 << 1) } AvbVBMetaImageFlags; /* Binary format for header of the vbmeta image. @@ -107,8 +111,8 @@ typedef enum { * minimum version of libavb required to verify the header and depends * on the features (e.g. algorithms, descriptors) used. Note that this * may be 1.0 even if generated by an avbtool from 1.4 but where no - * features introduced after 1.0 has been used. See the VERSIONING AND - * COMPATIBILITY section in the README file for more details. + * features introduced after 1.0 has been used. See the "Versioning + * and compatibility" section in the README.md file for more details. * * All fields are stored in network byte order when serialized. To * generate a copy with fields swapped to native byte order, use the diff --git a/lib/avb/libavb/avb_version.h b/lib/avb/libavb/avb_version.h index 7757d090d3..9d92970074 100644 --- a/lib/avb/libavb/avb_version.h +++ b/lib/avb/libavb/avb_version.h @@ -52,10 +52,6 @@ extern "C" { */ const char* avb_version_string(void); -/* TODO: remove when there are no more users of AVB_{MAJOR,MINOR}_VERSION. */ -#define AVB_MAJOR_VERSION AVB_VERSION_MAJOR -#define AVB_MINOR_VERSION AVB_VERSION_MINOR - #ifdef __cplusplus } #endif |