in lsvmutils/tpm2.c [4602:4765]
TPM_RC TPM2X_Seal(
IN EFI_TCG2_PROTOCOL *protocol,
IN TPM_HANDLE parentKey,
BOOLEAN predictive,
UINT32 pcrMask,
const SHA256Hash pcrs[MAX_PCRS],
IN const BYTE data[TPM2X_MAX_DATA_SIZE],
IN UINT16 size,
OUT TPM2X_BLOB *blob,
Error* err)
{
TPM_RC rc = TPM_RC_SUCCESS;
TPMI_SH_AUTH_SESSION policyHandle;
BOOLEAN policyHandleNull = TRUE;
TPM2B_DIGEST policyDigest;
TPM2B_PRIVATE outPrivate;
TPM2B_PUBLIC outPublic;
ClearErr(err);
if (!protocol)
{
SetErr(err, TCS("null protocol parameter"));
rc = TPM_RC_FAILURE;
goto done;
}
if (!data)
{
SetErr(err, TCS("null data parameter"));
rc = TPM_RC_FAILURE;
goto done;
}
if (size > TPM2X_MAX_DATA_SIZE)
{
SetErr(err, TCS("size parameter too big"));
rc = TPM_RC_FAILURE;
goto done;
}
if (!blob)
{
SetErr(err, TCS("null blob parameter"));
rc = TPM_RC_FAILURE;
goto done;
}
if ((rc = TPM2X_StartAuthSession(
protocol,
TRUE,
TPM_ALG_SHA256,
&policyHandle)) != TPM_RC_SUCCESS)
{
SetErr(err, TCS("failed to start authentication session"));
return rc;
goto done;
}
policyHandleNull = FALSE;
if (TPM2X_BuildPolicy(
protocol,
policyHandle,
predictive,
pcrMask,
pcrs,
TPM_ALG_SHA256,
err) != TPM_RC_SUCCESS)
{
goto done;
}
if ((rc = TPM2_PolicyGetDigest(
protocol,
policyHandle,
NULL,
&policyDigest,
NULL)) != TPM_RC_SUCCESS)
{
SetErr(err, TCS("failed to get the policy digest"));
goto done;
}
/* Create */
{
TPMS_AUTH_COMMAND authCommand;
TPM2B_SENSITIVE_CREATE inSensitive;
TPM2B_PUBLIC inPublic;
TPM2B_DATA outsideInfo;
TPML_PCR_SELECTION creationPCR;
TPM2B_CREATION_DATA creationData;
TPM2B_DIGEST creationHash;
TPMT_TK_CREATION creationTicket;
TPMS_AUTH_RESPONSE authResponse;
UINT32 i;
/* authCommand */
Memset(&authCommand, 0, sizeof(authCommand));
authCommand.sessionHandle = TPM_RS_PW;
/* inSensitive */
Memset(&inSensitive, 0, sizeof(inSensitive));
inSensitive.sensitive.data.size = size;
Memcpy(inSensitive.sensitive.data.buffer, (void*)data, size);
/* inPublic */
Memset(&inPublic, 0, sizeof(inPublic));
inPublic.publicArea.type = TPM_ALG_KEYEDHASH;
inPublic.publicArea.nameAlg = TPM_ALG_SHA256;
inPublic.publicArea.parameters.keyedHashDetail.scheme.scheme =
TPM_ALG_NULL;
inPublic.publicArea.authPolicy = policyDigest;
/* outsideInfo */
Memset(&outsideInfo, 0, sizeof(outsideInfo));
/* creationPCR: Select PCRs */
Memset(&creationPCR, 0, sizeof(creationPCR));
creationPCR.count = 1;
creationPCR.pcrSelections[0].sizeofSelect = 3;
creationPCR.pcrSelections[0].hash = TPM_ALG_SHA256;
for (i = 0; i < MAX_PCRS; i++)
{
if (pcrMask & (1 << i))
TPMS_PCR_SELECTION_SelectPCR(&creationPCR.pcrSelections[0], i);
}
if ((rc = TPM2_Create(
protocol,
parentKey,
&authCommand,
&inSensitive,
&inPublic,
&outsideInfo,
&creationPCR,
&outPrivate,
&outPublic,
&creationData,
&creationHash,
&creationTicket,
&authResponse)) != TPM_RC_SUCCESS)
{
SetErr(err, TCS("failed to create sealed object"));
goto done;
}
blob->private = outPrivate;
blob->public = outPublic;
blob->hash = creationHash;
blob->pcr.sizeofSelect = creationPCR.pcrSelections[0].sizeofSelect;
Memcpy(blob->pcr.pcrSelect,
creationPCR.pcrSelections[0].pcrSelect,
sizeof(blob->pcr.pcrSelect));
}
done:
if (!policyHandleNull)
TPM2_FlushContext(protocol, policyHandle);
return rc;
}