// This file was extracted from the TCG Published
// Trusted Platform Module Library
// Part 4: Supporting Routines
// Family "2.0"
// Level 00 Revision 01.16
// October 30, 2014
#include "InternalRoutines.h"
#include "Policy_spt_fp.h"
#include "PolicySigned_fp.h"
#include "PolicySecret_fp.h"
#include "PolicyTicket_fp.h"
//
//
// PolicyParameterChecks()
//
// This function validates the common parameters of TPM2_PolicySiged() and TPM2_PolicySecret(). The
// common parameters are nonceTPM, expiration, and cpHashA.
//
TPM_RC
PolicyParameterChecks(
SESSION *session,
UINT64 authTimeout,
TPM2B_DIGEST *cpHashA,
TPM2B_NONCE *nonce,
TPM_RC nonceParameterNumber,
TPM_RC cpHashParameterNumber,
TPM_RC expirationParameterNumber
)
{
TPM_RC result;
// Validate that input nonceTPM is correct if present
if(nonce != NULL && nonce->t.size != 0)
//
{
if(!Memory2BEqual(&nonce->b, &session->nonceTPM.b))
return TPM_RC_NONCE + RC_PolicySigned_nonceTPM;
}
// If authTimeout is set (expiration != 0...
if(authTimeout != 0)
{
// ...then nonce must be present
// nonce present isn't checked in PolicyTicket
if(nonce != NULL && nonce->t.size == 0)
// This error says that the time has expired but it is pointing
// at the nonceTPM value.
return TPM_RC_EXPIRED + nonceParameterNumber;
// Validate input expiration.
// Cannot compare time if clock stop advancing. A TPM_RC_NV_UNAVAILABLE
// or TPM_RC_NV_RATE error may be returned here.
result = NvIsAvailable();
if(result != TPM_RC_SUCCESS)
return result;
if(authTimeout < go.clock)
return TPM_RC_EXPIRED + expirationParameterNumber;
}
// If the cpHash is present, then check it
if(cpHashA != NULL && cpHashA->t.size != 0)
{
// The cpHash input has to have the correct size
if(cpHashA->t.size != session->u2.policyDigest.t.size)
return TPM_RC_SIZE + cpHashParameterNumber;
// If the cpHash has already been set, then this input value
// must match the current value.
if( session->u1.cpHash.b.size != 0
&& !Memory2BEqual(&cpHashA->b, &session->u1.cpHash.b))
return TPM_RC_CPHASH;
}
return TPM_RC_SUCCESS;
}
//
//
// PolicyContextUpdate()
//
// Update policy hash Update the policyDigest in policy session by extending policyRef and objectName to
// it. This will also update the cpHash if it is present.
//
void
PolicyContextUpdate(
TPM_CC commandCode, // IN: command code
TPM2B_NAME *name, // IN: name of entity
TPM2B_NONCE *ref, // IN: the reference data
TPM2B_DIGEST *cpHash, // IN: the cpHash (optional)
UINT64 policyTimeout,
SESSION *session // IN/OUT: policy session to be updated
)
{
HASH_STATE hashState;
UINT16 policyDigestSize;
// Start hash
policyDigestSize = CryptStartHash(session->authHashAlg, &hashState);
// policyDigest size should always be the digest size of session hash algorithm.
pAssert(session->u2.policyDigest.t.size == policyDigestSize);
// add old digest
CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b);
// add commandCode
CryptUpdateDigestInt(&hashState, sizeof(commandCode), &commandCode);
// add name if applicable
if(name != NULL)
CryptUpdateDigest2B(&hashState, &name->b);
// Complete the digest and get the results
CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b);
// Start second hash computation
CryptStartHash(session->authHashAlg, &hashState);
// add policyDigest
CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b);
// add policyRef
if(ref != NULL)
CryptUpdateDigest2B(&hashState, &ref->b);
// Complete second digest
CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b);
// Deal with the cpHash. If the cpHash value is present
// then it would have already been checked to make sure that
// it is compatible with the current value so all we need
// to do here is copy it and set the iscoHashDefined attribute
if(cpHash != NULL && cpHash->t.size != 0)
{
session->u1.cpHash = *cpHash;
session->attributes.iscpHashDefined = SET;
}
// update the timeout if it is specified
if(policyTimeout!= 0)
{
// If the timeout has not been set, then set it to the new value
if(session->timeOut == 0)
session->timeOut = policyTimeout;
else if(session->timeOut > policyTimeout)
session->timeOut = policyTimeout;
}
return;
}