Skip to content

boot: bootutil: fault-injection hardening for RSA-PSS verification#2735

Open
d3zd3z wants to merge 2 commits into
mcu-tools:mainfrom
d3zd3z:fix-rsa-fault
Open

boot: bootutil: fault-injection hardening for RSA-PSS verification#2735
d3zd3z wants to merge 2 commits into
mcu-tools:mainfrom
d3zd3z:fix-rsa-fault

Conversation

@d3zd3z
Copy link
Copy Markdown
Member

@d3zd3z d3zd3z commented May 14, 2026

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:

  • The bootutil_rsa_public() call is routed through a thin FIH wrapper invoked via FIH_CALL, so a skipped call is caught by control-flow integrity counting, consistent with the rest of bootutil.
  • After the exponentiation, the signature is rejected if the output buffer is identical to the input. A correct RSA public-key operation does not produce that result. A dedicated fih_ret variable 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 define MCUBOOT_RSA_PSA_DOUBLE_VERIFY keep the previous single-verification behaviour. Hardening of the modular exponentiation itself remains the responsibility of the PSA crypto implementation.

Testing

  • cargo test --features sig-rsa and --features sig-rsa3072: all pass; legitimately signed images still validate.
  • The non-PSA path compiles cleanly under all four FIH profiles (OFF/LOW/MEDIUM/HIGH).
  • The PSA path compiles cleanly with and without MCUBOOT_RSA_PSA_DOUBLE_VERIFY.
  • Negative check: temporarily forcing the exponentiation output to equal its input causes bootutil_cmp_rsasig() to reject the image, confirming the new check fires.

d3zd3z added 2 commits May 14, 2026 14:09
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>
Copilot AI review requested due to automatic review settings May 14, 2026 20:12
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

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_VERIFY and map it to MCUBOOT_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.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants