Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e5bfa384 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Revert "releasetools: Deprecate GKI build rules"" into main

parents 1a9dd1c7 92a517d7
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -168,6 +168,7 @@ python_defaults {
        "apexd_host",
        "brillo_update_payload",
        "checkvintf",
        "generate_gki_certificate",
        "lz4",
        "toybox",
        "unpack_bootimg",
@@ -244,6 +245,7 @@ python_library_host {
        "boot_signer",
        "brotli",
        "bsdiff",
        "generate_gki_certificate",
        "imgdiff",
        "lz4",
        "mkbootfs",
@@ -308,6 +310,7 @@ python_defaults {
        "brotli",
        "bsdiff",
        "deapexer",
        "generate_gki_certificate",
        "imgdiff",
        "lz4",
        "mkbootfs",
+70 −0
Original line number Diff line number Diff line
@@ -1575,6 +1575,50 @@ def GetAvbChainedPartitionArg(partition, info_dict, key=None):
      pubkey_path=pubkey_path)


def _HasGkiCertificationArgs():
  return ("gki_signing_key_path" in OPTIONS.info_dict and
          "gki_signing_algorithm" in OPTIONS.info_dict)


def _GenerateGkiCertificate(image, image_name):
  key_path = OPTIONS.info_dict.get("gki_signing_key_path")
  algorithm = OPTIONS.info_dict.get("gki_signing_algorithm")

  key_path = ResolveAVBSigningPathArgs(key_path)

  # 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))

  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", "")
  signature_args = signature_args.strip()
  if signature_args:
    cmd.extend(["--additional_avb_args", signature_args])

  args = OPTIONS.info_dict.get("avb_boot_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,
                resolve_rollback_index_location_conflict=False):
  """Creates a VBMeta image.
@@ -1797,6 +1841,29 @@ def _BuildBootableImage(image_name, sourcedir, fs_config_file,

  RunAndCheckOutput(cmd)

  if _HasGkiCertificationArgs():
    if not os.path.exists(img.name):
      raise ValueError("Cannot find GKI boot.img")
    if kernel_path is None or not os.path.exists(kernel_path):
      raise ValueError("Cannot find GKI kernel.img")

    # Certify GKI images.
    boot_signature_bytes = b''
    boot_signature_bytes += _GenerateGkiCertificate(img.name, "boot")
    boot_signature_bytes += _GenerateGkiCertificate(
        kernel_path, "generic_kernel")

    BOOT_SIGNATURE_SIZE = 16 * 1024
    if len(boot_signature_bytes) > BOOT_SIGNATURE_SIZE:
      raise ValueError(
          f"GKI boot_signature size must be <= {BOOT_SIGNATURE_SIZE}")
    boot_signature_bytes += (
        b'\0' * (BOOT_SIGNATURE_SIZE - len(boot_signature_bytes)))
    assert len(boot_signature_bytes) == BOOT_SIGNATURE_SIZE

    with open(img.name, 'ab') as f:
      f.write(boot_signature_bytes)

  # Sign the image if vboot is non-empty.
  if info_dict.get("vboot"):
    path = "/" + partition_name
@@ -1910,6 +1977,9 @@ def HasRamdisk(partition_name, info_dict=None):
  if info_dict.get("recovery_as_boot") == "true":
    return True  # the recovery-as-boot boot.img has a RECOVERY ramdisk.

  if info_dict.get("gki_boot_image_without_ramdisk") == "true":
    return False  # A GKI boot.img has no ramdisk since Android-13.

  if info_dict.get("system_root_image") == "true":
    # The ramdisk content is merged into the system.img, so there is NO
    # ramdisk in the boot.img or boot-<kernel version>.img.
+48 −1
Original line number Diff line number Diff line
@@ -123,6 +123,17 @@ Usage: sign_target_files_apks [flags] input_target_files output_target_files
      mounted on the partition (e.g. "--signing_helper /path/to/helper"). The
      args will be appended to the existing ones in info dict.

  --gki_signing_algorithm <algorithm>
  --gki_signing_key <key>
      Use the specified algorithm (e.g. SHA256_RSA4096) and the key to generate
      'boot signature' in a v4 boot.img. Otherwise it uses the existing values
      in info dict.

  --gki_signing_extra_args <args>
      Specify any additional args that are needed to generate 'boot signature'
      (e.g. --prop foo:bar). The args will be appended to the existing ones
      in info dict.

  --android_jar_path <path>
      Path to the android.jar to repack the apex file.

@@ -182,6 +193,9 @@ OPTIONS.tag_changes = ("-test-keys", "-dev-keys", "+release-keys")
OPTIONS.avb_keys = {}
OPTIONS.avb_algorithms = {}
OPTIONS.avb_extra_args = {}
OPTIONS.gki_signing_key = None
OPTIONS.gki_signing_algorithm = None
OPTIONS.gki_signing_extra_args = None
OPTIONS.android_jar_path = None
OPTIONS.vendor_partitions = set()
OPTIONS.vendor_otatools = None
@@ -538,7 +552,7 @@ def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info,
        [len(os.path.basename(i.filename)) for i in input_tf_zip.infolist()
         if GetApkFileInfo(i.filename, compressed_extension, [])[0]])
  except ValueError:
    # Sets this to zero for targets without APK files.
    # Sets this to zero for targets without APK files, e.g., gki_arm64.
    maxsize = 0

  system_root_image = misc_info.get("system_root_image") == "true"
@@ -754,6 +768,9 @@ def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info,
  if misc_info.get('avb_enable') == 'true':
    RewriteAvbProps(misc_info)

  # Replace the GKI signing key for boot.img, if any.
  ReplaceGkiSigningKey(misc_info)

  # Write back misc_info with the latest values.
  ReplaceMiscInfoTxt(input_tf_zip, output_tf_zip, misc_info)

@@ -1035,6 +1052,27 @@ def RewriteAvbProps(misc_info):
      misc_info[args_key] = result


def ReplaceGkiSigningKey(misc_info):
  """Replaces the GKI signing key."""

  key = OPTIONS.gki_signing_key
  if not key:
    return

  algorithm = OPTIONS.gki_signing_algorithm
  if not algorithm:
    raise ValueError("Missing --gki_signing_algorithm")

  print('Replacing GKI signing key with "%s" (%s)' % (key, algorithm))
  misc_info["gki_signing_algorithm"] = algorithm
  misc_info["gki_signing_key_path"] = key

  extra_args = OPTIONS.gki_signing_extra_args
  if extra_args:
    print('Setting GKI signing args: "%s"' % (extra_args))
    misc_info["gki_signing_signature_args"] = extra_args


def BuildKeyMap(misc_info, key_mapping_options):
  for s, d in key_mapping_options:
    if s is None:   # -d option
@@ -1388,6 +1426,12 @@ def main(argv):
      # 'oem=--signing_helper_with_files=/tmp/avbsigner.sh'.
      partition, extra_args = a.split("=", 1)
      OPTIONS.avb_extra_args[partition] = extra_args
    elif o == "--gki_signing_key":
      OPTIONS.gki_signing_key = a
    elif o == "--gki_signing_algorithm":
      OPTIONS.gki_signing_algorithm = a
    elif o == "--gki_signing_extra_args":
      OPTIONS.gki_signing_extra_args = a
    elif o == "--vendor_otatools":
      OPTIONS.vendor_otatools = a
    elif o == "--vendor_partitions":
@@ -1451,6 +1495,9 @@ def main(argv):
          "avb_extra_custom_image_key=",
          "avb_extra_custom_image_algorithm=",
          "avb_extra_custom_image_extra_args=",
          "gki_signing_key=",
          "gki_signing_algorithm=",
          "gki_signing_extra_args=",
          "vendor_partitions=",
          "vendor_otatools=",
          "allow_gsi_debug_sepolicy",
+34 −0
Original line number Diff line number Diff line
@@ -1636,6 +1636,40 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase):
    self.assertEqual(3, chained_partition_args.rollback_index_location)
    self.assertTrue(os.path.exists(chained_partition_args.pubkey_path))

  def test_GenerateGkiCertificate_KeyPathNotFound(self):
    pubkey = os.path.join(self.testdata_dir, 'no_testkey_gki.pem')
    self.assertFalse(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',
    }
    common.OPTIONS.search_path = None
    test_file = tempfile.NamedTemporaryFile()
    self.assertRaises(common.ExternalError, common._GenerateGkiCertificate,
                      test_file.name, 'generic_kernel')

  def test_GenerateGkiCertificate_SearchKeyPathNotFound(self):
    pubkey = 'no_testkey_gki.pem'
    self.assertFalse(os.path.exists(pubkey))

    # Tests it should raise ExternalError if no key found under
    # OPTIONS.search_path.
    search_path_dir = common.MakeTempDir()
    search_pubkey = os.path.join(search_path_dir, pubkey)
    self.assertFalse(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',
    }
    test_file = tempfile.NamedTemporaryFile()
    self.assertRaises(common.ExternalError, common._GenerateGkiCertificate,
                      test_file.name, 'generic_kernel')


class InstallRecoveryScriptFormatTest(test_utils.ReleaseToolsTestCase):
  """Checks the format of install-recovery.sh.
+51 −1
Original line number Diff line number Diff line
@@ -23,7 +23,8 @@ import common
import test_utils
from sign_target_files_apks import (
    CheckApkAndApexKeysAvailable, EditTags, GetApkFileInfo, ReadApexKeysInfo,
    ReplaceCerts, RewriteAvbProps, RewriteProps, WriteOtacerts)
    ReplaceCerts, ReplaceGkiSigningKey, RewriteAvbProps, RewriteProps,
    WriteOtacerts)


class SignTargetFilesApksTest(test_utils.ReleaseToolsTestCase):
@@ -535,3 +536,52 @@ name="apex.apexd_test_different_app.apex" public_key="system/apex/apexd/apexd_te
            'system/apex/apexd/apexd_testdata/com.android.apex.test_package_2.pem',
            'build/make/target/product/security/testkey', None),
        }, keys_info)

  def test_ReplaceGkiSigningKey(self):
    common.OPTIONS.gki_signing_key = 'release_gki_key'
    common.OPTIONS.gki_signing_algorithm = 'release_gki_algorithm'
    common.OPTIONS.gki_signing_extra_args = 'release_gki_signature_extra_args'

    misc_info = {
        'gki_signing_key_path': 'default_gki_key',
        'gki_signing_algorithm': 'default_gki_algorithm',
        'gki_signing_signature_args': 'default_gki_signature_args',
    }
    expected_dict = {
        'gki_signing_key_path': 'release_gki_key',
        'gki_signing_algorithm': 'release_gki_algorithm',
        'gki_signing_signature_args': 'release_gki_signature_extra_args',
    }
    ReplaceGkiSigningKey(misc_info)
    self.assertDictEqual(expected_dict, misc_info)

  def test_ReplaceGkiSigningKey_MissingSigningAlgorithm(self):
    common.OPTIONS.gki_signing_key = 'release_gki_key'
    common.OPTIONS.gki_signing_algorithm = None
    common.OPTIONS.gki_signing_extra_args = 'release_gki_signature_extra_args'

    misc_info = {
        'gki_signing_key_path': 'default_gki_key',
        'gki_signing_algorithm': 'default_gki_algorithm',
        'gki_signing_signature_args': 'default_gki_signature_args',
    }
    self.assertRaises(ValueError, ReplaceGkiSigningKey, misc_info)

  def test_ReplaceGkiSigningKey_MissingSigningKeyNop(self):
    common.OPTIONS.gki_signing_key = None
    common.OPTIONS.gki_signing_algorithm = 'release_gki_algorithm'
    common.OPTIONS.gki_signing_extra_args = 'release_gki_signature_extra_args'

    # No change to misc_info if common.OPTIONS.gki_signing_key is missing.
    misc_info = {
        'gki_signing_key_path': 'default_gki_key',
        'gki_signing_algorithm': 'default_gki_algorithm',
        'gki_signing_signature_args': 'default_gki_signature_args',
    }
    expected_dict = {
        'gki_signing_key_path': 'default_gki_key',
        'gki_signing_algorithm': 'default_gki_algorithm',
        'gki_signing_signature_args': 'default_gki_signature_args',
    }
    ReplaceGkiSigningKey(misc_info)
    self.assertDictEqual(expected_dict, misc_info)
Loading