Keep copy of raw TrillianLogRoot am: 479237118c am: a246667414
Change-Id: I82d2a1e2f867f0f1de08a8292b8de33b17119ab9
diff --git a/libavb_aftl/avb_aftl_types.h b/libavb_aftl/avb_aftl_types.h
index c56b465..964928e 100644
--- a/libavb_aftl/avb_aftl_types.h
+++ b/libavb_aftl/avb_aftl_types.h
@@ -141,6 +141,7 @@
uint32_t inc_proof_size;
uint8_t* log_url;
TrillianLogRootDescriptor log_root_descriptor;
+ uint8_t* log_root_descriptor_raw;
FirmwareInfo fw_info_leaf;
uint8_t* log_root_signature;
uint8_t (*proofs)[AVB_AFTL_HASH_SIZE];
diff --git a/libavb_aftl/avb_aftl_util.c b/libavb_aftl/avb_aftl_util.c
index 73d1141..e6ea54c 100644
--- a/libavb_aftl/avb_aftl_util.c
+++ b/libavb_aftl/avb_aftl_util.c
@@ -47,105 +47,6 @@
return true;
}
-/* Calculates a SHA256 hash of the TrillianLogRootDescriptor in icp_entry.
-
- The hash is calculated over the entire TrillianLogRootDescriptor
- structure. Some of the fields in this implementation are dynamically
- allocated, and so the data needs to be reconstructed so that the hash
- can be properly calculated. The TrillianLogRootDescriptor is defined
- here: https://github.com/google/trillian/blob/master/trillian.proto#L255 */
-bool avb_aftl_hash_log_root_descriptor(AftlIcpEntry* icp_entry, uint8_t* hash) {
- uint8_t* buffer;
- uint8_t* lrd_offset; /* Byte offset into the descriptor. */
- uint32_t tlrd_size;
- uint16_t version;
- uint64_t tree_size;
- uint64_t timestamp;
- uint64_t revision;
- uint16_t metadata_size;
- bool retval;
-
- avb_assert(icp_entry != NULL && hash != NULL);
-
- /* Size of the non-pointer elements of the TrillianLogRootDescriptor. */
- tlrd_size = sizeof(uint16_t) * 2 + sizeof(uint64_t) * 3 + sizeof(uint8_t);
- /* Ensure the log_root_descriptor size is correct. */
- if (icp_entry->log_root_descriptor_size > AVB_AFTL_MAX_TLRD_SIZE) {
- avb_error("Invalid log root descriptor size.\n");
- return false;
- }
- if (icp_entry->log_root_descriptor_size !=
- (tlrd_size + icp_entry->log_root_descriptor.root_hash_size +
- icp_entry->log_root_descriptor.metadata_size)) {
- avb_error("Log root descriptor size doesn't match fields.\n");
- return false;
- }
- /* Check that the root_hash exists, and if not, it's size is sane. */
- if (!icp_entry->log_root_descriptor.root_hash &&
- (icp_entry->log_root_descriptor.root_hash_size != 0)) {
- avb_error("Invalid tree root hash values.\n");
- return false;
- }
-
- /* Check that the metadata exists, and if not, it's size is sane. */
- if (!icp_entry->log_root_descriptor.metadata &&
- (icp_entry->log_root_descriptor.metadata_size != 0)) {
- avb_error("Invalid log root descriptor metadata values.\n");
- return false;
- }
- buffer = (uint8_t*)avb_malloc(icp_entry->log_root_descriptor_size);
- if (buffer == NULL) {
- avb_error("Allocation failure in avb_aftl_hash_log_root_descriptor.\n");
- return false;
- }
- lrd_offset = buffer;
- /* Copy in the version, tree_size and root hash length. */
- /* Ensure endianness is correct. */
- version = avb_be16toh(icp_entry->log_root_descriptor.version);
- avb_memcpy(lrd_offset, &version, sizeof(uint16_t));
- lrd_offset += sizeof(uint16_t);
- /* Ensure endianness is correct. */
- tree_size = avb_be64toh(icp_entry->log_root_descriptor.tree_size);
- avb_memcpy(lrd_offset, &tree_size, sizeof(uint64_t));
- lrd_offset += sizeof(uint64_t);
- avb_memcpy(lrd_offset,
- &(icp_entry->log_root_descriptor.root_hash_size),
- sizeof(uint8_t));
- lrd_offset += sizeof(uint8_t);
- /* Copy the root hash. */
- if (icp_entry->log_root_descriptor.root_hash_size > 0) {
- avb_memcpy(lrd_offset,
- icp_entry->log_root_descriptor.root_hash,
- icp_entry->log_root_descriptor.root_hash_size);
- }
- lrd_offset += icp_entry->log_root_descriptor.root_hash_size;
- /* Copy in the timestamp, revision, and the metadata length. */
- /* Ensure endianness is correct. */
- timestamp = avb_be64toh(icp_entry->log_root_descriptor.timestamp);
- avb_memcpy(lrd_offset, ×tamp, sizeof(uint64_t));
- lrd_offset += sizeof(uint64_t);
- /* Ensure endianness is correct. */
- revision = avb_be64toh(icp_entry->log_root_descriptor.revision);
- avb_memcpy(lrd_offset, &revision, sizeof(uint64_t));
- lrd_offset += sizeof(uint64_t);
- /* Ensure endianness is correct. */
- metadata_size = avb_be16toh(icp_entry->log_root_descriptor.metadata_size);
- avb_memcpy(lrd_offset, &metadata_size, sizeof(uint16_t));
- lrd_offset += sizeof(uint16_t);
-
- /* Copy the metadata if it exists. */
- if (icp_entry->log_root_descriptor.metadata_size > 0) {
- avb_memcpy(lrd_offset,
- icp_entry->log_root_descriptor.metadata,
- icp_entry->log_root_descriptor.metadata_size);
- }
- /* Hash the result & clean up. */
-
- retval = avb_aftl_sha256(buffer, icp_entry->log_root_descriptor_size, hash);
- avb_free(buffer);
- return retval;
-}
-
/* Computes a leaf hash as detailed by https://tools.ietf.org/html/rfc6962. */
bool avb_aftl_rfc6962_hash_leaf(uint8_t* leaf,
uint64_t leaf_size,
@@ -755,6 +656,16 @@
free_aftl_icp_entry(icp_entry);
return NULL;
}
+ icp_entry->log_root_descriptor_raw =
+ (uint8_t*)avb_calloc(icp_entry->log_root_descriptor_size);
+ if (!icp_entry->log_root_descriptor_raw) {
+ avb_error("Failure to allocate log root descriptor.\n");
+ free_aftl_icp_entry(icp_entry);
+ return NULL;
+ }
+ avb_memcpy(icp_entry->log_root_descriptor_raw,
+ *aftl_blob,
+ icp_entry->log_root_descriptor_size);
if (!parse_trillian_log_root_descriptor(
icp_entry, aftl_blob, icp_entry->log_root_descriptor_size)) {
free_aftl_icp_entry(icp_entry);
@@ -878,6 +789,8 @@
avb_free(icp_entry->log_root_descriptor.metadata);
if (icp_entry->log_root_descriptor.root_hash)
avb_free(icp_entry->log_root_descriptor.root_hash);
+ if (icp_entry->log_root_descriptor_raw)
+ avb_free(icp_entry->log_root_descriptor_raw);
if (icp_entry->proofs) avb_free(icp_entry->proofs);
/* Finally, free the AftlIcpEntry. */
avb_free(icp_entry);
diff --git a/libavb_aftl/avb_aftl_validate.c b/libavb_aftl/avb_aftl_validate.c
index 4121792..5b3c6b0 100644
--- a/libavb_aftl/avb_aftl_validate.c
+++ b/libavb_aftl/avb_aftl_validate.c
@@ -114,7 +114,9 @@
log_root_hash_num_bytes = AVB_AFTL_HASH_SIZE;
/* Calculate the SHA256 of the TrillianLogRootDescriptor. */
- if (!avb_aftl_hash_log_root_descriptor(icp_entry, log_root_hash))
+ if (!avb_aftl_sha256(icp_entry->log_root_descriptor_raw,
+ icp_entry->log_root_descriptor_size,
+ log_root_hash))
return false;
/* algorithm_data is used to calculate the padding for signature verification.
diff --git a/test/avb_aftl_validate_unittest.cc b/test/avb_aftl_validate_unittest.cc
index 8a8e057..e9cf6d1 100644
--- a/test/avb_aftl_validate_unittest.cc
+++ b/test/avb_aftl_validate_unittest.cc
@@ -67,6 +67,22 @@
"VT3Ngec17SeZUFfKj1Uv1z6bt6fusfv6Veb84ch0Yx5elLXNfnvvguF0z5qZp+"
"AjlkUEbhI5sRKrE9v1wV/IFiwYuHNMX3NBuKpx+8e7SXwZodXRBeocpSlA/"
"Qf8dtomxAALZrB30HSOzYavMs/4=\"}}}}}";
+ uint8_t kLogRootDescriptorHeader[] =
+ "\x00\x01" // Version
+ "\x00\x00\x00\x00\x00\x00\x00\x03" // Tree size
+ "\x20"; // Root hash size
+ /* We define kLogRootDescriptorHeader as a string literal (to be able to
+ * annotate the bytes). Do not count the final null byte that is
+ * automatically appended */
+ size_t kLogRootDescriptorHeaderSize = sizeof(kLogRootDescriptorHeader) - 1;
+ uint8_t kLogRootDescriptorHash[] =
+ "\x5a\xb3\x43\x21\x8f\x54\x4d\x05\x46\x34\x62\x86\x2f\xa8\xf8\x6e"
+ "\x3b\xa3\x19\x2d\xe9\x9c\xb2\xab\x8e\x09\xd8\x55\xc3\xde\x34\xd6";
+ uint8_t kLogRootDescriptorFooter[] =
+ "\x00\x00\x00\x00\x13\x36\x4b\xff" // Timestamp
+ "\x00\x00\x00\x00\x00\x00\x00\x00" // Revision
+ "\x00\x00"; // Metadata size
+ size_t kLogRootDescriptorFooterSize = sizeof(kLogRootDescriptorFooter) - 1;
BaseAvbToolTest::SetUp();
/* Read in test data from the key and log_sig binaries. */
@@ -94,6 +110,28 @@
icp_entry_->log_root_descriptor_size =
icp_entry_->log_root_descriptor.root_hash_size +
icp_entry_->log_root_descriptor.metadata_size + 29;
+ icp_entry_->log_root_descriptor_raw =
+ (uint8_t*)avb_malloc(icp_entry_->log_root_descriptor_size);
+ if (!icp_entry_->log_root_descriptor_raw) {
+ return;
+ }
+ memcpy(icp_entry_->log_root_descriptor_raw,
+ kLogRootDescriptorHeader,
+ kLogRootDescriptorHeaderSize);
+ memcpy(icp_entry_->log_root_descriptor_raw + kLogRootDescriptorHeaderSize,
+ kLogRootDescriptorHash,
+ AVB_AFTL_HASH_SIZE);
+ memcpy(icp_entry_->log_root_descriptor_raw + kLogRootDescriptorHeaderSize +
+ AVB_AFTL_HASH_SIZE,
+ kLogRootDescriptorFooter,
+ kLogRootDescriptorFooterSize);
+ icp_entry_->log_root_descriptor.root_hash =
+ (uint8_t*)avb_malloc(AVB_AFTL_HASH_SIZE);
+ if (!icp_entry_->log_root_descriptor.root_hash) return;
+ /* Copy the hash from within the raw version */
+ memcpy(icp_entry_->log_root_descriptor.root_hash,
+ kLogRootDescriptorHash,
+ AVB_AFTL_HASH_SIZE);
icp_entry_->fw_info_leaf_size = sizeof(kAftlJsonData);
icp_entry_->fw_info_leaf.vbmeta_hash_size = AVB_AFTL_HASH_SIZE;
@@ -124,24 +162,19 @@
"\xba\xf7\x0a\xd9\xe6\x21\xf4\xbd\x8d\x98\x66\x2f\x00\xe3\xc1\x25",
AVB_AFTL_HASH_SIZE);
icp_entry_->proof_hash_count = 1;
- icp_entry_->log_root_descriptor.root_hash =
- (uint8_t*)avb_malloc(AVB_AFTL_HASH_SIZE);
- if (!icp_entry_->log_root_descriptor.root_hash) return;
- memcpy(icp_entry_->log_root_descriptor.root_hash,
- "\x5a\xb3\x43\x21\x8f\x54\x4d\x05\x46\x34\x62\x86\x2f\xa8\xf8\x6e"
- "\x3b\xa3\x19\x2d\xe9\x9c\xb2\xab\x8e\x09\xd8\x55\xc3\xde\x34\xd6",
- AVB_AFTL_HASH_SIZE);
}
void TearDown() override {
- if (icp_entry_ != NULL) {
- if (icp_entry_->fw_info_leaf.json_data != NULL)
+ if (icp_entry_) {
+ if (icp_entry_->fw_info_leaf.json_data)
avb_free(icp_entry_->fw_info_leaf.json_data);
- if (icp_entry_->fw_info_leaf.vbmeta_hash != NULL)
+ if (icp_entry_->fw_info_leaf.vbmeta_hash)
avb_free(icp_entry_->fw_info_leaf.vbmeta_hash);
- if (icp_entry_->log_root_descriptor.root_hash != NULL)
+ if (icp_entry_->log_root_descriptor.root_hash)
avb_free(icp_entry_->log_root_descriptor.root_hash);
- if (icp_entry_->proofs != NULL) avb_free(icp_entry_->proofs);
+ if (icp_entry_->log_root_descriptor_raw)
+ avb_free(icp_entry_->log_root_descriptor_raw);
+ if (icp_entry_->proofs) avb_free(icp_entry_->proofs);
avb_free(icp_entry_);
}
avb_free(key_bytes_);
@@ -168,16 +201,6 @@
avb_free(icp_entry_->log_root_signature);
}
-TEST_F(AvbAftlValidateTest, AvbAftlHashLogRootDescriptor) {
- uint8_t hash[AVB_AFTL_HASH_SIZE];
-
- /* Initialize the icp_entry components used with the test. */
-
- avb_aftl_hash_log_root_descriptor(icp_entry_, hash);
- EXPECT_EQ("4f932f328f4b1c9b16500d6d09005c46abebf5c4dc761bbd1e8602378789edac",
- mem_to_hexstring(hash, AVB_AFTL_HASH_SIZE));
-}
-
TEST_F(AvbAftlValidateTest, AvbAftlVerifyIcpRootHash) {
/* Initialize the icp_entry components used with the test. */
EXPECT_EQ(true, avb_aftl_verify_icp_root_hash(icp_entry_));