Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions .github/workflows/fwtpm-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,88 @@ jobs:
build_only: true
extra_cflags: -DFWTPM_NO_PARAM_ENC

# Build-only: finer per-command-group FWTPM_NO_* macros
- name: fwtpm-no-key-migration

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

🟠 [Medium] New feature gates receive no behavioral/runtime test coverage · Missing Tests

Every newly added matrix configuration sets build_only: true and no test or example source references any of the six new macros, so CI verifies compilation only. It never checks that a gated command returns TPM_RC_COMMAND_CODE, disappears from TPM_CAP_COMMANDS, or updates TPM_PT_TOTAL_COMMANDS, nor that the FWTPM_NO_HASH_CMDS + MLDSA sequence path works. This gap is exactly what let the retained-but-unusable MLDSA SequenceComplete entry pass. Additionally, the documented all-gates ECC-only/NO_RSA minimal configuration is not built because the all-gates entry does not disable RSA. Severity views differ (review: Medium; review-security: Low); stricter Medium kept.

Fix: Add at least one runtime gated configuration that checks command rejection and capability/count reporting, plus an MLDSA sequence test under FWTPM_NO_HASH_CMDS. Also build the documented all-gates ECC-only/NO_RSA configuration.

os: ubuntu-latest
wolftpm_config: --enable-fwtpm --enable-swtpm
wolfssl_config: --enable-wolftpm --enable-pkcallbacks --enable-keygen
build_only: true
extra_cflags: -DFWTPM_NO_KEY_MIGRATION

- name: fwtpm-no-ecdh
os: ubuntu-latest
wolftpm_config: --enable-fwtpm --enable-swtpm
wolfssl_config: --enable-wolftpm --enable-pkcallbacks --enable-keygen
build_only: true
extra_cflags: -DFWTPM_NO_ECDH

- name: fwtpm-no-hash-cmds
os: ubuntu-latest
wolftpm_config: --enable-fwtpm --enable-swtpm
wolfssl_config: --enable-wolftpm --enable-pkcallbacks --enable-keygen
build_only: true
extra_cflags: -DFWTPM_NO_HASH_CMDS

- name: fwtpm-no-context
os: ubuntu-latest
wolftpm_config: --enable-fwtpm --enable-swtpm
wolfssl_config: --enable-wolftpm --enable-pkcallbacks --enable-keygen
build_only: true
extra_cflags: -DFWTPM_NO_CONTEXT

- name: fwtpm-no-sym-encrypt
os: ubuntu-latest
wolftpm_config: --enable-fwtpm --enable-swtpm
wolfssl_config: --enable-wolftpm --enable-pkcallbacks --enable-keygen
build_only: true
extra_cflags: -DFWTPM_NO_SYM_ENCRYPT

- name: fwtpm-no-clock
os: ubuntu-latest
wolftpm_config: --enable-fwtpm --enable-swtpm
wolfssl_config: --enable-wolftpm --enable-pkcallbacks --enable-keygen
build_only: true
extra_cflags: -DFWTPM_NO_CLOCK

# Build-only: all command-group gates enabled together (there is no
# umbrella macro; each flag is set explicitly), standalone and combined
# with MLDSA (which shares the sequence commands)
- name: fwtpm-all-gates
os: ubuntu-latest
wolftpm_config: --enable-fwtpm --enable-swtpm
wolfssl_config: --enable-wolftpm --enable-pkcallbacks --enable-keygen
build_only: true
extra_cflags: >-
-DFWTPM_NO_POLICY
-DFWTPM_NO_ATTESTATION
-DFWTPM_NO_CREDENTIAL
-DFWTPM_NO_DA
-DFWTPM_NO_PARAM_ENC
-DFWTPM_NO_KEY_MIGRATION
-DFWTPM_NO_ECDH
-DFWTPM_NO_HASH_CMDS
-DFWTPM_NO_CONTEXT
-DFWTPM_NO_SYM_ENCRYPT
-DFWTPM_NO_CLOCK

