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, &timestamp, 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_));