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
TPM2_PolicyCounterTimer(PolicyCounterTimer_In * in)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 }
175