-
Notifications
You must be signed in to change notification settings - Fork 7.6k
scripts: west: sign: Add support for image signing for Silabs SiWx91x #87669
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
scripts: west: sign: Add support for image signing for Silabs SiWx91x #87669
Conversation
Hello @Aasimshaik11, and thank you very much for your first pull request to the Zephyr project! |
7541fb9
to
7052317
Compare
7052317
to
da52b68
Compare
CMakeLists.txt
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert these unrelated changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved this comment
@@ -3,3 +3,25 @@ | |||
|
|||
config BOARD_SIWX917_RB4338A | |||
select SOC_PART_NUMBER_SIWG917M111MGTBA | |||
|
|||
# Kconfig.board for SiWx917 RB4338A |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary comment, please remove.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved this comment
|
||
# Kconfig.board for SiWx917 RB4338A | ||
|
||
config SIGNING_ENABLED |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signing support should be a property of the SiWx91x SoC, not of the board. All of this must move to soc/silabs/silabs_siwx91x/
, and the Kconfig options must be renamed to show that they apply to 91x only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved this comment
@@ -11,3 +11,71 @@ include(${ZEPHYR_BASE}/boards/common/silabs_commander.board.cmake) | |||
# Once started, it should be possible to reset the device with "monitor reset" | |||
board_runner_args(jlink "--device=Si917" "--speed=10000") | |||
include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) | |||
|
|||
# Custom signing with Silicon Labs Commander |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move to SoC level
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved this comment
|
||
# Define paths and keys from Kconfig | ||
set(WORKSPACE_ROOT $ENV{PWD}) | ||
set(SL_COMMANDER_PATH $ENV{PWD}/SimplicityCommander-Linux/commander/commander) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can't hardcode the path to Commander. You must assume that it exists on PATH
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I resolved this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved this comment
scripts/west_commands/sign.py
Outdated
@@ -79,6 +80,21 @@ | |||
[rimage] sections in your west config file(s); this is especially useful | |||
when invoking west sign _indirectly_ through CMake/ninja. See how at | |||
https://docs.zephyrproject.org/latest/develop/west/sign.html | |||
|
|||
sirps |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be silabs_rps
or silabs_commander_rps
for consistency with the silabs_commander
runner.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved this comment
scripts/west_commands/sign.py
Outdated
|
||
# Primary source: Board Kconfig defaults | ||
board_dir = cache.get('BOARD_DIR') # Fallback to PWD if BOARD_DIR missing | ||
board_kconfig = pathlib.Path(board_dir) / 'Kconfig.siwx917_r4338a' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can't hard-code the board Kconfig path, this must generically work for all SiWx91x based boards.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved this comment
message(STATUS "Private key found at '${M4_PRIVATE_KEY}'") | ||
endif() | ||
|
||
# Define the commander signing command |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this calling Commander directly, and not invoking west sign
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The direct call to Silicon Labs Commander in board.cmake is intentional to integrate signing into the west build process, ensuring that zephyr.bin.rps is generated automatically as part of the build output for SiWx917-based boards. This approach is used to meet hardware requirements where a signed binary is mandatory for flashing or execution. Invoking west sign would require a separate post-build step, which we avoid here to streamline the workflow and guarantee that the signed artifact is available immediately after west build, consistent with the board’s firmware deployment needs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would a post-build step need to be separately invoked just because it's calling west instead of Commander? There is no difference if west sign
or commander
is called as a custom command.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's right. We can do that too, But there will be extra call of west sign that's it.
If west sign used:
Cmakefile -> west sign -> sign.py -> commander for signing
If not west sign:
Cmake -> Commander
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO it would be better to call west sign
, in order to avoid duplicating the implementation. The overhead of an extra call is well worth avoiding two implementations of the same logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved this comments
726af6b
to
b9ddd52
Compare
6015f25
to
d329322
Compare
Please, do not resolve comments as per the contribution guidelines. |
82ac254
to
2a2c05b
Compare
scripts/west_commands/sign.py
Outdated
elif current_config == 'M4_PRIVATE_KEY': | ||
m4_private_key = value | ||
elif current_config == 'COMMANDER_PATH': | ||
commander_path = value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
6 level of indentation is a lot, especially in a function of 125 lines. Probably you could introduce a subfunction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved this comment
437fe54
to
fd7c629
Compare
board_runner_args(silabs_commander "--device=SiWG917M111GTBA" "--file-type=bin" | ||
"--file=${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}.rps") | ||
"--file=${FLASH_FILE}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my experience, a build system that produces outputs with changing filenames tends to be really painful to maintain and to use, I don't recommend it. Among others, this variability may require extra logic in a CI building and consuming this output. Is it really important to have a different filename? Instead you could have KERNEL_NAME_pre.rps
and KERNEL_NAME.rps
. When you don't sign, the latter is either a mere copy of the former, or signed with a development, pseudo-private key.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So FLASH_FILE has a _signed
suffix even when CONFIG_SIWX91X_SILABS_SIGN
is false? That does not seem to make sense.
Just drop _signed
and keep the filenames constant and CONFIG-independent, see #87669 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact, I believe the others tools change property bin_file
of the target runners_yaml_props_target
(see cmake/mcuboot.cmake:16
or soc/st/stm32/stm32n6x/CMakeLists.txt:35
). Probably we should adopt the same design.
Then, we could probably remove the --file=${FLASH_FILE}
from our command line.
@marc-hb any objection?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have any blocking objection here, never had. But I've always thought and still think that the simplest and cleanest is to have something like:
KERNEL_BIN_NAME_unsigned.bin
orKERNEL_BIN_NAME_pre.bin
aswest sign
input.- Default
KERNEL_BIN_NAME.bin
aswest sign
output
When there is no signing, just copy the file. Print some warning that this is a mere copy.
This keeps everything "immutable": files and filenames. It's the best design from a ninja perspective and build troubleshooting perspective.
I believe the others tools change property bin_file ...
This area has always been a mess and I don't think there is a need to be "consistent" with other products there. Are they even consistent with each other in the first place? Consistency helps because it reduces cognitive load. But how many people sign different products on a regular basis? Very few if any.
BTW, for another example of a similar problem please search _prebuilt
in zephyr/CMakeLists.txt
fd7c629
to
c654ef2
Compare
c654ef2
to
ddd06a8
Compare
ddd06a8
to
fbdbfca
Compare
scripts/west_commands/sign.py
Outdated
|
||
# Setting the input and output file directories | ||
input_rps = b / 'zephyr' / "zephyr.bin.rps" | ||
output_rps = args.sbin or (b / 'zephyr' / "zephyr_signed.bin.rps") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I belive you need to honor CONFIG_KERNEL_BIN_NAME
:
kernel_name = build_conf.get('CONFIG_KERNEL_BIN_NAME')
input_rps = str(b / 'zephyr' / f'{kernel_name}.bin.rps')
output_rps = str(b / 'zephyr' / f'{kernel_name}_signed.bin.rps')
scripts/west_commands/sign.py
Outdated
group.add_argument('-t', '--tool', choices=['imgtool', 'rimage'], | ||
help='''image signing tool name; imgtool and rimage | ||
group.add_argument('-t', '--tool', choices=['imgtool', 'rimage', 'silabs_commander'], | ||
help='''image signing tool name; imgtool ,rimage and silabs_commander |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
space should after the colon.
config SIWX91X_PRIVATE_KEY | ||
string "Private Key Path for Signing." | ||
help | ||
Path to private key file for signing with Silicon Labs Commander. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't you think we should mention "UG574: SiWx917 SoC Manufacturing Utility User Guide" somewhere?
soc/silabs/silabs_siwx91x/Kconfig
Outdated
config SIWX91X_OTA_KEY | ||
string "OTA Key for Encryption." | ||
help | ||
Specifies OTA key (hex) for signing/encryption with Silicon Labs Commander. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this key only used for OTA or it also works for encrypted XiP ?
BTW, commander uses mic
, encrypt
and sign
. I feel, it would make sense to name these option SIWX91X_ENCRYPT_KEY
and SIWX91X_SIGN_KEY
.
(BTW, the help message use "signing/encryption" while this key used for integrity check and encryption)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(BTW, the help message use "signing/encryption" while this key used for integrity check and encryption)
Indeed, it's not very clear what does what.
I agree that you should stick to the commander tool terminology. Ideally:
--mic
-> SIWX91X_MIC_KEY
--encrypt
-> SIWX91X_ENCRYPT_KEY
--sign
-> SIWX91X_SIGN_KEY
If that's not possible then stay as close as possible.
If the commander tool terminology is confusing in the first place, then add plenty comments and help text to explain it but do not try to rename anything for a "better" interface. That adds even more confusion.
scripts/west_commands/sign.py
Outdated
if not siwx91x_ota_key: | ||
command.die("SIWX91X_OTA_KEY not provided. Use --siwx91x-ota-key=your_key or add CONFIG_SIWX91X_OTA_KEY in prj.conf.") | ||
if not siwx91x_private_key: | ||
command.die("SIWX91X_PRIVATE_KEY not provided. Use --siwx91x-private-key=/path/to/key or add CONFIG_SIWX91X_PRIVATE_KEY in prj.conf.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This behavior does not match with diagram "Secure Firmware Update Flowchart" in
"AN1431: SiWx917 SoC Firmware Update Application Note". Commander also allows to use every option separately.
soc/silabs/silabs_siwx91x/Kconfig
Outdated
config SIWX91X_OTA_KEY | ||
string "OTA Key for Encryption." | ||
help | ||
Specifies OTA key (hex) for signing/encryption with Silicon Labs Commander. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Specifies OTA key (hex) for signing/encryption with Silicon Labs Commander. | |
Specifies Over-The-Air key (hex) for signing/encryption with Silicon Labs Commander. |
scripts/west_commands/sign.py
Outdated
if not siwx91x_ota_key: | ||
command.die("SIWX91X_OTA_KEY not provided. Use --siwx91x-ota-key=your_key or add CONFIG_SIWX91X_OTA_KEY in prj.conf.") | ||
if not siwx91x_private_key: | ||
command.die("SIWX91X_PRIVATE_KEY not provided. Use --siwx91x-private-key=/path/to/key or add CONFIG_SIWX91X_PRIVATE_KEY in prj.conf.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could drop CONFIG_SIWX91X_SILABS_COMMANDER_SIGN, make each key argument optional and use them as a toggle.
If none of them is found, then have west sign
print a warning and just copy the file without signing or encrypting (e.g., copy zephyr_pre.rps
-> zephyr.rps
). This also avoids outputs with variable filenames: no matter what you do, the build always produces the same files. Also, west sign
always runs. Fewer conditionals; simpler flow.
Commander also allows to use every option separately.
So, imagine the user wants to encrypt without signing. Is the final file going to be have some _signed
suffix in its name anyway? Confusing. If you never use any _signed
suffix in the first place then you don't have that problem. The final filename is always the final file no matter how the build is configured.
I speak from direct and painful experience dealing with builds that produce variable filenames: don't do it.
ca2a918
to
f91537b
Compare
Added changes to automate the signing of zephyr security using Simplicity Commander during the west build process. Upstream-status: pr <zephyrproject-rtos#87669> Signed-off-by: Aasim Shaik <[email protected]>
f91537b
to
0351532
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The picture is getting a bit clearer but the user interface is still confusing.
As of 0351532, it looks like you're forcing the users to define _KEY strings even when the corresponding boolean is false. You seem to be forcing this in two ways:
CONFIG_SIWX91X_OTA_ENCRYPT_KEY
exists even whenCONFIG_SIWX91X_SILABS_ENCRYPT
disables it.- The following checks are run even when the corresponding boolean is false and the key not used:
if not siwx91x_ota_sign_key:
command.die("SIWX91X_OTA_SIGN_KEY not provided. Use --siwx91x-ota-sign-key=/path/to/key or add CONFIG_SIWX91X_OTA_SIGN_KEY in prj.conf."
I think the key problem and the main reason why we seem to be going around in circles a bit is: you don't know yet what the user interface must be. Prototyping is useful and the code in this PR is currently even beyond a great prototype. But at some point one must take a step back from the code and define precisely what features and possibilities this code is meant to provide users. Documentation usually defines that and interestingly enough this PR does not provide any documentation.
So, I think what this PR misses the most is a new section in doc/develop/west/sign.rst
. Take a look at 1df0781 for inspiration.
EDIT: new sign.rst section now added, thanks!
board_runner_args(silabs_commander "--device=SiWG917M111GTBA" "--file-type=bin" | ||
"--file=${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}.rps") | ||
"--file=${FLASH_FILE}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So FLASH_FILE has a _signed
suffix even when CONFIG_SIWX91X_SILABS_SIGN
is false? That does not seem to make sense.
Just drop _signed
and keep the filenames constant and CONFIG-independent, see #87669 (comment)
sign_base.extend(["--encrypt", str(siwx91x_ota_encrypt_key)]) | ||
|
||
if siwx91x_sign_enable: | ||
sign_base.extend(["--sign", str(siwx91x_ota_sign_key)]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is "OTA" everywhere in the key names but no "OTA" in the name of the booleans? This inconsistency gives the impression that there is some subtle difference between the keys and the booleans. But this code looks like there is none. Confusing.
0351532
to
5df1b45
Compare
Added changes to automate the signing of zephyr security using customtool during the west build process. Signed-off-by: Aasim Shaik <[email protected]>
5df1b45
to
eef65bb
Compare
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @Aasimshaik11 for the new sign.rst
section! Makes a big difference IMHO.
Now we need someone very familiar with https://www.silabs.com/documents/public/user-guides/ug574-siwx917-soc-manufacturing-utility-user-guide.pdf to review that sign.rst
section and user interface. @jerome-pouiller is that you?
I have resolved all the comments from @asmellby , @jerome-pouiller , @jhedberg , and @pdgendt . Could you mark these comments as resolved and provide any further suggestions or approval for my PR?
I second that: this PR has got old and long and a lot of comments are either resolved or now irrelevant. Yet they are still open. I just reviewed and closed mine. @asmellby and @jerome-pouiller please do the same so this PR becomes less noisy and somewhat readable again.
@Aasimshaik11 , please be cautious but if you applied someone 's suggestion EXACTLY, then you can close it yourself:
https://docs.zephyrproject.org/latest/contribute/contributor_expectations.html#workflow-suggestions-that-help-reviewers
Especially if that suggestion is very old: reviewers had their chance.
Also, if someone made a minor typo or codestyle suggestion on some code that does not even exist anymore, then you can close those too. Just make sure you don't close any higher level, more "philosophical" design discussion. These don't need to be closed before merge.
Another option is to abandon this PR and open a fresh new one (that links to the older one). We're probably not there yet but getting close?
Happened in #92181 by @jerome-pouiller |
Added changes to automate the signing of zephyr security using customtool during the west build process.