// This file was extracted from the TCG Published
// Trusted Platform Module Library
// Part 4: Supporting Routines
// Family "2.0"
// Level 00 Revision 01.16
// October 30, 2014

#define OBJECT_C
#include "InternalRoutines.h"
#include <Platform.h>
//
//
//            Functions
//
//             ObjectStartup()
//
//       This function is called at TPM2_Startup() to initialize the object subsystem.
//
void
ObjectStartup(
     void
     )
{
     UINT32        i;
     // object slots initialization
     for(i = 0; i < MAX_LOADED_OBJECTS; i++)
     {
         //Set the slot to not occupied
         s_objects[i].occupied = FALSE;
     }
     return;
}
//
//
//             ObjectCleanupEvict()
//
//       In this implementation, a persistent object is moved from NV into an object slot for processing. It is
//       flushed after command execution. This function is called from ExecuteCommand().
//
void
ObjectCleanupEvict(
     void
     )
{
     UINT32        i;
     // This has to be iterated because a command may have two handles
     // and they may both be persistent.
     // This could be made to be more efficient so that a search is not needed.
     for(i = 0; i < MAX_LOADED_OBJECTS; i++)
     {
         // If an object is a temporary evict object, flush it from slot
         if(s_objects[i].object.entity.attributes.evict == SET)
             s_objects[i].occupied = FALSE;
     }
   return;
}
//
//
//          ObjectIsPresent()
//
//     This function checks to see if a transient handle references a loaded object. This routine should not be
//     called if the handle is not a transient handle. The function validates that the handle is in the
//     implementation-dependent allowed in range for loaded transient objects.
//
//     Return Value                      Meaning
//
//     TRUE                              if the handle references a loaded object
//     FALSE                             if the handle is not an object handle, or it does not reference to a
//                                       loaded object
//
BOOL
ObjectIsPresent(
   TPMI_DH_OBJECT        handle              // IN: handle to be checked
   )
{
   UINT32              slotIndex;                  // index of object slot
   pAssert(HandleGetType(handle) == TPM_HT_TRANSIENT);
   // The index in the loaded object array is found by subtracting the first
   // object handle number from the input handle number. If the indicated
   // slot is occupied, then indicate that there is already is a loaded
   // object associated with the handle.
   slotIndex = handle - TRANSIENT_FIRST;
   if(slotIndex >= MAX_LOADED_OBJECTS)
       return FALSE;
   return s_objects[slotIndex].occupied;
}
//
//
//          ObjectIsSequence()
//
//     This function is used to check if the object is a sequence object. This function should not be called if the
//     handle does not reference a loaded object.
//
//     Return Value                      Meaning
//
//     TRUE                              object is an HMAC, hash, or event sequence object
//     FALSE                             object is not an HMAC, hash, or event sequence object
//
BOOL
ObjectIsSequence(
   OBJECT              *object               // IN: handle to be checked
   )
{
   pAssert (object != NULL);
   if(   object->attributes.hmacSeq == SET
      || object->attributes.hashSeq == SET
      || object->attributes.eventSeq == SET)
       return TRUE;
   else
       return FALSE;
}
//
//
//           ObjectGet()
//
//      This function is used to find the object structure associated with a handle.
//      This function requires that handle references a loaded object.
//
OBJECT*
ObjectGet(
    TPMI_DH_OBJECT       handle             // IN: handle of the object
    )
{
    pAssert(   handle >= TRANSIENT_FIRST
            && handle - TRANSIENT_FIRST < MAX_LOADED_OBJECTS);
    pAssert(s_objects[handle - TRANSIENT_FIRST].occupied == TRUE);
    // In this implementation, the handle is determined by the slot occupied by the
    // object.
    return &s_objects[handle - TRANSIENT_FIRST].object.entity;
}
//
//
//           ObjectGetName()
//
//      This function is used to access the Name of the object. In this implementation, the Name is computed
//      when the object is loaded and is saved in the internal representation of the object. This function copies
//      the Name data from the object into the buffer at name and returns the number of octets copied.
//      This function requires that handle references a loaded object.
//
UINT16
ObjectGetName(
    TPMI_DH_OBJECT       handle,            // IN: handle of the object
    NAME                *name               // OUT: name of the object
    )
{
    OBJECT      *object = ObjectGet(handle);
    if(object->publicArea.nameAlg == TPM_ALG_NULL)
        return 0;
    // Copy the Name data to the output
    MemoryCopy(name, object->name.t.name, object->name.t.size, sizeof(NAME));
    return object->name.t.size;
}
//
//
//           ObjectGetNameAlg()
//
//      This function is used to get the Name algorithm of a object.
//      This function requires that handle references a loaded object.
//
TPMI_ALG_HASH
ObjectGetNameAlg(
    TPMI_DH_OBJECT       handle             // IN: handle of the object
    )
{
    OBJECT                   *object = ObjectGet(handle);
    return object->publicArea.nameAlg;
}
//
//
//
//           ObjectGetQualifiedName()
//
//      This function returns the Qualified Name of the object. In this implementation, the Qualified Name is
//      computed when the object is loaded and is saved in the internal representation of the object. The
//      alternative would be to retain the Name of the parent and compute the QN when needed. This would take
//      the same amount of space so it is not recommended that the alternate be used.
//      This function requires that handle references a loaded object.
//
void
ObjectGetQualifiedName(
    TPMI_DH_OBJECT       handle,            // IN: handle of the object
    TPM2B_NAME          *qualifiedName      // OUT: qualified name of the object
    )
{
    OBJECT      *object = ObjectGet(handle);
    if(object->publicArea.nameAlg == TPM_ALG_NULL)
        qualifiedName->t.size = 0;
    else
        // Copy the name
        *qualifiedName = object->qualifiedName;
    return;
}
//
//
//           ObjectDataGetHierarchy()
//
//      This function returns the handle for the hierarchy of an object.
//
TPMI_RH_HIERARCHY
ObjectDataGetHierarchy(
    OBJECT              *object             // IN :object
    )
{
    if(object->attributes.spsHierarchy)
    {
        return TPM_RH_OWNER;
    }
    else if(object->attributes.epsHierarchy)
    {
        return TPM_RH_ENDORSEMENT;
    }
    else if(object->attributes.ppsHierarchy)
    {
        return TPM_RH_PLATFORM;
    }
    else
    {
        return TPM_RH_NULL;
    }
}
//
//
//          ObjectGetHierarchy()
//
//      This function returns the handle of the hierarchy to which a handle belongs. This function is similar to
//      ObjectDataGetHierarchy() but this routine takes a handle but ObjectDataGetHierarchy() takes an pointer
//      to an object.
//      This function requires that handle references a loaded object.
//
TPMI_RH_HIERARCHY
ObjectGetHierarchy(
    TPMI_DH_OBJECT        handle              // IN :object handle
    )
{
    OBJECT               *object = ObjectGet(handle);
    return ObjectDataGetHierarchy(object);
}
//
//
//           ObjectAllocateSlot()
//
//      This function is used to allocate a slot in internal object array.
//
//      Return Value                       Meaning
//
//      TRUE                               allocate success
//      FALSE                              do not have free slot
//
static BOOL
ObjectAllocateSlot(
    TPMI_DH_OBJECT       *handle,             // OUT: handle of allocated object
    OBJECT               **object             // OUT: points to the allocated object
    )
{
    UINT32          i;
    // find an unoccupied handle slot
    for(i = 0; i < MAX_LOADED_OBJECTS; i++)
    {
        if(!s_objects[i].occupied)          // If found a free slot
        {
            // Mark the slot as occupied
            s_objects[i].occupied = TRUE;
            break;
        }
    }
    // If we reach the end of object slot without finding a free one, return
    // error.
    if(i == MAX_LOADED_OBJECTS) return FALSE;
    *handle = i + TRANSIENT_FIRST;
    *object = &s_objects[i].object.entity;
    // Initialize the object attributes
    MemorySet(&((*object)->attributes), 0, sizeof(OBJECT_ATTRIBUTES));
    return TRUE;
}
//
//
//           ObjectLoad()
//
//      This function loads an object into an internal object structure. If an error is returned, the internal state is
//      unchanged.
//
//
//
//
//      Error Returns                     Meaning
//
//      TPM_RC_BINDING                    if the public and sensitive parts of the object are not matched
//      TPM_RC_KEY                        if the parameters in the public area of the object are not consistent
//      TPM_RC_OBJECT_MEMORY              if there is no free slot for an object
//      TPM_RC_TYPE                       the public and private parts are not the same type
//
TPM_RC
ObjectLoad(
   TPMI_RH_HIERARCHY        hierarchy,               //   IN: hierarchy to which the object belongs
   TPMT_PUBLIC             *publicArea,              //   IN: public area
   TPMT_SENSITIVE          *sensitive,               //   IN: sensitive area (may be null)
   TPM2B_NAME              *name,                    //   IN: object's name (may be null)
   TPM_HANDLE               parentHandle,            //   IN: handle of parent
   BOOL                     skipChecks,              //   IN: flag to indicate if it is OK to skip
                                                     //       consistency checks.
   TPMI_DH_OBJECT          *handle                   //   OUT: object handle
   )
{
   OBJECT                   *object = NULL;
   OBJECT                   *parent = NULL;
   TPM_RC                    result = TPM_RC_SUCCESS;
   TPM2B_NAME                parentQN;         // Parent qualified name
   // Try to allocate a slot for new object
   if(!ObjectAllocateSlot(handle, &object))
       return TPM_RC_OBJECT_MEMORY;
   // Initialize public
   object->publicArea = *publicArea;
   if(sensitive != NULL)
       object->sensitive = *sensitive;
   // Are the consistency checks needed
   if(!skipChecks)
   {
       // Check if key size matches
       if(!CryptObjectIsPublicConsistent(&object->publicArea))
       {
           result = TPM_RC_KEY;
           goto ErrorExit;
       }
       if(sensitive != NULL)
       {
           // Check if public type matches sensitive type
           result = CryptObjectPublicPrivateMatch(object);
           if(result != TPM_RC_SUCCESS)
               goto ErrorExit;
       }
   }
   object->attributes.publicOnly = (sensitive == NULL);
   // If 'name' is NULL, then there is nothing left to do for this
   // object as it has no qualified name and it is not a member of any
   // hierarchy and it is temporary
   if(name == NULL || name->t.size == 0)
   {
       object->qualifiedName.t.size = 0;
       object->name.t.size = 0;
       object->attributes.temporary = SET;
       return TPM_RC_SUCCESS;
   }
   // If parent handle is a permanent handle, it is a primary or temporary
   // object
   if(HandleGetType(parentHandle) == TPM_HT_PERMANENT)
   {
       // initialize QN
       parentQN.t.size = 4;
        // for a primary key, parent qualified name is the handle of hierarchy
        UINT32_TO_BYTE_ARRAY(parentHandle, parentQN.t.name);
   }
   else
   {
       // Get hierarchy and qualified name of parent
       ObjectGetQualifiedName(parentHandle, &parentQN);
        // Check for stClear object
        parent = ObjectGet(parentHandle);
        if(    publicArea->objectAttributes.stClear == SET
            || parent->attributes.stClear == SET)
             object->attributes.stClear = SET;
   }
   object->name = *name;
   // Compute object qualified name
   ObjectComputeQualifiedName(&parentQN, publicArea->nameAlg,
                              name, &object->qualifiedName);
   // Any object in TPM_RH_NULL hierarchy is temporary
   if(hierarchy == TPM_RH_NULL)
   {
       object->attributes.temporary = SET;
   }
   else if(parentQN.t.size == sizeof(TPM_HANDLE))
   {
       // Otherwise, if the size of parent's qualified name is the size of a
       // handle, this object is a primary object
       object->attributes.primary = SET;
   }
   switch(hierarchy)
   {
       case TPM_RH_PLATFORM:
           object->attributes.ppsHierarchy = SET;
           break;
       case TPM_RH_OWNER:
           object->attributes.spsHierarchy = SET;
           break;
       case TPM_RH_ENDORSEMENT:
           object->attributes.epsHierarchy = SET;
           break;
       case TPM_RH_NULL:
           break;
       default:
           pAssert(FALSE);
           break;
   }
   return TPM_RC_SUCCESS;
ErrorExit:
   ObjectFlush(*handle);
   return result;
}
//
//
//
//          AllocateSequenceSlot()
//
//      This function allocates a sequence slot and initializes the parts that are used by the normal objects so
//      that a sequence object is not inadvertently used for an operation that is not appropriate for a sequence.
//
static BOOL
AllocateSequenceSlot(
   TPM_HANDLE          *newHandle,             // OUT: receives the allocated handle
   HASH_OBJECT         **object,               // OUT: receives pointer to allocated object
   TPM2B_AUTH          *auth                   // IN: the authValue for the slot
   )
{
   OBJECT                   *objectHash;                   // the hash as an object
   if(!ObjectAllocateSlot(newHandle, &objectHash))
       return FALSE;
   *object = (HASH_OBJECT *)objectHash;
   // Validate that the proper location of the hash state data relative to the
   // object state data.
   pAssert(&((*object)->auth) == &objectHash->publicArea.authPolicy);
   // Set the common values that a sequence object shares with an ordinary object
   // The type is TPM_ALG_NULL
   (*object)->type = TPM_ALG_NULL;
   // This has no name algorithm and the name is the Empty Buffer
   (*object)->nameAlg = TPM_ALG_NULL;
   // Clear the attributes
   MemorySet(&((*object)->objectAttributes), 0, sizeof(TPMA_OBJECT));
   // A sequence object is considered to be in the NULL hierarchy so it should
   // be marked as temporary so that it can't be persisted
   (*object)->attributes.temporary = SET;
   // A sequence object is DA exempt.
   (*object)->objectAttributes.noDA = SET;
   if(auth != NULL)
   {
       MemoryRemoveTrailingZeros(auth);
       (*object)->auth = *auth;
   }
   else
       (*object)->auth.t.size = 0;
   return TRUE;
}
//
//
//          ObjectCreateHMACSequence()
//
//      This function creates an internal HMAC sequence object.
//
//      Error Returns                     Meaning
//
//      TPM_RC_OBJECT_MEMORY              if there is no free slot for an object
//
TPM_RC
ObjectCreateHMACSequence(
   TPMI_ALG_HASH        hashAlg,               // IN: hash algorithm
   TPM_HANDLE           handle,                // IN: the handle associated with sequence
                                               //     object
   TPM2B_AUTH         *auth,                 // IN: authValue
   TPMI_DH_OBJECT     *newHandle             // OUT: HMAC sequence object handle
   )
{
   HASH_OBJECT               *hmacObject;
   OBJECT                    *keyObject;
   // Try to allocate a slot for new object
   if(!AllocateSequenceSlot(newHandle, &hmacObject, auth))
       return TPM_RC_OBJECT_MEMORY;
   // Set HMAC sequence bit
   hmacObject->attributes.hmacSeq = SET;
   // Get pointer to the HMAC key object
   keyObject = ObjectGet(handle);
   CryptStartHMACSequence2B(hashAlg, &keyObject->sensitive.sensitive.bits.b,
                            &hmacObject->state.hmacState);
   return TPM_RC_SUCCESS;
}
//
//
//         ObjectCreateHashSequence()
//
//      This function creates a hash sequence object.
//
//      Error Returns                   Meaning
//
//      TPM_RC_OBJECT_MEMORY            if there is no free slot for an object
//
TPM_RC
ObjectCreateHashSequence(
   TPMI_ALG_HASH       hashAlg,              // IN: hash algorithm
   TPM2B_AUTH         *auth,                 // IN: authValue
   TPMI_DH_OBJECT     *newHandle             // OUT: sequence object handle
   )
{
   HASH_OBJECT               *hashObject;
   // Try to allocate a slot for new object
   if(!AllocateSequenceSlot(newHandle, &hashObject, auth))
       return TPM_RC_OBJECT_MEMORY;
   // Set hash sequence bit
   hashObject->attributes.hashSeq = SET;
   // Start hash for hash sequence
   CryptStartHashSequence(hashAlg, &hashObject->state.hashState[0]);
   return TPM_RC_SUCCESS;
}
//
//
//         ObjectCreateEventSequence()
//
//      This function creates an event sequence object.
//
//      Error Returns                   Meaning
//
//      TPM_RC_OBJECT_MEMORY            if there is no free slot for an object
//
TPM_RC
ObjectCreateEventSequence(
   TPM2B_AUTH          *auth,              // IN: authValue
   TPMI_DH_OBJECT      *newHandle          // OUT: sequence object handle
   )
{
   HASH_OBJECT              *hashObject;
   UINT32                    count;
   TPM_ALG_ID                hash;
   // Try to allocate a slot for new object
   if(!AllocateSequenceSlot(newHandle, &hashObject, auth))
       return TPM_RC_OBJECT_MEMORY;
   // Set the event sequence attribute
   hashObject->attributes.eventSeq = SET;
   // Initialize hash states for each implemented PCR algorithms
   for(count = 0; (hash = CryptGetHashAlgByIndex(count)) != TPM_ALG_NULL; count++)
   {
       // If this is a _TPM_Init or _TPM_HashStart, the sequence object will
       // not leave the TPM so it doesn't need the sequence handling
       if(auth == NULL)
            CryptStartHash(hash, &hashObject->state.hashState[count]);
       else
            CryptStartHashSequence(hash, &hashObject->state.hashState[count]);
   }
   return TPM_RC_SUCCESS;
}
//
//
//          ObjectTerminateEvent()
//
//      This function is called to close out the event sequence and clean up the hash context states.
//
void
ObjectTerminateEvent(
   void
   )
{
   HASH_OBJECT         *hashObject;
   int                  count;
   BYTE                 buffer[MAX_DIGEST_SIZE];
   hashObject = (HASH_OBJECT *)ObjectGet(g_DRTMHandle);
   // Don't assume that this is a proper sequence object
   if(hashObject->attributes.eventSeq)
   {
       // If it is, close any open hash contexts. This is done in case
       // the crypto implementation has some context values that need to be
       // cleaned up (hygiene).
       //
       for(count = 0; CryptGetHashAlgByIndex(count) != TPM_ALG_NULL; count++)
       {
           CryptCompleteHash(&hashObject->state.hashState[count], 0, buffer);
       }
       // Flush sequence object
       ObjectFlush(g_DRTMHandle);
   }
   g_DRTMHandle = TPM_RH_UNASSIGNED;
}
//
//
//
//          ObjectContextLoad()
//
//      This function loads an object from a saved object context.
//
//      Error Returns                     Meaning
//
//      TPM_RC_OBJECT_MEMORY              if there is no free slot for an object
//
TPM_RC
ObjectContextLoad(
    OBJECT              *object,               // IN: object structure from saved context
    TPMI_DH_OBJECT      *handle                // OUT: object handle
    )
{
    OBJECT         *newObject;
    // Try to allocate a slot for new object
    if(!ObjectAllocateSlot(handle, &newObject))
        return TPM_RC_OBJECT_MEMORY;
    // Copy input object data to internal structure
    *newObject = *object;
    return TPM_RC_SUCCESS;
}
//
//
//          ObjectFlush()
//
//      This function frees an object slot.
//      This function requires that the object is loaded.
//
void
ObjectFlush(
    TPMI_DH_OBJECT        handle               // IN: handle to be freed
    )
{
    UINT32      index = handle - TRANSIENT_FIRST;
    pAssert(ObjectIsPresent(handle));
    // Mark the handle slot as unoccupied
    s_objects[index].occupied = FALSE;
    // With no attributes
    MemorySet((BYTE*)&(s_objects[index].object.entity.attributes),
               0, sizeof(OBJECT_ATTRIBUTES));
    return;
}
//
//
//          ObjectFlushHierarchy()
//
//      This function is called to flush all the loaded transient objects associated with a hierarchy when the
//      hierarchy is disabled.
//
void
ObjectFlushHierarchy(
    TPMI_RH_HIERARCHY          hierarchy             // IN: hierarchy to be flush
    )
{
    UINT16              i;
    // iterate object slots
    for(i = 0; i < MAX_LOADED_OBJECTS; i++)
    {
        if(s_objects[i].occupied)           // If found an occupied slot
        {
            switch(hierarchy)
            {
                case TPM_RH_PLATFORM:
                    if(s_objects[i].object.entity.attributes.ppsHierarchy == SET)
                         s_objects[i].occupied = FALSE;
                    break;
                case TPM_RH_OWNER:
                    if(s_objects[i].object.entity.attributes.spsHierarchy == SET)
                         s_objects[i].occupied = FALSE;
                    break;
                case TPM_RH_ENDORSEMENT:
                    if(s_objects[i].object.entity.attributes.epsHierarchy == SET)
                         s_objects[i].occupied = FALSE;
                    break;
                default:
                    pAssert(FALSE);
                    break;
            }
        }
    }
    return;
}
//
//
//           ObjectLoadEvict()
//
//      This function loads a persistent object into a transient object slot.
//      This function requires that handle is associated with a persistent object.
//
//      Error Returns                     Meaning
//
//      TPM_RC_HANDLE                     the persistent object does not exist or the associated hierarchy is
//                                        disabled.
//      TPM_RC_OBJECT_MEMORY              no object slot
//
TPM_RC
ObjectLoadEvict(
    TPM_HANDLE           *handle,             // IN:OUT: evict object handle. If success, it
                                              // will be replace by the loaded object handle
    TPM_CC                commandCode         // IN: the command being processed
    )
{
    TPM_RC               result;
    TPM_HANDLE           evictHandle = *handle;           // Save the evict handle
    OBJECT               *object;
    // If this is an index that references a persistent object created by
    // the platform, then return TPM_RH_HANDLE if the phEnable is FALSE
    if(*handle >= PLATFORM_PERSISTENT)
    {
        // belongs to platform
        if(g_phEnable == CLEAR)
            return TPM_RC_HANDLE;
    }
    // belongs to owner
    else if(gc.shEnable == CLEAR)
        return TPM_RC_HANDLE;
   // Try to allocate a slot for an object
   if(!ObjectAllocateSlot(handle, &object))
       return TPM_RC_OBJECT_MEMORY;
   // Copy persistent object to transient object slot. A TPM_RC_HANDLE
   // may be returned at this point. This will mark the slot as containing
   // a transient object so that it will be flushed at the end of the
   // command
   result = NvGetEvictObject(evictHandle, object);
   // Bail out if this failed
   if(result != TPM_RC_SUCCESS)
       return result;
   // check the object to see if it is in the endorsement hierarchy
   // if it is and this is not a TPM2_EvictControl() command, indicate
   // that the hierarchy is disabled.
   // If the associated hierarchy is disabled, make it look like the
   // handle is not defined
   if(     ObjectDataGetHierarchy(object) == TPM_RH_ENDORSEMENT
        && gc.ehEnable == CLEAR
        && commandCode != TPM_CC_EvictControl
      )
        return TPM_RC_HANDLE;
   return result;
}
//
//
//          ObjectComputeName()
//
//      This function computes the Name of an object from its public area.
//
void
ObjectComputeName(
   TPMT_PUBLIC         *publicArea,       // IN: public area of an object
   TPM2B_NAME          *name              // OUT: name of the object
   )
{
   TPM2B_PUBLIC               marshalBuffer;
   BYTE                      *buffer;               // auxiliary marshal buffer pointer
   HASH_STATE                 hashState;            // hash state
   // if the nameAlg is NULL then there is no name.
   if(publicArea->nameAlg == TPM_ALG_NULL)
   {
       name->t.size = 0;
       return;
   }
   // Start hash stack
   name->t.size = CryptStartHash(publicArea->nameAlg, &hashState);
   // Marshal the public area into its canonical form
   buffer = marshalBuffer.b.buffer;
   marshalBuffer.t.size = TPMT_PUBLIC_Marshal(publicArea, &buffer, NULL);
   // Adding public area
   CryptUpdateDigest2B(&hashState, &marshalBuffer.b);
   // Complete hash leaving room for the name algorithm
   CryptCompleteHash(&hashState, name->t.size, &name->t.name[2]);
   // set the nameAlg
   UINT16_TO_BYTE_ARRAY(publicArea->nameAlg, name->t.name);
//
   name->t.size += 2;
   return;
}
//
//
//          ObjectComputeQualifiedName()
//
//      This function computes the qualified name of an object.
//
void
ObjectComputeQualifiedName(
   TPM2B_NAME          *parentQN,             //   IN: parent's qualified name
   TPM_ALG_ID           nameAlg,              //   IN: name hash
   TPM2B_NAME          *name,                 //   IN: name of the object
   TPM2B_NAME          *qualifiedName         //   OUT: qualified name of the object
   )
{
   HASH_STATE          hashState;         // hash state
   //         QN_A = hash_A (QN of parent || NAME_A)
   // Start hash
   qualifiedName->t.size = CryptStartHash(nameAlg, &hashState);
   // Add parent's qualified name
   CryptUpdateDigest2B(&hashState, &parentQN->b);
   // Add self name
   CryptUpdateDigest2B(&hashState, &name->b);
   // Complete hash leaving room for the name algorithm
   CryptCompleteHash(&hashState, qualifiedName->t.size,
                     &qualifiedName->t.name[2]);
   UINT16_TO_BYTE_ARRAY(nameAlg, qualifiedName->t.name);
   qualifiedName->t.size += 2;
   return;
}
//
//
//          ObjectDataIsStorage()
//
//      This function determines if a public area has the attributes associated with a storage key. A storage key is
//      an asymmetric object that has its restricted and decrypt attributes SET, and sign CLEAR.
//
//      Return Value                      Meaning
//
//      TRUE                              if the object is a storage key
//      FALSE                             if the object is not a storage key
//
BOOL
ObjectDataIsStorage(
   TPMT_PUBLIC         *publicArea            // IN: public area of the object
   )
{
   if(   CryptIsAsymAlgorithm(publicArea->type)                          //   must be asymmetric,
      && publicArea->objectAttributes.restricted == SET                  //   restricted,
      && publicArea->objectAttributes.decrypt == SET                     //   decryption key
      && publicArea->objectAttributes.sign == CLEAR                      //   can not be sign key
     )
       return TRUE;
   else
       return FALSE;
}
//
//          ObjectIsStorage()
//
//      This function determines if an object has the attributes associated with a storage key. A storage key is an
//      asymmetric object that has its restricted and decrypt attributes SET, and sign CLEAR.
//
//      Return Value                    Meaning
//
//      TRUE                            if the object is a storage key
//      FALSE                           if the object is not a storage key
//
BOOL
ObjectIsStorage(
     TPMI_DH_OBJECT     handle              // IN: object handle
     )
{
     OBJECT           *object = ObjectGet(handle);
     return ObjectDataIsStorage(&object->publicArea);
}
//
//
//          ObjectCapGetLoaded()
//
//      This function returns a a list of handles of loaded object, starting from handle. Handle must be in the
//      range of valid transient object handles, but does not have to be the handle of a loaded transient object.
//
//      Return Value                    Meaning
//
//      YES                             if there are more handles available
//      NO                              all the available handles has been returned
//
TPMI_YES_NO
ObjectCapGetLoaded(
     TPMI_DH_OBJECT     handle,             // IN: start handle
     UINT32             count,              // IN: count of returned handles
     TPML_HANDLE       *handleList          // OUT: list of handle
     )
{
     TPMI_YES_NO             more = NO;
     UINT32                  i;
     pAssert(HandleGetType(handle) == TPM_HT_TRANSIENT);
     // Initialize output handle list
     handleList->count = 0;
     // The maximum count of handles we may return is MAX_CAP_HANDLES
     if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
     // Iterate object slots to get loaded object handles
     for(i = handle - TRANSIENT_FIRST; i < MAX_LOADED_OBJECTS; i++)
     {
         if(s_objects[i].occupied == TRUE)
         {
             // A valid transient object can not be the copy of a persistent object
             pAssert(s_objects[i].object.entity.attributes.evict == CLEAR);
              if(handleList->count < count)
              {
                  // If we have not filled up the return list, add this object
                  // handle to it
                  handleList->handle[handleList->count] = i + TRANSIENT_FIRST;
                  handleList->count++;
//
                 }
                 else
                 {
                     // If the return list is full but we still have loaded object
                     // available, report this and stop iterating
                     more = YES;
                     break;
                 }
          }
     }
     return more;
}
//
//
//             ObjectCapGetTransientAvail()
//
//      This function returns an estimate of the number of additional transient objects that could be loaded into
//      the TPM.
//
UINT32
ObjectCapGetTransientAvail(
     void
     )
{
     UINT32          i;
     UINT32          num = 0;
     // Iterate object slot to get the number of unoccupied slots
     for(i = 0; i < MAX_LOADED_OBJECTS; i++)
     {
         if(s_objects[i].occupied == FALSE) num++;
     }
     return num;
}
