Skip to content

TPM locality control + optional nRST reset HAL#546

Open
dgarske wants to merge 2 commits into
wolfSSL:masterfrom
dgarske:fwtpm_locality_enforce
Open

TPM locality control + optional nRST reset HAL#546
dgarske wants to merge 2 commits into
wolfSSL:masterfrom
dgarske:fwtpm_locality_enforce

Conversation

@dgarske

@dgarske dgarske commented Jul 2, 2026

Copy link
Copy Markdown
Member

Adds runtime TPM locality selection, fixes the fwTPM's per-PCR locality enforcement, and adds an optional hardware-reset HAL. Verified on a real ST33KTPM (SPI) and the fwTPM software TPM.

Runtime TPM locality control

wolfTPM2_SetLocality() switches the active locality at runtime - over the built-in TIS/SPI driver (ACCESS handshake, with a 0xFF guard and startup self-heal) and over the fwTPM on both its socket and TIS/SHM transports. examples/pcr/reset gains -loc=n. This makes PCRs that are not resettable at locality 0 (e.g. 20-22 at loc 2/3, 17-19 at loc 4) reachable where the platform allows.

fwTPM per-PCR locality enforcement (fix)

The fwTPM's PCR locality checks were incorrect and incomplete. Replaced with one source-of-truth table (per the TCG PC Client profile) driving reset and extend: fixes the reset map (PCR 18/19 wrongly allowed loc 3, 20-22 wrongly rejected loc 2), adds the missing PCR-extend locality check (DRTM PCRs were freely extendable from loc 0), and makes TPM2_GetCapability(TPM_CAP_PCR_PROPERTIES) report proper RESET_L*/EXTEND_L*/DRTM_RESET bitmaps.

Optional TPM reset (nRST) HAL

--enable-hal-reset adds TPM2_IoCb_Reset(), which pulses nRST via the Linux GPIO char device (raw GPIO v2 uAPI, no libgpiod). Default line: ST33 = GPIO24 (Pi pin 18), Nuvoton = GPIO4; overridable.

Testing

  • fwTPM unit tests (reset/extend map + capability report) and an end-to-end fwtpm_check.sh locality check run in CI across both socket and TIS/SHM modes; a new CI job compiles --enable-hal-reset.
  • Builds clean: default, --enable-fwtpm, --enable-fwtpm --enable-swtpm, --enable-hal-reset.

@dgarske dgarske requested a review from aidangarske July 2, 2026 23:25
@dgarske dgarske self-assigned this Jul 2, 2026
Copilot AI review requested due to automatic review settings July 2, 2026 23:25
@dgarske dgarske requested a review from tmael July 2, 2026 23:26

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

Adds runtime TPM locality switching across supported transports, corrects fwTPM per-PCR locality enforcement for reset/extend (and capability reporting), and introduces an optional Linux GPIO-based nRST reset hook in the example HAL.

Changes:

  • Add wolfTPM2_SetLocality() plus TIS-side locality request/release helpers and updated startup locality acquisition behavior.
  • Fix and harden fwTPM locality behavior: correct per-PCR reset map, add missing per-PCR extend enforcement, and generate TPM_CAP_PCR_PROPERTIES from the same source-of-truth table.
  • Add optional --enable-hal-reset support with a Linux GPIO char-device implementation and CI compile coverage.

Reviewed changes

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

