From 15a2265364ba3b0835eff7c4e9f4ba5c2a4c403a Mon Sep 17 00:00:00 2001 From: Igor Sukhov Date: Wed, 23 Oct 2024 14:44:07 +0300 Subject: [PATCH] Add support for multiple SEC_UNLOCK sections in BD file Enable the ability to unlock multiple features from different engines using the boot descriptor (BD) file with multiple SEC_UNLOCK sections --- spsdk/image/hab/commands/commands.py | 51 +++++++++++++++------------- spsdk/image/hab/segments.py | 3 +- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/spsdk/image/hab/commands/commands.py b/spsdk/image/hab/commands/commands.py index 612d2fca..4c050d15 100644 --- a/spsdk/image/hab/commands/commands.py +++ b/spsdk/image/hab/commands/commands.py @@ -507,35 +507,40 @@ def __init__(self, cmd: CmdUnlockAbstract) -> None: super().__init__(cmd) @classmethod - def load_from_config(cls, config: HabConfig, search_paths: Optional[list[str]] = None) -> Self: + def load_from_config(cls, config: HabConfig, search_paths: Optional[list[str]] = None) -> list[Self]: """Load configuration into the command. :param config: Section config :param search_paths: List of paths where to search for the file, defaults to None :raises SPSDKKeyError: Unknown engine. + :return: List of command instances """ - command_params = config.commands.get_command_params(SecCommand.UNLOCK) - cls.check_config_section_params(command_params) - - unlock_engine = EnumEngine.from_label(command_params["Unlock_Engine"]) - if unlock_engine not in UNLOCK_COMMANDS_MAPPING: - raise SPSDKKeyError(f"Unknown engine {unlock_engine}") - klass = UNLOCK_COMMANDS_MAPPING[unlock_engine] - kwargs = {} - unlock_features: str = command_params.get("Unlock_Features") - if unlock_features is not None: - # features may be defined as single feature of coma separated list of features - features = [ - klass.FEATURES.from_label(feature.strip()).tag - for feature in unlock_features.split(",") - ] - kwargs["features"] = cls.calc_features_value(features) - unlock_uid: str = command_params.get("Unlock_UID") - if unlock_uid: - uids = [int(uid.strip(), 0) for uid in unlock_uid.split(",")] - kwargs["uid"] = cls.calc_uid(uids) - cmd = klass(**kwargs) - return cls(cmd) + cmds = [] + for command in config.commands: + if command.index == SecCommand.UNLOCK.tag: + command_params = command.params + cls.check_config_section_params(command_params) + + unlock_engine = EnumEngine.from_label(command_params["Unlock_Engine"]) + if unlock_engine not in UNLOCK_COMMANDS_MAPPING: + raise SPSDKKeyError(f"Unknown engine {unlock_engine}") + klass = UNLOCK_COMMANDS_MAPPING[unlock_engine] + kwargs = {} + unlock_features: str = command_params.get("Unlock_Features") + if unlock_features is not None: + # features may be defined as single feature or comma-separated list of features + features = [ + klass.FEATURES.from_label(feature.strip()).tag + for feature in unlock_features.split(",") + ] + kwargs["features"] = cls.calc_features_value(features) + unlock_uid: str = command_params.get("Unlock_UID") + if unlock_uid: + uids = [int(uid.strip(), 0) for uid in unlock_uid.split(",")] + kwargs["uid"] = cls.calc_uid(uids) + cmd = klass(**kwargs) + cmds.append(cls(cmd)) + return cmds @classmethod def calc_features_value(cls, features: List[int]) -> int: diff --git a/spsdk/image/hab/segments.py b/spsdk/image/hab/segments.py index 01edce81..d7fdee12 100644 --- a/spsdk/image/hab/segments.py +++ b/spsdk/image/hab/segments.py @@ -420,7 +420,8 @@ def load_from_config(cls, config: HabConfig, search_paths: Optional[list[str]] = command_class = COMMANDS_MAPPING.get(SecCommand.from_tag(cmd_config.index)) if not command_class: raise SPSDKValueError(f"Command with index does not exist {cmd_config.index}") - commands.append(command_class.load_from_config(config, search_paths=search_paths)) + cmd_objs = command_class.load_from_config(config, search_paths=search_paths) + commands.extend(cmd_objs if isinstance(cmd_objs, list) else [cmd_objs]) segment = SegCSF(enabled=True, version=header.version) for command in commands: segment.append_command(command.cmd)