Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6a14ba31 authored by Sami Tolvanen's avatar Sami Tolvanen Committed by Android Git Automerger
Browse files

am 58a748d3: am 87f58261: Merge "Error correction: Append codes to verified partitions"

* commit '58a748d3':
  Error correction: Append codes to verified partitions
parents 6129c60a 58a748d3
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -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
@@ -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))
@@ -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 += \
+1 −0
Original line number Diff line number Diff line
@@ -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)
+1 −0
Original line number Diff line number Diff line
@@ -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 \
+1 −0
Original line number Diff line number Diff line
@@ -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.
+85 −17
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import tempfile
OPTIONS = common.OPTIONS

FIXED_SALT = "aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7"
BLOCK_SIZE = 4096

def RunCommand(cmd):
  """Echo and run the given command.
@@ -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
@@ -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.
@@ -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" % (
@@ -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):
@@ -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:
@@ -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):
@@ -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

@@ -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)
@@ -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"]
@@ -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":
@@ -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)