libavb: Add new routine to calculate a digest of all vbmeta images.
This is similar to the androidboot.vbmeta.{digest, hash_alg, size}
properties set on the kernel commandline. The intent is to make this
data easily available to the bootloader without having it parse the
commandline.
Bug: None
Test: Update unit tests and all unit tests pass.
Change-Id: I4134f1a4116468bf063db2f15b8b67edd26918c2
diff --git a/examples/things/avb_atx_slot_verify.c b/examples/things/avb_atx_slot_verify.c
index 3129d2e..0de6d2e 100644
--- a/examples/things/avb_atx_slot_verify.c
+++ b/examples/things/avb_atx_slot_verify.c
@@ -133,7 +133,6 @@
const char* partitions_without_oem[] = {"boot", NULL};
const char* partitions_with_oem[] = {"boot", "oem_bootloader", NULL};
AvbSlotVerifyResult result = AVB_SLOT_VERIFY_RESULT_OK;
- AvbSHA256Ctx ctx;
size_t i = 0;
AvbAtxOpsWithContext ops_with_context;
@@ -155,13 +154,8 @@
}
/* Compute the Android Things Verified Boot Hash (VBH) extension. */
- avb_sha256_init(&ctx);
- for (i = 0; i < (*verify_data)->num_vbmeta_images; i++) {
- avb_sha256_update(&ctx,
- (*verify_data)->vbmeta_images[i].vbmeta_data,
- (*verify_data)->vbmeta_images[i].vbmeta_size);
- }
- avb_memcpy(vbh_extension, avb_sha256_final(&ctx), AVB_SHA256_DIGEST_SIZE);
+ avb_slot_verify_data_calculate_vbmeta_digest(
+ *verify_data, AVB_DIGEST_TYPE_SHA256, vbh_extension);
/* Increase rollback index values to match the verified slot. */
if (slot_state == AVB_ATX_SLOT_MARKED_SUCCESSFUL) {
diff --git a/libavb/avb_cmdline.c b/libavb/avb_cmdline.c
index 426f909..3f4b99a 100644
--- a/libavb/avb_cmdline.c
+++ b/libavb/avb_cmdline.c
@@ -269,13 +269,11 @@
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);
+ uint8_t vbmeta_digest[AVB_SHA256_DIGEST_SIZE];
+ avb_slot_verify_data_calculate_vbmeta_digest(
+ slot_data, AVB_DIGEST_TYPE_SHA256, vbmeta_digest);
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(
@@ -284,7 +282,7 @@
slot_data, "androidboot.vbmeta.size", total_size) ||
!cmdline_append_hex(slot_data,
"androidboot.vbmeta.digest",
- avb_sha256_final(&ctx),
+ vbmeta_digest,
AVB_SHA256_DIGEST_SIZE)) {
ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
goto out;
@@ -294,13 +292,11 @@
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);
+ uint8_t vbmeta_digest[AVB_SHA512_DIGEST_SIZE];
+ avb_slot_verify_data_calculate_vbmeta_digest(
+ slot_data, AVB_DIGEST_TYPE_SHA512, vbmeta_digest);
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(
@@ -309,7 +305,7 @@
slot_data, "androidboot.vbmeta.size", total_size) ||
!cmdline_append_hex(slot_data,
"androidboot.vbmeta.digest",
- avb_sha512_final(&ctx),
+ vbmeta_digest,
AVB_SHA512_DIGEST_SIZE)) {
ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
goto out;
diff --git a/libavb/avb_crypto.h b/libavb/avb_crypto.h
index 0903baa..30c1e4b 100644
--- a/libavb/avb_crypto.h
+++ b/libavb/avb_crypto.h
@@ -53,6 +53,12 @@
/* Size in bytes of a SHA-512 digest. */
#define AVB_SHA512_DIGEST_SIZE 64
+/* Possible digest types supported by libavb routines. */
+typedef enum {
+ AVB_DIGEST_TYPE_SHA256,
+ AVB_DIGEST_TYPE_SHA512,
+} AvbDigestType;
+
/* Algorithms that can be used in the vbmeta image for
* verification. An algorithm consists of a hash type and a signature
* type.
diff --git a/libavb/avb_slot_verify.c b/libavb/avb_slot_verify.c
index 3e6b04c..64e2666 100644
--- a/libavb/avb_slot_verify.c
+++ b/libavb/avb_slot_verify.c
@@ -1344,3 +1344,42 @@
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");
+ }
+}
diff --git a/libavb/avb_slot_verify.h b/libavb/avb_slot_verify.h
index 78e7dcc..375db3d 100644
--- a/libavb/avb_slot_verify.h
+++ b/libavb/avb_slot_verify.h
@@ -260,6 +260,15 @@
uint64_t rollback_indexes[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS];
} AvbSlotVerifyData;
+/* Calculates a digest of all vbmeta images in |data| using
+ * the digest indicated by |digest_type|. Stores the result
+ * in |out_digest| which must be large enough to hold a digest
+ * of the requested type.
+ */
+void avb_slot_verify_data_calculate_vbmeta_digest(AvbSlotVerifyData* data,
+ AvbDigestType digest_type,
+ uint8_t* out_digest);
+
/* Frees a |AvbSlotVerifyData| including all data it points to. */
void avb_slot_verify_data_free(AvbSlotVerifyData* data);
diff --git a/test/avb_slot_verify_unittest.cc b/test/avb_slot_verify_unittest.cc
index 823257e..87c7a1c 100644
--- a/test/avb_slot_verify_unittest.cc
+++ b/test/avb_slot_verify_unittest.cc
@@ -81,6 +81,11 @@
"androidboot.vbmeta.invalidate_on_error=yes "
"androidboot.veritymode=enforcing",
std::string(slot_data->cmdline));
+ uint8_t vbmeta_digest[AVB_SHA256_DIGEST_SIZE];
+ avb_slot_verify_data_calculate_vbmeta_digest(
+ slot_data, AVB_DIGEST_TYPE_SHA256, vbmeta_digest);
+ EXPECT_EQ("4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d",
+ mem_to_hexstring(vbmeta_digest, AVB_SHA256_DIGEST_SIZE));
avb_slot_verify_data_free(slot_data);
}
@@ -115,6 +120,13 @@
"androidboot.vbmeta.invalidate_on_error=yes "
"androidboot.veritymode=enforcing",
std::string(slot_data->cmdline));
+ uint8_t vbmeta_digest[AVB_SHA512_DIGEST_SIZE];
+ avb_slot_verify_data_calculate_vbmeta_digest(
+ slot_data, AVB_DIGEST_TYPE_SHA512, vbmeta_digest);
+ EXPECT_EQ(
+ "cb913d2f1a884f4e04c1db5bb181f3133fd16ac02fb367a20ef0776c0b07b3656ad1f081"
+ "e01932cf70f38b8960877470b448f1588dff022808387cc52fa77e77",
+ mem_to_hexstring(vbmeta_digest, AVB_SHA512_DIGEST_SIZE));
avb_slot_verify_data_free(slot_data);
}