Skip to content

Commit de11f20

Browse files
committed
fwtpm: peer-review batch 1 (quick wins)
- NV_Write: reject non-ordinary/PIN NV types (CWE-697 counter reset) - wolfTPM2_SetAuth/SetAuthHandleName: validate bounds before mutating session state so failures don't leave auth.size oversized - wolfTPM2_SetAuthHandle policyAuth: clamp name.size before XMEMCPY - EventSequenceComplete: authHandleCnt 1->2 (sequenceHandle was unauth'd) - NV_ChangeAuth: zero newAuthBuf stack copy before return - FwRspParamsEnd: guard against rsp->pos < paramStart underflow - wolfTPM2_ECDHGen: remove duplicate ForceZero
1 parent f3ee625 commit de11f20

2 files changed

Lines changed: 32 additions & 16 deletions

File tree

src/fwtpm/fwtpm_command.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ void FwRspParamsEnd(TPM2_Packet* rsp, UINT16 cmdTag,
119119
int paramSzPos, int paramStart)
120120
{
121121
/* Patch parameterSize if sessions */
122-
if (paramSzPos >= 0) {
122+
if (paramSzPos >= 0 && rsp->pos >= paramStart) {
123123
int paramSize = rsp->pos - paramStart;
124124
int savedPos = rsp->pos;
125125
rsp->pos = paramSzPos;
@@ -9732,6 +9732,18 @@ static TPM_RC FwCmd_NV_Write(FWTPM_CTX* ctx, TPM2_Packet* cmd,
97329732
rc = FW_NV_HANDLE_ERR_2;
97339733
}
97349734

9735+
/* Per TPM 2.0 Part 3 §31.3, NV_Write only valid for ordinary and PIN
9736+
* indices. Counter, Bits, and Extend types must use their dedicated
9737+
* commands (NV_Increment, NV_SetBits, NV_Extend). Allowing NV_Write on
9738+
* counters would let an attacker reset a monotonic counter to zero. */
9739+
if (rc == 0) {
9740+
UINT32 nt = (nv->nvPublic.attributes & TPMA_NV_TPM_NT) >> 4;
9741+
if (nt != TPM_NT_ORDINARY && nt != TPM_NT_PIN_FAIL &&
9742+
nt != TPM_NT_PIN_PASS) {
9743+
rc = TPM_RC_ATTRIBUTES;
9744+
}
9745+
}
9746+
97359747
if (rc == 0 && (nv->nvPublic.attributes & TPMA_NV_WRITELOCKED)) {
97369748
rc = TPM_RC_NV_LOCKED;
97379749
}
@@ -10158,6 +10170,9 @@ static TPM_RC FwCmd_NV_ChangeAuth(FWTPM_CTX* ctx, TPM2_Packet* cmd,
1015810170
FwRspNoParams(rsp, cmdTag);
1015910171
}
1016010172

10173+
/* Zero stack copy of new auth value before returning */
10174+
TPM2_ForceZero(newAuthBuf, sizeof(newAuthBuf));
10175+
1016110176
return rc;
1016210177
}
1016310178

@@ -12064,7 +12079,7 @@ static const FWTPM_CMD_ENTRY fwCmdTable[] = {
1206412079
{ TPM_CC_HashSequenceStart, FwCmd_HashSequenceStart, 0, 0, 0, FW_CMD_FLAG_ENC },
1206512080
{ TPM_CC_SequenceUpdate, FwCmd_SequenceUpdate, 1, 1, 0, FW_CMD_FLAG_ENC },
1206612081
{ TPM_CC_SequenceComplete, FwCmd_SequenceComplete, 1, 1, 0, FW_CMD_FLAG_ENC | FW_CMD_FLAG_DEC },
12067-
{ TPM_CC_EventSequenceComplete, FwCmd_EventSequenceComplete, 2, 1, 0, FW_CMD_FLAG_ENC },
12082+
{ TPM_CC_EventSequenceComplete, FwCmd_EventSequenceComplete, 2, 2, 0, FW_CMD_FLAG_ENC },
1206812083
/* --- ECC --- */
1206912084
#ifdef HAVE_ECC
1207012085
{ TPM_CC_ECDH_KeyGen, FwCmd_ECDH_KeyGen, 1, 0, 0, FW_CMD_FLAG_DEC },

src/tpm2_wrap.c

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,15 +1664,17 @@ int wolfTPM2_SetAuth(WOLFTPM2_DEV* dev, int index,
16641664
}
16651665
#endif
16661666

1667+
/* Validate bounds before mutating session state so that an oversized
1668+
* auth value doesn't leave the session with an invalid auth.size that
1669+
* subsequent code paths could read past the buffer end. */
1670+
if (auth != NULL && auth->size > sizeof(session->auth.buffer)) {
1671+
return BUFFER_E;
1672+
}
16671673
XMEMSET(session, 0, sizeof(TPM2_AUTH_SESSION));
16681674
session->sessionHandle = sessionHandle;
16691675
session->sessionAttributes = sessionAttributes;
16701676
if (auth) {
16711677
session->auth.size = auth->size;
1672-
/* Note: returns error instead of truncating for security (v3.11+) */
1673-
if (session->auth.size > sizeof(session->auth.buffer)) {
1674-
return BUFFER_E;
1675-
}
16761678
XMEMCPY(session->auth.buffer, auth->buffer, session->auth.size);
16771679
}
16781680
if (name) {
@@ -1731,7 +1733,10 @@ int wolfTPM2_SetAuthHandle(WOLFTPM2_DEV* dev, int index,
17311733
XMEMCPY(&session->auth.buffer[authDigestSz], handle->auth.buffer,
17321734
handle->auth.size);
17331735
session->name.size = handle->name.size;
1734-
XMEMCPY(session->name.name, handle->name.name, handle->name.size);
1736+
if (session->name.size > sizeof(session->name.name)) {
1737+
session->name.size = sizeof(session->name.name); /* truncate */
1738+
}
1739+
XMEMCPY(session->name.name, handle->name.name, session->name.size);
17351740
return TPM_RC_SUCCESS;
17361741
}
17371742
auth = &handle->auth;
@@ -1754,24 +1759,21 @@ int wolfTPM2_SetAuthHandleName(WOLFTPM2_DEV* dev, int index,
17541759
session = &dev->session[index];
17551760

17561761
if (handle->auth.size > 0) {
1762+
/* Validate bounds before mutating session.auth so a failure leaves
1763+
* session->auth.size unchanged rather than oversized. */
1764+
if (handle->auth.size > sizeof(session->auth.buffer)) {
1765+
return BUFFER_E;
1766+
}
17571767
if (session->sessionHandle == TPM_RS_PW) {
17581768
/* password based authentication */
17591769
session->auth.size = handle->auth.size;
1760-
/* Note: returns error instead of truncating for security (v3.11+) */
1761-
if (session->auth.size > sizeof(session->auth.buffer)) {
1762-
return BUFFER_E;
1763-
}
17641770
XMEMCPY(session->auth.buffer, handle->auth.buffer,
17651771
session->auth.size);
17661772
}
17671773
else {
17681774
if (handle->policyPass) {
17691775
/* use policy password directly */
17701776
session->auth.size = handle->auth.size;
1771-
/* Note: returns error instead of truncating for security (v3.11+) */
1772-
if (session->auth.size > sizeof(session->auth.buffer)) {
1773-
return BUFFER_E;
1774-
}
17751777
XMEMCPY(session->auth.buffer, handle->auth.buffer,
17761778
session->auth.size);
17771779
session->policyPass = handle->policyPass;
@@ -5112,7 +5114,6 @@ int wolfTPM2_ECDHGen(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* privKey,
51125114
ecdhOut.pubPoint.size);
51135115
#endif
51145116

5115-
TPM2_ForceZero(&ecdhOut, sizeof(ecdhOut));
51165117
TPM2_ForceZero(&ecdhOut, sizeof(ecdhOut));
51175118
return rc;
51185119
}

0 commit comments

Comments
 (0)