releasetools: Android T GKI certification scheme
Companion change of Iaf48a6e3d4b97fa6bfb5e1635a288b045baa248f
To support new GKI certification scheme for boot.img and
init_boot.img on upgrading and launching device combinations.
Bug: 210367929
Bug: 211741246
Bug: 203698939
Test: atest --host releasetools_test:test_common
Test: unpack_bootimg --boot_img boot.img
Test: unpack_bootimg --boot_img init_boot.img
Test: avbtool info_image --image out/boot_signature
Change-Id: I3749297c09c3899046550e4be776acbeea37ef2e
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