blob: 42b0153657a3942a69571865af6e30fd9b62ac2a [file] [log] [blame]
Vadim Bendebury56797522015-05-20 10:32:25 -07001// 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//
24static BOOL
25TPMPropertyIsDefined(
26 TPM_PT property, // IN: property
27 UINT32 *value // OUT: property value
28 )
29{
30 switch(property)
31 {
32 case TPM_PT_FAMILY_INDICATOR:
33 // from the title page of the specification
34 // For this specification, the value is "2.0".
35 *value = TPM_SPEC_FAMILY;
36 break;
37 case TPM_PT_LEVEL:
38 // from the title page of the specification
39 *value = TPM_SPEC_LEVEL;
40 break;
41 case TPM_PT_REVISION:
42 // from the title page of the specification
43 *value = TPM_SPEC_VERSION;
44 break;
45 case TPM_PT_DAY_OF_YEAR:
46 // computed from the date value on the title page of the specification
47 *value = TPM_SPEC_DAY_OF_YEAR;
48 break;
49 case TPM_PT_YEAR:
50 // from the title page of the specification
51 *value = TPM_SPEC_YEAR;
52 break;
53 case TPM_PT_MANUFACTURER:
54 // vendor ID unique to each TPM manufacturer
55 *value = BYTE_ARRAY_TO_UINT32(MANUFACTURER);
56 break;
57 case TPM_PT_VENDOR_STRING_1:
58 // first four characters of the vendor ID string
59 *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_1);
60 break;
61 case TPM_PT_VENDOR_STRING_2:
62 // second four characters of the vendor ID string
63#ifdef VENDOR_STRING_2
64 *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_2);
65#else
66 *value = 0;
67#endif
68 break;
69 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 *value = 0;
75#endif
76 break;
77 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 *value = 0;
83#endif
84 break;
85 case TPM_PT_VENDOR_TPM_TYPE:
86 // vendor-defined value indicating the TPM model
87 *value = 1;
88 break;
89 case TPM_PT_FIRMWARE_VERSION_1:
90 // more significant 32-bits of a vendor-specific value
91 *value = gp.firmwareV1;
92 break;
93 case TPM_PT_FIRMWARE_VERSION_2:
94 // less significant 32-bits of a vendor-specific value
95 *value = gp.firmwareV2;
96 break;
97 case TPM_PT_INPUT_BUFFER:
98 // maximum size of TPM2B_MAX_BUFFER
99 *value = MAX_DIGEST_BUFFER;
100 break;
101 case TPM_PT_HR_TRANSIENT_MIN:
102 // minimum number of transient objects that can be held in TPM
103 // RAM
104 *value = MAX_LOADED_OBJECTS;
105 break;
106 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 *value = MIN_EVICT_OBJECTS;
112 break;
113 case TPM_PT_HR_LOADED_MIN:
114 // minimum number of authorization sessions that can be held in
115 // TPM RAM
116 *value = MAX_LOADED_SESSIONS;
117 break;
118 case TPM_PT_ACTIVE_SESSIONS_MAX:
119 // number of authorization sessions that may be active at a time
120 *value = MAX_ACTIVE_SESSIONS;
121 break;
122 case TPM_PT_PCR_COUNT:
123 // number of PCR implemented
124 *value = IMPLEMENTATION_PCR;
125 break;
126 case TPM_PT_PCR_SELECT_MIN:
127 // minimum number of bytes in a TPMS_PCR_SELECT.sizeOfSelect
128 *value = PCR_SELECT_MIN;
129 break;
130 case TPM_PT_CONTEXT_GAP_MAX:
131 // maximum allowed difference (unsigned) between the contextID
132 // values of two saved session contexts
133 *value = (1 << (sizeof(CONTEXT_SLOT) * 8)) - 1;
134 break;
135 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 *value = 0;
141 break;
142 case TPM_PT_NV_INDEX_MAX:
143 // maximum size of an NV index data area
144 *value = MAX_NV_INDEX_SIZE;
145 break;
146 case TPM_PT_MEMORY:
147 // a TPMA_MEMORY indicating the memory management method for the TPM
148 {
149 TPMA_MEMORY attributes = {0};
150 attributes.sharedNV = SET;
151 attributes.objectCopiedToRam = SET;
152 // Note: Different compilers may require a different method to cast
153 // a bit field structure to a UINT32.
Jocelyn Bohr71e3b992015-08-14 12:05:59 -0700154 memcpy(value, &attributes, sizeof(UINT32));
Vadim Bendebury56797522015-05-20 10:32:25 -0700155 break;
156 }
157 case TPM_PT_CLOCK_UPDATE:
158 // interval, in seconds, between updates to the copy of
159 // TPMS_TIME_INFO .clock in NV
160 *value = (1 << NV_CLOCK_UPDATE_INTERVAL);
161 break;
162 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 *value = CONTEXT_INTEGRITY_HASH_ALG;
166 break;
167 case TPM_PT_CONTEXT_SYM:
168 // algorithm used for encryption of saved contexts
169 *value = CONTEXT_ENCRYPT_ALG;
170 break;
171 case TPM_PT_CONTEXT_SYM_SIZE:
172 // size of the key used for encryption of saved contexts
173 *value = CONTEXT_ENCRYPT_KEY_BITS;
174 break;
175 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 *value = MAX_ORDERLY_COUNT;
179 break;
180 case TPM_PT_MAX_COMMAND_SIZE:
181 // maximum value for 'commandSize'
182 *value = MAX_COMMAND_SIZE;
183 break;
184 case TPM_PT_MAX_RESPONSE_SIZE:
185 // maximum value for 'responseSize'
186 *value = MAX_RESPONSE_SIZE;
187 break;
188 case TPM_PT_MAX_DIGEST:
189 // maximum size of a digest that can be produced by the TPM
190 *value = sizeof(TPMU_HA);
191 break;
192 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 *value = 0;
196 // adding sequence, saved handle and hierarchy
197 *value += sizeof(UINT64) + sizeof(TPMI_DH_CONTEXT) +
198 sizeof(TPMI_RH_HIERARCHY);
199 // add size field in TPM2B_CONTEXT
200 *value += sizeof(UINT16);
201 // add integrity hash size
202 *value += sizeof(UINT16) +
203 CryptGetHashDigestSize(CONTEXT_INTEGRITY_HASH_ALG);
204 // Add fingerprint size, which is the same as sequence size
205 *value += sizeof(UINT64);
206 // Add OBJECT structure size
207 *value += sizeof(OBJECT);
208 break;
209 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 *value = 0;
213 // adding sequence, saved handle and hierarchy
214 *value += sizeof(UINT64) + sizeof(TPMI_DH_CONTEXT) +
215 sizeof(TPMI_RH_HIERARCHY);
216 // Add size field in TPM2B_CONTEXT
217 *value += sizeof(UINT16);
218 // Add integrity hash size
219 *value += sizeof(UINT16) +
220 CryptGetHashDigestSize(CONTEXT_INTEGRITY_HASH_ALG);
221 // Add fingerprint size, which is the same as sequence size
222 *value += sizeof(UINT64);
223 // Add SESSION structure size
224 *value += sizeof(SESSION);
225 break;
226 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 *value = 0;
231 break;
232 case TPM_PT_PS_LEVEL:
233 // level of the platform-specific specification
234 *value = 0;
235 break;
236 case TPM_PT_PS_REVISION:
237 // specification Revision times 100 for the platform-specific
238 // specification
239 *value = 0;
240 break;
241 case TPM_PT_PS_DAY_OF_YEAR:
242 // platform-specific specification day of year using TCG calendar
243 *value = 0;
244 break;
245 case TPM_PT_PS_YEAR:
246 // platform-specific specification year using the CE
247 *value = 0;
248 break;
249 case TPM_PT_SPLIT_MAX:
250 // number of split signing operations supported by the TPM
251 *value = 0;
252 #ifdef TPM_ALG_ECC
253 *value = sizeof(gr.commitArray) * 8;
254 #endif
255 break;
256 case TPM_PT_TOTAL_COMMANDS:
257 // total number of commands implemented in the TPM
Vadim Bendebury56797522015-05-20 10:32:25 -0700258 {
259 UINT32 i;
260 *value = 0;
261 // calculate implemented command numbers
262 for(i = TPM_CC_FIRST; i <= TPM_CC_LAST; i++)
263 {
264 if(CommandIsImplemented(i)) (*value)++;
265 }
Namyoon Woo65994902019-10-31 10:38:51 -0700266 for(i = TPM_CCE_FIRST; i <= TPM_CCE_LAST; i++)
267 {
268 if(CommandIsImplemented(i)) (*value)++;
269 }
Vadim Bendebury56797522015-05-20 10:32:25 -0700270 break;
271 }
272 case TPM_PT_LIBRARY_COMMANDS:
273 // number of commands from the TPM library that are implemented
274 {
275 UINT32 i;
276 *value = 0;
277 // calculate implemented command numbers
278 for(i = TPM_CC_FIRST; i <= TPM_CC_LAST; i++)
279 {
280 if(CommandIsImplemented(i)) (*value)++;
281 }
282 break;
283 }
284 case TPM_PT_VENDOR_COMMANDS:
285 // number of vendor commands that are implemented
286 *value = 0;
287 break;
288 case TPM_PT_PERMANENT:
289 // TPMA_PERMANENT
290 {
291 TPMA_PERMANENT flags = {0};
292 if(gp.ownerAuth.t.size != 0)
293 flags.ownerAuthSet = SET;
294 if(gp.endorsementAuth.t.size != 0)
295 flags.endorsementAuthSet = SET;
296 if(gp.lockoutAuth.t.size != 0)
297 flags.lockoutAuthSet = SET;
298 if(gp.disableClear)
299 flags.disableClear = SET;
300 if(gp.failedTries >= gp.maxTries)
301 flags.inLockout = SET;
302 // In this implementation, EPS is always generated by TPM
303 flags.tpmGeneratedEPS = SET;
304 // Note: Different compilers may require a different method to cast
305 // a bit field structure to a UINT32.
Jocelyn Bohr71e3b992015-08-14 12:05:59 -0700306 memcpy(value, &flags, sizeof(UINT32));
Vadim Bendebury56797522015-05-20 10:32:25 -0700307 break;
308 }
309 case TPM_PT_STARTUP_CLEAR:
310 // TPMA_STARTUP_CLEAR
311 {
312 TPMA_STARTUP_CLEAR flags = {0};
313 if(g_phEnable)
314 flags.phEnable = SET;
315 if(gc.shEnable)
316 flags.shEnable = SET;
317 if(gc.ehEnable)
318 flags.ehEnable = SET;
319 if(gc.phEnableNV)
320 flags.phEnableNV = SET;
321 if(g_prevOrderlyState != SHUTDOWN_NONE)
322 flags.orderly = SET;
323 // Note: Different compilers may require a different method to cast
324 // a bit field structure to a UINT32.
Jocelyn Bohr71e3b992015-08-14 12:05:59 -0700325 memcpy(value, &flags, sizeof(UINT32));
Vadim Bendebury56797522015-05-20 10:32:25 -0700326 break;
327 }
328 case TPM_PT_HR_NV_INDEX:
329 // number of NV indexes currently defined
330 *value = NvCapGetIndexNumber();
331 break;
332 case TPM_PT_HR_LOADED:
333 // number of authorization sessions currently loaded into TPM
334 // RAM
335 *value = SessionCapGetLoadedNumber();
336 break;
337 case TPM_PT_HR_LOADED_AVAIL:
338 // number of additional authorization sessions, of any type,
339 // that could be loaded into TPM RAM
340 *value = SessionCapGetLoadedAvail();
341 break;
342 case TPM_PT_HR_ACTIVE:
343 // number of active authorization sessions currently being
344 // tracked by the TPM
345 *value = SessionCapGetActiveNumber();
346 break;
347 case TPM_PT_HR_ACTIVE_AVAIL:
348 // number of additional authorization sessions, of any type,
349 // that could be created
350 *value = SessionCapGetActiveAvail();
351 break;
352 case TPM_PT_HR_TRANSIENT_AVAIL:
353 // estimate of the number of additional transient objects that
354 // could be loaded into TPM RAM
355 *value = ObjectCapGetTransientAvail();
356 break;
357 case TPM_PT_HR_PERSISTENT:
358 // number of persistent objects currently loaded into TPM
359 // NV memory
360 *value = NvCapGetPersistentNumber();
361 break;
362 case TPM_PT_HR_PERSISTENT_AVAIL:
363 // number of additional persistent objects that could be loaded
364 // into NV memory
365 *value = NvCapGetPersistentAvail();
366 break;
367 case TPM_PT_NV_COUNTERS:
368 // number of defined NV indexes that have NV TPMA_NV_COUNTER
369 // attribute SET
370 *value = NvCapGetCounterNumber();
371 break;
372 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 *value = NvCapGetCounterAvail();
376 break;
377 case TPM_PT_ALGORITHM_SET:
378 // region code for the TPM
379 *value = gp.algorithmSet;
380 break;
381 case TPM_PT_LOADED_CURVES:
382 #ifdef TPM_ALG_ECC
383 // number of loaded ECC curves
384 *value = CryptCapGetEccCurveNumber();
385 #else // TPM_ALG_ECC
386 *value = 0;
387 #endif // TPM_ALG_ECC
388 break;
389 case TPM_PT_LOCKOUT_COUNTER:
390 // current value of the lockout counter
391 *value = gp.failedTries;
392 break;
393 case TPM_PT_MAX_AUTH_FAIL:
394 // number of authorization failures before DA lockout is invoked
395 *value = gp.maxTries;
396 break;
397 case TPM_PT_LOCKOUT_INTERVAL:
398 // number of seconds before the value reported by
399 // TPM_PT_LOCKOUT_COUNTER is decremented
400 *value = gp.recoveryTime;
401 break;
402 case TPM_PT_LOCKOUT_RECOVERY:
403 // number of seconds after a lockoutAuth failure before use of
404 // lockoutAuth may be attempted again
405 *value = gp.lockoutRecovery;
406 break;
407 case TPM_PT_AUDIT_COUNTER_0:
408 // high-order 32 bits of the command audit counter
409 *value = (UINT32) (gp.auditCounter >> 32);
410 break;
411 case TPM_PT_AUDIT_COUNTER_1:
412 // low-order 32 bits of the command audit counter
413 *value = (UINT32) (gp.auditCounter);
414 break;
415 default:
416 // property is not defined
417 return FALSE;
418 break;
419 }
420 return TRUE;
421}
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//
435TPMI_YES_NO
436TPMCapGetProperties(
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{
443 TPMI_YES_NO more = NO;
444 UINT32 i;
445 // initialize output property list
446 propertyList->count = 0;
447 // maximum count of properties we may return is MAX_PCR_PROPERTIES
448 if(count > MAX_TPM_PROPERTIES) count = MAX_TPM_PROPERTIES;
449 // If property is less than PT_FIXED, start from PT_FIXED.
450 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 for(i = property; i <= PT_FIXED + PT_GROUP * 2; i++)
455 {
456 UINT32 value;
457 if(TPMPropertyIsDefined((TPM_PT) i, &value))
458 {
459 if(propertyList->count < count)
460 {
461 // If the list is not full, add this property
462 propertyList->tpmProperty[propertyList->count].property =
463 (TPM_PT) i;
464 propertyList->tpmProperty[propertyList->count].value = value;
465 propertyList->count++;
466 }
467 else
468 {
469 // If the return list is full but there are more properties
470 // available, set the indication and exit the loop.
471 more = YES;
472 break;
473 }
474 }
475 }
476 return more;
477}