From 2ce63edab715ae4ff34e1a2ef240b05216f6ca5d Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Thu, 15 Sep 2016 13:43:54 -0400 Subject: [PATCH] Update for new Android Verified Boot (AVB). This updates the build system for the new Android Verified Boot codebase. As this is based on Brillo Verified Boot, this change replaces the existing BVB support. Android Verified Boot is enabled by the BOARD_AVB_ENABLE variable BOARD_AVB_ENABLE := true This will make the build system create vbmeta.img which will contain a hash descriptor for boot.img, a hashtree descriptor for system.img, a kernel-cmdline descriptor for setting up dm-verity for system.img and append a hash-tree to system.img. Additionally, the descriptors are left in boot.img and system.img so a third party can create their own vbmeta.img file linking - using the option --chain_partition - to these images. If this is not needed footers can be erased using the 'avbtool erase_footer' command. It's also harmless to just leave them in the images. By default, the algorithm SHA256_RSA4096 is used with a test key from the AVB source directory. This can be overriden by the BOARD_AVB_ALGORITHM and BOARD_AVB_KEY_PATH variables to use e.g. a 4096-bit RSA key and SHA-512: BOARD_AVB_ALGORITHM := SHA512_RSA4096 BOARD_AVB_KEY_PATH := /path/to/rsa_key_4096bits.pem To prevent rollback attacks, the rollback index should be increased on a regular basis. The rollback index can be set with the BOARD_AVB_ROLLBACK_INDEX variable: BOARD_AVB_ROLLBACK_INDEX := 5 If this is not set, the rollback index defaults to 0. The variable BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS can be used to specify additional options passed to 'avbtool make_vbmeta_image'. Typical options to be used here include '--prop', '--prop_from_file', and '--chain_partition'. The variable BOARD_AVBTOOL_BOOT_ADD_HASH_FOOTER_ARGS can be used to specify additional options passed to 'avbtool add_hash_footer' for boot.img. Typical options to be used here include '--hash_algorithm' and '--salt'. The variable BOARD_AVBTOOL_SYSTEM_ADD_HASHTREE_FOOTER_ARGS can be used to specify additional options passed to 'avbtool add_hashtree_footer' for systems.img. Typical options to be used here include '--hash_algorithm', '--salt', and '--block_size'. BUG=31264226 TEST=Manually tested on edison-eng by inspecting {boot, system, vbmeta}.img in out/ directory as well as their counterparts in the IMAGES/ directory of edision-target_files-eng.zeuthen.zip Merged-In: Ic9a61cfc65c148b12996e57f04da5432eef6b982 Change-Id: I97042655bca15e7eac899f12c5bada2f6184d307 --- core/Makefile | 138 ++++++++++++++++--------- core/config.mk | 6 +- core/main.mk | 5 + tools/releasetools/add_img_to_target_files.py | 73 +++++++------- tools/releasetools/common.py | 140 +++++--------------------- 5 files changed, 163 insertions(+), 199 deletions(-) diff --git a/core/Makefile b/core/Makefile index 8fc35270b..7a1041a4f 100644 --- a/core/Makefile +++ b/core/Makefile @@ -516,28 +516,8 @@ 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 external/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 INTERNAL_BOOTIMAGE_FILES := $(filter-out --%,$(INTERNAL_BOOTIMAGE_ARGS)) @@ -577,28 +557,35 @@ ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true) endif endif -ifeq ($(BOARD_BVB_ENABLE),true) +# 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) +$(error TARGET_BOOTIMAGE_USE_EXT2 is not supported anymore) + +else ifeq (true,$(BOARD_AVB_ENABLE)) # TARGET_BOOTIMAGE_USE_EXT2 != true -$(INSTALLED_BOOTIMAGE_TARGET): $(BVBTOOL) $(INTERNAL_BOOTIMAGE_FILES) $(PRODUCT_OUT)/system.img +$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(AVBTOOL) $(INTERNAL_BOOTIMAGE_FILES) $(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) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@ $(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE)) + $(hide) $(AVBTOOL) add_hash_footer \ + --image $@ \ + --partition_size $(BOARD_BOOTIMAGE_PARTITION_SIZE) \ + --partition_name boot $(INTERNAL_AVB_SIGNING_ARGS) \ + $(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS) .PHONY: bootimage-nodeps -bootimage-nodeps: $(BVBTOOL) +bootimage-nodeps: $(MKBOOTIMG) $(AVBTOOL) @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) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(INSTALLED_BOOTIMAGE_TARGET) $(hide) $(call assert-max-image-size,$(INSTALLED_BOOTIMAGE_TARGET),$(BOARD_BOOTIMAGE_PARTITION_SIZE)) + $(hide) $(AVBTOOL) add_hash_footer \ + --image $@ \ + --partition_size $(BOARD_BOOTIMAGE_PARTITION_SIZE) \ + --partition_name boot $(INTERNAL_AVB_SIGNING_ARGS) \ + $(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS) -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) -$(error TARGET_BOOTIMAGE_USE_EXT2 is not supported anymore) -else ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_BOOT_SIGNER)) # TARGET_BOOTIMAGE_USE_EXT2 != true +else ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_BOOT_SIGNER)) # BOARD_AVB_ENABLE != true $(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES) $(BOOT_SIGNER) $(call pretty,"Target boot image: $@") @@ -643,7 +630,6 @@ 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 @@ -1194,13 +1180,15 @@ 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)) + $(if $(BOARD_AVB_ENABLE), \ + $(hide) $(AVBTOOL) add_hashtree_footer \ + --image $(1) \ + --partition_size $(BOARD_SYSTEMIMAGE_PARTITION_SIZE) \ + --partition_name system \ + $(INTERNAL_AVB_SIGNING_ARGS) \ + $(BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS)) endef -ifeq ($(BOARD_BVB_ENABLE),true) -FULL_SYSTEMIMAGE_DEPS += $(BVBTOOL) -endif - $(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE) $(BUILD_IMAGE_SRCS) $(call build-systemimage-target,$@) @@ -1515,6 +1503,60 @@ cacheimage-nodeps: | $(INTERNAL_USERIMAGES_DEPS) endif # BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE +# ----------------------------------------------------------------- +# vbmeta image +ifeq ($(BOARD_AVB_ENABLE),true) + +BUILT_VBMETAIMAGE_TARGET := $(PRODUCT_OUT)/vbmeta.img + +INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS := \ + --include_descriptors_from_image $(INSTALLED_BOOTIMAGE_TARGET) \ + --include_descriptors_from_image $(INSTALLED_SYSTEMIMAGE) \ + --generate_dm_verity_cmdline_from_hashtree $(INSTALLED_SYSTEMIMAGE) + +ifdef BOARD_AVB_ROLLBACK_INDEX +INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += --rollback_index $(BOARD_AVB_ROLLBACK_INDEX) +endif + +ifndef BOARD_AVB_KEY_PATH +# If key path isn't specified, use the 4096-bit test key. +INTERNAL_AVB_SIGNING_ARGS := \ + --algorithm SHA256_RSA4096 \ + --key external/avb/test/data/testkey_rsa4096.pem +else +INTERNAL_AVB_SIGNING_ARGS := \ + --algorithm $(BOARD_AVB_ALGORITHM) --key $(BOARD_AVB_KEY_PATH) +endif + +ifndef BOARD_BOOTIMAGE_PARTITION_SIZE + $(error BOARD_BOOTIMAGE_PARTITION_SIZE must be set for BOARD_AVB_ENABLE) +endif + +ifndef BOARD_SYSTEMIMAGE_PARTITION_SIZE + $(error BOARD_SYSTEMIMAGE_PARTITION_SIZE must be set for BOARD_AVB_ENABLE) +endif + +define build-vbmetaimage-target + $(call pretty,"Target vbmeta image: $(INSTALLED_VBMETAIMAGE_TARGET)") + $(hide) $(AVBTOOL) make_vbmeta_image \ + $(INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS) \ + $(INTERNAL_AVB_SIGNING_ARGS) \ + $(BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS) \ + --output $@ +endef + +INSTALLED_VBMETAIMAGE_TARGET := $(BUILT_VBMETAIMAGE_TARGET) +$(INSTALLED_VBMETAIMAGE_TARGET): $(AVBTOOL) $(INSTALLED_BOOTIMAGE_TARGET) $(INSTALLED_SYSTEMIMAGE) + $(build-vbmetaimage-target) + +.PHONY: vbmetaimage-nodeps +vbmetaimage-nodeps: + $(build-vbmetaimage-target) + +# We need $(AVBTOOL) for system.img generation. +FULL_SYSTEMIMAGE_DEPS += $(AVBTOOL) + +endif # BOARD_AVB_ENABLE # ----------------------------------------------------------------- # vendor partition image @@ -1898,14 +1940,14 @@ 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 +ifeq ($(BOARD_AVB_ENABLE),true) + $(hide) echo "board_avb_enable=true" >> $(zip_root)/META/misc_info.txt + $(hide) echo "board_avb_rollback_index=$(BOARD_AVB_ROLLBACK_INDEX)" >> $(zip_root)/META/misc_info.txt + $(hide) echo "board_avb_key_path=$(BOARD_AVB_KEY_PATH)" >> $(zip_root)/META/misc_info.txt + $(hide) echo "board_avb_algorithm=$(BOARD_AVB_ALGORITHM)" >> $(zip_root)/META/misc_info.txt + $(hide) echo "board_avb_boot_add_hash_footer_args=$(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS)" >> $(zip_root)/META/misc_info.txt + $(hide) echo "board_avb_system_add_hashtree_footer_args=$(BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS)" >> $(zip_root)/META/misc_info.txt + $(hide) echo "board_avb_make_vbmeta_image_args=$(BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS)" >> $(zip_root)/META/misc_info.txt endif ifdef BOARD_BPT_INPUT_FILES $(hide) echo "board_bpt_enable=true" >> $(zip_root)/META/misc_info.txt diff --git a/core/config.mk b/core/config.mk index 525b63980..1e3b4469f 100644 --- a/core/config.mk +++ b/core/config.mk @@ -549,10 +549,10 @@ BPTTOOL := $(HOST_OUT_EXECUTABLES)/bpttool$(HOST_EXECUTABLE_SUFFIX) else BPTTOOL := $(BOARD_CUSTOM_BPTTOOL) endif -ifeq (,$(strip $(BOARD_CUSTOM_BVBTOOL))) -BVBTOOL := $(HOST_OUT_EXECUTABLES)/bvbtool$(HOST_EXECUTABLE_SUFFIX) +ifeq (,$(strip $(BOARD_CUSTOM_AVBTOOL))) +AVBTOOL := $(HOST_OUT_EXECUTABLES)/avbtool$(HOST_EXECUTABLE_SUFFIX) else -BVBTOOL := $(BOARD_CUSTOM_BVBTOOL) +AVBTOOL := $(BOARD_CUSTOM_AVBTOOL) endif APICHECK := $(HOST_OUT_EXECUTABLES)/apicheck$(HOST_EXECUTABLE_SUFFIX) FS_GET_STATS := $(HOST_OUT_EXECUTABLES)/fs_get_stats$(HOST_EXECUTABLE_SUFFIX) diff --git a/core/main.mk b/core/main.mk index b20044ade..fee299569 100644 --- a/core/main.mk +++ b/core/main.mk @@ -82,6 +82,7 @@ dont_bother_goals := clean clobber dataclean installclean \ ramdisk-nodeps \ bootimage-nodeps \ recoveryimage-nodeps \ + vbmetaimage-nodeps \ product-graph dump-products ifneq ($(filter $(dont_bother_goals), $(MAKECMDGOALS)),) @@ -936,6 +937,9 @@ vendorimage: $(INSTALLED_VENDORIMAGE_TARGET) .PHONY: bootimage bootimage: $(INSTALLED_BOOTIMAGE_TARGET) +.PHONY: vbmetaimage +vbmetaimage: $(INSTALLED_VBMETAIMAGE_TARGET) + .PHONY: auxiliary auxiliary: $(INSTALLED_AUX_TARGETS) @@ -945,6 +949,7 @@ droidcore: files \ systemimage \ $(INSTALLED_BOOTIMAGE_TARGET) \ $(INSTALLED_RECOVERYIMAGE_TARGET) \ + $(INSTALLED_VBMETAIMAGE_TARGET) \ $(INSTALLED_USERDATAIMAGE_TARGET) \ $(INSTALLED_CACHEIMAGE_TARGET) \ $(INSTALLED_BPTIMAGE_TARGET) \ diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py index 5369c5b6b..8c5dbcfc9 100755 --- a/tools/releasetools/add_img_to_target_files.py +++ b/tools/releasetools/add_img_to_target_files.py @@ -96,18 +96,22 @@ def AddSystem(output_zip, prefix="IMAGES/", recovery_img=None, boot_img=None): imgname = BuildSystem(OPTIONS.input_tmp, OPTIONS.info_dict, block_list=block_list) - # If requested, calculate and add dm-verity integrity hashes and + # AVB: if enabled, 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 OPTIONS.info_dict.get("board_avb_enable", None) == "true": + avbtool = os.getenv('AVBTOOL') or "avbtool" + part_size = OPTIONS.info_dict.get("system_size", None) + cmd = [avbtool, "add_hashtree_footer", "--image", imgname, + "--partition_size", str(part_size), "--partition_name", "system"] + common.AppendAVBSigningArgs(cmd) + args = OPTIONS.info_dict.get("board_avb_system_add_hashtree_footer_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),) + assert p.returncode == 0, "avbtool add_hashtree_footer of %s failed" % ( + os.path.basename(OPTIONS.input_tmp)) common.ZipWrite(output_zip, imgname, prefix + "system.img") common.ZipWrite(output_zip, block_list, prefix + "system.map") @@ -251,6 +255,25 @@ def AddUserdata(output_zip, prefix="IMAGES/"): shutil.rmtree(temp_dir) +def AddVBMeta(output_zip, boot_img_path, system_img_path, prefix="IMAGES/"): + """Create a VBMeta image and store it in output_zip.""" + _, img_file_name = tempfile.mkstemp() + avbtool = os.getenv('AVBTOOL') or "avbtool" + cmd = [avbtool, "make_vbmeta_image", + "--output", img_file_name, + "--include_descriptors_from_image", boot_img_path, + "--include_descriptors_from_image", system_img_path, + "--generate_dm_verity_cmdline_from_hashtree", system_img_path] + common.AppendAVBSigningArgs(cmd) + args = OPTIONS.info_dict.get("board_avb_make_vbmeta_image_args", None) + if args and args.strip(): + cmd.extend(shlex.split(args)) + p = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + p.communicate() + assert p.returncode == 0, "avbtool make_vbmeta_image failed" + common.ZipWrite(output_zip, img_file_name, prefix + "vbmeta.img") + + def AddPartitionTable(output_zip, prefix="IMAGES/"): """Create a partition table image and store it in output_zip.""" @@ -346,15 +369,6 @@ def AddImagesToTargetFiles(filename): 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" @@ -368,17 +382,11 @@ def AddImagesToTargetFiles(filename): 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( + banner("boot") + boot_image = common.GetBootableImage( "IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT") - if boot_image: - boot_image.AddToZip(output_zip) + if boot_image: + boot_image.AddToZip(output_zip) recovery_image = None if has_recovery: @@ -399,15 +407,6 @@ def AddImagesToTargetFiles(filename): banner("system") 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) @@ -419,6 +418,10 @@ def AddImagesToTargetFiles(filename): if OPTIONS.info_dict.get("board_bpt_enable", None) == "true": banner("partition-table") AddPartitionTable(output_zip) + if OPTIONS.info_dict.get("board_avb_enable", None) == "true": + banner("vbmeta") + boot_contents = boot_image.WriteToTemp() + AddVBMeta(output_zip, boot_contents.name, system_img_path) # For devices using A/B update, copy over images from RADIO/ and/or # VENDOR_IMAGES/ to IMAGES/ and make sure we have all the needed diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py index 3f3b0119f..564cd1788 100644 --- a/tools/releasetools/common.py +++ b/tools/releasetools/common.py @@ -384,6 +384,16 @@ def DumpInfoDict(d): print "%-25s = (%s) %s" % (k, type(v).__name__, v) +def AppendAVBSigningArgs(cmd): + """Append signing arguments for avbtool.""" + keypath = OPTIONS.info_dict.get("board_avb_key_path", None) + algorithm = OPTIONS.info_dict.get("board_avb_algorithm", None) + if not keypath or not algorithm: + algorithm = "SHA256_RSA4096" + keypath = "external/avb/test/data/testkey_rsa4096.pem" + cmd.extend(["--key", keypath, "--algorithm", algorithm]) + + def _BuildBootableImage(sourcedir, fs_config_file, info_dict=None, has_ramdisk=False): """Build a bootable image from the specified sourcedir. @@ -503,111 +513,20 @@ def _BuildBootableImage(sourcedir, fs_config_file, info_dict=None, img_unsigned.close() img_keyblock.close() - img.seek(os.SEEK_SET, 0) - data = img.read() - - if has_ramdisk: - ramdisk_img.close() - img.close() - - 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", "external/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),) + # AVB: if enabled, calculate and add hash to boot.img. + if OPTIONS.info_dict.get("board_avb_enable", None) == "true": + avbtool = os.getenv('AVBTOOL') or "avbtool" + part_size = OPTIONS.info_dict.get("boot_size", None) + cmd = [avbtool, "add_hash_footer", "--image", img.name, + "--partition_size", str(part_size), "--partition_name", "boot"] + AppendAVBSigningArgs(cmd) + args = OPTIONS.info_dict.get("board_avb_boot_add_hash_footer_args", None) + if args and args.strip(): + cmd.extend(shlex.split(args)) + p = Run(cmd, stdout=subprocess.PIPE) + p.communicate() + assert p.returncode == 0, "avbtool add_hash_footer of %s failed" % ( + os.path.basename(OPTIONS.input_tmp)) img.seek(os.SEEK_SET, 0) data = img.read() @@ -650,14 +569,9 @@ 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) + data = _BuildBootableImage(os.path.join(unpack_dir, tree_subdir), + os.path.join(unpack_dir, fs_config), + info_dict, has_ramdisk) if data: return File(name, data) return None -- 2.11.0