Coverage Report

Created: 2026-09-03 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ibmswtpm2/src/Entity.c
Line
Count
Source
1
/********************************************************************************/
2
/*                    */
3
/*    Accessing properties for handles of various types   */
4
/*           Written by Ken Goldman       */
5
/*           IBM Thomas J. Watson Research Center     */
6
/*            $Id: Entity.c 1259 2018-07-10 19:11:09Z kgoldman $    */
7
/*                    */
8
/*  Licenses and Notices              */
9
/*                    */
10
/*  1. Copyright Licenses:              */
11
/*                    */
12
/*  - Trusted Computing Group (TCG) grants to the user of the source code in  */
13
/*    this specification (the "Source Code") a worldwide, irrevocable,    */
14
/*    nonexclusive, royalty free, copyright license to reproduce, create  */
15
/*    derivative works, distribute, display and perform the Source Code and */
16
/*    derivative works thereof, and to grant others the rights granted herein.  */
17
/*                    */
18
/*  - The TCG grants to the user of the other parts of the specification  */
19
/*    (other than the Source Code) the rights to reproduce, distribute,   */
20
/*    display, and perform the specification solely for the purpose of    */
21
/*    developing products based on such documents.        */
22
/*                    */
23
/*  2. Source Code Distribution Conditions:         */
24
/*                    */
25
/*  - Redistributions of Source Code must retain the above copyright licenses,  */
26
/*    this list of conditions and the following disclaimers.      */
27
/*                    */
28
/*  - Redistributions in binary form must reproduce the above copyright   */
29
/*    licenses, this list of conditions and the following disclaimers in the  */
30
/*    documentation and/or other materials provided with the distribution.  */
31
/*                    */
32
/*  3. Disclaimers:               */
33
/*                    */
34
/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
35
/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
36
/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
37
/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.   */
38
/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for    */
39
/*  information on specification licensing rights available through TCG   */
40
/*  membership agreements.              */
41
/*                    */
42
/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED   */
43
/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR   */
44
/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR    */
45
/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY    */
46
/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.   */
47
/*                    */
48
/*  - Without limitation, TCG and its members and licensors disclaim all  */
49
/*    liability, including liability for infringement of any proprietary  */
50
/*    rights, relating to use of information in this specification and to the */
51
/*    implementation of this specification, and TCG disclaims all liability for */
52
/*    cost of procurement of substitute goods or services, lost profits, loss   */
53
/*    of use, loss of data or any incidental, consequential, direct, indirect,  */
54
/*    or special damages, whether under contract, tort, warranty or otherwise,  */
55
/*    arising in any way out of use or reliance upon this specification or any  */
56
/*    information herein.             */
57
/*                    */
58
/*  (c) Copyright IBM Corp. and others, 2016 - 2018       */
59
/*                    */
60
/********************************************************************************/
61
62
/* 9.4 Entity.c */
63
/* 9.4.1 Description */
64
/* The functions in this file are used for accessing properties for handles of various
65
   types. Functions in other files require handles of a specific type but the functions in this file
66
   allow use of any handle type. */
67
/* 9.4.2 Includes */
68
#include "Tpm.h"
69
/* 9.4.3 Functions */
70
/* 9.4.3.1 EntityGetLoadStatus() */
71
/* This function will check that all the handles access loaded entities. */
72
/* Error Returns Meaning */
73
/* TPM_RC_HANDLE handle type does not match */
74
/* TPM_RC_REFERENCE_Hx() entity is not present */
75
/* TPM_RC_HIERARCHY entity belongs to a disabled hierarchy */
76
/* TPM_RC_OBJECT_MEMORY handle is an evict object but there is no space to load it to RAM */
77
TPM_RC
78
EntityGetLoadStatus(
79
        COMMAND         *command        // IN/OUT: command parsing structure
80
        )
