// 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 container.
    MemorySet(*object, 0, sizeof(**object));
    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
   INT32                      bufferSize;
   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;
   bufferSize = sizeof(TPMT_PUBLIC);
   marshalBuffer.t.size = TPMT_PUBLIC_Marshal(publicArea, &buffer, &bufferSize);
   // 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;
}
