Coverage Report

Created: 2026-03-31 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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