Show a summary per file
File Description
wolftpm/tpm2_wrap.h Public wrapper API docs for runtime locality switching.
wolftpm/tpm2_tis.h Adds locality timeout macro and TIS locality request/release declarations.
wolftpm/fwtpm/fwtpm.h Tracks active command locality plus TIS-transport locality ownership state.
wolftpm/fwtpm/fwtpm_tis.h Clarifies TIS address/locality encoding for fwTPM TIS transport.
src/tpm2.c Startup now proactively relinquishes stale locality ownership before requesting default locality.
src/tpm2_wrap.c Implements wolfTPM2_SetLocality() for SWTPM and TIS backends.
src/tpm2_tis.c Adds TPM2_TIS_RequestLocalityEx() and TPM2_TIS_ReleaseLocality() and hardens locality grant detection.
src/fwtpm/fwtpm_tis.c fwTPM TIS transport now grants/releases the requested locality and passes it into command processing.
src/fwtpm/fwtpm_command.c Adds a per-PCR locality table and enforces it for reset/extend/event paths; reports PCR properties from that table.
tests/fwtpm_unit_tests.c Adds unit tests covering reset/extend locality enforcement and PCR properties reporting.
tests/fwtpm_check.sh Adds end-to-end locality reset checks via examples/pcr/reset.
examples/pcr/reset.c Adds -loc=n to exercise runtime locality switching before PCR reset.
examples/pcr/README.md Documents locality requirements for PCR reset and -loc usage.
examples/run_examples.sh Adds a locality exercise for PCR reset example where supported.
README.md Documents Raspberry Pi wiring and optional nRST reset HAL availability.
hal/tpm_io.h Declares optional TPM2_IoCb_Reset() API when WOLFTPM_HAL_RESET is enabled.
hal/tpm_io.c Adds reset HAL dispatch stub (TPM2_IoCb_Reset).
hal/tpm_io_linux.c Implements Linux GPIO v2 char-device nRST pulse logic.
hal/README.md Documents reset HAL option and macros.
examples/spdm/README.md Updates reset-line guidance and references TPM2_IoCb_Reset() support.
configure.ac Adds --enable-hal-reset[=LINE] configure option and build flag plumbing.
.github/workflows/make-test-swtpm.yml Adds a CI compile-only job for --enable-hal-reset.

Comment thread src/tpm2_wrap.c
Comment on lines +6726 to +6745
rc = TPM2_TIS_RequestLocalityEx(&dev->ctx, locality,
WOLFTPM_LOCALITY_TIMEOUT_TRIES);
if (rc < 0) {
/* No preemption: relinquish the current locality and retry */
(void)TPM2_TIS_ReleaseLocality(&dev->ctx, oldLocality);
rc = TPM2_TIS_RequestLocalityEx(&dev->ctx, locality,
WOLFTPM_LOCALITY_TIMEOUT_TRIES);
if (rc < 0) {
/* Not grantable - restore the old locality so the TPM stays usable */
(void)TPM2_TIS_RequestLocalityEx(&dev->ctx, oldLocality,
WOLFTPM_LOCALITY_TIMEOUT_TRIES);
}
}
else if (oldLocality < locality) {
/* Preempted the lower locality; relinquish it now */
(void)TPM2_TIS_ReleaseLocality(&dev->ctx, oldLocality);
}
if (rc >= 0) {
rc = TPM_RC_SUCCESS;
}
Comment thread src/tpm2_tis.c
Comment on lines +355 to +358
if (TPM2_TIS_CheckLocality(ctx, l, &access) == TPM_RC_SUCCESS &&
(access & TPM_ACCESS_ACTIVE_LOCALITY)) {
(void)TPM2_TIS_ReleaseLocality(ctx, l);
}
Comment thread src/fwtpm/fwtpm_tis.c
Comment on lines +94 to +98
if (ctx->tisLocality < 0 || ctx->tisLocality == loc) {
ctx->tisLocality = loc;
regs->sts = TisBuildSts(
FWTPM_STS_VALID | FWTPM_STS_COMMAND_READY,
FWTPM_TIS_BURST_COUNT);
Comment thread src/fwtpm/fwtpm_tis.c
Comment on lines +103 to +105
if (ctx->tisLocality == loc) {
ctx->tisLocality = -1;
regs->sts = TisBuildSts(0, 0);
Comment thread hal/README.md
* `WOLFTPM_CHECK_WAIT_STATE`: Enables check of the wait state during a SPI transaction. Most TPM 2.0 chips require this and typically only require 0-2 wait cycles depending on the command. Only the Infineon TPM's guarantee no wait states.
* `WOLFTPM_ADV_IO`: Enables advanced IO callback mode that includes TIS register and read/write flag. This is requires for I2C, but can be used with SPI also.
* `WOLFTPM_DEBUG_IO`: Enable logging of the IO (if using the example HAL).
* `WOLFTPM_HAL_RESET`: Optional TPM hardware reset (nRST) control in the example HAL (`--enable-hal-reset`). On Linux, `TPM2_IoCb_Reset(dev->ctx, userCtx)` pulses nRST (active low) via the GPIO char device (raw GPIO v2 uAPI, no libgpiod).
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