boot: bootutil: fault-injection hardening for RSA-PSS verification#2735
Open
d3zd3z wants to merge 2 commits into
Open
boot: bootutil: fault-injection hardening for RSA-PSS verification#2735d3zd3z wants to merge 2 commits into
d3zd3z wants to merge 2 commits into
Conversation
The RSA-PSS signature check in bootutil_cmp_rsasig() invoked the public-key modular exponentiation as a plain, unwrapped call with no fault-injection hardening around it. Add two defensive measures, in line with the FIH patterns used elsewhere in bootutil: - Route the bootutil_rsa_public() call through a thin FIH wrapper invoked via FIH_CALL, so that a skipped call is detected by control-flow integrity counting. - After the exponentiation, reject the signature if the output buffer is identical to the input. A correct RSA public-key operation does not produce that result, so equality indicates the exponentiation did not run as intended. A dedicated fih_ret variable is used for this comparison so that a later skipped check cannot leave a stale success value behind. Only the mbedTLS branch is affected. The PSA branch performs the verification inside the PSA implementation and is unchanged here. Assisted-By: Claude:opus-4.7 Signed-off-by: David Brown <david.brown@linaro.org>
With the PSA crypto backend, the RSA-PSS signature verification is performed by a single psa_verify_hash() call and the modular exponentiation runs inside the PSA implementation, where it is not reachable from MCUboot. The non-PSA path can inspect the exponentiation result directly; the PSA path cannot. Add an optional fault-injection countermeasure for the PSA path that runs the whole RSA-PSS verification a second time and requires both attempts to succeed. It is gated by a new configuration option so that users can pick the tradeoff that suits them, since the extra verification roughly doubles the (relatively expensive) RSA verify time. The new Kconfig option BOOT_RSA_PSA_DOUBLE_VERIFY defaults to enabled whenever a fault injection hardening profile is active, and disabled otherwise. Ports that do not define MCUBOOT_RSA_PSA_DOUBLE_VERIFY keep the previous single-verification behaviour. Assisted-By: Claude:opus-4.7 Signed-off-by: David Brown <david.brown@linaro.org>
There was a problem hiding this comment.
Pull request overview
This PR adds fault-injection hardening to RSA-PSS signature verification in MCUboot’s bootutil, aligning the RSA verification flow with existing FIH (fault injection hardening) patterns used elsewhere in the bootloader.
Changes:
- Non-PSA RSA-PSS path: route the RSA public operation through an
FIH_CALL-protected wrapper and add a post-operation “output != input” defensive check. - PSA RSA-PSS path: add an optional, Kconfig-controlled “double verify” mode that repeats
psa_verify_hash()and requires both attempts to succeed. - Zephyr integration: introduce
BOOT_RSA_PSA_DOUBLE_VERIFYand map it toMCUBOOT_RSA_PSA_DOUBLE_VERIFY, plus document the setting in the sample config template.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| samples/mcuboot_config/mcuboot_config.template.h | Documents the new optional MCUBOOT_RSA_PSA_DOUBLE_VERIFY hardening knob for PSA-based RSA verification. |
| boot/zephyr/Kconfig | Adds BOOT_RSA_PSA_DOUBLE_VERIFY, default-enabled when a non-OFF FIH profile is selected. |
| boot/zephyr/include/mcuboot_config/mcuboot_config.h | Maps CONFIG_BOOT_RSA_PSA_DOUBLE_VERIFY to MCUBOOT_RSA_PSA_DOUBLE_VERIFY for Zephyr builds. |
| boot/bootutil/src/image_rsa.c | Implements FIH-wrapped RSA public operation for the non-PSA path and optional redundant verification for the PSA path. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This series adds fault-injection hardening around the RSA-PSS signature verification in
bootutil, in line with the FIH patterns already used elsewhere in the bootloader.Changes
1. Harden the non-PSA RSA-PSS verification path
bootutil_cmp_rsasig()previously invoked the public-key modular exponentiation as a plain, unwrapped call with no hardening around it. Two defensive measures are added:bootutil_rsa_public()call is routed through a thinFIHwrapper invoked viaFIH_CALL, so a skipped call is caught by control-flow integrity counting, consistent with the rest ofbootutil.fih_retvariable is used for this comparison so a later skipped check cannot leave a stale success value behind.2. Optional redundant RSA-PSS verification for the PSA crypto path
With the PSA crypto backend the verification is a single
psa_verify_hash()call and the modular exponentiation runs inside the PSA implementation, where it is not reachable from MCUboot. A new optional countermeasure runs the whole RSA-PSS verification a second time and requires both attempts to succeed.It is gated by a new Kconfig option,
BOOT_RSA_PSA_DOUBLE_VERIFY, because the extra verification roughly doubles the RSA verify time and different users will want different tradeoffs. The option defaults to enabled whenever a fault injection hardening profile is active, and disabled otherwise. Ports that do not defineMCUBOOT_RSA_PSA_DOUBLE_VERIFYkeep the previous single-verification behaviour. Hardening of the modular exponentiation itself remains the responsibility of the PSA crypto implementation.Testing
cargo test --features sig-rsaand--features sig-rsa3072: all pass; legitimately signed images still validate.OFF/LOW/MEDIUM/HIGH).MCUBOOT_RSA_PSA_DOUBLE_VERIFY.bootutil_cmp_rsasig()to reject the image, confirming the new check fires.