// This file was extracted from the TCG Published
// Trusted Platform Module Library
// Part 3: Commands
// Family "2.0"
// Level 00 Revision 01.16
// October 30, 2014
#include "InternalRoutines.h"
#include "PolicyAuthorize_fp.h"
#include "Policy_spt_fp.h"
//
//
// Error Returns Meaning
//
// TPM_RC_HASH hash algorithm in keyName is not supported
// TPM_RC_SIZE keyName is not the correct size for its hash algorithm
// TPM_RC_VALUE the current policyDigest of policySession does not match
// approvedPolicy; or checkTicket doesn't match the provided values
//
TPM_RC
TPM2_PolicyAuthorize(
PolicyAuthorize_In *in // IN: input parameter list
)
{
SESSION *session;
TPM2B_DIGEST authHash;
HASH_STATE hashState;
TPMT_TK_VERIFIED ticket;
TPM_ALG_ID hashAlg;
UINT16 digestSize;
// Input Validation
// Get pointer to the session structure
session = SessionGet(in->policySession);
// Extract from the Name of the key, the algorithm used to compute it's Name
hashAlg = BYTE_ARRAY_TO_UINT16(in->keySign.t.name);
// 'keySign' parameter needs to use a supported hash algorithm, otherwise
// can't tell how large the digest should be
digestSize = CryptGetHashDigestSize(hashAlg);
if(digestSize == 0)
return TPM_RC_HASH + RC_PolicyAuthorize_keySign;
if(digestSize != (in->keySign.t.size - 2))
return TPM_RC_SIZE + RC_PolicyAuthorize_keySign;
//If this is a trial policy, skip all validations
if(session->attributes.isTrialPolicy == CLEAR)
{
// Check that "approvedPolicy" matches the current value of the
// policyDigest in policy session
if(!Memory2BEqual(&session->u2.policyDigest.b,
&in->approvedPolicy.b))
return TPM_RC_VALUE + RC_PolicyAuthorize_approvedPolicy;
// Validate ticket TPMT_TK_VERIFIED
// Compute aHash. The authorizing object sign a digest
// aHash := hash(approvedPolicy || policyRef).
// Start hash
authHash.t.size = CryptStartHash(hashAlg, &hashState);
// add approvedPolicy
CryptUpdateDigest2B(&hashState, &in->approvedPolicy.b);
// add policyRef
CryptUpdateDigest2B(&hashState, &in->policyRef.b);
// complete hash
CryptCompleteHash2B(&hashState, &authHash.b);
// re-compute TPMT_TK_VERIFIED
TicketComputeVerified(in->checkTicket.hierarchy, &authHash,
&in->keySign, &ticket);
// Compare ticket digest. If not match, return error
if(!Memory2BEqual(&in->checkTicket.digest.b, &ticket.digest.b))
return TPM_RC_VALUE+ RC_PolicyAuthorize_checkTicket;
}
// Internal Data Update
// Set policyDigest to zero digest
MemorySet(session->u2.policyDigest.t.buffer, 0,
session->u2.policyDigest.t.size);
// Update policyDigest
PolicyContextUpdate(TPM_CC_PolicyAuthorize, &in->keySign, &in->policyRef,
NULL, 0, session);
return TPM_RC_SUCCESS;
}