mirror of https://github.com/wolfSSL/wolfTPM.git
F-13524 - Verify the PolicyPCR digest against live PCR values
parent
9bb9e2f8f7
commit
11917addc0
|
|
@ -10667,6 +10667,7 @@ static TPM_RC FwCmd_PolicyPCR(FWTPM_CTX* ctx, TPM2_Packet* cmd,
|
|||
UINT32 sessHandle;
|
||||
UINT16 pcrDigestSize;
|
||||
byte pcrDigest[TPM_MAX_DIGEST_SIZE];
|
||||
byte liveDigest[TPM_MAX_DIGEST_SIZE];
|
||||
TPML_PCR_SELECTION pcrs;
|
||||
FWTPM_Session* sess = NULL;
|
||||
int digestSz = 0;
|
||||
|
|
@ -10733,8 +10734,10 @@ static TPM_RC FwCmd_PolicyPCR(FWTPM_CTX* ctx, TPM2_Packet* cmd,
|
|||
}
|
||||
}
|
||||
|
||||
/* If pcrDigest.size == 0, compute it from current PCR values */
|
||||
if (rc == 0 && pcrDigestSize == 0) {
|
||||
/* Compute the digest of the selected PCRs when none was supplied, and
|
||||
* always for a real policy session so a supplied digest is verified
|
||||
* against the live PCR values rather than trusted (Part 3 Sec.23.7). */
|
||||
if (rc == 0 && (pcrDigestSize == 0 || sess->sessionType == TPM_SE_POLICY)) {
|
||||
/* Hash together all selected PCR values */
|
||||
wcHash = FwGetWcHashType(sess->authHash);
|
||||
if (wc_HashInit_ex(hashCtx, wcHash, NULL, INVALID_DEVID) != 0) {
|
||||
|
|
@ -10750,17 +10753,29 @@ static TPM_RC FwCmd_PolicyPCR(FWTPM_CTX* ctx, TPM2_Packet* cmd,
|
|||
pcrs.pcrSelections[i].hash);
|
||||
if (bankIdx < 0 || pcrDSz == 0)
|
||||
continue;
|
||||
for (j = 0; j < IMPLEMENTATION_PCR; j++) {
|
||||
for (j = 0; j < IMPLEMENTATION_PCR && rc == 0; j++) {
|
||||
if (j / 8 < pcrs.pcrSelections[i].sizeofSelect &&
|
||||
(pcrs.pcrSelections[i].pcrSelect[j / 8] &
|
||||
(1 << (j % 8)))) {
|
||||
wc_HashUpdate(hashCtx, wcHash,
|
||||
ctx->pcrDigest[j][bankIdx], pcrDSz);
|
||||
if (wc_HashUpdate(hashCtx, wcHash,
|
||||
ctx->pcrDigest[j][bankIdx], pcrDSz) != 0) {
|
||||
rc = TPM_RC_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pcrDigestSize = digestSz;
|
||||
wc_HashFinal(hashCtx, wcHash, pcrDigest);
|
||||
if (rc == 0 && wc_HashFinal(hashCtx, wcHash, liveDigest) != 0) {
|
||||
rc = TPM_RC_FAILURE;
|
||||
}
|
||||
if (rc == 0 && pcrDigestSize != 0 &&
|
||||
(pcrDigestSize != digestSz ||
|
||||
TPM2_ConstantCompare(pcrDigest, liveDigest, digestSz) != 0)) {
|
||||
rc = TPM_RC_VALUE;
|
||||
}
|
||||
if (rc == 0) {
|
||||
pcrDigestSize = (UINT16)digestSz;
|
||||
XMEMCPY(pcrDigest, liveDigest, digestSz);
|
||||
}
|
||||
}
|
||||
if (hashInit) {
|
||||
wc_HashFree(hashCtx, wcHash);
|
||||
|
|
|
|||
|
|
@ -9587,6 +9587,65 @@ static void test_fwtpm_policy_cphash_enforced(void)
|
|||
}
|
||||
#endif /* !FWTPM_NO_NV */
|
||||
|
||||
/* PolicyPCR selecting PCR 0 in the SHA-256 bank with an optional caller digest */
|
||||
static TPM_RC SendPolicyPcrCmd(FWTPM_CTX* ctx, UINT32 sessH,
|
||||
const byte* digest, UINT16 digestSz)
|
||||
{
|
||||
int pos = 0, rspSize = 0;
|
||||
PutU16BE(gCmd + pos, TPM_ST_SESSIONS); pos += 2;
|
||||
PutU32BE(gCmd + pos, 0); pos += 4;
|
||||
PutU32BE(gCmd + pos, TPM_CC_PolicyPCR); pos += 4;
|
||||
PutU32BE(gCmd + pos, sessH); pos += 4;
|
||||
pos = AppendPwAuth(gCmd, pos, NULL, 0);
|
||||
PutU16BE(gCmd + pos, digestSz); pos += 2;
|
||||
if (digestSz > 0) {
|
||||
memcpy(gCmd + pos, digest, digestSz); pos += digestSz;
|
||||
}
|
||||
PutU32BE(gCmd + pos, 1); pos += 4; /* count */
|
||||
PutU16BE(gCmd + pos, TPM_ALG_SHA256); pos += 2; /* hash */
|
||||
gCmd[pos++] = 3; /* sizeofSelect */
|
||||
gCmd[pos++] = 0x01; gCmd[pos++] = 0x00; gCmd[pos++] = 0x00; /* PCR 0 */
|
||||
PutU32BE(gCmd + 2, (UINT32)pos);
|
||||
FWTPM_ProcessCommand(ctx, gCmd, pos, gRsp, &rspSize, 0);
|
||||
return GetRspRC(gRsp);
|
||||
}
|
||||
|
||||
/* A real policy session must verify a caller-supplied pcrDigest against the
|
||||
* live PCR values; only a trial session may take it on faith. */
|
||||
static void test_fwtpm_policy_pcr_digest_verified(void)
|
||||
{
|
||||
FWTPM_CTX ctx;
|
||||
UINT32 sessH;
|
||||
byte pcr0[32];
|
||||
byte expect[32];
|
||||
byte wrong[32];
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
AssertIntEQ(fwtpm_test_startup(&ctx), 0);
|
||||
memset(pcr0, 0, sizeof(pcr0)); /* PCR 0 reset by Startup */
|
||||
AssertIntEQ(wc_Hash(WC_HASH_TYPE_SHA256, pcr0, sizeof(pcr0),
|
||||
expect, sizeof(expect)), 0);
|
||||
memset(wrong, 0xAB, sizeof(wrong));
|
||||
|
||||
sessH = StartSessionHelper(&ctx, TPM_SE_POLICY);
|
||||
AssertIntNE(sessH, 0);
|
||||
AssertIntEQ(SendPolicyPcrCmd(&ctx, sessH, wrong, sizeof(wrong)),
|
||||
TPM_RC_VALUE);
|
||||
AssertIntEQ(SendPolicyPcrCmd(&ctx, sessH, expect, 16), TPM_RC_VALUE);
|
||||
AssertIntEQ(SendPolicyPcrCmd(&ctx, sessH, expect, sizeof(expect)),
|
||||
TPM_RC_SUCCESS);
|
||||
FlushHandle(&ctx, sessH);
|
||||
|
||||
sessH = StartSessionHelper(&ctx, TPM_SE_TRIAL);
|
||||
AssertIntNE(sessH, 0);
|
||||
AssertIntEQ(SendPolicyPcrCmd(&ctx, sessH, wrong, sizeof(wrong)),
|
||||
TPM_RC_SUCCESS);
|
||||
FlushHandle(&ctx, sessH);
|
||||
|
||||
FWTPM_Cleanup(&ctx);
|
||||
fwtpm_pass("PolicyPCR digest verified:", 0);
|
||||
}
|
||||
|
||||
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
|
||||
static void test_fwtpm_admin_authorization_requires_policy(void)
|
||||
{
|
||||
|
|
@ -14543,6 +14602,7 @@ int fwtpm_unit_tests(int argc, char *argv[])
|
|||
test_fwtpm_policy_command_code();
|
||||
test_fwtpm_policy_locality();
|
||||
test_fwtpm_policy_pcr();
|
||||
test_fwtpm_policy_pcr_digest_verified();
|
||||
test_fwtpm_policy_ticket_zero_digest_rejected();
|
||||
test_fwtpm_policyauthorize_null_ticket_rejected();
|
||||
#ifndef FWTPM_NO_NV
|
||||
|
|
|
|||
Loading…
Reference in New Issue