All of lore.kernel.org
 help / color / mirror / Atom feed
From: Igor Opaniuk <igor.opaniuk@linaro.org>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 3/8] avb2.0: implement AVB ops
Date: Wed, 25 Apr 2018 16:18:00 +0300	[thread overview]
Message-ID: <1524662285-19617-4-git-send-email-igor.opaniuk@linaro.org> (raw)
In-Reply-To: <1524662285-19617-1-git-send-email-igor.opaniuk@linaro.org>

Implement AVB ops on top of existing mmc subsystem API. Currently there
is a full implementation of such operations, defined by [1]
AVB2.0 specification:

.read_from_partition() - reads N bytes from a partition identified by
a name.
.write_to_partition() - Writes N bytes to a partition identified by a name.
.validate_vbmeta_public_key() - checks if the given public ‘vbmeta’
partition is trusted.
.get_unique_guid_for_partition() - Gets the GUID for a partition identified
by a string name.

As [1] specification recommends to use tamper-evident storage for storing
rollback indexes and device state (LOCKED/UNLOCKED),
currently are only stubs instead of full implementation for these ops:
.read_rollback_index() - Gets the rollback index for a given index location
.write_rollback_index() - Sets the rollback index to a given location
.read_is_device_unlocked() - Gets where the device is unlocked

[1] https://android.googlesource.com/platform/external/avb/+/master/README.md

Signed-off-by: Igor Opaniuk <igor.opaniuk@linaro.org>
---
 common/Makefile      |   2 +
 common/avb_verify.c  | 614 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/avb_verify.h |  80 +++++++
 3 files changed, 696 insertions(+)
 create mode 100644 common/avb_verify.c
 create mode 100644 include/avb_verify.h

diff --git a/common/Makefile b/common/Makefile
index 7011dad..7ae7ee1 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -136,3 +136,5 @@ obj-$(CONFIG_$(SPL_)LOG) += log.o
 obj-$(CONFIG_$(SPL_)LOG_CONSOLE) += log_console.o
 obj-y += s_record.o
 obj-y += xyzModem.o
+
+obj-$(CONFIG_LIBAVB_AB) += avb_verify.o
diff --git a/common/avb_verify.c b/common/avb_verify.c
new file mode 100644
index 0000000..b3d1229
--- /dev/null
+++ b/common/avb_verify.c
@@ -0,0 +1,614 @@
+/*
+ * (C) Copyright 2018, Linaro Limited
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <avb_verify.h>
+#include <fastboot.h>
+#include <image.h>
+#include <malloc.h>
+#include <part.h>
+
+const unsigned char avb_root_pub[1032] = {
+	0x0, 0x0, 0x10, 0x0, 0x55, 0xd9, 0x4, 0xad, 0xd8, 0x4,
+	0xaf, 0xe3, 0xd3, 0x84, 0x6c, 0x7e, 0xd, 0x89, 0x3d, 0xc2,
+	0x8c, 0xd3, 0x12, 0x55, 0xe9, 0x62, 0xc9, 0xf1, 0xf, 0x5e,
+	0xcc, 0x16, 0x72, 0xab, 0x44, 0x7c, 0x2c, 0x65, 0x4a, 0x94,
+	0xb5, 0x16, 0x2b, 0x0, 0xbb, 0x6, 0xef, 0x13, 0x7, 0x53,
+	0x4c, 0xf9, 0x64, 0xb9, 0x28, 0x7a, 0x1b, 0x84, 0x98, 0x88,
+	0xd8, 0x67, 0xa4, 0x23, 0xf9, 0xa7, 0x4b, 0xdc, 0x4a, 0xf,
+	0xf7, 0x3a, 0x18, 0xae, 0x54, 0xa8, 0x15, 0xfe, 0xb0, 0xad,
+	0xac, 0x35, 0xda, 0x3b, 0xad, 0x27, 0xbc, 0xaf, 0xe8, 0xd3,
+	0x2f, 0x37, 0x34, 0xd6, 0x51, 0x2b, 0x6c, 0x5a, 0x27, 0xd7,
+	0x96, 0x6, 0xaf, 0x6b, 0xb8, 0x80, 0xca, 0xfa, 0x30, 0xb4,
+	0xb1, 0x85, 0xb3, 0x4d, 0xaa, 0xaa, 0xc3, 0x16, 0x34, 0x1a,
+	0xb8, 0xe7, 0xc7, 0xfa, 0xf9, 0x9, 0x77, 0xab, 0x97, 0x93,
+	0xeb, 0x44, 0xae, 0xcf, 0x20, 0xbc, 0xf0, 0x80, 0x11, 0xdb,
+	0x23, 0xc, 0x47, 0x71, 0xb9, 0x6d, 0xd6, 0x7b, 0x60, 0x47,
+	0x87, 0x16, 0x56, 0x93, 0xb7, 0xc2, 0x2a, 0x9a, 0xb0, 0x4c,
+	0x1, 0xc, 0x30, 0xd8, 0x93, 0x87, 0xf0, 0xed, 0x6e, 0x8b,
+	0xbe, 0x30, 0x5b, 0xf6, 0xa6, 0xaf, 0xdd, 0x80, 0x7c, 0x45,
+	0x5e, 0x8f, 0x91, 0x93, 0x5e, 0x44, 0xfe, 0xb8, 0x82, 0x7,
+	0xee, 0x79, 0xca, 0xbf, 0x31, 0x73, 0x62, 0x58, 0xe3, 0xcd,
+	0xc4, 0xbc, 0xc2, 0x11, 0x1d, 0xa1, 0x4a, 0xbf, 0xfe, 0x27,
+	0x7d, 0xa1, 0xf6, 0x35, 0xa3, 0x5e, 0xca, 0xdc, 0x57, 0x2f,
+	0x3e, 0xf0, 0xc9, 0x5d, 0x86, 0x6a, 0xf8, 0xaf, 0x66, 0xa7,
+	0xed, 0xcd, 0xb8, 0xed, 0xa1, 0x5f, 0xba, 0x9b, 0x85, 0x1a,
+	0xd5, 0x9, 0xae, 0x94, 0x4e, 0x3b, 0xcf, 0xcb, 0x5c, 0xc9,
+	0x79, 0x80, 0xf7, 0xcc, 0xa6, 0x4a, 0xa8, 0x6a, 0xd8, 0xd3,
+	0x31, 0x11, 0xf9, 0xf6, 0x2, 0x63, 0x2a, 0x1a, 0x2d, 0xd1,
+	0x1a, 0x66, 0x1b, 0x16, 0x41, 0xbd, 0xbd, 0xf7, 0x4d, 0xc0,
+	0x4a, 0xe5, 0x27, 0x49, 0x5f, 0x7f, 0x58, 0xe3, 0x27, 0x2d,
+	0xe5, 0xc9, 0x66, 0xe, 0x52, 0x38, 0x16, 0x38, 0xfb, 0x16,
+	0xeb, 0x53, 0x3f, 0xe6, 0xfd, 0xe9, 0xa2, 0x5e, 0x25, 0x59,
+	0xd8, 0x79, 0x45, 0xff, 0x3, 0x4c, 0x26, 0xa2, 0x0, 0x5a,
+	0x8e, 0xc2, 0x51, 0xa1, 0x15, 0xf9, 0x7b, 0xf4, 0x5c, 0x81,
+	0x9b, 0x18, 0x47, 0x35, 0xd8, 0x2d, 0x5, 0xe9, 0xad, 0xf,
+	0x35, 0x74, 0x15, 0xa3, 0x8e, 0x8b, 0xcc, 0x27, 0xda, 0x7c,
+	0x5d, 0xe4, 0xfa, 0x4, 0xd3, 0x5, 0xb, 0xba, 0x3a, 0xb2,
+	0x49, 0x45, 0x2f, 0x47, 0xc7, 0xd, 0x41, 0x3f, 0x97, 0x80,
+	0x4d, 0x3f, 0xc1, 0xb5, 0xbb, 0x70, 0x5f, 0xa7, 0x37, 0xaf,
+	0x48, 0x22, 0x12, 0x45, 0x2e, 0xf5, 0xf, 0x87, 0x92, 0xe2,
+	0x84, 0x1, 0xf9, 0x12, 0xf, 0x14, 0x15, 0x24, 0xce, 0x89,
+	0x99, 0xee, 0xb9, 0xc4, 0x17, 0x70, 0x70, 0x15, 0xea, 0xbe,
+	0xc6, 0x6c, 0x1f, 0x62, 0xb3, 0xf4, 0x2d, 0x16, 0x87, 0xfb,
+	0x56, 0x1e, 0x45, 0xab, 0xae, 0x32, 0xe4, 0x5e, 0x91, 0xed,
+	0x53, 0x66, 0x5e, 0xbd, 0xed, 0xad, 0xe6, 0x12, 0x39, 0xd,
+	0x83, 0xc9, 0xe8, 0x6b, 0x6c, 0x2d, 0xa5, 0xee, 0xc4, 0x5a,
+	0x66, 0xae, 0x8c, 0x97, 0xd7, 0xd, 0x6c, 0x49, 0xc7, 0xf5,
+	0xc4, 0x92, 0x31, 0x8b, 0x9, 0xee, 0x33, 0xda, 0xa9, 0x37,
+	0xb6, 0x49, 0x18, 0xf8, 0xe, 0x60, 0x45, 0xc8, 0x33, 0x91,
+	0xef, 0x20, 0x57, 0x10, 0xbe, 0x78, 0x2d, 0x83, 0x26, 0xd6,
+	0xca, 0x61, 0xf9, 0x2f, 0xe0, 0xbf, 0x5, 0x30, 0x52, 0x5a,
+	0x12, 0x1c, 0x0, 0xa7, 0x5d, 0xcc, 0x7c, 0x2e, 0xc5, 0x95,
+	0x8b, 0xa3, 0x3b, 0xf0, 0x43, 0x2e, 0x5e, 0xdd, 0x0, 0xdb,
+	0xd, 0xb3, 0x37, 0x99, 0xa9, 0xcd, 0x9c, 0xb7, 0x43, 0xf7,
+	0x35, 0x44, 0x21, 0xc2, 0x82, 0x71, 0xab, 0x8d, 0xaa, 0xb4,
+	0x41, 0x11, 0xec, 0x1e, 0x8d, 0xfc, 0x14, 0x82, 0x92, 0x4e,
+	0x83, 0x6a, 0xa, 0x6b, 0x35, 0x5e, 0x5d, 0xe9, 0x5c, 0xcc,
+	0x8c, 0xde, 0x39, 0xd1, 0x4a, 0x5b, 0x5f, 0x63, 0xa9, 0x64,
+	0xe0, 0xa, 0xcb, 0xb, 0xb8, 0x5a, 0x7c, 0xc3, 0xb, 0xe6,
+	0xbe, 0xfe, 0x8b, 0xf, 0x7d, 0x34, 0x8e, 0x2, 0x66, 0x74,
+	0x1, 0x6c, 0xca, 0x76, 0xac, 0x7c, 0x67, 0x8, 0x2f, 0x3f,
+	0x1a, 0xa6, 0x2c, 0x60, 0xb3, 0xff, 0xda, 0x8d, 0xb8, 0x12,
+	0xc, 0x0, 0x7f, 0xcc, 0x50, 0xa1, 0x5c, 0x64, 0xa1, 0xe2,
+	0x5f, 0x32, 0x65, 0xc9, 0x9c, 0xbe, 0xd6, 0xa, 0x13, 0x87,
+	0x3c, 0x2a, 0x45, 0x47, 0xc, 0xca, 0x42, 0x82, 0xfa, 0x89,
+	0x65, 0xe7, 0x89, 0xb4, 0x8f, 0xf7, 0x1e, 0xe6, 0x23, 0xa5,
+	0xd0, 0x59, 0x37, 0x79, 0x92, 0xd7, 0xce, 0x3d, 0xfd, 0xe3,
+	0xa1, 0xb, 0xcf, 0x6c, 0x85, 0xa0, 0x65, 0xf3, 0x5c, 0xc6,
+	0x4a, 0x63, 0x5f, 0x6e, 0x3a, 0x3a, 0x2a, 0x8b, 0x6a, 0xb6,
+	0x2f, 0xbb, 0xf8, 0xb2, 0x4b, 0x62, 0xbc, 0x1a, 0x91, 0x25,
+	0x66, 0xe3, 0x69, 0xca, 0x60, 0x49, 0xb, 0xf6, 0x8a, 0xbe,
+	0x3e, 0x76, 0x53, 0xc2, 0x7a, 0xa8, 0x4, 0x17, 0x75, 0xf1,
+	0xf3, 0x3, 0x62, 0x1b, 0x85, 0xb2, 0xb0, 0xef, 0x80, 0x15,
+	0xb6, 0xd4, 0x4e, 0xdf, 0x71, 0xac, 0xdb, 0x2a, 0x4, 0xd4,
+	0xb4, 0x21, 0xba, 0x65, 0x56, 0x57, 0xe8, 0xfa, 0x84, 0xa2,
+	0x7d, 0x13, 0xe, 0xaf, 0xd7, 0x9a, 0x58, 0x2a, 0xa3, 0x81,
+	0x84, 0x8d, 0x9, 0xa0, 0x6a, 0xc1, 0xbb, 0xd9, 0xf5, 0x86,
+	0xac, 0xbd, 0x75, 0x61, 0x9, 0xe6, 0x8c, 0x3d, 0x77, 0xb2,
+	0xed, 0x30, 0x20, 0xe4, 0x0, 0x1d, 0x97, 0xe8, 0xbf, 0xc7,
+	0x0, 0x1b, 0x21, 0xb1, 0x16, 0xe7, 0x41, 0x67, 0x2e, 0xec,
+	0x38, 0xbc, 0xe5, 0x1b, 0xb4, 0x6, 0x23, 0x31, 0x71, 0x1c,
+	0x49, 0xcd, 0x76, 0x4a, 0x76, 0x36, 0x8d, 0xa3, 0x89, 0x8b,
+	0x4a, 0x7a, 0xf4, 0x87, 0xc8, 0x15, 0xf, 0x37, 0x39, 0xf6,
+	0x6d, 0x80, 0x19, 0xef, 0x5c, 0xa8, 0x66, 0xce, 0x1b, 0x16,
+	0x79, 0x21, 0xdf, 0xd7, 0x31, 0x30, 0xc4, 0x21, 0xdd, 0x34,
+	0x5b, 0xd2, 0x1a, 0x2b, 0x3e, 0x5d, 0xf7, 0xea, 0xca, 0x5,
+	0x8e, 0xb7, 0xcb, 0x49, 0x2e, 0xa0, 0xe3, 0xf4, 0xa7, 0x48,
+	0x19, 0x10, 0x9c, 0x4, 0xa7, 0xf4, 0x28, 0x74, 0xc8, 0x6f,
+	0x63, 0x20, 0x2b, 0x46, 0x24, 0x26, 0x19, 0x1d, 0xd1, 0x2c,
+	0x31, 0x6d, 0x5a, 0x29, 0xa2, 0x6, 0xa6, 0xb2, 0x41, 0xcc,
+	0xa, 0x27, 0x96, 0x9, 0x96, 0xac, 0x47, 0x65, 0x78, 0x68,
+	0x51, 0x98, 0xd6, 0xd8, 0xa6, 0x2d, 0xa0, 0xcf, 0xec, 0xe2,
+	0x74, 0xf2, 0x82, 0xe3, 0x97, 0xd9, 0x7e, 0xd4, 0xf8, 0xb,
+	0x70, 0x43, 0x3d, 0xb1, 0x7b, 0x97, 0x80, 0xd6, 0xcb, 0xd7,
+	0x19, 0xbc, 0x63, 0xb, 0xfd, 0x4d, 0x88, 0xfe, 0x67, 0xac,
+	0xb8, 0xcc, 0x50, 0xb7, 0x68, 0xb3, 0x5b, 0xd6, 0x1e, 0x25,
+	0xfc, 0x5f, 0x3c, 0x8d, 0xb1, 0x33, 0x7c, 0xb3, 0x49, 0x1,
+	0x3f, 0x71, 0x55, 0xe, 0x51, 0xba, 0x61, 0x26, 0xfa, 0xea,
+	0xe5, 0xb5, 0xe8, 0xaa, 0xcf, 0xcd, 0x96, 0x9f, 0xd6, 0xc1,
+	0x5f, 0x53, 0x91, 0xad, 0x5, 0xde, 0x20, 0xe7, 0x51, 0xda,
+	0x5b, 0x95, 0x67, 0xed, 0xf4, 0xee, 0x42, 0x65, 0x70, 0x13,
+	0xb, 0x70, 0x14, 0x1c, 0xc9, 0xe0, 0x19, 0xca, 0x5f, 0xf5,
+	0x1d, 0x70, 0x4b, 0x6c, 0x6, 0x74, 0xec, 0xb5, 0x2e, 0x77,
+	0xe1, 0x74, 0xa1, 0xa3, 0x99, 0xa0, 0x85, 0x9e, 0xf1, 0xac,
+	0xd8, 0x7e,
+};
+
+/**
+ * ============================================================================
+ * IO(mmc) auxiliary functions
+ * ============================================================================
+ */
+static unsigned long mmc_read_and_flush(struct mmc_part *part,
+					lbaint_t start,
+					lbaint_t sectors,
+					void *buffer)
+{
+	unsigned long blks;
+	void *tmp_buf;
+	size_t buf_size;
+	bool unaligned = is_buf_unaligned(buffer);
+
+	if (start < part->info.start) {
+		printf("%s: partition start out of bounds\n", __func__);
+		return 0;
+	}
+	if ((start + sectors) > (part->info.start + part->info.size)) {
+		sectors = part->info.start + part->info.size - start;
+		printf("%s: read sector aligned to partition bounds (%ld)\n",
+		       __func__, sectors);
+	}
+
+	/*
+	 * Reading fails on unaligned buffers, so we have to
+	 * use aligned temporary buffer and then copy to destination
+	 */
+
+	if (unaligned) {
+		printf("Handling unaligned read buffer..\n");
+		tmp_buf = get_sector_buf();
+		buf_size = get_sector_buf_size();
+		if (sectors > buf_size / part->info.blksz)
+			sectors = buf_size / part->info.blksz;
+	} else {
+		tmp_buf = buffer;
+	}
+
+	blks = part->mmc->block_dev.block_read(part->mmc_blk,
+				start, sectors, tmp_buf);
+	/* flush cache after read */
+	flush_cache((ulong)tmp_buf, sectors * part->info.blksz);
+
+	if (unaligned)
+		memcpy(buffer, tmp_buf, sectors * part->info.blksz);
+
+	return blks;
+}
+
+static unsigned long mmc_write(struct mmc_part *part, lbaint_t start,
+			       lbaint_t sectors, void *buffer)
+{
+	void *tmp_buf;
+	size_t buf_size;
+	bool unaligned = is_buf_unaligned(buffer);
+
+	if (start < part->info.start) {
+		printf("%s: partition start out of bounds\n", __func__);
+		return 0;
+	}
+	if ((start + sectors) > (part->info.start + part->info.size)) {
+		sectors = part->info.start + part->info.size - start;
+		printf("%s: sector aligned to partition bounds (%ld)\n",
+		       __func__, sectors);
+	}
+	if (unaligned) {
+		tmp_buf = get_sector_buf();
+		buf_size = get_sector_buf_size();
+		printf("Handling unaligned wrire buffer..\n");
+		if (sectors > buf_size / part->info.blksz)
+			sectors = buf_size / part->info.blksz;
+
+		memcpy(tmp_buf, buffer, sectors * part->info.blksz);
+	} else {
+		tmp_buf = buffer;
+	}
+
+	return part->mmc->block_dev.block_write(part->mmc_blk,
+				start, sectors, tmp_buf);
+}
+
+static struct mmc_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;
+
+	part = malloc(sizeof(struct mmc_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);
+		return NULL;
+	}
+
+	if (mmc_init(part->mmc)) {
+		printf("MMC initialization failed\n");
+		return NULL;
+	}
+
+	ret = mmc_switch_part(part->mmc, part_num);
+	if (ret)
+		return NULL;
+
+	mmc_blk = mmc_get_blk_desc(part->mmc);
+	if (!mmc_blk) {
+		printf("Error - failed to obtain block descriptor\n");
+		return NULL;
+	}
+
+	ret = part_get_info_by_name(mmc_blk, partition, &part->info);
+	if (!ret) {
+		printf("Can't find partition '%s'\n", partition);
+		return NULL;
+	}
+
+	part->dev_num = dev_num;
+	part->mmc_blk = mmc_blk;
+
+	return part;
+}
+
+static AvbIOResult mmc_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)
+{
+	ulong ret;
+	struct mmc_part *part;
+	u64 start_offset, start_sector, sectors, residue;
+	u8 *tmp_buf;
+	size_t io_cnt = 0;
+
+	if (!partition || !buffer || io_type > IO_WRITE)
+		return AVB_IO_RESULT_ERROR_IO;
+
+	part = get_partition(ops, partition);
+	if (!part)
+		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
+
+	start_offset = calc_offset(part, offset);
+	while (num_bytes) {
+		start_sector = start_offset / part->info.blksz;
+		sectors = num_bytes / part->info.blksz;
+		/* handle non block-aligned reads */
+		if (start_offset % part->info.blksz ||
+		    num_bytes < part->info.blksz) {
+			tmp_buf = get_sector_buf();
+			if (start_offset % part->info.blksz) {
+				residue = part->info.blksz -
+					(start_offset % part->info.blksz);
+				if (residue > num_bytes)
+					residue = num_bytes;
+			} else {
+				residue = num_bytes;
+			}
+
+			if (io_type == IO_READ) {
+				ret = mmc_read_and_flush(part,
+							 part->info.start +
+							 start_sector,
+							 1, tmp_buf);
+
+				if (ret != 1) {
+					printf("%s: read error (%ld, %lld)\n",
+					       __func__, ret, start_sector);
+					return AVB_IO_RESULT_ERROR_IO;
+				}
+				/*
+				 * if this is not aligned at sector start,
+				 * we have to adjust the tmp buffer
+				 */
+				tmp_buf += (start_offset % part->info.blksz);
+				memcpy(buffer, (void *)tmp_buf, residue);
+			} else {
+				ret = mmc_read_and_flush(part,
+							 part->info.start +
+							 start_sector,
+							 1, tmp_buf);
+
+				if (ret != 1) {
+					printf("%s: read error (%ld, %lld)\n",
+					       __func__, ret, start_sector);
+					return AVB_IO_RESULT_ERROR_IO;
+				}
+				memcpy((void *)tmp_buf +
+					start_offset % part->info.blksz,
+					buffer, residue);
+
+				ret = mmc_write(part, part->info.start +
+						start_sector, 1, tmp_buf);
+				if (ret != 1) {
+					printf("%s: write error (%ld, %lld)\n",
+					       __func__, ret, start_sector);
+					return AVB_IO_RESULT_ERROR_IO;
+				}
+			}
+
+			io_cnt += residue;
+			buffer += residue;
+			start_offset += residue;
+			num_bytes -= residue;
+			continue;
+		}
+
+		if (sectors) {
+			if (io_type == IO_READ) {
+				ret = mmc_read_and_flush(part,
+							 part->info.start +
+							 start_sector,
+							 sectors, buffer);
+			} else {
+				ret = mmc_write(part,
+						part->info.start +
+						start_sector,
+						sectors, buffer);
+			}
+
+			if (!ret) {
+				printf("%s: sector read error\n", __func__);
+				return AVB_IO_RESULT_ERROR_IO;
+			}
+
+			io_cnt += ret * part->info.blksz;
+			buffer += ret * part->info.blksz;
+			start_offset += ret * part->info.blksz;
+			num_bytes -= ret * part->info.blksz;
+		}
+	}
+
+	/* Set counter for read operation */
+	if (io_type == IO_READ && out_num_read)
+		*out_num_read = io_cnt;
+
+	return AVB_IO_RESULT_OK;
+}
+
+/**
+ * ============================================================================
+ * AVB 2.0 operations
+ * ============================================================================
+ */
+
+/**
+ * read_from_partition() - reads @num_bytes from  @offset from partition
+ * identified by a string name
+ *
+ * @ops: contains AVB ops handlers
+ * @partition_name: partition name, NUL-terminated UTF-8 string
+ * @offset: offset from the beginning of partition
+ * @num_bytes: amount of bytes to read
+ * @buffer: destination buffer to store data
+ * @out_num_read:
+ *
+ * @return:
+ *      AVB_IO_RESULT_OK, if partition was found and read operation succeed
+ *      AVB_IO_RESULT_ERROR_IO, if i/o error occurred from the underlying i/o
+ *            subsystem
+ *      AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION, if there is no partition with
+ *      the given name
+ */
+static AvbIOResult read_from_partition(AvbOps *ops,
+				       const char *partition_name,
+				       s64 offset_from_partition,
+				       size_t num_bytes,
+				       void *buffer,
+				       size_t *out_num_read)
+{
+	return mmc_byte_io(ops, partition_name, offset_from_partition,
+			   num_bytes, buffer, out_num_read, IO_READ);
+}
+
+/**
+ * write_to_partition() - writes N bytes to a partition identified by a string
+ * name
+ *
+ * @ops: AvbOps, contains AVB ops handlers
+ * @partition_name: partition name
+ * @offset_from_partition: offset from the beginning of partition
+ * @num_bytes: amount of bytes to write
+ * @buf: data to write
+ * @out_num_read:
+ *
+ * @return:
+ *      AVB_IO_RESULT_OK, if partition was found and read operation succeed
+ *      AVB_IO_RESULT_ERROR_IO, if input/output error occurred
+ *      AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION, if partition, specified in
+ *            @partition_name was not found
+ */
+static AvbIOResult write_to_partition(AvbOps *ops,
+				      const char *partition_name,
+				      s64 offset_from_partition,
+				      size_t num_bytes,
+				      const void *buffer)
+{
+	return mmc_byte_io(ops, partition_name, offset_from_partition,
+			   num_bytes, (void *)buffer, NULL, IO_WRITE);
+}
+
+/**
+ * validate_vmbeta_public_key() - checks if the given public key used to sign
+ * the vbmeta partition is trusted
+ *
+ * @ops: AvbOps, contains AVB ops handlers
+ * @public_key_data: public key for verifying vbmeta partition signature
+ * @public_key_length: length of public key
+ * @public_key_metadata:
+ * @public_key_metadata_length:
+ * @out_key_is_trusted:
+ *
+ * @return:
+ *      AVB_IO_RESULT_OK, if partition was found and read operation succeed
+ */
+static AvbIOResult validate_vbmeta_public_key(AvbOps *ops,
+					      const u8 *public_key_data,
+					      size_t public_key_length,
+					      const u8
+					      *public_key_metadata,
+					      size_t
+					      public_key_metadata_length,
+					      bool *out_key_is_trusted)
+{
+	if (!public_key_length || !public_key_data || !out_key_is_trusted)
+		return AVB_IO_RESULT_ERROR_IO;
+
+	*out_key_is_trusted = false;
+	if (public_key_length != sizeof(avb_root_pub))
+		return AVB_IO_RESULT_ERROR_IO;
+
+	if (memcmp(avb_root_pub, public_key_data, public_key_length) == 0)
+		*out_key_is_trusted = true;
+
+	return AVB_IO_RESULT_OK;
+}
+
+/**
+ * read_rollback_index() - gets the rollback index corresponding to the
+ * location of given by @out_rollback_index.
+ *
+ * @ops: contains AvbOps handlers
+ * @rollback_index_slot:
+ * @out_rollback_index: used to write a retrieved rollback index.
+ *
+ * @return
+ *       AVB_IO_RESULT_OK, if the roolback index was retrieved
+ */
+static AvbIOResult read_rollback_index(AvbOps *ops,
+				       size_t rollback_index_slot,
+				       u64 *out_rollback_index)
+{
+	/* For now we always return 0 as the stored rollback index. */
+	printf("TODO: implement %s.\n", __func__);
+
+	if (out_rollback_index)
+		*out_rollback_index = 0;
+
+	return AVB_IO_RESULT_OK;
+}
+
+/**
+ * write_rollback_index() - sets the rollback index corresponding to the
+ * location of given by @out_rollback_index.
+ *
+ * @ops: contains AvbOps handlers
+ * @rollback_index_slot:
+ * @rollback_index: rollback index to write.
+ *
+ * @return
+ *       AVB_IO_RESULT_OK, if the roolback index was retrieved
+ */
+static AvbIOResult write_rollback_index(AvbOps *ops,
+					size_t rollback_index_slot,
+					u64 rollback_index)
+{
+	/* For now this is a no-op. */
+	printf("TODO: implement %s.\n", __func__);
+
+	return AVB_IO_RESULT_OK;
+}
+
+/**
+ * read_is_device_unlocked() - gets whether the device is unlocked
+ *
+ * @ops: contains AVB ops handlers
+ * @out_is_unlocked: device unlock state is stored here, true if unlocked,
+ *       false otherwise
+ *
+ * @return:
+ *       AVB_IO_RESULT_OK: state is retrieved successfully
+ *       AVB_IO_RESULT_ERROR_IO: an error occurred
+ */
+static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
+{
+	/* For now we always return that the device is unlocked. */
+
+	printf("TODO: implement %s.\n", __func__);
+
+	*out_is_unlocked = true;
+
+	return AVB_IO_RESULT_OK;
+}
+
+/**
+ * get_unique_guid_for_partition() - gets the GUID for a partition identified
+ * by a string name
+ *
+ * @ops: contains AVB ops handlers
+ * @partition: partition name (NUL-terminated UTF-8 string)
+ * @guid_buf: buf, used to copy in GUID string. Example of value:
+ *      527c1c6d-6361-4593-8842-3c78fcd39219
+ * @guid_buf_size: @guid_buf buffer size
+ *
+ * @return:
+ *      AVB_IO_RESULT_OK, on success (GUID found)
+ *      AVB_IO_RESULT_ERROR_IO, if incorrect buffer size (@guid_buf_size) was
+ *             provided
+ *      AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION, if partition was not found
+ */
+static AvbIOResult get_unique_guid_for_partition(AvbOps *ops,
+						 const char *partition,
+						 char *guid_buf,
+						 size_t guid_buf_size)
+{
+	struct mmc_part *part;
+	size_t uuid_size;
+
+	part = get_partition(ops, partition);
+	if (!part)
+		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
+
+	uuid_size = sizeof(part->info.uuid);
+	if (uuid_size > guid_buf_size)
+		return AVB_IO_RESULT_ERROR_IO;
+
+	memcpy(guid_buf, part->info.uuid, uuid_size);
+	guid_buf[uuid_size - 1] = 0;
+
+	return AVB_IO_RESULT_OK;
+}
+
+/**
+ * ============================================================================
+ * AVB2.0 AvbOps alloc/initialisation/free
+ * ============================================================================
+ */
+AvbOps *avb_ops_alloc(int boot_device)
+{
+	struct AvbOpsData *ops_data;
+
+	ops_data = avb_calloc(sizeof(struct AvbOpsData));
+	if (!ops_data)
+		return NULL;
+
+	ops_data->ops.user_data = ops_data;
+
+	ops_data->ops.ab_ops = &ops_data->ab_ops;
+	ops_data->ops.read_from_partition = read_from_partition;
+	ops_data->ops.write_to_partition = write_to_partition;
+	ops_data->ops.validate_vbmeta_public_key = validate_vbmeta_public_key;
+	ops_data->ops.read_rollback_index = read_rollback_index;
+	ops_data->ops.write_rollback_index = write_rollback_index;
+	ops_data->ops.read_is_device_unlocked = read_is_device_unlocked;
+	ops_data->ops.get_unique_guid_for_partition =
+		get_unique_guid_for_partition;
+
+	ops_data->ab_ops.ops = &ops_data->ops;
+	ops_data->ab_ops.read_ab_metadata = avb_ab_data_read;
+	ops_data->ab_ops.write_ab_metadata = avb_ab_data_write;
+	ops_data->mmc_dev = boot_device;
+
+	return &ops_data->ops;
+}
+
+void avb_ops_free(AvbOps *ops)
+{
+	struct AvbOpsData *ops_data;
+
+	if (ops)
+		return;
+
+	ops_data = ops->user_data;
+
+	if (ops_data)
+		avb_free(ops_data);
+}
diff --git a/include/avb_verify.h b/include/avb_verify.h
new file mode 100644
index 0000000..fb7ab23
--- /dev/null
+++ b/include/avb_verify.h
@@ -0,0 +1,80 @@
+
+/*
+ * (C) Copyright 2018, Linaro Limited
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef	_AVB_VERIFY_H
+#define _AVB_VERIFY_H
+
+#include <avb/libavb_ab.h>
+#include <mmc.h>
+
+#define ALLOWED_BUF_ALIGN	8
+
+struct AvbOpsData {
+	struct AvbOps ops;
+	struct AvbABOps ab_ops;
+	int mmc_dev;
+};
+
+struct mmc_part {
+	int dev_num;
+	struct mmc *mmc;
+	struct blk_desc *mmc_blk;
+	disk_partition_t info;
+};
+
+enum mmc_io_type {
+	IO_READ,
+	IO_WRITE
+};
+
+AvbOps *avb_ops_alloc(int boot_device);
+void avb_ops_free(AvbOps *ops);
+
+/**
+ * ============================================================================
+ * I/O helper inline functions
+ * ============================================================================
+ */
+static inline uint64_t calc_offset(struct mmc_part *part, int64_t offset)
+{
+	u64 part_size = part->info.size * part->info.blksz;
+
+	if (offset < 0)
+		return part_size + offset;
+
+	return offset;
+}
+
+static inline size_t get_sector_buf_size(void)
+{
+	return (size_t)CONFIG_FASTBOOT_BUF_SIZE;
+}
+
+static inline void *get_sector_buf(void)
+{
+	return (void *)CONFIG_FASTBOOT_BUF_ADDR;
+}
+
+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 */
-- 
2.7.4

  parent reply	other threads:[~2018-04-25 13:18 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-25 13:17 [U-Boot] [PATCH 0/8] Initial integration of AVB2.0 Igor Opaniuk
2018-04-25 13:17 ` [U-Boot] [PATCH 1/8] avb2.0: add Android Verified Boot 2.0 libraries Igor Opaniuk
2018-04-25 13:17 ` [U-Boot] [PATCH 2/8] avb2.0: integrate avb 2.0 into the build system Igor Opaniuk
2018-04-25 13:18 ` Igor Opaniuk [this message]
2018-04-25 13:18 ` [U-Boot] [PATCH 4/8] cmd: avb2.0: avb command for performing verification Igor Opaniuk
2018-05-02 18:52   ` Sam Protsenko
2018-05-03  2:31   ` Simon Glass
2018-05-15 15:44     ` Igor Opaniuk
2018-05-15 16:26       ` Simon Glass
2018-05-15 17:31         ` Igor Opaniuk
2018-05-15 18:28           ` Simon Glass
2018-05-16  8:20             ` Igor Opaniuk
2018-05-16 15:40               ` Simon Glass
2018-04-25 13:18 ` [U-Boot] [PATCH 5/8] avb2.0: add boot states and dm-verity support Igor Opaniuk
2018-05-02 18:59   ` Sam Protsenko
2018-04-25 13:18 ` [U-Boot] [PATCH 6/8] am57xx_hs: avb2.0: add support of AVB 2.0 Igor Opaniuk
2018-05-02 19:06   ` Sam Protsenko
2018-04-25 13:18 ` [U-Boot] [PATCH 7/8] test/py: avb2.0: add tests for avb commands Igor Opaniuk
2018-04-25 13:18 ` [U-Boot] [PATCH 8/8] doc: avb2.0: add README about AVB2.0 integration Igor Opaniuk
2018-05-02 19:12   ` Sam Protsenko
2018-05-16  9:20     ` Igor Opaniuk
2018-04-26  3:05 ` [U-Boot] [PATCH 0/8] Initial integration of AVB2.0 Kever Yang
2018-04-26 13:00   ` Igor Opaniuk
2018-04-26 18:35   ` Alex Deymo
2018-04-27  9:53     ` Igor Opaniuk
2018-04-30 10:47       ` Alex Deymo
2018-05-06 11:31 ` Eugeniu Rosca
2018-05-15 15:31   ` Eugeniu Rosca
2018-05-15 16:58     ` Igor Opaniuk
2018-05-15 17:10       ` Eugeniu Rosca

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1524662285-19617-4-git-send-email-igor.opaniuk@linaro.org \
    --to=igor.opaniuk@linaro.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.