|
13 | 13 | import sys
|
14 | 14 |
|
15 | 15 | from elftools.elf.elffile import ELFFile
|
16 |
| - |
17 | 16 | from west import manifest
|
18 | 17 | from west.commands import Verbosity
|
19 | 18 | from west.util import quote_sh_list
|
|
79 | 78 | [rimage] sections in your west config file(s); this is especially useful
|
80 | 79 | when invoking west sign _indirectly_ through CMake/ninja. See how at
|
81 | 80 | https://docs.zephyrproject.org/latest/develop/west/sign.html
|
| 81 | +
|
| 82 | +silabs_commander |
| 83 | +----- |
| 84 | +
|
| 85 | +To create a signed binary with the silabs_commander tool, run this from your build directory: |
| 86 | +
|
| 87 | + west sign -t silabs_commander |
| 88 | +
|
| 89 | +For this to work, Silabs Commander tool must be installed in your PATH. |
| 90 | +
|
| 91 | +The input binary (zephyr.bin.rps) is signed using the specified OTA key and private key, |
| 92 | +producing zephyr_signed.bin.rps by default. If CONFIG_SIWX91X_OTA_KEY and CONFIG_SIWX91X_PRIVATE_KEY are set |
| 93 | +in your build configuration, they will be used unless overridden by command-line arguments. |
| 94 | +Additional arguments after '--' are passed to silabs_commander directly. |
82 | 95 | '''
|
83 | 96 |
|
84 | 97 | class ToggleAction(argparse.Action):
|
@@ -112,7 +125,7 @@ def do_add_parser(self, parser_adder):
|
112 | 125 |
|
113 | 126 | # general options
|
114 | 127 | group = parser.add_argument_group('tool control options')
|
115 |
| - group.add_argument('-t', '--tool', choices=['imgtool', 'rimage'], |
| 128 | + group.add_argument('-t', '--tool', choices=['imgtool', 'rimage', 'silabs_commander'], |
116 | 129 | help='''image signing tool name; imgtool and rimage
|
117 | 130 | are currently supported (imgtool is deprecated)''')
|
118 | 131 | group.add_argument('-p', '--tool-path', default=None,
|
@@ -195,6 +208,8 @@ def do_run(self, args, ignored):
|
195 | 208 | signer = ImgtoolSigner()
|
196 | 209 | elif args.tool == 'rimage':
|
197 | 210 | signer = RimageSigner()
|
| 211 | + elif args.tool == 'silabs_commander': |
| 212 | + signer = SilabsRPSSigner() |
198 | 213 | # (Add support for other signers here in elif blocks)
|
199 | 214 | else:
|
200 | 215 | if args.tool is None:
|
@@ -633,3 +648,80 @@ def sign(self, command, build_dir, build_conf, formats):
|
633 | 648 |
|
634 | 649 | os.remove(out_bin)
|
635 | 650 | os.rename(out_tmp, out_bin)
|
| 651 | + |
| 652 | +class SilabsRPSSigner(Signer): |
| 653 | + # Signer class for Silicon Labs Commander tool via west sign -t silabs_commander. |
| 654 | + def find_commandertool(self, cmd, args): |
| 655 | + if args.tool_path: |
| 656 | + commandertool = args.tool_path |
| 657 | + if not os.path.isfile(commandertool): |
| 658 | + cmd.die(f'--tool-path {commandertool}: no such file') |
| 659 | + else: |
| 660 | + commandertool = shutil.which('commander') |
| 661 | + if not commandertool: |
| 662 | + cmd.die(f'SILABS "commander" not found in PATH, try "--tool-path"? Cannot sign {args}') |
| 663 | + return commandertool |
| 664 | + |
| 665 | + def get_security_configs(self, build_conf, args, command): |
| 666 | + # Retrieve configurations, prioritizing command-line args, then build_conf |
| 667 | + siwx91x_ota_key = getattr(args, 'siwx91x-ota-key', build_conf.get('CONFIG_SIWX91X_OTA_KEY')) |
| 668 | + siwx91x_private_key = getattr(args, 'siwx91x-private-key', build_conf.get('CONFIG_SIWX91X_PRIVATE_KEY')) |
| 669 | + |
| 670 | + # Refer find_commandertool() function to identify the Commander tool. |
| 671 | + commander_path = self.find_commandertool(command, args) |
| 672 | + # Validate required settings |
| 673 | + if not siwx91x_ota_key: |
| 674 | + command.die("SIWX91X_OTA_KEY not provided. Use --siwx91x-ota-key=your_key or add CONFIG_SIWX91X_OTA_KEY in prj.conf.") |
| 675 | + if not siwx91x_private_key: |
| 676 | + command.die("SIWX91X_PRIVATE_KEY not provided. Use --siwx91x-private-key=/path/to/key or add CONFIG_SIWX91X_PRIVATE_KEY in prj.conf.") |
| 677 | + |
| 678 | + # Validate private key path |
| 679 | + if not os.path.isfile(siwx91x_private_key): |
| 680 | + command.die(f"Private key not found at {siwx91x_private_key}. Please ensure the path is correct.") |
| 681 | + |
| 682 | + return siwx91x_ota_key, commander_path, siwx91x_private_key |
| 683 | + |
| 684 | + def sign(self, command, build_dir, build_conf, formats): |
| 685 | + """Sign the Zephyr binary using Silicon Labs Commander. |
| 686 | +
|
| 687 | + :param command: The Sign instance (provides args and utility methods) |
| 688 | + :param build_dir: The build directory path |
| 689 | + :param build_conf: BuildConfiguration object for the build directory |
| 690 | + :param formats: List of formats to generate (e.g., ['bin', 'rps']) |
| 691 | + """ |
| 692 | + self.command = command |
| 693 | + args = command.args |
| 694 | + b = pathlib.Path(build_dir) |
| 695 | + |
| 696 | + # Check if signing is needed |
| 697 | + if not formats: |
| 698 | + if not args.quiet: |
| 699 | + command.inf(f"No output formats specified, not signing {args}") |
| 700 | + return |
| 701 | + |
| 702 | + # Setting the input and output paths |
| 703 | + input_rps = b / 'zephyr' / "zephyr.bin.rps" |
| 704 | + output_rps = args.sbin or (b / 'zephyr' / "zephyr_signed.bin.rps") |
| 705 | + |
| 706 | + # Check if input binary exists |
| 707 | + if not input_rps.is_file(): |
| 708 | + command.die(f"No .rps found at {input_rps}. Ensure the build generated zephyr.bin.rps in {b / 'zephyr'}") |
| 709 | + |
| 710 | + # Load configuration |
| 711 | + siwx91x_ota_key, commander_path, siwx91x_private_key = self.get_security_configs(build_conf, args, command) |
| 712 | + |
| 713 | + # Build the Silicon Labs Commander signing command |
| 714 | + sign_base = [ |
| 715 | + commander_path, |
| 716 | + "rps", |
| 717 | + "convert", |
| 718 | + str(output_rps), |
| 719 | + "--app", str(input_rps), |
| 720 | + "--mic", siwx91x_ota_key, |
| 721 | + "--encrypt", siwx91x_ota_key, |
| 722 | + "--sign", siwx91x_private_key, |
| 723 | + *args.tool_args |
| 724 | + ] |
| 725 | + |
| 726 | + command.inf("Running command:", ' '.join(sign_base)) |
| 727 | + subprocess.run(sign_base, check=True) |
0 commit comments