Skip to content

Add caller-supplied policy authorization for firmware upgrade - #560

Open
dgarske wants to merge 1 commit into
wolfSSL:masterfrom
dgarske:firmware_upgrade_policy_auth
Open

Add caller-supplied policy authorization for firmware upgrade#560
dgarske wants to merge 1 commit into
wolfSSL:masterfrom
dgarske:firmware_upgrade_policy_auth

Conversation

@dgarske

@dgarske dgarske commented Jul 24, 2026

Copy link
Copy Markdown
Member

Summary

Adds a supported way for callers to authorize the firmware-upgrade "start" command with their own platform-hierarchy policy, instead of the fixed library-managed authorization (Infineon: an internal PolicyCommandCode; ST33: password/TPM_RS_PW). This lets deployments gate firmware upgrade behind a custom platform authPolicy, including multi-branch PolicyOR and SHA-2 384/512 policy digests for post-quantum use.

Features

  • New _ex APIs that accept a caller-satisfied authorization session: wolfTPM2_FirmwareUpgradeHash_ex(), wolfTPM2_FirmwareUpgrade_ex(), and wolfTPM2_FirmwareUpgradeRecover_ex(). The existing wolfTPM2_FirmwareUpgrade[Hash|Recover]() entry points now forward to the _ex form with a NULL session, so current behavior is unchanged.
  • New wolfTPM2_PolicyOR() wrapper over TPM2_PolicyOR (hash-agnostic; supports SHA-256 through SHA-512 branches, up to the TPML_DIGEST capacity).
  • When a caller session is supplied: Infineon no longer overwrites the platform primary policy (the caller provisions it), and ST33 uses the caller session in place of the default TPM_RS_PW.
  • Firmware examples (ifx_fw_update, st33_fw_update): a non-destructive --policytest self-test and --policy / --policyor end-to-end upgrade modes with a selectable policy hash (--sha256|--sha384|--sha512). The shared helpers live in one file (examples/firmware/firmware_policy.c) used by both tools. README documents the flow.

Fixes

  • wolfTPM2_PolicyOR() validates the branch count and each branch's digests[i].size against the digest buffer before marshaling, preventing an out-of-bounds read on a caller-supplied oversized size (CWE-125).
  • wolfTPM2_FirmwareUpgradeHash_ex() explicitly initializes rc on the caller-session path so it cannot use a stale value.
  • Firmware self-test now fails on any unexpected TPM error (only an intentional "hash not implemented" result is treated as a skip), and prints digests via an always-available hex helper rather than the debug-only TPM2_PrintBin.
  • Firmware examples skip a policy hash the TPM does not implement (via TPM_CAP_ALGS) instead of issuing a session that fails with TPM_RC_SIZE.
  • Caller policy session is released using an explicit "start consumed" flag rather than the aggregate return code, avoiding both a stale FlushContext and a leaked session.
  • The example clears any platform authPolicy it provisioned on a failure path so a later default-auth run is not locked out.
  • Example argument parsing rejects unrecognized options and extra arguments with a usage error.

Testing coverage

  • Unit tests (tests/unit_tests.c): test_wolfTPM2_PolicyOR covers the argument-validation branches (NULL args, count 0, count over capacity, per-branch size overflow) host-side with no TPM; the firmware test adds NULL-dev cases for the three _ex functions and asserts startSession == NULL matches the legacy call.
  • Backward compatibility: the legacy APIs forward to _ex with a NULL session; existing example flows are unchanged.
  • Hardware validation on a Raspberry Pi 5 (SPI):
    • ST33KTPM2X (Fw 9.x): real firmware upgrade 9.257 -> 9.258 driven by a caller-supplied policy session (--policy --sha256).
    • Infineon SLB9672 (Fw 15.21): real firmware upgrade 15.21 -> 15.23 driven by a caller session with both --policy and --policyor (confirms Infineon accepts a PolicyOR platform policy for the start command).
    • ST33KTPMQ (Fw 11.1): --policytest passes for SHA-256, SHA-384, and SHA-512.
    • --policytest across parts: SHA-256 and SHA-384 pass on ST33 and SLB9672; SHA-512 passes on SHA-512-capable firmware and is cleanly skipped elsewhere.
  • The --policytest self-test cross-checks the TPM's running policy digest (PolicyCommandCode + PolicyOR) against an offline computation and is non-destructive.

@dgarske dgarske self-assigned this Jul 24, 2026
Copilot AI review requested due to automatic review settings July 24, 2026 22:28

Copilot AI left a comment

Copy link
Copy Markdown

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 extends wolfTPM’s firmware-upgrade wrappers to support caller-supplied authorization sessions (e.g., policy sessions) for the vendor “firmware start” command, enabling platforms that gate upgrade behind custom platform hierarchy policies.

Changes:

  • Added a wolfTPM2_PolicyOR() wrapper to satisfy policy sessions via TPM2_PolicyOR.
  • Added wolfTPM2_FirmwareUpgradeHash_ex(..., startSession) and routed the legacy wolfTPM2_FirmwareUpgradeHash() through it (preserving existing behavior when startSession == NULL).
  • Updated the ST33 firmware update example and documentation to demonstrate/describe policy-based authorization and a safe self-test flow.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
wolftpm/tpm2_wrap.h Declares new wolfTPM2_PolicyOR wrapper and wolfTPM2_FirmwareUpgradeHash_ex API with caller-supplied session support.
src/tpm2_wrap.c Implements wolfTPM2_PolicyOR and adds the _ex firmware upgrade routing + vendor start-session plumbing.
examples/firmware/st33_fw_update.c Adds --policytest self-test to validate policy-session + PolicyOR behavior without performing an upgrade.
examples/firmware/README.md Documents advanced policy-based firmware start authorization and the new _ex API usage.

Comment thread src/tpm2_wrap.c

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Comment thread src/tpm2_wrap.c
Comment thread src/tpm2_wrap.c
@dgarske
dgarske force-pushed the firmware_upgrade_policy_auth branch from e738710 to 0b72b95 Compare August 3, 2026 20:53
@dgarske
dgarske force-pushed the firmware_upgrade_policy_auth branch from 0b72b95 to bda21be Compare August 3, 2026 21:17
@dgarske
dgarske marked this pull request as ready for review August 3, 2026 21:25
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