/src/libtpms/src/tpm2/EACommands.c
Line | Count | Source |
1 | | /********************************************************************************/ |
2 | | /* */ |
3 | | /* Enhanced Authorization Commands */ |
4 | | /* Written by Ken Goldman */ |
5 | | /* IBM Thomas J. Watson Research Center */ |
6 | | /* */ |
7 | | /* Licenses and Notices */ |
8 | | /* */ |
9 | | /* 1. Copyright Licenses: */ |
10 | | /* */ |
11 | | /* - Trusted Computing Group (TCG) grants to the user of the source code in */ |
12 | | /* this specification (the "Source Code") a worldwide, irrevocable, */ |
13 | | /* nonexclusive, royalty free, copyright license to reproduce, create */ |
14 | | /* derivative works, distribute, display and perform the Source Code and */ |
15 | | /* derivative works thereof, and to grant others the rights granted herein. */ |
16 | | /* */ |
17 | | /* - The TCG grants to the user of the other parts of the specification */ |
18 | | /* (other than the Source Code) the rights to reproduce, distribute, */ |
19 | | /* display, and perform the specification solely for the purpose of */ |
20 | | /* developing products based on such documents. */ |
21 | | /* */ |
22 | | /* 2. Source Code Distribution Conditions: */ |
23 | | /* */ |
24 | | /* - Redistributions of Source Code must retain the above copyright licenses, */ |
25 | | /* this list of conditions and the following disclaimers. */ |
26 | | /* */ |
27 | | /* - Redistributions in binary form must reproduce the above copyright */ |
28 | | /* licenses, this list of conditions and the following disclaimers in the */ |
29 | | /* documentation and/or other materials provided with the distribution. */ |
30 | | /* */ |
31 | | /* 3. Disclaimers: */ |
32 | | /* */ |
33 | | /* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */ |
34 | | /* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */ |
35 | | /* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */ |
36 | | /* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */ |
37 | | /* Contact TCG Administration (admin@trustedcomputinggroup.org) for */ |
38 | | /* information on specification licensing rights available through TCG */ |
39 | | /* membership agreements. */ |
40 | | /* */ |
41 | | /* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */ |
42 | | /* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */ |
43 | | /* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */ |
44 | | /* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */ |
45 | | /* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */ |
46 | | /* */ |
47 | | /* - Without limitation, TCG and its members and licensors disclaim all */ |
48 | | /* liability, including liability for infringement of any proprietary */ |
49 | | /* rights, relating to use of information in this specification and to the */ |
50 | | /* implementation of this specification, and TCG disclaims all liability for */ |
51 | | /* cost of procurement of substitute goods or services, lost profits, loss */ |
52 | | /* of use, loss of data or any incidental, consequential, direct, indirect, */ |
53 | | /* or special damages, whether under contract, tort, warranty or otherwise, */ |
54 | | /* arising in any way out of use or reliance upon this specification or any */ |
55 | | /* information herein. */ |
56 | | /* */ |
57 | | /* (c) Copyright IBM Corp. and others, 2016 - 2023 */ |
58 | | /* */ |
59 | | /********************************************************************************/ |
60 | | |
61 | | |
62 | | #include "Tpm.h" |
63 | | #include "PolicyOR_fp.h" |
64 | | |
65 | | #if CC_PolicyOR // Conditional expansion of this file |
66 | | |
67 | | # include "Policy_spt_fp.h" |
68 | | |
69 | | /*(See part 3 specification) |
70 | | // PolicyOR command |
71 | | */ |
72 | | // Return Type: TPM_RC |
73 | | // TPM_RC_VALUE no digest in 'pHashList' matched the current |
74 | | // value of policyDigest for 'policySession' |
75 | | TPM_RC |
76 | | TPM2_PolicyOR(PolicyOR_In* in // IN: input parameter list |
77 | | ) |
78 | 0 | { |
79 | 0 | SESSION* session; |
80 | 0 | UINT32 i; |
81 | | // Input Validation and Update |
82 | | |
83 | | // Get pointer to the session structure |
84 | 0 | session = SessionGet(in->policySession); |
85 | 0 | pAssert_RC(session); |
86 | | |
87 | | // Compare and Update Internal Session policy if match |
88 | 0 | for(i = 0; i < in->pHashList.count; i++) |
89 | 0 | { |
90 | 0 | if(session->attributes.isTrialPolicy == SET |
91 | 0 | || (MemoryEqual2B(&session->u2.policyDigest.b, |
92 | 0 | &in->pHashList.digests[i].b))) |
93 | 0 | { |
94 | | // Found a match |
95 | 0 | HASH_STATE hashState; |
96 | 0 | TPM_CC commandCode = TPM_CC_PolicyOR; |
97 | | |
98 | | // Start hash |
99 | 0 | session->u2.policyDigest.t.size = |
100 | 0 | CryptHashStart(&hashState, session->authHashAlg); |
101 | | // Set policyDigest to 0 string and add it to hash |
102 | 0 | MemorySet(session->u2.policyDigest.t.buffer, |
103 | 0 | 0, |
104 | 0 | session->u2.policyDigest.t.size); |
105 | 0 | CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b); |
106 | | |
107 | | // add command code |
108 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode); |
109 | | |
110 | | // Add each of the hashes in the list |
111 | 0 | for(i = 0; i < in->pHashList.count; i++) |
112 | 0 | { |
113 | | // Extend policyDigest |
114 | 0 | CryptDigestUpdate2B(&hashState, &in->pHashList.digests[i].b); |
115 | 0 | } |
116 | | // Complete digest |
117 | 0 | CryptHashEnd2B(&hashState, &session->u2.policyDigest.b); |
118 | |
|
119 | 0 | return TPM_RC_SUCCESS; |
120 | 0 | } |
121 | 0 | } |
122 | | // None of the values in the list matched the current policyDigest |
123 | 0 | return TPM_RCS_VALUE + RC_PolicyOR_pHashList; |
124 | 0 | } |
125 | | |
126 | | #endif // CC_PolicyOR |
127 | | |
128 | | |
129 | | #include "Tpm.h" |
130 | | #include "PolicyPhysicalPresence_fp.h" |
131 | | |
132 | | #if CC_PolicyPhysicalPresence // Conditional expansion of this file |
133 | | |
134 | | /*(See part 3 specification) |
135 | | // indicate that physical presence will need to be asserted at the time the |
136 | | // authorization is performed |
137 | | */ |
138 | | TPM_RC |
139 | | TPM2_PolicyPhysicalPresence(PolicyPhysicalPresence_In* in // IN: input parameter list |
140 | | ) |
141 | 0 | { |
142 | 0 | SESSION* session; |
143 | 0 | TPM_CC commandCode = TPM_CC_PolicyPhysicalPresence; |
144 | 0 | HASH_STATE hashState; |
145 | | |
146 | | // Internal Data Update |
147 | | |
148 | | // Get pointer to the session structure |
149 | 0 | session = SessionGet(in->policySession); |
150 | 0 | pAssert_RC(session); |
151 | | |
152 | | // Update policy hash |
153 | | // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyPhysicalPresence) |
154 | | // Start hash |
155 | 0 | CryptHashStart(&hashState, session->authHashAlg); |
156 | | |
157 | | // add old digest |
158 | 0 | CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b); |
159 | | |
160 | | // add commandCode |
161 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode); |
162 | | |
163 | | // complete the digest |
164 | 0 | CryptHashEnd2B(&hashState, &session->u2.policyDigest.b); |
165 | | |
166 | | // update session attribute |
167 | 0 | session->attributes.isPPRequired = SET; |
168 | |
|
169 | 0 | return TPM_RC_SUCCESS; |
170 | 0 | } |
171 | | |
172 | | #endif // CC_PolicyPhysicalPresence |
173 | | |
174 | | |
175 | | #include "Tpm.h" |
176 | | #include "PolicyLocality_fp.h" |
177 | | #include "Marshal.h" |
178 | | |
179 | | #if CC_PolicyLocality // Conditional expansion of this file |
180 | | |
181 | | // Return Type: TPM_RC |
182 | | // TPM_RC_RANGE all the locality values selected by |
183 | | // 'locality' have been disabled |
184 | | // by previous TPM2_PolicyLocality() calls. |
185 | | TPM_RC |
186 | | TPM2_PolicyLocality(PolicyLocality_In* in // IN: input parameter list |
187 | | ) |
188 | 0 | { |
189 | 0 | SESSION* session; |
190 | 0 | BYTE marshalBuffer[sizeof(TPMA_LOCALITY)]; |
191 | 0 | BYTE prevSetting[sizeof(TPMA_LOCALITY)]; |
192 | 0 | UINT32 marshalSize; |
193 | 0 | BYTE* buffer; |
194 | 0 | TPM_CC commandCode = TPM_CC_PolicyLocality; |
195 | 0 | HASH_STATE hashState; |
196 | | // Input Validation |
197 | | |
198 | | // Get pointer to the session structure |
199 | 0 | session = SessionGet(in->policySession); |
200 | 0 | pAssert_RC(session); |
201 | | |
202 | | // Get new locality setting in canonical form |
203 | 0 | marshalBuffer[0] = 0; // Code analysis says that this is not initialized |
204 | 0 | buffer = marshalBuffer; |
205 | 0 | marshalSize = TPMA_LOCALITY_Marshal(&in->locality, &buffer, NULL); |
206 | | |
207 | | // Its an error if the locality parameter is zero |
208 | 0 | if(marshalBuffer[0] == 0) |
209 | 0 | return TPM_RCS_RANGE + RC_PolicyLocality_locality; |
210 | | |
211 | | // Get existing locality setting in canonical form |
212 | 0 | prevSetting[0] = 0; // Code analysis says that this is not initialized |
213 | 0 | buffer = prevSetting; |
214 | 0 | TPMA_LOCALITY_Marshal(&session->commandLocality, &buffer, NULL); |
215 | | |
216 | | // If the locality has previously been set |
217 | 0 | if(prevSetting[0] != 0 |
218 | | // then the current locality setting and the requested have to be the same |
219 | | // type (that is, either both normal or both extended |
220 | 0 | && ((prevSetting[0] < 32) != (marshalBuffer[0] < 32))) |
221 | 0 | return TPM_RCS_RANGE + RC_PolicyLocality_locality; |
222 | | |
223 | | // See if the input is a regular or extended locality |
224 | 0 | if(marshalBuffer[0] < 32) |
225 | 0 | { |
226 | | // if there was no previous setting, start with all normal localities |
227 | | // enabled |
228 | 0 | if(prevSetting[0] == 0) |
229 | 0 | prevSetting[0] = 0x1F; |
230 | | |
231 | | // AND the new setting with the previous setting and store it in prevSetting |
232 | 0 | prevSetting[0] &= marshalBuffer[0]; |
233 | | |
234 | | // The result setting can not be 0 |
235 | 0 | if(prevSetting[0] == 0) |
236 | 0 | return TPM_RCS_RANGE + RC_PolicyLocality_locality; |
237 | 0 | } |
238 | 0 | else |
239 | 0 | { |
240 | | // for extended locality |
241 | | // if the locality has already been set, then it must match the |
242 | 0 | if(prevSetting[0] != 0 && prevSetting[0] != marshalBuffer[0]) |
243 | 0 | return TPM_RCS_RANGE + RC_PolicyLocality_locality; |
244 | | |
245 | | // Setting is OK |
246 | 0 | prevSetting[0] = marshalBuffer[0]; |
247 | 0 | } |
248 | | |
249 | | // Internal Data Update |
250 | | |
251 | | // Update policy hash |
252 | | // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyLocality || locality) |
253 | | // Start hash |
254 | 0 | CryptHashStart(&hashState, session->authHashAlg); |
255 | | |
256 | | // add old digest |
257 | 0 | CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b); |
258 | | |
259 | | // add commandCode |
260 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode); |
261 | | |
262 | | // add input locality |
263 | 0 | CryptDigestUpdate(&hashState, marshalSize, marshalBuffer); |
264 | | |
265 | | // complete the digest |
266 | 0 | CryptHashEnd2B(&hashState, &session->u2.policyDigest.b); |
267 | | |
268 | | // update session locality by unmarshal function. The function must succeed |
269 | | // because both input and existing locality setting have been validated. |
270 | 0 | buffer = prevSetting; |
271 | 0 | TPMA_LOCALITY_Unmarshal(&session->commandLocality, &buffer, (INT32*)&marshalSize); |
272 | |
|
273 | 0 | return TPM_RC_SUCCESS; |
274 | 0 | } |
275 | | |
276 | | #endif // CC_PolicyLocality |
277 | | |
278 | | |
279 | | |
280 | | #include "Tpm.h" |
281 | | #include "PolicyNV_fp.h" |
282 | | |
283 | | #if CC_PolicyNV // Conditional expansion of this file |
284 | | |
285 | | # include "Policy_spt_fp.h" |
286 | | |
287 | | /*(See part 3 specification) |
288 | | // Do comparison to NV location |
289 | | */ |
290 | | // Return Type: TPM_RC |
291 | | // TPM_RC_AUTH_TYPE NV index authorization type is not correct |
292 | | // TPM_RC_NV_LOCKED NV index read locked |
293 | | // TPM_RC_NV_UNINITIALIZED the NV index has not been initialized |
294 | | // TPM_RC_POLICY the comparison to the NV contents failed |
295 | | // TPM_RC_SIZE the size of 'nvIndex' data starting at 'offset' |
296 | | // is less than the size of 'operandB' |
297 | | // TPM_RC_VALUE 'offset' is too large |
298 | | TPM_RC |
299 | | TPM2_PolicyNV(PolicyNV_In* in // IN: input parameter list |
300 | | ) |
301 | 0 | { |
302 | 0 | TPM_RC result; |
303 | 0 | SESSION* session; |
304 | 0 | NV_REF locator; |
305 | 0 | NV_INDEX* nvIndex; |
306 | 0 | BYTE nvBuffer[sizeof(in->operandB.t.buffer)]; |
307 | 0 | TPM2B_NAME nvName; |
308 | 0 | TPM_CC commandCode = TPM_CC_PolicyNV; |
309 | 0 | HASH_STATE hashState; |
310 | 0 | TPM2B_DIGEST argHash; |
311 | | // Input Validation |
312 | | |
313 | | // Get pointer to the session structure |
314 | 0 | session = SessionGet(in->policySession); |
315 | 0 | pAssert_RC(session); |
316 | | |
317 | | //If this is a trial policy, skip all validations and the operation |
318 | 0 | if(session->attributes.isTrialPolicy == CLEAR) |
319 | 0 | { |
320 | | // No need to access the actual NV index information for a trial policy. |
321 | 0 | nvIndex = NvGetIndexInfo(in->nvIndex, &locator); |
322 | | |
323 | | // Common read access checks. NvReadAccessChecks() may return |
324 | | // TPM_RC_NV_AUTHORIZATION, TPM_RC_NV_LOCKED, or TPM_RC_NV_UNINITIALIZED |
325 | 0 | result = NvReadAccessChecks( |
326 | 0 | in->authHandle, in->nvIndex, nvIndex->publicArea.attributes); |
327 | 0 | if(result != TPM_RC_SUCCESS) |
328 | 0 | return result; |
329 | | |
330 | | // Make sure that offset is within range |
331 | 0 | if(in->offset > nvIndex->publicArea.dataSize) |
332 | 0 | return TPM_RCS_VALUE + RC_PolicyNV_offset; |
333 | | |
334 | | // Valid NV data size should not be smaller than input operandB size |
335 | 0 | if((nvIndex->publicArea.dataSize - in->offset) < in->operandB.t.size) |
336 | 0 | return TPM_RCS_SIZE + RC_PolicyNV_operandB; |
337 | | |
338 | | // Get NV data. The size of NV data equals the input operand B size |
339 | 0 | NvGetIndexData(nvIndex, locator, in->offset, in->operandB.t.size, nvBuffer); |
340 | | |
341 | | // Check to see if the condition is valid |
342 | 0 | if(!PolicySptCheckCondition(in->operation, nvBuffer, |
343 | 0 | in->operandB.t.buffer, in->operandB.t.size)) |
344 | 0 | return TPM_RC_POLICY; |
345 | 0 | } |
346 | | // Internal Data Update |
347 | | |
348 | | // Start argument hash |
349 | 0 | argHash.t.size = CryptHashStart(&hashState, session->authHashAlg); |
350 | | |
351 | | // add operandB |
352 | 0 | CryptDigestUpdate2B(&hashState, &in->operandB.b); |
353 | | |
354 | | // add offset |
355 | 0 | CryptDigestUpdateInt(&hashState, sizeof(UINT16), in->offset); |
356 | | |
357 | | // add operation |
358 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_EO), in->operation); |
359 | | |
360 | | // complete argument digest |
361 | 0 | CryptHashEnd2B(&hashState, &argHash.b); |
362 | | |
363 | | // Update policyDigest |
364 | | // Start digest |
365 | 0 | CryptHashStart(&hashState, session->authHashAlg); |
366 | | |
367 | | // add old digest |
368 | 0 | CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b); |
369 | | |
370 | | // add commandCode |
371 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode); |
372 | | |
373 | | // add argument digest |
374 | 0 | CryptDigestUpdate2B(&hashState, &argHash.b); |
375 | | |
376 | | // Adding nvName |
377 | 0 | CryptDigestUpdate2B(&hashState, &EntityGetName(in->nvIndex, &nvName)->b); |
378 | | |
379 | | // complete the digest |
380 | 0 | CryptHashEnd2B(&hashState, &session->u2.policyDigest.b); |
381 | |
|
382 | 0 | return TPM_RC_SUCCESS; |
383 | 0 | } |
384 | | |
385 | | #endif // CC_PolicyNV |
386 | | |
387 | | |
388 | | #include "Tpm.h" |
389 | | #include "PolicyCounterTimer_fp.h" |
390 | | |
391 | | #if CC_PolicyCounterTimer // Conditional expansion of this file |
392 | | |
393 | | # include "Policy_spt_fp.h" |
394 | | |
395 | | /*(See part 3 specification) |
396 | | // Add a conditional gating of a policy based on the contents of the |
397 | | // TPMS_TIME_INFO structure. |
398 | | */ |
399 | | // Return Type: TPM_RC |
400 | | // TPM_RC_POLICY the comparison of the selected portion of the |
401 | | // TPMS_TIME_INFO with 'operandB' failed |
402 | | // TPM_RC_RANGE 'offset' + 'size' exceed size of TPMS_TIME_INFO |
403 | | // structure |
404 | | TPM_RC |
405 | | TPM2_PolicyCounterTimer(PolicyCounterTimer_In* in // IN: input parameter list |
406 | | ) |
407 | 0 | { |
408 | 0 | SESSION* session; |
409 | 0 | TIME_INFO infoData; // data buffer of TPMS_TIME_INFO |
410 | 0 | BYTE* pInfoData = (BYTE*)&infoData; |
411 | 0 | UINT16 infoDataSize; |
412 | 0 | TPM_CC commandCode = TPM_CC_PolicyCounterTimer; |
413 | 0 | HASH_STATE hashState; |
414 | 0 | TPM2B_DIGEST argHash; |
415 | | // Input Validation |
416 | | // Get a marshaled time structure |
417 | 0 | infoDataSize = TimeGetMarshaled(&infoData); |
418 | 0 | pAssert(infoDataSize <= sizeof(infoData)); // libtpms added; 25 < 32 ==> unfounded coverity complaint |
419 | | // Make sure that the referenced stays within the bounds of the structure. |
420 | | // NOTE: the offset checks are made even for a trial policy because the policy |
421 | | // will not make any sense if the references are out of bounds of the timer |
422 | | // structure. |
423 | 0 | if(in->offset > infoDataSize) |
424 | 0 | return TPM_RCS_VALUE + RC_PolicyCounterTimer_offset; |
425 | 0 | if((UINT32)in->offset + (UINT32)in->operandB.t.size > infoDataSize) |
426 | 0 | return TPM_RCS_RANGE; |
427 | | // Get pointer to the session structure |
428 | 0 | session = SessionGet(in->policySession); |
429 | 0 | pAssert_RC(session); |
430 | | |
431 | | //If this is a trial policy, skip the check to see if the condition is met. |
432 | 0 | if(session->attributes.isTrialPolicy == CLEAR) |
433 | 0 | { |
434 | | // If the command is going to use any part of the counter or timer, need |
435 | | // to verify that time is advancing. |
436 | | // The time and clock vales are the first two 64-bit values in the clock |
437 | 0 | if(in->offset < sizeof(UINT64) + sizeof(UINT64)) |
438 | 0 | { |
439 | | // Using Clock or Time so see if clock is running. Clock doesn't |
440 | | // run while NV is unavailable. |
441 | | // TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned here. |
442 | 0 | RETURN_IF_NV_IS_NOT_AVAILABLE; |
443 | 0 | } |
444 | | // offset to the starting position |
445 | 0 | pInfoData = (BYTE*)infoData; |
446 | | // Check to see if the condition is valid |
447 | 0 | if(!PolicySptCheckCondition(in->operation, |
448 | 0 | pInfoData + in->offset, |
449 | 0 | in->operandB.t.buffer, |
450 | 0 | in->operandB.t.size)) |
451 | 0 | return TPM_RC_POLICY; |
452 | 0 | } |
453 | | // Internal Data Update |
454 | | // Start argument list hash |
455 | 0 | argHash.t.size = CryptHashStart(&hashState, session->authHashAlg); |
456 | | // add operandB |
457 | 0 | CryptDigestUpdate2B(&hashState, &in->operandB.b); |
458 | | // add offset |
459 | 0 | CryptDigestUpdateInt(&hashState, sizeof(UINT16), in->offset); |
460 | | // add operation |
461 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_EO), in->operation); |
462 | | // complete argument hash |
463 | 0 | CryptHashEnd2B(&hashState, &argHash.b); |
464 | | |
465 | | // update policyDigest |
466 | | // start hash |
467 | 0 | CryptHashStart(&hashState, session->authHashAlg); |
468 | | |
469 | | // add old digest |
470 | 0 | CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b); |
471 | | |
472 | | // add commandCode |
473 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode); |
474 | | |
475 | | // add argument digest |
476 | 0 | CryptDigestUpdate2B(&hashState, &argHash.b); |
477 | | |
478 | | // complete the digest |
479 | 0 | CryptHashEnd2B(&hashState, &session->u2.policyDigest.b); |
480 | |
|
481 | 0 | return TPM_RC_SUCCESS; |
482 | 0 | } |
483 | | |
484 | | #endif // CC_PolicyCounterTimer |
485 | | |
486 | | |
487 | | |
488 | | #include "Tpm.h" |
489 | | #include "PolicyCommandCode_fp.h" |
490 | | |
491 | | #if CC_PolicyCommandCode // Conditional expansion of this file |
492 | | |
493 | | /*(See part 3 specification) |
494 | | // Add a Command Code restriction to the policyDigest |
495 | | */ |
496 | | // Return Type: TPM_RC |
497 | | // TPM_RC_VALUE 'commandCode' of 'policySession' previously set to |
498 | | // a different value |
499 | | |
500 | | TPM_RC |
501 | | TPM2_PolicyCommandCode(PolicyCommandCode_In* in // IN: input parameter list |
502 | | ) |
503 | 0 | { |
504 | 0 | SESSION* session; |
505 | 0 | TPM_CC commandCode = TPM_CC_PolicyCommandCode; |
506 | 0 | HASH_STATE hashState; |
507 | | // Input validation |
508 | | |
509 | | // Get pointer to the session structure |
510 | 0 | session = SessionGet(in->policySession); |
511 | 0 | pAssert_RC(session); |
512 | |
|
513 | 0 | if(session->commandCode != 0 && session->commandCode != in->code) |
514 | 0 | return TPM_RCS_VALUE + RC_PolicyCommandCode_code; |
515 | 0 | if(CommandCodeToCommandIndex(in->code) == UNIMPLEMENTED_COMMAND_INDEX) |
516 | 0 | return TPM_RCS_POLICY_CC + RC_PolicyCommandCode_code; |
517 | | |
518 | | // Internal Data Update |
519 | | // Update policy hash |
520 | | // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyCommandCode || code) |
521 | | // Start hash |
522 | 0 | CryptHashStart(&hashState, session->authHashAlg); |
523 | | |
524 | | // add old digest |
525 | 0 | CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b); |
526 | | |
527 | | // add commandCode |
528 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode); |
529 | | |
530 | | // add input commandCode |
531 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), in->code); |
532 | | |
533 | | // complete the hash and get the results |
534 | 0 | CryptHashEnd2B(&hashState, &session->u2.policyDigest.b); |
535 | | |
536 | | // update commandCode value in session context |
537 | 0 | session->commandCode = in->code; |
538 | |
|
539 | 0 | return TPM_RC_SUCCESS; |
540 | 0 | } |
541 | | |
542 | | #endif // CC_PolicyCommandCode |
543 | | |
544 | | |
545 | | #include "Tpm.h" |
546 | | #include "PolicyCpHash_fp.h" |
547 | | |
548 | | #if CC_PolicyCpHash // Conditional expansion of this file |
549 | | |
550 | | /*(See part 3 specification) |
551 | | // Add a cpHash restriction to the policyDigest |
552 | | */ |
553 | | // Return Type: TPM_RC |
554 | | // TPM_RC_CPHASH cpHash of 'policySession' has previously been set |
555 | | // to a different value |
556 | | // TPM_RC_SIZE 'cpHashA' is not the size of a digest produced |
557 | | // by the hash algorithm associated with |
558 | | // 'policySession' |
559 | | TPM_RC |
560 | | TPM2_PolicyCpHash(PolicyCpHash_In* in // IN: input parameter list |
561 | | ) |
562 | 0 | { |
563 | 0 | SESSION* session; |
564 | 0 | TPM_CC commandCode = TPM_CC_PolicyCpHash; |
565 | 0 | HASH_STATE hashState; |
566 | | // Input Validation |
567 | | |
568 | | // Get pointer to the session structure |
569 | 0 | session = SessionGet(in->policySession); |
570 | 0 | pAssert_RC(session); |
571 | | |
572 | | // A valid cpHash must have the same size as session hash digest |
573 | | // NOTE: the size of the digest can't be zero because TPM_ALG_NULL |
574 | | // can't be used for the authHashAlg. |
575 | 0 | if(in->cpHashA.t.size != CryptHashGetDigestSize(session->authHashAlg)) |
576 | 0 | return TPM_RCS_SIZE + RC_PolicyCpHash_cpHashA; |
577 | | |
578 | | // error if the cpHash in session context is not empty and is not the same |
579 | | // as the input or is not a cpHash |
580 | 0 | if((IsCpHashUnionOccupied(session->attributes)) |
581 | 0 | && (!session->attributes.isCpHashDefined |
582 | 0 | || !MemoryEqual2B(&in->cpHashA.b, &session->u1.cpHash.b))) |
583 | 0 | return TPM_RC_CPHASH; |
584 | | |
585 | | // Internal Data Update |
586 | | |
587 | | // Update policy hash |
588 | | // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyCpHash || cpHashA) |
589 | | // Start hash |
590 | 0 | CryptHashStart(&hashState, session->authHashAlg); |
591 | | |
592 | | // add old digest |
593 | 0 | CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b); |
594 | | |
595 | | // add commandCode |
596 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode); |
597 | | |
598 | | // add cpHashA |
599 | 0 | CryptDigestUpdate2B(&hashState, &in->cpHashA.b); |
600 | | |
601 | | // complete the digest and get the results |
602 | 0 | CryptHashEnd2B(&hashState, &session->u2.policyDigest.b); |
603 | | |
604 | | // update cpHash in session context |
605 | 0 | session->u1.cpHash = in->cpHashA; |
606 | 0 | session->attributes.isCpHashDefined = SET; |
607 | |
|
608 | 0 | return TPM_RC_SUCCESS; |
609 | 0 | } |
610 | | |
611 | | #endif // CC_PolicyCpHash |
612 | | |
613 | | |
614 | | #include "Tpm.h" |
615 | | #include "PolicyNameHash_fp.h" |
616 | | |
617 | | #if CC_PolicyNameHash // Conditional expansion of this file |
618 | | |
619 | | /*(See part 3 specification) |
620 | | // Add a nameHash restriction to the policyDigest |
621 | | */ |
622 | | // Return Type: TPM_RC |
623 | | // TPM_RC_CPHASH 'nameHash' has been previously set to a different value |
624 | | // TPM_RC_SIZE 'nameHash' is not the size of the digest produced by the |
625 | | // hash algorithm associated with 'policySession' |
626 | | TPM_RC |
627 | | TPM2_PolicyNameHash(PolicyNameHash_In* in // IN: input parameter list |
628 | | ) |
629 | 0 | { |
630 | 0 | SESSION* session; |
631 | 0 | TPM_CC commandCode = TPM_CC_PolicyNameHash; |
632 | 0 | HASH_STATE hashState; |
633 | | // Input Validation |
634 | | |
635 | | // Get pointer to the session structure |
636 | 0 | session = SessionGet(in->policySession); |
637 | 0 | pAssert_RC(session); |
638 | | |
639 | | // A valid nameHash must have the same size as session hash digest |
640 | | // Since the authHashAlg for a session cannot be TPM_ALG_NULL, the digest size |
641 | | // is always non-zero. |
642 | 0 | if(in->nameHash.t.size != CryptHashGetDigestSize(session->authHashAlg)) |
643 | 0 | return TPM_RCS_SIZE + RC_PolicyNameHash_nameHash; |
644 | | |
645 | | // error if the nameHash in session context is not empty |
646 | 0 | if(IsCpHashUnionOccupied(session->attributes)) |
647 | 0 | return TPM_RC_CPHASH; |
648 | | |
649 | | // Internal Data Update |
650 | | |
651 | | // Update policy hash |
652 | | // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyNameHash || nameHash) |
653 | | // Start hash |
654 | 0 | CryptHashStart(&hashState, session->authHashAlg); |
655 | | |
656 | | // add old digest |
657 | 0 | CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b); |
658 | | |
659 | | // add commandCode |
660 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode); |
661 | | |
662 | | // add nameHash |
663 | 0 | CryptDigestUpdate2B(&hashState, &in->nameHash.b); |
664 | | |
665 | | // complete the digest |
666 | 0 | CryptHashEnd2B(&hashState, &session->u2.policyDigest.b); |
667 | | |
668 | | // update nameHash in session context |
669 | 0 | session->u1.nameHash = in->nameHash; |
670 | 0 | if (g_RuntimeProfile.stateFormatLevel >= 4) // libtpms added: isNameHashDefined was added |
671 | 0 | session->attributes.isNameHashDefined = SET; |
672 | |
|
673 | 0 | return TPM_RC_SUCCESS; |
674 | 0 | } |
675 | | |
676 | | #endif // CC_PolicyNameHash |
677 | | |
678 | | |
679 | | #include "Tpm.h" |
680 | | #include "PolicyDuplicationSelect_fp.h" |
681 | | |
682 | | #if CC_PolicyDuplicationSelect // Conditional expansion of this file |
683 | | |
684 | | /*(See part 3 specification) |
685 | | // allows qualification of duplication so that it a specific new parent may be |
686 | | // selected or a new parent selected for a specific object. |
687 | | */ |
688 | | // Return Type: TPM_RC |
689 | | // TPM_RC_COMMAND_CODE 'commandCode' of 'policySession' is not empty |
690 | | // TPM_RC_CPHASH 'nameHash' of 'policySession' is not empty |
691 | | TPM_RC |
692 | | TPM2_PolicyDuplicationSelect( |
693 | | PolicyDuplicationSelect_In* in // IN: input parameter list |
694 | | ) |
695 | 0 | { |
696 | 0 | SESSION* session; |
697 | 0 | HASH_STATE hashState; |
698 | 0 | TPM_CC commandCode = TPM_CC_PolicyDuplicationSelect; |
699 | | // Input Validation |
700 | | |
701 | | // Get pointer to the session structure |
702 | 0 | session = SessionGet(in->policySession); |
703 | 0 | pAssert_RC(session); |
704 | | |
705 | | // nameHash in session context must be empty |
706 | 0 | if(session->u1.nameHash.t.size != 0) |
707 | 0 | return TPM_RC_CPHASH; |
708 | | |
709 | | // commandCode in session context must be empty |
710 | 0 | if(session->commandCode != 0) |
711 | 0 | return TPM_RC_COMMAND_CODE; |
712 | | |
713 | | // Internal Data Update |
714 | | |
715 | | // Update name hash |
716 | 0 | session->u1.nameHash.t.size = CryptHashStart(&hashState, session->authHashAlg); |
717 | | |
718 | | // add objectName |
719 | 0 | CryptDigestUpdate2B(&hashState, &in->objectName.b); |
720 | | |
721 | | // add new parent name |
722 | 0 | CryptDigestUpdate2B(&hashState, &in->newParentName.b); |
723 | | |
724 | | // complete hash |
725 | 0 | CryptHashEnd2B(&hashState, &session->u1.nameHash.b); |
726 | 0 | if (g_RuntimeProfile.stateFormatLevel >= 4) // libtpms added: isNameHashDefined was added |
727 | 0 | session->attributes.isNameHashDefined = SET; |
728 | | |
729 | | // update policy hash |
730 | | // Old policyDigest size should be the same as the new policyDigest size since |
731 | | // they are using the same hash algorithm |
732 | 0 | session->u2.policyDigest.t.size = |
733 | 0 | CryptHashStart(&hashState, session->authHashAlg); |
734 | | // add old policy |
735 | 0 | CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b); |
736 | | |
737 | | // add command code |
738 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode); |
739 | | |
740 | | // add objectName |
741 | 0 | if(in->includeObject == YES) |
742 | 0 | CryptDigestUpdate2B(&hashState, &in->objectName.b); |
743 | | |
744 | | // add new parent name |
745 | 0 | CryptDigestUpdate2B(&hashState, &in->newParentName.b); |
746 | | |
747 | | // add includeObject |
748 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPMI_YES_NO), in->includeObject); |
749 | | |
750 | | // complete digest |
751 | 0 | CryptHashEnd2B(&hashState, &session->u2.policyDigest.b); |
752 | | |
753 | | // set commandCode in session context |
754 | 0 | session->commandCode = TPM_CC_Duplicate; |
755 | |
|
756 | 0 | return TPM_RC_SUCCESS; |
757 | 0 | } |
758 | | |
759 | | #endif // CC_PolicyDuplicationSelect |
760 | | |
761 | | |
762 | | #include "Tpm.h" |
763 | | #include "PolicyAuthValue_fp.h" |
764 | | |
765 | | #if CC_PolicyAuthValue // Conditional expansion of this file |
766 | | |
767 | | # include "Policy_spt_fp.h" |
768 | | |
769 | | /*(See part 3 specification) |
770 | | // allows a policy to be bound to the authorization value of the authorized |
771 | | // object |
772 | | */ |
773 | | TPM_RC |
774 | | TPM2_PolicyAuthValue(PolicyAuthValue_In* in // IN: input parameter list |
775 | | ) |
776 | 0 | { |
777 | 0 | SESSION* session; |
778 | 0 | TPM_CC commandCode = TPM_CC_PolicyAuthValue; |
779 | 0 | HASH_STATE hashState; |
780 | | // Internal Data Update |
781 | | |
782 | | // Get pointer to the session structure |
783 | 0 | session = SessionGet(in->policySession); |
784 | 0 | pAssert_RC(session); |
785 | | |
786 | | // Update policy hash |
787 | | // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyAuthValue) |
788 | | // Start hash |
789 | 0 | CryptHashStart(&hashState, session->authHashAlg); |
790 | | |
791 | | // add old digest |
792 | 0 | CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b); |
793 | | |
794 | | // add commandCode |
795 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode); |
796 | | |
797 | | // complete the hash and get the results |
798 | 0 | CryptHashEnd2B(&hashState, &session->u2.policyDigest.b); |
799 | | |
800 | | // update isAuthValueNeeded bit in the session context |
801 | 0 | session->attributes.isAuthValueNeeded = SET; |
802 | 0 | session->attributes.isPasswordNeeded = CLEAR; |
803 | |
|
804 | 0 | return TPM_RC_SUCCESS; |
805 | 0 | } |
806 | | |
807 | | #endif // CC_PolicyAuthValue |
808 | | |
809 | | |
810 | | #include "Tpm.h" |
811 | | #include "PolicyPassword_fp.h" |
812 | | |
813 | | #if CC_PolicyPassword // Conditional expansion of this file |
814 | | |
815 | | # include "Policy_spt_fp.h" |
816 | | |
817 | | /*(See part 3 specification) |
818 | | // allows a policy to be bound to the authorization value of the authorized |
819 | | // object |
820 | | */ |
821 | | TPM_RC |
822 | | TPM2_PolicyPassword(PolicyPassword_In* in // IN: input parameter list |
823 | | ) |
824 | 0 | { |
825 | 0 | SESSION* session; |
826 | 0 | TPM_CC commandCode = TPM_CC_PolicyAuthValue; |
827 | 0 | HASH_STATE hashState; |
828 | | // Internal Data Update |
829 | | |
830 | | // Get pointer to the session structure |
831 | 0 | session = SessionGet(in->policySession); |
832 | 0 | pAssert_RC(session); |
833 | | |
834 | | // Update policy hash |
835 | | // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyAuthValue) |
836 | | // Start hash |
837 | 0 | CryptHashStart(&hashState, session->authHashAlg); |
838 | | |
839 | | // add old digest |
840 | 0 | CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b); |
841 | | |
842 | | // add commandCode |
843 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode); |
844 | | |
845 | | // complete the digest |
846 | 0 | CryptHashEnd2B(&hashState, &session->u2.policyDigest.b); |
847 | | |
848 | | // Update isPasswordNeeded bit |
849 | 0 | session->attributes.isPasswordNeeded = SET; |
850 | 0 | session->attributes.isAuthValueNeeded = CLEAR; |
851 | |
|
852 | 0 | return TPM_RC_SUCCESS; |
853 | 0 | } |
854 | | |
855 | | #endif // CC_PolicyPassword |
856 | | |
857 | | |
858 | | #include "Tpm.h" |
859 | | #include "PolicyGetDigest_fp.h" |
860 | | #if CC_PolicyGetDigest // Conditional expansion of this file |
861 | | TPM_RC |
862 | | TPM2_PolicyGetDigest( |
863 | | PolicyGetDigest_In *in, // IN: input parameter list |
864 | | PolicyGetDigest_Out *out // OUT: output parameter list |
865 | | ) |
866 | 0 | { |
867 | 0 | SESSION *session; |
868 | | // Command Output |
869 | | // Get pointer to the session structure |
870 | 0 | session = SessionGet(in->policySession); |
871 | 0 | pAssert_RC(session); |
872 | |
|
873 | 0 | out->policyDigest = session->u2.policyDigest; |
874 | 0 | return TPM_RC_SUCCESS; |
875 | 0 | } |
876 | | #endif // CC_PolicyGetDigest |
877 | | |
878 | | #include "Tpm.h" |
879 | | #include "PolicyNvWritten_fp.h" |
880 | | |
881 | | #if CC_PolicyNvWritten // Conditional expansion of this file |
882 | | |
883 | | // Make an NV Index policy dependent on the state of the TPMA_NV_WRITTEN |
884 | | // attribute of the index. |
885 | | // Return Type: TPM_RC |
886 | | // TPM_RC_VALUE a conflicting request for the attribute has |
887 | | // already been processed |
888 | | TPM_RC |
889 | | TPM2_PolicyNvWritten(PolicyNvWritten_In* in // IN: input parameter list |
890 | | ) |
891 | 0 | { |
892 | 0 | SESSION* session; |
893 | 0 | TPM_CC commandCode = TPM_CC_PolicyNvWritten; |
894 | 0 | HASH_STATE hashState; |
895 | | // Input Validation |
896 | | |
897 | | // Get pointer to the session structure |
898 | 0 | session = SessionGet(in->policySession); |
899 | 0 | pAssert_RC(session); |
900 | | |
901 | | // If already set is this a duplicate (the same setting)? If it |
902 | | // is a conflicting setting, it is an error |
903 | 0 | if(session->attributes.checkNvWritten == SET) |
904 | 0 | { |
905 | 0 | if(((session->attributes.nvWrittenState == SET) != (in->writtenSet == YES))) |
906 | 0 | return TPM_RCS_VALUE + RC_PolicyNvWritten_writtenSet; |
907 | 0 | } |
908 | | |
909 | | // Internal Data Update |
910 | | |
911 | | // Set session attributes so that the NV Index needs to be checked |
912 | 0 | session->attributes.checkNvWritten = SET; |
913 | 0 | session->attributes.nvWrittenState = (in->writtenSet == YES); |
914 | | |
915 | | // Update policy hash |
916 | | // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyNvWritten |
917 | | // || writtenSet) |
918 | | // Start hash |
919 | 0 | CryptHashStart(&hashState, session->authHashAlg); |
920 | | |
921 | | // add old digest |
922 | 0 | CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b); |
923 | | |
924 | | // add commandCode |
925 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode); |
926 | | |
927 | | // add the byte of writtenState |
928 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPMI_YES_NO), in->writtenSet); |
929 | | |
930 | | // complete the digest |
931 | 0 | CryptHashEnd2B(&hashState, &session->u2.policyDigest.b); |
932 | |
|
933 | 0 | return TPM_RC_SUCCESS; |
934 | 0 | } |
935 | | |
936 | | #endif // CC_PolicyNvWritten |
937 | | |
938 | | #include "Tpm.h" |
939 | | #include "PolicyTemplate_fp.h" |
940 | | |
941 | | #if CC_PolicyTemplate // Conditional expansion of this file |
942 | | |
943 | | /*(See part 3 specification) |
944 | | // Add a cpHash restriction to the policyDigest |
945 | | */ |
946 | | // Return Type: TPM_RC |
947 | | // TPM_RC_CPHASH cpHash of 'policySession' has previously been set |
948 | | // to a different value |
949 | | // TPM_RC_SIZE 'templateHash' is not the size of a digest produced |
950 | | // by the hash algorithm associated with |
951 | | // 'policySession' |
952 | | TPM_RC |
953 | | TPM2_PolicyTemplate(PolicyTemplate_In* in // IN: input parameter list |
954 | | ) |
955 | 0 | { |
956 | 0 | SESSION* session; |
957 | 0 | TPM_CC commandCode = TPM_CC_PolicyTemplate; |
958 | 0 | HASH_STATE hashState; |
959 | | // Input Validation |
960 | | |
961 | | // Get pointer to the session structure |
962 | 0 | session = SessionGet(in->policySession); |
963 | 0 | pAssert_RC(session); |
964 | | |
965 | | // error if the templateHash in session context is not empty and is not the |
966 | | // same as the input or is not a template |
967 | 0 | if((IsCpHashUnionOccupied(session->attributes)) |
968 | 0 | && (!session->attributes.isTemplateHashDefined |
969 | 0 | || !MemoryEqual2B(&in->templateHash.b, &session->u1.templateHash.b))) |
970 | 0 | return TPM_RC_CPHASH; |
971 | | |
972 | | // A valid templateHash must have the same size as session hash digest |
973 | 0 | if(in->templateHash.t.size != CryptHashGetDigestSize(session->authHashAlg)) |
974 | 0 | return TPM_RCS_SIZE + RC_PolicyTemplate_templateHash; |
975 | | |
976 | | // Internal Data Update |
977 | | // Update policy hash |
978 | | // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyCpHash |
979 | | // || cpHashA.buffer) |
980 | | // Start hash |
981 | 0 | CryptHashStart(&hashState, session->authHashAlg); |
982 | | |
983 | | // add old digest |
984 | 0 | CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b); |
985 | | |
986 | | // add commandCode |
987 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode); |
988 | | |
989 | | // add cpHashA |
990 | 0 | CryptDigestUpdate2B(&hashState, &in->templateHash.b); |
991 | | |
992 | | // complete the digest and get the results |
993 | 0 | CryptHashEnd2B(&hashState, &session->u2.policyDigest.b); |
994 | | |
995 | | // update templateHash in session context |
996 | 0 | session->u1.templateHash = in->templateHash; |
997 | 0 | session->attributes.isTemplateHashDefined = SET; |
998 | |
|
999 | 0 | return TPM_RC_SUCCESS; |
1000 | 0 | } |
1001 | | |
1002 | | #endif // CC_PolicyTemplate |
1003 | | |
1004 | | |
1005 | | #include "Tpm.h" |
1006 | | #include "PolicyCapability_fp.h" |
1007 | | #include "Policy_spt_fp.h" |
1008 | | #include "ACT_spt_fp.h" |
1009 | | #include "AlgorithmCap_fp.h" |
1010 | | #include "CommandAudit_fp.h" |
1011 | | #include "CommandCodeAttributes_fp.h" |
1012 | | #include "CryptEccMain_fp.h" |
1013 | | #include "Handle_fp.h" |
1014 | | #include "NvDynamic_fp.h" |
1015 | | #include "Object_fp.h" |
1016 | | #include "PCR_fp.h" |
1017 | | #include "PP_fp.h" |
1018 | | #include "PropertyCap_fp.h" |
1019 | | #include "Session_fp.h" |
1020 | | |
1021 | | #if CC_PolicyCapability // Conditional expansion of this file |
1022 | | |
1023 | | /*(See part 3 specification) |
1024 | | // This command performs an immediate policy assertion against the current |
1025 | | // value of a TPM Capability. |
1026 | | */ |
1027 | | // Return Type: TPM_RC |
1028 | | // TPM_RC_HANDLE value of 'property' is in an unsupported handle range |
1029 | | // for the TPM_CAP_HANDLES 'capability' value |
1030 | | // TPM_RC_VALUE invalid 'capability'; or 'property' is not 0 for the |
1031 | | // TPM_CAP_PCRS 'capability' value |
1032 | | // TPM_RC_SIZE 'operandB' is larger than the size of the capability |
1033 | | // data minus 'offset'. |
1034 | | TPM_RC |
1035 | | TPM2_PolicyCapability(PolicyCapability_In* in // IN: input parameter list |
1036 | | ) |
1037 | 0 | { |
1038 | 0 | union |
1039 | 0 | { |
1040 | 0 | TPMS_ALG_PROPERTY alg; |
1041 | 0 | TPM_HANDLE handle; |
1042 | 0 | TPMA_CC commandAttributes; |
1043 | 0 | TPM_CC command; |
1044 | 0 | TPMS_TAGGED_PCR_SELECT pcrSelect; |
1045 | 0 | TPMS_TAGGED_PROPERTY tpmProperty; |
1046 | 0 | # if ALG_ECC |
1047 | 0 | TPM_ECC_CURVE curve; |
1048 | 0 | # endif // ALG_ECC |
1049 | 0 | TPMS_TAGGED_POLICY policy; |
1050 | 0 | # if ACT_SUPPORT |
1051 | 0 | TPMS_ACT_DATA act; |
1052 | 0 | # endif // ACT_SUPPORT |
1053 | 0 | } propertyUnion; |
1054 | |
|
1055 | 0 | SESSION* session; |
1056 | 0 | BYTE propertyData[sizeof(propertyUnion)]; |
1057 | 0 | UINT16 propertySize = 0; |
1058 | 0 | BYTE* buffer = propertyData; |
1059 | 0 | INT32 bufferSize = sizeof(propertyData); |
1060 | 0 | TPM_CC commandCode = TPM_CC_PolicyCapability; |
1061 | 0 | HASH_STATE hashState; |
1062 | 0 | TPM2B_DIGEST argHash; |
1063 | | |
1064 | | // Get pointer to the session structure |
1065 | 0 | session = SessionGet(in->policySession); |
1066 | 0 | pAssert_RC(session); |
1067 | |
|
1068 | 0 | if(session->attributes.isTrialPolicy == CLEAR) |
1069 | 0 | { |
1070 | 0 | switch(in->capability) |
1071 | 0 | { |
1072 | 0 | case TPM_CAP_ALGS: |
1073 | 0 | if(AlgorithmCapGetOneImplemented((TPM_ALG_ID)in->property, |
1074 | 0 | &propertyUnion.alg)) |
1075 | 0 | { |
1076 | 0 | propertySize = TPMS_ALG_PROPERTY_Marshal |
1077 | 0 | (&propertyUnion.alg, &buffer, &bufferSize); |
1078 | 0 | } |
1079 | 0 | break; |
1080 | 0 | case TPM_CAP_HANDLES: { // libtpms changed: older gcc |
1081 | 0 | BOOL foundHandle = FALSE; |
1082 | 0 | switch(HandleGetType((TPM_HANDLE)in->property)) |
1083 | 0 | { |
1084 | 0 | case TPM_HT_TRANSIENT: |
1085 | 0 | foundHandle = ObjectCapGetOneLoaded((TPM_HANDLE)in->property); |
1086 | 0 | break; |
1087 | 0 | case TPM_HT_PERSISTENT: |
1088 | 0 | foundHandle = NvCapGetOnePersistent((TPM_HANDLE)in->property); |
1089 | 0 | break; |
1090 | 0 | case TPM_HT_NV_INDEX: |
1091 | 0 | foundHandle = NvCapGetOneIndex((TPM_HANDLE)in->property); |
1092 | 0 | break; |
1093 | 0 | case TPM_HT_LOADED_SESSION: |
1094 | 0 | foundHandle = |
1095 | 0 | SessionCapGetOneLoaded((TPM_HANDLE)in->property); |
1096 | 0 | break; |
1097 | 0 | case TPM_HT_SAVED_SESSION: |
1098 | 0 | foundHandle = SessionCapGetOneSaved((TPM_HANDLE)in->property); |
1099 | 0 | break; |
1100 | 0 | case TPM_HT_PCR: |
1101 | 0 | foundHandle = PCRCapGetOneHandle((TPM_HANDLE)in->property); |
1102 | 0 | break; |
1103 | 0 | case TPM_HT_PERMANENT: |
1104 | 0 | foundHandle = |
1105 | 0 | PermanentCapGetOneHandle((TPM_HANDLE)in->property); |
1106 | 0 | break; |
1107 | 0 | default: |
1108 | | // Unsupported input handle type |
1109 | 0 | return TPM_RCS_HANDLE + RC_PolicyCapability_property; |
1110 | 0 | break; |
1111 | 0 | } // libtpms added |
1112 | 0 | if(foundHandle) |
1113 | 0 | { |
1114 | 0 | TPM_HANDLE handle = (TPM_HANDLE)in->property; |
1115 | 0 | propertySize = TPM_HANDLE_Marshal(&handle, &buffer, &bufferSize); |
1116 | 0 | } |
1117 | 0 | break; |
1118 | 0 | } |
1119 | 0 | case TPM_CAP_COMMANDS: |
1120 | 0 | if(CommandCapGetOneCC((TPM_CC)in->property, |
1121 | 0 | &propertyUnion.commandAttributes)) |
1122 | 0 | { |
1123 | 0 | propertySize = TPMA_CC_Marshal |
1124 | 0 | (&propertyUnion.commandAttributes, &buffer, &bufferSize); |
1125 | 0 | } |
1126 | 0 | break; |
1127 | 0 | case TPM_CAP_PP_COMMANDS: |
1128 | 0 | if(PhysicalPresenceCapGetOneCC((TPM_CC)in->property)) |
1129 | 0 | { |
1130 | 0 | TPM_CC cc = (TPM_CC)in->property; |
1131 | 0 | propertySize = TPM_CC_Marshal(&cc, &buffer, &bufferSize); |
1132 | 0 | } |
1133 | 0 | break; |
1134 | 0 | case TPM_CAP_AUDIT_COMMANDS: |
1135 | 0 | if(CommandAuditCapGetOneCC((TPM_CC)in->property)) |
1136 | 0 | { |
1137 | 0 | TPM_CC cc = (TPM_CC)in->property; |
1138 | 0 | propertySize = TPM_CC_Marshal(&cc, &buffer, &bufferSize); |
1139 | 0 | } |
1140 | 0 | break; |
1141 | | // NOTE: TPM_CAP_PCRS can't work for PolicyCapability since CAP_PCRS |
1142 | | // requires property to be 0 and always returns all the PCR banks. |
1143 | 0 | case TPM_CAP_PCR_PROPERTIES: |
1144 | 0 | if(PCRGetProperty((TPM_PT_PCR)in->property, &propertyUnion.pcrSelect)) |
1145 | 0 | { |
1146 | 0 | propertySize = TPMS_TAGGED_PCR_SELECT_Marshal |
1147 | 0 | (&propertyUnion.pcrSelect, &buffer, &bufferSize); |
1148 | 0 | } |
1149 | 0 | break; |
1150 | 0 | case TPM_CAP_TPM_PROPERTIES: |
1151 | 0 | if(TPMCapGetOneProperty((TPM_PT)in->property, |
1152 | 0 | &propertyUnion.tpmProperty)) |
1153 | 0 | { |
1154 | 0 | propertySize = TPMS_TAGGED_PROPERTY_Marshal |
1155 | 0 | (&propertyUnion.tpmProperty, &buffer, &bufferSize); |
1156 | 0 | } |
1157 | 0 | break; |
1158 | 0 | # if ALG_ECC |
1159 | 0 | case TPM_CAP_ECC_CURVES: { // libtpms changed: older gcc |
1160 | 0 | TPM_ECC_CURVE curve = (TPM_ECC_CURVE)in->property; |
1161 | 0 | if(CryptCapGetOneECCCurve(curve)) |
1162 | 0 | { |
1163 | 0 | propertySize = |
1164 | 0 | TPM_ECC_CURVE_Marshal(&curve, &buffer, &bufferSize); |
1165 | 0 | } |
1166 | 0 | break; |
1167 | 0 | } // libtpms added: older gcc |
1168 | 0 | # endif // ALG_ECC |
1169 | 0 | case TPM_CAP_AUTH_POLICIES: |
1170 | 0 | if(HandleGetType((TPM_HANDLE)in->property) != TPM_HT_PERMANENT) |
1171 | 0 | return TPM_RCS_VALUE + RC_PolicyCapability_property; |
1172 | 0 | if(PermanentHandleGetOnePolicy((TPM_HANDLE)in->property, |
1173 | 0 | &propertyUnion.policy)) |
1174 | 0 | { |
1175 | 0 | propertySize = TPMS_TAGGED_POLICY_Marshal |
1176 | 0 | (&propertyUnion.policy, &buffer, &bufferSize); |
1177 | 0 | } |
1178 | 0 | break; |
1179 | | # ifndef __ACT_DISABLED // libtpms: added |
1180 | | # if ACT_SUPPORT |
1181 | | case TPM_CAP_ACT: |
1182 | | if(((TPM_RH)in->property < TPM_RH_ACT_0) |
1183 | | || ((TPM_RH)in->property > TPM_RH_ACT_F)) |
1184 | | return TPM_RCS_VALUE + RC_PolicyCapability_property; |
1185 | | if(ActGetOneCapability((TPM_HANDLE)in->property, &propertyUnion.act)) |
1186 | | { |
1187 | | propertySize = TPMS_ACT_DATA_Marshal |
1188 | | (&propertyUnion.act, &buffer, &bufferSize); |
1189 | | } |
1190 | | break; |
1191 | | # endif // ACT_SUPPORT |
1192 | | # endif // __ACT_DISABLED // libtpms: added |
1193 | 0 | case TPM_CAP_VENDOR_PROPERTY: |
1194 | | // vendor property is not implemented |
1195 | 0 | default: |
1196 | | // Unsupported TPM_CAP value |
1197 | 0 | return TPM_RCS_VALUE + RC_PolicyCapability_capability; |
1198 | 0 | break; |
1199 | 0 | } |
1200 | | |
1201 | 0 | if(propertySize == 0) |
1202 | 0 | { |
1203 | | // A property that doesn't exist trivially satisfies NEQ, and |
1204 | | // trivially can't satisfy any other operation. |
1205 | 0 | if(in->operation != TPM_EO_NEQ) |
1206 | 0 | { |
1207 | 0 | return TPM_RC_POLICY; |
1208 | 0 | } |
1209 | 0 | } |
1210 | 0 | else |
1211 | 0 | { |
1212 | | // The property was found, so we need to perform the comparison. |
1213 | | |
1214 | | // Make sure that offset is within range |
1215 | 0 | if(in->offset > propertySize) |
1216 | 0 | { |
1217 | 0 | return TPM_RCS_VALUE + RC_PolicyCapability_offset; |
1218 | 0 | } |
1219 | | |
1220 | | // Property data size should not be smaller than input operandB size |
1221 | 0 | if((propertySize - in->offset) < in->operandB.t.size) |
1222 | 0 | { |
1223 | 0 | return TPM_RCS_SIZE + RC_PolicyCapability_operandB; |
1224 | 0 | } |
1225 | | |
1226 | 0 | if(!PolicySptCheckCondition(in->operation, |
1227 | 0 | propertyData + in->offset, |
1228 | 0 | in->operandB.t.buffer, |
1229 | 0 | in->operandB.t.size)) |
1230 | 0 | { |
1231 | 0 | return TPM_RC_POLICY; |
1232 | 0 | } |
1233 | 0 | } |
1234 | 0 | } |
1235 | | // Internal Data Update |
1236 | | |
1237 | | // Start argument hash |
1238 | 0 | argHash.t.size = CryptHashStart(&hashState, session->authHashAlg); |
1239 | | |
1240 | | // add operandB |
1241 | 0 | CryptDigestUpdate2B(&hashState, &in->operandB.b); |
1242 | | |
1243 | | // add offset |
1244 | 0 | CryptDigestUpdateInt(&hashState, sizeof(UINT16), in->offset); |
1245 | | |
1246 | | // add operation |
1247 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_EO), in->operation); |
1248 | | |
1249 | | // add capability |
1250 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_CAP), in->capability); |
1251 | | |
1252 | | // add property |
1253 | 0 | CryptDigestUpdateInt(&hashState, sizeof(UINT32), in->property); |
1254 | | |
1255 | | // complete argument digest |
1256 | 0 | CryptHashEnd2B(&hashState, &argHash.b); |
1257 | | |
1258 | | // Update policyDigest |
1259 | | // Start digest |
1260 | 0 | CryptHashStart(&hashState, session->authHashAlg); |
1261 | | |
1262 | | // add old digest |
1263 | 0 | CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b); |
1264 | | |
1265 | | // add commandCode |
1266 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode); |
1267 | | |
1268 | | // add argument digest |
1269 | 0 | CryptDigestUpdate2B(&hashState, &argHash.b); |
1270 | | |
1271 | | // complete the digest |
1272 | 0 | CryptHashEnd2B(&hashState, &session->u2.policyDigest.b); |
1273 | |
|
1274 | 0 | return TPM_RC_SUCCESS; |
1275 | 0 | } |
1276 | | |
1277 | | #endif // CC_PolicyCapability |
1278 | | |
1279 | | #include "Tpm.h" |
1280 | | #include "PolicyParameters_fp.h" |
1281 | | |
1282 | | #if CC_PolicyParameters // Conditional expansion of this file |
1283 | | |
1284 | | /*(See part 3 specification) |
1285 | | // Add a parameters restriction to the policyDigest |
1286 | | */ |
1287 | | // Return Type: TPM_RC |
1288 | | // TPM_RC_CPHASH cpHash of 'policySession' has previously been set |
1289 | | // to a different value |
1290 | | // TPM_RC_SIZE 'pHash' is not the size of the digest produced by the |
1291 | | // hash algorithm associated with 'policySession' |
1292 | | TPM_RC |
1293 | | TPM2_PolicyParameters(PolicyParameters_In* in // IN: input parameter list |
1294 | | ) |
1295 | 0 | { |
1296 | 0 | SESSION* session; |
1297 | 0 | TPM_CC commandCode = TPM_CC_PolicyParameters; |
1298 | 0 | HASH_STATE hashState; |
1299 | | |
1300 | | // Input Validation |
1301 | | |
1302 | | // Get pointer to the session structure |
1303 | 0 | session = SessionGet(in->policySession); |
1304 | 0 | pAssert_RC(session); |
1305 | | |
1306 | | // A valid pHash must have the same size as session hash digest |
1307 | | // Since the authHashAlg for a session cannot be TPM_ALG_NULL, the digest size |
1308 | | // is always non-zero. |
1309 | 0 | if(in->pHash.t.size != CryptHashGetDigestSize(session->authHashAlg)) |
1310 | 0 | return TPM_RCS_SIZE + RC_PolicyParameters_pHash; |
1311 | | |
1312 | | // error if the pHash in session context is not empty |
1313 | 0 | if(IsCpHashUnionOccupied(session->attributes)) |
1314 | 0 | return TPM_RC_CPHASH; |
1315 | | |
1316 | | // Internal Data Update |
1317 | | |
1318 | | // Update policy hash |
1319 | | // policyDigestnew = hash(policyDigestold || TPM_CC_PolicyParameters || pHash) |
1320 | | // Start hash |
1321 | 0 | CryptHashStart(&hashState, session->authHashAlg); |
1322 | | |
1323 | | // add old digest |
1324 | 0 | CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b); |
1325 | | |
1326 | | // add commandCode |
1327 | 0 | CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), commandCode); |
1328 | | |
1329 | | // add pHash |
1330 | 0 | CryptDigestUpdate2B(&hashState, &in->pHash.b); |
1331 | | |
1332 | | // complete the digest |
1333 | 0 | CryptHashEnd2B(&hashState, &session->u2.policyDigest.b); |
1334 | | |
1335 | | // update pHash in session context |
1336 | 0 | session->u1.pHash = in->pHash; |
1337 | 0 | session->attributes.isParametersHashDefined = SET; |
1338 | |
|
1339 | 0 | return TPM_RC_SUCCESS; |
1340 | 0 | } |
1341 | | |
1342 | | #endif // CC_PolicyParameters |