Skip to content

Commit ca2a918

Browse files
committed
Scripts: Security enablement during west build
Added changes to automate the signing of zephyr security using customtool during the west build process. Signed-off-by: Aasim Shaik <[email protected]>
1 parent e48c907 commit ca2a918

File tree

4 files changed

+127
-4
lines changed

4 files changed

+127
-4
lines changed

boards/silabs/radio_boards/siwx917_rb4338a/board.cmake

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
# Copyright (c) 2024 Silicon Laboratories Inc.
22
# SPDX-License-Identifier: Apache-2.0
3+
# Set the flash file based on signing is enabled or not.
34

5+
if(CONFIG_SIWX91X_SILABS_COMMANDER_SIGN)
6+
set(FLASH_FILE ${PROJECT_BINARY_DIR}/${KERNEL_NAME}_signed.bin.rps)
7+
else()
8+
set(FLASH_FILE ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}.rps)
9+
endif()
410
board_runner_args(silabs_commander "--device=SiWG917M111GTBA" "--file-type=bin"
5-
"--file=${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}.rps")
11+
"--file=${FLASH_FILE}")
612
include(${ZEPHYR_BASE}/boards/common/silabs_commander.board.cmake)
713

814
# It is not possible to load/flash a firmware using JLink, but it is possible to

scripts/west_commands/sign.py

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import sys
1414

1515
from elftools.elf.elffile import ELFFile
16-
1716
from west import manifest
1817
from west.commands import Verbosity
1918
from west.util import quote_sh_list
@@ -79,6 +78,20 @@
7978
[rimage] sections in your west config file(s); this is especially useful
8079
when invoking west sign _indirectly_ through CMake/ninja. See how at
8180
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.
8295
'''
8396

8497
class ToggleAction(argparse.Action):
@@ -112,8 +125,8 @@ def do_add_parser(self, parser_adder):
112125

113126
# general options
114127
group = parser.add_argument_group('tool control options')
115-
group.add_argument('-t', '--tool', choices=['imgtool', 'rimage'],
116-
help='''image signing tool name; imgtool and rimage
128+
group.add_argument('-t', '--tool', choices=['imgtool', 'rimage', 'silabs_commander'],
129+
help='''image signing tool name; imgtool , rimage and silabs_commander
117130
are currently supported (imgtool is deprecated)''')
118131
group.add_argument('-p', '--tool-path', default=None,
119132
help='''path to the tool itself, if needed''')
@@ -195,6 +208,8 @@ def do_run(self, args, ignored):
195208
signer = ImgtoolSigner()
196209
elif args.tool == 'rimage':
197210
signer = RimageSigner()
211+
elif args.tool == 'silabs_commander':
212+
signer = SilabsRPSSigner()
198213
# (Add support for other signers here in elif blocks)
199214
else:
200215
if args.tool is None:
@@ -633,3 +648,74 @@ def sign(self, command, build_dir, build_conf, formats):
633648

634649
os.remove(out_bin)
635650
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+
kernel_name = build_conf.get('CONFIG_KERNEL_BIN_NAME')
696+
# Setting the input and output paths
697+
input_rps = b / 'zephyr' / f'{kernel_name}.bin.rps'
698+
output_rps = args.sbin or (b / 'zephyr' / f'{kernel_name}_signed.bin.rps')
699+
700+
# Check if input binary exists
701+
if not input_rps.is_file():
702+
command.die(f"No .rps found at {input_rps}. Ensure the build generated kernel_name.bin.rps in {b / 'zephyr'}")
703+
704+
# Load configuration
705+
siwx91x_ota_key, commander_path, siwx91x_private_key = self.get_security_configs(build_conf, args, command)
706+
707+
# Build the Silicon Labs Commander signing command
708+
sign_base = [
709+
commander_path,
710+
"rps",
711+
"convert",
712+
str(output_rps),
713+
"--app", str(input_rps),
714+
"--mic", siwx91x_ota_key,
715+
"--encrypt", siwx91x_ota_key,
716+
"--sign", siwx91x_private_key,
717+
*args.tool_args
718+
]
719+
720+
command.inf("Running command:", ' '.join(sign_base))
721+
subprocess.run(sign_base, check=True)

soc/silabs/silabs_siwx91x/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Copyright (c) 2024 Silicon Laboratories Inc.
22
# SPDX-License-Identifier: Apache-2.0
33

4+
include(west) # Add this at the top or before using ${WEST}
5+
46
add_subdirectory(siwg917)
57

68
# Necessary to not overwrite NWP Firmware
@@ -12,3 +14,12 @@ set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
1214
${KERNEL_BIN_NAME}
1315
${KERNEL_BIN_NAME}.rps
1416
)
17+
18+
# Custom signing with Silicon Labs Commander
19+
if(CONFIG_SIWX91X_SILABS_COMMANDER_SIGN)
20+
# Necessary to invoke west sign after build
21+
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
22+
COMMAND ${WEST} sign -t silabs_commander --build-dir ${CMAKE_BINARY_DIR} --sbin ${PROJECT_BINARY_DIR}/${KERNEL_NAME}_signed.bin.rps
23+
DEPENDS zephyr_final
24+
)
25+
endif()

soc/silabs/silabs_siwx91x/Kconfig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,23 @@ config SIWX91X_NWP_INIT_PRIORITY
2828
Wi-Fi and crypto.
2929

3030
endif # SOC_FAMILY_SILABS_SIWX91X
31+
32+
if SOC_FAMILY_SILABS_SIWX91X
33+
config SIWX91X_SILABS_COMMANDER_SIGN
34+
bool "Silicon Labs Commander Signing Support"
35+
depends on BUILD_OUTPUT_BIN
36+
help
37+
Activates signing of Zephyr binary with Silicon Labs Commander during build process.
38+
For more information refer this
39+
"https://www.silabs.com/documents/public/user-guides/ug574-siwx917-soc-manufacturing-utility-user-guide.pdf"
40+
41+
config SIWX91X_OTA_KEY
42+
string "OTA Key for Encryption."
43+
help
44+
Specifies Over the Air key (hex) for encryption with Silicon Labs Commander.
45+
46+
config SIWX91X_PRIVATE_KEY
47+
string "Private Key Path for Signing."
48+
help
49+
Path to private key file for signing with Silicon Labs Commander.
50+
endif

0 commit comments

Comments
 (0)