forked from openkylin/platform_build
Add support for Brillo Verified Boot.
The following variables are introduced BOARD_BVB_ENABLE: can be set to true to build boot.img and system.img files compatible with Brillo Verfied Boot. BOARD_BVB_ROLLBACK_INDEX: can be set to an integer to use for the rollback index. BOARD_BVB_KEY_PATH, BOARD_BVB_ALGORITHM: If set, the former must be a path to the private key used to sign the boot image and the latter must be the algorithm to use. If unset, a test-key stored in the tree will be used. BOARD_BVB_MAKE_BOOT_IMAGE_ARGS: Extra options to pass to 'bvbtool make_boot_image'. BOARD_BVB_SIGN_BOOT_IMAGE_ARGS: Extra options to pass to 'bvbtool sign_boot_image'. BOARD_BVB_ADD_IMAGE_HASHES_ARGS: Extra options to pass to 'bvbtool add_image_hashes'. BOARD_CUSTOM_BVBTOOL: Can be set to specify what bvbtool program to use. The existing BOARD_KERNEL_CMDLINE variable is also used, as are existing kernel and initrd-related variables. Therefore, simply adding BOARD_BVB_ENABLE := true to an existing Makefile should do the trick. Bug: 26185038 TEST=Added 'BOARD_BVB_ENABLE := true' to hardware/bsp/intel/soc/edison/soc.mk and built an image and then ran bvbtool's info_boot_image and info_image_hashes commands on the resulting boot.img and system.img files and verified that the information was correct. Also ran 'm dist' and verified that the boot.img and system.img files in the resulting target_files.zip file had similar information. Change-Id: I08045ed8b0cbddc7c3acdd3a6f2c4bb75cb44bbc
This commit is contained in:
parent
de005f0c85
commit
d995f4b04d
|
@ -507,8 +507,28 @@ INTERNAL_BOOTIMAGE_ARGS := \
|
|||
$(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) \
|
||||
--kernel $(INSTALLED_KERNEL_TARGET)
|
||||
|
||||
INTERNAL_BVBTOOL_MAKE_BOOT_IMAGE_ARGS := \
|
||||
--kernel $(INSTALLED_KERNEL_TARGET) \
|
||||
--rootfs_with_hashes $(PRODUCT_OUT)/system.img
|
||||
|
||||
ifdef BOARD_BVB_ROLLBACK_INDEX
|
||||
INTERNAL_BVBTOOL_MAKE_BOOT_IMAGE_ARGS += \
|
||||
--rollback_index $(BOARD_BVB_ROLLBACK_INDEX)
|
||||
endif
|
||||
|
||||
ifndef BOARD_BVB_KEY_PATH
|
||||
# If key path isn't specified, use the 4096-bit test key.
|
||||
INTERNAL_BVBTOOL_SIGN_BOOT_IMAGE_ARGS := --algorithm SHA256_RSA4096 \
|
||||
--key system/bvb/test/testkey_rsa4096.pem
|
||||
else
|
||||
INTERNAL_BVBTOOL_SIGN_BOOT_IMAGE_ARGS := \
|
||||
--algorithm $(BOARD_BVB_ALGORITHM) --key $(BOARD_BVB_KEY_PATH)
|
||||
endif
|
||||
|
||||
|
||||
ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
|
||||
INTERNAL_BOOTIMAGE_ARGS += --ramdisk $(INSTALLED_RAMDISK_TARGET)
|
||||
INTERNAL_BVBTOOL_MAKE_BOOT_IMAGE_ARGS += --initrd $(INSTALLED_RAMDISK_TARGET)
|
||||
endif
|
||||
|
||||
|
||||
|
@ -517,6 +537,7 @@ INTERNAL_BOOTIMAGE_FILES := $(filter-out --%,$(INTERNAL_BOOTIMAGE_ARGS))
|
|||
BOARD_KERNEL_CMDLINE := $(strip $(BOARD_KERNEL_CMDLINE))
|
||||
ifdef BOARD_KERNEL_CMDLINE
|
||||
INTERNAL_BOOTIMAGE_ARGS += --cmdline "$(BOARD_KERNEL_CMDLINE)"
|
||||
INTERNAL_BVBTOOL_MAKE_BOOT_IMAGE_ARGS += --kernel_cmdline "$(BOARD_KERNEL_CMDLINE)"
|
||||
endif
|
||||
|
||||
BOARD_KERNEL_BASE := $(strip $(BOARD_KERNEL_BASE))
|
||||
|
@ -542,6 +563,23 @@ ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
|
|||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(BOARD_BVB_ENABLE),true)
|
||||
|
||||
$(INSTALLED_BOOTIMAGE_TARGET): $(BVBTOOL) $(INTERNAL_BOOTIMAGE_FILES) $(PRODUCT_OUT)/system.img
|
||||
$(call pretty,"Target boot image: $@")
|
||||
$(hide) $(BVBTOOL) make_boot_image $(INTERNAL_BVBTOOL_MAKE_BOOT_IMAGE_ARGS) $(BOARD_BVB_MAKE_BOOT_IMAGE_ARGS) --output $@
|
||||
$(hide) $(BVBTOOL) sign_boot_image $(INTERNAL_BVBTOOL_SIGN_BOOT_IMAGE_ARGS) $(BOARD_BVB_SIGN_BOOT_IMAGE_ARGS) --image $@
|
||||
$(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE))
|
||||
|
||||
.PHONY: bootimage-nodeps
|
||||
bootimage-nodeps: $(BVBTOOL)
|
||||
@echo "make $@: ignoring dependencies"
|
||||
$(hide) $(BVBTOOL) make_boot_image $(INTERNAL_BVBTOOL_MAKE_BOOT_IMAGE_ARGS) $(BOARD_BVB_MAKE_BOOT_IMAGE_ARGS) --output $(INSTALLED_BOOTIMAGE_TARGET)
|
||||
$(hide) $(BVBTOOL) sign_boot_image $(INTERNAL_BVBTOOL_SIGN_BOOT_IMAGE_ARGS) $(BOARD_BVB_SIGN_BOOT_IMAGE_ARGS) --image $(INSTALLED_BOOTIMAGE_TARGET)
|
||||
$(hide) $(call assert-max-image-size,$(INSTALLED_BOOTIMAGE_TARGET),$(BOARD_BOOTIMAGE_PARTITION_SIZE))
|
||||
|
||||
else # BOARD_BVB_ENABLE
|
||||
|
||||
# We build recovery as boot image if BOARD_USES_RECOVERY_AS_BOOT is true.
|
||||
ifneq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
|
||||
ifeq ($(TARGET_BOOTIMAGE_USE_EXT2),true)
|
||||
|
@ -591,6 +629,7 @@ bootimage-nodeps: $(MKBOOTIMG)
|
|||
|
||||
endif # TARGET_BOOTIMAGE_USE_EXT2
|
||||
endif # BOARD_USES_RECOVERY_AS_BOOT
|
||||
endif # BOARD_BVB_ENABLE
|
||||
|
||||
else # TARGET_NO_KERNEL
|
||||
# HACK: The top-level targets depend on the bootimage. Not all targets
|
||||
|
@ -1117,8 +1156,13 @@ define build-systemimage-target
|
|||
fi; \
|
||||
mkdir -p $(DIST_DIR); cp $(INSTALLED_FILES_FILE) $(DIST_DIR)/installed-files-rescued.txt; \
|
||||
exit 1 )
|
||||
$(if $(BOARD_BVB_ENABLE), $(hide) $(BVBTOOL) add_image_hashes $(BOARD_BVB_ADD_IMAGE_HASHES_ARGS) --image $(1))
|
||||
endef
|
||||
|
||||
ifeq ($(BOARD_BVB_ENABLE),true)
|
||||
FULL_SYSTEMIMAGE_DEPS += $(BVBTOOL)
|
||||
endif
|
||||
|
||||
$(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE)
|
||||
$(call build-systemimage-target,$@)
|
||||
|
||||
|
@ -1721,6 +1765,15 @@ ifneq ($(strip $(SANITIZE_TARGET)),)
|
|||
endif
|
||||
ifeq ($(BOARD_USES_FULL_RECOVERY_IMAGE),true)
|
||||
$(hide) echo "full_recovery_image=true" >> $(zip_root)/META/misc_info.txt
|
||||
endif
|
||||
ifeq ($(BOARD_BVB_ENABLE),true)
|
||||
$(hide) echo "board_bvb_enable=true" >> $(zip_root)/META/misc_info.txt
|
||||
$(hide) echo "board_bvb_make_boot_image_args=$(BOARD_BVB_MAKE_BOOT_IMAGE_ARGS)" >> $(zip_root)/META/misc_info.txt
|
||||
$(hide) echo "board_bvb_sign_boot_image_args=$(BOARD_BVB_SIGN_BOOT_IMAGE_ARGS)" >> $(zip_root)/META/misc_info.txt
|
||||
$(hide) echo "board_bvb_algorithm=$(BOARD_BVB_ALGORITHM)" >> $(zip_root)/META/misc_info.txt
|
||||
$(hide) echo "board_bvb_key_path=$(BOARD_BVB_KEY_PATH)" >> $(zip_root)/META/misc_info.txt
|
||||
$(hide) echo "board_bvb_rollback_index=$(BOARD_BVB_ROLLBACK_INDEX)" >> $(zip_root)/META/misc_info.txt
|
||||
$(hide) echo "board_bvb_add_image_hashes_args=$(BOARD_BVB_ADD_IMAGE_HASHES_ARGS)" >> $(zip_root)/META/misc_info.txt
|
||||
endif
|
||||
$(call generate-userimage-prop-dictionary, $(zip_root)/META/misc_info.txt)
|
||||
ifneq ($(INSTALLED_RECOVERYIMAGE_TARGET),)
|
||||
|
|
|
@ -518,6 +518,11 @@ MKBOOTIMG := $(HOST_OUT_EXECUTABLES)/mkbootimg$(HOST_EXECUTABLE_SUFFIX)
|
|||
else
|
||||
MKBOOTIMG := $(BOARD_CUSTOM_MKBOOTIMG)
|
||||
endif
|
||||
ifeq (,$(strip $(BOARD_CUSTOM_BVBTOOL)))
|
||||
BVBTOOL := $(HOST_OUT_EXECUTABLES)/bvbtool$(HOST_EXECUTABLE_SUFFIX)
|
||||
else
|
||||
BVBTOOL := $(BOARD_CUSTOM_BVBTOOL)
|
||||
endif
|
||||
APICHECK := $(HOST_OUT_EXECUTABLES)/apicheck$(HOST_EXECUTABLE_SUFFIX)
|
||||
FS_GET_STATS := $(HOST_OUT_EXECUTABLES)/fs_get_stats$(HOST_EXECUTABLE_SUFFIX)
|
||||
MAKE_EXT4FS := $(HOST_OUT_EXECUTABLES)/make_ext4fs$(HOST_EXECUTABLE_SUFFIX)
|
||||
|
|
|
@ -31,7 +31,9 @@ if sys.hexversion < 0x02070000:
|
|||
import datetime
|
||||
import errno
|
||||
import os
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import zipfile
|
||||
|
||||
|
@ -48,12 +50,12 @@ OPTIONS.verity_signer_path = None
|
|||
|
||||
def AddSystem(output_zip, prefix="IMAGES/", recovery_img=None, boot_img=None):
|
||||
"""Turn the contents of SYSTEM into a system image and store it in
|
||||
output_zip."""
|
||||
output_zip. Returns the name of the system image file."""
|
||||
|
||||
prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "system.img")
|
||||
if os.path.exists(prebuilt_path):
|
||||
print "system.img already exists in %s, no need to rebuild..." % (prefix,)
|
||||
return
|
||||
return prebuilt_path
|
||||
|
||||
def output_sink(fn, data):
|
||||
ofile = open(os.path.join(OPTIONS.input_tmp, "SYSTEM", fn), "w")
|
||||
|
@ -68,8 +70,23 @@ def AddSystem(output_zip, prefix="IMAGES/", recovery_img=None, boot_img=None):
|
|||
block_list = common.MakeTempFile(prefix="system-blocklist-", suffix=".map")
|
||||
imgname = BuildSystem(OPTIONS.input_tmp, OPTIONS.info_dict,
|
||||
block_list=block_list)
|
||||
|
||||
# If requested, calculate and add dm-verity integrity hashes and
|
||||
# metadata to system.img.
|
||||
if OPTIONS.info_dict.get("board_bvb_enable", None) == "true":
|
||||
bvbtool = os.getenv('BVBTOOL') or "bvbtool"
|
||||
cmd = [bvbtool, "add_image_hashes", "--image", imgname]
|
||||
args = OPTIONS.info_dict.get("board_bvb_add_image_hashes_args", None)
|
||||
if args and args.strip():
|
||||
cmd.extend(shlex.split(args))
|
||||
p = common.Run(cmd, stdout=subprocess.PIPE)
|
||||
p.communicate()
|
||||
assert p.returncode == 0, "bvbtool add_image_hashes of %s image failed" % (
|
||||
os.path.basename(OPTIONS.input_tmp),)
|
||||
|
||||
common.ZipWrite(output_zip, imgname, prefix + "system.img")
|
||||
common.ZipWrite(output_zip, block_list, prefix + "system.map")
|
||||
return imgname
|
||||
|
||||
|
||||
def BuildSystem(input_dir, info_dict, block_list=None):
|
||||
|
@ -275,19 +292,36 @@ def AddImagesToTargetFiles(filename):
|
|||
compression=zipfile.ZIP_DEFLATED)
|
||||
|
||||
has_recovery = (OPTIONS.info_dict.get("no_recovery") != "true")
|
||||
system_root_image = (OPTIONS.info_dict.get("system_root_image", None) == "true")
|
||||
board_bvb_enable = (OPTIONS.info_dict.get("board_bvb_enable", None) == "true")
|
||||
|
||||
# Brillo Verified Boot is incompatible with certain
|
||||
# configurations. Explicitly check for these.
|
||||
if board_bvb_enable:
|
||||
assert not has_recovery, "has_recovery incompatible with bvb"
|
||||
assert not system_root_image, "system_root_image incompatible with bvb"
|
||||
assert not OPTIONS.rebuild_recovery, "rebuild_recovery incompatible with bvb"
|
||||
assert not has_vendor, "VENDOR images currently incompatible with bvb"
|
||||
|
||||
def banner(s):
|
||||
print "\n\n++++ " + s + " ++++\n\n"
|
||||
|
||||
banner("boot")
|
||||
prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "boot.img")
|
||||
boot_image = None
|
||||
if os.path.exists(prebuilt_path):
|
||||
banner("boot")
|
||||
print "boot.img already exists in IMAGES/, no need to rebuild..."
|
||||
if OPTIONS.rebuild_recovery:
|
||||
boot_image = common.GetBootableImage(
|
||||
"IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
|
||||
else:
|
||||
if board_bvb_enable:
|
||||
# With Brillo Verified Boot, we need to build system.img before
|
||||
# boot.img since the latter includes the dm-verity root hash and
|
||||
# salt for the former.
|
||||
pass
|
||||
else:
|
||||
banner("boot")
|
||||
boot_image = common.GetBootableImage(
|
||||
"IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
|
||||
if boot_image:
|
||||
|
@ -310,7 +344,17 @@ def AddImagesToTargetFiles(filename):
|
|||
recovery_image.AddToZip(output_zip)
|
||||
|
||||
banner("system")
|
||||
AddSystem(output_zip, recovery_img=recovery_image, boot_img=boot_image)
|
||||
system_img_path = AddSystem(
|
||||
output_zip, recovery_img=recovery_image, boot_img=boot_image)
|
||||
if OPTIONS.info_dict.get("board_bvb_enable", None) == "true":
|
||||
# If we're using Brillo Verified Boot, we can now build boot.img
|
||||
# given that we have system.img.
|
||||
banner("boot")
|
||||
boot_image = common.GetBootableImage(
|
||||
"IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT",
|
||||
system_img_path=system_img_path)
|
||||
if boot_image:
|
||||
boot_image.AddToZip(output_zip)
|
||||
if has_vendor:
|
||||
banner("vendor")
|
||||
AddVendor(output_zip)
|
||||
|
|
|
@ -473,8 +473,114 @@ def _BuildBootableImage(sourcedir, fs_config_file, info_dict=None,
|
|||
return data
|
||||
|
||||
|
||||
def _BuildBvbBootableImage(sourcedir, fs_config_file, system_img_path,
|
||||
info_dict=None, has_ramdisk=False):
|
||||
"""Build a bootable image compatible with Brillo Verified Boot from the
|
||||
specified sourcedir.
|
||||
|
||||
Take a kernel, cmdline, system image path, and optionally a ramdisk
|
||||
directory from the input (in 'sourcedir'), and turn them into a boot
|
||||
image. Return the image data, or None if sourcedir does not appear
|
||||
to contains files for building the requested image.
|
||||
"""
|
||||
|
||||
def make_ramdisk():
|
||||
ramdisk_img = tempfile.NamedTemporaryFile()
|
||||
|
||||
if os.access(fs_config_file, os.F_OK):
|
||||
cmd = ["mkbootfs", "-f", fs_config_file,
|
||||
os.path.join(sourcedir, "RAMDISK")]
|
||||
else:
|
||||
cmd = ["mkbootfs", os.path.join(sourcedir, "RAMDISK")]
|
||||
p1 = Run(cmd, stdout=subprocess.PIPE)
|
||||
p2 = Run(["minigzip"], stdin=p1.stdout, stdout=ramdisk_img.file.fileno())
|
||||
|
||||
p2.wait()
|
||||
p1.wait()
|
||||
assert p1.returncode == 0, "mkbootfs of %s ramdisk failed" % (sourcedir,)
|
||||
assert p2.returncode == 0, "minigzip of %s ramdisk failed" % (sourcedir,)
|
||||
|
||||
return ramdisk_img
|
||||
|
||||
if not os.access(os.path.join(sourcedir, "kernel"), os.F_OK):
|
||||
return None
|
||||
|
||||
if has_ramdisk and not os.access(os.path.join(sourcedir, "RAMDISK"), os.F_OK):
|
||||
return None
|
||||
|
||||
if info_dict is None:
|
||||
info_dict = OPTIONS.info_dict
|
||||
|
||||
img = tempfile.NamedTemporaryFile()
|
||||
|
||||
if has_ramdisk:
|
||||
ramdisk_img = make_ramdisk()
|
||||
|
||||
# use BVBTOOL from environ, or "bvbtool" if empty or not set
|
||||
bvbtool = os.getenv('BVBTOOL') or "bvbtool"
|
||||
|
||||
# First, create boot.img.
|
||||
cmd = [bvbtool, "make_boot_image"]
|
||||
|
||||
fn = os.path.join(sourcedir, "cmdline")
|
||||
if os.access(fn, os.F_OK):
|
||||
cmd.append("--kernel_cmdline")
|
||||
cmd.append(open(fn).read().rstrip("\n"))
|
||||
|
||||
cmd.extend(["--kernel", os.path.join(sourcedir, "kernel")])
|
||||
|
||||
if has_ramdisk:
|
||||
cmd.extend(["--initrd", ramdisk_img.name])
|
||||
|
||||
cmd.extend(["--rootfs_with_hashes", system_img_path])
|
||||
|
||||
args = info_dict.get("board_bvb_make_boot_image_args", None)
|
||||
if args and args.strip():
|
||||
cmd.extend(shlex.split(args))
|
||||
|
||||
rollback_index = info_dict.get("board_bvb_rollback_index", None)
|
||||
if rollback_index and rollback_index.strip():
|
||||
cmd.extend(["--rollback_index", rollback_index.strip()])
|
||||
|
||||
cmd.extend(["--output", img.name])
|
||||
|
||||
p = Run(cmd, stdout=subprocess.PIPE)
|
||||
p.communicate()
|
||||
assert p.returncode == 0, "bvbtool make_boot_image of %s image failed" % (
|
||||
os.path.basename(sourcedir),)
|
||||
|
||||
# Then, sign boot.img.
|
||||
cmd = [bvbtool, "sign_boot_image", "--image", img.name]
|
||||
|
||||
algorithm = info_dict.get("board_bvb_algorithm", None)
|
||||
key_path = info_dict.get("board_bvb_key_path", None)
|
||||
if algorithm and algorithm.strip() and key_path and key_path.strip():
|
||||
cmd.extend(["--algorithm", algorithm, "--key", key_path])
|
||||
else:
|
||||
cmd.extend(["--algorithm", "SHA256_RSA4096"])
|
||||
cmd.extend(["--key", "system/bvb/test/testkey_rsa4096.pem"])
|
||||
|
||||
args = info_dict.get("board_bvb_sign_boot_image_args", None)
|
||||
if args and args.strip():
|
||||
cmd.extend(shlex.split(args))
|
||||
|
||||
p = Run(cmd, stdout=subprocess.PIPE)
|
||||
p.communicate()
|
||||
assert p.returncode == 0, "bvbtool sign_boot_image of %s image failed" % (
|
||||
os.path.basename(sourcedir),)
|
||||
|
||||
img.seek(os.SEEK_SET, 0)
|
||||
data = img.read()
|
||||
|
||||
if has_ramdisk:
|
||||
ramdisk_img.close()
|
||||
img.close()
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def GetBootableImage(name, prebuilt_name, unpack_dir, tree_subdir,
|
||||
info_dict=None):
|
||||
info_dict=None, system_img_path=None):
|
||||
"""Return a File object with the desired bootable image.
|
||||
|
||||
Look for it in 'unpack_dir'/BOOTABLE_IMAGES under the name 'prebuilt_name',
|
||||
|
@ -504,6 +610,11 @@ def GetBootableImage(name, prebuilt_name, unpack_dir, tree_subdir,
|
|||
info_dict.get("recovery_as_boot") == "true")
|
||||
|
||||
fs_config = "META/" + tree_subdir.lower() + "_filesystem_config.txt"
|
||||
if info_dict.get("board_bvb_enable", None) == "true":
|
||||
data = _BuildBvbBootableImage(os.path.join(unpack_dir, tree_subdir),
|
||||
os.path.join(unpack_dir, fs_config),
|
||||
system_img_path, info_dict, has_ramdisk)
|
||||
else:
|
||||
data = _BuildBootableImage(os.path.join(unpack_dir, tree_subdir),
|
||||
os.path.join(unpack_dir, fs_config),
|
||||
info_dict, has_ramdisk)
|
||||
|
|
Loading…
Reference in New Issue