Thomas Gassmann (ETH)

Relocking bootloader on a custom ROM

2023-02-07 - 4 min read

This is an old unfinished blog migrated from my old blog, I cannot guarantee the correctness of this. I have switched to a Pixel now.

I have been using OnePlus phones for about five years now. One of the neat things OnePlus allows you to do is relocking the bootloader with a custom AVB key. However, most custom ROMs do not seem to be signing their builds.

Based on the following guide, I've had to do the following to sign a Pixel Experience build. Here's the diff:

project build/make/
diff --git a/core/Makefile b/core/Makefile
index ebd8cf206..95235e9cc 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -4113,7 +4113,7 @@ $(if $(BOARD_AVB_ALGORITHM),,$(error BOARD_AVB_ALGORITHM is not defined))
 else
 # If key path isn't specified, use the 4096-bit test key.
 BOARD_AVB_ALGORITHM := SHA256_RSA4096
-BOARD_AVB_KEY_PATH := external/avb/test/data/testkey_rsa4096.pem
+# BOARD_AVB_KEY_PATH := external/avb/test/data/testkey_rsa4096.pem
 endif
 
 # AVB signing for system_other.img.
@@ -4356,16 +4356,19 @@ endef
 # $(1): Partition name, e.g. boot or system.
 define check-and-set-avb-args
 $(eval _in_chained_vbmeta := $(filter $(1),$(INTERNAL_AVB_PARTITIONS_IN_CHAINED_VBMETA_IMAGES)))
-$(if $(BOARD_AVB_$(call to-upper,$(1))_KEY_PATH),\
-    $(if $(_in_chained_vbmeta),\
-        $(error Chaining partition "$(1)" in chained VBMeta image is not supported)) \
-    $(call _check-and-set-avb-chain-args,$(1)),\
-    $(if $(_in_chained_vbmeta),,\
-        $(if $(filter boot,$(1)),\
-            $(eval INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
-                --include_descriptors_from_image $(firstword $(call images-for-partitions,$(1)))),\
-            $(eval INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
-                --include_descriptors_from_image $(call images-for-partitions,$(1))))))
+$(eval _partition_path := $(call images-for-partitions,$(1)))
+$(if $(_partition_path),\
+    $(if $(BOARD_AVB_$(call to-upper,$(1))_KEY_PATH),\
+        $(if $(_in_chained_vbmeta),\
+            $(error Chaining partition "$(1)" in chained VBMeta image is not supported)) \
+        $(call _check-and-set-avb-chain-args,$(1)),\
+        $(if $(_in_chained_vbmeta),,\
+            $(if $(filter boot,$(1)),\
+                $(eval INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
+                    --include_descriptors_from_image $(firstword $(_partition_path))),\
+                $(eval INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
+                    --include_descriptors_from_image $(_partition_path))))),\
+    $(info Partition path for "$(1)" not yet defined, not adding it to vbmeta))
 endef
 
 # Checks and sets build variables for a custom chained partition to include it into vbmeta.img.
@@ -4472,7 +4475,7 @@ BOARD_AVB_MAKE_VBMETA_VENDOR_IMAGE_ARGS += --padding_size 4096
 
 ifeq (eng,$(filter eng, $(TARGET_BUILD_VARIANT)))
 # We only need the flag in top-level vbmeta.img.
-BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --set_hashtree_disabled_flag
+# BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --set_hashtree_disabled_flag
 endif
 
 ifdef BOARD_AVB_ROLLBACK_INDEX
diff --git a/tools/releasetools/apex_utils.py b/tools/releasetools/apex_utils.py
index 4b6052488..9d345480d 100644
--- a/tools/releasetools/apex_utils.py
+++ b/tools/releasetools/apex_utils.py
@@ -21,7 +21,7 @@ import shlex
 import shutil
 import zipfile
 
-import apex_manifest
+# import apex_manifest
 import common
 from common import UnzipTemp, RunAndCheckOutput, MakeTempFile, OPTIONS
 
@@ -572,9 +572,9 @@ def GetApexInfoFromTargetFiles(input_file, partition, compressed_only=True):
       continue
     apex_info = ota_metadata_pb2.ApexInfo()
     # Open the apex file to retrieve information
-    manifest = apex_manifest.fromApex(apex_filepath)
-    apex_info.package_name = manifest.name
-    apex_info.version = manifest.version
+    # manifest = apex_manifest.fromApex(apex_filepath)
+    # apex_info.package_name = manifest.name
+    # apex_info.version = manifest.version
     # Check if the file is compressed or not
     apex_type = RunAndCheckOutput([
         deapexer, "--debugfs_path", debugfs_path,

project device/google/bonito/
diff --git a/BoardConfig-common.mk b/BoardConfig-common.mk
index 8a7b1141..cc7fd0da 100644
--- a/BoardConfig-common.mk
+++ b/BoardConfig-common.mk
@@ -86,7 +86,7 @@ BOARD_USES_RECOVERY_AS_BOOT := true
 BOARD_USES_METADATA_PARTITION := true
 
 # Verified Boot
-BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --flags 3
+# BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --flags 3
 
 # System Image
 BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE := erofs
diff --git a/sargo/BoardConfig.mk b/sargo/BoardConfig.mk
index bb7e9ea9..b3331ff4 100644
--- a/sargo/BoardConfig.mk
+++ b/sargo/BoardConfig.mk
@@ -25,3 +25,6 @@ else
   -include vendor/google_devices/bonito/proprietary/BoardConfigVendor.mk
   include vendor/google/sargo/BoardConfigVendor.mk
 endif
+
+BOARD_AVB_ALGORITHM := SHA256_RSA2048
+BOARD_AVB_KEY_PATH := /home/thomas/.android-certs/releasekey.pk8

project device/google/cuttlefish/
diff --git a/shared/BoardConfig.mk b/shared/BoardConfig.mk
index b59b39ca1..808367d1c 100644
--- a/shared/BoardConfig.mk
+++ b/shared/BoardConfig.mk
@@ -79,11 +79,11 @@ TARGET_COPY_OUT_SYSTEM_DLKM := system_dlkm
 # Enable AVB
 BOARD_AVB_ENABLE := true
 BOARD_AVB_ALGORITHM := SHA256_RSA4096
-BOARD_AVB_KEY_PATH := external/avb/test/data/testkey_rsa4096.pem
+# BOARD_AVB_KEY_PATH := external/avb/test/data/testkey_rsa4096.pem
 
 # Enable chained vbmeta for system image mixing
 BOARD_AVB_VBMETA_SYSTEM := product system system_ext
-BOARD_AVB_VBMETA_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa4096.pem
+BOARD_AVB_KEY_PATH := /home/thomas/.android-certs/releasekey.pk8
 BOARD_AVB_VBMETA_SYSTEM_ALGORITHM := SHA256_RSA4096
 BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
 BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX_LOCATION := 1

To build an OTA:

source build/envsetup.sh
lunch aosp_sargo-userdebug
croot
mka bacon -j8
mka target-files-package otatools
./build/tools/releasetools/sign_target_files_apks -o -d ~/.android-certs $OUT/obj/PACKAGING/target_files_intermediates/*-target_files-*.zip signed-target_files.zip
./build/tools/releasetools/ota_from_target_files -k ~/.android-certs/releasekey --block signed-target_files.zip pe-UNOFFICIAL-kebab-signed.zip

And to flash the new AVB key and relock the bootloader:

fastboot flash avb_custom_key ~/android/kebab/pkmd/pkmd.bin
fastboot reboot bootloader
fastboot oem lock