- name: fwtpm-all-gates-mldsa
os: ubuntu-latest
wolftpm_config: --enable-fwtpm --enable-swtpm --enable-v185 --enable-mldsa
wolfssl_config: --enable-wolftpm --enable-pkcallbacks --enable-keygen --enable-experimental --enable-mldsa
build_only: true
extra_cflags: >-
-DFWTPM_NO_POLICY
-DFWTPM_NO_ATTESTATION
-DFWTPM_NO_CREDENTIAL
-DFWTPM_NO_DA
-DFWTPM_NO_PARAM_ENC
-DFWTPM_NO_KEY_MIGRATION
-DFWTPM_NO_ECDH
-DFWTPM_NO_HASH_CMDS
-DFWTPM_NO_CONTEXT
-DFWTPM_NO_SYM_ENCRYPT
-DFWTPM_NO_CLOCK

# Build-only: cross-algorithm + feature macro combinations
- name: fwtpm-no-rsa-no-policy
os: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Features:
* TIS register-level transport over shared memory or SPI/I2C for bare-metal integration
* HAL abstractions for IO transport and NV storage portability
* File-based or custom NV storage via HAL callbacks
* Compile-time algorithm and feature selection (e.g., `NO_RSA`, `FWTPM_NO_NV`)
* Compile-time algorithm and per-command-group feature selection (e.g., `NO_RSA`, `FWTPM_NO_NV`, and independent per-command-group gates you pick and choose to shrink the fTPM footprint)
* `WOLFTPM_SMALL_STACK` support for constrained environments

See [docs/FWTPM.md](docs/FWTPM.md) for build instructions, configuration, and API reference.
Expand Down
31 changes: 26 additions & 5 deletions docs/FWTPM.md
Original file line number Diff line number Diff line change
Expand Up @@ -664,22 +664,43 @@ to reduce code size on constrained targets.
| `FWTPM_NO_POLICY` | not defined | `PolicyGetDigest`, `PolicyRestart`, `PolicyPCR`, `PolicyPassword`, `PolicyAuthValue`, `PolicyCommandCode`, `PolicyOR`, `PolicySecret`, `PolicyAuthorize`, `PolicyNV` |
| `FWTPM_NO_CREDENTIAL` | not defined | `MakeCredential`, `ActivateCredential` |
| `FWTPM_NO_DA` | not defined | `DictionaryAttackParameters`, `DictionaryAttackLockReset`, and all lockout accounting |
| `FWTPM_NO_PARAM_ENC` | not defined | command/response parameter (XOR/AES-CFB) encryption support in sessions |
| `FWTPM_NO_KEY_MIGRATION` | not defined | `Import`, `Duplicate`, `Rewrap` |
| `FWTPM_NO_ECDH` | not defined | `ECDH_KeyGen`, `ECDH_ZGen`, `EC_Ephemeral`, `ZGen_2Phase`, `ECC_Parameters` (ECDSA sign/verify retained) |
| `FWTPM_NO_HASH_CMDS` | not defined | `Hash`, `HMAC`, `HMAC_Start`, `HashSequenceStart`, `SequenceUpdate`, `SequenceComplete`, `EventSequenceComplete` |
| `FWTPM_NO_CONTEXT` | not defined | `ContextSave`, `ContextLoad` (`FlushContext` retained) |
| `FWTPM_NO_SYM_ENCRYPT` | not defined | `EncryptDecrypt`, `EncryptDecrypt2` |
| `FWTPM_NO_CLOCK` | not defined | `ReadClock`, `ClockSet`, `ClockRateAdjust` |

