From 681d0a97c440c2cd2017e2c09802aefbcc0e67b5 Mon Sep 17 00:00:00 2001 From: Anthony Chen Date: Mon, 21 Oct 2024 16:32:22 +0800 Subject: [PATCH] [bazel,otp] update ROM_EXT immutable section OTP gen tooling This updates the logic to consider both `_ottf_start_address` and `_rom_ext_start_address` when determining the manifest start address. This ensures compatibility with different ELF file formats that generated from linker scripts such as `ottf_silicon_owner_a.ld` and `rom_ext_slot_a.ld`, which may use either symbol to represent the start address of the ROM_EXT section. This also introduces a new feature that conditionally updates the OTP JSON file with data from immutable ROM_EXT section. This update is performed only if the immutable ROM_EXT is enabled. Signed-off-by: Anthony Chen --- rules/otp.bzl | 1 + util/design/gen-otp-immutable-rom-ext-json.py | 52 ++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/rules/otp.bzl b/rules/otp.bzl index 2634fa4ffd027d..13d9dbcd8cc235 100644 --- a/rules/otp.bzl +++ b/rules/otp.bzl @@ -169,6 +169,7 @@ def _otp_json_immutable_rom_ext_impl(ctx): args.add("--input", intput_file) args.add("--elf", rom_ext_elf_file) args.add("--output", output_file) + args.add("--hardened-true-value", CONST.HARDENED_TRUE) tc = ctx.toolchains[LOCALTOOLS_TOOLCHAIN] ctx.actions.run( diff --git a/util/design/gen-otp-immutable-rom-ext-json.py b/util/design/gen-otp-immutable-rom-ext-json.py index b8fa612d90f079..ec7a9f927489d4 100644 --- a/util/design/gen-otp-immutable-rom-ext-json.py +++ b/util/design/gen-otp-immutable-rom-ext-json.py @@ -16,8 +16,10 @@ _OTP_PARTITION_NAME = "CREATOR_SW_CFG" _OTTF_START_OFFSET_SYMBOL_NAME = "_ottf_start_address" +_ROM_EXT_SATRT_OFFSET_SYMBOL_NAME = "_rom_ext_start_address" _ROM_EXT_IMMUTABLE_SECTION_NAME = ".rom_ext_immutable" +_ENABLE_FIELD_NAME = "CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_EN" _START_OFFSET_FIELD_NAME = "CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_START_OFFSET" _SIZE_FIELD_NAME = "CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_LENGTH" _HASH_FIELD_NAME = "CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_SHA256_HASH" @@ -33,11 +35,21 @@ def __init__(self, rom_ext_elf, json_data): self.start_offset = None self.size_in_bytes = None self.hash = None + with open(self.rom_ext_elf, 'rb') as f: elf = elffile.ELFFile(f) # Find the offset of the current slot we are in. for symbol in elf.get_section_by_name(".symtab").iter_symbols(): - if symbol.name == _OTTF_START_OFFSET_SYMBOL_NAME: + if symbol.name in [ + _OTTF_START_OFFSET_SYMBOL_NAME, + _ROM_EXT_SATRT_OFFSET_SYMBOL_NAME, + ]: + if self.manifest_offset is not None: + raise ValueError( + f"More than one manifest start address exists. " + f"Current offset: {self.manifest_offset}, " + f"new offset: {symbol.entry['st_value']}" + ) self.manifest_offset = symbol.entry["st_value"] assert self.manifest_offset, "Manifest start address not found." @@ -74,6 +86,20 @@ def insert_key_value(self, item_name: str, value: str): return partition["items"].append({"name": item_name, "value": value}) + def get_key_value(self, item_name: str): + """Get the value of the item if it exists. + Args: + item_name: The name of the item to insert. + Returns: + The value of the item if found, otherwise "0x0". + """ + for partition in self.json_data["partitions"]: + if partition["name"] == _OTP_PARTITION_NAME: + for item in partition["items"]: + if item["name"] == item_name: + return item["value"] + return "0x0" + def update_json_with_immutable_rom_ext_section_data(self): """Update the JSON with the ROM_EXT immutable section data. Args: @@ -86,6 +112,22 @@ def update_json_with_immutable_rom_ext_section_data(self): self.insert_key_value(_SIZE_FIELD_NAME, f"{hex(self.size_in_bytes)}") self.insert_key_value(_HASH_FIELD_NAME, f"0x{self.hash.hex()}") + def immutable_rom_ext_enable(self, hardened_true_value: int): + """Checks if immutable ROM extension is enabled. + + This method retrieves the value of the enable field from the OTP + partition and compares it with the provided hardened true value. + + Args: + hardened_true_value: The expected value for the enable field + when immutable ROM extension is enabled. + + Returns: + True if immutable ROM extension is enabled, False otherwise. + """ + immutable_rom_ext_en_value = int(self.get_key_value(_ENABLE_FIELD_NAME), 0) + return immutable_rom_ext_en_value == hardened_true_value + def main(): parser = argparse.ArgumentParser( @@ -107,6 +149,10 @@ def main(): type=str, metavar='', help='Output JSON file path.') + parser.add_argument('--hardened-true-value', + type=int, + help='The integer value representing "true" for the ' + 'enable field in the OTP partition.') args = parser.parse_args() # Read in the OTP fields (encoded in JSON) we will be updating. @@ -121,7 +167,9 @@ def main(): logging.error("Cannot find {} section in ROM_EXT ELF {}.".format( _ROM_EXT_IMMUTABLE_SECTION_NAME, args.elf)) sys.exit(1) - imm_section_otp.update_json_with_immutable_rom_ext_section_data() + + if imm_section_otp.immutable_rom_ext_enable(args.hardened_true_value): + imm_section_otp.update_json_with_immutable_rom_ext_section_data() # Write out the OTP fields to a JSON file. with open(args.output, 'w') as f: