1 // This file was extracted from the TCG Published 2 // Trusted Platform Module Library 3 // Part 4: Supporting Routines 4 // Family "2.0" 5 // Level 00 Revision 01.16 6 // October 30, 2014 7 8 #include "InternalRoutines.h" 9 #include "Policy_spt_fp.h" 10 #include "PolicySigned_fp.h" 11 #include "PolicySecret_fp.h" 12 #include "PolicyTicket_fp.h" 13 // 14 // 15 // PolicyParameterChecks() 16 // 17 // This function validates the common parameters of TPM2_PolicySiged() and TPM2_PolicySecret(). The 18 // common parameters are nonceTPM, expiration, and cpHashA. 19 // 20 TPM_RC 21 PolicyParameterChecks( 22 SESSION *session, 23 UINT64 authTimeout, 24 TPM2B_DIGEST *cpHashA, 25 TPM2B_NONCE *nonce, 26 TPM_RC nonceParameterNumber, 27 TPM_RC cpHashParameterNumber, 28 TPM_RC expirationParameterNumber 29 ) 30 { 31 TPM_RC result; 32 // Validate that input nonceTPM is correct if present 33 if(nonce != NULL && nonce->t.size != 0) 34 // 35 { 36 if(!Memory2BEqual(&nonce->b, &session->nonceTPM.b)) 37 return TPM_RC_NONCE + RC_PolicySigned_nonceTPM; 38 } 39 // If authTimeout is set (expiration != 0... 40 if(authTimeout != 0) 41 { 42 // ...then nonce must be present 43 // nonce present isn't checked in PolicyTicket 44 if(nonce != NULL && nonce->t.size == 0) 45 // This error says that the time has expired but it is pointing 46 // at the nonceTPM value. 47 return TPM_RC_EXPIRED + nonceParameterNumber; 48 // Validate input expiration. 49 // Cannot compare time if clock stop advancing. A TPM_RC_NV_UNAVAILABLE 50 // or TPM_RC_NV_RATE error may be returned here. 51 result = NvIsAvailable(); 52 if(result != TPM_RC_SUCCESS) 53 return result; 54 if(authTimeout < go.clock) 55 return TPM_RC_EXPIRED + expirationParameterNumber; 56 } 57 // If the cpHash is present, then check it 58 if(cpHashA != NULL && cpHashA->t.size != 0) 59 { 60 // The cpHash input has to have the correct size 61 if(cpHashA->t.size != session->u2.policyDigest.t.size) 62 return TPM_RC_SIZE + cpHashParameterNumber; 63 // If the cpHash has already been set, then this input value 64 // must match the current value. 65 if( session->u1.cpHash.b.size != 0 66 && !Memory2BEqual(&cpHashA->b, &session->u1.cpHash.b)) 67 return TPM_RC_CPHASH; 68 } 69 return TPM_RC_SUCCESS; 70 } 71 // 72 // 73 // PolicyContextUpdate() 74 // 75 // Update policy hash Update the policyDigest in policy session by extending policyRef and objectName to 76 // it. This will also update the cpHash if it is present. 77 // 78 void 79 PolicyContextUpdate( 80 TPM_CC commandCode, // IN: command code 81 TPM2B_NAME *name, // IN: name of entity 82 TPM2B_NONCE *ref, // IN: the reference data 83 TPM2B_DIGEST *cpHash, // IN: the cpHash (optional) 84 UINT64 policyTimeout, 85 SESSION *session // IN/OUT: policy session to be updated 86 ) 87 { 88 HASH_STATE hashState; 89 UINT16 policyDigestSize; 90 // Start hash 91 policyDigestSize = CryptStartHash(session->authHashAlg, &hashState); 92 // policyDigest size should always be the digest size of session hash algorithm. 93 pAssert(session->u2.policyDigest.t.size == policyDigestSize); 94 // add old digest 95 CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b); 96 // add commandCode 97 CryptUpdateDigestInt(&hashState, sizeof(commandCode), &commandCode); 98 // add name if applicable 99 if(name != NULL) 100 CryptUpdateDigest2B(&hashState, &name->b); 101 // Complete the digest and get the results 102 CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b); 103 // Start second hash computation 104 CryptStartHash(session->authHashAlg, &hashState); 105 // add policyDigest 106 CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b); 107 // add policyRef 108 if(ref != NULL) 109 CryptUpdateDigest2B(&hashState, &ref->b); 110 // Complete second digest 111 CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b); 112 // Deal with the cpHash. If the cpHash value is present 113 // then it would have already been checked to make sure that 114 // it is compatible with the current value so all we need 115 // to do here is copy it and set the iscoHashDefined attribute 116 if(cpHash != NULL && cpHash->t.size != 0) 117 { 118 session->u1.cpHash = *cpHash; 119 session->attributes.iscpHashDefined = SET; 120 } 121 // update the timeout if it is specified 122 if(policyTimeout!= 0) 123 { 124 // If the timeout has not been set, then set it to the new value 125 if(session->timeOut == 0) 126 session->timeOut = policyTimeout; 127 else if(session->timeOut > policyTimeout) 128 session->timeOut = policyTimeout; 129 } 130 return; 131 } 132