Removing a command group also removes it from the `TPM2_GetCapability(TPM_CAP_COMMANDS)` advertisement and the `TPM_PT_TOTAL_COMMANDS` count, since both are derived from the dispatch table. Note: when `WOLFTPM_MLDSA` is built, `SequenceUpdate`/`SequenceComplete` are retained even under `FWTPM_NO_HASH_CMDS` because the MLDSA sign-sequence commands share them.

The `FWTPM_DA_USED_RETRY` macro (off by default) does not remove commands; it
makes the server return `TPM_RC_RETRY` on the first DA-protected auth use after
startup, emulating a real TPM persisting `daUsed`. See
[Dictionary Attack (DA) Protection](#dictionary-attack-da-protection).

**Minimal build example** (measured boot only):
**Minimal build example.** There is no umbrella macro - select the command
groups to drop explicitly, so each is a deliberate choice. For example, to build
a small ECC-only signing + NV fTPM (this set drops attestation; keep
`Sign`/`VerifySignature`, PCR, and NV):

```sh
./configure --enable-fwtpm --enable-swtpm \
CFLAGS="-DNO_RSA -DFWTPM_NO_NV -DFWTPM_NO_ATTESTATION \
-DFWTPM_NO_POLICY -DFWTPM_NO_CREDENTIAL"
CFLAGS="-DNO_RSA \
-DFWTPM_NO_POLICY -DFWTPM_NO_ATTESTATION -DFWTPM_NO_CREDENTIAL \
-DFWTPM_NO_DA -DFWTPM_NO_PARAM_ENC -DFWTPM_NO_KEY_MIGRATION \
-DFWTPM_NO_ECDH -DFWTPM_NO_HASH_CMDS -DFWTPM_NO_CONTEXT \
-DFWTPM_NO_SYM_ENCRYPT -DFWTPM_NO_CLOCK"
```

This retains only: `Startup`, `Shutdown`, `SelfTest`, `GetRandom`, `GetCapability`,
`PCR_Read`, `PCR_Extend`, `PCR_Reset`, `Hash`, ECC keygen/sign, and session support.
That set retains a core fTPM: `Startup`, `Shutdown`, `SelfTest`, `GetRandom`,
`GetCapability`, the `PCR_*` commands, `Create`/`CreatePrimary`/`Load`/
`ReadPublic`/`FlushContext`, `Sign`/`VerifySignature`, the `NV_*` commands, and
session support (`StartAuthSession`/`Unseal`). Add `-DFWTPM_NO_NV` to also drop
NV, or drop any `-DFWTPM_NO_*` above to keep that group. This ECC-only build is
small enough to run as a soft-core fTPM on a constrained FPGA (see the MicroBlaze
V example in the `wolftpm-examples` repo, which fits an ECC-only fTPM into
~192 KB of on-chip memory).

**Dependencies:**
- `FWTPM_NO_NV` also removes `NV_Certify` (even if `FWTPM_NO_ATTESTATION` is not set)
Expand Down
28 changes: 28 additions & 0 deletions src/fwtpm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,14 @@ All tests below run in GitHub Actions CI. Run manually before PR submission.
| fwtpm-no-credential | `--enable-fwtpm --enable-swtpm` | | `-DFWTPM_NO_CREDENTIAL` |
| fwtpm-no-da | `--enable-fwtpm --enable-swtpm` | | `-DFWTPM_NO_DA` |
| fwtpm-no-param-enc | `--enable-fwtpm --enable-swtpm` | | `-DFWTPM_NO_PARAM_ENC` |
| fwtpm-no-key-migration | `--enable-fwtpm --enable-swtpm` | | `-DFWTPM_NO_KEY_MIGRATION` |
| fwtpm-no-ecdh | `--enable-fwtpm --enable-swtpm` | | `-DFWTPM_NO_ECDH` |
| fwtpm-no-hash-cmds | `--enable-fwtpm --enable-swtpm` | | `-DFWTPM_NO_HASH_CMDS` |
| fwtpm-no-context | `--enable-fwtpm --enable-swtpm` | | `-DFWTPM_NO_CONTEXT` |
| fwtpm-no-sym-encrypt | `--enable-fwtpm --enable-swtpm` | | `-DFWTPM_NO_SYM_ENCRYPT` |
| fwtpm-no-clock | `--enable-fwtpm --enable-swtpm` | | `-DFWTPM_NO_CLOCK` |
| fwtpm-all-gates | `--enable-fwtpm --enable-swtpm` | | the eleven command-group `-DFWTPM_NO_*` gates together (NV retained) |
| fwtpm-all-gates-mldsa | `--enable-fwtpm --enable-swtpm --enable-v185 --enable-mldsa` | | the eleven command-group `-DFWTPM_NO_*` gates together (NV retained) |
| fwtpm-no-rsa-no-policy | `--enable-fwtpm --enable-swtpm` | `--disable-rsa` | `-DFWTPM_NO_POLICY` |
| fwtpm-no-ecc-no-nv | `--enable-fwtpm --enable-swtpm` | `--disable-ecc` | `-DFWTPM_NO_NV` |
| fwtpm-small-stack | `--enable-fwtpm --enable-swtpm` | | `-DWOLFTPM_SMALL_STACK` |
Expand Down Expand Up @@ -221,6 +229,26 @@ EncryptDecrypt, EncryptDecrypt2
- `FWTPM_NO_PARAM_ENC`: Disables parameter encryption/decryption for command and
response parameters. Sessions still work for HMAC auth, but encrypted transport
is disabled. Reduces code size by removing AES-CFB and XOR param encryption.
- `FWTPM_NO_KEY_MIGRATION`: Import, Duplicate, Rewrap (3 commands). Shared key

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

🟠 [Medium] Command coverage docs still label newly gated commands as always enabled · Documentation

The new macro descriptions say commands such as ReadClock, ContextSave, hash sequences, and Import can be disabled, while the preceding command-coverage section still lists them under "Always enabled (47 commands)". The new feature makes that count and category inaccurate for gated builds.

Fix: Rename that section to describe the default command set, or move the newly gated commands into conditional groups and adjust the count. Also include the six new macros in the earlier feature-disable macro summary.

helpers (used by Create/Load) are retained.
- `FWTPM_NO_ECDH`: ECDH\_KeyGen, ECDH\_ZGen, EC\_Ephemeral, ZGen\_2Phase,
ECC\_Parameters (5 commands). ECDSA sign/verify are retained.
- `FWTPM_NO_HASH_CMDS`: Hash, HMAC, HMAC\_Start, HashSequenceStart,
SequenceUpdate, SequenceComplete, EventSequenceComplete (7 commands). When
`WOLFTPM_MLDSA` is built, SequenceUpdate/SequenceComplete are retained because
the MLDSA sign-sequence commands share them.
- `FWTPM_NO_CONTEXT`: ContextSave, ContextLoad (2 commands). FlushContext is
retained.
- `FWTPM_NO_SYM_ENCRYPT`: EncryptDecrypt, EncryptDecrypt2 (2 commands). Nests
inside `NO_AES`; AES itself is retained for context protection and AES-GCM.
- `FWTPM_NO_CLOCK`: ReadClock, ClockSet, ClockRateAdjust (3 commands). GetTime is
under `FWTPM_NO_ATTESTATION`, not this flag.
These gates are independent and there is intentionally no umbrella macro: pick
exactly the groups your fTPM does not need. Applying all of them plus the earlier
`FWTPM_NO_POLICY/ATTESTATION/CREDENTIAL/DA/PARAM_ENC` (keeping NV, or adding
`FWTPM_NO_NV` to drop it) leaves a core fTPM (Startup/GetCapability/GetRandom/
PCR/Create/Load/Sign/VerifySignature/NV/sessions) - see the MicroBlaze V example
in wolftpm-examples for a worked selection.

### Missing Commands -- TODO

Expand Down
Loading
Loading