payload_generator: Verify hash tree.

Generate the hash tree based on the descriptor and verify that it
matches with the hash tree stored in the image before enabling verity
hash tree configs.

Bug: 28171891
Test: generate a payload with verity hash tree
Change-Id: I1f2a220d631093607e648afc105ca9b5379cc74a
diff --git a/Android.mk b/Android.mk
index 4d306c4..eb31771 100644
--- a/Android.mk
+++ b/Android.mk
@@ -634,10 +634,12 @@
     liblzma \
     libpayload_consumer \
     libpuffdiff \
+    libverity_tree \
     update_metadata-protos \
     $(ue_libpayload_consumer_exported_static_libraries) \
     $(ue_update_metadata_protos_exported_static_libraries)
 ue_libpayload_generator_exported_shared_libraries := \
+    libbase \
     libext2fs \
     $(ue_libpayload_consumer_exported_shared_libraries) \
     $(ue_update_metadata_protos_exported_shared_libraries)
diff --git a/payload_generator/payload_generation_config_android.cc b/payload_generator/payload_generation_config_android.cc
index 5ffd11e..7d9988f 100644
--- a/payload_generator/payload_generation_config_android.cc
+++ b/payload_generator/payload_generation_config_android.cc
@@ -19,6 +19,7 @@
 #include <base/logging.h>
 #include <brillo/secure_blob.h>
 #include <libavb/libavb.h>
+#include <verity/hash_tree_builder.h>
 
 #include "update_engine/common/utils.h"
 #include "update_engine/payload_generator/extent_ranges.h"
@@ -55,9 +56,38 @@
 
   TEST_AND_RETURN_FALSE(hashtree.hash_block_size ==
                         part->fs_interface->GetBlockSize());
+
+  // Generate hash tree based on the descriptor and verify that it matches
+  // the hash tree stored in the image.
+  auto hash_function =
+      HashTreeBuilder::HashFunction(part->verity.hash_tree_algorithm);
+  TEST_AND_RETURN_FALSE(hash_function != nullptr);
+  HashTreeBuilder hash_tree_builder(hashtree.data_block_size, hash_function);
+  TEST_AND_RETURN_FALSE(hash_tree_builder.Initialize(
+      hashtree.image_size, part->verity.hash_tree_salt));
+  TEST_AND_RETURN_FALSE(hash_tree_builder.CalculateSize(hashtree.image_size) ==
+                        hashtree.tree_size);
+
+  brillo::Blob buffer;
+  for (uint64_t offset = 0; offset < hashtree.image_size;) {
+    constexpr uint64_t kBufferSize = 1024 * 1024;
+    size_t bytes_to_read = std::min(kBufferSize, hashtree.image_size - offset);
+    TEST_AND_RETURN_FALSE(
+        utils::ReadFileChunk(part->path, offset, bytes_to_read, &buffer));
+    TEST_AND_RETURN_FALSE(
+        hash_tree_builder.Update(buffer.data(), buffer.size()));
+    offset += buffer.size();
+    buffer.clear();
+  }
+  TEST_AND_RETURN_FALSE(hash_tree_builder.BuildHashTree());
+  TEST_AND_RETURN_FALSE(utils::ReadFileChunk(
+      part->path, hashtree.tree_offset, hashtree.tree_size, &buffer));
+  TEST_AND_RETURN_FALSE(hash_tree_builder.CheckHashTree(buffer));
+
   part->verity.hash_tree_extent = ExtentForBytes(
       hashtree.hash_block_size, hashtree.tree_offset, hashtree.tree_size);
 
+  // TODO(senj): Verify FEC data.
   part->verity.fec_data_extent =
       ExtentForBytes(hashtree.data_block_size, 0, hashtree.fec_offset);
   part->verity.fec_extent = ExtentForBytes(