Coverage Report

Created: 2025-08-26 06:27

/src/tpm2/Entity.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
//
12
//          Functions
13
//
14
//          EntityGetLoadStatus()
15
//
16
//     This function will indicate if the entity associated with a handle is present in TPM memory. If the handle is
17
//     a persistent object handle, and the object exists, the persistent object is moved from NV memory into a
18
//     RAM object slot and the persistent handle is replaced with the transient object handle for the slot.
19
//
20
//     Error Returns                     Meaning
21
//
22
//     TPM_RC_HANDLE                     handle type does not match
23
//     TPM_RC_REFERENCE_H0               entity is not present
24
//     TPM_RC_HIERARCHY                  entity belongs to a disabled hierarchy
25
//     TPM_RC_OBJECT_MEMORY              handle is an evict object but there is no space to load it to RAM
26
//
27
TPM_RC
28
EntityGetLoadStatus(
29
    TPM_HANDLE          *handle,              // IN/OUT: handle of the entity
30
    TPM_CC               commandCode          // IN: the commmandCode
31
    )
32
71
{
33
71
    TPM_RC              result = TPM_RC_SUCCESS;
34
71
    switch(HandleGetType(*handle))
35
71
    {
36
        // For handles associated with hierarchies, the entity is present
37
        // only if the associated enable is SET.
38
50
        case TPM_HT_PERMANENT:
39
50
            switch(*handle)
40
50
            {
41
7
                case TPM_RH_OWNER:
42
7
                    if(!gc.shEnable)
43
0
                        result = TPM_RC_HIERARCHY;
44
7
                    break;
45
#ifdef    VENDOR_PERMANENT
46
                 case VENDOR_PERMANENT:
47
#endif
48
12
                   case TPM_RH_ENDORSEMENT:
49
12
                       if(!gc.ehEnable)
50
0
                            result = TPM_RC_HIERARCHY;
51
12
                       break;
52
13
                   case TPM_RH_PLATFORM:
53
13
                       if(!g_phEnable)
54
0
                            result = TPM_RC_HIERARCHY;
55
13
                       break;
56
                       // null handle, PW session handle and lockout
57
                       // handle are always available
58
18
                   case TPM_RH_NULL:
59
18
                   case TPM_RS_PW:
60
18
                   case TPM_RH_LOCKOUT:
61
18
                       break;
62
0
                   default:
63
                       // handling of the manufacture_specific handles
64
0
                       if(      ((TPM_RH)*handle >= TPM_RH_FIRST)
65
0
                            && ((TPM_RH)*handle <= TPM_RH_LAST))
66
                            // use the value that would have been returned from
67
                            // unmarshaling if it did the handle filtering
68
0
                                result = TPM_RC_VALUE;
69
0
                       else
70
0
                            pAssert(FALSE);
71
0
                       break;
72
50
            }
73
50
            break;
74
50
        case TPM_HT_TRANSIENT:
75
            // For a transient object, check if the handle is associated
76
            // with a loaded object.
77
0
            if(!ObjectIsPresent(*handle))
78
0
                 result = TPM_RC_REFERENCE_H0;
79
0
            break;
80
0
        case TPM_HT_PERSISTENT:
81
            // Persistent object
82
            // Copy the persistent object to RAM and replace the handle with the
83
            // handle of the assigned slot. A TPM_RC_OBJECT_MEMORY,
84
            // TPM_RC_HIERARCHY or TPM_RC_REFERENCE_H0 error may be returned by
85
            // ObjectLoadEvict()
86
0
            result = ObjectLoadEvict(handle, commandCode);
87
0
            break;
88
0
        case TPM_HT_HMAC_SESSION:
89
            // For an HMAC session, see if the session is loaded
90
            // and if the session in the session slot is actually
91
            // an HMAC session.
92
0
            if(SessionIsLoaded(*handle))
93
0
            {
94
0
                 SESSION             *session;
95
0
                 session = SessionGet(*handle);
96
                 // Check if the session is a HMAC session
97
0
                 if(session->attributes.isPolicy == SET)
98
0
                     result = TPM_RC_HANDLE;
99
0
            }
100
0
            else
101
0
                 result = TPM_RC_REFERENCE_H0;
102
0
            break;
103
0
        case TPM_HT_POLICY_SESSION:
104
            // For a policy session, see if the session is loaded
105
            // and if the session in the session slot is actually
106
            // a policy session.
107
0
            if(SessionIsLoaded(*handle))
108
0
            {
109
0
                 SESSION             *session;
110
0
                 session = SessionGet(*handle);
111
                 // Check if the session is a policy session
112
0
                 if(session->attributes.isPolicy == CLEAR)
113
0
                     result = TPM_RC_HANDLE;
114
0
            }
115
0
            else
116
0
                 result = TPM_RC_REFERENCE_H0;
117
0
            break;
118
1
        case TPM_HT_NV_INDEX:
119
            // For an NV Index, use the platform-specific routine
120
            // to search the IN Index space.
121
1
            result = NvIndexIsAccessible(*handle, commandCode);
122
1
            break;
123
20
        case TPM_HT_PCR:
124
            // Any PCR handle that is unmarshaled successfully referenced
125
            // a PCR that is defined.
126
20
            break;
127
0
        default:
128
            // Any other handle type is a defect in the unmarshaling code.
129
0
            pAssert(FALSE);
130
0
            break;
131
71
   }
132
71
   return result;
133
71
}
134
//
135
//
136
//
137
//           EntityGetAuthValue()
138
//
139
//      This function is used to access the authValue associated with a handle. This function assumes that the
140
//      handle references an entity that is accessible and the handle is not for a persistent objects. That is
141
//      EntityGetLoadStatus() should have been called. Also, the accessibility of the authValue should have been
142
//      verified by IsAuthValueAvailable().
143
//      This function copies the authorization value of the entity to auth.
144
//      Return value is the number of octets copied to auth.
145
//
146
UINT16
147
EntityGetAuthValue(
148
    TPMI_DH_ENTITY       handle,             // IN: handle of entity
149
    AUTH_VALUE          *auth                // OUT: authValue of the entity
150
    )
151
48
{
152
48
    TPM2B_AUTH           authValue = {};
153
48
   switch(HandleGetType(handle))
154
48
   {
155
32
       case TPM_HT_PERMANENT:
156
32
           switch(handle)
157
32
           {
158
6
               case TPM_RH_OWNER:
159
                   // ownerAuth for TPM_RH_OWNER
160
6
                   authValue = gp.ownerAuth;
161
6
                   break;
162
6
               case TPM_RH_ENDORSEMENT:
163
                   // endorsementAuth for TPM_RH_ENDORSEMENT
164
6
                   authValue = gp.endorsementAuth;
165
6
                   break;
166
8
               case TPM_RH_PLATFORM:
167
                   // platformAuth for TPM_RH_PLATFORM
168
8
                   authValue = gc.platformAuth;
169
8
                   break;
170
0
               case TPM_RH_LOCKOUT:
171
                   // lockoutAuth for TPM_RH_LOCKOUT
172
0
                   authValue = gp.lockoutAuth;
173
0
                   break;
174
12
               case TPM_RH_NULL:
175
                   // nullAuth for TPM_RH_NULL. Return 0 directly here
176
12
                   return 0;
177
0
                   break;
178
#ifdef VENDOR_PERMANENT
179
               case VENDOR_PERMANENT:
180
                   // vendor auth value
181
                   authValue = g_platformUniqueDetails;
182
#endif
183
0
               default:
184
                   // If any other permanent handle is present it is
185
                   // a code defect.
186
0
                   pAssert(FALSE);
187
0
                   break;
188
32
           }
189
20
           break;
190
20
       case TPM_HT_TRANSIENT:
191
           // authValue for an object
192
           // A persistent object would have been copied into RAM
193
           // and would have an transient object handle here.
194
0
           {
195
0
               OBJECT          *object;
196
0
               object = ObjectGet(handle);
197
               // special handling if this is a sequence object
198
0
               if(ObjectIsSequence(object))
199
0
                   {
200
0
                       authValue = ((HASH_OBJECT *)object)->auth;
201
0
                   }
202
0
                   else
203
0
                   {
204
                       // Auth value is available only when the private portion of
205
                       // the object is loaded. The check should be made before
206
                       // this function is called
207
0
                       pAssert(object->attributes.publicOnly == CLEAR);
208
0
                       authValue = object->sensitive.authValue;
209
0
                   }
210
0
             }
211
0
             break;
212
0
         case TPM_HT_NV_INDEX:
213
             // authValue for an NV index
214
0
             {
215
0
                  NV_INDEX        nvIndex;
216
0
                  NvGetIndexInfo(handle, &nvIndex);
217
0
                  authValue = nvIndex.authValue;
218
0
             }
219
0
             break;
220
16
         case TPM_HT_PCR:
221
             // authValue for PCR
222
16
             PCRGetAuthValue(handle, &authValue);
223
16
             break;
224
0
         default:
225
             // If any other handle type is present here, then there is a defect
226
             // in the unmarshaling code.
227
0
             pAssert(FALSE);
228
0
             break;
229
48
    }
230
    // Copy the authValue
231
36
    pAssert(authValue.t.size <= sizeof(authValue.t.buffer));
232
36
    MemoryCopy(auth, authValue.t.buffer, authValue.t.size, sizeof(TPMU_HA));
233
36
    return authValue.t.size;
234
48
}
235
//
236
//
237
//           EntityGetAuthPolicy()
238
//
239
//      This function is used to access the authPolicy associated with a handle. This function assumes that the
240
//      handle references an entity that is accessible and the handle is not for a persistent objects. That is
241
//      EntityGetLoadStatus() should have been called. Also, the accessibility of the authPolicy should have
242
//      been verified by IsAuthPolicyAvailable().
243
//      This function copies the authorization policy of the entity to authPolicy.
244
//      The return value is the hash algorithm for the policy.
245
//
246
TPMI_ALG_HASH
247
EntityGetAuthPolicy(
248
    TPMI_DH_ENTITY       handle,             // IN: handle of entity
249
    TPM2B_DIGEST        *authPolicy          // OUT: authPolicy of the entity
250
    )
251
0
{
252
0
    TPMI_ALG_HASH            hashAlg = TPM_ALG_NULL;
253
0
    switch(HandleGetType(handle))
254
0
    {
255
0
        case TPM_HT_PERMANENT:
256
0
            switch(handle)
257
0
            {
258
0
                case TPM_RH_OWNER:
259
//
260
                      // ownerPolicy for TPM_RH_OWNER
261
0
                      *authPolicy = gp.ownerPolicy;
262
0
                      hashAlg = gp.ownerAlg;
263
0
                      break;
264
0
                  case TPM_RH_ENDORSEMENT:
265
                      // endorsementPolicy for TPM_RH_ENDORSEMENT
266
0
                      *authPolicy = gp.endorsementPolicy;
267
0
                      hashAlg = gp.endorsementAlg;
268
0
                      break;
269
0
                  case TPM_RH_PLATFORM:
270
                      // platformPolicy for TPM_RH_PLATFORM
271
0
                      *authPolicy = gc.platformPolicy;
272
0
                      hashAlg = gc.platformAlg;
273
0
                      break;
274
0
                  case TPM_RH_LOCKOUT:
275
                      // lockoutPolicy for TPM_RH_LOCKOUT
276
0
                      *authPolicy = gp.lockoutPolicy;
277
0
                      hashAlg = gp.lockoutAlg;
278
0
                      break;
279
0
                  default:
280
                      // If any other permanent handle is present it is
281
                      // a code defect.
282
0
                      pAssert(FALSE);
283
0
                      break;
284
0
             }
285
0
             break;
286
0
         case TPM_HT_TRANSIENT:
287
             // authPolicy for an object
288
0
             {
289
0
                  OBJECT *object = ObjectGet(handle);
290
0
                  *authPolicy = object->publicArea.authPolicy;
291
0
                  hashAlg = object->publicArea.nameAlg;
292
0
             }
293
0
             break;
294
0
         case TPM_HT_NV_INDEX:
295
             // authPolicy for a NV index
296
0
             {
297
0
                  NV_INDEX        nvIndex;
298
0
                  NvGetIndexInfo(handle, &nvIndex);
299
0
                  *authPolicy = nvIndex.publicArea.authPolicy;
300
0
                  hashAlg = nvIndex.publicArea.nameAlg;
301
0
             }
302
0
             break;
303
0
         case TPM_HT_PCR:
304
             // authPolicy for a PCR
305
0
             hashAlg = PCRGetAuthPolicy(handle, authPolicy);
306
0
             break;
307
0
         default:
308
             // If any other handle type is present it is a code defect.
309
0
             pAssert(FALSE);
310
0
             break;
311
0
   }
312
0
   return hashAlg;
313
0
}
314
//
315
//
316
//           EntityGetName()
317
//
318
//      This function returns the Name associated with a handle. It will set name to the Name and return the size
319
//      of the Name string.
320
//
321
UINT16
322
EntityGetName(
323
   TPMI_DH_ENTITY       handle,           // IN: handle of entity
324
   NAME                *name              // OUT: name of entity
325
    )
326
0
{
327
0
    UINT16              nameSize;
328
0
    INT32 bufferSize = sizeof(TPM_HANDLE);
329
0
    switch(HandleGetType(handle))
330
0
    {
331
0
        case TPM_HT_TRANSIENT:
332
            // Name for an object
333
0
            nameSize = ObjectGetName(handle, name);
334
0
            break;
335
0
        case TPM_HT_NV_INDEX:
336
            // Name for a NV index
337
0
            nameSize = NvGetName(handle, name);
338
0
            break;
339
0
        default:
340
            // For all other types, the handle is the Name
341
0
            nameSize = TPM_HANDLE_Marshal(&handle, (BYTE **)&name, &bufferSize);
342
0
            break;
343
0
    }
344
0
    return nameSize;
345
0
}
346
//
347
//
348
//           EntityGetHierarchy()
349
//
350
//      This function returns the hierarchy handle associated with an entity.
351
//      a) A handle that is a hierarchy handle is associated with itself.
352
//      b) An NV index belongs to TPM_RH_PLATFORM if TPMA_NV_PLATFORMCREATE, is SET,
353
//         otherwise it belongs to TPM_RH_OWNER
354
//      c) An object handle belongs to its hierarchy. All other handles belong to the platform hierarchy. or an NV
355
//         Index.
356
//
357
TPMI_RH_HIERARCHY
358
EntityGetHierarchy(
359
    TPMI_DH_ENTITY       handle             // IN :handle of entity
360
    )
361
4
{
362
4
    TPMI_RH_HIERARCHY             hierarcy = TPM_RH_NULL;
363
4
    switch(HandleGetType(handle))
364
4
    {
365
4
        case TPM_HT_PERMANENT:
366
            // hierarchy for a permanent handle
367
4
            switch(handle)
368
4
            {
369
0
                case TPM_RH_PLATFORM:
370
3
                case TPM_RH_ENDORSEMENT:
371
4
                case TPM_RH_NULL:
372
4
                    hierarcy = handle;
373
4
                    break;
374
                // all other permanent handles are associated with the owner
375
                // hierarchy. (should only be TPM_RH_OWNER and TPM_RH_LOCKOUT)
376
0
                default:
377
0
                    hierarcy = TPM_RH_OWNER;
378
0
                    break;
379
4
            }
380
4
            break;
381
4
        case TPM_HT_NV_INDEX:
382
            // hierarchy for NV index
383
0
            {
384
0
                NV_INDEX        nvIndex;
385
0
                NvGetIndexInfo(handle, &nvIndex);
386
                // If only the platform can delete the index, then it is
387
                  // considered to be in the platform hierarchy, otherwise it
388
                  // is in the owner hierarchy.
389
0
                  if(nvIndex.publicArea.attributes.TPMA_NV_PLATFORMCREATE == SET)
390
0
                      hierarcy = TPM_RH_PLATFORM;
391
0
                  else
392
0
                      hierarcy = TPM_RH_OWNER;
393
0
             }
394
0
             break;
395
0
         case TPM_HT_TRANSIENT:
396
             // hierarchy for an object
397
0
             {
398
0
                 OBJECT          *object;
399
0
                 object = ObjectGet(handle);
400
0
                 if(object->attributes.ppsHierarchy)
401
0
                 {
402
0
                     hierarcy = TPM_RH_PLATFORM;
403
0
                 }
404
0
                 else if(object->attributes.epsHierarchy)
405
0
                 {
406
0
                     hierarcy = TPM_RH_ENDORSEMENT;
407
0
                 }
408
0
                 else if(object->attributes.spsHierarchy)
409
0
                 {
410
0
                     hierarcy = TPM_RH_OWNER;
411
0
                 }
412
0
             }
413
0
             break;
414
0
         case TPM_HT_PCR:
415
0
             hierarcy = TPM_RH_OWNER;
416
0
             break;
417
0
         default:
418
0
             pAssert(0);
419
0
             break;
420
4
     }
421
     // this is unreachable but it provides a return value for the default
422
     // case which makes the complier happy
423
4
     return hierarcy;
424
4
}