Vadim Bendebury | 5679752 | 2015-05-20 10:32:25 -0700 | [diff] [blame] | 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 | // |
| 19 | TPM_RC |
| 20 | TPM2_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 | } |