
From: Jiyong Park jiyong@google.com
Previously Android AVB supported block devices only on eMMC. This change eliminates the restriction by using the generic block driver model.
The `avb init' command is modified to accept another parameter which specifies the interface type. e.g., `avb init virtio 0' initializes avb for the first (0) disk that is accessible via the virtio interface.
[adelva: The "avb init" command is updated directly, as this is considered a "debug command" that can't be usefully used in u-boot scripts.]
Signed-off-by: Alistair Delva adelva@google.com Cc: Igor Opaniuk igor.opaniuk@gmail.com Cc: Ram Muthiah rammuthiah@google.com Cc: Jiyong Park jiyong@google.com Cc: Simon Glass sjg@chromium.org --- cmd/avb.c | 16 ++++--- common/Kconfig | 1 - common/avb_verify.c | 105 +++++++++++++++++++++---------------------- include/avb_verify.h | 31 ++++--------- 4 files changed, 69 insertions(+), 84 deletions(-)
diff --git a/cmd/avb.c b/cmd/avb.c index 783f51b816..8bffe49011 100644 --- a/cmd/avb.c +++ b/cmd/avb.c @@ -10,24 +10,25 @@ #include <env.h> #include <image.h> #include <malloc.h> -#include <mmc.h>
#define AVB_BOOTARGS "avb_bootargs" static struct AvbOps *avb_ops;
int do_avb_init(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { - unsigned long mmc_dev; + const char *iface; + const char *devnum;
- if (argc != 2) + if (argc != 3) return CMD_RET_USAGE;
- mmc_dev = hextoul(argv[1], NULL); + iface = argv[1]; + devnum = argv[2];
if (avb_ops) avb_ops_free(avb_ops);
- avb_ops = avb_ops_alloc(mmc_dev); + avb_ops = avb_ops_alloc(iface, devnum); if (avb_ops) return CMD_RET_SUCCESS;
@@ -419,7 +420,7 @@ int do_avb_write_pvalue(struct cmd_tbl *cmdtp, int flag, int argc, }
static struct cmd_tbl cmd_avb[] = { - U_BOOT_CMD_MKENT(init, 2, 0, do_avb_init, "", ""), + U_BOOT_CMD_MKENT(init, 3, 0, do_avb_init, "", ""), U_BOOT_CMD_MKENT(read_rb, 2, 0, do_avb_read_rb, "", ""), U_BOOT_CMD_MKENT(write_rb, 3, 0, do_avb_write_rb, "", ""), U_BOOT_CMD_MKENT(is_unlocked, 1, 0, do_avb_is_unlocked, "", ""), @@ -455,7 +456,8 @@ static int do_avb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) U_BOOT_CMD( avb, 29, 0, do_avb, "Provides commands for testing Android Verified Boot 2.0 functionality", - "init <dev> - initialize avb2 for <dev>\n" + "init <interface> <devnum> - initialize avb2 for the disk <devnum> which\n" + " is on the interface <interface>\n" "avb read_rb <num> - read rollback index at location <num>\n" "avb write_rb <num> <rb> - write rollback index <rb> to <num>\n" "avb is_unlocked - returns unlock status of the device\n" diff --git a/common/Kconfig b/common/Kconfig index ebee856e56..a66060767c 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -703,7 +703,6 @@ config HASH config AVB_VERIFY bool "Build Android Verified Boot operations" depends on LIBAVB - depends on MMC depends on PARTITION_UUIDS help This option enables compilation of bootloader-dependent operations, diff --git a/common/avb_verify.c b/common/avb_verify.c index 0520a71455..d30bbb5726 100644 --- a/common/avb_verify.c +++ b/common/avb_verify.c @@ -253,10 +253,10 @@ char *avb_set_enforce_verity(const char *cmdline)
/** * ============================================================================ - * IO(mmc) auxiliary functions + * IO auxiliary functions * ============================================================================ */ -static unsigned long mmc_read_and_flush(struct mmc_part *part, +static unsigned long blk_read_and_flush(struct avb_part *part, lbaint_t start, lbaint_t sectors, void *buffer) @@ -291,7 +291,7 @@ static unsigned long mmc_read_and_flush(struct mmc_part *part, tmp_buf = buffer; }
- blks = blk_dread(part->mmc_blk, + blks = blk_dread(part->blk, start, sectors, tmp_buf); /* flush cache after read */ flush_cache((ulong)tmp_buf, sectors * part->info.blksz); @@ -302,7 +302,7 @@ static unsigned long mmc_read_and_flush(struct mmc_part *part, return blks; }
-static unsigned long mmc_write(struct mmc_part *part, lbaint_t start, +static unsigned long blk_write(struct avb_part *part, lbaint_t start, lbaint_t sectors, void *buffer) { void *tmp_buf; @@ -330,69 +330,59 @@ static unsigned long mmc_write(struct mmc_part *part, lbaint_t start, tmp_buf = buffer; }
- return blk_dwrite(part->mmc_blk, + return blk_dwrite(part->blk, start, sectors, tmp_buf); }
-static struct mmc_part *get_partition(AvbOps *ops, const char *partition) +static struct avb_part *get_partition(AvbOps *ops, const char *partition) { - int ret; - u8 dev_num; - int part_num = 0; - struct mmc_part *part; - struct blk_desc *mmc_blk; + struct avb_part *part; + struct AvbOpsData *data; + size_t dev_part_str_len; + char *dev_part_str;
- part = malloc(sizeof(struct mmc_part)); + part = malloc(sizeof(struct avb_part)); if (!part) return NULL;
- dev_num = get_boot_device(ops); - part->mmc = find_mmc_device(dev_num); - if (!part->mmc) { - printf("No MMC device at slot %x\n", dev_num); - goto err; - } - - if (mmc_init(part->mmc)) { - printf("MMC initialization failed\n"); - goto err; - } + if (!ops) + return NULL;
- ret = mmc_switch_part(part->mmc, part_num); - if (ret) - goto err; + data = ops->user_data; + if (!data) + return NULL;
- mmc_blk = mmc_get_blk_desc(part->mmc); - if (!mmc_blk) { - printf("Error - failed to obtain block descriptor\n"); - goto err; + // format is "<devnum>#<partition>\0" + dev_part_str_len = strlen(data->devnum) + 1 + strlen(partition) + 1; + dev_part_str = (char *)malloc(dev_part_str_len); + if (!dev_part_str) { + free(part); + return NULL; }
- ret = part_get_info_by_name(mmc_blk, partition, &part->info); - if (ret < 0) { - printf("Can't find partition '%s'\n", partition); - goto err; + snprintf(dev_part_str, dev_part_str_len, "%s#%s", data->devnum, + partition); + if (part_get_info_by_dev_and_name_or_num(data->iface, dev_part_str, + &part->blk, &part->info, + false) < 0) { + free(part); + part = NULL; }
- part->dev_num = dev_num; - part->mmc_blk = mmc_blk; - + free(dev_part_str); return part; -err: - free(part); - return NULL; }
-static AvbIOResult mmc_byte_io(AvbOps *ops, +static AvbIOResult blk_byte_io(AvbOps *ops, const char *partition, s64 offset, size_t num_bytes, void *buffer, size_t *out_num_read, - enum mmc_io_type io_type) + enum io_type io_type) { ulong ret; - struct mmc_part *part; + struct avb_part *part; u64 start_offset, start_sector, sectors, residue; u8 *tmp_buf; size_t io_cnt = 0; @@ -425,7 +415,7 @@ static AvbIOResult mmc_byte_io(AvbOps *ops, }
if (io_type == IO_READ) { - ret = mmc_read_and_flush(part, + ret = blk_read_and_flush(part, part->info.start + start_sector, 1, tmp_buf); @@ -442,7 +432,7 @@ static AvbIOResult mmc_byte_io(AvbOps *ops, tmp_buf += (start_offset % part->info.blksz); memcpy(buffer, (void *)tmp_buf, residue); } else { - ret = mmc_read_and_flush(part, + ret = blk_read_and_flush(part, part->info.start + start_sector, 1, tmp_buf); @@ -456,7 +446,7 @@ static AvbIOResult mmc_byte_io(AvbOps *ops, start_offset % part->info.blksz, buffer, residue);
- ret = mmc_write(part, part->info.start + + ret = blk_write(part, part->info.start + start_sector, 1, tmp_buf); if (ret != 1) { printf("%s: write error (%ld, %lld)\n", @@ -474,12 +464,12 @@ static AvbIOResult mmc_byte_io(AvbOps *ops,
if (sectors) { if (io_type == IO_READ) { - ret = mmc_read_and_flush(part, + ret = blk_read_and_flush(part, part->info.start + start_sector, sectors, buffer); } else { - ret = mmc_write(part, + ret = blk_write(part, part->info.start + start_sector, sectors, buffer); @@ -535,7 +525,7 @@ static AvbIOResult read_from_partition(AvbOps *ops, void *buffer, size_t *out_num_read) { - return mmc_byte_io(ops, partition_name, offset_from_partition, + return blk_byte_io(ops, partition_name, offset_from_partition, num_bytes, buffer, out_num_read, IO_READ); }
@@ -562,7 +552,7 @@ static AvbIOResult write_to_partition(AvbOps *ops, size_t num_bytes, const void *buffer) { - return mmc_byte_io(ops, partition_name, offset_from_partition, + return blk_byte_io(ops, partition_name, offset_from_partition, num_bytes, (void *)buffer, NULL, IO_WRITE); }
@@ -803,7 +793,7 @@ static AvbIOResult get_unique_guid_for_partition(AvbOps *ops, char *guid_buf, size_t guid_buf_size) { - struct mmc_part *part; + struct avb_part *part; size_t uuid_size;
part = get_partition(ops, partition); @@ -837,7 +827,7 @@ static AvbIOResult get_size_of_partition(AvbOps *ops, const char *partition, u64 *out_size_num_bytes) { - struct mmc_part *part; + struct avb_part *part;
if (!out_size_num_bytes) return AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE; @@ -976,7 +966,7 @@ free_name: * AVB2.0 AvbOps alloc/initialisation/free * ============================================================================ */ -AvbOps *avb_ops_alloc(int boot_device) +AvbOps *avb_ops_alloc(const char *iface, const char *devnum) { struct AvbOpsData *ops_data;
@@ -999,7 +989,8 @@ AvbOps *avb_ops_alloc(int boot_device) ops_data->ops.read_persistent_value = read_persistent_value; #endif ops_data->ops.get_size_of_partition = get_size_of_partition; - ops_data->mmc_dev = boot_device; + ops_data->iface = avb_strdup(iface); + ops_data->devnum = avb_strdup(devnum);
return &ops_data->ops; } @@ -1018,6 +1009,12 @@ void avb_ops_free(AvbOps *ops) if (ops_data->tee) tee_close_session(ops_data->tee, ops_data->session); #endif + if (ops_data->iface) + avb_free((void*)ops_data->iface); + + if (ops_data->devnum) + avb_free((void*)ops_data->devnum); + avb_free(ops_data); } } diff --git a/include/avb_verify.h b/include/avb_verify.h index 1e787ba666..732839f74b 100644 --- a/include/avb_verify.h +++ b/include/avb_verify.h @@ -9,8 +9,9 @@ #define _AVB_VERIFY_H
#include <../lib/libavb/libavb.h> +#include <blk.h> #include <mapmem.h> -#include <mmc.h> +#include <part.h>
#define AVB_MAX_ARGS 1024 #define VERITY_TABLE_OPT_RESTART "restart_on_corruption" @@ -26,7 +27,8 @@ enum avb_boot_state {
struct AvbOpsData { struct AvbOps ops; - int mmc_dev; + const char *iface; + const char *devnum; enum avb_boot_state boot_state; #ifdef CONFIG_OPTEE_TA_AVB struct udevice *tee; @@ -34,19 +36,17 @@ struct AvbOpsData { #endif };
-struct mmc_part { - int dev_num; - struct mmc *mmc; - struct blk_desc *mmc_blk; +struct avb_part { + struct blk_desc *blk; struct disk_partition info; };
-enum mmc_io_type { +enum io_type { IO_READ, IO_WRITE };
-AvbOps *avb_ops_alloc(int boot_device); +AvbOps *avb_ops_alloc(const char *iface, const char *devnum); void avb_ops_free(AvbOps *ops);
char *avb_set_state(AvbOps *ops, enum avb_boot_state boot_state); @@ -60,7 +60,7 @@ char *append_cmd_line(char *cmdline_orig, char *cmdline_new); * I/O helper inline functions * ============================================================================ */ -static inline uint64_t calc_offset(struct mmc_part *part, int64_t offset) +static inline uint64_t calc_offset(struct avb_part *part, int64_t offset) { u64 part_size = part->info.size * part->info.blksz;
@@ -85,17 +85,4 @@ static inline bool is_buf_unaligned(void *buffer) return (bool)((uintptr_t)buffer % ALLOWED_BUF_ALIGN); }
-static inline int get_boot_device(AvbOps *ops) -{ - struct AvbOpsData *data; - - if (ops) { - data = ops->user_data; - if (data) - return data->mmc_dev; - } - - return -1; -} - #endif /* _AVB_VERIFY_H */