Support GKI boot.img v4 signing

Commit I9967d06bde0e18a12b84b5b0b568db09765fe305 supports adding a
generic boot_signature into boot.img v4. This change allows replacing
the boot_signture signing key with a release key during the release
process.

The default GKI signing key can be specified in a BoardConfig.mk via:

  BOARD_GKI_SIGNING_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
  BOARD_GKI_SIGNING_ALGORITHM := SHA256_RSA2048
  BOARD_GKI_SIGNING_SIGNATURE_ARGS := --prop foo:bar

The release signing key/algorithm can be specified by the following options
when invoking sign_target_files_apks:

  --gki_signing_key=external/avb/test/data/testkey_rsa4096.pem
  --gki_signing_algorithm=SHA256_RSA4096

Additional arguments for generating the GKI signature can be
specified as below:

  --gki_signing_extra_args="--prop gki:prop1 --prop gki:prop2"

Bug: 177862434
Test: make dist
Test: sign_target_files_apks \
        --gki_signing_key=external/avb/test/data/testkey_rsa4096.pem \
        --gki_signing_algorithm=SHA256_RSA4096 \
        --gki_signing_extra_args="--prop gki:prop1 --prop gki:prop2" \
        ./out/dist/*-target_files-eng.*.zip signed.zip
Test: Checks GKI boot_signature is expected after signing:
      `unzip signed.zip IMAGES/boot.img`
      `unpack_bootimg --boot_img IMAGES/boot.img --out unpack`
      `avbtool info_image --image unpack/boot_signature`
Test: unit test: releasetools_test and releasetools_py3_test

Change-Id: I61dadbc242360e4cab3dc70295931b4a5b9422a9
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 0061819..414ab97 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -1339,6 +1339,35 @@
   RunAndCheckOutput(verify_cmd)
 
 
+def AppendGkiSigningArgs(cmd):
+  """Append GKI signing arguments for mkbootimg."""
+  # e.g., --gki_signing_key path/to/signing_key
+  #       --gki_signing_algorithm SHA256_RSA4096"
+
+  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
+
+  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.
+  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])
+
+    signature_args = OPTIONS.info_dict.get("gki_signing_signature_args")
+    if signature_args:
+      cmd.extend(["--gki_signing_signature_args", signature_args])
+
+
 def BuildVBMeta(image_path, partitions, name, needed_partitions):
   """Creates a VBMeta image.
 
@@ -1520,6 +1549,8 @@
   if has_ramdisk:
     cmd.extend(["--ramdisk", ramdisk_img.name])
 
+  AppendGkiSigningArgs(cmd)
+
   img_unsigned = None
   if info_dict.get("vboot"):
     img_unsigned = tempfile.NamedTemporaryFile()