in lsvmutils/tpm2.c [4381:4524]
TPM_RC TPM2X_BuildPolicy(
EFI_TCG2_PROTOCOL *protocol,
TPMI_SH_AUTH_SESSION policySession,
BOOLEAN predictive,
UINT32 pcrMask,
const SHA256Hash pcrs[MAX_PCRS],
TPMI_ALG_HASH hashAlg,
Error* err)
{
TPM_RC rc;
TPML_PCR_SELECTION pcrSelectionIn;
UINT32 pcrUpdateCounter;
TPML_PCR_SELECTION pcrSelectionOut;
TPML_DIGEST pcrValues;
UINT32 i = 0;
UINT32 npcrs = 0;
ClearErr(err);
/* Check the hashing algorithm, should be SHA1 or SHA256. */
if (hashAlg != TPM_ALG_SHA1 && hashAlg != TPM_ALG_SHA256)
{
SetErr(err, TCS("Unsupported hash function"));
return TPM_RC_FAILURE;
}
/* Set NULL password for this policy */
if ((rc = TPM2_PolicyPassword(
protocol,
policySession,
NULL,
NULL)) != TPM_RC_SUCCESS)
{
SetErr(err, TCS("failed to set the policy password"));
return rc;
}
Memset(&pcrSelectionIn, 0, sizeof(pcrSelectionIn));
pcrSelectionIn.count = 1;
/* Note: this is not the number of PCRs */
pcrSelectionIn.pcrSelections[0].sizeofSelect = 3;
pcrSelectionIn.pcrSelections[0].hash = hashAlg;
for (i = 0; i < MAX_PCRS; i++)
{
if (pcrMask & (1 << i))
{
TPMS_PCR_SELECTION_SelectPCR(&pcrSelectionIn.pcrSelections[0], i);
npcrs++;
}
}
Memset(&pcrUpdateCounter, 0, sizeof(pcrUpdateCounter));
Memset(&pcrSelectionOut, 0, sizeof(pcrSelectionOut));
Memset(&pcrValues, 0, sizeof(pcrValues));
if (predictive)
{
UINT32 n;
pcrValues.count = npcrs;
for (i = 0, n = 0; i < MAX_PCRS; i++)
{
if (pcrMask & (1 << i))
{
Memcpy(pcrValues.digests[n].buffer, &pcrs[i], sizeof(pcrs[i]));
pcrValues.digests[n].size = sizeof(pcrs[i]);
n++;
}
}
}
else
{
if ((rc = TPM2_PCR_Read(
protocol,
NULL, /* input */
&pcrSelectionIn, /* input */
&pcrUpdateCounter, /* not used */
&pcrSelectionOut, /* not used */
&pcrValues,
NULL)) != TPM_RC_SUCCESS)
{
SetErr(err, TCS("failed to read PCRs when building policy"));
return rc;
}
}
if (pcrValues.count != npcrs)
{
SetErr(err, TCS("unexpected error when building policy"));
return TPM_RC_FAILURE;
}
/* Hash the PCRs together */
TPM2B_DIGEST pcrDigest;
{
unsigned char data[sizeof(pcrValues.digests[0].buffer) * MAX_PCRS];
unsigned char* end = data;
Memset(&pcrDigest, 0, sizeof(pcrDigest));
for (i = 0; i < npcrs; i++)
{
Memcpy(end, pcrValues.digests[i].buffer, pcrValues.digests[i].size);
end += pcrValues.digests[i].size;
}
if (hashAlg == TPM_ALG_SHA1)
{
if (!ComputeSHA1(data, end - data, (SHA1Hash*)pcrDigest.buffer))
{
SetErr(err, TCS("hash operation failed while building policy"));
return rc;
}
pcrDigest.size = sizeof(SHA1Hash);
}
else /* SHA256 */
{
if (!ComputeSHA256(data, end - data, (SHA256Hash*)pcrDigest.buffer))
{
SetErr(err, TCS("hash operation failed while building policy"));
return rc;
}
pcrDigest.size = sizeof(SHA256Hash);
}
}
/* Create the PCR policy */
if ((rc = TPM2_PolicyPCR(
protocol,
policySession,
NULL,
&pcrDigest,
&pcrSelectionIn,
NULL)) != TPM_RC_SUCCESS)
{
SetErr(err, TCS("failed to create PCR policy"));
return rc;
}
return TPM_RC_SUCCESS;
}