TPM_RC TPM2X_Seal()

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;
}