Loading core/Makefile +6 −1 Original line number Diff line number Diff line Loading @@ -724,6 +724,9 @@ INTERNAL_USERIMAGES_BINARY_PATHS := $(sort $(dir $(INTERNAL_USERIMAGES_DEPS))) ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY)) INTERNAL_USERIMAGES_DEPS += $(BUILD_VERITY_TREE) $(APPEND2SIMG) $(VERITY_SIGNER) ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY_FEC)) INTERNAL_USERIMAGES_DEPS += $(FEC) endif endif SELINUX_FC := $(TARGET_ROOT_OUT)/file_contexts.bin Loading Loading @@ -754,6 +757,7 @@ $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_BOOT_SIGNER),$(hide) echo " $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),$(hide) echo "verity=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY)" >> $(1)) $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),$(hide) echo "verity_key=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY)" >> $(1)) $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),$(hide) echo "verity_signer_cmd=$(notdir $(VERITY_SIGNER))" >> $(1)) $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY_FEC),$(hide) echo "verity_fec=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY_FEC)" >> $(1)) $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_VERITY_PARTITION),$(hide) echo "system_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_VERITY_PARTITION)" >> $(1)) $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_VERITY_PARTITION),$(hide) echo "vendor_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_VERITY_PARTITION)" >> $(1)) $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT)" >> $(1)) Loading Loading @@ -1364,7 +1368,8 @@ OTATOOLS := $(HOST_OUT_EXECUTABLES)/minigzip \ $(HOST_OUT_EXECUTABLES)/verity_signer \ $(HOST_OUT_EXECUTABLES)/append2simg \ $(HOST_OUT_EXECUTABLES)/img2simg \ $(HOST_OUT_EXECUTABLES)/boot_signer $(HOST_OUT_EXECUTABLES)/boot_signer \ $(HOST_OUT_EXECUTABLES)/fec # Shared libraries. OTATOOLS += \ Loading core/config.mk +1 −0 Original line number Diff line number Diff line Loading @@ -515,6 +515,7 @@ BUILD_VERITY_TREE := $(HOST_OUT_EXECUTABLES)/build_verity_tree BOOT_SIGNER := $(HOST_OUT_EXECUTABLES)/boot_signer FUTILITY := prebuilts/misc/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/futility/futility VBOOT_SIGNER := prebuilts/misc/scripts/vboot_signer/vboot_signer.sh FEC := $(HOST_OUT_EXECUTABLES)/fec # ACP is always for the build OS, not for the host OS ACP := $(BUILD_OUT_EXECUTABLES)/acp$(BUILD_EXECUTABLE_SUFFIX) Loading core/product.mk +1 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ _product_var_list := \ PRODUCT_SUPPORTS_BOOT_SIGNER \ PRODUCT_SUPPORTS_VBOOT \ PRODUCT_SUPPORTS_VERITY \ PRODUCT_SUPPORTS_VERITY_FEC \ PRODUCT_OEM_PROPERTIES \ PRODUCT_SYSTEM_PROPERTY_BLACKLIST \ PRODUCT_SYSTEM_SERVER_JARS \ Loading target/product/verity.mk +1 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ user_variant := $(filter user userdebug,$(TARGET_BUILD_VARIANT)) ifneq (,$(user_variant)) PRODUCT_SUPPORTS_BOOT_SIGNER := true PRODUCT_SUPPORTS_VERITY := true PRODUCT_SUPPORTS_VERITY_FEC := true # The dev key is used to sign boot and recovery images, and the verity # metadata table. Actual product deliverables will be re-signed by hand. Loading tools/releasetools/build_image.py +85 −17 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import tempfile OPTIONS = common.OPTIONS FIXED_SALT = "aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7" BLOCK_SIZE = 4096 def RunCommand(cmd): """Echo and run the given command. Loading @@ -48,6 +49,14 @@ def RunCommand(cmd): print "%s" % (output.rstrip(),) return (output, p.returncode) def GetVerityFECSize(partition_size): cmd = "fec -s %d" % partition_size status, output = commands.getstatusoutput(cmd) if status: print output return False, 0 return True, int(output) def GetVerityTreeSize(partition_size): cmd = "build_verity_tree -s %d" cmd %= partition_size Loading @@ -67,7 +76,22 @@ def GetVerityMetadataSize(partition_size): return False, 0 return True, int(output) def AdjustPartitionSizeForVerity(partition_size): def GetVeritySize(partition_size, fec_supported): success, verity_tree_size = GetVerityTreeSize(partition_size) if not success: return 0 success, verity_metadata_size = GetVerityMetadataSize(partition_size) if not success: return 0 verity_size = verity_tree_size + verity_metadata_size if fec_supported: success, fec_size = GetVerityFECSize(partition_size + verity_size) if not success: return 0 return verity_size + fec_size return verity_size def AdjustPartitionSizeForVerity(partition_size, fec_supported): """Modifies the provided partition size to account for the verity metadata. This information is used to size the created image appropriately. Loading @@ -76,13 +100,43 @@ def AdjustPartitionSizeForVerity(partition_size): Returns: The size of the partition adjusted for verity metadata. """ success, verity_tree_size = GetVerityTreeSize(partition_size) if not success: return 0 success, verity_metadata_size = GetVerityMetadataSize(partition_size) if not success: return 0 return partition_size - verity_tree_size - verity_metadata_size key = "%d %d" % (partition_size, fec_supported) if key in AdjustPartitionSizeForVerity.results: return AdjustPartitionSizeForVerity.results[key] hi = partition_size if hi % BLOCK_SIZE != 0: hi = (hi // BLOCK_SIZE) * BLOCK_SIZE # verity tree and fec sizes depend on the partition size, which # means this estimate is always going to be unnecessarily small lo = partition_size - GetVeritySize(hi, fec_supported) result = lo # do a binary search for the optimal size while lo < hi: i = ((lo + hi) // (2 * BLOCK_SIZE)) * BLOCK_SIZE size = i + GetVeritySize(i, fec_supported) if size <= partition_size: if result < i: result = i lo = i + BLOCK_SIZE else: hi = i AdjustPartitionSizeForVerity.results[key] = result return result AdjustPartitionSizeForVerity.results = {} def BuildVerityFEC(sparse_image_path, verity_fec_path, prop_dict): cmd = "fec -e %s %s" % (sparse_image_path, verity_fec_path) print cmd status, output = commands.getstatusoutput(cmd) if status: print "Could not build FEC data! Error: %s" % output return False return True def BuildVerityTree(sparse_image_path, verity_image_path, prop_dict): cmd = "build_verity_tree -A %s %s %s" % ( Loading Loading @@ -130,12 +184,12 @@ def Append2Simg(sparse_image_path, unsparse_image_path, error_message): def BuildVerifiedImage(data_image_path, verity_image_path, verity_metadata_path): if not Append2Simg(data_image_path, verity_metadata_path, "Could not append verity metadata!"): return False if not Append2Simg(data_image_path, verity_image_path, "Could not append verity tree!"): return False if not Append2Simg(data_image_path, verity_metadata_path, "Could not append verity metadata!"): return False return True def UnsparseImage(sparse_image_path, replace=True): Loading @@ -154,7 +208,7 @@ def UnsparseImage(sparse_image_path, replace=True): return False, None return True, unsparse_image_path def MakeVerityEnabledImage(out_file, prop_dict): def MakeVerityEnabledImage(out_file, fec_supported, prop_dict): """Creates an image that is verifiable using dm-verity. Args: Loading @@ -180,6 +234,7 @@ def MakeVerityEnabledImage(out_file, prop_dict): # get partial image paths verity_image_path = os.path.join(tempdir_name, "verity.img") verity_metadata_path = os.path.join(tempdir_name, "verity_metadata.img") verity_fec_path = os.path.join(tempdir_name, "verity_fec.img") # build the verity tree and get the root hash and salt if not BuildVerityTree(out_file, verity_image_path, prop_dict): Loading @@ -201,6 +256,16 @@ def MakeVerityEnabledImage(out_file, prop_dict): shutil.rmtree(tempdir_name, ignore_errors=True) return False if fec_supported: # build FEC for the entire partition, including metadata if not BuildVerityFEC(out_file, verity_fec_path, prop_dict): shutil.rmtree(tempdir_name, ignore_errors=True) return False if not Append2Simg(out_file, verity_fec_path, "Could not append FEC!"): shutil.rmtree(tempdir_name, ignore_errors=True) return False shutil.rmtree(tempdir_name, ignore_errors=True) return True Loading Loading @@ -248,12 +313,14 @@ def BuildImage(in_dir, prop_dict, out_file, target_out=None): is_verity_partition = "verity_block_device" in prop_dict verity_supported = prop_dict.get("verity") == "true" verity_fec_supported = prop_dict.get("verity_fec") == "true" # Adjust the partition size to make room for the hashes if this is to be # verified. if verity_supported and is_verity_partition and fs_spans_partition: partition_size = int(prop_dict.get("partition_size")) adjusted_size = AdjustPartitionSizeForVerity(partition_size) adjusted_size = AdjustPartitionSizeForVerity(partition_size, verity_fec_supported) if not adjusted_size: return False prop_dict["partition_size"] = str(adjusted_size) Loading Loading @@ -366,7 +433,7 @@ def BuildImage(in_dir, prop_dict, out_file, target_out=None): "%d" % (mount_point, image_size, partition_size)) return False if verity_supported and is_verity_partition: if 2 * image_size - AdjustPartitionSizeForVerity(image_size) > partition_size: if 2 * image_size - AdjustPartitionSizeForVerity(image_size, verity_fec_supported) > partition_size: print "Error: No more room on %s to fit verity data" % mount_point return False prop_dict["original_partition_size"] = prop_dict["partition_size"] Loading @@ -374,7 +441,7 @@ def BuildImage(in_dir, prop_dict, out_file, target_out=None): # create the verified image if this is to be verified if verity_supported and is_verity_partition: if not MakeVerityEnabledImage(out_file, prop_dict): if not MakeVerityEnabledImage(out_file, verity_fec_supported, prop_dict): return False if run_fsck and prop_dict.get("skip_fsck") != "true": Loading Loading @@ -416,7 +483,8 @@ def ImagePropFromGlobalDict(glob_dict, mount_point): "skip_fsck", "verity", "verity_key", "verity_signer_cmd" "verity_signer_cmd", "verity_fec" ) for p in common_props: copy_prop(p, p) Loading Loading
core/Makefile +6 −1 Original line number Diff line number Diff line Loading @@ -724,6 +724,9 @@ INTERNAL_USERIMAGES_BINARY_PATHS := $(sort $(dir $(INTERNAL_USERIMAGES_DEPS))) ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY)) INTERNAL_USERIMAGES_DEPS += $(BUILD_VERITY_TREE) $(APPEND2SIMG) $(VERITY_SIGNER) ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY_FEC)) INTERNAL_USERIMAGES_DEPS += $(FEC) endif endif SELINUX_FC := $(TARGET_ROOT_OUT)/file_contexts.bin Loading Loading @@ -754,6 +757,7 @@ $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_BOOT_SIGNER),$(hide) echo " $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),$(hide) echo "verity=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY)" >> $(1)) $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),$(hide) echo "verity_key=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY)" >> $(1)) $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),$(hide) echo "verity_signer_cmd=$(notdir $(VERITY_SIGNER))" >> $(1)) $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY_FEC),$(hide) echo "verity_fec=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY_FEC)" >> $(1)) $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_VERITY_PARTITION),$(hide) echo "system_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_VERITY_PARTITION)" >> $(1)) $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_VERITY_PARTITION),$(hide) echo "vendor_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_VERITY_PARTITION)" >> $(1)) $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT)" >> $(1)) Loading Loading @@ -1364,7 +1368,8 @@ OTATOOLS := $(HOST_OUT_EXECUTABLES)/minigzip \ $(HOST_OUT_EXECUTABLES)/verity_signer \ $(HOST_OUT_EXECUTABLES)/append2simg \ $(HOST_OUT_EXECUTABLES)/img2simg \ $(HOST_OUT_EXECUTABLES)/boot_signer $(HOST_OUT_EXECUTABLES)/boot_signer \ $(HOST_OUT_EXECUTABLES)/fec # Shared libraries. OTATOOLS += \ Loading
core/config.mk +1 −0 Original line number Diff line number Diff line Loading @@ -515,6 +515,7 @@ BUILD_VERITY_TREE := $(HOST_OUT_EXECUTABLES)/build_verity_tree BOOT_SIGNER := $(HOST_OUT_EXECUTABLES)/boot_signer FUTILITY := prebuilts/misc/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/futility/futility VBOOT_SIGNER := prebuilts/misc/scripts/vboot_signer/vboot_signer.sh FEC := $(HOST_OUT_EXECUTABLES)/fec # ACP is always for the build OS, not for the host OS ACP := $(BUILD_OUT_EXECUTABLES)/acp$(BUILD_EXECUTABLE_SUFFIX) Loading
core/product.mk +1 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ _product_var_list := \ PRODUCT_SUPPORTS_BOOT_SIGNER \ PRODUCT_SUPPORTS_VBOOT \ PRODUCT_SUPPORTS_VERITY \ PRODUCT_SUPPORTS_VERITY_FEC \ PRODUCT_OEM_PROPERTIES \ PRODUCT_SYSTEM_PROPERTY_BLACKLIST \ PRODUCT_SYSTEM_SERVER_JARS \ Loading
target/product/verity.mk +1 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ user_variant := $(filter user userdebug,$(TARGET_BUILD_VARIANT)) ifneq (,$(user_variant)) PRODUCT_SUPPORTS_BOOT_SIGNER := true PRODUCT_SUPPORTS_VERITY := true PRODUCT_SUPPORTS_VERITY_FEC := true # The dev key is used to sign boot and recovery images, and the verity # metadata table. Actual product deliverables will be re-signed by hand. Loading
tools/releasetools/build_image.py +85 −17 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import tempfile OPTIONS = common.OPTIONS FIXED_SALT = "aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7" BLOCK_SIZE = 4096 def RunCommand(cmd): """Echo and run the given command. Loading @@ -48,6 +49,14 @@ def RunCommand(cmd): print "%s" % (output.rstrip(),) return (output, p.returncode) def GetVerityFECSize(partition_size): cmd = "fec -s %d" % partition_size status, output = commands.getstatusoutput(cmd) if status: print output return False, 0 return True, int(output) def GetVerityTreeSize(partition_size): cmd = "build_verity_tree -s %d" cmd %= partition_size Loading @@ -67,7 +76,22 @@ def GetVerityMetadataSize(partition_size): return False, 0 return True, int(output) def AdjustPartitionSizeForVerity(partition_size): def GetVeritySize(partition_size, fec_supported): success, verity_tree_size = GetVerityTreeSize(partition_size) if not success: return 0 success, verity_metadata_size = GetVerityMetadataSize(partition_size) if not success: return 0 verity_size = verity_tree_size + verity_metadata_size if fec_supported: success, fec_size = GetVerityFECSize(partition_size + verity_size) if not success: return 0 return verity_size + fec_size return verity_size def AdjustPartitionSizeForVerity(partition_size, fec_supported): """Modifies the provided partition size to account for the verity metadata. This information is used to size the created image appropriately. Loading @@ -76,13 +100,43 @@ def AdjustPartitionSizeForVerity(partition_size): Returns: The size of the partition adjusted for verity metadata. """ success, verity_tree_size = GetVerityTreeSize(partition_size) if not success: return 0 success, verity_metadata_size = GetVerityMetadataSize(partition_size) if not success: return 0 return partition_size - verity_tree_size - verity_metadata_size key = "%d %d" % (partition_size, fec_supported) if key in AdjustPartitionSizeForVerity.results: return AdjustPartitionSizeForVerity.results[key] hi = partition_size if hi % BLOCK_SIZE != 0: hi = (hi // BLOCK_SIZE) * BLOCK_SIZE # verity tree and fec sizes depend on the partition size, which # means this estimate is always going to be unnecessarily small lo = partition_size - GetVeritySize(hi, fec_supported) result = lo # do a binary search for the optimal size while lo < hi: i = ((lo + hi) // (2 * BLOCK_SIZE)) * BLOCK_SIZE size = i + GetVeritySize(i, fec_supported) if size <= partition_size: if result < i: result = i lo = i + BLOCK_SIZE else: hi = i AdjustPartitionSizeForVerity.results[key] = result return result AdjustPartitionSizeForVerity.results = {} def BuildVerityFEC(sparse_image_path, verity_fec_path, prop_dict): cmd = "fec -e %s %s" % (sparse_image_path, verity_fec_path) print cmd status, output = commands.getstatusoutput(cmd) if status: print "Could not build FEC data! Error: %s" % output return False return True def BuildVerityTree(sparse_image_path, verity_image_path, prop_dict): cmd = "build_verity_tree -A %s %s %s" % ( Loading Loading @@ -130,12 +184,12 @@ def Append2Simg(sparse_image_path, unsparse_image_path, error_message): def BuildVerifiedImage(data_image_path, verity_image_path, verity_metadata_path): if not Append2Simg(data_image_path, verity_metadata_path, "Could not append verity metadata!"): return False if not Append2Simg(data_image_path, verity_image_path, "Could not append verity tree!"): return False if not Append2Simg(data_image_path, verity_metadata_path, "Could not append verity metadata!"): return False return True def UnsparseImage(sparse_image_path, replace=True): Loading @@ -154,7 +208,7 @@ def UnsparseImage(sparse_image_path, replace=True): return False, None return True, unsparse_image_path def MakeVerityEnabledImage(out_file, prop_dict): def MakeVerityEnabledImage(out_file, fec_supported, prop_dict): """Creates an image that is verifiable using dm-verity. Args: Loading @@ -180,6 +234,7 @@ def MakeVerityEnabledImage(out_file, prop_dict): # get partial image paths verity_image_path = os.path.join(tempdir_name, "verity.img") verity_metadata_path = os.path.join(tempdir_name, "verity_metadata.img") verity_fec_path = os.path.join(tempdir_name, "verity_fec.img") # build the verity tree and get the root hash and salt if not BuildVerityTree(out_file, verity_image_path, prop_dict): Loading @@ -201,6 +256,16 @@ def MakeVerityEnabledImage(out_file, prop_dict): shutil.rmtree(tempdir_name, ignore_errors=True) return False if fec_supported: # build FEC for the entire partition, including metadata if not BuildVerityFEC(out_file, verity_fec_path, prop_dict): shutil.rmtree(tempdir_name, ignore_errors=True) return False if not Append2Simg(out_file, verity_fec_path, "Could not append FEC!"): shutil.rmtree(tempdir_name, ignore_errors=True) return False shutil.rmtree(tempdir_name, ignore_errors=True) return True Loading Loading @@ -248,12 +313,14 @@ def BuildImage(in_dir, prop_dict, out_file, target_out=None): is_verity_partition = "verity_block_device" in prop_dict verity_supported = prop_dict.get("verity") == "true" verity_fec_supported = prop_dict.get("verity_fec") == "true" # Adjust the partition size to make room for the hashes if this is to be # verified. if verity_supported and is_verity_partition and fs_spans_partition: partition_size = int(prop_dict.get("partition_size")) adjusted_size = AdjustPartitionSizeForVerity(partition_size) adjusted_size = AdjustPartitionSizeForVerity(partition_size, verity_fec_supported) if not adjusted_size: return False prop_dict["partition_size"] = str(adjusted_size) Loading Loading @@ -366,7 +433,7 @@ def BuildImage(in_dir, prop_dict, out_file, target_out=None): "%d" % (mount_point, image_size, partition_size)) return False if verity_supported and is_verity_partition: if 2 * image_size - AdjustPartitionSizeForVerity(image_size) > partition_size: if 2 * image_size - AdjustPartitionSizeForVerity(image_size, verity_fec_supported) > partition_size: print "Error: No more room on %s to fit verity data" % mount_point return False prop_dict["original_partition_size"] = prop_dict["partition_size"] Loading @@ -374,7 +441,7 @@ def BuildImage(in_dir, prop_dict, out_file, target_out=None): # create the verified image if this is to be verified if verity_supported and is_verity_partition: if not MakeVerityEnabledImage(out_file, prop_dict): if not MakeVerityEnabledImage(out_file, verity_fec_supported, prop_dict): return False if run_fsck and prop_dict.get("skip_fsck") != "true": Loading Loading @@ -416,7 +483,8 @@ def ImagePropFromGlobalDict(glob_dict, mount_point): "skip_fsck", "verity", "verity_key", "verity_signer_cmd" "verity_signer_cmd", "verity_fec" ) for p in common_props: copy_prop(p, p) Loading