Merge changes from topic "gki-avb-vts"
* changes:
releasetools: Android T GKI certification scheme
Android T GKI certification scheme
diff --git a/core/Makefile b/core/Makefile
index a283380..c45fc15 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -901,9 +901,11 @@
INTERNAL_INIT_BOOT_IMAGE_ARGS :=
+INTERNAL_BOOT_HAS_RAMDISK :=
ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
ifneq ($(BUILDING_INIT_BOOT_IMAGE),true)
INTERNAL_BOOTIMAGE_ARGS += --ramdisk $(INSTALLED_RAMDISK_TARGET)
+ INTERNAL_BOOT_HAS_RAMDISK := true
else
INTERNAL_INIT_BOOT_IMAGE_ARGS += --ramdisk $(INSTALLED_RAMDISK_TARGET)
endif
@@ -952,21 +954,48 @@
--os_version $(PLATFORM_VERSION_LAST_STABLE) \
--os_patch_level $(PLATFORM_SECURITY_PATCH)
-ifdef BOARD_GKI_SIGNING_KEY_PATH
-ifndef BOARD_GKI_SIGNING_ALGORITHM
-$(error BOARD_GKI_SIGNING_ALGORITHM should be defined with BOARD_GKI_SIGNING_KEY_PATH)
-endif
-INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS := \
- --gki_signing_key $(BOARD_GKI_SIGNING_KEY_PATH) \
- --gki_signing_algorithm $(BOARD_GKI_SIGNING_ALGORITHM) \
- --gki_signing_avbtool_path $(AVBTOOL)
-endif
+# $(1): image target to certify
+# $(2): out certificate target
+# $(3): image name
+# $(4): additional AVB arguments
+define generate_generic_boot_image_certificate
+ rm -rf "$(2)"
+ mkdir -p "$(dir $(2))"
+ $(GENERATE_GKI_CERTIFICATE) $(INTERNAL_GKI_CERTIFICATE_ARGS) \
+ --additional_avb_args "$(4)" \
+ --name "$(3)" --output "$(2)" "$(1)"
+endef
-# Using double quote to pass BOARD_GKI_SIGNING_SIGNATURE_ARGS as a single string
-# to MKBOOTIMG, although it may contain multiple args.
-ifdef BOARD_GKI_SIGNING_SIGNATURE_ARGS
-INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS += \
- --gki_signing_signature_args "$(BOARD_GKI_SIGNING_SIGNATURE_ARGS)"
+INTERNAL_GKI_CERTIFICATE_ARGS :=
+INTERNAL_GKI_CERTIFICATE_DEPS :=
+INTERNAL_GENERIC_RAMDISK_BOOT_SIGNATURE :=
+ifdef BOARD_GKI_SIGNING_KEY_PATH
+ ifndef BOARD_GKI_SIGNING_ALGORITHM
+ $(error BOARD_GKI_SIGNING_ALGORITHM should be defined with BOARD_GKI_SIGNING_KEY_PATH)
+ endif
+
+ INTERNAL_GKI_CERTIFICATE_ARGS := \
+ --key "$(BOARD_GKI_SIGNING_KEY_PATH)" \
+ --algorithm "$(BOARD_GKI_SIGNING_ALGORITHM)" \
+ --avbtool "$(AVBTOOL)"
+
+ # Quote and pass BOARD_GKI_SIGNING_SIGNATURE_ARGS as a single string argument.
+ ifdef BOARD_GKI_SIGNING_SIGNATURE_ARGS
+ INTERNAL_GKI_CERTIFICATE_ARGS += --additional_avb_args "$(BOARD_GKI_SIGNING_SIGNATURE_ARGS)"
+ endif
+
+ INTERNAL_GKI_CERTIFICATE_DEPS := \
+ $(GENERATE_GKI_CERTIFICATE) \
+ $(BOARD_GKI_SIGNING_KEY_PATH) \
+ $(AVBTOOL)
+
+ ifdef INSTALLED_RAMDISK_TARGET
+ INTERNAL_GENERIC_RAMDISK_BOOT_SIGNATURE := \
+ $(call intermediates-dir-for,PACKAGING,generic_ramdisk)/boot_signature
+
+ $(INTERNAL_GENERIC_RAMDISK_BOOT_SIGNATURE): $(INSTALLED_RAMDISK_TARGET) $(INTERNAL_GKI_CERTIFICATE_DEPS)
+ $(call generate_generic_boot_image_certificate,$(INSTALLED_RAMDISK_TARGET),$@,generic_ramdisk,$(BOARD_AVB_INIT_BOOT_ADD_HASH_FOOTER_ARGS))
+ endif
endif
# Define these only if we are building boot
@@ -983,8 +1012,15 @@
# $1: boot image target
define build_boot_board_avb_enabled
- $(MKBOOTIMG) --kernel $(call bootimage-to-kernel,$(1)) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) \
- $(INTERNAL_MKBOOTIMG_GKI_SINGING_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(1)
+ $(eval kernel := $(call bootimage-to-kernel,$(1)))
+ $(if $(BOARD_GKI_SIGNING_KEY_PATH), \
+ $(eval kernel_signature := $(call intermediates-dir-for,PACKAGING,generic_kernel)/$(notdir $(kernel)).boot_signature) \
+ $(call generate_generic_boot_image_certificate,$(kernel),$(kernel_signature),generic_kernel,$(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS)) $(newline) \
+ $(if $(INTERNAL_BOOT_HAS_RAMDISK), \
+ cat $(INTERNAL_GENERIC_RAMDISK_BOOT_SIGNATURE) >> $(kernel_signature) $(newline)))
+ $(MKBOOTIMG) --kernel $(kernel) $(INTERNAL_BOOTIMAGE_ARGS) \
+ $(if $(BOARD_GKI_SIGNING_KEY_PATH),--boot_signature "$(kernel_signature)",$(INTERNAL_MKBOOTIMG_VERSION_ARGS)) \
+ $(BOARD_MKBOOTIMG_ARGS) --output $(1)
$(call assert-max-image-size,$(1),$(call get-hash-image-max-size,$(call get-bootimage-partition-size,$(1),boot)))
$(AVBTOOL) add_hash_footer \
--image $(1) \
@@ -993,12 +1029,15 @@
$(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS)
endef
-$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(AVBTOOL) $(INTERNAL_BOOTIMAGE_FILES) $(BOARD_AVB_BOOT_KEY_PATH) $(BOARD_GKI_SIGNING_KEY_PATH)
+ifdef INTERNAL_BOOT_HAS_RAMDISK
+$(INSTALLED_BOOTIMAGE_TARGET): $(INTERNAL_GENERIC_RAMDISK_BOOT_SIGNATURE)
+endif
+$(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(AVBTOOL) $(INTERNAL_BOOTIMAGE_FILES) $(BOARD_AVB_BOOT_KEY_PATH) $(INTERNAL_GKI_CERTIFICATE_DEPS)
$(call pretty,"Target boot image: $@")
$(call build_boot_board_avb_enabled,$@)
.PHONY: bootimage-nodeps
-bootimage-nodeps: $(MKBOOTIMG) $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH) $(BOARD_GKI_SIGNING_KEY_PATH)
+bootimage-nodeps: $(MKBOOTIMG) $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH) $(INTERNAL_GKI_CERTIFICATE_DEPS)
@echo "make $@: ignoring dependencies"
$(foreach b,$(INSTALLED_BOOTIMAGE_TARGET),$(call build_boot_board_avb_enabled,$(b)))
@@ -1097,9 +1136,12 @@
endif
ifeq ($(BOARD_AVB_ENABLE),true)
+$(INSTALLED_INIT_BOOT_IMAGE_TARGET): $(INTERNAL_GENERIC_RAMDISK_BOOT_SIGNATURE)
$(INSTALLED_INIT_BOOT_IMAGE_TARGET): $(AVBTOOL) $(BOARD_AVB_INIT_BOOT_KEY_PATH)
$(call pretty,"Target init_boot image: $@")
- $(MKBOOTIMG) $(INTERNAL_INIT_BOOT_IMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_INIT_ARGS) --output $@
+ $(MKBOOTIMG) $(INTERNAL_INIT_BOOT_IMAGE_ARGS) \
+ $(if $(BOARD_GKI_SIGNING_KEY_PATH),--boot_signature "$(INTERNAL_GENERIC_RAMDISK_BOOT_SIGNATURE)",$(INTERNAL_MKBOOTIMG_VERSION_ARGS)) \
+ $(BOARD_MKBOOTIMG_INIT_ARGS) --output "$@"
$(call assert-max-image-size,$@,$(BOARD_INIT_BOOT_IMAGE_PARTITION_SIZE))
$(AVBTOOL) add_hash_footer \
--image $@ \
@@ -3774,6 +3816,13 @@
--prop com.android.build.pvmfw.security_patch:$(PVMFW_SECURITY_PATCH)
endif
+# For upgrading devices without a init_boot partition, the init_boot footer args
+# should fallback to boot partition footer.
+ifndef INSTALLED_INIT_BOOT_IMAGE_TARGET
+BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS += \
+ $(BOARD_AVB_INIT_BOOT_ADD_HASH_FOOTER_ARGS)
+endif
+
BOOT_FOOTER_ARGS := BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS
INIT_BOOT_FOOTER_ARGS := BOARD_AVB_INIT_BOOT_ADD_HASH_FOOTER_ARGS
VENDOR_BOOT_FOOTER_ARGS := BOARD_AVB_VENDOR_BOOT_ADD_HASH_FOOTER_ARGS
@@ -4485,6 +4534,7 @@
fec \
fsck.f2fs \
fs_config \
+ generate_gki_certificate \
generate_verity_key \
host_init_verifier \
img2simg \
diff --git a/core/config.mk b/core/config.mk
index 3c7c5ce..6a50738 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -593,6 +593,7 @@
MKBOOTFS := $(HOST_OUT_EXECUTABLES)/mkbootfs$(HOST_EXECUTABLE_SUFFIX)
MINIGZIP := $(HOST_OUT_EXECUTABLES)/minigzip$(HOST_EXECUTABLE_SUFFIX)
LZ4 := $(HOST_OUT_EXECUTABLES)/lz4$(HOST_EXECUTABLE_SUFFIX)
+GENERATE_GKI_CERTIFICATE := $(HOST_OUT_EXECUTABLES)/generate_gki_certificate$(HOST_EXECUTABLE_SUFFIX)
ifeq (,$(strip $(BOARD_CUSTOM_MKBOOTIMG)))
MKBOOTIMG := $(HOST_OUT_EXECUTABLES)/mkbootimg$(HOST_EXECUTABLE_SUFFIX)
else
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index f3123b2..7b2c290 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -162,6 +162,7 @@
required: [
"brillo_update_payload",
"checkvintf",
+ "generate_gki_certificate",
"minigzip",
"lz4",
"toybox",
@@ -236,6 +237,7 @@
"boot_signer",
"brotli",
"bsdiff",
+ "generate_gki_certificate",
"imgdiff",
"minigzip",
"lz4",
@@ -301,6 +303,7 @@
"brotli",
"bsdiff",
"deapexer",
+ "generate_gki_certificate",
"imgdiff",
"minigzip",
"lz4",
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 30dcf5b..e5c68bc 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -1396,34 +1396,52 @@
return "{}:{}:{}".format(partition, rollback_index_location, pubkey_path)
-def AppendGkiSigningArgs(cmd):
- """Append GKI signing arguments for mkbootimg."""
- # e.g., --gki_signing_key path/to/signing_key
- # --gki_signing_algorithm SHA256_RSA4096"
+def _HasGkiCertificationArgs():
+ return ("gki_signing_key_path" in OPTIONS.info_dict and
+ "gki_signing_algorithm" in OPTIONS.info_dict)
+
+def _GenerateGkiCertificate(image, image_name, partition_name):
key_path = OPTIONS.info_dict.get("gki_signing_key_path")
- # It's fine that a non-GKI boot.img has no gki_signing_key_path.
- if not key_path:
- return
+ algorithm = OPTIONS.info_dict.get("gki_signing_algorithm")
if not os.path.exists(key_path) and OPTIONS.search_path:
new_key_path = os.path.join(OPTIONS.search_path, key_path)
if os.path.exists(new_key_path):
key_path = new_key_path
- # Checks key_path exists, before appending --gki_signing_* args.
+ # Checks key_path exists, before processing --gki_signing_* args.
if not os.path.exists(key_path):
raise ExternalError(
'gki_signing_key_path: "{}" not found'.format(key_path))
- algorithm = OPTIONS.info_dict.get("gki_signing_algorithm")
- if key_path and algorithm:
- cmd.extend(["--gki_signing_key", key_path,
- "--gki_signing_algorithm", algorithm])
+ output_certificate = tempfile.NamedTemporaryFile()
+ cmd = [
+ "generate_gki_certificate",
+ "--name", image_name,
+ "--algorithm", algorithm,
+ "--key", key_path,
+ "--output", output_certificate.name,
+ image,
+ ]
- signature_args = OPTIONS.info_dict.get("gki_signing_signature_args")
- if signature_args:
- cmd.extend(["--gki_signing_signature_args", signature_args])
+ signature_args = OPTIONS.info_dict.get("gki_signing_signature_args", "")
+ signature_args = signature_args.strip()
+ if signature_args:
+ cmd.extend(["--additional_avb_args", signature_args])
+
+ args = OPTIONS.info_dict.get(
+ "avb_" + partition_name + "_add_hash_footer_args", "")
+ args = args.strip()
+ if args:
+ cmd.extend(["--additional_avb_args", args])
+
+ RunAndCheckOutput(cmd)
+
+ output_certificate.seek(os.SEEK_SET, 0)
+ data = output_certificate.read()
+ output_certificate.close()
+ return data
def BuildVBMeta(image_path, partitions, name, needed_partitions):
@@ -1549,6 +1567,8 @@
if kernel and not os.access(os.path.join(sourcedir, kernel), os.F_OK):
return None
+ kernel_path = os.path.join(sourcedir, kernel) if kernel else None
+
if has_ramdisk and not os.access(os.path.join(sourcedir, "RAMDISK"), os.F_OK):
return None
@@ -1563,8 +1583,8 @@
mkbootimg = os.getenv('MKBOOTIMG') or "mkbootimg"
cmd = [mkbootimg]
- if kernel:
- cmd += ["--kernel", os.path.join(sourcedir, kernel)]
+ if kernel_path is not None:
+ cmd.extend(["--kernel", kernel_path])
fn = os.path.join(sourcedir, "second")
if os.access(fn, os.F_OK):
@@ -1604,15 +1624,31 @@
if args and args.strip():
cmd.extend(shlex.split(args))
- args = info_dict.get("mkbootimg_version_args")
- if args and args.strip():
- cmd.extend(shlex.split(args))
+ boot_signature = None
+ if _HasGkiCertificationArgs():
+ # Certify GKI images.
+ boot_signature_bytes = b''
+ if kernel_path is not None:
+ boot_signature_bytes += _GenerateGkiCertificate(
+ kernel_path, "generic_kernel", "boot")
+ if has_ramdisk:
+ boot_signature_bytes += _GenerateGkiCertificate(
+ ramdisk_img.name, "generic_ramdisk", "init_boot")
+
+ if len(boot_signature_bytes) > 0:
+ boot_signature = tempfile.NamedTemporaryFile()
+ boot_signature.write(boot_signature_bytes)
+ boot_signature.flush()
+ cmd.extend(["--boot_signature", boot_signature.name])
+ else:
+ # Certified GKI boot/init_boot image mustn't set 'mkbootimg_version_args'.
+ args = info_dict.get("mkbootimg_version_args")
+ if args and args.strip():
+ cmd.extend(shlex.split(args))
if has_ramdisk:
cmd.extend(["--ramdisk", ramdisk_img.name])
- AppendGkiSigningArgs(cmd)
-
img_unsigned = None
if info_dict.get("vboot"):
img_unsigned = tempfile.NamedTemporaryFile()
@@ -1690,6 +1726,9 @@
ramdisk_img.close()
img.close()
+ if boot_signature is not None:
+ boot_signature.close()
+
return data
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index e42d417..7dd365f 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -1631,66 +1631,7 @@
self.assertEqual('3', chained_partition_args[1])
self.assertTrue(os.path.exists(chained_partition_args[2]))
- @test_utils.SkipIfExternalToolsUnavailable()
- def test_AppendGkiSigningArgs_NoSigningKeyPath(self):
- # A non-GKI boot.img has no gki_signing_key_path.
- common.OPTIONS.info_dict = {
- # 'gki_signing_key_path': pubkey,
- 'gki_signing_algorithm': 'SHA256_RSA4096',
- 'gki_signing_signature_args': '--prop foo:bar',
- }
-
- # Tests no --gki_signing_* args are appended if there is no
- # gki_signing_key_path.
- cmd = ['mkbootimg', '--header_version', '4']
- expected_cmd = ['mkbootimg', '--header_version', '4']
- common.AppendGkiSigningArgs(cmd)
- self.assertEqual(cmd, expected_cmd)
-
- def test_AppendGkiSigningArgs_NoSigningAlgorithm(self):
- pubkey = os.path.join(self.testdata_dir, 'testkey_gki.pem')
- with open(pubkey, 'wb') as f:
- f.write(b'\x00' * 100)
- self.assertTrue(os.path.exists(pubkey))
-
- # Tests no --gki_signing_* args are appended if there is no
- # gki_signing_algorithm.
- common.OPTIONS.info_dict = {
- 'gki_signing_key_path': pubkey,
- # 'gki_signing_algorithm': 'SHA256_RSA4096',
- 'gki_signing_signature_args': '--prop foo:bar',
- }
-
- cmd = ['mkbootimg', '--header_version', '4']
- expected_cmd = ['mkbootimg', '--header_version', '4']
- common.AppendGkiSigningArgs(cmd)
- self.assertEqual(cmd, expected_cmd)
-
- @test_utils.SkipIfExternalToolsUnavailable()
- def test_AppendGkiSigningArgs(self):
- pubkey = os.path.join(self.testdata_dir, 'testkey_gki.pem')
- with open(pubkey, 'wb') as f:
- f.write(b'\x00' * 100)
- self.assertTrue(os.path.exists(pubkey))
-
- common.OPTIONS.info_dict = {
- 'gki_signing_key_path': pubkey,
- 'gki_signing_algorithm': 'SHA256_RSA4096',
- 'gki_signing_signature_args': '--prop foo:bar',
- }
- cmd = ['mkbootimg', '--header_version', '4']
- common.AppendGkiSigningArgs(cmd)
-
- expected_cmd = [
- 'mkbootimg', '--header_version', '4',
- '--gki_signing_key', pubkey,
- '--gki_signing_algorithm', 'SHA256_RSA4096',
- '--gki_signing_signature_args', '--prop foo:bar'
- ]
- self.assertEqual(cmd, expected_cmd)
-
- @test_utils.SkipIfExternalToolsUnavailable()
- def test_AppendGkiSigningArgs_KeyPathNotFound(self):
+ def test_GenerateGkiCertificate_KeyPathNotFound(self):
pubkey = os.path.join(self.testdata_dir, 'no_testkey_gki.pem')
self.assertFalse(os.path.exists(pubkey))
@@ -1699,41 +1640,11 @@
'gki_signing_algorithm': 'SHA256_RSA4096',
'gki_signing_signature_args': '--prop foo:bar',
}
- cmd = ['mkbootimg', '--header_version', '4']
- self.assertRaises(common.ExternalError, common.AppendGkiSigningArgs, cmd)
+ test_file = tempfile.NamedTemporaryFile()
+ self.assertRaises(common.ExternalError, common._GenerateGkiCertificate,
+ test_file.name, 'generic_kernel', 'boot')
- @test_utils.SkipIfExternalToolsUnavailable()
- def test_AppendGkiSigningArgs_SearchKeyPath(self):
- pubkey = 'testkey_gki.pem'
- self.assertFalse(os.path.exists(pubkey))
-
- # Tests it should replace the pubkey with an existed key under
- # OPTIONS.search_path, i.e., os.path.join(OPTIONS.search_path, pubkey).
- search_path_dir = common.MakeTempDir()
- search_pubkey = os.path.join(search_path_dir, pubkey)
- with open(search_pubkey, 'wb') as f:
- f.write(b'\x00' * 100)
- self.assertTrue(os.path.exists(search_pubkey))
-
- common.OPTIONS.search_path = search_path_dir
- common.OPTIONS.info_dict = {
- 'gki_signing_key_path': pubkey,
- 'gki_signing_algorithm': 'SHA256_RSA4096',
- 'gki_signing_signature_args': '--prop foo:bar',
- }
- cmd = ['mkbootimg', '--header_version', '4']
- common.AppendGkiSigningArgs(cmd)
-
- expected_cmd = [
- 'mkbootimg', '--header_version', '4',
- '--gki_signing_key', search_pubkey,
- '--gki_signing_algorithm', 'SHA256_RSA4096',
- '--gki_signing_signature_args', '--prop foo:bar'
- ]
- self.assertEqual(cmd, expected_cmd)
-
- @test_utils.SkipIfExternalToolsUnavailable()
- def test_AppendGkiSigningArgs_SearchKeyPathNotFound(self):
+ def test_GenerateGkiCertificate_SearchKeyPathNotFound(self):
pubkey = 'no_testkey_gki.pem'
self.assertFalse(os.path.exists(pubkey))
@@ -1749,9 +1660,9 @@
'gki_signing_algorithm': 'SHA256_RSA4096',
'gki_signing_signature_args': '--prop foo:bar',
}
- cmd = ['mkbootimg', '--header_version', '4']
- self.assertRaises(common.ExternalError, common.AppendGkiSigningArgs, cmd)
-
+ test_file = tempfile.NamedTemporaryFile()
+ self.assertRaises(common.ExternalError, common._GenerateGkiCertificate,
+ test_file.name, 'generic_kernel', 'boot')
class InstallRecoveryScriptFormatTest(test_utils.ReleaseToolsTestCase):
"""Checks the format of install-recovery.sh.