Skip to content

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Aasimshaik11
Copy link

Added changes to automate the signing of zephyr security using customtool during the west build process.

Copy link

Hello @Aasimshaik11, and thank you very much for your first pull request to the Zephyr project!
Our Continuous Integration pipeline will execute a series of checks on your Pull Request commit messages and code, and you are expected to address any failures by updating the PR. Please take a look at our commit message guidelines to find out how to format your commit messages, and at our contribution workflow to understand how to update your Pull Request. If you haven't already, please make sure to review the project's Contributor Expectations and update (by amending and force-pushing the commits) your pull request if necessary.
If you are stuck or need help please join us on Discord and ask your question there. Additionally, you can escalate the review when applicable. 😊

@Aasimshaik11 Aasimshaik11 force-pushed the zephyr-boot-security branch 2 times, most recently from 7541fb9 to 7052317 Compare March 26, 2025 11:28
@Aasimshaik11 Aasimshaik11 force-pushed the zephyr-boot-security branch from 7052317 to da52b68 Compare April 4, 2025 06:46
@jerome-pouiller jerome-pouiller self-requested a review April 4, 2025 09:55
CMakeLists.txt Outdated
Copy link
Collaborator

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.

Copy link
Author

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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary comment, please remove.

Copy link
Author

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
Copy link
Collaborator

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.

Copy link
Author

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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to SoC level

Copy link
Author

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)
Copy link
Collaborator

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.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I resolved this

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved this comment

@@ -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
Copy link
Collaborator

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.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved this comment


# 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'
Copy link
Collaborator

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.

Copy link
Author

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
Copy link
Collaborator

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?

Copy link
Author

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.

Copy link
Collaborator

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.

Copy link
Author

@Aasimshaik11 Aasimshaik11 Apr 7, 2025

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

Copy link
Collaborator

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.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved this comments

@Aasimshaik11 Aasimshaik11 force-pushed the zephyr-boot-security branch 4 times, most recently from 726af6b to b9ddd52 Compare April 8, 2025 10:31
@Aasimshaik11 Aasimshaik11 marked this pull request as ready for review April 9, 2025 04:34
@github-actions github-actions bot added platform: Silabs Silicon Labs area: West West utility labels Apr 9, 2025
pdgendt
pdgendt previously requested changes Apr 9, 2025
@Aasimshaik11 Aasimshaik11 force-pushed the zephyr-boot-security branch 2 times, most recently from 6015f25 to d329322 Compare April 9, 2025 09:35
@pdgendt
Copy link
Collaborator

pdgendt commented Apr 9, 2025

Please, do not resolve comments as per the contribution guidelines.

@Aasimshaik11 Aasimshaik11 force-pushed the zephyr-boot-security branch 2 times, most recently from 82ac254 to 2a2c05b Compare April 9, 2025 11:29
elif current_config == 'M4_PRIVATE_KEY':
m4_private_key = value
elif current_config == 'COMMANDER_PATH':
commander_path = value
Copy link
Collaborator

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.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved this comment

@Aasimshaik11 Aasimshaik11 force-pushed the zephyr-boot-security branch from 437fe54 to fd7c629 Compare May 16, 2025 05:12
@jhedberg jhedberg requested a review from marc-hb May 16, 2025 16:01
board_runner_args(silabs_commander "--device=SiWG917M111GTBA" "--file-type=bin"
"--file=${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}.rps")
"--file=${FLASH_FILE}")
Copy link
Collaborator

@marc-hb marc-hb May 16, 2025

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.

Copy link
Collaborator

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)

Copy link
Collaborator

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?

Copy link
Collaborator

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:

  1. KERNEL_BIN_NAME_unsigned.bin or KERNEL_BIN_NAME_pre.bin as west sign input.
  2. Default KERNEL_BIN_NAME.bin as west 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

@Aasimshaik11 Aasimshaik11 force-pushed the zephyr-boot-security branch from c654ef2 to ddd06a8 Compare May 20, 2025 04:52
@Aasimshaik11 Aasimshaik11 requested a review from marc-hb May 20, 2025 04:52
@Aasimshaik11 Aasimshaik11 force-pushed the zephyr-boot-security branch from ddd06a8 to fbdbfca Compare May 22, 2025 09:39

# 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")
Copy link
Collaborator

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')

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
Copy link
Collaborator

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.
Copy link
Collaborator

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?

config SIWX91X_OTA_KEY
string "OTA Key for Encryption."
help
Specifies OTA key (hex) for signing/encryption with Silicon Labs Commander.
Copy link
Collaborator

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)

Copy link
Collaborator

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.

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.")
Copy link
Collaborator

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.

@jerome-pouiller jerome-pouiller self-requested a review May 22, 2025 15:17
config SIWX91X_OTA_KEY
string "OTA Key for Encryption."
help
Specifies OTA key (hex) for signing/encryption with Silicon Labs Commander.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Specifies OTA key (hex) for signing/encryption with Silicon Labs Commander.
Specifies Over-The-Air key (hex) for signing/encryption with Silicon Labs Commander.

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.")
Copy link
Collaborator

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.

@Aasimshaik11 Aasimshaik11 force-pushed the zephyr-boot-security branch 2 times, most recently from ca2a918 to f91537b Compare May 23, 2025 16:05
jerome-pouiller pushed a commit to jerome-pouiller/zephyr that referenced this pull request May 28, 2025
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]>
@Aasimshaik11 Aasimshaik11 force-pushed the zephyr-boot-security branch from f91537b to 0351532 Compare May 29, 2025 10:36
@Aasimshaik11 Aasimshaik11 requested a review from marc-hb May 29, 2025 10:37
Copy link
Collaborator

@marc-hb marc-hb left a 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 when CONFIG_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}")
Copy link
Collaborator

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)])
Copy link
Collaborator

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.

Added changes to automate the signing of zephyr security
using customtool during the west build process.

Signed-off-by: Aasim Shaik <[email protected]>
@Aasimshaik11 Aasimshaik11 force-pushed the zephyr-boot-security branch from 5df1b45 to eef65bb Compare May 30, 2025 10:43
Copy link

Copy link
Collaborator

@marc-hb marc-hb left a 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?

@marc-hb
Copy link
Collaborator

marc-hb commented Jun 25, 2025

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants