Implement fsverity metadata generator

Using fsverity tool, fsverity metadata for specific artifacts in system
mage can be generated. Users can do that by setting a makefile variable
PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA to true.

If set to true, the following artifacts will be signed.

- system/framework/*.jar
- system/framework/oat/<arch>/*.{oat,vdex,art}
- system/etc/boot-image.prof
- system/etc/dirty-image-objects

One fsverity metadata container file per one input file will be
generated in system.img, with a suffix ".fsv_meta". e.g. a container
file for "system/framework/foo.jar" will be
"system/framework/foo.jar.fsv_meta".

Bug: 193113311
Test: build with PRODUCT_SYSTEM_FSVERITY_GENERATE_METADATA := true
Change-Id: Ib70d591a72d23286b5debcb05fbad799dfd79b94
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 38104af..8e8bcde 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -24,6 +24,7 @@
 
 from __future__ import print_function
 
+import glob
 import logging
 import os
 import os.path
@@ -34,6 +35,8 @@
 import common
 import verity_utils
 
+from fsverity_metadata_generator import FSVerityMetadataGenerator
+
 logger = logging.getLogger(__name__)
 
 OPTIONS = common.OPTIONS
@@ -475,6 +478,24 @@
   elif fs_type.startswith("f2fs") and prop_dict.get("f2fs_compress") == "true":
     fs_spans_partition = False
 
+  if "fsverity_generate_metadata" in prop_dict:
+    patterns = [
+      "system/framework/*.jar",
+      "system/framework/oat/*/*.oat",
+      "system/framework/oat/*/*.vdex",
+      "system/framework/oat/*/*.art",
+      "system/etc/boot-image.prof",
+      "system/etc/dirty-image-objects",
+    ]
+    files = []
+    for pattern in patterns:
+      files += glob.glob(os.path.join(in_dir, pattern))
+    files = sorted(set(files))
+
+    generator = FSVerityMetadataGenerator(prop_dict["fsverity"])
+    for f in files:
+      generator.generate(f)
+
   # Get a builder for creating an image that's to be verified by Verified Boot,
   # or None if not applicable.
   verity_image_builder = verity_utils.CreateVerityImageBuilder(prop_dict)
@@ -589,7 +610,6 @@
   if verity_image_builder:
     verity_image_builder.Build(out_file)
 
-
 def ImagePropFromGlobalDict(glob_dict, mount_point):
   """Build an image property dictionary from the global dictionary.
 
@@ -725,6 +745,8 @@
     copy_prop("system_root_image", "system_root_image")
     copy_prop("root_dir", "root_dir")
     copy_prop("root_fs_config", "root_fs_config")
+    copy_prop("fsverity", "fsverity")
+    copy_prop("fsverity_generate_metadata", "fsverity_generate_metadata")
   elif mount_point == "data":
     # Copy the generic fs type first, override with specific one if available.
     copy_prop("flash_logical_block_size", "flash_logical_block_size")