Coverage Report

Created: 2025-07-09 06:07

/src/tpm2/PropertyCap.c
Line
Count
Source (jump to first uncovered line)
1
// This file was extracted from the TCG Published
2
// Trusted Platform Module Library
3
// Part 4: Supporting Routines
4
// Family "2.0"
5
// Level 00 Revision 01.16
6
// October 30, 2014
7
8
#include "InternalRoutines.h"
9
//
10
//
11
//          Functions
12
//
13
//         PCRGetProperty()
14
//
15
//     This function accepts a property selection and, if so, sets value to the value of the property.
16
//     All the fixed values are vendor dependent or determined by a platform-specific specification. The values
17
//     in the table below are examples and should be changed by the vendor.
18
//
19
//     Return Value                      Meaning
20
//
21
//     TRUE                              referenced property exists and value set
22
//     FALSE                             referenced property does not exist
23
//
24
static BOOL
25
TPMPropertyIsDefined(
26
    TPM_PT               property,           // IN: property
27
    UINT32              *value               // OUT: property value
28
    )
29
0
{
30
0
   switch(property)
31
0
   {
32
0
       case TPM_PT_FAMILY_INDICATOR:
33
           // from the title page of the specification
34
           // For this specification, the value is "2.0".
35
0
           *value = TPM_SPEC_FAMILY;
36
0
           break;
37
0
       case TPM_PT_LEVEL:
38
           // from the title page of the specification
39
0
           *value = TPM_SPEC_LEVEL;
40
0
           break;
41
0
       case TPM_PT_REVISION:
42
           // from the title page of the specification
43
0
           *value = TPM_SPEC_VERSION;
44
0
           break;
45
0
       case TPM_PT_DAY_OF_YEAR:
46
           // computed from the date value on the title page of the specification
47
0
           *value = TPM_SPEC_DAY_OF_YEAR;
48
0
           break;
49
0
       case TPM_PT_YEAR:
50
           // from the title page of the specification
51
0
           *value = TPM_SPEC_YEAR;
52
0
           break;
53
0
       case TPM_PT_MANUFACTURER:
54
           // vendor ID unique to each TPM manufacturer
55
0
           *value = BYTE_ARRAY_TO_UINT32(MANUFACTURER);
56
0
           break;
57
0
       case TPM_PT_VENDOR_STRING_1:
58
           // first four characters of the vendor ID string
59
0
           *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_1);
60
0
           break;
61
0
       case TPM_PT_VENDOR_STRING_2:
62
           // second four characters of the vendor ID string
63
0
#ifdef VENDOR_STRING_2
64
0
           *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_2);
65
#else
66
           *value = 0;
67
#endif
68
0
           break;
69
0
       case TPM_PT_VENDOR_STRING_3:
70
           // third four characters of the vendor ID string
71
#ifdef VENDOR_STRING_3
72
           *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_3);
73
#else
74
0
           *value = 0;
75
0
#endif
76
0
           break;
77
0
       case TPM_PT_VENDOR_STRING_4:
78
           // fourth four characters of the vendor ID string
79
#ifdef VENDOR_STRING_4
80
           *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_4);
81
#else
82
0
           *value = 0;
83
0
#endif
84
0
           break;
85
0
       case TPM_PT_VENDOR_TPM_TYPE:
86
           // vendor-defined value indicating the TPM model
87
0
           *value = 1;
88
0
           break;
89
0
       case TPM_PT_FIRMWARE_VERSION_1:
90
           // more significant 32-bits of a vendor-specific value
91
0
           *value = gp.firmwareV1;
92
0
           break;
93
0
       case TPM_PT_FIRMWARE_VERSION_2:
94
           // less significant 32-bits of a vendor-specific value
95
0
           *value = gp.firmwareV2;
96
0
           break;
97
0
       case TPM_PT_INPUT_BUFFER:
98
           // maximum size of TPM2B_MAX_BUFFER
99
0
           *value = MAX_DIGEST_BUFFER;
100
0
           break;
101
0
       case TPM_PT_HR_TRANSIENT_MIN:
102
           // minimum number of transient objects that can be held in TPM
103
           // RAM
104
0
           *value = MAX_LOADED_OBJECTS;
105
0
           break;
106
0
       case TPM_PT_HR_PERSISTENT_MIN:
107
           // minimum number of persistent objects that can be held in
108
           // TPM NV memory
109
           // In this implementation, there is no minimum number of
110
           // persistent objects.
111
0
           *value = MIN_EVICT_OBJECTS;
112
0
           break;
113
0
       case TPM_PT_HR_LOADED_MIN:
114
           // minimum number of authorization sessions that can be held in
115
           // TPM RAM
116
0
           *value = MAX_LOADED_SESSIONS;
117
0
           break;
118
0
       case TPM_PT_ACTIVE_SESSIONS_MAX:
119
           // number of authorization sessions that may be active at a time
120
0
           *value = MAX_ACTIVE_SESSIONS;
121
0
           break;
122
0
       case TPM_PT_PCR_COUNT:
123
           // number of PCR implemented
124
0
           *value = IMPLEMENTATION_PCR;
125
0
           break;
126
0
       case TPM_PT_PCR_SELECT_MIN:
127
           // minimum number of bytes in a TPMS_PCR_SELECT.sizeOfSelect
128
0
           *value = PCR_SELECT_MIN;
129
0
           break;
130
0
       case TPM_PT_CONTEXT_GAP_MAX:
131
           // maximum allowed difference (unsigned) between the contextID
132
           // values of two saved session contexts
133
0
           *value = (1 << (sizeof(CONTEXT_SLOT) * 8)) - 1;
134
0
            break;
135
0
        case TPM_PT_NV_COUNTERS_MAX:
136
            // maximum number of NV indexes that are allowed to have the
137
            // TPMA_NV_COUNTER attribute SET
138
            // In this implementation, there is no limitation on the number
139
            // of counters, except for the size of the NV Index memory.
140
0
            *value = 0;
141
0
            break;
142
0
        case TPM_PT_NV_INDEX_MAX:
143
            // maximum size of an NV index data area
144
0
            *value = MAX_NV_INDEX_SIZE;
145
0
            break;
146
0
        case TPM_PT_MEMORY:
147
            // a TPMA_MEMORY indicating the memory management method for the TPM
148
0
        {
149
0
            TPMA_MEMORY         attributes = {0};
150
0
            attributes.sharedNV = SET;
151
0
            attributes.objectCopiedToRam = SET;
152
             // Note: Different compilers may require a different method to cast
153
             // a bit field structure to a UINT32.
154
0
             memcpy(value, &attributes, sizeof(UINT32));
155
0
             break;
156
0
        }
157
0
        case TPM_PT_CLOCK_UPDATE:
158
            // interval, in seconds, between updates to the copy of
159
            // TPMS_TIME_INFO .clock in NV
160
0
            *value = (1 << NV_CLOCK_UPDATE_INTERVAL);
161
0
            break;
162
0
        case TPM_PT_CONTEXT_HASH:
163
            // algorithm used for the integrity hash on saved contexts and
164
            // for digesting the fuData of TPM2_FirmwareRead()
165
0
            *value = CONTEXT_INTEGRITY_HASH_ALG;
166
0
            break;
167
0
        case TPM_PT_CONTEXT_SYM:
168
            // algorithm used for encryption of saved contexts
169
0
            *value = CONTEXT_ENCRYPT_ALG;
170
0
            break;
171
0
        case TPM_PT_CONTEXT_SYM_SIZE:
172
            // size of the key used for encryption of saved contexts
173
0
            *value = CONTEXT_ENCRYPT_KEY_BITS;
174
0
            break;
175
0
        case TPM_PT_ORDERLY_COUNT:
176
            // maximum difference between the volatile and non-volatile
177
            // versions of TPMA_NV_COUNTER that have TPMA_NV_ORDERLY SET
178
0
            *value = MAX_ORDERLY_COUNT;
179
0
            break;
180
0
        case TPM_PT_MAX_COMMAND_SIZE:
181
            // maximum value for 'commandSize'
182
0
            *value = MAX_COMMAND_SIZE;
183
0
            break;
184
0
        case TPM_PT_MAX_RESPONSE_SIZE:
185
            // maximum value for 'responseSize'
186
0
            *value = MAX_RESPONSE_SIZE;
187
0
            break;
188
0
        case TPM_PT_MAX_DIGEST:
189
            // maximum size of a digest that can be produced by the TPM
190
0
            *value = sizeof(TPMU_HA);
191
0
            break;
192
0
        case TPM_PT_MAX_OBJECT_CONTEXT:
193
            // maximum size of a TPMS_CONTEXT that will be returned by
194
            // TPM2_ContextSave for object context
195
0
            *value = 0;
196
             // adding sequence, saved handle and hierarchy
197
0
             *value += sizeof(UINT64) + sizeof(TPMI_DH_CONTEXT) +
198
0
                        sizeof(TPMI_RH_HIERARCHY);
199
              // add size field in TPM2B_CONTEXT
200
0
              *value += sizeof(UINT16);
201
              // add integrity hash size
202
0
              *value += sizeof(UINT16) +
203
0
                        CryptGetHashDigestSize(CONTEXT_INTEGRITY_HASH_ALG);
204
              // Add fingerprint size, which is the same as sequence size
205
0
              *value += sizeof(UINT64);
206
            // Add OBJECT structure size
207
0
            *value += sizeof(OBJECT);
208
0
            break;
209
0
        case TPM_PT_MAX_SESSION_CONTEXT:
210
            // the maximum size of a TPMS_CONTEXT that will be returned by
211
            // TPM2_ContextSave for object context
212
0
            *value = 0;
213
              // adding sequence, saved handle and hierarchy
214
0
              *value += sizeof(UINT64) + sizeof(TPMI_DH_CONTEXT) +
215
0
                        sizeof(TPMI_RH_HIERARCHY);
216
              // Add size field in TPM2B_CONTEXT
217
0
              *value += sizeof(UINT16);
218
              // Add integrity hash size
219
0
              *value += sizeof(UINT16) +
220
0
                        CryptGetHashDigestSize(CONTEXT_INTEGRITY_HASH_ALG);
221
              // Add fingerprint size, which is the same as sequence size
222
0
              *value += sizeof(UINT64);
223
           // Add SESSION structure size
224
0
           *value += sizeof(SESSION);
225
0
           break;
226
0
       case TPM_PT_PS_FAMILY_INDICATOR:
227
           // platform specific values for the TPM_PT_PS parameters from
228
           // the relevant platform-specific specification
229
           // In this reference implementation, all of these values are 0.
230
0
           *value = 0;
231
0
           break;
232
0
       case TPM_PT_PS_LEVEL:
233
           // level of the platform-specific specification
234
0
           *value = 0;
235
0
           break;
236
0
       case TPM_PT_PS_REVISION:
237
           // specification Revision times 100 for the platform-specific
238
           // specification
239
0
           *value = 0;
240
0
           break;
241
0
       case TPM_PT_PS_DAY_OF_YEAR:
242
           // platform-specific specification day of year using TCG calendar
243
0
           *value = 0;
244
0
           break;
245
0
       case TPM_PT_PS_YEAR:
246
           // platform-specific specification year using the CE
247
0
           *value = 0;
248
0
           break;
249
0
       case TPM_PT_SPLIT_MAX:
250
           // number of split signing operations supported by the TPM
251
0
           *value = 0;
252
0
   #ifdef TPM_ALG_ECC
253
0
           *value = sizeof(gr.commitArray) * 8;
254
0
   #endif
255
0
           break;
256
0
       case TPM_PT_TOTAL_COMMANDS:
257
           // total number of commands implemented in the TPM
258
0
        {
259
0
             UINT32 i;
260
0
             *value = 0;
261
             // calculate implemented command numbers
262
0
             for(i = TPM_CC_FIRST; i <= TPM_CC_LAST; i++)
263
0
             {
264
0
                 if(CommandIsImplemented(i)) (*value)++;
265
0
             }
266
0
             for(i = TPM_CCE_FIRST; i <= TPM_CCE_LAST; i++)
267
0
             {
268
0
                 if(CommandIsImplemented(i)) (*value)++;
269
0
             }
270
0
             break;
271
0
        }
272
0
        case TPM_PT_LIBRARY_COMMANDS:
273
            // number of commands from the TPM library that are implemented
274
0
        {
275
0
            UINT32 i;
276
0
            *value = 0;
277
             // calculate implemented command numbers
278
0
             for(i = TPM_CC_FIRST; i <= TPM_CC_LAST; i++)
279
0
             {
280
0
                 if(CommandIsImplemented(i)) (*value)++;
281
0
             }
282
0
             break;
283
0
        }
284
0
        case TPM_PT_VENDOR_COMMANDS:
285
            // number of vendor commands that are implemented
286
0
            *value = 0;
287
0
            break;
288
0
        case TPM_PT_PERMANENT:
289
            // TPMA_PERMANENT
290
0
        {
291
0
            TPMA_PERMANENT           flags = {0};
292
0
            if(gp.ownerAuth.t.size != 0)
293
0
                flags.ownerAuthSet = SET;
294
0
            if(gp.endorsementAuth.t.size != 0)
295
0
                flags.endorsementAuthSet = SET;
296
0
            if(gp.lockoutAuth.t.size != 0)
297
0
                flags.lockoutAuthSet = SET;
298
0
            if(gp.disableClear)
299
0
                flags.disableClear = SET;
300
0
            if(gp.failedTries >= gp.maxTries)
301
0
                flags.inLockout = SET;
302
            // In this implementation, EPS is always generated by TPM
303
0
            flags.tpmGeneratedEPS = SET;
304
             // Note: Different compilers may require a different method to cast
305
             // a bit field structure to a UINT32.
306
0
             memcpy(value, &flags, sizeof(UINT32));
307
0
             break;
308
0
        }
309
0
        case TPM_PT_STARTUP_CLEAR:
310
            // TPMA_STARTUP_CLEAR
311
0
        {
312
0
            TPMA_STARTUP_CLEAR      flags = {0};
313
0
            if(g_phEnable)
314
0
                flags.phEnable = SET;
315
0
            if(gc.shEnable)
316
0
                flags.shEnable = SET;
317
0
            if(gc.ehEnable)
318
0
                flags.ehEnable = SET;
319
0
            if(gc.phEnableNV)
320
0
                flags.phEnableNV = SET;
321
0
            if(g_prevOrderlyState != SHUTDOWN_NONE)
322
0
                  flags.orderly = SET;
323
              // Note: Different compilers may require a different method to cast
324
              // a bit field structure to a UINT32.
325
0
              memcpy(value, &flags, sizeof(UINT32));
326
0
              break;
327
0
        }
328
0
        case TPM_PT_HR_NV_INDEX:
329
            // number of NV indexes currently defined
330
0
            *value = NvCapGetIndexNumber();
331
0
            break;
332
0
        case TPM_PT_HR_LOADED:
333
            // number of authorization sessions currently loaded into TPM
334
            // RAM
335
0
            *value = SessionCapGetLoadedNumber();
336
0
            break;
337
0
        case TPM_PT_HR_LOADED_AVAIL:
338
            // number of additional authorization sessions, of any type,
339
            // that could be loaded into TPM RAM
340
0
            *value = SessionCapGetLoadedAvail();
341
0
            break;
342
0
        case TPM_PT_HR_ACTIVE:
343
            // number of active authorization sessions currently being
344
            // tracked by the TPM
345
0
            *value = SessionCapGetActiveNumber();
346
0
            break;
347
0
        case TPM_PT_HR_ACTIVE_AVAIL:
348
            // number of additional authorization sessions, of any type,
349
            // that could be created
350
0
            *value = SessionCapGetActiveAvail();
351
0
            break;
352
0
        case TPM_PT_HR_TRANSIENT_AVAIL:
353
            // estimate of the number of additional transient objects that
354
            // could be loaded into TPM RAM
355
0
            *value = ObjectCapGetTransientAvail();
356
0
            break;
357
0
        case TPM_PT_HR_PERSISTENT:
358
            // number of persistent objects currently loaded into TPM
359
            // NV memory
360
0
            *value = NvCapGetPersistentNumber();
361
0
            break;
362
0
        case TPM_PT_HR_PERSISTENT_AVAIL:
363
            // number of additional persistent objects that could be loaded
364
            // into NV memory
365
0
            *value = NvCapGetPersistentAvail();
366
0
            break;
367
0
        case TPM_PT_NV_COUNTERS:
368
            // number of defined NV indexes that have NV TPMA_NV_COUNTER
369
            // attribute SET
370
0
            *value = NvCapGetCounterNumber();
371
0
            break;
372
0
        case TPM_PT_NV_COUNTERS_AVAIL:
373
            // number of additional NV indexes that can be defined with their
374
            // TPMA_NV_COUNTER attribute SET
