am 87f58261
: Merge "Error correction: Append codes to verified partitions"
* commit '87f582611a5a5c23abf3237abe0e467e46111567': Error correction: Append codes to verified partitions
This commit is contained in:
@@ -724,6 +724,9 @@ INTERNAL_USERIMAGES_BINARY_PATHS := $(sort $(dir $(INTERNAL_USERIMAGES_DEPS)))
|
|||||||
|
|
||||||
ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY))
|
ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY))
|
||||||
INTERNAL_USERIMAGES_DEPS += $(BUILD_VERITY_TREE) $(APPEND2SIMG) $(VERITY_SIGNER)
|
INTERNAL_USERIMAGES_DEPS += $(BUILD_VERITY_TREE) $(APPEND2SIMG) $(VERITY_SIGNER)
|
||||||
|
ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY_FEC))
|
||||||
|
INTERNAL_USERIMAGES_DEPS += $(FEC)
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SELINUX_FC := $(TARGET_ROOT_OUT)/file_contexts.bin
|
SELINUX_FC := $(TARGET_ROOT_OUT)/file_contexts.bin
|
||||||
@@ -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=$(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_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),$(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_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_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))
|
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT)" >> $(1))
|
||||||
@@ -1364,7 +1368,8 @@ OTATOOLS := $(HOST_OUT_EXECUTABLES)/minigzip \
|
|||||||
$(HOST_OUT_EXECUTABLES)/verity_signer \
|
$(HOST_OUT_EXECUTABLES)/verity_signer \
|
||||||
$(HOST_OUT_EXECUTABLES)/append2simg \
|
$(HOST_OUT_EXECUTABLES)/append2simg \
|
||||||
$(HOST_OUT_EXECUTABLES)/img2simg \
|
$(HOST_OUT_EXECUTABLES)/img2simg \
|
||||||
$(HOST_OUT_EXECUTABLES)/boot_signer
|
$(HOST_OUT_EXECUTABLES)/boot_signer \
|
||||||
|
$(HOST_OUT_EXECUTABLES)/fec
|
||||||
|
|
||||||
# Shared libraries.
|
# Shared libraries.
|
||||||
OTATOOLS += \
|
OTATOOLS += \
|
||||||
|
@@ -515,6 +515,7 @@ BUILD_VERITY_TREE := $(HOST_OUT_EXECUTABLES)/build_verity_tree
|
|||||||
BOOT_SIGNER := $(HOST_OUT_EXECUTABLES)/boot_signer
|
BOOT_SIGNER := $(HOST_OUT_EXECUTABLES)/boot_signer
|
||||||
FUTILITY := prebuilts/misc/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/futility/futility
|
FUTILITY := prebuilts/misc/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/futility/futility
|
||||||
VBOOT_SIGNER := prebuilts/misc/scripts/vboot_signer/vboot_signer.sh
|
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 is always for the build OS, not for the host OS
|
||||||
ACP := $(BUILD_OUT_EXECUTABLES)/acp$(BUILD_EXECUTABLE_SUFFIX)
|
ACP := $(BUILD_OUT_EXECUTABLES)/acp$(BUILD_EXECUTABLE_SUFFIX)
|
||||||
|
@@ -100,6 +100,7 @@ _product_var_list := \
|
|||||||
PRODUCT_SUPPORTS_BOOT_SIGNER \
|
PRODUCT_SUPPORTS_BOOT_SIGNER \
|
||||||
PRODUCT_SUPPORTS_VBOOT \
|
PRODUCT_SUPPORTS_VBOOT \
|
||||||
PRODUCT_SUPPORTS_VERITY \
|
PRODUCT_SUPPORTS_VERITY \
|
||||||
|
PRODUCT_SUPPORTS_VERITY_FEC \
|
||||||
PRODUCT_OEM_PROPERTIES \
|
PRODUCT_OEM_PROPERTIES \
|
||||||
PRODUCT_SYSTEM_PROPERTY_BLACKLIST \
|
PRODUCT_SYSTEM_PROPERTY_BLACKLIST \
|
||||||
PRODUCT_SYSTEM_SERVER_JARS \
|
PRODUCT_SYSTEM_SERVER_JARS \
|
||||||
|
@@ -21,6 +21,7 @@ user_variant := $(filter user userdebug,$(TARGET_BUILD_VARIANT))
|
|||||||
ifneq (,$(user_variant))
|
ifneq (,$(user_variant))
|
||||||
PRODUCT_SUPPORTS_BOOT_SIGNER := true
|
PRODUCT_SUPPORTS_BOOT_SIGNER := true
|
||||||
PRODUCT_SUPPORTS_VERITY := true
|
PRODUCT_SUPPORTS_VERITY := true
|
||||||
|
PRODUCT_SUPPORTS_VERITY_FEC := true
|
||||||
|
|
||||||
# The dev key is used to sign boot and recovery images, and the verity
|
# 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.
|
# metadata table. Actual product deliverables will be re-signed by hand.
|
||||||
|
@@ -33,6 +33,7 @@ import tempfile
|
|||||||
OPTIONS = common.OPTIONS
|
OPTIONS = common.OPTIONS
|
||||||
|
|
||||||
FIXED_SALT = "aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7"
|
FIXED_SALT = "aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7"
|
||||||
|
BLOCK_SIZE = 4096
|
||||||
|
|
||||||
def RunCommand(cmd):
|
def RunCommand(cmd):
|
||||||
"""Echo and run the given command.
|
"""Echo and run the given command.
|
||||||
@@ -48,6 +49,14 @@ def RunCommand(cmd):
|
|||||||
print "%s" % (output.rstrip(),)
|
print "%s" % (output.rstrip(),)
|
||||||
return (output, p.returncode)
|
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):
|
def GetVerityTreeSize(partition_size):
|
||||||
cmd = "build_verity_tree -s %d"
|
cmd = "build_verity_tree -s %d"
|
||||||
cmd %= partition_size
|
cmd %= partition_size
|
||||||
@@ -67,7 +76,22 @@ def GetVerityMetadataSize(partition_size):
|
|||||||
return False, 0
|
return False, 0
|
||||||
return True, int(output)
|
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.
|
"""Modifies the provided partition size to account for the verity metadata.
|
||||||
|
|
||||||
This information is used to size the created image appropriately.
|
This information is used to size the created image appropriately.
|
||||||
@@ -76,13 +100,43 @@ def AdjustPartitionSizeForVerity(partition_size):
|
|||||||
Returns:
|
Returns:
|
||||||
The size of the partition adjusted for verity metadata.
|
The size of the partition adjusted for verity metadata.
|
||||||
"""
|
"""
|
||||||
success, verity_tree_size = GetVerityTreeSize(partition_size)
|
key = "%d %d" % (partition_size, fec_supported)
|
||||||
if not success:
|
if key in AdjustPartitionSizeForVerity.results:
|
||||||
return 0
|
return AdjustPartitionSizeForVerity.results[key]
|
||||||
success, verity_metadata_size = GetVerityMetadataSize(partition_size)
|
|
||||||
if not success:
|
hi = partition_size
|
||||||
return 0
|
if hi % BLOCK_SIZE != 0:
|
||||||
return partition_size - verity_tree_size - verity_metadata_size
|
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):
|
def BuildVerityTree(sparse_image_path, verity_image_path, prop_dict):
|
||||||
cmd = "build_verity_tree -A %s %s %s" % (
|
cmd = "build_verity_tree -A %s %s %s" % (
|
||||||
@@ -130,12 +184,12 @@ def Append2Simg(sparse_image_path, unsparse_image_path, error_message):
|
|||||||
|
|
||||||
def BuildVerifiedImage(data_image_path, verity_image_path,
|
def BuildVerifiedImage(data_image_path, verity_image_path,
|
||||||
verity_metadata_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,
|
if not Append2Simg(data_image_path, verity_image_path,
|
||||||
"Could not append verity tree!"):
|
"Could not append verity tree!"):
|
||||||
return False
|
return False
|
||||||
|
if not Append2Simg(data_image_path, verity_metadata_path,
|
||||||
|
"Could not append verity metadata!"):
|
||||||
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def UnsparseImage(sparse_image_path, replace=True):
|
def UnsparseImage(sparse_image_path, replace=True):
|
||||||
@@ -154,7 +208,7 @@ def UnsparseImage(sparse_image_path, replace=True):
|
|||||||
return False, None
|
return False, None
|
||||||
return True, unsparse_image_path
|
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.
|
"""Creates an image that is verifiable using dm-verity.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -180,6 +234,7 @@ def MakeVerityEnabledImage(out_file, prop_dict):
|
|||||||
# get partial image paths
|
# get partial image paths
|
||||||
verity_image_path = os.path.join(tempdir_name, "verity.img")
|
verity_image_path = os.path.join(tempdir_name, "verity.img")
|
||||||
verity_metadata_path = os.path.join(tempdir_name, "verity_metadata.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
|
# build the verity tree and get the root hash and salt
|
||||||
if not BuildVerityTree(out_file, verity_image_path, prop_dict):
|
if not BuildVerityTree(out_file, verity_image_path, prop_dict):
|
||||||
@@ -201,6 +256,16 @@ def MakeVerityEnabledImage(out_file, prop_dict):
|
|||||||
shutil.rmtree(tempdir_name, ignore_errors=True)
|
shutil.rmtree(tempdir_name, ignore_errors=True)
|
||||||
return False
|
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)
|
shutil.rmtree(tempdir_name, ignore_errors=True)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -248,12 +313,14 @@ def BuildImage(in_dir, prop_dict, out_file, target_out=None):
|
|||||||
|
|
||||||
is_verity_partition = "verity_block_device" in prop_dict
|
is_verity_partition = "verity_block_device" in prop_dict
|
||||||
verity_supported = prop_dict.get("verity") == "true"
|
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
|
# Adjust the partition size to make room for the hashes if this is to be
|
||||||
# verified.
|
# verified.
|
||||||
if verity_supported and is_verity_partition and fs_spans_partition:
|
if verity_supported and is_verity_partition and fs_spans_partition:
|
||||||
partition_size = int(prop_dict.get("partition_size"))
|
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:
|
if not adjusted_size:
|
||||||
return False
|
return False
|
||||||
prop_dict["partition_size"] = str(adjusted_size)
|
prop_dict["partition_size"] = str(adjusted_size)
|
||||||
@@ -366,7 +433,7 @@ def BuildImage(in_dir, prop_dict, out_file, target_out=None):
|
|||||||
"%d" % (mount_point, image_size, partition_size))
|
"%d" % (mount_point, image_size, partition_size))
|
||||||
return False
|
return False
|
||||||
if verity_supported and is_verity_partition:
|
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
|
print "Error: No more room on %s to fit verity data" % mount_point
|
||||||
return False
|
return False
|
||||||
prop_dict["original_partition_size"] = prop_dict["partition_size"]
|
prop_dict["original_partition_size"] = prop_dict["partition_size"]
|
||||||
@@ -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
|
# create the verified image if this is to be verified
|
||||||
if verity_supported and is_verity_partition:
|
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
|
return False
|
||||||
|
|
||||||
if run_fsck and prop_dict.get("skip_fsck") != "true":
|
if run_fsck and prop_dict.get("skip_fsck") != "true":
|
||||||
@@ -416,7 +483,8 @@ def ImagePropFromGlobalDict(glob_dict, mount_point):
|
|||||||
"skip_fsck",
|
"skip_fsck",
|
||||||
"verity",
|
"verity",
|
||||||
"verity_key",
|
"verity_key",
|
||||||
"verity_signer_cmd"
|
"verity_signer_cmd",
|
||||||
|
"verity_fec"
|
||||||
)
|
)
|
||||||
for p in common_props:
|
for p in common_props:
|
||||||
copy_prop(p, p)
|
copy_prop(p, p)
|
||||||
|
Reference in New Issue
Block a user