81
2.44k
{
82
2.44k
    UINT32               i;
83
2.44k
    TPM_RC               result = TPM_RC_SUCCESS;
84
    //
85
2.44k
    for(i = 0; i < command->handleNum; i++)
86
0
  {
87
0
      TPM_HANDLE      handle = command->handles[i];
88
0
      switch(HandleGetType(handle))
89
0
    {
90
        // For handles associated with hierarchies, the entity is present
91
        // only if the associated enable is SET.
92
0
      case TPM_HT_PERMANENT:
93
0
        switch(handle)
94
0
      {
95
0
        case TPM_RH_OWNER:
96
0
          if(!gc.shEnable)
97
0
        result = TPM_RC_HIERARCHY;
98
0
          break;
99
#ifdef  VENDOR_PERMANENT
100
        case VENDOR_PERMANENT:
101
#endif
102
0
        case TPM_RH_ENDORSEMENT:
103
0
          if(!gc.ehEnable)
104
0
        result = TPM_RC_HIERARCHY;
105
0
          break;
106
0
        case TPM_RH_PLATFORM:
107
0
          if(!g_phEnable)
108
0
        result = TPM_RC_HIERARCHY;
109
0
          break;
110
          // null handle, PW session handle and lockout
111
          // handle are always available
112
0
        case TPM_RH_NULL:
113
0
        case TPM_RS_PW:
114
          // Need to be careful for lockout. Lockout is always available
115
          // for policy checks but not always available when authValue
116
          // is being checked.
117
0
        case TPM_RH_LOCKOUT:
118
0
          break;
119
0
        default:
120
          // handling of the manufacture_specific handles
121
0
          if(((TPM_RH)handle >= TPM_RH_AUTH_00)
122
0
             && ((TPM_RH)handle <= TPM_RH_AUTH_FF))
123
        // use the value that would have been returned from
124
        // unmarshaling if it did the handle filtering
125
0
        result = TPM_RC_VALUE;
126
0
          else
127
0
        FAIL(FATAL_ERROR_INTERNAL);
128
0
          break;
129
0
      }
130
0
        break;
131
0
      case TPM_HT_TRANSIENT:
132
        // For a transient object, check if the handle is associated
133
        // with a loaded object.
134
0
        if(!IsObjectPresent(handle))
135
0
      result = TPM_RC_REFERENCE_H0;
136
0
        break;
137
0
      case TPM_HT_PERSISTENT:
138
        // Persistent object
139
        // Copy the persistent object to RAM and replace the handle with the
140
        // handle of the assigned slot.  A TPM_RC_OBJECT_MEMORY,
141
        // TPM_RC_HIERARCHY or TPM_RC_REFERENCE_H0 error may be returned by
142
        // ObjectLoadEvict()
143
0
        result = ObjectLoadEvict(&command->handles[i], command->index);
144
0
        break;
145
0
      case TPM_HT_HMAC_SESSION:
146
        // For an HMAC session, see if the session is loaded
147
        // and if the session in the session slot is actually
148
        // an HMAC session.
149
0
        if(SessionIsLoaded(handle))
150
0
      {
151
0
          SESSION             *session;
152
0
          session = SessionGet(handle);
153
          // Check if the session is a HMAC session
154
0
          if(session->attributes.isPolicy == SET)
155
0
        result = TPM_RC_HANDLE;
156
0
      }
157
0
        else
158
0
      result = TPM_RC_REFERENCE_H0;
159
0
        break;
160
0
      case TPM_HT_POLICY_SESSION:
161
        // For a policy session, see if the session is loaded
162
        // and if the session in the session slot is actually
163
        // a policy session.
164
0
        if(SessionIsLoaded(handle))
165
0
      {
166
0
          SESSION             *session;
167
0
          session = SessionGet(handle);
168
          // Check if the session is a policy session
169
0
          if(session->attributes.isPolicy == CLEAR)
170
0
        result = TPM_RC_HANDLE;
171
0
      }
172
0
        else
173
0
      result = TPM_RC_REFERENCE_H0;
174
0
        break;
175
0
      case TPM_HT_NV_INDEX:
176
        // For an NV Index, use the TPM-specific routine
177
        // to search the IN Index space.
178
0
        result = NvIndexIsAccessible(handle);
179
0
        break;
180
0
      case TPM_HT_PCR:
181
        // Any PCR handle that is unmarshaled successfully referenced
182
        // a PCR that is defined.
183
0
        break;
184
#if CC_AC_Send
185
      case TPM_HT_AC:
186
        // Use the TPM-specific routine to search for the AC
187
        result = AcIsAccessible(handle);
188
        break;
189
#endif
190
0
      default:
191
        // Any other handle type is a defect in the unmarshaling code.
192
0
        FAIL(FATAL_ERROR_INTERNAL);
193
0
        break;
194
0
    }
195
0
      if(result != TPM_RC_SUCCESS)
196
0
    {
197
0
        if(result == TPM_RC_REFERENCE_H0)
198
0
      result = result + i;
199
0
        else
200
0
      result = RcSafeAddToResult(result, TPM_RC_H + g_rcIndex[i]);
201
0
        break;
202
0
    }
203
0
  }
204
2.44k
    return result;
205
2.44k
}
206
/* 9.4.3.2 EntityGetAuthValue() */
207
/* This function is used to access the authValue associated with a handle. This function assumes
208
   that the handle references an entity that is accessible and the handle is not for a persistent
209
   objects. That is EntityGetLoadStatus() should have been called. Also, the accessibility of the
210
   authValue should have been verified by IsAuthValueAvailable(). */
211
/* This function copies the authorization value of the entity to auth. */
212
/* Return Values Meaning */
213
/* count number of bytes in the authValue with zeros stripped */
214
UINT16
215
EntityGetAuthValue(
216
       TPMI_DH_ENTITY   handle,        // IN: handle of entity
217
       TPM2B_AUTH      *auth           // OUT: authValue of the entity
218
       )
219
0
{
220
0
    TPM2B_AUTH      *pAuth = NULL;
221
0
    auth->t.size = 0;
222
0
    switch(HandleGetType(handle))
223
0
  {
224
0
    case TPM_HT_PERMANENT:
225
0
        {
226
0
      switch(handle)
227
0
          {
228
0
      case TPM_RH_OWNER:
229
        // ownerAuth for TPM_RH_OWNER
230
0
        pAuth = &gp.ownerAuth;
231
0
        break;
232
0
      case TPM_RH_ENDORSEMENT:
233
        // endorsementAuth for TPM_RH_ENDORSEMENT
234
0
        pAuth = &gp.endorsementAuth;
235
0
        break;
236
0
      case TPM_RH_PLATFORM:
237
        // platformAuth for TPM_RH_PLATFORM
238
0
        pAuth = &gc.platformAuth;
239
0
        break;
240
0
      case TPM_RH_LOCKOUT:
241
        // lockoutAuth for TPM_RH_LOCKOUT
242
0
        pAuth = &gp.lockoutAuth;
243
0
        break;
244
0
      case TPM_RH_NULL:
245
        // nullAuth for TPM_RH_NULL. Return 0 directly here
246
0
        return 0;
247
0
        break;
248
#ifdef  VENDOR_PERMANENT
249
      case VENDOR_PERMANENT:
250
        // vendor authorization value
251
        pAauth = &g_platformUniqueDetails;
252
#endif
253
0
      default:
254
        // If any other permanent handle is present it is
255
        // a code defect.
256
0
        FAIL(FATAL_ERROR_INTERNAL);
257
0
        break;
258
0
          }
259
0
      break;
260
0
        }
261
0
    case TPM_HT_TRANSIENT:
262
      // authValue for an object
263
      // A persistent object would have been copied into RAM
264
      // and would have an transient object handle here.
265
0
        {
266
0
      OBJECT          *object;
267
0
      object = HandleToObject(handle);
268
      // special handling if this is a sequence object
269
0
      if(ObjectIsSequence(object))
270
0
          {
271
0
        pAuth = &((HASH_OBJECT *)object)->auth;
272
0
          }
273
0
      else
274
0
          {
275
        // Authorization is available only when the private portion of
276
        // the object is loaded.  The check should be made before
277
        // this function is called
278
0
        pAssert(object->attributes.publicOnly == CLEAR);
279
0
        pAuth = &object->sensitive.authValue;
280
0
          }
281
0
        }
282
0
        break;
283
0
    case TPM_HT_NV_INDEX:
284
      // authValue for an NV index
285
0
        {
286
0
      NV_INDEX        *nvIndex = NvGetIndexInfo(handle, NULL);
287
0
      pAssert(nvIndex != NULL);
288
0
      pAuth = &nvIndex->authValue;
289
0
        }
290
0
        break;
291
0
    case TPM_HT_PCR:
292
      // authValue for PCR
293
0
      pAuth = PCRGetAuthValue(handle);
294
0
      break;
295
0
    default:
296
      // If any other handle type is present here, then there is a defect
297
      // in the unmarshaling code.
298
0
      FAIL(FATAL_ERROR_INTERNAL);
299
0
      break;
300
0
  }
301
    // Copy the authValue
302
0
    MemoryCopy2B(&auth->b, &pAuth->b, sizeof(auth->t.buffer));
303
0
    MemoryRemoveTrailingZeros(auth);
304
0
    return auth->t.size;
305
0
}
306
/* 9.4.3.3 EntityGetAuthPolicy() */
307
/* This function is used to access the authPolicy associated with a handle. This function assumes
308
   that the handle references an entity that is accessible and the handle is not for a persistent
309
   objects. That is EntityGetLoadStatus() should have been called. Also, the accessibility of the
310
   authPolicy should have been verified by IsAuthPolicyAvailable(). */
311
/* This function copies the authorization policy of the entity to authPolicy. */
312
/* The return value is the hash algorithm for the policy. */
313
TPMI_ALG_HASH
314
EntityGetAuthPolicy(
315
        TPMI_DH_ENTITY   handle,        // IN: handle of entity
316
        TPM2B_DIGEST    *authPolicy     // OUT: authPolicy of the entity
317
        )
318
0
{
319
0
    TPMI_ALG_HASH       hashAlg = TPM_ALG_NULL;
320
0
    authPolicy->t.size = 0;
321
0
    switch(HandleGetType(handle))
322
0
  {
323
0
    case TPM_HT_PERMANENT:
324
0
      switch(handle)
325
0
    {
326
0
      case TPM_RH_OWNER:
327
        // ownerPolicy for TPM_RH_OWNER
328
0
        *authPolicy = gp.ownerPolicy;
329
0
        hashAlg = gp.ownerAlg;
330
0
        break;
331
0
      case TPM_RH_ENDORSEMENT:
332
        // endorsementPolicy for TPM_RH_ENDORSEMENT
333
0
        *authPolicy = gp.endorsementPolicy;
334
0
        hashAlg = gp.endorsementAlg;
335
0
        break;
336
0
      case TPM_RH_PLATFORM:
337
        // platformPolicy for TPM_RH_PLATFORM
338
0
        *authPolicy = gc.platformPolicy;
339
0
        hashAlg = gc.platformAlg;
340
0
        break;
341
0
      case TPM_RH_LOCKOUT:
342
        // lockoutPolicy for TPM_RH_LOCKOUT
343
0
        *authPolicy = gp.lockoutPolicy;
344
0
        hashAlg = gp.lockoutAlg;
345
0
        break;
346
0
      default:
347
0
        return TPM_ALG_ERROR;
348
0
        break;
349
0
    }
350
0
      break;
351
0
    case TPM_HT_TRANSIENT:
352
      // authPolicy for an object
353
0
        {
354
0
      OBJECT *object = HandleToObject(handle);
355
0
      *authPolicy = object->publicArea.authPolicy;
356
0
      hashAlg = object->publicArea.nameAlg;
357
0
        }
358
0
        break;
359
0
    case TPM_HT_NV_INDEX:
360
      // authPolicy for a NV index
361
0
        {
362
0
      NV_INDEX        *nvIndex = NvGetIndexInfo(handle, NULL);
363
0
      pAssert(nvIndex != 0);
364
0
      *authPolicy = nvIndex->publicArea.authPolicy;
365
0
      hashAlg = nvIndex->publicArea.nameAlg;
366
0
        }
367
0
        break;
368
0
    case TPM_HT_PCR:
369
      // authPolicy for a PCR
370
0
      hashAlg = PCRGetAuthPolicy(handle, authPolicy);
371
0
      break;
372
0
    default:
373
      // If any other handle type is present it is a code defect.
374
0
      FAIL(FATAL_ERROR_INTERNAL);
375
0
      break;
376
0
  }
377
0
    return hashAlg;
378
0
}
379
/* 9.4.3.4 EntityGetName() */
380
/* This function returns the Name associated with a handle. */
381
TPM2B_NAME *
382
EntityGetName(
383
        TPMI_DH_ENTITY   handle,        // IN: handle of entity
384
        TPM2B_NAME      *name           // OUT: name of entity
385
        )
386
0
{
387
0
    switch(HandleGetType(handle))
388
0
  {
389
0
    case TPM_HT_TRANSIENT:
390
0
        {
391
      // Name for an object
392
0
      OBJECT      *object = HandleToObject(handle);
393
      // an object with no nameAlg has no name
394
0
      if(object->publicArea.nameAlg == TPM_ALG_NULL)
395
0
          name->b.size = 0;
396
0
      else
397
0
          *name = object->name;
398
0
      break;
399
0
        }
400
0
    case TPM_HT_NV_INDEX:
401
      // Name for a NV index
402
0
      NvGetNameByIndexHandle(handle, name);
403
0
      break;
404
0
    default:
405
      // For all other types, the handle is the Name
406
0
      name->t.size = sizeof(TPM_HANDLE);
407
0
      UINT32_TO_BYTE_ARRAY(handle, name->t.name);
408
0
      break;
409
0
  }
410
0
    return name;
411
0
}
412
/* 9.4.3.5 EntityGetHierarchy() */
413
/* This function returns the hierarchy handle associated with an entity. */
414
/* a) A handle that is a hierarchy handle is associated with itself. */
415
/* b) An NV index belongs to TPM_RH_PLATFORM if TPMA_NV_PLATFORMCREATE, is SET, otherwise it belongs
416
   to TPM_RH_OWNER */
417
/* c) An object handle belongs to its hierarchy. All other handles belong to the platform
418
   hierarchy. or an NV Index. */
419
TPMI_RH_HIERARCHY
420
EntityGetHierarchy(
421
       TPMI_DH_ENTITY   handle         // IN :handle of entity
422
       )
423
0
{
424
0
    TPMI_RH_HIERARCHY       hierarchy = TPM_RH_NULL;
425
0
    switch(HandleGetType(handle))
426
0
  {
427
0
    case TPM_HT_PERMANENT:
428
      // hierarchy for a permanent handle
429
0
      switch(handle)
430
0
    {
431
0
      case TPM_RH_PLATFORM:
432
0
      case TPM_RH_ENDORSEMENT:
433
0
      case TPM_RH_NULL:
434
0
        hierarchy = handle;
435
0
        break;
436
        // all other permanent handles are associated with the owner
437
        // hierarchy. (should only be TPM_RH_OWNER and TPM_RH_LOCKOUT)
438
0
      default:
439
0
        hierarchy = TPM_RH_OWNER;
440
0
        break;
441
0
    }
442
0
      break;
443
0
    case TPM_HT_NV_INDEX:
444
      // hierarchy for NV index
445
0
        {
446
0
      NV_INDEX        *nvIndex = NvGetIndexInfo(handle, NULL);
447
0
      pAssert(nvIndex != NULL);
448
      // If only the platform can delete the index, then it is
449
      // considered to be in the platform hierarchy, otherwise it
450
      // is in the owner hierarchy.
451
0
      if(IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV,
452
0
          PLATFORMCREATE))
453
0
          hierarchy = TPM_RH_PLATFORM;
454
0
      else
455
0
          hierarchy = TPM_RH_OWNER;
456
0
        }
457
0
        break;
458
0
    case TPM_HT_TRANSIENT:
459
      // hierarchy for an object
460
0
        {
461
0
      OBJECT          *object;
462
0
      object = HandleToObject(handle);
463
0
      if(object->attributes.ppsHierarchy)
464
0
          {
465
0
        hierarchy = TPM_RH_PLATFORM;
466
0
          }
467
0
      else if(object->attributes.epsHierarchy)
468
0
          {
469
0
        hierarchy = TPM_RH_ENDORSEMENT;
470
0
          }
471
0
      else if(object->attributes.spsHierarchy)
472
0
          {
473
0
        hierarchy = TPM_RH_OWNER;
474
0
          }
475
0
        }
476
0
        break;
477
0
    case TPM_HT_PCR:
478
0
      hierarchy = TPM_RH_OWNER;
479
0
      break;
480
0
    default:
481
0
      FAIL(FATAL_ERROR_INTERNAL);
482
0
      break;
483
0
  }
484
    // this is unreachable but it provides a return value for the default
485
    // case which makes the complier happy
486
0
    return hierarchy;
487
0
}