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