mirror of https://github.com/wolfSSL/wolfTPM.git
F-5277 F-5122 - Store and enforce policy cpHashA command binding
parent
0d95be5f65
commit
5617f43aae
|
|
@ -8856,6 +8856,8 @@ static TPM_RC FwCmd_PolicySecret(FWTPM_CTX* ctx, TPM2_Packet* cmd,
|
|||
UINT16 nonceTpmSz, cpHashASz, policyRefSz = 0;
|
||||
INT32 expiration;
|
||||
byte policyRef[64];
|
||||
byte nonceTpmBuf[TPM_MAX_DIGEST_SIZE];
|
||||
byte cpHashBuf[TPM_MAX_DIGEST_SIZE];
|
||||
byte entityName[sizeof(TPM2B_NAME)];
|
||||
int entityNameSz = 0;
|
||||
FWTPM_Session* sess;
|
||||
|
|
@ -8868,19 +8870,25 @@ static TPM_RC FwCmd_PolicySecret(FWTPM_CTX* ctx, TPM2_Packet* cmd,
|
|||
|
||||
if (rc == 0) {
|
||||
TPM2_Packet_ParseU16(cmd, &nonceTpmSz);
|
||||
if (cmd->pos + nonceTpmSz > cmdSize) {
|
||||
rc = TPM_RC_COMMAND_SIZE;
|
||||
if (nonceTpmSz > (UINT16)sizeof(nonceTpmBuf) ||
|
||||
cmd->pos + nonceTpmSz > cmdSize) {
|
||||
rc = TPM_RC_SIZE;
|
||||
}
|
||||
}
|
||||
if (rc == 0) {
|
||||
cmd->pos += nonceTpmSz;
|
||||
if (nonceTpmSz > 0) {
|
||||
TPM2_Packet_ParseBytes(cmd, nonceTpmBuf, nonceTpmSz);
|
||||
}
|
||||
TPM2_Packet_ParseU16(cmd, &cpHashASz);
|
||||
if (cmd->pos + cpHashASz > cmdSize) {
|
||||
rc = TPM_RC_COMMAND_SIZE;
|
||||
if (cpHashASz > (UINT16)sizeof(cpHashBuf) ||
|
||||
cmd->pos + cpHashASz > cmdSize) {
|
||||
rc = TPM_RC_SIZE;
|
||||
}
|
||||
}
|
||||
if (rc == 0) {
|
||||
cmd->pos += cpHashASz;
|
||||
if (cpHashASz > 0) {
|
||||
TPM2_Packet_ParseBytes(cmd, cpHashBuf, cpHashASz);
|
||||
}
|
||||
TPM2_Packet_ParseU16(cmd, &policyRefSz);
|
||||
if (policyRefSz > (UINT16)sizeof(policyRef)) {
|
||||
rc = TPM_RC_SIZE;
|
||||
|
|
@ -8909,6 +8917,16 @@ static TPM_RC FwCmd_PolicySecret(FWTPM_CTX* ctx, TPM2_Packet* cmd,
|
|||
rc = TPM_RC_AUTH_TYPE;
|
||||
}
|
||||
|
||||
/* A supplied nonceTPM must match the session nonce (Part 3 Sec.23.4),
|
||||
* preventing replay of a PolicySecret authorization to another session. */
|
||||
if (rc == 0 && nonceTpmSz > 0) {
|
||||
if (nonceTpmSz != sess->nonceTPM.size ||
|
||||
TPM2_ConstantCompare(nonceTpmBuf, sess->nonceTPM.buffer,
|
||||
nonceTpmSz) != 0) {
|
||||
rc = TPM_RC_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc == 0) {
|
||||
/* Auth verification for authHandle is handled by the command dispatch
|
||||
* framework (FWTPM_ProcessCommand) via the authorization area, not
|
||||
|
|
@ -8926,6 +8944,12 @@ static TPM_RC FwCmd_PolicySecret(FWTPM_CTX* ctx, TPM2_Packet* cmd,
|
|||
}
|
||||
}
|
||||
|
||||
/* Bind the command to cpHashA so policy enforcement can verify it */
|
||||
if (rc == 0 && cpHashASz > 0) {
|
||||
sess->cpHashA.size = cpHashASz;
|
||||
XMEMCPY(sess->cpHashA.buffer, cpHashBuf, cpHashASz);
|
||||
}
|
||||
|
||||
if (rc == 0) {
|
||||
/* Response: timeout(TPM2B size=0) + ticket(TPMT_TK_AUTH) */
|
||||
paramStart = FwRspParamsBegin(rsp, cmdTag, ¶mSzPos);
|
||||
|
|
@ -9431,6 +9455,12 @@ static TPM_RC FwCmd_PolicySigned(FWTPM_CTX* ctx, TPM2_Packet* cmd,
|
|||
}
|
||||
}
|
||||
|
||||
/* Bind the command to cpHashA so policy enforcement can verify it */
|
||||
if (rc == 0 && cpHashASz > 0) {
|
||||
sess->cpHashA.size = cpHashASz;
|
||||
XMEMCPY(sess->cpHashA.buffer, cpHashBuf, cpHashASz);
|
||||
}
|
||||
|
||||
if (rc == 0) {
|
||||
/* Response: timeout(TPM2B size=0) + ticket(TPMT_TK_AUTH) */
|
||||
paramStart = FwRspParamsBegin(rsp, cmdTag, ¶mSzPos);
|
||||
|
|
@ -15775,6 +15805,22 @@ int FWTPM_ProcessCommand(FWTPM_CTX* ctx,
|
|||
TPM_ST_NO_SESSIONS, TPM_RC_LOCALITY);
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
/* Enforce any PolicyCpHash command binding: the command's
|
||||
* cpHash must equal the value the policy committed to. */
|
||||
if (pSess->cpHashA.size > 0) {
|
||||
byte ccpHash[TPM_MAX_DIGEST_SIZE];
|
||||
int ccpHashSz = 0;
|
||||
if (FwComputeCpHash(pSess->authHash, cmdCode,
|
||||
cmdBuf, cmdSize, cmdHandles, cmdHandleCnt,
|
||||
ctx, cpStart, ccpHash, &ccpHashSz) != 0 ||
|
||||
(int)pSess->cpHashA.size != ccpHashSz ||
|
||||
TPM2_ConstantCompare(pSess->cpHashA.buffer,
|
||||
ccpHash, (word32)ccpHashSz) != 0) {
|
||||
*rspSize = FwBuildErrorResponse(rspBuf,
|
||||
TPM_ST_NO_SESSIONS, TPM_RC_POLICY_FAIL);
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (authPolicy != NULL && authPolicy->size == 0 &&
|
||||
cmdAuths[pj].cmdHmacSize == 0) {
|
||||
|
|
|
|||
|
|
@ -7170,6 +7170,67 @@ static void test_fwtpm_policy_locality_enforced(void)
|
|||
FWTPM_Cleanup(&ctx);
|
||||
printf("Test fwTPM:\tPolicyLocality enforced:\tPassed\n");
|
||||
}
|
||||
|
||||
/* PolicyCpHash binds a session to a specific command; a command whose real
|
||||
* cpHash differs must be rejected even when the policyDigest matches. */
|
||||
static void test_fwtpm_policy_cphash_enforced(void)
|
||||
{
|
||||
FWTPM_CTX ctx;
|
||||
int pos, cmdSz, rspSize = 0;
|
||||
UINT32 sessH;
|
||||
UINT16 dSz;
|
||||
byte digest[64];
|
||||
byte cph[32];
|
||||
UINT32 nvIdx = 0x01500062;
|
||||
UINT32 nvAttrs = TPMA_NV_OWNERWRITE | TPMA_NV_OWNERREAD | TPMA_NV_NO_DA;
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
AssertIntEQ(fwtpm_test_startup(&ctx), 0);
|
||||
memset(cph, 0xCC, sizeof(cph));
|
||||
|
||||
sessH = StartSessionHelper(&ctx, TPM_SE_POLICY);
|
||||
AssertIntNE(sessH, 0);
|
||||
|
||||
/* Bind the session to a cpHash no real command will produce */
|
||||
pos = BuildCmdHeader(gCmd, TPM_ST_NO_SESSIONS, 0, TPM_CC_PolicyCpHash);
|
||||
PutU32BE(gCmd + pos, sessH); pos += 4;
|
||||
PutU16BE(gCmd + pos, (UINT16)sizeof(cph)); pos += 2;
|
||||
memcpy(gCmd + pos, cph, sizeof(cph)); pos += sizeof(cph);
|
||||
PutU32BE(gCmd + 2, (UINT32)pos);
|
||||
FWTPM_ProcessCommand(&ctx, gCmd, pos, gRsp, &rspSize, 0);
|
||||
AssertIntEQ(GetRspRC(gRsp), TPM_RC_SUCCESS);
|
||||
|
||||
AssertIntEQ(SendPolicyCmd(&ctx, TPM_CC_PolicyGetDigest, sessH),
|
||||
TPM_RC_SUCCESS);
|
||||
dSz = GetU16BE(gRsp + TPM2_HEADER_SIZE + 4);
|
||||
AssertIntEQ(dSz, 32);
|
||||
memcpy(digest, gRsp + TPM2_HEADER_SIZE + 6, dSz);
|
||||
|
||||
pos = 0;
|
||||
PutU16BE(gCmd + pos, TPM_ST_SESSIONS); pos += 2;
|
||||
PutU32BE(gCmd + pos, 0); pos += 4;
|
||||
PutU32BE(gCmd + pos, TPM_CC_SetPrimaryPolicy); pos += 4;
|
||||
PutU32BE(gCmd + pos, TPM_RH_OWNER); pos += 4;
|
||||
pos = AppendPwAuth(gCmd, pos, NULL, 0);
|
||||
PutU16BE(gCmd + pos, dSz); pos += 2;
|
||||
memcpy(gCmd + pos, digest, dSz); pos += dSz;
|
||||
PutU16BE(gCmd + pos, TPM_ALG_SHA256); pos += 2;
|
||||
PutU32BE(gCmd + 2, (UINT32)pos);
|
||||
rspSize = 0;
|
||||
FWTPM_ProcessCommand(&ctx, gCmd, pos, gRsp, &rspSize, 0);
|
||||
AssertIntEQ(GetRspRC(gRsp), TPM_RC_SUCCESS);
|
||||
|
||||
/* The NV_DefineSpace cpHash will not match the bound cpHashA */
|
||||
cmdSz = BuildNvDefineCmd(gCmd, nvIdx, 8, nvAttrs);
|
||||
PutU32BE(gCmd + 18, sessH);
|
||||
rspSize = 0;
|
||||
FWTPM_ProcessCommand(&ctx, gCmd, cmdSz, gRsp, &rspSize, 0);
|
||||
AssertIntEQ(GetRspRC(gRsp), TPM_RC_POLICY_FAIL);
|
||||
|
||||
FlushHandle(&ctx, sessH);
|
||||
FWTPM_Cleanup(&ctx);
|
||||
printf("Test fwTPM:\tPolicyCpHash enforced:\tPassed\n");
|
||||
}
|
||||
#endif /* !FWTPM_NO_NV */
|
||||
|
||||
#endif /* !FWTPM_NO_POLICY */
|
||||
|
|
@ -9255,6 +9316,7 @@ int fwtpm_unit_tests(int argc, char *argv[])
|
|||
test_fwtpm_policynv_owner_read_denied();
|
||||
test_fwtpm_policyauthorizenv_owner_read_denied();
|
||||
test_fwtpm_policy_locality_enforced();
|
||||
test_fwtpm_policy_cphash_enforced();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue