• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stefanberger / libtpms / #2022

23 Sep 2025 01:11PM UTC coverage: 77.227% (+0.009%) from 77.218%
#2022

push

travis-ci

web-flow
Merge a45c293de into 4504f47c6

36116 of 46766 relevant lines covered (77.23%)

125180.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.16
/src/tpm2/PropertyCap.c
1
/********************************************************************************/
2
/*                                                                                */
3
/*                For accessing the TPM_CAP_TPM_PROPERTY values                          */
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 - 2025                                */
58
/*                                                                                */
59
/********************************************************************************/
60
//** Description
61
// This file contains the functions that are used for accessing the
62
// TPM_CAP_TPM_PROPERTY values.
63

64
//** Includes
65

66
#include "Tpm.h"
67

68
#define TPM_HAVE_TPM2_DECLARATIONS
69
#include "tpm_library_intern.h"  // libtpms added
70
//** Functions
71

72
//*** TPMPropertyIsDefined()
73
// This function accepts a property selection and, if so, sets 'value'
74
// to the value of the property.
75
//
76
// All the fixed values are vendor dependent or determined by a
77
// platform-specific specification. The values in the table below
78
// are examples and should be changed by the vendor.
79
//  Return Type: BOOL
80
//      TRUE(1)         referenced property exists and 'value' set
81
//      FALSE(0)        referenced property does not exist
82
static BOOL TPMPropertyIsDefined(TPM_PT  property,  // IN: property
5,096✔
83
                                 UINT32* value      // OUT: property value
84
)
85
{
86
    switch(property)
5,096✔
87
    {
88
        case TPM_PT_FAMILY_INDICATOR:
17✔
89
            // from the title page of the specification
90
            // For this specification, the value is "2.0".
91
            *value = TPM_SPEC_FAMILY;
17✔
92
            break;
17✔
93
        case TPM_PT_LEVEL:
17✔
94
            // from the title page of the specification
95
            *value = TPM_SPEC_LEVEL;
17✔
96
            break;
17✔
97
        case TPM_PT_REVISION:
18✔
98
            // from the title page of the specification
99
            *value = TPM_SPEC_VERSION;
18✔
100
            break;
18✔
101
        case TPM_PT_DAY_OF_YEAR:
13✔
102
            // computed from the date value on the title page of the specification
103
            *value = TPM_SPEC_DAY_OF_YEAR;
13✔
104
            break;
13✔
105
        case TPM_PT_YEAR:
13✔
106
            // from the title page of the specification
107
            *value = TPM_SPEC_YEAR;
13✔
108
            break;
13✔
109

110
        case TPM_PT_MANUFACTURER:
13✔
111
            // the vendor ID unique to each TPM manufacturer
112
            *value = _plat__GetManufacturerCapabilityCode();
13✔
113
            break;
13✔
114

115
        case TPM_PT_VENDOR_STRING_1:
13✔
116
            // the first four characters of the vendor ID string
117
            *value = _plat__GetVendorCapabilityCode(1);
13✔
118
            break;
13✔
119

120
        case TPM_PT_VENDOR_STRING_2:
13✔
121
            // the second four characters of the vendor ID string
122
            *value = _plat__GetVendorCapabilityCode(2);
13✔
123
            break;
13✔
124

125
        case TPM_PT_VENDOR_STRING_3:
13✔
126
            // the third four characters of the vendor ID string
127
            *value = _plat__GetVendorCapabilityCode(3);
13✔
128
            break;
13✔
129

130
        case TPM_PT_VENDOR_STRING_4:
13✔
131
            // the fourth four characters of the vendor ID string
132
            *value = _plat__GetVendorCapabilityCode(4);
13✔
133
            break;
13✔
134

135
        case TPM_PT_VENDOR_TPM_TYPE:
13✔
136
            // vendor-defined value indicating the TPM model
137
            // We just make up a number here
138
            *value = _plat__GetTpmType();
13✔
139
            break;
13✔
140

141
        case TPM_PT_FIRMWARE_VERSION_1:
13✔
142
            // more significant 32-bits of a vendor-specific value
143
            *value = gp.firmwareV1;
13✔
144
            break;
13✔
145
        case TPM_PT_FIRMWARE_VERSION_2:
13✔
146
            // less significant 32-bits of a vendor-specific value
147
            *value = gp.firmwareV2;
13✔
148
            break;
13✔
149
        case TPM_PT_INPUT_BUFFER:
13✔
150
            // maximum size of TPM2B_MAX_BUFFER
151
            *value = MAX_DIGEST_BUFFER;
13✔
152
            break;
13✔
153
        case TPM_PT_HR_TRANSIENT_MIN:
13✔
154
            // minimum number of transient objects that can be held in TPM
155
            // RAM
156
            *value = MAX_LOADED_OBJECTS;
13✔
157
            break;
13✔
158
        case TPM_PT_HR_PERSISTENT_MIN:
13✔
159
            // minimum number of persistent objects that can be held in
160
            // TPM NV memory
161
            // In this implementation, there is no minimum number of
162
            // persistent objects.
163
            *value = MIN_EVICT_OBJECTS;
13✔
164
            break;
13✔
165
        case TPM_PT_HR_LOADED_MIN:
9✔
166
            // minimum number of authorization sessions that can be held in
167
            // TPM RAM
168
            *value = MAX_LOADED_SESSIONS;
9✔
169
            break;
9✔
170
        case TPM_PT_ACTIVE_SESSIONS_MAX:
9✔
171
            // number of authorization sessions that may be active at a time
172
            *value = MAX_ACTIVE_SESSIONS;
9✔
173
            break;
9✔
174
        case TPM_PT_PCR_COUNT:
9✔
175
            // number of PCR implemented
176
            *value = IMPLEMENTATION_PCR;
9✔
177
            break;
9✔
178
        case TPM_PT_PCR_SELECT_MIN:
9✔
179
            // minimum number of bytes in a TPMS_PCR_SELECT.sizeOfSelect
180
            *value = PCR_SELECT_MIN;
9✔
181
            break;
9✔
182
        case TPM_PT_CONTEXT_GAP_MAX:
13✔
183
            // maximum allowed difference (unsigned) between the contextID
184
            // values of two saved session contexts
185
#if 0                                        // libtpms added
186
            *value = ((UINT32)1 << (sizeof(CONTEXT_SLOT) * 8)) - 1;
187
#endif                                        // libtpms added
188
            *value = s_ContextSlotMask; // libtpms added; the mask is either 0xff (old state) or 0xffff
13✔
189
            break;
13✔
190
        case TPM_PT_NV_COUNTERS_MAX:
25✔
191
            // maximum number of NV indexes that are allowed to have the
192
            // TPMA_NV_COUNTER attribute SET
193
            // In this implementation, there is no limitation on the number
194
            // of counters, except for the size of the NV Index memory.
195
            *value = 0;
25✔
196
            break;
25✔
197
        case TPM_PT_NV_INDEX_MAX:
25✔
198
            // maximum size of an NV index data area
199
            *value = MAX_NV_INDEX_SIZE;
25✔
200
            break;
25✔
201
        case TPM_PT_MEMORY:
25✔
202
            // a TPMA_MEMORY indicating the memory management method for the TPM
203
            {
204
                union
25✔
205
                {
206
                    TPMA_MEMORY att;
207
                    UINT32      u32;
208
                } attributes = {TPMA_ZERO_INITIALIZER()};
25✔
209
                SET_ATTRIBUTE(attributes.att, TPMA_MEMORY, sharedNV);
25✔
210
                SET_ATTRIBUTE(attributes.att, TPMA_MEMORY, objectCopiedToRam);
25✔
211

212
                // Note: For a LSb0 machine, the bits in a bit field are in the correct
213
                // order even if the machine is MSB0. For a MSb0 machine, a TPMA will
214
                // be an integer manipulated by masking (USE_BIT_FIELD_STRUCTURES will
215
                // be NO) so the bits are manipulate correctly.
216
                *value = attributes.u32;
25✔
217
                break;
25✔
218
            }
219
        case TPM_PT_CLOCK_UPDATE:
25✔
220
            // interval, in seconds, between updates to the copy of
221
            // TPMS_TIME_INFO .clock in NV
222
            *value = (1 << NV_CLOCK_UPDATE_INTERVAL);
25✔
223
            break;
25✔
224
        case TPM_PT_CONTEXT_HASH:
21✔
225
            // algorithm used for the integrity hash on saved contexts and
226
            // for digesting the fuData of TPM2_FirmwareRead()
227
            *value = CONTEXT_INTEGRITY_HASH_ALG;
21✔
228
            break;
21✔
229
        case TPM_PT_CONTEXT_SYM:
17✔
230
            // algorithm used for encryption of saved contexts
231
            *value = CONTEXT_ENCRYPT_ALG;
17✔
232
            break;
17✔
233
        case TPM_PT_CONTEXT_SYM_SIZE:
17✔
234
            // size of the key used for encryption of saved contexts
235
            *value = CONTEXT_ENCRYPT_KEY_BITS;
17✔
236
            break;
17✔
237
        case TPM_PT_ORDERLY_COUNT:
13✔
238
            // maximum difference between the volatile and non-volatile
239
            // versions of TPMA_NV_COUNTER that have TPMA_NV_ORDERLY SET
240
            *value = MAX_ORDERLY_COUNT;
13✔
241
            break;
13✔
242
        case TPM_PT_MAX_COMMAND_SIZE:
16✔
243
            // maximum value for 'commandSize'
244
            *value = MAX_COMMAND_SIZE;
16✔
245
            break;
16✔
246
        case TPM_PT_MAX_RESPONSE_SIZE:
16✔
247
            // maximum value for 'responseSize'
248
            *value = MAX_RESPONSE_SIZE;
16✔
249
            break;
16✔
250
        case TPM_PT_MAX_DIGEST:
16✔
251
            // maximum size of a digest that can be produced by the TPM
252
            *value = sizeof(TPMU_HA);
16✔
253
            break;
16✔
254
        case TPM_PT_MAX_OBJECT_CONTEXT:
19✔
255
// Header has 'sequence', 'handle' and 'hierarchy'
256
#define SIZE_OF_CONTEXT_HEADER \
257
    sizeof(UINT64) + sizeof(TPMI_DH_CONTEXT) + sizeof(TPMI_RH_HIERARCHY)
258
#define SIZE_OF_CONTEXT_INTEGRITY (sizeof(UINT16) + CONTEXT_INTEGRITY_HASH_SIZE)
259
#define SIZE_OF_FINGERPRINT       sizeof(UINT64)
260
#define SIZE_OF_CONTEXT_BLOB_OVERHEAD \
261
    (sizeof(UINT16) + SIZE_OF_CONTEXT_INTEGRITY + SIZE_OF_FINGERPRINT)
262
#define SIZE_OF_CONTEXT_OVERHEAD \
263
    (SIZE_OF_CONTEXT_HEADER + SIZE_OF_CONTEXT_BLOB_OVERHEAD)
264
#if 0
265
            // maximum size of a TPMS_CONTEXT that will be returned by
266
            // TPM2_ContextSave for object context
267
            *value = 0;
268
            // adding sequence, saved handle and hierarchy
269
            *value += sizeof(UINT64) + sizeof(TPMI_DH_CONTEXT) +
270
                sizeof(TPMI_RH_HIERARCHY);
271
            // add size field in TPM2B_CONTEXT
272
            *value += sizeof(UINT16);
273
            // add integrity hash size
274
            *value += sizeof(UINT16) +
275
                CryptHashGetDigestSize(CONTEXT_INTEGRITY_HASH_ALG);
276
            // Add fingerprint size, which is the same as sequence size
277
            *value += sizeof(UINT64);
278
            // Add OBJECT structure size
279
            *value += sizeof(OBJECT);
280
#else
281
            // the maximum size of a TPMS_CONTEXT that will be returned by
282
            // TPM2_ContextSave for object context
283
            *value = SIZE_OF_CONTEXT_OVERHEAD + sizeof(OBJECT);
19✔
284
#endif
285
            break;
19✔
286
        case TPM_PT_MAX_SESSION_CONTEXT:
19✔
287
#if 0
288

289
            // the maximum size of a TPMS_CONTEXT that will be returned by
290
            // TPM2_ContextSave for object context
291
            *value = 0;
292
            // adding sequence, saved handle and hierarchy
293
            *value += sizeof(UINT64) + sizeof(TPMI_DH_CONTEXT) +
294
                sizeof(TPMI_RH_HIERARCHY);
295
            // Add size field in TPM2B_CONTEXT
296
            *value += sizeof(UINT16);
297
// Add integrity hash size
298
            *value += sizeof(UINT16) +
299
                CryptHashGetDigestSize(CONTEXT_INTEGRITY_HASH_ALG);
300
      // Add fingerprint size, which is the same as sequence size
301
            *value += sizeof(UINT64);
302
            // Add SESSION structure size
303
            *value += sizeof(SESSION);
304
#else
305
            // the maximum size of a TPMS_CONTEXT that will be returned by
306
            // TPM2_ContextSave for object context
307
            *value = SIZE_OF_CONTEXT_OVERHEAD + sizeof(SESSION);
19✔
308
#endif
309
            break;
19✔
310
        case TPM_PT_PS_FAMILY_INDICATOR:
13✔
311
            // platform specific values for the TPM_PT_PS parameters from
312
            // the relevant platform-specific specification
313
            // In this reference implementation, all of these values are 0.
314
            *value = PLATFORM_FAMILY;
13✔
315
            break;
13✔
316
        case TPM_PT_PS_LEVEL:
13✔
317
            // level of the platform-specific specification
318
            *value = PLATFORM_LEVEL;
13✔
319
            break;
13✔
320
        case TPM_PT_PS_REVISION:
13✔
321
            // specification Revision times 100 for the platform-specific
322
            // specification
323
            *value = PLATFORM_VERSION;
13✔
324
            break;
13✔
325
        case TPM_PT_PS_DAY_OF_YEAR:
13✔
326
            // platform-specific specification day of year using TCG calendar
327
            *value = PLATFORM_DAY_OF_YEAR;
13✔
328
            break;
13✔
329
        case TPM_PT_PS_YEAR:
13✔
330
            // platform-specific specification year using the CE
331
            *value = PLATFORM_YEAR;
13✔
332
            break;
13✔
333
        case TPM_PT_SPLIT_MAX:
13✔
334
            // number of split signing operations supported by the TPM
335
            *value = 0;
13✔
336
#if ALG_ECC
337
            *value = sizeof(gr.commitArray) * 8;
13✔
338
#endif
339
            break;
13✔
340
        case TPM_PT_TOTAL_COMMANDS:
13✔
341
            // total number of commands implemented in the TPM
342
            // Since the reference implementation does not have any
343
            // vendor-defined commands, this will be the same as the
344
            // number of library commands.
345
            {
346
#if COMPRESSED_LISTS
347
                (*value) = RuntimeCommandsCountEnabled(&g_RuntimeProfile.RuntimeCommands); // libtpms changed: was COMMAND_COUNT
348
#else
349
                COMMAND_INDEX commandIndex;
13✔
350
                *value = 0;
13✔
351

352
                // scan all implemented commands
353
                for(commandIndex = GetClosestCommandIndex(0);
13✔
354
                    commandIndex != UNIMPLEMENTED_COMMAND_INDEX;
1,447✔
355
                    commandIndex = GetNextCommandIndex(commandIndex))
1,434✔
356
                {
357
                    (*value)++;  // count of all implemented
1,434✔
358
                }
359
#endif
360
                break;
361
            }
362
        case TPM_PT_LIBRARY_COMMANDS:
13✔
363
            // number of commands from the TPM library that are implemented
364
            {
365
#if COMPRESSED_LISTS
366
                *value = RuntimeCommandsCountEnabled(&g_RuntimeProfile.RuntimeCommands); // libtpms changed: was LIBRARY_COMMAND_ARRAY_SIZE
367
#else
368
                COMMAND_INDEX commandIndex;
13✔
369
                *value = 0;
13✔
370

371
                // scan all implemented commands
372
                for(commandIndex = GetClosestCommandIndex(0);
13✔
373
                    commandIndex < LIBRARY_COMMAND_ARRAY_SIZE;
1,447✔
374
                    commandIndex = GetNextCommandIndex(commandIndex))
1,434✔
375
                {
376
                    (*value)++;
1,434✔
377
                }
378
#endif
379
                break;
380
            }
381
        case TPM_PT_VENDOR_COMMANDS:
13✔
382
            // number of vendor commands that are implemented
383
            *value = VENDOR_COMMAND_ARRAY_SIZE;
13✔
384
            break;
13✔
385
        case TPM_PT_NV_BUFFER_MAX:
429✔
386
            // Maximum data size in an NV write command
387
            *value = MAX_NV_BUFFER_SIZE;
429✔
388
            break;
429✔
389
        case TPM_PT_MODES:
429✔
390
        {
391
            union
429✔
392
            {
393
                TPMA_MODES attr;
394
                UINT32     u32;
395
            } flags = {TPMA_ZERO_INITIALIZER()};
429✔
396
#if FIPS_COMPLIANT
397
            SET_ATTRIBUTE(flags.attr, TPMA_MODES, FIPS_140_2);
398
#endif
399
            *value = flags.u32;
429✔
400
            break;
429✔
401
        }
402
        case TPM_PT_MAX_CAP_BUFFER:
13✔
403
            *value = MAX_CAP_BUFFER;
13✔
404
            break;
13✔
405
        case TPM_PT_FIRMWARE_SVN:
13✔
406
            *value = _plat__GetTpmFirmwareSvn();
13✔
407
            break;
13✔
408
        case TPM_PT_FIRMWARE_MAX_SVN:
13✔
409
            *value = _plat__GetTpmFirmwareMaxSvn();
13✔
410
            break;
13✔
411

412
        // Start of variable commands
413
        case TPM_PT_PERMANENT:
1✔
414
            // TPMA_PERMANENT
415
            {
416
                union
1✔
417
                {
418
                    TPMA_PERMANENT attr;
419
                    UINT32         u32;
420
                } flags = {TPMA_ZERO_INITIALIZER()};
1✔
421
                if(gp.ownerAuth.t.size != 0)
1✔
422
                    SET_ATTRIBUTE(flags.attr, TPMA_PERMANENT, ownerAuthSet);
×
423
                if(gp.endorsementAuth.t.size != 0)
1✔
424
                    SET_ATTRIBUTE(flags.attr, TPMA_PERMANENT, endorsementAuthSet);
×
425
                if(gp.lockoutAuth.t.size != 0)
1✔
426
                    SET_ATTRIBUTE(flags.attr, TPMA_PERMANENT, lockoutAuthSet);
×
427
                if(gp.disableClear)
1✔
428
                    SET_ATTRIBUTE(flags.attr, TPMA_PERMANENT, disableClear);
×
429
                if(gp.failedTries >= gp.maxTries)
1✔
430
                    SET_ATTRIBUTE(flags.attr, TPMA_PERMANENT, inLockout);
×
431
                // In this implementation, EPS is always generated by TPM
432
                SET_ATTRIBUTE(flags.attr, TPMA_PERMANENT, tpmGeneratedEPS);
1✔
433

434
                // Note: For a LSb0 machine, the bits in a bit field are in the correct
435
                // order even if the machine is MSB0. For a MSb0 machine, a TPMA will
436
                // be an integer manipulated by masking (USE_BIT_FIELD_STRUCTURES will
437
                // be NO) so the bits are manipulate correctly.
438
                *value = flags.u32;
1✔
439
                break;
1✔
440
            }
441
        case TPM_PT_STARTUP_CLEAR:
1✔
442
            // TPMA_STARTUP_CLEAR
443
            {
444
                union
1✔
445
                {
446
                    TPMA_STARTUP_CLEAR attr;
447
                    UINT32             u32;
448
                } flags = {TPMA_ZERO_INITIALIZER()};
1✔
449
                //
450
                if(g_phEnable)
1✔
451
                    SET_ATTRIBUTE(flags.attr, TPMA_STARTUP_CLEAR, phEnable);
1✔
452
                if(gc.shEnable)
1✔
453
                    SET_ATTRIBUTE(flags.attr, TPMA_STARTUP_CLEAR, shEnable);
1✔
454
                if(gc.ehEnable)
1✔
455
                    SET_ATTRIBUTE(flags.attr, TPMA_STARTUP_CLEAR, ehEnable);
1✔
456
                if(gc.phEnableNV)
1✔
457
                    SET_ATTRIBUTE(flags.attr, TPMA_STARTUP_CLEAR, phEnableNV);
1✔
458
                if(g_prevOrderlyState != SU_NONE_VALUE)
1✔
459
                    SET_ATTRIBUTE(flags.attr, TPMA_STARTUP_CLEAR, orderly);
1✔
460

461
                // Note: For a LSb0 machine, the bits in a bit field are in the correct
462
                // order even if the machine is MSB0. For a MSb0 machine, a TPMA will
463
                // be an integer manipulated by masking (USE_BIT_FIELD_STRUCTURES will
464
                // be NO) so the bits are manipulate correctly.
465
                *value = flags.u32;
1✔
466
                break;
1✔
467
            }
468
        case TPM_PT_HR_NV_INDEX:
1✔
469
            // number of NV indexes currently defined
470
            *value = NvCapGetIndexNumber();
1✔
471
            break;
1✔
472
        case TPM_PT_HR_LOADED:
1✔
473
            // number of authorization sessions currently loaded into TPM
474
            // RAM
475
            *value = SessionCapGetLoadedNumber();
1✔
476
            break;
1✔
477
        case TPM_PT_HR_LOADED_AVAIL:
1✔
478
            // number of additional authorization sessions, of any type,
479
            // that could be loaded into TPM RAM
480
            *value = SessionCapGetLoadedAvail();
1✔
481
            break;
1✔
482
        case TPM_PT_HR_ACTIVE:
1✔
483
            // number of active authorization sessions currently being
484
            // tracked by the TPM
485
            *value = SessionCapGetActiveNumber();
1✔
486
            break;
1✔
487
        case TPM_PT_HR_ACTIVE_AVAIL:
1✔
488
            // number of additional authorization sessions, of any type,
489
            // that could be created
490
            *value = SessionCapGetActiveAvail();
1✔
491
            break;
1✔
492
        case TPM_PT_HR_TRANSIENT_AVAIL:
1✔
493
            // estimate of the number of additional transient objects that
494
            // could be loaded into TPM RAM
495
            *value = ObjectCapGetTransientAvail();
1✔
496
            break;
1✔
497
        case TPM_PT_HR_PERSISTENT:
1✔
498
            // number of persistent objects currently loaded into TPM
499
            // NV memory
500
            *value = NvCapGetPersistentNumber();
1✔
501
            break;
1✔
502
        case TPM_PT_HR_PERSISTENT_AVAIL:
1✔
503
            // number of additional persistent objects that could be loaded
504
            // into NV memory
505
            *value = NvCapGetPersistentAvail();
1✔
506
            break;
1✔
507
        case TPM_PT_NV_COUNTERS:
1✔
508
            // number of defined NV indexes that have NV TPMA_NV_COUNTER
509
            // attribute SET
510
            *value = NvCapGetCounterNumber();
1✔
511
            break;
1✔
512
        case TPM_PT_NV_COUNTERS_AVAIL:
1✔
513
            // number of additional NV indexes that can be defined with their
514
            // TPMA_NV_COUNTER attribute SET
515
            *value = NvCapGetCounterAvail();
1✔
516
            break;
1✔
517
        case TPM_PT_ALGORITHM_SET:
1✔
518
            // region code for the TPM
519
            *value = gp.algorithmSet;
1✔
520
            break;
1✔
521
        case TPM_PT_LOADED_CURVES:
1✔
522
#if ALG_ECC
523
            // number of loaded ECC curves
524
            *value = ECC_CURVE_COUNT;
1✔
525
#else   // ALG_ECC
526
            *value = 0;
527
#endif  // ALG_ECC
528
            break;
1✔
529
        case TPM_PT_LOCKOUT_COUNTER:
10✔
530
            // current value of the lockout counter
531
            *value = gp.failedTries;
10✔
532
            break;
10✔
533
        case TPM_PT_MAX_AUTH_FAIL:
10✔
534
            // number of authorization failures before DA lockout is invoked
535
            *value = gp.maxTries;
10✔
536
            break;
10✔
537
        case TPM_PT_LOCKOUT_INTERVAL:
1✔
538
            // number of seconds before the value reported by
539
            // TPM_PT_LOCKOUT_COUNTER is decremented
540
            *value = gp.recoveryTime;
1✔
541
            break;
1✔
542
        case TPM_PT_LOCKOUT_RECOVERY:
1✔
543
            // number of seconds after a lockoutAuth failure before use of
544
            // lockoutAuth may be attempted again
545
            *value = gp.lockoutRecovery;
1✔
546
            break;
1✔
547
        case TPM_PT_NV_WRITE_RECOVERY:
1✔
548
            // number of milliseconds before the TPM will accept another command
549
            // that will modify NV.
550
            // This should make a call to the platform code that is doing rate
551
            // limiting of NV. Rate limiting is not implemented in the reference
552
            // code so no call is made.
553
            *value = 0;
1✔
554
            break;
1✔
555
        case TPM_PT_AUDIT_COUNTER_0:
1✔
556
            // high-order 32 bits of the command audit counter
557
            *value = (UINT32)(gp.auditCounter >> 32);
1✔
558
            break;
1✔
559
        case TPM_PT_AUDIT_COUNTER_1:
1✔
560
            // low-order 32 bits of the command audit counter
561
            *value = (UINT32)(gp.auditCounter);
1✔
562
            break;
1✔
563
        default:
564
            // property is not defined
565
            return FALSE;
566
            break;
567
    }
568
    return TRUE;
569
}
570

571
//*** TPMCapGetProperties()
572
// This function is used to get the TPM_PT values. The search of properties will
573
// start at 'property' and continue until 'propertyList' has as many values as
574
// will fit, or the last property has been reported, or the list has as many
575
// values as requested in 'count'.
576
//  Return Type: TPMI_YES_NO
577
//  YES        more properties are available
578
//  NO         no more properties to be reported
579
TPMI_YES_NO
580
TPMCapGetProperties(TPM_PT property,  // IN: the starting TPM property
496✔
581
                    UINT32 count,     // IN: maximum number of returned
582
                                      //     properties
583
                    TPML_TAGGED_TPM_PROPERTY* propertyList  // OUT: property list
584
)
585
{
586
    TPMI_YES_NO more = NO;
496✔
587
    UINT32      i;
496✔
588
    UINT32      nextGroup;
496✔
589

590
    // initialize output property list
591
    propertyList->count = 0;
496✔
592

593
    // maximum count of properties we may return is MAX_PCR_PROPERTIES
594
    if(count > MAX_TPM_PROPERTIES)
496✔
595
        count = MAX_TPM_PROPERTIES;
596

597
    // if property is less than PT_FIXED, start from PT_FIXED
598
    if(property < PT_FIXED)
496✔
599
        property = PT_FIXED;
600
    // There is only the fixed and variable groups with the variable group coming
601
    // last
602
    if(property >= (PT_VAR + PT_GROUP))
484✔
603
        return more;
604

605
    // Don't read past the end of the selected group
606
    nextGroup = ((property / PT_GROUP) * PT_GROUP) + PT_GROUP;
492✔
607

608
    // Scan through the TPM properties of the requested group.
609
    for(i = property; i < nextGroup; i++)
5,133✔
610
    {
611
        UINT32 value;
5,095✔
612
        // if we have hit the end of the group, quit
613
        if(i != property && ((i % PT_GROUP) == 0))
5,095✔
614
            break;
615
        if(TPMPropertyIsDefined((TPM_PT)i, &value))
5,095✔
616
        {
617
            if(propertyList->count < count)
1,576✔
618
            {
619
                // If the list is not full, add this property
620
                propertyList->tpmProperty[propertyList->count].property = (TPM_PT)i;
1,122✔
621
                propertyList->tpmProperty[propertyList->count].value    = value;
1,122✔
622
                propertyList->count++;
1,122✔
623
            }
624
            else
625
            {
626
                // If the return list is full but there are more properties
627
                // available, set the indication and exit the loop.
628
                more = YES;
629
                break;
630
            }
631
        }
632
    }
633
    return more;
634
}
635

636
//*** TPMCapGetOneProperty()
637
// This function returns a single TPM property, if present.
638
BOOL TPMCapGetOneProperty(TPM_PT                pt,       // IN: the TPM property
1✔
639
                          TPMS_TAGGED_PROPERTY* property  // OUT: tagged property
640
)
641
{
642
    UINT32 value;
1✔
643

644
    if(TPMPropertyIsDefined((TPM_PT)pt, &value))
1✔
645
    {
646
        property->property = (TPM_PT)pt;
1✔
647
        property->value    = value;
1✔
648
        return TRUE;
1✔
649
    }
650

651
    return FALSE;
652
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc