1// This file was extracted from the TCG Published 2// Trusted Platform Module Library 3// Part 3: Commands 4// Family "2.0" 5// Level 00 Revision 01.16 6// October 30, 2014 7 8#include "InternalRoutines.h" 9#include "PolicyCounterTimer_fp.h" 10#include "Policy_spt_fp.h" 11// 12// 13// Error Returns Meaning 14// 15// TPM_RC_POLICY the comparison of the selected portion of the TPMS_TIME_INFO with 16// operandB failed 17// TPM_RC_RANGE offset + size exceed size of TPMS_TIME_INFO structure 18// 19TPM_RC 20TPM2_PolicyCounterTimer( 21 PolicyCounterTimer_In *in // IN: input parameter list 22 ) 23{ 24 TPM_RC result; 25 SESSION *session; 26 TIME_INFO infoData; // data buffer of TPMS_TIME_INFO 27 TPM_CC commandCode = TPM_CC_PolicyCounterTimer; 28 HASH_STATE hashState; 29 TPM2B_DIGEST argHash; 30 31// Input Validation 32 33 // If the command is going to use any part of the counter or timer, need 34 // to verify that time is advancing. 35 // The time and clock vales are the first two 64-bit values in the clock 36 if(in->offset < sizeof(UINT64) + sizeof(UINT64)) 37 { 38 // Using Clock or Time so see if clock is running. Clock doesn't run while 39 // NV is unavailable. 40 // TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned here. 41 result = NvIsAvailable(); 42 if(result != TPM_RC_SUCCESS) 43 return result; 44 } 45 // Get pointer to the session structure 46 session = SessionGet(in->policySession); 47 48 //If this is a trial policy, skip all validations and the operation 49 if(session->attributes.isTrialPolicy == CLEAR) 50 { 51 // Get time data info. The size of time info data equals the input 52 // operand B size. A TPM_RC_RANGE error may be returned at this point 53 result = TimeGetRange(in->offset, in->operandB.t.size, &infoData); 54 if(result != TPM_RC_SUCCESS) return result; 55 56 // Arithmetic Comparison 57 switch(in->operation) 58 { 59 case TPM_EO_EQ: 60 // compare A = B 61 if(CryptCompare(in->operandB.t.size, infoData, 62 in->operandB.t.size, in->operandB.t.buffer) != 0) 63 return TPM_RC_POLICY; 64 break; 65 case TPM_EO_NEQ: 66 // compare A != B 67 if(CryptCompare(in->operandB.t.size, infoData, 68 in->operandB.t.size, in->operandB.t.buffer) == 0) 69 return TPM_RC_POLICY; 70 break; 71 case TPM_EO_SIGNED_GT: 72 // compare A > B signed 73 if(CryptCompareSigned(in->operandB.t.size, infoData, 74 in->operandB.t.size, in->operandB.t.buffer) <= 0) 75 return TPM_RC_POLICY; 76 break; 77 case TPM_EO_UNSIGNED_GT: 78 // compare A > B unsigned 79 if(CryptCompare(in->operandB.t.size, infoData, 80 in->operandB.t.size, in->operandB.t.buffer) <= 0) 81 return TPM_RC_POLICY; 82 break; 83 case TPM_EO_SIGNED_LT: 84 // compare A < B signed 85 if(CryptCompareSigned(in->operandB.t.size, infoData, 86 in->operandB.t.size, in->operandB.t.buffer) >= 0) 87 return TPM_RC_POLICY; 88 break; 89 case TPM_EO_UNSIGNED_LT: 90 // compare A < B unsigned 91 if(CryptCompare(in->operandB.t.size, infoData, 92 in->operandB.t.size, in->operandB.t.buffer) >= 0) 93 return TPM_RC_POLICY; 94 break; 95 case TPM_EO_SIGNED_GE: 96 // compare A >= B signed 97 if(CryptCompareSigned(in->operandB.t.size, infoData, 98 in->operandB.t.size, in->operandB.t.buffer) < 0) 99 return TPM_RC_POLICY; 100 break; 101 case TPM_EO_UNSIGNED_GE: 102 // compare A >= B unsigned 103 if(CryptCompare(in->operandB.t.size, infoData, 104 in->operandB.t.size, in->operandB.t.buffer) < 0) 105 return TPM_RC_POLICY; 106 break; 107 case TPM_EO_SIGNED_LE: 108 // compare A <= B signed 109 if(CryptCompareSigned(in->operandB.t.size, infoData, 110 in->operandB.t.size, in->operandB.t.buffer) > 0) 111 return TPM_RC_POLICY; 112 break; 113 case TPM_EO_UNSIGNED_LE: 114 // compare A <= B unsigned 115 if(CryptCompare(in->operandB.t.size, infoData, 116 in->operandB.t.size, in->operandB.t.buffer) > 0) 117 return TPM_RC_POLICY; 118 break; 119 case TPM_EO_BITSET: 120 // All bits SET in B are SET in A. ((A&B)=B) 121 { 122 UINT32 i; 123 for (i = 0; i < in->operandB.t.size; i++) 124 if( (infoData[i] & in->operandB.t.buffer[i]) 125 != in->operandB.t.buffer[i]) 126 return TPM_RC_POLICY; 127 } 128 break; 129 case TPM_EO_BITCLEAR: 130 // All bits SET in B are CLEAR in A. ((A&B)=0) 131 { 132 UINT32 i; 133 for (i = 0; i < in->operandB.t.size; i++) 134 if((infoData[i] & in->operandB.t.buffer[i]) != 0) 135 return TPM_RC_POLICY; 136 } 137 break; 138 default: 139 pAssert(FALSE); 140 break; 141 } 142 } 143 144// Internal Data Update 145 146 // Start argument list hash 147 argHash.t.size = CryptStartHash(session->authHashAlg, &hashState); 148 // add operandB 149 CryptUpdateDigest2B(&hashState, &in->operandB.b); 150 // add offset 151 CryptUpdateDigestInt(&hashState, sizeof(UINT16), &in->offset); 152 // add operation 153 CryptUpdateDigestInt(&hashState, sizeof(TPM_EO), &in->operation); 154 // complete argument hash 155 CryptCompleteHash2B(&hashState, &argHash.b); 156 157 // update policyDigest 158 // start hash 159 CryptStartHash(session->authHashAlg, &hashState); 160 161 // add old digest 162 CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b); 163 164 // add commandCode 165 CryptUpdateDigestInt(&hashState, sizeof(TPM_CC), &commandCode); 166 167 // add argument digest 168 CryptUpdateDigest2B(&hashState, &argHash.b); 169 170 // complete the digest 171 CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b); 172 173 return TPM_RC_SUCCESS; 174} 175