375
0
            *value = NvCapGetCounterAvail();
376
0
            break;
377
0
        case TPM_PT_ALGORITHM_SET:
378
            // region code for the TPM
379
0
            *value = gp.algorithmSet;
380
0
            break;
381
0
       case TPM_PT_LOADED_CURVES:
382
0
   #ifdef TPM_ALG_ECC
383
           // number of loaded ECC curves
384
0
           *value = CryptCapGetEccCurveNumber();
385
   #else // TPM_ALG_ECC
386
             *value = 0;
387
     #endif // TPM_ALG_ECC
388
0
             break;
389
0
          case TPM_PT_LOCKOUT_COUNTER:
390
              // current value of the lockout counter
391
0
              *value = gp.failedTries;
392
0
              break;
393
0
          case TPM_PT_MAX_AUTH_FAIL:
394
              // number of authorization failures before DA lockout is invoked
395
0
              *value = gp.maxTries;
396
0
              break;
397
0
          case TPM_PT_LOCKOUT_INTERVAL:
398
              // number of seconds before the value reported by
399
              // TPM_PT_LOCKOUT_COUNTER is decremented
400
0
              *value = gp.recoveryTime;
401
0
              break;
402
0
          case TPM_PT_LOCKOUT_RECOVERY:
403
              // number of seconds after a lockoutAuth failure before use of
404
              // lockoutAuth may be attempted again
405
0
              *value = gp.lockoutRecovery;
406
0
              break;
407
0
          case TPM_PT_AUDIT_COUNTER_0:
408
              // high-order 32 bits of the command audit counter
409
0
              *value = (UINT32) (gp.auditCounter >> 32);
410
0
              break;
411
0
          case TPM_PT_AUDIT_COUNTER_1:
412
              // low-order 32 bits of the command audit counter
413
0
              *value = (UINT32) (gp.auditCounter);
414
0
              break;
415
0
          default:
416
              // property is not defined
417
0
              return FALSE;
418
0
              break;
419
0
     }
420
0
     return TRUE;
421
0
}
422
//
423
//
424
//           TPMCapGetProperties()
425
//
426
//      This function is used to get the TPM_PT values. The search of properties will start at property and
427
//      continue until propertyList has as many values as will fit, or the last property has been reported, or the list
428
//      has as many values as requested in count.
429
//
430
//      Return Value                      Meaning
431
//
432
//      YES                               more properties are available
433
//      NO                                no more properties to be reported
434
//
435
TPMI_YES_NO
436
TPMCapGetProperties(
437
     TPM_PT                              property,           // IN: the starting TPM property
438
     UINT32                              count,              // IN: maximum number of returned
439
                                                             //     propertie
440
     TPML_TAGGED_TPM_PROPERTY           *propertyList        // OUT: property list
441
     )
442
0
{
443
0
     TPMI_YES_NO        more = NO;
444
0
     UINT32             i;
445
     // initialize output property list
446
0
     propertyList->count = 0;
447
      // maximum count of properties we may return is MAX_PCR_PROPERTIES
448
0
      if(count > MAX_TPM_PROPERTIES) count = MAX_TPM_PROPERTIES;
449
      // If property is less than PT_FIXED, start from PT_FIXED.
450
0
      if(property < PT_FIXED) property = PT_FIXED;
451
      // Scan through the TPM properties of the requested group.
452
      // The size of TPM property group is PT_GROUP * 2 for fix and
453
      // variable groups.
454
0
      for(i = property; i <= PT_FIXED + PT_GROUP * 2; i++)
455
0
      {
456
0
          UINT32          value;
457
0
          if(TPMPropertyIsDefined((TPM_PT) i, &value))
458
0
          {
459
0
              if(propertyList->count < count)
460
0
              {
461
                    // If the list is not full, add this property
462
0
                    propertyList->tpmProperty[propertyList->count].property =
463
0
                        (TPM_PT) i;
464
0
                    propertyList->tpmProperty[propertyList->count].value = value;
465
0
                    propertyList->count++;
466
0
              }
467
0
              else
468
0
              {
469
                  // If the return list is full but there are more properties
470
                  // available, set the indication and exit the loop.
471
0
                  more = YES;
472
0
                  break;
473
0
              }
474
0
          }
475
0
      }
476
0
      return more;
477
0
}