xref: /aosp_15_r20/external/ms-tpm-20-ref/TPMCmd/tpm/src/subsystem/Object.c (revision 5c591343844d1f9da7da26467c4bf7efc8a7a413)
1*5c591343SA. Cody Schuffelen /* Microsoft Reference Implementation for TPM 2.0
2*5c591343SA. Cody Schuffelen  *
3*5c591343SA. Cody Schuffelen  *  The copyright in this software is being made available under the BSD License,
4*5c591343SA. Cody Schuffelen  *  included below. This software may be subject to other third party and
5*5c591343SA. Cody Schuffelen  *  contributor rights, including patent rights, and no such rights are granted
6*5c591343SA. Cody Schuffelen  *  under this license.
7*5c591343SA. Cody Schuffelen  *
8*5c591343SA. Cody Schuffelen  *  Copyright (c) Microsoft Corporation
9*5c591343SA. Cody Schuffelen  *
10*5c591343SA. Cody Schuffelen  *  All rights reserved.
11*5c591343SA. Cody Schuffelen  *
12*5c591343SA. Cody Schuffelen  *  BSD License
13*5c591343SA. Cody Schuffelen  *
14*5c591343SA. Cody Schuffelen  *  Redistribution and use in source and binary forms, with or without modification,
15*5c591343SA. Cody Schuffelen  *  are permitted provided that the following conditions are met:
16*5c591343SA. Cody Schuffelen  *
17*5c591343SA. Cody Schuffelen  *  Redistributions of source code must retain the above copyright notice, this list
18*5c591343SA. Cody Schuffelen  *  of conditions and the following disclaimer.
19*5c591343SA. Cody Schuffelen  *
20*5c591343SA. Cody Schuffelen  *  Redistributions in binary form must reproduce the above copyright notice, this
21*5c591343SA. Cody Schuffelen  *  list of conditions and the following disclaimer in the documentation and/or
22*5c591343SA. Cody Schuffelen  *  other materials provided with the distribution.
23*5c591343SA. Cody Schuffelen  *
24*5c591343SA. Cody Schuffelen  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
25*5c591343SA. Cody Schuffelen  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26*5c591343SA. Cody Schuffelen  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27*5c591343SA. Cody Schuffelen  *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28*5c591343SA. Cody Schuffelen  *  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29*5c591343SA. Cody Schuffelen  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30*5c591343SA. Cody Schuffelen  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31*5c591343SA. Cody Schuffelen  *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32*5c591343SA. Cody Schuffelen  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33*5c591343SA. Cody Schuffelen  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*5c591343SA. Cody Schuffelen  */
35*5c591343SA. Cody Schuffelen //** Introduction
36*5c591343SA. Cody Schuffelen // This file contains the functions that manage the object store of the TPM.
37*5c591343SA. Cody Schuffelen 
38*5c591343SA. Cody Schuffelen //** Includes and Data Definitions
39*5c591343SA. Cody Schuffelen #define OBJECT_C
40*5c591343SA. Cody Schuffelen 
41*5c591343SA. Cody Schuffelen #include "Tpm.h"
42*5c591343SA. Cody Schuffelen 
43*5c591343SA. Cody Schuffelen //** Functions
44*5c591343SA. Cody Schuffelen 
45*5c591343SA. Cody Schuffelen //*** ObjectFlush()
46*5c591343SA. Cody Schuffelen // This function marks an object slot as available.
47*5c591343SA. Cody Schuffelen // Since there is no checking of the input parameters, it should be used
48*5c591343SA. Cody Schuffelen // judiciously.
49*5c591343SA. Cody Schuffelen // Note: This could be converted to a macro.
50*5c591343SA. Cody Schuffelen void
ObjectFlush(OBJECT * object)51*5c591343SA. Cody Schuffelen ObjectFlush(
52*5c591343SA. Cody Schuffelen     OBJECT          *object
53*5c591343SA. Cody Schuffelen     )
54*5c591343SA. Cody Schuffelen {
55*5c591343SA. Cody Schuffelen     object->attributes.occupied = CLEAR;
56*5c591343SA. Cody Schuffelen }
57*5c591343SA. Cody Schuffelen 
58*5c591343SA. Cody Schuffelen //*** ObjectSetInUse()
59*5c591343SA. Cody Schuffelen // This access function sets the occupied attribute of an object slot.
60*5c591343SA. Cody Schuffelen void
ObjectSetInUse(OBJECT * object)61*5c591343SA. Cody Schuffelen ObjectSetInUse(
62*5c591343SA. Cody Schuffelen     OBJECT          *object
63*5c591343SA. Cody Schuffelen     )
64*5c591343SA. Cody Schuffelen {
65*5c591343SA. Cody Schuffelen     object->attributes.occupied = SET;
66*5c591343SA. Cody Schuffelen }
67*5c591343SA. Cody Schuffelen 
68*5c591343SA. Cody Schuffelen //*** ObjectStartup()
69*5c591343SA. Cody Schuffelen // This function is called at TPM2_Startup() to initialize the object subsystem.
70*5c591343SA. Cody Schuffelen BOOL
ObjectStartup(void)71*5c591343SA. Cody Schuffelen ObjectStartup(
72*5c591343SA. Cody Schuffelen     void
73*5c591343SA. Cody Schuffelen     )
74*5c591343SA. Cody Schuffelen {
75*5c591343SA. Cody Schuffelen     UINT32      i;
76*5c591343SA. Cody Schuffelen //
77*5c591343SA. Cody Schuffelen     // object slots initialization
78*5c591343SA. Cody Schuffelen     for(i = 0; i < MAX_LOADED_OBJECTS; i++)
79*5c591343SA. Cody Schuffelen     {
80*5c591343SA. Cody Schuffelen         //Set the slot to not occupied
81*5c591343SA. Cody Schuffelen         ObjectFlush(&s_objects[i]);
82*5c591343SA. Cody Schuffelen     }
83*5c591343SA. Cody Schuffelen     return TRUE;
84*5c591343SA. Cody Schuffelen }
85*5c591343SA. Cody Schuffelen 
86*5c591343SA. Cody Schuffelen //*** ObjectCleanupEvict()
87*5c591343SA. Cody Schuffelen //
88*5c591343SA. Cody Schuffelen // In this implementation, a persistent object is moved from NV into an object slot
89*5c591343SA. Cody Schuffelen // for processing. It is flushed after command execution. This function is called
90*5c591343SA. Cody Schuffelen // from ExecuteCommand().
91*5c591343SA. Cody Schuffelen void
ObjectCleanupEvict(void)92*5c591343SA. Cody Schuffelen ObjectCleanupEvict(
93*5c591343SA. Cody Schuffelen     void
94*5c591343SA. Cody Schuffelen     )
95*5c591343SA. Cody Schuffelen {
96*5c591343SA. Cody Schuffelen     UINT32      i;
97*5c591343SA. Cody Schuffelen //
98*5c591343SA. Cody Schuffelen     // This has to be iterated because a command may have two handles
99*5c591343SA. Cody Schuffelen     // and they may both be persistent.
100*5c591343SA. Cody Schuffelen     // This could be made to be more efficient so that a search is not needed.
101*5c591343SA. Cody Schuffelen     for(i = 0; i < MAX_LOADED_OBJECTS; i++)
102*5c591343SA. Cody Schuffelen     {
103*5c591343SA. Cody Schuffelen         // If an object is a temporary evict object, flush it from slot
104*5c591343SA. Cody Schuffelen         OBJECT      *object = &s_objects[i];
105*5c591343SA. Cody Schuffelen         if(object->attributes.evict == SET)
106*5c591343SA. Cody Schuffelen             ObjectFlush(object);
107*5c591343SA. Cody Schuffelen     }
108*5c591343SA. Cody Schuffelen     return;
109*5c591343SA. Cody Schuffelen }
110*5c591343SA. Cody Schuffelen 
111*5c591343SA. Cody Schuffelen //*** IsObjectPresent()
112*5c591343SA. Cody Schuffelen // This function checks to see if a transient handle references a loaded
113*5c591343SA. Cody Schuffelen // object.  This routine should not be called if the handle is not a
114*5c591343SA. Cody Schuffelen // transient handle. The function validates that the handle is in the
115*5c591343SA. Cody Schuffelen // implementation-dependent allowed in range for loaded transient objects.
116*5c591343SA. Cody Schuffelen //  Return Type: BOOL
117*5c591343SA. Cody Schuffelen //      TRUE(1)         handle references a loaded object
118*5c591343SA. Cody Schuffelen //      FALSE(0)        handle is not an object handle, or it does not
119*5c591343SA. Cody Schuffelen //                      reference to a loaded object
120*5c591343SA. Cody Schuffelen BOOL
IsObjectPresent(TPMI_DH_OBJECT handle)121*5c591343SA. Cody Schuffelen IsObjectPresent(
122*5c591343SA. Cody Schuffelen     TPMI_DH_OBJECT   handle         // IN: handle to be checked
123*5c591343SA. Cody Schuffelen     )
124*5c591343SA. Cody Schuffelen {
125*5c591343SA. Cody Schuffelen     UINT32          slotIndex = handle - TRANSIENT_FIRST;
126*5c591343SA. Cody Schuffelen     // Since the handle is just an index into the array that is zero based, any
127*5c591343SA. Cody Schuffelen     // handle value outsize of the range of:
128*5c591343SA. Cody Schuffelen     //    TRANSIENT_FIRST -- (TRANSIENT_FIRST + MAX_LOADED_OBJECT - 1)
129*5c591343SA. Cody Schuffelen     // will now be greater than or equal to MAX_LOADED_OBJECTS
130*5c591343SA. Cody Schuffelen     if(slotIndex >= MAX_LOADED_OBJECTS)
131*5c591343SA. Cody Schuffelen         return FALSE;
132*5c591343SA. Cody Schuffelen     // Indicate if the slot is occupied
133*5c591343SA. Cody Schuffelen     return (s_objects[slotIndex].attributes.occupied == TRUE);
134*5c591343SA. Cody Schuffelen }
135*5c591343SA. Cody Schuffelen 
136*5c591343SA. Cody Schuffelen //*** ObjectIsSequence()
137*5c591343SA. Cody Schuffelen // This function is used to check if the object is a sequence object. This function
138*5c591343SA. Cody Schuffelen // should not be called if the handle does not reference a loaded object.
139*5c591343SA. Cody Schuffelen //  Return Type: BOOL
140*5c591343SA. Cody Schuffelen //      TRUE(1)         object is an HMAC, hash, or event sequence object
141*5c591343SA. Cody Schuffelen //      FALSE(0)        object is not an HMAC, hash, or event sequence object
142*5c591343SA. Cody Schuffelen BOOL
ObjectIsSequence(OBJECT * object)143*5c591343SA. Cody Schuffelen ObjectIsSequence(
144*5c591343SA. Cody Schuffelen     OBJECT          *object         // IN: handle to be checked
145*5c591343SA. Cody Schuffelen     )
146*5c591343SA. Cody Schuffelen {
147*5c591343SA. Cody Schuffelen     pAssert(object != NULL);
148*5c591343SA. Cody Schuffelen     return (object->attributes.hmacSeq == SET
149*5c591343SA. Cody Schuffelen             || object->attributes.hashSeq == SET
150*5c591343SA. Cody Schuffelen             || object->attributes.eventSeq == SET);
151*5c591343SA. Cody Schuffelen }
152*5c591343SA. Cody Schuffelen 
153*5c591343SA. Cody Schuffelen //*** HandleToObject()
154*5c591343SA. Cody Schuffelen // This function is used to find the object structure associated with a handle.
155*5c591343SA. Cody Schuffelen //
156*5c591343SA. Cody Schuffelen // This function requires that 'handle' references a loaded object or a permanent
157*5c591343SA. Cody Schuffelen // handle.
158*5c591343SA. Cody Schuffelen OBJECT*
HandleToObject(TPMI_DH_OBJECT handle)159*5c591343SA. Cody Schuffelen HandleToObject(
160*5c591343SA. Cody Schuffelen     TPMI_DH_OBJECT   handle         // IN: handle of the object
161*5c591343SA. Cody Schuffelen     )
162*5c591343SA. Cody Schuffelen {
163*5c591343SA. Cody Schuffelen     UINT32              index;
164*5c591343SA. Cody Schuffelen //
165*5c591343SA. Cody Schuffelen     // Return NULL if the handle references a permanent handle because there is no
166*5c591343SA. Cody Schuffelen     // associated OBJECT.
167*5c591343SA. Cody Schuffelen     if(HandleGetType(handle) == TPM_HT_PERMANENT)
168*5c591343SA. Cody Schuffelen         return NULL;
169*5c591343SA. Cody Schuffelen     // In this implementation, the handle is determined by the slot occupied by the
170*5c591343SA. Cody Schuffelen     // object.
171*5c591343SA. Cody Schuffelen     index = handle - TRANSIENT_FIRST;
172*5c591343SA. Cody Schuffelen     pAssert(index < MAX_LOADED_OBJECTS);
173*5c591343SA. Cody Schuffelen     pAssert(s_objects[index].attributes.occupied);
174*5c591343SA. Cody Schuffelen     return &s_objects[index];
175*5c591343SA. Cody Schuffelen }
176*5c591343SA. Cody Schuffelen 
177*5c591343SA. Cody Schuffelen 
178*5c591343SA. Cody Schuffelen //*** GetQualifiedName()
179*5c591343SA. Cody Schuffelen // This function returns the Qualified Name of the object. In this implementation,
180*5c591343SA. Cody Schuffelen // the Qualified Name is computed when the object is loaded and is saved in the
181*5c591343SA. Cody Schuffelen // internal representation of the object. The alternative would be to retain the
182*5c591343SA. Cody Schuffelen // Name of the parent and compute the QN when needed. This would take the same
183*5c591343SA. Cody Schuffelen // amount of space so it is not recommended that the alternate be used.
184*5c591343SA. Cody Schuffelen //
185*5c591343SA. Cody Schuffelen // This function requires that 'handle' references a loaded object.
186*5c591343SA. Cody Schuffelen void
GetQualifiedName(TPMI_DH_OBJECT handle,TPM2B_NAME * qualifiedName)187*5c591343SA. Cody Schuffelen GetQualifiedName(
188*5c591343SA. Cody Schuffelen     TPMI_DH_OBJECT   handle,        // IN: handle of the object
189*5c591343SA. Cody Schuffelen     TPM2B_NAME      *qualifiedName  // OUT: qualified name of the object
190*5c591343SA. Cody Schuffelen     )
191*5c591343SA. Cody Schuffelen {
192*5c591343SA. Cody Schuffelen     OBJECT      *object;
193*5c591343SA. Cody Schuffelen //
194*5c591343SA. Cody Schuffelen     switch(HandleGetType(handle))
195*5c591343SA. Cody Schuffelen     {
196*5c591343SA. Cody Schuffelen         case TPM_HT_PERMANENT:
197*5c591343SA. Cody Schuffelen             qualifiedName->t.size = sizeof(TPM_HANDLE);
198*5c591343SA. Cody Schuffelen             UINT32_TO_BYTE_ARRAY(handle, qualifiedName->t.name);
199*5c591343SA. Cody Schuffelen             break;
200*5c591343SA. Cody Schuffelen         case TPM_HT_TRANSIENT:
201*5c591343SA. Cody Schuffelen             object = HandleToObject(handle);
202*5c591343SA. Cody Schuffelen             if(object == NULL || object->publicArea.nameAlg == TPM_ALG_NULL)
203*5c591343SA. Cody Schuffelen                 qualifiedName->t.size = 0;
204*5c591343SA. Cody Schuffelen             else
205*5c591343SA. Cody Schuffelen                 // Copy the name
206*5c591343SA. Cody Schuffelen                 *qualifiedName = object->qualifiedName;
207*5c591343SA. Cody Schuffelen             break;
208*5c591343SA. Cody Schuffelen         default:
209*5c591343SA. Cody Schuffelen             FAIL(FATAL_ERROR_INTERNAL);
210*5c591343SA. Cody Schuffelen     }
211*5c591343SA. Cody Schuffelen     return;
212*5c591343SA. Cody Schuffelen }
213*5c591343SA. Cody Schuffelen 
214*5c591343SA. Cody Schuffelen //*** ObjectGetHierarchy()
215*5c591343SA. Cody Schuffelen // This function returns the handle for the hierarchy of an object.
216*5c591343SA. Cody Schuffelen TPMI_RH_HIERARCHY
ObjectGetHierarchy(OBJECT * object)217*5c591343SA. Cody Schuffelen ObjectGetHierarchy(
218*5c591343SA. Cody Schuffelen     OBJECT          *object         // IN :object
219*5c591343SA. Cody Schuffelen     )
220*5c591343SA. Cody Schuffelen {
221*5c591343SA. Cody Schuffelen     if(object->attributes.spsHierarchy)
222*5c591343SA. Cody Schuffelen     {
223*5c591343SA. Cody Schuffelen         return TPM_RH_OWNER;
224*5c591343SA. Cody Schuffelen     }
225*5c591343SA. Cody Schuffelen     else if(object->attributes.epsHierarchy)
226*5c591343SA. Cody Schuffelen     {
227*5c591343SA. Cody Schuffelen         return TPM_RH_ENDORSEMENT;
228*5c591343SA. Cody Schuffelen     }
229*5c591343SA. Cody Schuffelen     else if(object->attributes.ppsHierarchy)
230*5c591343SA. Cody Schuffelen     {
231*5c591343SA. Cody Schuffelen         return TPM_RH_PLATFORM;
232*5c591343SA. Cody Schuffelen     }
233*5c591343SA. Cody Schuffelen     else
234*5c591343SA. Cody Schuffelen     {
235*5c591343SA. Cody Schuffelen         return TPM_RH_NULL;
236*5c591343SA. Cody Schuffelen     }
237*5c591343SA. Cody Schuffelen }
238*5c591343SA. Cody Schuffelen 
239*5c591343SA. Cody Schuffelen //*** GetHierarchy()
240*5c591343SA. Cody Schuffelen // This function returns the handle of the hierarchy to which a handle belongs.
241*5c591343SA. Cody Schuffelen // This function is similar to ObjectGetHierarchy() but this routine takes
242*5c591343SA. Cody Schuffelen // a handle but ObjectGetHierarchy() takes an pointer to an object.
243*5c591343SA. Cody Schuffelen //
244*5c591343SA. Cody Schuffelen // This function requires that 'handle' references a loaded object.
245*5c591343SA. Cody Schuffelen TPMI_RH_HIERARCHY
GetHierarchy(TPMI_DH_OBJECT handle)246*5c591343SA. Cody Schuffelen GetHierarchy(
247*5c591343SA. Cody Schuffelen     TPMI_DH_OBJECT   handle         // IN :object handle
248*5c591343SA. Cody Schuffelen     )
249*5c591343SA. Cody Schuffelen {
250*5c591343SA. Cody Schuffelen     OBJECT          *object = HandleToObject(handle);
251*5c591343SA. Cody Schuffelen //
252*5c591343SA. Cody Schuffelen     return ObjectGetHierarchy(object);
253*5c591343SA. Cody Schuffelen }
254*5c591343SA. Cody Schuffelen 
255*5c591343SA. Cody Schuffelen //*** FindEmptyObjectSlot()
256*5c591343SA. Cody Schuffelen // This function finds an open object slot, if any. It will clear the attributes
257*5c591343SA. Cody Schuffelen // but will not set the occupied attribute. This is so that a slot may be used
258*5c591343SA. Cody Schuffelen // and discarded if everything does not go as planned.
259*5c591343SA. Cody Schuffelen //  Return Type: OBJECT *
260*5c591343SA. Cody Schuffelen //      NULL        no open slot found
261*5c591343SA. Cody Schuffelen //      != NULL     pointer to available slot
262*5c591343SA. Cody Schuffelen OBJECT *
FindEmptyObjectSlot(TPMI_DH_OBJECT * handle)263*5c591343SA. Cody Schuffelen FindEmptyObjectSlot(
264*5c591343SA. Cody Schuffelen     TPMI_DH_OBJECT  *handle         // OUT: (optional)
265*5c591343SA. Cody Schuffelen     )
266*5c591343SA. Cody Schuffelen {
267*5c591343SA. Cody Schuffelen     UINT32               i;
268*5c591343SA. Cody Schuffelen     OBJECT              *object;
269*5c591343SA. Cody Schuffelen //
270*5c591343SA. Cody Schuffelen     for(i = 0; i < MAX_LOADED_OBJECTS; i++)
271*5c591343SA. Cody Schuffelen     {
272*5c591343SA. Cody Schuffelen         object = &s_objects[i];
273*5c591343SA. Cody Schuffelen         if(object->attributes.occupied == CLEAR)
274*5c591343SA. Cody Schuffelen         {
275*5c591343SA. Cody Schuffelen             if(handle)
276*5c591343SA. Cody Schuffelen                 *handle = i + TRANSIENT_FIRST;
277*5c591343SA. Cody Schuffelen             // Initialize the object attributes
278*5c591343SA. Cody Schuffelen             MemorySet(&object->attributes, 0, sizeof(OBJECT_ATTRIBUTES));
279*5c591343SA. Cody Schuffelen             return object;
280*5c591343SA. Cody Schuffelen         }
281*5c591343SA. Cody Schuffelen     }
282*5c591343SA. Cody Schuffelen     return NULL;
283*5c591343SA. Cody Schuffelen }
284*5c591343SA. Cody Schuffelen 
285*5c591343SA. Cody Schuffelen //*** ObjectAllocateSlot()
286*5c591343SA. Cody Schuffelen // This function is used to allocate a slot in internal object array.
287*5c591343SA. Cody Schuffelen OBJECT *
ObjectAllocateSlot(TPMI_DH_OBJECT * handle)288*5c591343SA. Cody Schuffelen ObjectAllocateSlot(
289*5c591343SA. Cody Schuffelen     TPMI_DH_OBJECT  *handle        // OUT: handle of allocated object
290*5c591343SA. Cody Schuffelen     )
291*5c591343SA. Cody Schuffelen {
292*5c591343SA. Cody Schuffelen     OBJECT          *object = FindEmptyObjectSlot(handle);
293*5c591343SA. Cody Schuffelen //
294*5c591343SA. Cody Schuffelen     if(object != NULL)
295*5c591343SA. Cody Schuffelen     {
296*5c591343SA. Cody Schuffelen         // if found, mark as occupied
297*5c591343SA. Cody Schuffelen         ObjectSetInUse(object);
298*5c591343SA. Cody Schuffelen     }
299*5c591343SA. Cody Schuffelen     return object;
300*5c591343SA. Cody Schuffelen }
301*5c591343SA. Cody Schuffelen 
302*5c591343SA. Cody Schuffelen //*** ObjectSetLoadedAttributes()
303*5c591343SA. Cody Schuffelen // This function sets the internal attributes for a loaded object. It is called to
304*5c591343SA. Cody Schuffelen // finalize the OBJECT attributes (not the TPMA_OBJECT attributes) for a loaded
305*5c591343SA. Cody Schuffelen // object.
306*5c591343SA. Cody Schuffelen void
ObjectSetLoadedAttributes(OBJECT * object,TPM_HANDLE parentHandle)307*5c591343SA. Cody Schuffelen ObjectSetLoadedAttributes(
308*5c591343SA. Cody Schuffelen     OBJECT          *object,        // IN: object attributes to finalize
309*5c591343SA. Cody Schuffelen     TPM_HANDLE       parentHandle   // IN: the parent handle
310*5c591343SA. Cody Schuffelen     )
311*5c591343SA. Cody Schuffelen {
312*5c591343SA. Cody Schuffelen     OBJECT              *parent = HandleToObject(parentHandle);
313*5c591343SA. Cody Schuffelen     TPMA_OBJECT          objectAttributes = object->publicArea.objectAttributes;
314*5c591343SA. Cody Schuffelen //
315*5c591343SA. Cody Schuffelen     // Copy the stClear attribute from the public area. This could be overwritten
316*5c591343SA. Cody Schuffelen     // if the parent has stClear SET
317*5c591343SA. Cody Schuffelen     object->attributes.stClear =
318*5c591343SA. Cody Schuffelen         IS_ATTRIBUTE(objectAttributes, TPMA_OBJECT, stClear);
319*5c591343SA. Cody Schuffelen     // If parent handle is a permanent handle, it is a primary (unless it is NULL
320*5c591343SA. Cody Schuffelen     if(parent == NULL)
321*5c591343SA. Cody Schuffelen     {
322*5c591343SA. Cody Schuffelen         object->attributes.primary = SET;
323*5c591343SA. Cody Schuffelen         switch(parentHandle)
324*5c591343SA. Cody Schuffelen         {
325*5c591343SA. Cody Schuffelen             case TPM_RH_ENDORSEMENT:
326*5c591343SA. Cody Schuffelen                 object->attributes.epsHierarchy = SET;
327*5c591343SA. Cody Schuffelen                 break;
328*5c591343SA. Cody Schuffelen             case TPM_RH_OWNER:
329*5c591343SA. Cody Schuffelen                 object->attributes.spsHierarchy = SET;
330*5c591343SA. Cody Schuffelen                 break;
331*5c591343SA. Cody Schuffelen             case TPM_RH_PLATFORM:
332*5c591343SA. Cody Schuffelen                 object->attributes.ppsHierarchy = SET;
333*5c591343SA. Cody Schuffelen                 break;
334*5c591343SA. Cody Schuffelen             default:
335*5c591343SA. Cody Schuffelen                 // Treat the temporary attribute as a hierarchy
336*5c591343SA. Cody Schuffelen                 object->attributes.temporary = SET;
337*5c591343SA. Cody Schuffelen                 object->attributes.primary = CLEAR;
338*5c591343SA. Cody Schuffelen                 break;
339*5c591343SA. Cody Schuffelen         }
340*5c591343SA. Cody Schuffelen     }
341*5c591343SA. Cody Schuffelen     else
342*5c591343SA. Cody Schuffelen     {
343*5c591343SA. Cody Schuffelen         // is this a stClear object
344*5c591343SA. Cody Schuffelen         object->attributes.stClear =
345*5c591343SA. Cody Schuffelen             (IS_ATTRIBUTE(objectAttributes, TPMA_OBJECT, stClear)
346*5c591343SA. Cody Schuffelen              || (parent->attributes.stClear == SET));
347*5c591343SA. Cody Schuffelen         object->attributes.epsHierarchy = parent->attributes.epsHierarchy;
348*5c591343SA. Cody Schuffelen         object->attributes.spsHierarchy = parent->attributes.spsHierarchy;
349*5c591343SA. Cody Schuffelen         object->attributes.ppsHierarchy = parent->attributes.ppsHierarchy;
350*5c591343SA. Cody Schuffelen         // An object is temporary if its parent is temporary or if the object
351*5c591343SA. Cody Schuffelen         // is external
352*5c591343SA. Cody Schuffelen         object->attributes.temporary = parent->attributes.temporary
353*5c591343SA. Cody Schuffelen             || object->attributes.external;
354*5c591343SA. Cody Schuffelen     }
355*5c591343SA. Cody Schuffelen     // If this is an external object, set the QN == name but don't SET other
356*5c591343SA. Cody Schuffelen     // key properties ('parent' or 'derived')
357*5c591343SA. Cody Schuffelen     if(object->attributes.external)
358*5c591343SA. Cody Schuffelen         object->qualifiedName = object->name;
359*5c591343SA. Cody Schuffelen     else
360*5c591343SA. Cody Schuffelen     {
361*5c591343SA. Cody Schuffelen         // check attributes for different types of parents
362*5c591343SA. Cody Schuffelen         if(IS_ATTRIBUTE(objectAttributes, TPMA_OBJECT, restricted)
363*5c591343SA. Cody Schuffelen            && !object->attributes.publicOnly
364*5c591343SA. Cody Schuffelen            && IS_ATTRIBUTE(objectAttributes, TPMA_OBJECT, decrypt)
365*5c591343SA. Cody Schuffelen            && object->publicArea.nameAlg != TPM_ALG_NULL)
366*5c591343SA. Cody Schuffelen         {
367*5c591343SA. Cody Schuffelen             // This is a parent. If it is not a KEYEDHASH, it is an ordinary parent.
368*5c591343SA. Cody Schuffelen             // Otherwise, it is a derivation parent.
369*5c591343SA. Cody Schuffelen             if(object->publicArea.type == TPM_ALG_KEYEDHASH)
370*5c591343SA. Cody Schuffelen                 object->attributes.derivation = SET;
371*5c591343SA. Cody Schuffelen             else
372*5c591343SA. Cody Schuffelen                 object->attributes.isParent = SET;
373*5c591343SA. Cody Schuffelen         }
374*5c591343SA. Cody Schuffelen         ComputeQualifiedName(parentHandle, object->publicArea.nameAlg,
375*5c591343SA. Cody Schuffelen                              &object->name, &object->qualifiedName);
376*5c591343SA. Cody Schuffelen     }
377*5c591343SA. Cody Schuffelen     // Set slot occupied
378*5c591343SA. Cody Schuffelen     ObjectSetInUse(object);
379*5c591343SA. Cody Schuffelen     return;
380*5c591343SA. Cody Schuffelen }
381*5c591343SA. Cody Schuffelen 
382*5c591343SA. Cody Schuffelen //*** ObjectLoad()
383*5c591343SA. Cody Schuffelen // Common function to load an object. A loaded object has its public area validated
384*5c591343SA. Cody Schuffelen // (unless its 'nameAlg' is TPM_ALG_NULL). If a sensitive part is loaded, it is
385*5c591343SA. Cody Schuffelen // verified to be correct and if both public and sensitive parts are loaded, then
386*5c591343SA. Cody Schuffelen // the cryptographic binding between the objects is validated. This function does
387*5c591343SA. Cody Schuffelen // not cause the allocated slot to be marked as in use.
388*5c591343SA. Cody Schuffelen TPM_RC
ObjectLoad(OBJECT * object,OBJECT * parent,TPMT_PUBLIC * publicArea,TPMT_SENSITIVE * sensitive,TPM_RC blamePublic,TPM_RC blameSensitive,TPM2B_NAME * name)389*5c591343SA. Cody Schuffelen ObjectLoad(
390*5c591343SA. Cody Schuffelen     OBJECT          *object,        // IN: pointer to object slot
391*5c591343SA. Cody Schuffelen                                     //     object
392*5c591343SA. Cody Schuffelen     OBJECT          *parent,        // IN: (optional) the parent object
393*5c591343SA. Cody Schuffelen     TPMT_PUBLIC     *publicArea,    // IN: public area to be installed in the object
394*5c591343SA. Cody Schuffelen     TPMT_SENSITIVE  *sensitive,     // IN: (optional) sensitive area to be
395*5c591343SA. Cody Schuffelen                                     //      installed in the object
396*5c591343SA. Cody Schuffelen     TPM_RC           blamePublic,   // IN: parameter number to associate with the
397*5c591343SA. Cody Schuffelen                                     //     publicArea errors
398*5c591343SA. Cody Schuffelen     TPM_RC           blameSensitive,// IN: parameter number to associate with the
399*5c591343SA. Cody Schuffelen                                     //     sensitive area errors
400*5c591343SA. Cody Schuffelen     TPM2B_NAME      *name           // IN: (optional)
401*5c591343SA. Cody Schuffelen )
402*5c591343SA. Cody Schuffelen {
403*5c591343SA. Cody Schuffelen     TPM_RC           result = TPM_RC_SUCCESS;
404*5c591343SA. Cody Schuffelen //
405*5c591343SA. Cody Schuffelen // Do validations of public area object descriptions
406*5c591343SA. Cody Schuffelen     pAssert(publicArea != NULL);
407*5c591343SA. Cody Schuffelen 
408*5c591343SA. Cody Schuffelen     // Is this public only or a no-name object?
409*5c591343SA. Cody Schuffelen     if(sensitive == NULL || publicArea->nameAlg == TPM_ALG_NULL)
410*5c591343SA. Cody Schuffelen     {
411*5c591343SA. Cody Schuffelen         // Need to have schemes checked so that we do the right thing with the
412*5c591343SA. Cody Schuffelen         // public key.
413*5c591343SA. Cody Schuffelen         result = SchemeChecks(NULL, publicArea);
414*5c591343SA. Cody Schuffelen     }
415*5c591343SA. Cody Schuffelen     else
416*5c591343SA. Cody Schuffelen     {
417*5c591343SA. Cody Schuffelen         // For any sensitive area, make sure that the seedSize is no larger than the
418*5c591343SA. Cody Schuffelen         // digest size of nameAlg
419*5c591343SA. Cody Schuffelen         if(sensitive->seedValue.t.size > CryptHashGetDigestSize(publicArea->nameAlg))
420*5c591343SA. Cody Schuffelen             return TPM_RCS_KEY_SIZE + blameSensitive;
421*5c591343SA. Cody Schuffelen         // Check attributes and schemes for consistency
422*5c591343SA. Cody Schuffelen         result = PublicAttributesValidation(parent, publicArea);
423*5c591343SA. Cody Schuffelen     }
424*5c591343SA. Cody Schuffelen     if(result != TPM_RC_SUCCESS)
425*5c591343SA. Cody Schuffelen         return RcSafeAddToResult(result, blamePublic);
426*5c591343SA. Cody Schuffelen 
427*5c591343SA. Cody Schuffelen // Sensitive area and binding checks
428*5c591343SA. Cody Schuffelen 
429*5c591343SA. Cody Schuffelen     // On load, check nothing if the parent is fixedTPM. For all other cases, validate
430*5c591343SA. Cody Schuffelen     // the keys.
431*5c591343SA. Cody Schuffelen     if((parent == NULL)
432*5c591343SA. Cody Schuffelen        || ((parent != NULL) && !IS_ATTRIBUTE(parent->publicArea.objectAttributes,
433*5c591343SA. Cody Schuffelen                                              TPMA_OBJECT, fixedTPM)))
434*5c591343SA. Cody Schuffelen     {
435*5c591343SA. Cody Schuffelen         // Do the cryptographic key validation
436*5c591343SA. Cody Schuffelen         result = CryptValidateKeys(publicArea, sensitive, blamePublic,
437*5c591343SA. Cody Schuffelen                                    blameSensitive);
438*5c591343SA. Cody Schuffelen         if(result != TPM_RC_SUCCESS)
439*5c591343SA. Cody Schuffelen             return result;
440*5c591343SA. Cody Schuffelen     }
441*5c591343SA. Cody Schuffelen #if ALG_RSA
442*5c591343SA. Cody Schuffelen     // If this is an RSA key, then expand the private exponent.
443*5c591343SA. Cody Schuffelen     // Note: ObjectLoad() is only called by TPM2_Import() if the parent is fixedTPM.
444*5c591343SA. Cody Schuffelen     // For any key that does not have a fixedTPM parent, the exponent is computed
445*5c591343SA. Cody Schuffelen     // whenever it is loaded
446*5c591343SA. Cody Schuffelen     if((publicArea->type == TPM_ALG_RSA) && (sensitive != NULL))
447*5c591343SA. Cody Schuffelen     {
448*5c591343SA. Cody Schuffelen         result = CryptRsaLoadPrivateExponent(publicArea, sensitive);
449*5c591343SA. Cody Schuffelen         if(result != TPM_RC_SUCCESS)
450*5c591343SA. Cody Schuffelen             return result;
451*5c591343SA. Cody Schuffelen     }
452*5c591343SA. Cody Schuffelen #endif // ALG_RSA
453*5c591343SA. Cody Schuffelen     // See if there is an object to populate
454*5c591343SA. Cody Schuffelen     if((result == TPM_RC_SUCCESS) && (object != NULL))
455*5c591343SA. Cody Schuffelen     {
456*5c591343SA. Cody Schuffelen         // Initialize public
457*5c591343SA. Cody Schuffelen         object->publicArea = *publicArea;
458*5c591343SA. Cody Schuffelen         // Copy sensitive if there is one
459*5c591343SA. Cody Schuffelen         if(sensitive == NULL)
460*5c591343SA. Cody Schuffelen             object->attributes.publicOnly = SET;
461*5c591343SA. Cody Schuffelen         else
462*5c591343SA. Cody Schuffelen             object->sensitive = *sensitive;
463*5c591343SA. Cody Schuffelen         // Set the name, if one was provided
464*5c591343SA. Cody Schuffelen         if(name != NULL)
465*5c591343SA. Cody Schuffelen             object->name = *name;
466*5c591343SA. Cody Schuffelen         else
467*5c591343SA. Cody Schuffelen             object->name.t.size = 0;
468*5c591343SA. Cody Schuffelen     }
469*5c591343SA. Cody Schuffelen     return result;
470*5c591343SA. Cody Schuffelen }
471*5c591343SA. Cody Schuffelen 
472*5c591343SA. Cody Schuffelen //*** AllocateSequenceSlot()
473*5c591343SA. Cody Schuffelen // This function allocates a sequence slot and initializes the parts that
474*5c591343SA. Cody Schuffelen // are used by the normal objects so that a sequence object is not inadvertently
475*5c591343SA. Cody Schuffelen // used for an operation that is not appropriate for a sequence.
476*5c591343SA. Cody Schuffelen //
477*5c591343SA. Cody Schuffelen static HASH_OBJECT *
AllocateSequenceSlot(TPM_HANDLE * newHandle,TPM2B_AUTH * auth)478*5c591343SA. Cody Schuffelen AllocateSequenceSlot(
479*5c591343SA. Cody Schuffelen     TPM_HANDLE      *newHandle,     // OUT: receives the allocated handle
480*5c591343SA. Cody Schuffelen     TPM2B_AUTH      *auth           // IN: the authValue for the slot
481*5c591343SA. Cody Schuffelen     )
482*5c591343SA. Cody Schuffelen {
483*5c591343SA. Cody Schuffelen     HASH_OBJECT      *object = (HASH_OBJECT *)ObjectAllocateSlot(newHandle);
484*5c591343SA. Cody Schuffelen //
485*5c591343SA. Cody Schuffelen     // Validate that the proper location of the hash state data relative to the
486*5c591343SA. Cody Schuffelen     // object state data. It would be good if this could have been done at compile
487*5c591343SA. Cody Schuffelen     // time but it can't so do it in something that can be removed after debug.
488*5c591343SA. Cody Schuffelen     cAssert(offsetof(HASH_OBJECT, auth) == offsetof(OBJECT, publicArea.authPolicy));
489*5c591343SA. Cody Schuffelen 
490*5c591343SA. Cody Schuffelen     if(object != NULL)
491*5c591343SA. Cody Schuffelen     {
492*5c591343SA. Cody Schuffelen 
493*5c591343SA. Cody Schuffelen     // Set the common values that a sequence object shares with an ordinary object
494*5c591343SA. Cody Schuffelen         // First, clear all attributes
495*5c591343SA. Cody Schuffelen         MemorySet(&object->objectAttributes, 0, sizeof(TPMA_OBJECT));
496*5c591343SA. Cody Schuffelen 
497*5c591343SA. Cody Schuffelen         // The type is TPM_ALG_NULL
498*5c591343SA. Cody Schuffelen         object->type = TPM_ALG_NULL;
499*5c591343SA. Cody Schuffelen 
500*5c591343SA. Cody Schuffelen         // This has no name algorithm and the name is the Empty Buffer
501*5c591343SA. Cody Schuffelen         object->nameAlg = TPM_ALG_NULL;
502*5c591343SA. Cody Schuffelen 
503*5c591343SA. Cody Schuffelen         // A sequence object is considered to be in the NULL hierarchy so it should
504*5c591343SA. Cody Schuffelen         // be marked as temporary so that it can't be persisted
505*5c591343SA. Cody Schuffelen         object->attributes.temporary = SET;
506*5c591343SA. Cody Schuffelen 
507*5c591343SA. Cody Schuffelen         // A sequence object is DA exempt.
508*5c591343SA. Cody Schuffelen         SET_ATTRIBUTE(object->objectAttributes, TPMA_OBJECT, noDA);
509*5c591343SA. Cody Schuffelen 
510*5c591343SA. Cody Schuffelen         // Copy the authorization value
511*5c591343SA. Cody Schuffelen         if(auth != NULL)
512*5c591343SA. Cody Schuffelen             object->auth = *auth;
513*5c591343SA. Cody Schuffelen         else
514*5c591343SA. Cody Schuffelen             object->auth.t.size = 0;
515*5c591343SA. Cody Schuffelen     }
516*5c591343SA. Cody Schuffelen     return object;
517*5c591343SA. Cody Schuffelen }
518*5c591343SA. Cody Schuffelen 
519*5c591343SA. Cody Schuffelen 
520*5c591343SA. Cody Schuffelen #if CC_HMAC_Start || CC_MAC_Start
521*5c591343SA. Cody Schuffelen //*** ObjectCreateHMACSequence()
522*5c591343SA. Cody Schuffelen // This function creates an internal HMAC sequence object.
523*5c591343SA. Cody Schuffelen //  Return Type: TPM_RC
524*5c591343SA. Cody Schuffelen //      TPM_RC_OBJECT_MEMORY        if there is no free slot for an object
525*5c591343SA. Cody Schuffelen TPM_RC
ObjectCreateHMACSequence(TPMI_ALG_HASH hashAlg,OBJECT * keyObject,TPM2B_AUTH * auth,TPMI_DH_OBJECT * newHandle)526*5c591343SA. Cody Schuffelen ObjectCreateHMACSequence(
527*5c591343SA. Cody Schuffelen     TPMI_ALG_HASH    hashAlg,       // IN: hash algorithm
528*5c591343SA. Cody Schuffelen     OBJECT          *keyObject,     // IN: the object containing the HMAC key
529*5c591343SA. Cody Schuffelen     TPM2B_AUTH      *auth,          // IN: authValue
530*5c591343SA. Cody Schuffelen     TPMI_DH_OBJECT  *newHandle      // OUT: HMAC sequence object handle
531*5c591343SA. Cody Schuffelen     )
532*5c591343SA. Cody Schuffelen {
533*5c591343SA. Cody Schuffelen     HASH_OBJECT         *hmacObject;
534*5c591343SA. Cody Schuffelen //
535*5c591343SA. Cody Schuffelen     // Try to allocate a slot for new object
536*5c591343SA. Cody Schuffelen     hmacObject = AllocateSequenceSlot(newHandle, auth);
537*5c591343SA. Cody Schuffelen 
538*5c591343SA. Cody Schuffelen     if(hmacObject == NULL)
539*5c591343SA. Cody Schuffelen         return TPM_RC_OBJECT_MEMORY;
540*5c591343SA. Cody Schuffelen     // Set HMAC sequence bit
541*5c591343SA. Cody Schuffelen     hmacObject->attributes.hmacSeq = SET;
542*5c591343SA. Cody Schuffelen 
543*5c591343SA. Cody Schuffelen #if !SMAC_IMPLEMENTED
544*5c591343SA. Cody Schuffelen     if(CryptHmacStart(&hmacObject->state.hmacState, hashAlg,
545*5c591343SA. Cody Schuffelen                    keyObject->sensitive.sensitive.bits.b.size,
546*5c591343SA. Cody Schuffelen                    keyObject->sensitive.sensitive.bits.b.buffer) == 0)
547*5c591343SA. Cody Schuffelen #else
548*5c591343SA. Cody Schuffelen     if(CryptMacStart(&hmacObject->state.hmacState,
549*5c591343SA. Cody Schuffelen                      &keyObject->publicArea.parameters,
550*5c591343SA. Cody Schuffelen                      hashAlg, &keyObject->sensitive.sensitive.any.b) == 0)
551*5c591343SA. Cody Schuffelen #endif // SMAC_IMPLEMENTED
552*5c591343SA. Cody Schuffelen         return TPM_RC_FAILURE;
553*5c591343SA. Cody Schuffelen     return TPM_RC_SUCCESS;
554*5c591343SA. Cody Schuffelen }
555*5c591343SA. Cody Schuffelen #endif
556*5c591343SA. Cody Schuffelen 
557*5c591343SA. Cody Schuffelen //*** ObjectCreateHashSequence()
558*5c591343SA. Cody Schuffelen // This function creates a hash sequence object.
559*5c591343SA. Cody Schuffelen //  Return Type: TPM_RC
560*5c591343SA. Cody Schuffelen //      TPM_RC_OBJECT_MEMORY        if there is no free slot for an object
561*5c591343SA. Cody Schuffelen TPM_RC
ObjectCreateHashSequence(TPMI_ALG_HASH hashAlg,TPM2B_AUTH * auth,TPMI_DH_OBJECT * newHandle)562*5c591343SA. Cody Schuffelen ObjectCreateHashSequence(
563*5c591343SA. Cody Schuffelen     TPMI_ALG_HASH    hashAlg,       // IN: hash algorithm
564*5c591343SA. Cody Schuffelen     TPM2B_AUTH      *auth,          // IN: authValue
565*5c591343SA. Cody Schuffelen     TPMI_DH_OBJECT  *newHandle      // OUT: sequence object handle
566*5c591343SA. Cody Schuffelen     )
567*5c591343SA. Cody Schuffelen {
568*5c591343SA. Cody Schuffelen     HASH_OBJECT         *hashObject = AllocateSequenceSlot(newHandle, auth);
569*5c591343SA. Cody Schuffelen //
570*5c591343SA. Cody Schuffelen     // See if slot allocated
571*5c591343SA. Cody Schuffelen     if(hashObject == NULL)
572*5c591343SA. Cody Schuffelen         return TPM_RC_OBJECT_MEMORY;
573*5c591343SA. Cody Schuffelen     // Set hash sequence bit
574*5c591343SA. Cody Schuffelen     hashObject->attributes.hashSeq = SET;
575*5c591343SA. Cody Schuffelen 
576*5c591343SA. Cody Schuffelen     // Start hash for hash sequence
577*5c591343SA. Cody Schuffelen     CryptHashStart(&hashObject->state.hashState[0], hashAlg);
578*5c591343SA. Cody Schuffelen 
579*5c591343SA. Cody Schuffelen     return TPM_RC_SUCCESS;
580*5c591343SA. Cody Schuffelen }
581*5c591343SA. Cody Schuffelen 
582*5c591343SA. Cody Schuffelen //*** ObjectCreateEventSequence()
583*5c591343SA. Cody Schuffelen // This function creates an event sequence object.
584*5c591343SA. Cody Schuffelen //  Return Type: TPM_RC
585*5c591343SA. Cody Schuffelen //      TPM_RC_OBJECT_MEMORY        if there is no free slot for an object
586*5c591343SA. Cody Schuffelen TPM_RC
ObjectCreateEventSequence(TPM2B_AUTH * auth,TPMI_DH_OBJECT * newHandle)587*5c591343SA. Cody Schuffelen ObjectCreateEventSequence(
588*5c591343SA. Cody Schuffelen     TPM2B_AUTH      *auth,          // IN: authValue
589*5c591343SA. Cody Schuffelen     TPMI_DH_OBJECT  *newHandle      // OUT: sequence object handle
590*5c591343SA. Cody Schuffelen     )
591*5c591343SA. Cody Schuffelen {
592*5c591343SA. Cody Schuffelen     HASH_OBJECT         *hashObject = AllocateSequenceSlot(newHandle, auth);
593*5c591343SA. Cody Schuffelen     UINT32               count;
594*5c591343SA. Cody Schuffelen     TPM_ALG_ID           hash;
595*5c591343SA. Cody Schuffelen //
596*5c591343SA. Cody Schuffelen     // See if slot allocated
597*5c591343SA. Cody Schuffelen     if(hashObject == NULL)
598*5c591343SA. Cody Schuffelen         return TPM_RC_OBJECT_MEMORY;
599*5c591343SA. Cody Schuffelen     // Set the event sequence attribute
600*5c591343SA. Cody Schuffelen     hashObject->attributes.eventSeq = SET;
601*5c591343SA. Cody Schuffelen 
602*5c591343SA. Cody Schuffelen     // Initialize hash states for each implemented PCR algorithms
603*5c591343SA. Cody Schuffelen     for(count = 0; (hash = CryptHashGetAlgByIndex(count)) != TPM_ALG_NULL; count++)
604*5c591343SA. Cody Schuffelen         CryptHashStart(&hashObject->state.hashState[count], hash);
605*5c591343SA. Cody Schuffelen     return TPM_RC_SUCCESS;
606*5c591343SA. Cody Schuffelen }
607*5c591343SA. Cody Schuffelen 
608*5c591343SA. Cody Schuffelen //*** ObjectTerminateEvent()
609*5c591343SA. Cody Schuffelen // This function is called to close out the event sequence and clean up the hash
610*5c591343SA. Cody Schuffelen // context states.
611*5c591343SA. Cody Schuffelen void
ObjectTerminateEvent(void)612*5c591343SA. Cody Schuffelen ObjectTerminateEvent(
613*5c591343SA. Cody Schuffelen     void
614*5c591343SA. Cody Schuffelen     )
615*5c591343SA. Cody Schuffelen {
616*5c591343SA. Cody Schuffelen     HASH_OBJECT         *hashObject;
617*5c591343SA. Cody Schuffelen     int                  count;
618*5c591343SA. Cody Schuffelen     BYTE                 buffer[MAX_DIGEST_SIZE];
619*5c591343SA. Cody Schuffelen //
620*5c591343SA. Cody Schuffelen     hashObject = (HASH_OBJECT *)HandleToObject(g_DRTMHandle);
621*5c591343SA. Cody Schuffelen 
622*5c591343SA. Cody Schuffelen     // Don't assume that this is a proper sequence object
623*5c591343SA. Cody Schuffelen     if(hashObject->attributes.eventSeq)
624*5c591343SA. Cody Schuffelen     {
625*5c591343SA. Cody Schuffelen         // If it is, close any open hash contexts. This is done in case
626*5c591343SA. Cody Schuffelen         // the cryptographic implementation has some context values that need to be
627*5c591343SA. Cody Schuffelen         // cleaned up (hygiene).
628*5c591343SA. Cody Schuffelen         //
629*5c591343SA. Cody Schuffelen         for(count = 0; CryptHashGetAlgByIndex(count) != TPM_ALG_NULL; count++)
630*5c591343SA. Cody Schuffelen         {
631*5c591343SA. Cody Schuffelen             CryptHashEnd(&hashObject->state.hashState[count], 0, buffer);
632*5c591343SA. Cody Schuffelen         }
633*5c591343SA. Cody Schuffelen         // Flush sequence object
634*5c591343SA. Cody Schuffelen         FlushObject(g_DRTMHandle);
635*5c591343SA. Cody Schuffelen     }
636*5c591343SA. Cody Schuffelen     g_DRTMHandle = TPM_RH_UNASSIGNED;
637*5c591343SA. Cody Schuffelen }
638*5c591343SA. Cody Schuffelen 
639*5c591343SA. Cody Schuffelen //*** ObjectContextLoad()
640*5c591343SA. Cody Schuffelen // This function loads an object from a saved object context.
641*5c591343SA. Cody Schuffelen //  Return Type: OBJECT *
642*5c591343SA. Cody Schuffelen //      NULL        if there is no free slot for an object
643*5c591343SA. Cody Schuffelen //      != NULL     points to the loaded object
644*5c591343SA. Cody Schuffelen OBJECT *
ObjectContextLoad(ANY_OBJECT_BUFFER * object,TPMI_DH_OBJECT * handle)645*5c591343SA. Cody Schuffelen ObjectContextLoad(
646*5c591343SA. Cody Schuffelen     ANY_OBJECT_BUFFER   *object,        // IN: pointer to object structure in saved
647*5c591343SA. Cody Schuffelen                                         //     context
648*5c591343SA. Cody Schuffelen     TPMI_DH_OBJECT      *handle         // OUT: object handle
649*5c591343SA. Cody Schuffelen     )
650*5c591343SA. Cody Schuffelen {
651*5c591343SA. Cody Schuffelen     OBJECT      *newObject = ObjectAllocateSlot(handle);
652*5c591343SA. Cody Schuffelen //
653*5c591343SA. Cody Schuffelen     // Try to allocate a slot for new object
654*5c591343SA. Cody Schuffelen     if(newObject != NULL)
655*5c591343SA. Cody Schuffelen     {
656*5c591343SA. Cody Schuffelen         // Copy the first part of the object
657*5c591343SA. Cody Schuffelen         MemoryCopy(newObject, object, offsetof(HASH_OBJECT, state));
658*5c591343SA. Cody Schuffelen         // See if this is a sequence object
659*5c591343SA. Cody Schuffelen         if(ObjectIsSequence(newObject))
660*5c591343SA. Cody Schuffelen         {
661*5c591343SA. Cody Schuffelen             // If this is a sequence object, import the data
662*5c591343SA. Cody Schuffelen             SequenceDataImport((HASH_OBJECT *)newObject,
663*5c591343SA. Cody Schuffelen                                (HASH_OBJECT_BUFFER *)object);
664*5c591343SA. Cody Schuffelen         }
665*5c591343SA. Cody Schuffelen         else
666*5c591343SA. Cody Schuffelen         {
667*5c591343SA. Cody Schuffelen             // Copy input object data to internal structure
668*5c591343SA. Cody Schuffelen             MemoryCopy(newObject, object, sizeof(OBJECT));
669*5c591343SA. Cody Schuffelen         }
670*5c591343SA. Cody Schuffelen     }
671*5c591343SA. Cody Schuffelen     return newObject;
672*5c591343SA. Cody Schuffelen }
673*5c591343SA. Cody Schuffelen 
674*5c591343SA. Cody Schuffelen //*** FlushObject()
675*5c591343SA. Cody Schuffelen // This function frees an object slot.
676*5c591343SA. Cody Schuffelen //
677*5c591343SA. Cody Schuffelen // This function requires that the object is loaded.
678*5c591343SA. Cody Schuffelen void
FlushObject(TPMI_DH_OBJECT handle)679*5c591343SA. Cody Schuffelen FlushObject(
680*5c591343SA. Cody Schuffelen     TPMI_DH_OBJECT   handle         // IN: handle to be freed
681*5c591343SA. Cody Schuffelen     )
682*5c591343SA. Cody Schuffelen {
683*5c591343SA. Cody Schuffelen     UINT32      index = handle - TRANSIENT_FIRST;
684*5c591343SA. Cody Schuffelen //
685*5c591343SA. Cody Schuffelen     pAssert(index < MAX_LOADED_OBJECTS);
686*5c591343SA. Cody Schuffelen     // Clear all the object attributes
687*5c591343SA. Cody Schuffelen     MemorySet((BYTE*)&(s_objects[index].attributes),
688*5c591343SA. Cody Schuffelen               0, sizeof(OBJECT_ATTRIBUTES));
689*5c591343SA. Cody Schuffelen     return;
690*5c591343SA. Cody Schuffelen }
691*5c591343SA. Cody Schuffelen 
692*5c591343SA. Cody Schuffelen //*** ObjectFlushHierarchy()
693*5c591343SA. Cody Schuffelen // This function is called to flush all the loaded transient objects associated
694*5c591343SA. Cody Schuffelen // with a hierarchy when the hierarchy is disabled.
695*5c591343SA. Cody Schuffelen void
ObjectFlushHierarchy(TPMI_RH_HIERARCHY hierarchy)696*5c591343SA. Cody Schuffelen ObjectFlushHierarchy(
697*5c591343SA. Cody Schuffelen     TPMI_RH_HIERARCHY    hierarchy      // IN: hierarchy to be flush
698*5c591343SA. Cody Schuffelen     )
699*5c591343SA. Cody Schuffelen {
700*5c591343SA. Cody Schuffelen     UINT16          i;
701*5c591343SA. Cody Schuffelen //
702*5c591343SA. Cody Schuffelen     // iterate object slots
703*5c591343SA. Cody Schuffelen     for(i = 0; i < MAX_LOADED_OBJECTS; i++)
704*5c591343SA. Cody Schuffelen     {
705*5c591343SA. Cody Schuffelen         if(s_objects[i].attributes.occupied)          // If found an occupied slot
706*5c591343SA. Cody Schuffelen         {
707*5c591343SA. Cody Schuffelen             switch(hierarchy)
708*5c591343SA. Cody Schuffelen             {
709*5c591343SA. Cody Schuffelen                 case TPM_RH_PLATFORM:
710*5c591343SA. Cody Schuffelen                     if(s_objects[i].attributes.ppsHierarchy == SET)
711*5c591343SA. Cody Schuffelen                         s_objects[i].attributes.occupied = FALSE;
712*5c591343SA. Cody Schuffelen                     break;
713*5c591343SA. Cody Schuffelen                 case TPM_RH_OWNER:
714*5c591343SA. Cody Schuffelen                     if(s_objects[i].attributes.spsHierarchy == SET)
715*5c591343SA. Cody Schuffelen                         s_objects[i].attributes.occupied = FALSE;
716*5c591343SA. Cody Schuffelen                     break;
717*5c591343SA. Cody Schuffelen                 case TPM_RH_ENDORSEMENT:
718*5c591343SA. Cody Schuffelen                     if(s_objects[i].attributes.epsHierarchy == SET)
719*5c591343SA. Cody Schuffelen                         s_objects[i].attributes.occupied = FALSE;
720*5c591343SA. Cody Schuffelen                     break;
721*5c591343SA. Cody Schuffelen                 default:
722*5c591343SA. Cody Schuffelen                     FAIL(FATAL_ERROR_INTERNAL);
723*5c591343SA. Cody Schuffelen                     break;
724*5c591343SA. Cody Schuffelen             }
725*5c591343SA. Cody Schuffelen         }
726*5c591343SA. Cody Schuffelen     }
727*5c591343SA. Cody Schuffelen 
728*5c591343SA. Cody Schuffelen     return;
729*5c591343SA. Cody Schuffelen }
730*5c591343SA. Cody Schuffelen 
731*5c591343SA. Cody Schuffelen //*** ObjectLoadEvict()
732*5c591343SA. Cody Schuffelen // This function loads a persistent object into a transient object slot.
733*5c591343SA. Cody Schuffelen //
734*5c591343SA. Cody Schuffelen // This function requires that 'handle' is associated with a persistent object.
735*5c591343SA. Cody Schuffelen //  Return Type: TPM_RC
736*5c591343SA. Cody Schuffelen //      TPM_RC_HANDLE               the persistent object does not exist
737*5c591343SA. Cody Schuffelen //                                  or the associated hierarchy is disabled.
738*5c591343SA. Cody Schuffelen //      TPM_RC_OBJECT_MEMORY        no object slot
739*5c591343SA. Cody Schuffelen TPM_RC
ObjectLoadEvict(TPM_HANDLE * handle,COMMAND_INDEX commandIndex)740*5c591343SA. Cody Schuffelen ObjectLoadEvict(
741*5c591343SA. Cody Schuffelen     TPM_HANDLE      *handle,        // IN:OUT: evict object handle.  If success, it
742*5c591343SA. Cody Schuffelen                                     // will be replace by the loaded object handle
743*5c591343SA. Cody Schuffelen     COMMAND_INDEX    commandIndex   // IN: the command being processed
744*5c591343SA. Cody Schuffelen     )
745*5c591343SA. Cody Schuffelen {
746*5c591343SA. Cody Schuffelen     TPM_RC          result;
747*5c591343SA. Cody Schuffelen     TPM_HANDLE      evictHandle = *handle;   // Save the evict handle
748*5c591343SA. Cody Schuffelen     OBJECT          *object;
749*5c591343SA. Cody Schuffelen //
750*5c591343SA. Cody Schuffelen     // If this is an index that references a persistent object created by
751*5c591343SA. Cody Schuffelen     // the platform, then return TPM_RH_HANDLE if the phEnable is FALSE
752*5c591343SA. Cody Schuffelen     if(*handle >= PLATFORM_PERSISTENT)
753*5c591343SA. Cody Schuffelen     {
754*5c591343SA. Cody Schuffelen         // belongs to platform
755*5c591343SA. Cody Schuffelen         if(g_phEnable == CLEAR)
756*5c591343SA. Cody Schuffelen             return TPM_RC_HANDLE;
757*5c591343SA. Cody Schuffelen     }
758*5c591343SA. Cody Schuffelen     // belongs to owner
759*5c591343SA. Cody Schuffelen     else if(gc.shEnable == CLEAR)
760*5c591343SA. Cody Schuffelen         return TPM_RC_HANDLE;
761*5c591343SA. Cody Schuffelen     // Try to allocate a slot for an object
762*5c591343SA. Cody Schuffelen     object = ObjectAllocateSlot(handle);
763*5c591343SA. Cody Schuffelen     if(object == NULL)
764*5c591343SA. Cody Schuffelen         return TPM_RC_OBJECT_MEMORY;
765*5c591343SA. Cody Schuffelen     // Copy persistent object to transient object slot.  A TPM_RC_HANDLE
766*5c591343SA. Cody Schuffelen     // may be returned at this point. This will mark the slot as containing
767*5c591343SA. Cody Schuffelen     // a transient object so that it will be flushed at the end of the
768*5c591343SA. Cody Schuffelen     // command
769*5c591343SA. Cody Schuffelen     result = NvGetEvictObject(evictHandle, object);
770*5c591343SA. Cody Schuffelen 
771*5c591343SA. Cody Schuffelen     // Bail out if this failed
772*5c591343SA. Cody Schuffelen     if(result != TPM_RC_SUCCESS)
773*5c591343SA. Cody Schuffelen         return result;
774*5c591343SA. Cody Schuffelen     // check the object to see if it is in the endorsement hierarchy
775*5c591343SA. Cody Schuffelen     // if it is and this is not a TPM2_EvictControl() command, indicate
776*5c591343SA. Cody Schuffelen     // that the hierarchy is disabled.
777*5c591343SA. Cody Schuffelen     // If the associated hierarchy is disabled, make it look like the
778*5c591343SA. Cody Schuffelen     // handle is not defined
779*5c591343SA. Cody Schuffelen     if(ObjectGetHierarchy(object) == TPM_RH_ENDORSEMENT
780*5c591343SA. Cody Schuffelen        && gc.ehEnable == CLEAR
781*5c591343SA. Cody Schuffelen        && GetCommandCode(commandIndex) != TPM_CC_EvictControl)
782*5c591343SA. Cody Schuffelen         return TPM_RC_HANDLE;
783*5c591343SA. Cody Schuffelen 
784*5c591343SA. Cody Schuffelen     return result;
785*5c591343SA. Cody Schuffelen }
786*5c591343SA. Cody Schuffelen 
787*5c591343SA. Cody Schuffelen //*** ObjectComputeName()
788*5c591343SA. Cody Schuffelen // This does the name computation from a public area (can be marshaled or not).
789*5c591343SA. Cody Schuffelen TPM2B_NAME *
ObjectComputeName(UINT32 size,BYTE * publicArea,TPM_ALG_ID nameAlg,TPM2B_NAME * name)790*5c591343SA. Cody Schuffelen ObjectComputeName(
791*5c591343SA. Cody Schuffelen     UINT32           size,          // IN: the size of the area to digest
792*5c591343SA. Cody Schuffelen     BYTE            *publicArea,    // IN: the public area to digest
793*5c591343SA. Cody Schuffelen     TPM_ALG_ID       nameAlg,       // IN: the hash algorithm to use
794*5c591343SA. Cody Schuffelen     TPM2B_NAME      *name           // OUT: Computed name
795*5c591343SA. Cody Schuffelen     )
796*5c591343SA. Cody Schuffelen {
797*5c591343SA. Cody Schuffelen     // Hash the publicArea into the name buffer leaving room for the nameAlg
798*5c591343SA. Cody Schuffelen     name->t.size = CryptHashBlock(nameAlg, size, publicArea,
799*5c591343SA. Cody Schuffelen                                   sizeof(name->t.name) - 2,
800*5c591343SA. Cody Schuffelen                                   &name->t.name[2]);
801*5c591343SA. Cody Schuffelen     // set the nameAlg
802*5c591343SA. Cody Schuffelen     UINT16_TO_BYTE_ARRAY(nameAlg, name->t.name);
803*5c591343SA. Cody Schuffelen     name->t.size += 2;
804*5c591343SA. Cody Schuffelen     return name;
805*5c591343SA. Cody Schuffelen }
806*5c591343SA. Cody Schuffelen 
807*5c591343SA. Cody Schuffelen //*** PublicMarshalAndComputeName()
808*5c591343SA. Cody Schuffelen // This function computes the Name of an object from its public area.
809*5c591343SA. Cody Schuffelen TPM2B_NAME *
PublicMarshalAndComputeName(TPMT_PUBLIC * publicArea,TPM2B_NAME * name)810*5c591343SA. Cody Schuffelen PublicMarshalAndComputeName(
811*5c591343SA. Cody Schuffelen     TPMT_PUBLIC     *publicArea,    // IN: public area of an object
812*5c591343SA. Cody Schuffelen     TPM2B_NAME      *name           // OUT: name of the object
813*5c591343SA. Cody Schuffelen     )
814*5c591343SA. Cody Schuffelen {
815*5c591343SA. Cody Schuffelen     // Will marshal a public area into a template. This is because the internal
816*5c591343SA. Cody Schuffelen     // format for a TPM2B_PUBLIC is a structure and not a simple BYTE buffer.
817*5c591343SA. Cody Schuffelen     TPM2B_TEMPLATE       marshaled;     // this is big enough to hold a
818*5c591343SA. Cody Schuffelen                                         //  marshaled TPMT_PUBLIC
819*5c591343SA. Cody Schuffelen     BYTE                *buffer = (BYTE *)&marshaled.t.buffer;
820*5c591343SA. Cody Schuffelen //
821*5c591343SA. Cody Schuffelen     // if the nameAlg is NULL then there is no name.
822*5c591343SA. Cody Schuffelen     if(publicArea->nameAlg == TPM_ALG_NULL)
823*5c591343SA. Cody Schuffelen         name->t.size = 0;
824*5c591343SA. Cody Schuffelen     else
825*5c591343SA. Cody Schuffelen     {
826*5c591343SA. Cody Schuffelen         // Marshal the public area into its canonical form
827*5c591343SA. Cody Schuffelen         marshaled.t.size = TPMT_PUBLIC_Marshal(publicArea, &buffer, NULL);
828*5c591343SA. Cody Schuffelen         // and compute the name
829*5c591343SA. Cody Schuffelen         ObjectComputeName(marshaled.t.size, marshaled.t.buffer,
830*5c591343SA. Cody Schuffelen                           publicArea->nameAlg, name);
831*5c591343SA. Cody Schuffelen     }
832*5c591343SA. Cody Schuffelen     return name;
833*5c591343SA. Cody Schuffelen }
834*5c591343SA. Cody Schuffelen 
835*5c591343SA. Cody Schuffelen //*** ComputeQualifiedName()
836*5c591343SA. Cody Schuffelen // This function computes the qualified name of an object.
837*5c591343SA. Cody Schuffelen void
ComputeQualifiedName(TPM_HANDLE parentHandle,TPM_ALG_ID nameAlg,TPM2B_NAME * name,TPM2B_NAME * qualifiedName)838*5c591343SA. Cody Schuffelen ComputeQualifiedName(
839*5c591343SA. Cody Schuffelen     TPM_HANDLE       parentHandle,  // IN: parent's handle
840*5c591343SA. Cody Schuffelen     TPM_ALG_ID       nameAlg,       // IN: name hash
841*5c591343SA. Cody Schuffelen     TPM2B_NAME      *name,          // IN: name of the object
842*5c591343SA. Cody Schuffelen     TPM2B_NAME      *qualifiedName  // OUT: qualified name of the object
843*5c591343SA. Cody Schuffelen     )
844*5c591343SA. Cody Schuffelen {
845*5c591343SA. Cody Schuffelen     HASH_STATE      hashState;   // hash state
846*5c591343SA. Cody Schuffelen     TPM2B_NAME      parentName;
847*5c591343SA. Cody Schuffelen //
848*5c591343SA. Cody Schuffelen     if(parentHandle == TPM_RH_UNASSIGNED)
849*5c591343SA. Cody Schuffelen     {
850*5c591343SA. Cody Schuffelen         MemoryCopy2B(&qualifiedName->b, &name->b, sizeof(qualifiedName->t.name));
851*5c591343SA. Cody Schuffelen         *qualifiedName = *name;
852*5c591343SA. Cody Schuffelen     }
853*5c591343SA. Cody Schuffelen     else
854*5c591343SA. Cody Schuffelen     {
855*5c591343SA. Cody Schuffelen         GetQualifiedName(parentHandle, &parentName);
856*5c591343SA. Cody Schuffelen 
857*5c591343SA. Cody Schuffelen         //      QN_A = hash_A (QN of parent || NAME_A)
858*5c591343SA. Cody Schuffelen 
859*5c591343SA. Cody Schuffelen         // Start hash
860*5c591343SA. Cody Schuffelen         qualifiedName->t.size = CryptHashStart(&hashState, nameAlg);
861*5c591343SA. Cody Schuffelen 
862*5c591343SA. Cody Schuffelen         // Add parent's qualified name
863*5c591343SA. Cody Schuffelen         CryptDigestUpdate2B(&hashState, &parentName.b);
864*5c591343SA. Cody Schuffelen 
865*5c591343SA. Cody Schuffelen         // Add self name
866*5c591343SA. Cody Schuffelen         CryptDigestUpdate2B(&hashState, &name->b);
867*5c591343SA. Cody Schuffelen 
868*5c591343SA. Cody Schuffelen         // Complete hash leaving room for the name algorithm
869*5c591343SA. Cody Schuffelen         CryptHashEnd(&hashState, qualifiedName->t.size,
870*5c591343SA. Cody Schuffelen                      &qualifiedName->t.name[2]);
871*5c591343SA. Cody Schuffelen         UINT16_TO_BYTE_ARRAY(nameAlg, qualifiedName->t.name);
872*5c591343SA. Cody Schuffelen         qualifiedName->t.size += 2;
873*5c591343SA. Cody Schuffelen     }
874*5c591343SA. Cody Schuffelen     return;
875*5c591343SA. Cody Schuffelen }
876*5c591343SA. Cody Schuffelen 
877*5c591343SA. Cody Schuffelen //*** ObjectIsStorage()
878*5c591343SA. Cody Schuffelen // This function determines if an object has the attributes associated
879*5c591343SA. Cody Schuffelen // with a parent. A parent is an asymmetric or symmetric block cipher key
880*5c591343SA. Cody Schuffelen // that has its 'restricted' and 'decrypt' attributes SET, and 'sign' CLEAR.
881*5c591343SA. Cody Schuffelen //  Return Type: BOOL
882*5c591343SA. Cody Schuffelen //      TRUE(1)         object is a storage key
883*5c591343SA. Cody Schuffelen //      FALSE(0)        object is not a storage key
884*5c591343SA. Cody Schuffelen BOOL
ObjectIsStorage(TPMI_DH_OBJECT handle)885*5c591343SA. Cody Schuffelen ObjectIsStorage(
886*5c591343SA. Cody Schuffelen     TPMI_DH_OBJECT   handle         // IN: object handle
887*5c591343SA. Cody Schuffelen     )
888*5c591343SA. Cody Schuffelen {
889*5c591343SA. Cody Schuffelen     OBJECT           *object = HandleToObject(handle);
890*5c591343SA. Cody Schuffelen     TPMT_PUBLIC      *publicArea = ((object != NULL) ? &object->publicArea : NULL);
891*5c591343SA. Cody Schuffelen //
892*5c591343SA. Cody Schuffelen     return (publicArea != NULL
893*5c591343SA. Cody Schuffelen             && IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted)
894*5c591343SA. Cody Schuffelen             && IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, decrypt)
895*5c591343SA. Cody Schuffelen             && !IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign)
896*5c591343SA. Cody Schuffelen             && (object->publicArea.type == TPM_ALG_RSA
897*5c591343SA. Cody Schuffelen                 || object->publicArea.type == TPM_ALG_ECC));
898*5c591343SA. Cody Schuffelen }
899*5c591343SA. Cody Schuffelen 
900*5c591343SA. Cody Schuffelen //*** ObjectCapGetLoaded()
901*5c591343SA. Cody Schuffelen // This function returns a a list of handles of loaded object, starting from
902*5c591343SA. Cody Schuffelen // 'handle'. 'Handle' must be in the range of valid transient object handles,
903*5c591343SA. Cody Schuffelen // but does not have to be the handle of a loaded transient object.
904*5c591343SA. Cody Schuffelen //  Return Type: TPMI_YES_NO
905*5c591343SA. Cody Schuffelen //      YES         if there are more handles available
906*5c591343SA. Cody Schuffelen //      NO          all the available handles has been returned
907*5c591343SA. Cody Schuffelen TPMI_YES_NO
ObjectCapGetLoaded(TPMI_DH_OBJECT handle,UINT32 count,TPML_HANDLE * handleList)908*5c591343SA. Cody Schuffelen ObjectCapGetLoaded(
909*5c591343SA. Cody Schuffelen     TPMI_DH_OBJECT   handle,        // IN: start handle
910*5c591343SA. Cody Schuffelen     UINT32           count,         // IN: count of returned handles
911*5c591343SA. Cody Schuffelen     TPML_HANDLE     *handleList     // OUT: list of handle
912*5c591343SA. Cody Schuffelen     )
913*5c591343SA. Cody Schuffelen {
914*5c591343SA. Cody Schuffelen     TPMI_YES_NO          more = NO;
915*5c591343SA. Cody Schuffelen     UINT32               i;
916*5c591343SA. Cody Schuffelen //
917*5c591343SA. Cody Schuffelen     pAssert(HandleGetType(handle) == TPM_HT_TRANSIENT);
918*5c591343SA. Cody Schuffelen 
919*5c591343SA. Cody Schuffelen     // Initialize output handle list
920*5c591343SA. Cody Schuffelen     handleList->count = 0;
921*5c591343SA. Cody Schuffelen 
922*5c591343SA. Cody Schuffelen     // The maximum count of handles we may return is MAX_CAP_HANDLES
923*5c591343SA. Cody Schuffelen     if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
924*5c591343SA. Cody Schuffelen 
925*5c591343SA. Cody Schuffelen     // Iterate object slots to get loaded object handles
926*5c591343SA. Cody Schuffelen     for(i = handle - TRANSIENT_FIRST; i < MAX_LOADED_OBJECTS; i++)
927*5c591343SA. Cody Schuffelen     {
928*5c591343SA. Cody Schuffelen         if(s_objects[i].attributes.occupied == TRUE)
929*5c591343SA. Cody Schuffelen         {
930*5c591343SA. Cody Schuffelen             // A valid transient object can not be the copy of a persistent object
931*5c591343SA. Cody Schuffelen             pAssert(s_objects[i].attributes.evict == CLEAR);
932*5c591343SA. Cody Schuffelen 
933*5c591343SA. Cody Schuffelen             if(handleList->count < count)
934*5c591343SA. Cody Schuffelen             {
935*5c591343SA. Cody Schuffelen                 // If we have not filled up the return list, add this object
936*5c591343SA. Cody Schuffelen                 // handle to it
937*5c591343SA. Cody Schuffelen                 handleList->handle[handleList->count] = i + TRANSIENT_FIRST;
938*5c591343SA. Cody Schuffelen                 handleList->count++;
939*5c591343SA. Cody Schuffelen             }
940*5c591343SA. Cody Schuffelen             else
941*5c591343SA. Cody Schuffelen             {
942*5c591343SA. Cody Schuffelen                 // If the return list is full but we still have loaded object
943*5c591343SA. Cody Schuffelen                 // available, report this and stop iterating
944*5c591343SA. Cody Schuffelen                 more = YES;
945*5c591343SA. Cody Schuffelen                 break;
946*5c591343SA. Cody Schuffelen             }
947*5c591343SA. Cody Schuffelen         }
948*5c591343SA. Cody Schuffelen     }
949*5c591343SA. Cody Schuffelen 
950*5c591343SA. Cody Schuffelen     return more;
951*5c591343SA. Cody Schuffelen }
952*5c591343SA. Cody Schuffelen 
953*5c591343SA. Cody Schuffelen //*** ObjectCapGetTransientAvail()
954*5c591343SA. Cody Schuffelen // This function returns an estimate of the number of additional transient
955*5c591343SA. Cody Schuffelen // objects that could be loaded into the TPM.
956*5c591343SA. Cody Schuffelen UINT32
ObjectCapGetTransientAvail(void)957*5c591343SA. Cody Schuffelen ObjectCapGetTransientAvail(
958*5c591343SA. Cody Schuffelen     void
959*5c591343SA. Cody Schuffelen     )
960*5c591343SA. Cody Schuffelen {
961*5c591343SA. Cody Schuffelen     UINT32      i;
962*5c591343SA. Cody Schuffelen     UINT32      num = 0;
963*5c591343SA. Cody Schuffelen //
964*5c591343SA. Cody Schuffelen     // Iterate object slot to get the number of unoccupied slots
965*5c591343SA. Cody Schuffelen     for(i = 0; i < MAX_LOADED_OBJECTS; i++)
966*5c591343SA. Cody Schuffelen     {
967*5c591343SA. Cody Schuffelen         if(s_objects[i].attributes.occupied == FALSE) num++;
968*5c591343SA. Cody Schuffelen     }
969*5c591343SA. Cody Schuffelen 
970*5c591343SA. Cody Schuffelen     return num;
971*5c591343SA. Cody Schuffelen }
972*5c591343SA. Cody Schuffelen 
973*5c591343SA. Cody Schuffelen //*** ObjectGetPublicAttributes()
974*5c591343SA. Cody Schuffelen // Returns the attributes associated with an object handles.
975*5c591343SA. Cody Schuffelen TPMA_OBJECT
ObjectGetPublicAttributes(TPM_HANDLE handle)976*5c591343SA. Cody Schuffelen ObjectGetPublicAttributes(
977*5c591343SA. Cody Schuffelen     TPM_HANDLE       handle
978*5c591343SA. Cody Schuffelen     )
979*5c591343SA. Cody Schuffelen {
980*5c591343SA. Cody Schuffelen     return HandleToObject(handle)->publicArea.objectAttributes;
981*5c591343SA. Cody Schuffelen }
982*5c591343SA. Cody Schuffelen 
983*5c591343SA. Cody Schuffelen OBJECT_ATTRIBUTES
ObjectGetProperties(TPM_HANDLE handle)984*5c591343SA. Cody Schuffelen ObjectGetProperties(
985*5c591343SA. Cody Schuffelen     TPM_HANDLE       handle
986*5c591343SA. Cody Schuffelen     )
987*5c591343SA. Cody Schuffelen {
988*5c591343SA. Cody Schuffelen     return HandleToObject(handle)->attributes;
989*5c591343SA. Cody Schuffelen }