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
EntityGetLoadStatus(TPM_HANDLE * handle,TPM_CC commandCode)28 EntityGetLoadStatus(
29     TPM_HANDLE          *handle,              // IN/OUT: handle of the entity
30     TPM_CC               commandCode          // IN: the commmandCode
31     )
32 {
33     TPM_RC              result = TPM_RC_SUCCESS;
34     switch(HandleGetType(*handle))
35     {
36         // For handles associated with hierarchies, the entity is present
37         // only if the associated enable is SET.
38         case TPM_HT_PERMANENT:
39             switch(*handle)
40             {
41                 case TPM_RH_OWNER:
42                     if(!gc.shEnable)
43                         result = TPM_RC_HIERARCHY;
44                     break;
45 #ifdef    VENDOR_PERMANENT
46                  case VENDOR_PERMANENT:
47 #endif
48                    case TPM_RH_ENDORSEMENT:
49                        if(!gc.ehEnable)
50                             result = TPM_RC_HIERARCHY;
51                        break;
52                    case TPM_RH_PLATFORM:
53                        if(!g_phEnable)
54                             result = TPM_RC_HIERARCHY;
55                        break;
56                        // null handle, PW session handle and lockout
57                        // handle are always available
58                    case TPM_RH_NULL:
59                    case TPM_RS_PW:
60                    case TPM_RH_LOCKOUT:
61                        break;
62                    default:
63                        // handling of the manufacture_specific handles
64                        if(      ((TPM_RH)*handle >= TPM_RH_FIRST)
65                             && ((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                                 result = TPM_RC_VALUE;
69                        else
70                             pAssert(FALSE);
71                        break;
72             }
73             break;
74         case TPM_HT_TRANSIENT:
75             // For a transient object, check if the handle is associated
76             // with a loaded object.
77             if(!ObjectIsPresent(*handle))
78                  result = TPM_RC_REFERENCE_H0;
79             break;
80         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             result = ObjectLoadEvict(handle, commandCode);
87             break;
88         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             if(SessionIsLoaded(*handle))
93             {
94                  SESSION             *session;
95                  session = SessionGet(*handle);
96                  // Check if the session is a HMAC session
97                  if(session->attributes.isPolicy == SET)
98                      result = TPM_RC_HANDLE;
99             }
100             else
101                  result = TPM_RC_REFERENCE_H0;
102             break;
103         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             if(SessionIsLoaded(*handle))
108             {
109                  SESSION             *session;
110                  session = SessionGet(*handle);
111                  // Check if the session is a policy session
112                  if(session->attributes.isPolicy == CLEAR)
113                      result = TPM_RC_HANDLE;
114             }
115             else
116                  result = TPM_RC_REFERENCE_H0;
117             break;
118         case TPM_HT_NV_INDEX:
119             // For an NV Index, use the platform-specific routine
120             // to search the IN Index space.
121             result = NvIndexIsAccessible(*handle, commandCode);
122             break;
123         case TPM_HT_PCR:
124             // Any PCR handle that is unmarshaled successfully referenced
125             // a PCR that is defined.
126             break;
127         default:
128             // Any other handle type is a defect in the unmarshaling code.
129             pAssert(FALSE);
130             break;
131    }
132    return result;
133 }
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
EntityGetAuthValue(TPMI_DH_ENTITY handle,AUTH_VALUE * auth)147 EntityGetAuthValue(
148     TPMI_DH_ENTITY       handle,             // IN: handle of entity
149     AUTH_VALUE          *auth                // OUT: authValue of the entity
150     )
151 {
152     TPM2B_AUTH           authValue = {};
153    switch(HandleGetType(handle))
154    {
155        case TPM_HT_PERMANENT:
156            switch(handle)
157            {
158                case TPM_RH_OWNER:
159                    // ownerAuth for TPM_RH_OWNER
160                    authValue = gp.ownerAuth;
161                    break;
162                case TPM_RH_ENDORSEMENT:
163                    // endorsementAuth for TPM_RH_ENDORSEMENT
164                    authValue = gp.endorsementAuth;
165                    break;
166                case TPM_RH_PLATFORM:
167                    // platformAuth for TPM_RH_PLATFORM
168                    authValue = gc.platformAuth;
169                    break;
170                case TPM_RH_LOCKOUT:
171                    // lockoutAuth for TPM_RH_LOCKOUT
172                    authValue = gp.lockoutAuth;
173                    break;
174                case TPM_RH_NULL:
175                    // nullAuth for TPM_RH_NULL. Return 0 directly here
176                    return 0;
177                    break;
178 #ifdef VENDOR_PERMANENT
179                case VENDOR_PERMANENT:
180                    // vendor auth value
181                    authValue = g_platformUniqueDetails;
182 #endif
183                default:
184                    // If any other permanent handle is present it is
185                    // a code defect.
186                    pAssert(FALSE);
187                    break;
188            }
189            break;
190        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            {
195                OBJECT          *object;
196                object = ObjectGet(handle);
197                // special handling if this is a sequence object
198                if(ObjectIsSequence(object))
199                    {
200                        authValue = ((HASH_OBJECT *)object)->auth;
201                    }
202                    else
203                    {
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                        pAssert(object->attributes.publicOnly == CLEAR);
208                        authValue = object->sensitive.authValue;
209                    }
210              }
211              break;
212          case TPM_HT_NV_INDEX:
213              // authValue for an NV index
214              {
215                   NV_INDEX        nvIndex;
216                   NvGetIndexInfo(handle, &nvIndex);
217                   authValue = nvIndex.authValue;
218              }
219              break;
220          case TPM_HT_PCR:
221              // authValue for PCR
222              PCRGetAuthValue(handle, &authValue);
223              break;
224          default:
225              // If any other handle type is present here, then there is a defect
226              // in the unmarshaling code.
227              pAssert(FALSE);
228              break;
229     }
230     // Copy the authValue
231     pAssert(authValue.t.size <= sizeof(authValue.t.buffer));
232     MemoryCopy(auth, authValue.t.buffer, authValue.t.size, sizeof(TPMU_HA));
233     return authValue.t.size;
234 }
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
EntityGetAuthPolicy(TPMI_DH_ENTITY handle,TPM2B_DIGEST * authPolicy)247 EntityGetAuthPolicy(
248     TPMI_DH_ENTITY       handle,             // IN: handle of entity
249     TPM2B_DIGEST        *authPolicy          // OUT: authPolicy of the entity
250     )
251 {
252     TPMI_ALG_HASH            hashAlg = TPM_ALG_NULL;
253     switch(HandleGetType(handle))
254     {
255         case TPM_HT_PERMANENT:
256             switch(handle)
257             {
258                 case TPM_RH_OWNER:
259 //
260                       // ownerPolicy for TPM_RH_OWNER
261                       *authPolicy = gp.ownerPolicy;
262                       hashAlg = gp.ownerAlg;
263                       break;
264                   case TPM_RH_ENDORSEMENT:
265                       // endorsementPolicy for TPM_RH_ENDORSEMENT
266                       *authPolicy = gp.endorsementPolicy;
267                       hashAlg = gp.endorsementAlg;
268                       break;
269                   case TPM_RH_PLATFORM:
270                       // platformPolicy for TPM_RH_PLATFORM
271                       *authPolicy = gc.platformPolicy;
272                       hashAlg = gc.platformAlg;
273                       break;
274                   case TPM_RH_LOCKOUT:
275                       // lockoutPolicy for TPM_RH_LOCKOUT
276                       *authPolicy = gp.lockoutPolicy;
277                       hashAlg = gp.lockoutAlg;
278                       break;
279                   default:
280                       // If any other permanent handle is present it is
281                       // a code defect.
282                       pAssert(FALSE);
283                       break;
284              }
285              break;
286          case TPM_HT_TRANSIENT:
287              // authPolicy for an object
288              {
289                   OBJECT *object = ObjectGet(handle);
290                   *authPolicy = object->publicArea.authPolicy;
291                   hashAlg = object->publicArea.nameAlg;
292              }
293              break;
294          case TPM_HT_NV_INDEX:
295              // authPolicy for a NV index
296              {
297                   NV_INDEX        nvIndex;
298                   NvGetIndexInfo(handle, &nvIndex);
299                   *authPolicy = nvIndex.publicArea.authPolicy;
300                   hashAlg = nvIndex.publicArea.nameAlg;
301              }
302              break;
303          case TPM_HT_PCR:
304              // authPolicy for a PCR
305              hashAlg = PCRGetAuthPolicy(handle, authPolicy);
306              break;
307          default:
308              // If any other handle type is present it is a code defect.
309              pAssert(FALSE);
310              break;
311    }
312    return hashAlg;
313 }
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
EntityGetName(TPMI_DH_ENTITY handle,NAME * name)322 EntityGetName(
323    TPMI_DH_ENTITY       handle,           // IN: handle of entity
324    NAME                *name              // OUT: name of entity
325     )
326 {
327     UINT16              nameSize;
328     INT32 bufferSize = sizeof(TPM_HANDLE);
329     switch(HandleGetType(handle))
330     {
331         case TPM_HT_TRANSIENT:
332             // Name for an object
333             nameSize = ObjectGetName(handle, name);
334             break;
335         case TPM_HT_NV_INDEX:
336             // Name for a NV index
337             nameSize = NvGetName(handle, name);
338             break;
339         default:
340             // For all other types, the handle is the Name
341             nameSize = TPM_HANDLE_Marshal(&handle, (BYTE **)&name, &bufferSize);
342             break;
343     }
344     return nameSize;
345 }
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
EntityGetHierarchy(TPMI_DH_ENTITY handle)358 EntityGetHierarchy(
359     TPMI_DH_ENTITY       handle             // IN :handle of entity
360     )
361 {
362     TPMI_RH_HIERARCHY             hierarcy = TPM_RH_NULL;
363     switch(HandleGetType(handle))
364     {
365         case TPM_HT_PERMANENT:
366             // hierarchy for a permanent handle
367             switch(handle)
368             {
369                 case TPM_RH_PLATFORM:
370                 case TPM_RH_ENDORSEMENT:
371                 case TPM_RH_NULL:
372                     hierarcy = handle;
373                     break;
374                 // all other permanent handles are associated with the owner
375                 // hierarchy. (should only be TPM_RH_OWNER and TPM_RH_LOCKOUT)
376                 default:
377                     hierarcy = TPM_RH_OWNER;
378                     break;
379             }
380             break;
381         case TPM_HT_NV_INDEX:
382             // hierarchy for NV index
383             {
384                 NV_INDEX        nvIndex;
385                 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                   if(nvIndex.publicArea.attributes.TPMA_NV_PLATFORMCREATE == SET)
390                       hierarcy = TPM_RH_PLATFORM;
391                   else
392                       hierarcy = TPM_RH_OWNER;
393              }
394              break;
395          case TPM_HT_TRANSIENT:
396              // hierarchy for an object
397              {
398                  OBJECT          *object;
399                  object = ObjectGet(handle);
400                  if(object->attributes.ppsHierarchy)
401                  {
402                      hierarcy = TPM_RH_PLATFORM;
403                  }
404                  else if(object->attributes.epsHierarchy)
405                  {
406                      hierarcy = TPM_RH_ENDORSEMENT;
407                  }
408                  else if(object->attributes.spsHierarchy)
409                  {
410                      hierarcy = TPM_RH_OWNER;
411                  }
412              }
413              break;
414          case TPM_HT_PCR:
415              hierarcy = TPM_RH_OWNER;
416              break;
417          default:
418              pAssert(0);
419              break;
420      }
421      // this is unreachable but it provides a return value for the default
422      // case which makes the complier happy
423      return hierarcy;
424 }
425