Also install verity_key to ramdisk for non-system-as-root target.
The commit in d14b895665
(https://android-review.googlesource.com/c/platform/build/+/728287)
changed partition layout, to always build the root dir into system.img,
even for devices not using system-as-root (i.e. the ones with separate
boot ramdisk).
With the new layout, there will be two root dirs for non-system-as-root
targets during the boot. If such a device uses Verified Boot 1.0,
/verity_key needs to be available in both roots, to establish the chain
of trust.
- bootloader uses the baked-in key to verify boot.img; it then loads
the ramdisk from the verified boot.img
- First stage init uses /verity_key (in ramdisk) to verify and mount
system.img at /system, then chroot's to it
- Second stage init uses /verity_key (in system.img) to verify and
mount other partitions
This CL adds rules to additionally install verity_key into ramdisk for
such targets.
Bug: 139770257
Test: Set up a target to use non-system-as-root
(BOARD_BUILD_SYSTEM_ROOT_IMAGE != true). `m dist`.
Test: Check that both ROOT/verity_key and BOOT/RAMDISK/verity_key exist
in the built target_files.zip.
Test: Run validate_target_files to validate the above target_files.zip.
$ validate_target_files \
--verity_key_mincrypt /path/to/verity_key \
target_files.zip
Test: Run sign_target_files_apks to sign the above target. Re-run
validate_target_files on the signed target_files.zip.
Test: python -m unittest test_validate_target_files
Change-Id: Ibe7e771c8c376429add85851ac86055564765d3c
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
#######################################
|
||||
# verity_key
|
||||
# verity_key (installed to /, i.e. part of system.img)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := verity_key
|
||||
@@ -9,8 +9,28 @@ LOCAL_SRC_FILES := $(LOCAL_MODULE)
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
|
||||
|
||||
# For devices using a separate ramdisk, we need a copy there to establish the chain of trust.
|
||||
ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
|
||||
LOCAL_REQUIRED_MODULES := verity_key_ramdisk
|
||||
endif
|
||||
|
||||
include $(BUILD_PREBUILT)
|
||||
|
||||
#######################################
|
||||
# verity_key (installed to ramdisk)
|
||||
#
|
||||
# Enabling the target when using system-as-root would cause build failure, as TARGET_RAMDISK_OUT
|
||||
# points to the same location as TARGET_ROOT_OUT.
|
||||
ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := verity_key_ramdisk
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
LOCAL_SRC_FILES := verity_key
|
||||
LOCAL_MODULE_STEM := verity_key
|
||||
LOCAL_MODULE_PATH := $(TARGET_RAMDISK_OUT)
|
||||
include $(BUILD_PREBUILT)
|
||||
endif
|
||||
|
||||
#######################################
|
||||
# adb key, if configured via PRODUCT_ADB_KEYS
|
||||
ifdef PRODUCT_ADB_KEYS
|
||||
|
@@ -602,11 +602,16 @@ def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info,
|
||||
ReplaceVerityPrivateKey(misc_info, OPTIONS.replace_verity_private_key[1])
|
||||
|
||||
if OPTIONS.replace_verity_public_key:
|
||||
dest = "ROOT/verity_key" if system_root_image else "BOOT/RAMDISK/verity_key"
|
||||
# We are replacing the one in boot image only, since the one under
|
||||
# recovery won't ever be needed.
|
||||
# Replace the one in root dir in system.img.
|
||||
ReplaceVerityPublicKey(
|
||||
output_tf_zip, dest, OPTIONS.replace_verity_public_key[1])
|
||||
output_tf_zip, 'ROOT/verity_key', OPTIONS.replace_verity_public_key[1])
|
||||
|
||||
if not system_root_image:
|
||||
# Additionally replace the copy in ramdisk if not using system-as-root.
|
||||
ReplaceVerityPublicKey(
|
||||
output_tf_zip,
|
||||
'BOOT/RAMDISK/verity_key',
|
||||
OPTIONS.replace_verity_public_key[1])
|
||||
|
||||
# Replace the keyid string in BOOT/cmdline.
|
||||
if OPTIONS.replace_verity_keyid:
|
||||
|
@@ -143,20 +143,51 @@ class ValidateTargetFilesTest(test_utils.ReleaseToolsTestCase):
|
||||
verity_image_builder.Build(output_file)
|
||||
|
||||
@test_utils.SkipIfExternalToolsUnavailable()
|
||||
def test_ValidateVerifiedBootImages_systemImage(self):
|
||||
def test_ValidateVerifiedBootImages_systemRootImage(self):
|
||||
input_tmp = common.MakeTempDir()
|
||||
os.mkdir(os.path.join(input_tmp, 'IMAGES'))
|
||||
system_image = os.path.join(input_tmp, 'IMAGES', 'system.img')
|
||||
self._generate_system_image(system_image)
|
||||
|
||||
# Pack the verity key.
|
||||
verity_key_mincrypt = os.path.join(
|
||||
input_tmp, 'BOOT', 'RAMDISK', 'verity_key')
|
||||
verity_key_mincrypt = os.path.join(input_tmp, 'ROOT', 'verity_key')
|
||||
os.makedirs(os.path.dirname(verity_key_mincrypt))
|
||||
shutil.copyfile(
|
||||
os.path.join(self.testdata_dir, 'testkey_mincrypt'),
|
||||
verity_key_mincrypt)
|
||||
|
||||
info_dict = {
|
||||
'system_root_image' : 'true',
|
||||
'verity' : 'true',
|
||||
}
|
||||
options = {
|
||||
'verity_key' : os.path.join(self.testdata_dir, 'testkey.x509.pem'),
|
||||
'verity_key_mincrypt' : verity_key_mincrypt,
|
||||
}
|
||||
ValidateVerifiedBootImages(input_tmp, info_dict, options)
|
||||
|
||||
@test_utils.SkipIfExternalToolsUnavailable()
|
||||
def test_ValidateVerifiedBootImages_nonSystemRootImage(self):
|
||||
input_tmp = common.MakeTempDir()
|
||||
os.mkdir(os.path.join(input_tmp, 'IMAGES'))
|
||||
system_image = os.path.join(input_tmp, 'IMAGES', 'system.img')
|
||||
self._generate_system_image(system_image)
|
||||
|
||||
# Pack the verity key into the root dir in system.img.
|
||||
verity_key_mincrypt = os.path.join(input_tmp, 'ROOT', 'verity_key')
|
||||
os.makedirs(os.path.dirname(verity_key_mincrypt))
|
||||
shutil.copyfile(
|
||||
os.path.join(self.testdata_dir, 'testkey_mincrypt'),
|
||||
verity_key_mincrypt)
|
||||
|
||||
# And a copy in ramdisk.
|
||||
verity_key_ramdisk = os.path.join(
|
||||
input_tmp, 'BOOT', 'RAMDISK', 'verity_key')
|
||||
os.makedirs(os.path.dirname(verity_key_ramdisk))
|
||||
shutil.copyfile(
|
||||
os.path.join(self.testdata_dir, 'testkey_mincrypt'),
|
||||
verity_key_ramdisk)
|
||||
|
||||
info_dict = {
|
||||
'verity' : 'true',
|
||||
}
|
||||
@@ -166,6 +197,39 @@ class ValidateTargetFilesTest(test_utils.ReleaseToolsTestCase):
|
||||
}
|
||||
ValidateVerifiedBootImages(input_tmp, info_dict, options)
|
||||
|
||||
@test_utils.SkipIfExternalToolsUnavailable()
|
||||
def test_ValidateVerifiedBootImages_nonSystemRootImage_mismatchingKeys(self):
|
||||
input_tmp = common.MakeTempDir()
|
||||
os.mkdir(os.path.join(input_tmp, 'IMAGES'))
|
||||
system_image = os.path.join(input_tmp, 'IMAGES', 'system.img')
|
||||
self._generate_system_image(system_image)
|
||||
|
||||
# Pack the verity key into the root dir in system.img.
|
||||
verity_key_mincrypt = os.path.join(input_tmp, 'ROOT', 'verity_key')
|
||||
os.makedirs(os.path.dirname(verity_key_mincrypt))
|
||||
shutil.copyfile(
|
||||
os.path.join(self.testdata_dir, 'testkey_mincrypt'),
|
||||
verity_key_mincrypt)
|
||||
|
||||
# And an invalid copy in ramdisk.
|
||||
verity_key_ramdisk = os.path.join(
|
||||
input_tmp, 'BOOT', 'RAMDISK', 'verity_key')
|
||||
os.makedirs(os.path.dirname(verity_key_ramdisk))
|
||||
shutil.copyfile(
|
||||
os.path.join(self.testdata_dir, 'verity_mincrypt'),
|
||||
verity_key_ramdisk)
|
||||
|
||||
info_dict = {
|
||||
'verity' : 'true',
|
||||
}
|
||||
options = {
|
||||
'verity_key' : os.path.join(self.testdata_dir, 'testkey.x509.pem'),
|
||||
'verity_key_mincrypt' : verity_key_mincrypt,
|
||||
}
|
||||
self.assertRaises(
|
||||
AssertionError, ValidateVerifiedBootImages, input_tmp, info_dict,
|
||||
options)
|
||||
|
||||
@test_utils.SkipIfExternalToolsUnavailable()
|
||||
def test_ValidateFileConsistency_incompleteRange(self):
|
||||
input_tmp = common.MakeTempDir()
|
||||
|
@@ -276,15 +276,12 @@ def ValidateVerifiedBootImages(input_tmp, info_dict, options):
|
||||
# Verify verity signed system images in Verified Boot 1.0. Note that not using
|
||||
# 'elif' here, since 'boot_signer' and 'verity' are not bundled in VB 1.0.
|
||||
if info_dict.get('verity') == 'true':
|
||||
# First verify that the verity key that's built into the root image (as
|
||||
# /verity_key) matches the one given via command line, if any.
|
||||
if info_dict.get("system_root_image") == "true":
|
||||
verity_key_mincrypt = os.path.join(input_tmp, 'ROOT', 'verity_key')
|
||||
else:
|
||||
verity_key_mincrypt = os.path.join(
|
||||
input_tmp, 'BOOT', 'RAMDISK', 'verity_key')
|
||||
# First verify that the verity key is built into the root image (regardless
|
||||
# of system-as-root).
|
||||
verity_key_mincrypt = os.path.join(input_tmp, 'ROOT', 'verity_key')
|
||||
assert os.path.exists(verity_key_mincrypt), 'Missing verity_key'
|
||||
|
||||
# Verify /verity_key matches the one given via command line, if any.
|
||||
if options['verity_key_mincrypt'] is None:
|
||||
logging.warn(
|
||||
'Skipped checking the content of /verity_key, as the key file not '
|
||||
@@ -295,6 +292,18 @@ def ValidateVerifiedBootImages(input_tmp, info_dict, options):
|
||||
"Mismatching mincrypt verity key files"
|
||||
logging.info('Verified the content of /verity_key')
|
||||
|
||||
# For devices with a separate ramdisk (i.e. non-system-as-root), there must
|
||||
# be a copy in ramdisk.
|
||||
if info_dict.get("system_root_image") != "true":
|
||||
verity_key_ramdisk = os.path.join(
|
||||
input_tmp, 'BOOT', 'RAMDISK', 'verity_key')
|
||||
assert os.path.exists(verity_key_ramdisk), 'Missing verity_key in ramdisk'
|
||||
|
||||
assert filecmp.cmp(
|
||||
verity_key_mincrypt, verity_key_ramdisk, shallow=False), \
|
||||
'Mismatching verity_key files in root and ramdisk'
|
||||
logging.info('Verified the content of /verity_key in ramdisk')
|
||||
|
||||
# Then verify the verity signed system/vendor/product images, against the
|
||||
# verity pubkey in mincrypt format.
|
||||
for image in ('system.img', 'vendor.img', 'product.img'):
|
||||
|
Reference in New Issue
Block a user