/* Microsoft Reference Implementation for TPM 2.0
 *
 *  The copyright in this software is being made available under the BSD License,
 *  included below. This software may be subject to other third party and
 *  contributor rights, including patent rights, and no such rights are granted
 *  under this license.
 *
 *  Copyright (c) Microsoft Corporation
 *
 *  All rights reserved.
 *
 *  BSD License
 *
 *  Redistribution and use in source and binary forms, with or without modification,
 *  are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice, this list
 *  of conditions and the following disclaimer.
 *
 *  Redistributions in binary form must reproduce the above copyright notice, this
 *  list of conditions and the following disclaimer in the documentation and/or
 *  other materials provided with the distribution.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 *  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
//** Introduction
// This file contains the functions that manage the object store of the TPM.

//** Includes and Data Definitions
#define OBJECT_C

#include "Tpm.h"

//** Functions

//*** ObjectFlush()
// This function marks an object slot as available.
// Since there is no checking of the input parameters, it should be used
// judiciously.
// Note: This could be converted to a macro.
void
ObjectFlush(
    OBJECT          *object
    )
{
    object->attributes.occupied = CLEAR;
}

//*** ObjectSetInUse()
// This access function sets the occupied attribute of an object slot.
void
ObjectSetInUse(
    OBJECT          *object
    )
{
    object->attributes.occupied = SET;
}

//*** ObjectStartup()
// This function is called at TPM2_Startup() to initialize the object subsystem.
BOOL
ObjectStartup(
    void
    )
{
    UINT32      i;
//
    // object slots initialization
    for(i = 0; i < MAX_LOADED_OBJECTS; i++)
    {
        //Set the slot to not occupied
        ObjectFlush(&s_objects[i]);
    }
    return TRUE;
}

//*** 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
        OBJECT      *object = &s_objects[i];
        if(object->attributes.evict == SET)
            ObjectFlush(object);
    }
    return;
}

//*** IsObjectPresent()
// 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 Type: BOOL
//      TRUE(1)         handle references a loaded object
//      FALSE(0)        handle is not an object handle, or it does not
//                      reference to a loaded object
BOOL
IsObjectPresent(
    TPMI_DH_OBJECT   handle         // IN: handle to be checked
    )
{
    UINT32          slotIndex = handle - TRANSIENT_FIRST;
    // Since the handle is just an index into the array that is zero based, any
    // handle value outsize of the range of:
    //    TRANSIENT_FIRST -- (TRANSIENT_FIRST + MAX_LOADED_OBJECT - 1)
    // will now be greater than or equal to MAX_LOADED_OBJECTS
    if(slotIndex >= MAX_LOADED_OBJECTS)
        return FALSE;
    // Indicate if the slot is occupied
    return (s_objects[slotIndex].attributes.occupied == TRUE);
}

//*** 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 Type: BOOL
//      TRUE(1)         object is an HMAC, hash, or event sequence object
//      FALSE(0)        object is not an HMAC, hash, or event sequence object
BOOL
ObjectIsSequence(
    OBJECT          *object         // IN: handle to be checked
    )
{
    pAssert(object != NULL);
    return (object->attributes.hmacSeq == SET
            || object->attributes.hashSeq == SET
            || object->attributes.eventSeq == SET);
}

//*** HandleToObject()
// This function is used to find the object structure associated with a handle.
//
// This function requires that 'handle' references a loaded object or a permanent
// handle.
OBJECT*
HandleToObject(
    TPMI_DH_OBJECT   handle         // IN: handle of the object
    )
{
    UINT32              index;
//
    // Return NULL if the handle references a permanent handle because there is no
    // associated OBJECT.
    if(HandleGetType(handle) == TPM_HT_PERMANENT)
        return NULL; 
    // In this implementation, the handle is determined by the slot occupied by the
    // object.
    index = handle - TRANSIENT_FIRST;
    pAssert(index < MAX_LOADED_OBJECTS);
    pAssert(s_objects[index].attributes.occupied);
    return &s_objects[index];
}


//*** GetQualifiedName()
// 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
GetQualifiedName(
    TPMI_DH_OBJECT   handle,        // IN: handle of the object
    TPM2B_NAME      *qualifiedName  // OUT: qualified name of the object
    )
{
    OBJECT      *object;
//
    switch(HandleGetType(handle))
    {
        case TPM_HT_PERMANENT:
            qualifiedName->t.size = sizeof(TPM_HANDLE);
            UINT32_TO_BYTE_ARRAY(handle, qualifiedName->t.name);
            break;
        case TPM_HT_TRANSIENT:
            object = HandleToObject(handle);
            if(object == NULL || object->publicArea.nameAlg == TPM_ALG_NULL)
                qualifiedName->t.size = 0;
            else
                // Copy the name
                *qualifiedName = object->qualifiedName;
            break;
        default:
            FAIL(FATAL_ERROR_INTERNAL);
    }
    return;
}

//*** ObjectGetHierarchy()
// This function returns the handle for the hierarchy of an object.
TPMI_RH_HIERARCHY
ObjectGetHierarchy(
    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;
    }
}

//*** GetHierarchy()
// This function returns the handle of the hierarchy to which a handle belongs.
// This function is similar to ObjectGetHierarchy() but this routine takes
// a handle but ObjectGetHierarchy() takes an pointer to an object.
//
// This function requires that 'handle' references a loaded object.
TPMI_RH_HIERARCHY
GetHierarchy(
    TPMI_DH_OBJECT   handle         // IN :object handle
    )
{
    OBJECT          *object = HandleToObject(handle);
//
    return ObjectGetHierarchy(object);
}

//*** FindEmptyObjectSlot()
// This function finds an open object slot, if any. It will clear the attributes
// but will not set the occupied attribute. This is so that a slot may be used
// and discarded if everything does not go as planned.
//  Return Type: OBJECT *
//      NULL        no open slot found
//      != NULL     pointer to available slot
OBJECT *
FindEmptyObjectSlot(
    TPMI_DH_OBJECT  *handle         // OUT: (optional)
    )
{
    UINT32               i;
    OBJECT              *object;
//
    for(i = 0; i < MAX_LOADED_OBJECTS; i++)
    {
        object = &s_objects[i];
        if(object->attributes.occupied == CLEAR)
        {
            if(handle)
                *handle = i + TRANSIENT_FIRST;
            // Initialize the object attributes
            MemorySet(&object->attributes, 0, sizeof(OBJECT_ATTRIBUTES));
            return object;
        }
    }
    return NULL;
}

//*** ObjectAllocateSlot()
// This function is used to allocate a slot in internal object array.
OBJECT *
ObjectAllocateSlot(
    TPMI_DH_OBJECT  *handle        // OUT: handle of allocated object
    )
{
    OBJECT          *object = FindEmptyObjectSlot(handle);
//
    if(object != NULL)
    {
        // if found, mark as occupied
        ObjectSetInUse(object);
    }
    return object;
}

//*** ObjectSetLoadedAttributes()
// This function sets the internal attributes for a loaded object. It is called to
// finalize the OBJECT attributes (not the TPMA_OBJECT attributes) for a loaded
// object.
void
ObjectSetLoadedAttributes(
    OBJECT          *object,        // IN: object attributes to finalize
    TPM_HANDLE       parentHandle   // IN: the parent handle
    )
{
    OBJECT              *parent = HandleToObject(parentHandle);
    TPMA_OBJECT          objectAttributes = object->publicArea.objectAttributes;
//
    // Copy the stClear attribute from the public area. This could be overwritten
    // if the parent has stClear SET
    object->attributes.stClear = 
        IS_ATTRIBUTE(objectAttributes, TPMA_OBJECT, stClear);
    // If parent handle is a permanent handle, it is a primary (unless it is NULL
    if(parent == NULL)
    {
        object->attributes.primary = SET;
        switch(parentHandle)
        {
            case TPM_RH_ENDORSEMENT:
                object->attributes.epsHierarchy = SET;
                break;
            case TPM_RH_OWNER:
                object->attributes.spsHierarchy = SET;
                break;
            case TPM_RH_PLATFORM:
                object->attributes.ppsHierarchy = SET;
                break;
            default:
                // Treat the temporary attribute as a hierarchy
                object->attributes.temporary = SET;
                object->attributes.primary = CLEAR;
                break;
        }
    }
    else
    {
        // is this a stClear object
        object->attributes.stClear =
            (IS_ATTRIBUTE(objectAttributes, TPMA_OBJECT, stClear)
             || (parent->attributes.stClear == SET));
        object->attributes.epsHierarchy = parent->attributes.epsHierarchy;
        object->attributes.spsHierarchy = parent->attributes.spsHierarchy;
        object->attributes.ppsHierarchy = parent->attributes.ppsHierarchy;
        // An object is temporary if its parent is temporary or if the object
        // is external
        object->attributes.temporary = parent->attributes.temporary 
            || object->attributes.external;
    }
    // If this is an external object, set the QN == name but don't SET other
    // key properties ('parent' or 'derived')
    if(object->attributes.external)
        object->qualifiedName = object->name;
    else
    {
        // check attributes for different types of parents
        if(IS_ATTRIBUTE(objectAttributes, TPMA_OBJECT, restricted)
           && !object->attributes.publicOnly
           && IS_ATTRIBUTE(objectAttributes, TPMA_OBJECT, decrypt)
           && object->publicArea.nameAlg != TPM_ALG_NULL)
        {
            // This is a parent. If it is not a KEYEDHASH, it is an ordinary parent.
            // Otherwise, it is a derivation parent.
            if(object->publicArea.type == TPM_ALG_KEYEDHASH)
                object->attributes.derivation = SET;
            else
                object->attributes.isParent = SET;
        }
        ComputeQualifiedName(parentHandle, object->publicArea.nameAlg,
                             &object->name, &object->qualifiedName);
    }
    // Set slot occupied
    ObjectSetInUse(object);
    return;
}

//*** ObjectLoad()
// Common function to load an object. A loaded object has its public area validated
// (unless its 'nameAlg' is TPM_ALG_NULL). If a sensitive part is loaded, it is
// verified to be correct and if both public and sensitive parts are loaded, then
// the cryptographic binding between the objects is validated. This function does 
// not cause the allocated slot to be marked as in use.
TPM_RC
ObjectLoad(
    OBJECT          *object,        // IN: pointer to object slot
                                    //     object
    OBJECT          *parent,        // IN: (optional) the parent object
    TPMT_PUBLIC     *publicArea,    // IN: public area to be installed in the object
    TPMT_SENSITIVE  *sensitive,     // IN: (optional) sensitive area to be 
                                    //      installed in the object
    TPM_RC           blamePublic,   // IN: parameter number to associate with the
                                    //     publicArea errors
    TPM_RC           blameSensitive,// IN: parameter number to associate with the
                                    //     sensitive area errors
    TPM2B_NAME      *name           // IN: (optional)
)
{
    TPM_RC           result = TPM_RC_SUCCESS;
//
// Do validations of public area object descriptions
    pAssert(publicArea != NULL);

    // Is this public only or a no-name object?
    if(sensitive == NULL || publicArea->nameAlg == TPM_ALG_NULL)
    {
        // Need to have schemes checked so that we do the right thing with the
        // public key.
        result = SchemeChecks(NULL, publicArea);
    }
    else
    {
        // For any sensitive area, make sure that the seedSize is no larger than the
        // digest size of nameAlg
        if(sensitive->seedValue.t.size > CryptHashGetDigestSize(publicArea->nameAlg))
            return TPM_RCS_KEY_SIZE + blameSensitive;
        // Check attributes and schemes for consistency
        result = PublicAttributesValidation(parent, publicArea);
    }
    if(result != TPM_RC_SUCCESS)
        return RcSafeAddToResult(result, blamePublic);

// Sensitive area and binding checks

    // On load, check nothing if the parent is fixedTPM. For all other cases, validate
    // the keys.
    if((parent == NULL)
       || ((parent != NULL) && !IS_ATTRIBUTE(parent->publicArea.objectAttributes,
                                             TPMA_OBJECT, fixedTPM)))
    {
        // Do the cryptographic key validation
        result = CryptValidateKeys(publicArea, sensitive, blamePublic,
                                   blameSensitive);
        if(result != TPM_RC_SUCCESS)
            return result;
    }
#if ALG_RSA
    // If this is an RSA key, then expand the private exponent. 
    // Note: ObjectLoad() is only called by TPM2_Import() if the parent is fixedTPM.
    // For any key that does not have a fixedTPM parent, the exponent is computed
    // whenever it is loaded
    if((publicArea->type == TPM_ALG_RSA) && (sensitive != NULL))
    {
        result = CryptRsaLoadPrivateExponent(publicArea, sensitive);
        if(result != TPM_RC_SUCCESS)
            return result;
    }
#endif // ALG_RSA
    // See if there is an object to populate
    if((result == TPM_RC_SUCCESS) && (object != NULL))
    {
        // Initialize public
        object->publicArea = *publicArea;
        // Copy sensitive if there is one
        if(sensitive == NULL)
            object->attributes.publicOnly = SET;
        else
            object->sensitive = *sensitive;
        // Set the name, if one was provided
        if(name != NULL)
            object->name = *name;
        else
            object->name.t.size = 0;
    }
    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 HASH_OBJECT *
AllocateSequenceSlot(
    TPM_HANDLE      *newHandle,     // OUT: receives the allocated handle
    TPM2B_AUTH      *auth           // IN: the authValue for the slot
    )
{
    HASH_OBJECT      *object = (HASH_OBJECT *)ObjectAllocateSlot(newHandle);
//
    // Validate that the proper location of the hash state data relative to the
    // object state data. It would be good if this could have been done at compile
    // time but it can't so do it in something that can be removed after debug.
    cAssert(offsetof(HASH_OBJECT, auth) == offsetof(OBJECT, publicArea.authPolicy));

    if(object != NULL)
    {

    // Set the common values that a sequence object shares with an ordinary object
        // First, clear all attributes
        MemorySet(&object->objectAttributes, 0, sizeof(TPMA_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;

        // 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.
        SET_ATTRIBUTE(object->objectAttributes, TPMA_OBJECT, noDA);

        // Copy the authorization value
        if(auth != NULL)
            object->auth = *auth;
        else
            object->auth.t.size = 0;
    }
    return object;
}


#if CC_HMAC_Start || CC_MAC_Start
//*** ObjectCreateHMACSequence()
// This function creates an internal HMAC sequence object.
//  Return Type: TPM_RC
//      TPM_RC_OBJECT_MEMORY        if there is no free slot for an object
TPM_RC
ObjectCreateHMACSequence(
    TPMI_ALG_HASH    hashAlg,       // IN: hash algorithm
    OBJECT          *keyObject,     // IN: the object containing the HMAC key
    TPM2B_AUTH      *auth,          // IN: authValue
    TPMI_DH_OBJECT  *newHandle      // OUT: HMAC sequence object handle
    )
{
    HASH_OBJECT         *hmacObject;
//
    // Try to allocate a slot for new object
    hmacObject = AllocateSequenceSlot(newHandle, auth);

    if(hmacObject == NULL)
        return TPM_RC_OBJECT_MEMORY;
    // Set HMAC sequence bit
    hmacObject->attributes.hmacSeq = SET;

#if !SMAC_IMPLEMENTED
    if(CryptHmacStart(&hmacObject->state.hmacState, hashAlg,
                   keyObject->sensitive.sensitive.bits.b.size,
                   keyObject->sensitive.sensitive.bits.b.buffer) == 0)
#else
    if(CryptMacStart(&hmacObject->state.hmacState, 
                     &keyObject->publicArea.parameters, 
                     hashAlg, &keyObject->sensitive.sensitive.any.b) == 0)
#endif // SMAC_IMPLEMENTED
        return TPM_RC_FAILURE;
    return TPM_RC_SUCCESS;
}
#endif

//*** ObjectCreateHashSequence()
// This function creates a hash sequence object.
//  Return Type: TPM_RC
//      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 = AllocateSequenceSlot(newHandle, auth);
//
    // See if slot allocated
    if(hashObject == NULL)
        return TPM_RC_OBJECT_MEMORY;
    // Set hash sequence bit
    hashObject->attributes.hashSeq = SET;

    // Start hash for hash sequence
    CryptHashStart(&hashObject->state.hashState[0], hashAlg);

    return TPM_RC_SUCCESS;
}

//*** ObjectCreateEventSequence()
// This function creates an event sequence object.
//  Return Type: TPM_RC
//      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 = AllocateSequenceSlot(newHandle, auth);
    UINT32               count;
    TPM_ALG_ID           hash;
//
    // See if slot allocated
    if(hashObject == NULL)
        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 = CryptHashGetAlgByIndex(count)) != TPM_ALG_NULL; count++)
        CryptHashStart(&hashObject->state.hashState[count], hash);
    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 *)HandleToObject(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 cryptographic implementation has some context values that need to be
        // cleaned up (hygiene).
        //
        for(count = 0; CryptHashGetAlgByIndex(count) != TPM_ALG_NULL; count++)
        {
            CryptHashEnd(&hashObject->state.hashState[count], 0, buffer);
        }
        // Flush sequence object
        FlushObject(g_DRTMHandle);
    }
    g_DRTMHandle = TPM_RH_UNASSIGNED;
}

//*** ObjectContextLoad()
// This function loads an object from a saved object context.
//  Return Type: OBJECT *
//      NULL        if there is no free slot for an object
//      != NULL     points to the loaded object
OBJECT *
ObjectContextLoad(
    ANY_OBJECT_BUFFER   *object,        // IN: pointer to object structure in saved
                                        //     context
    TPMI_DH_OBJECT      *handle         // OUT: object handle
    )
{
    OBJECT      *newObject = ObjectAllocateSlot(handle);
//
    // Try to allocate a slot for new object
    if(newObject != NULL)
    {
        // Copy the first part of the object
        MemoryCopy(newObject, object, offsetof(HASH_OBJECT, state));
        // See if this is a sequence object
        if(ObjectIsSequence(newObject))
        {
            // If this is a sequence object, import the data
            SequenceDataImport((HASH_OBJECT *)newObject,
                               (HASH_OBJECT_BUFFER *)object);
        }
        else
        {
            // Copy input object data to internal structure
            MemoryCopy(newObject, object, sizeof(OBJECT));
        }
    }
    return newObject;
}

//*** FlushObject()
// This function frees an object slot.
//
// This function requires that the object is loaded.
void
FlushObject(
    TPMI_DH_OBJECT   handle         // IN: handle to be freed
    )
{
    UINT32      index = handle - TRANSIENT_FIRST;
//
    pAssert(index < MAX_LOADED_OBJECTS);
    // Clear all the object attributes
    MemorySet((BYTE*)&(s_objects[index].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].attributes.occupied)          // If found an occupied slot
        {
            switch(hierarchy)
            {
                case TPM_RH_PLATFORM:
                    if(s_objects[i].attributes.ppsHierarchy == SET)
                        s_objects[i].attributes.occupied = FALSE;
                    break;
                case TPM_RH_OWNER:
                    if(s_objects[i].attributes.spsHierarchy == SET)
                        s_objects[i].attributes.occupied = FALSE;
                    break;
                case TPM_RH_ENDORSEMENT:
                    if(s_objects[i].attributes.epsHierarchy == SET)
                        s_objects[i].attributes.occupied = FALSE;
                    break;
                default:
                    FAIL(FATAL_ERROR_INTERNAL);
                    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.
//  Return Type: TPM_RC
//      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
    COMMAND_INDEX    commandIndex   // 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
    object = ObjectAllocateSlot(handle);
    if(object == NULL)
        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(ObjectGetHierarchy(object) == TPM_RH_ENDORSEMENT
       && gc.ehEnable == CLEAR
       && GetCommandCode(commandIndex) != TPM_CC_EvictControl)
        return TPM_RC_HANDLE;

    return result;
}

//*** ObjectComputeName()
// This does the name computation from a public area (can be marshaled or not).
TPM2B_NAME *
ObjectComputeName(
    UINT32           size,          // IN: the size of the area to digest
    BYTE            *publicArea,    // IN: the public area to digest
    TPM_ALG_ID       nameAlg,       // IN: the hash algorithm to use
    TPM2B_NAME      *name           // OUT: Computed name
    )
{
    // Hash the publicArea into the name buffer leaving room for the nameAlg
    name->t.size = CryptHashBlock(nameAlg, size, publicArea, 
                                  sizeof(name->t.name) - 2, 
                                  &name->t.name[2]);
    // set the nameAlg
    UINT16_TO_BYTE_ARRAY(nameAlg, name->t.name);
    name->t.size += 2;
    return name;
}

//*** PublicMarshalAndComputeName()
// This function computes the Name of an object from its public area.
TPM2B_NAME *
PublicMarshalAndComputeName(
    TPMT_PUBLIC     *publicArea,    // IN: public area of an object
    TPM2B_NAME      *name           // OUT: name of the object
    )
{
    // Will marshal a public area into a template. This is because the internal
    // format for a TPM2B_PUBLIC is a structure and not a simple BYTE buffer.
    TPM2B_TEMPLATE       marshaled;     // this is big enough to hold a
                                        //  marshaled TPMT_PUBLIC
    BYTE                *buffer = (BYTE *)&marshaled.t.buffer;
//
    // if the nameAlg is NULL then there is no name.
    if(publicArea->nameAlg == TPM_ALG_NULL)
        name->t.size = 0;
    else
    {
        // Marshal the public area into its canonical form
        marshaled.t.size = TPMT_PUBLIC_Marshal(publicArea, &buffer, NULL);
        // and compute the name
        ObjectComputeName(marshaled.t.size, marshaled.t.buffer,
                          publicArea->nameAlg, name);
    }
    return name;
}

//*** ComputeQualifiedName()
// This function computes the qualified name of an object.
void
ComputeQualifiedName(
    TPM_HANDLE       parentHandle,  // IN: parent's handle
    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
    TPM2B_NAME      parentName;
//
    if(parentHandle == TPM_RH_UNASSIGNED)
    {
        MemoryCopy2B(&qualifiedName->b, &name->b, sizeof(qualifiedName->t.name));
        *qualifiedName = *name;
    }
    else
    {
        GetQualifiedName(parentHandle, &parentName);

        //      QN_A = hash_A (QN of parent || NAME_A)

        // Start hash
        qualifiedName->t.size = CryptHashStart(&hashState, nameAlg);

        // Add parent's qualified name
        CryptDigestUpdate2B(&hashState, &parentName.b);

        // Add self name
        CryptDigestUpdate2B(&hashState, &name->b);

        // Complete hash leaving room for the name algorithm
        CryptHashEnd(&hashState, qualifiedName->t.size,
                     &qualifiedName->t.name[2]);
        UINT16_TO_BYTE_ARRAY(nameAlg, qualifiedName->t.name);
        qualifiedName->t.size += 2;
    }
    return;
}

//*** ObjectIsStorage()
// This function determines if an object has the attributes associated
// with a parent. A parent is an asymmetric or symmetric block cipher key 
// that has its 'restricted' and 'decrypt' attributes SET, and 'sign' CLEAR.
//  Return Type: BOOL
//      TRUE(1)         object is a storage key
//      FALSE(0)        object is not a storage key
BOOL
ObjectIsStorage(
    TPMI_DH_OBJECT   handle         // IN: object handle
    )
{
    OBJECT           *object = HandleToObject(handle);
    TPMT_PUBLIC      *publicArea = ((object != NULL) ? &object->publicArea : NULL);
//
    return (publicArea != NULL
            && IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted)
            && IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, decrypt)
            && !IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign)
            && (object->publicArea.type == TPM_ALG_RSA
                || object->publicArea.type == TPM_ALG_ECC));
}

//*** 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 Type: TPMI_YES_NO
//      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].attributes.occupied == TRUE)
        {
            // A valid transient object can not be the copy of a persistent object
            pAssert(s_objects[i].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].attributes.occupied == FALSE) num++;
    }

    return num;
}

//*** ObjectGetPublicAttributes()
// Returns the attributes associated with an object handles.
TPMA_OBJECT
ObjectGetPublicAttributes(
    TPM_HANDLE       handle
    )
{
    return HandleToObject(handle)->publicArea.objectAttributes;
}

OBJECT_ATTRIBUTES
ObjectGetProperties(
    TPM_HANDLE       handle
    )
{
    return HandleToObject(handle)->attributes;
}