Skip to content

Commit e777fc0

Browse files
committed
Peer review feedback
Addresses the Skoll multi-scan findings on the caller-supplied firmware upgrade policy authorization work. wolfTPM2_PolicyCommandCodeMake: digestSz is now in/out. On input it is the output buffer capacity and BUFFER_E is returned when it is smaller than the hash size, checked before the buffer is zeroed or hashed into. Previously the function wrote hashSz bytes with no capacity known to it and overwrote *digestSz before hashing, so a short caller buffer was silently overrun. Updates the doxygen and the callers in the firmware and nvram examples. wolfTPM2_PolicyOR: require at least two branch digests. TPM 2.0 Part 3 Sec.23.6 mandates a minimum of two and the fwTPM reference implementation enforces it as TPM_RC_VALUE, so a one-branch list is now rejected with BAD_FUNC_ARG rather than sent to the TPM. Firmware upgrade _ex session contract: the vendor FieldUpgradeStart commands are hand-marshalled with an authorization area carrying only the session handle - empty nonceCaller, zero attributes and an empty HMAC. That is correct only for an unsalted, unbound policy session with no auth value, so wolfTPM2_FirmwareUpgradeHash_ex now validates the caller session up front and rejects any session needing a computed session HMAC or parameter encryption (PolicyAuthValue/PolicyPassword, attached auth value, bind, salt, encrypt/decrypt/audit attributes, or a non-policy session handle). Validation runs before any TPM traffic. The doxygen and README state the supported contract and that a successful start consumes the session. Firmware policy example cleanup: firmware_policy_clear now returns a status and reports failure instead of silently ignoring it, and is gated on a new FirmwarePolicyCtx that records what was actually provisioned - previously any early failure (a missing firmware file, for example) cleared the platform policy even when the example had never installed one, wiping a policy the deployment owned. The PolicyOR filler branch is replaced with PolicyCommandCode(TPM_CC_SetPrimaryPolicy) so the provisioned policy can authorize its own removal when platformAuth is not the default. A failed rollback now propagates to the example exit status. Note the review's premise that cleanup cannot clear the policy it installed is incorrect: per TPM 2.0 Part 1 Sec.19.7 a hierarchy is authorized by either its authValue or its authPolicy, so installing an authPolicy does not disable the password path that firmware_policy_clear uses. Confirmed on an ST33KTPM over SPI and pinned by a new regression test. Firmware examples build fix: ifx_fw_update and st33_fw_update drive wolfTPM2_FirmwareUpgrade_ex, which only exists with wolfCrypt (it hashes the manifest with SHA-384), but their feature guards did not require it. Building --enable-firmware with --disable-wolfcrypt failed to compile. The guards now include !WOLFTPM2_NO_WOLFCRYPT, matching the pattern used by the boot examples, and the not-compiled-in message says so. This break predates the policy work. Tests: minimum PolicyOR branch count, short-buffer and canary coverage for wolfTPM2_PolicyCommandCodeMake, caller-session rejection for every unsupported session shape plus an accepted session reaching the manufacturer dispatch, and a simulator-only regression test that a platform authPolicy is still clearable with password authorization while a non-matching policy session is refused. Documentation: README gains the session contract, a rewritten rollback section explaining which mode can roll back and how, and the policy options that were missing from the two usage blocks.
1 parent 04a9269 commit e777fc0

9 files changed

Lines changed: 589 additions & 97 deletions

File tree

examples/firmware/README.md

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,13 @@ The TPM has a vendor capability for getting the key group id. This is populated
5454
Infineon Firmware Update Usage:
5555
./ifx_fw_update (get info)
5656
./ifx_fw_update --abandon (cancel)
57-
./ifx_fw_update <manifest_file> <firmware_file>
57+
./ifx_fw_update --policytest (safe policy auth self-test)
58+
./ifx_fw_update [policy opts] <manifest_file> <firmware_file>
59+
./ifx_fw_update <manifest_file> <firmware_file> (default auth)
60+
Policy options (caller-supplied authorization):
61+
--policy provision+satisfy a PolicyCommandCode
62+
--policyor provision+satisfy a PolicyOR (multi-branch)
63+
--sha256|--sha384|--sha512 policy hash (default SHA-256)
5864

5965
# Run without arguments to display the current firmware information including key group id and operational mode
6066
./ifx_fw_update
@@ -131,7 +137,13 @@ The `st33_fw_update` tool automatically detects the firmware format.
131137
ST33 Firmware Update Usage:
132138
./st33_fw_update (get info)
133139
./st33_fw_update --abandon (cancel)
134-
./st33_fw_update <firmware.fi>
140+
./st33_fw_update --policytest (safe policy auth self-test)
141+
./st33_fw_update [policy opts] <firmware.fi>
142+
./st33_fw_update <firmware.fi> (default password auth)
143+
Policy options (caller-supplied authorization):
144+
--policy provision+satisfy a PolicyCommandCode
145+
--policyor provision+satisfy a PolicyOR (multi-branch)
146+
--sha256|--sha384|--sha512 policy hash (default SHA-256)
135147

136148
Firmware format is auto-detected from TPM firmware version:
137149
- Firmware < 512: Non-LMS format (177 byte manifest)
@@ -206,9 +218,11 @@ By default wolfTPM manages the platform-hierarchy authorization for the firmware
206218

207219
Deployments that gate firmware upgrade behind their own platform policy (for example a signed-policy check, a PCR state, or a multi-branch `PolicyOR`) can supply an already-satisfied authorization session using `wolfTPM2_FirmwareUpgradeHash_ex()`. When a session is supplied:
208220

209-
- **Infineon**: the library does **not** overwrite your platform primary policy. You provision the platform `authPolicy` yourself (via `TPM2_SetPrimaryPolicy` with `authHandle = TPM_RH_PLATFORM`, using SHA2-256 or SHA2-512) and pass a session that satisfies it.
221+
- **Infineon**: the library does **not** overwrite your platform primary policy. You provision the platform `authPolicy` yourself (via `TPM2_SetPrimaryPolicy` with `authHandle = TPM_RH_PLATFORM`, using SHA2-256 or SHA2-512) and pass a session that satisfies it. Note this applies to the *library*: the `--policy`/`--policyor` example modes are themselves such a caller, and their helper (`examples/firmware/firmware_policy.c`) does overwrite the platform `authPolicy` with a digest it generates. Do not run those modes on a system whose platform hierarchy already carries a policy you need.
210222
- **ST33**: the supplied session replaces the default `TPM_RS_PW` password authorization.
211223

224+
**Supported session contract**: the vendor `FieldUpgradeStart` command is sent with an authorization area carrying only the session handle - empty `nonceCaller`, zero session attributes and an empty HMAC. The supplied session must therefore be an unsalted, unbound `TPM_SE_POLICY` session with no auth value and no parameter encryption. Policies satisfied with `wolfTPM2_PolicyAuthValue()` or `wolfTPM2_PolicyPassword()` are **not** supported, because the session HMAC they require is not serialized on this path; such a session is rejected with `BAD_FUNC_ARG` before anything is sent to the TPM. `PolicyPCR`, `PolicySigned`, `PolicySecret`, `PolicyAuthorize`, `PolicyCommandCode` and `PolicyOR` branches are all fine.
225+
212226
Both SHA2-256 (non-PQC) and SHA2-512 (PQC) policy digests are supported, because the session hash is chosen with `wolfTPM2_StartSession_ex(..., authHash)` and `wolfTPM2_PolicyOR()` carries per-branch digest sizes.
213227

214228
Example: satisfy a multi-branch `PolicyOR` (up to 8 branches, SHA2-512 shown) and start the upgrade under it:
@@ -228,9 +242,10 @@ rc = wolfTPM2_StartSession_ex(&dev, &session, NULL, NULL,
228242
TPM_SE_POLICY, TPM_ALG_NULL, TPM_ALG_SHA512);
229243
if (rc != TPM_RC_SUCCESS) goto cleanup;
230244

231-
/* Satisfy one branch (PCR, PolicySigned/Authorize, PolicyAuthValue, ...), then
232-
* OR against the full branch list the platform authPolicy encodes. Set count
233-
* and each digests[i].size/buffer for every branch you populate. */
245+
/* Satisfy one branch (PCR, PolicySigned, PolicyAuthorize, PolicyCommandCode,
246+
* ...), then OR against the full branch list the platform authPolicy encodes.
247+
* Set count and each digests[i].size/buffer for every branch you populate.
248+
* PolicyOR requires at least 2 branches. */
234249
orList.count = 2;
235250
/* orList.digests[0].size = ...; XMEMCPY(orList.digests[0].buffer, ...); */
236251
/* orList.digests[1].size = ...; XMEMCPY(orList.digests[1].buffer, ...); */
@@ -254,4 +269,12 @@ if (session.handle.hndl != 0)
254269
255270
Passing `NULL` for the final `startSession` argument makes `wolfTPM2_FirmwareUpgradeHash_ex()` behave exactly like `wolfTPM2_FirmwareUpgradeHash()` (library-managed authorization), so existing code is unaffected.
256271
257-
**Note:** the example `--policy`/`--policyor` modes provision the platform hierarchy `authPolicy` via `TPM2_SetPrimaryPolicy` before the upgrade. On failure the example restores the default (clears the policy) so a later default-auth run is not locked out; on success the required TPM reset clears it. If a run is interrupted before that cleanup, the platform hierarchy may still require the policy until the TPM is reset/power-cycled.
272+
### Rollback of the example-provisioned policy
273+
274+
The example `--policy`/`--policyor` modes provision the platform hierarchy `authPolicy` via `TPM2_SetPrimaryPolicy` before the upgrade. On failure the example clears it again so a later default-auth run is not locked out; on success the required TPM reset clears it.
275+
276+
- Rollback normally uses platform **password** authorization. Per TPM 2.0 Part 1 Sec.19.7 a hierarchy is authorized by *either* its `authValue` *or* its `authPolicy`, so installing an `authPolicy` does not disable the password path. With the default empty `platformAuth` the clear always succeeds.
277+
- `--policyor` additionally provisions a `PolicyCommandCode(TPM_CC_SetPrimaryPolicy)` branch alongside the firmware-start branch, so the policy can authorize its own removal. If the password path fails (a deployment that set a non-default `platformAuth`), the example retries the clear under that branch.
278+
- `--policy` provisions a single `PolicyCommandCode(FieldUpgradeStart)` branch and therefore has no policy-based rollback path. It relies entirely on `platformAuth` still being usable.
279+
- Rollback is attempted only when the example actually installed the policy, so an early failure (a missing firmware file, for example) never clears a policy the deployment provisioned itself.
280+
- A failed rollback is reported explicitly and becomes the exit status. If a run is interrupted before cleanup, or the clear fails, the platform hierarchy still requires the policy until the TPM is reset/power-cycled.

examples/firmware/firmware_policy.c

Lines changed: 123 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,12 @@ static int firmware_policy_selftest(WOLFTPM2_DEV* dev, TPMI_ALG_HASH hashAlg,
8181
return rc;
8282
}
8383

84-
/* Offline: two distinct PolicyCommandCode branch digests */
85-
aSz = hsz;
84+
/* Offline: two distinct PolicyCommandCode branch digests. aSz/bSz are
85+
* in/out - supply the buffer capacity, get back the digest size. */
86+
aSz = (word32)sizeof(branchA);
8687
rc = wolfTPM2_PolicyCommandCodeMake(hashAlg, branchA, &aSz, TPM_CC_NV_Read);
8788
if (rc == 0) {
88-
bSz = hsz;
89+
bSz = (word32)sizeof(branchB);
8990
rc = wolfTPM2_PolicyCommandCodeMake(hashAlg, branchB, &bSz,
9091
TPM_CC_Unseal);
9192
}
@@ -171,33 +172,128 @@ int firmware_policy_selftest_all(WOLFTPM2_DEV* dev)
171172
return hardFail ? -1 : 0;
172173
}
173174

174-
void firmware_policy_clear(WOLFTPM2_DEV* dev)
175+
/* Build the PolicyOR branch list this example provisions. Branch A authorizes
176+
* the vendor firmware start; branch B authorizes TPM2_SetPrimaryPolicy so the
177+
* policy can be rolled back under itself. */
178+
static void firmware_policy_or_list(const FirmwarePolicyCtx* ctx,
179+
TPML_DIGEST* orList)
175180
{
176-
if (wolfTPM2_SetPrimaryPolicy(dev, TPM_RH_PLATFORM, TPM_ALG_NULL,
177-
NULL, 0) == TPM_RC_SUCCESS) {
181+
XMEMSET(orList, 0, sizeof(*orList));
182+
orList->count = 2;
183+
orList->digests[0].size = (UINT16)ctx->branchSz;
184+
XMEMCPY(orList->digests[0].buffer, ctx->branchFu, ctx->branchSz);
185+
orList->digests[1].size = (UINT16)ctx->branchSz;
186+
XMEMCPY(orList->digests[1].buffer, ctx->branchSpp, ctx->branchSz);
187+
}
188+
189+
/* Clear the platform authPolicy under a policy session that satisfies the
190+
* SetPrimaryPolicy branch. Only usable when a PolicyOR was provisioned. */
191+
static int firmware_policy_clear_by_policy(WOLFTPM2_DEV* dev,
192+
FirmwarePolicyCtx* ctx)
193+
{
194+
int rc;
195+
int restoreAuth = 0;
196+
WOLFTPM2_SESSION sess;
197+
TPML_DIGEST orList;
198+
199+
XMEMSET(&sess, 0, sizeof(sess));
200+
201+
rc = wolfTPM2_StartSession_ex(dev, &sess, NULL, NULL,
202+
TPM_SE_POLICY, TPM_ALG_NULL, ctx->hashAlg);
203+
if (rc == 0) {
204+
rc = wolfTPM2_PolicyCommandCode(dev, &sess, TPM_CC_SetPrimaryPolicy);
205+
}
206+
if (rc == 0) {
207+
firmware_policy_or_list(ctx, &orList);
208+
rc = wolfTPM2_PolicyOR(dev, &sess, &orList);
209+
}
210+
if (rc == 0) {
211+
/* route the next command's authorization through this policy session */
212+
rc = wolfTPM2_SetAuthSession(dev, 0, &sess, 0);
213+
if (rc == 0) {
214+
restoreAuth = 1;
215+
}
216+
}
217+
if (rc == 0) {
218+
rc = wolfTPM2_SetPrimaryPolicy(dev, TPM_RH_PLATFORM, TPM_ALG_NULL,
219+
NULL, 0);
220+
}
221+
222+
/* restore the default password authorization on session slot 0 */
223+
if (restoreAuth) {
224+
wolfTPM2_SetAuthPassword(dev, 0, NULL);
225+
}
226+
if (sess.handle.hndl != 0) {
227+
wolfTPM2_UnloadHandle(dev, &sess.handle);
228+
}
229+
return rc;
230+
}
231+
232+
int firmware_policy_clear(WOLFTPM2_DEV* dev, FirmwarePolicyCtx* ctx)
233+
{
234+
int rc;
235+
236+
if (dev == NULL || ctx == NULL) {
237+
return BAD_FUNC_ARG;
238+
}
239+
/* Never touch a policy this example did not install. Without this an early
240+
* failure (a bad firmware file, for example) would clear a platform policy
241+
* the deployment provisioned itself. */
242+
if (!ctx->provisioned) {
243+
return 0;
244+
}
245+
246+
/* Default path: platform password authorization. Installing an authPolicy
247+
* does not disable the authValue path (TPM 2.0 Part 1 Sec.19.7), so this
248+
* succeeds whenever platformAuth is still the default empty password. */
249+
rc = wolfTPM2_SetPrimaryPolicy(dev, TPM_RH_PLATFORM, TPM_ALG_NULL, NULL, 0);
250+
251+
/* Fallback: authorize the clear with the provisioned SetPrimaryPolicy
252+
* branch, for a deployment that set a non-default platformAuth. */
253+
if (rc != TPM_RC_SUCCESS && ctx->useOr) {
254+
printf("Clearing platform policy with default auth failed 0x%x: %s\n",
255+
rc, TPM2_GetRCString(rc));
256+
printf(" retrying under the SetPrimaryPolicy branch\n");
257+
rc = firmware_policy_clear_by_policy(dev, ctx);
258+
}
259+
260+
if (rc == TPM_RC_SUCCESS) {
261+
ctx->provisioned = 0;
178262
printf("Cleared platform policy (restored default auth)\n");
179263
}
264+
else {
265+
printf("ERROR: could not clear the platform policy 0x%x: %s\n",
266+
rc, TPM2_GetRCString(rc));
267+
printf(" The platform hierarchy still requires the provisioned "
268+
"policy.\n");
269+
printf(" Reset or power cycle the TPM to restore default "
270+
"authorization.\n");
271+
}
272+
return rc;
180273
}
181274

182-
int firmware_policy_session_setup(WOLFTPM2_DEV* dev,
275+
int firmware_policy_session_setup(WOLFTPM2_DEV* dev, FirmwarePolicyCtx* ctx,
183276
TPMI_ALG_HASH hashAlg, int useOr, TPM_CC fuStartCC,
184277
WOLFTPM2_SESSION* session)
185278
{
186279
int rc;
187-
int provisioned = 0;
188280
TPML_DIGEST orList;
189281
word32 hsz = (word32)TPM2_GetHashDigestSize(hashAlg);
190-
byte branchA[TPM_MAX_DIGEST_SIZE];
191-
byte branchB[TPM_MAX_DIGEST_SIZE];
192282
byte concat[2 * TPM_MAX_DIGEST_SIZE];
193283
byte platformPolicy[TPM_MAX_DIGEST_SIZE];
194284
word32 aSz, bSz = 0, polSz = 0;
195285

286+
if (dev == NULL || ctx == NULL || session == NULL) {
287+
return BAD_FUNC_ARG;
288+
}
196289
if (hsz == 0 || hsz > TPM_MAX_DIGEST_SIZE) {
197290
return BAD_FUNC_ARG;
198291
}
292+
XMEMSET(ctx, 0, sizeof(*ctx));
199293
XMEMSET(session, 0, sizeof(*session));
200294
XMEMSET(&orList, 0, sizeof(orList));
295+
ctx->hashAlg = hashAlg;
296+
ctx->useOr = useOr;
201297

202298
/* Fail early (before provisioning) if the TPM can't use this policy hash.
203299
* rc==0 means not implemented; a negative rc is a query failure. */
@@ -218,27 +314,32 @@ int firmware_policy_session_setup(WOLFTPM2_DEV* dev,
218314
TPM2_GetAlgName(hashAlg));
219315

220316
/* Branch A: PolicyCommandCode(FieldUpgradeStart) - required to start FU */
221-
aSz = hsz;
222-
rc = wolfTPM2_PolicyCommandCodeMake(hashAlg, branchA, &aSz, fuStartCC);
317+
aSz = (word32)sizeof(ctx->branchFu);
318+
rc = wolfTPM2_PolicyCommandCodeMake(hashAlg, ctx->branchFu, &aSz,
319+
fuStartCC);
223320

224321
/* Compute the platform authPolicy digest */
225322
if (rc == 0) {
323+
ctx->branchSz = aSz;
226324
if (useOr) {
227-
/* Branch B: a second, distinct policy branch */
228-
bSz = hsz;
229-
rc = wolfTPM2_PolicyCommandCodeMake(hashAlg, branchB, &bSz,
230-
TPM_CC_NV_Read);
325+
/* Branch B: PolicyCommandCode(SetPrimaryPolicy). This is the
326+
* rollback branch - it lets the provisioned policy authorize its
327+
* own removal, so cleanup works even if platformAuth is not the
328+
* default empty password. */
329+
bSz = (word32)sizeof(ctx->branchSpp);
330+
rc = wolfTPM2_PolicyCommandCodeMake(hashAlg, ctx->branchSpp, &bSz,
331+
TPM_CC_SetPrimaryPolicy);
231332
if (rc == 0) {
232-
XMEMCPY(concat, branchA, aSz);
233-
XMEMCPY(&concat[aSz], branchB, bSz);
333+
XMEMCPY(concat, ctx->branchFu, aSz);
334+
XMEMCPY(&concat[aSz], ctx->branchSpp, bSz);
234335
XMEMSET(platformPolicy, 0, sizeof(platformPolicy));
235336
polSz = hsz;
236337
rc = wolfTPM2_PolicyHash(hashAlg, platformPolicy, &polSz,
237338
TPM_CC_PolicyOR, concat, aSz + bSz);
238339
}
239340
}
240341
else {
241-
XMEMCPY(platformPolicy, branchA, aSz);
342+
XMEMCPY(platformPolicy, ctx->branchFu, aSz);
242343
polSz = aSz;
243344
}
244345
}
@@ -252,7 +353,7 @@ int firmware_policy_session_setup(WOLFTPM2_DEV* dev,
252353
rc, TPM2_GetRCString(rc));
253354
}
254355
else {
255-
provisioned = 1;
356+
ctx->provisioned = 1;
256357
}
257358
}
258359

@@ -269,11 +370,7 @@ int firmware_policy_session_setup(WOLFTPM2_DEV* dev,
269370
rc = wolfTPM2_PolicyCommandCode(dev, session, fuStartCC);
270371
}
271372
if (rc == 0 && useOr) {
272-
orList.count = 2;
273-
orList.digests[0].size = (UINT16)aSz;
274-
XMEMCPY(orList.digests[0].buffer, branchA, aSz);
275-
orList.digests[1].size = (UINT16)bSz;
276-
XMEMCPY(orList.digests[1].buffer, branchB, bSz);
373+
firmware_policy_or_list(ctx, &orList);
277374
rc = wolfTPM2_PolicyOR(dev, session, &orList);
278375
}
279376

@@ -283,9 +380,7 @@ int firmware_policy_session_setup(WOLFTPM2_DEV* dev,
283380
}
284381
/* Restore default platform auth so a later run is not locked out (the
285382
* platform policy is otherwise cleared only on TPM reset). */
286-
if (provisioned) {
287-
firmware_policy_clear(dev);
288-
}
383+
(void)firmware_policy_clear(dev, ctx);
289384
}
290385
return rc;
291386
}

examples/firmware/firmware_policy.h

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,21 @@
3636
extern "C" {
3737
#endif
3838

39+
/* Records what firmware_policy_session_setup actually provisioned, so cleanup
40+
* only touches a policy this example installed and can reproduce the branch
41+
* digests needed to authorize the rollback. Treat as opaque; zero before
42+
* use. */
43+
typedef struct FirmwarePolicyCtx {
44+
TPMI_ALG_HASH hashAlg; /* policy session / authPolicy hash */
45+
int useOr; /* 1 = platform policy is a PolicyOR */
46+
int provisioned; /* 1 = we installed the platform authPolicy */
47+
word32 branchSz; /* size of each branch digest below */
48+
/* PolicyOR branch A: PolicyCommandCode(fuStartCC) */
49+
byte branchFu[TPM_MAX_DIGEST_SIZE];
50+
/* PolicyOR branch B: PolicyCommandCode(TPM_CC_SetPrimaryPolicy) */
51+
byte branchSpp[TPM_MAX_DIGEST_SIZE];
52+
} FirmwarePolicyCtx;
53+
3954
/* Non-destructive self-test: exercises wolfTPM2_PolicyOR at SHA-256/384/512 and
4055
* checks the TPM's running policy digest against an offline computation. A hash
4156
* the TPM does not implement is reported and skipped. Returns 0 on overall
@@ -45,18 +60,32 @@ int firmware_policy_selftest_all(WOLFTPM2_DEV* dev);
4560
/* Provision the platform authPolicy and return a session that satisfies it, so
4661
* the firmware-start command can be authorized by a caller-controlled policy
4762
* instead of the vendor default. When useOr is set the platform policy is a
48-
* PolicyOR of two branches; otherwise a single PolicyCommandCode branch.
49-
* fuStartCC is the vendor FieldUpgrade start command code. On success *session
50-
* is started and satisfied (the caller passes it to wolfTPM2_FirmwareUpgrade_ex
51-
* and must UnloadHandle it). On failure any provisioned platform policy is
52-
* cleared so a later default-auth run is not locked out. */
53-
int firmware_policy_session_setup(WOLFTPM2_DEV* dev,
63+
* PolicyOR of PolicyCommandCode(fuStartCC) and
64+
* PolicyCommandCode(TPM_CC_SetPrimaryPolicy); otherwise it is a single
65+
* PolicyCommandCode(fuStartCC) branch. fuStartCC is the vendor FieldUpgrade
66+
* start command code. ctx records what was provisioned and must be passed to
67+
* firmware_policy_clear. On success *session is started and satisfied (the
68+
* caller passes it to wolfTPM2_FirmwareUpgrade_ex and must UnloadHandle it).
69+
* On failure any provisioned platform policy is cleared so a later default-auth
70+
* run is not locked out. */
71+
int firmware_policy_session_setup(WOLFTPM2_DEV* dev, FirmwarePolicyCtx* ctx,
5472
TPMI_ALG_HASH hashAlg, int useOr, TPM_CC fuStartCC,
5573
WOLFTPM2_SESSION* session);
5674

57-
/* Clear the platform authPolicy (restore default auth) so a later default-auth
58-
* run is not locked out. Call after a failed policy-mode upgrade. */
59-
void firmware_policy_clear(WOLFTPM2_DEV* dev);
75+
/* Clear a platform authPolicy this example provisioned, restoring default auth
76+
* so a later default-auth run is not locked out. Does nothing (and returns 0)
77+
* when ctx reports nothing was provisioned, so an unconditional call on an
78+
* error path cannot wipe a policy the deployment installed itself.
79+
*
80+
* Rollback normally uses platform password authorization: per TPM 2.0 Part 1
81+
* Sec.19.7 a hierarchy is authorized by either its authValue or its authPolicy,
82+
* so installing an authPolicy does not disable the password path. If the
83+
* password path fails (a deployment that set a non-default platformAuth) and a
84+
* PolicyOR was provisioned, the SetPrimaryPolicy branch is used to authorize
85+
* the clear under policy instead. Returns 0 on success, otherwise the TPM rc;
86+
* a non-zero return means the platform hierarchy still requires the policy
87+
* until the TPM is reset or power cycled. */
88+
int firmware_policy_clear(WOLFTPM2_DEV* dev, FirmwarePolicyCtx* ctx);
6089

6190
#ifdef __cplusplus
6291
}

0 commit comments

Comments
 (0)