// 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

#include "InternalRoutines.h"
//
//
//
//          Functions
//
//          EntityGetLoadStatus()
//
//     This function will indicate if the entity associated with a handle is present in TPM memory. If the handle is
//     a persistent object handle, and the object exists, the persistent object is moved from NV memory into a
//     RAM object slot and the persistent handle is replaced with the transient object handle for the slot.
//
//     Error Returns                     Meaning
//
//     TPM_RC_HANDLE                     handle type does not match
//     TPM_RC_REFERENCE_H0               entity is not present
//     TPM_RC_HIERARCHY                  entity belongs to a disabled hierarchy
//     TPM_RC_OBJECT_MEMORY              handle is an evict object but there is no space to load it to RAM
//
TPM_RC
EntityGetLoadStatus(
    TPM_HANDLE          *handle,              // IN/OUT: handle of the entity
    TPM_CC               commandCode          // IN: the commmandCode
    )
{
    TPM_RC              result = TPM_RC_SUCCESS;
    switch(HandleGetType(*handle))
    {
        // For handles associated with hierarchies, the entity is present
        // only if the associated enable is SET.
        case TPM_HT_PERMANENT:
            switch(*handle)
            {
                case TPM_RH_OWNER:
                    if(!gc.shEnable)
                        result = TPM_RC_HIERARCHY;
                    break;
#ifdef    VENDOR_PERMANENT
                 case VENDOR_PERMANENT:
#endif
                   case TPM_RH_ENDORSEMENT:
                       if(!gc.ehEnable)
                            result = TPM_RC_HIERARCHY;
                       break;
                   case TPM_RH_PLATFORM:
                       if(!g_phEnable)
                            result = TPM_RC_HIERARCHY;
                       break;
                       // null handle, PW session handle and lockout
                       // handle are always available
                   case TPM_RH_NULL:
                   case TPM_RS_PW:
                   case TPM_RH_LOCKOUT:
                       break;
                   default:
                       // handling of the manufacture_specific handles
                       if(      ((TPM_RH)*handle >= TPM_RH_AUTH_00)
                            && ((TPM_RH)*handle <= TPM_RH_AUTH_FF))
                            // use the value that would have been returned from
                            // unmarshaling if it did the handle filtering
                                result = TPM_RC_VALUE;
                       else
                            pAssert(FALSE);
                       break;
            }
            break;
        case TPM_HT_TRANSIENT:
            // For a transient object, check if the handle is associated
            // with a loaded object.
            if(!ObjectIsPresent(*handle))
                 result = TPM_RC_REFERENCE_H0;
            break;
        case TPM_HT_PERSISTENT:
            // Persistent object
            // Copy the persistent object to RAM and replace the handle with the
            // handle of the assigned slot. A TPM_RC_OBJECT_MEMORY,
            // TPM_RC_HIERARCHY or TPM_RC_REFERENCE_H0 error may be returned by
            // ObjectLoadEvict()
            result = ObjectLoadEvict(handle, commandCode);
            break;
        case TPM_HT_HMAC_SESSION:
            // For an HMAC session, see if the session is loaded
            // and if the session in the session slot is actually
            // an HMAC session.
            if(SessionIsLoaded(*handle))
            {
                 SESSION             *session;
                 session = SessionGet(*handle);
                 // Check if the session is a HMAC session
                 if(session->attributes.isPolicy == SET)
                     result = TPM_RC_HANDLE;
            }
            else
                 result = TPM_RC_REFERENCE_H0;
            break;
        case TPM_HT_POLICY_SESSION:
            // For a policy session, see if the session is loaded
            // and if the session in the session slot is actually
            // a policy session.
            if(SessionIsLoaded(*handle))
            {
                 SESSION             *session;
                 session = SessionGet(*handle);
                 // Check if the session is a policy session
                 if(session->attributes.isPolicy == CLEAR)
                     result = TPM_RC_HANDLE;
            }
            else
                 result = TPM_RC_REFERENCE_H0;
            break;
        case TPM_HT_NV_INDEX:
            // For an NV Index, use the platform-specific routine
            // to search the IN Index space.
            result = NvIndexIsAccessible(*handle, commandCode);
            break;
        case TPM_HT_PCR:
            // Any PCR handle that is unmarshaled successfully referenced
            // a PCR that is defined.
            break;
        default:
            // Any other handle type is a defect in the unmarshaling code.
            pAssert(FALSE);
            break;
   }
   return result;
}
//
//
//
//           EntityGetAuthValue()
//
//      This function is used to access the authValue associated with a handle. This function assumes that the
//      handle references an entity that is accessible and the handle is not for a persistent objects. That is
//      EntityGetLoadStatus() should have been called. Also, the accessibility of the authValue should have been
//      verified by IsAuthValueAvailable().
//      This function copies the authorization value of the entity to auth.
//      Return value is the number of octets copied to auth.
//
UINT16
EntityGetAuthValue(
    TPMI_DH_ENTITY       handle,             // IN: handle of entity
    AUTH_VALUE          *auth                // OUT: authValue of the entity
    )
{
    TPM2B_AUTH           authValue = {0};
   switch(HandleGetType(handle))
   {
       case TPM_HT_PERMANENT:
           switch(handle)
           {
               case TPM_RH_OWNER:
                   // ownerAuth for TPM_RH_OWNER
                   authValue = gp.ownerAuth;
                   break;
               case TPM_RH_ENDORSEMENT:
                   // endorsementAuth for TPM_RH_ENDORSEMENT
                   authValue = gp.endorsementAuth;
                   break;
               case TPM_RH_PLATFORM:
                   // platformAuth for TPM_RH_PLATFORM
                   authValue = gc.platformAuth;
                   break;
               case TPM_RH_LOCKOUT:
                   // lockoutAuth for TPM_RH_LOCKOUT
                   authValue = gp.lockoutAuth;
                   break;
               case TPM_RH_NULL:
                   // nullAuth for TPM_RH_NULL. Return 0 directly here
                   return 0;
                   break;
#ifdef VENDOR_PERMANENT
               case VENDOR_PERMANENT:
                   // vendor auth value
                   authValue = g_platformUniqueDetails;
#endif
               default:
                   // If any other permanent handle is present it is
                   // a code defect.
                   pAssert(FALSE);
                   break;
           }
           break;
       case TPM_HT_TRANSIENT:
           // authValue for an object
           // A persistent object would have been copied into RAM
           // and would have an transient object handle here.
           {
               OBJECT          *object;
               object = ObjectGet(handle);
               // special handling if this is a sequence object
               if(ObjectIsSequence(object))
                   {
                       authValue = ((HASH_OBJECT *)object)->auth;
                   }
                   else
                   {
                       // Auth value is available only when the private portion of
                       // the object is loaded. The check should be made before
                       // this function is called
                       pAssert(object->attributes.publicOnly == CLEAR);
                       authValue = object->sensitive.authValue;
                   }
             }
             break;
         case TPM_HT_NV_INDEX:
             // authValue for an NV index
             {
                  NV_INDEX        nvIndex;
                  NvGetIndexInfo(handle, &nvIndex);
                  authValue = nvIndex.authValue;
             }
             break;
         case TPM_HT_PCR:
             // authValue for PCR
             PCRGetAuthValue(handle, &authValue);
             break;
         default:
             // If any other handle type is present here, then there is a defect
             // in the unmarshaling code.
             pAssert(FALSE);
             break;
    }
    // Copy the authValue
    pAssert(authValue.t.size <= sizeof(authValue.t.buffer));
    MemoryCopy(auth, authValue.t.buffer, authValue.t.size, sizeof(TPMU_HA));
    return authValue.t.size;
}
//
//
//           EntityGetAuthPolicy()
//
//      This function is used to access the authPolicy associated with a handle. This function assumes that the
//      handle references an entity that is accessible and the handle is not for a persistent objects. That is
//      EntityGetLoadStatus() should have been called. Also, the accessibility of the authPolicy should have
//      been verified by IsAuthPolicyAvailable().
//      This function copies the authorization policy of the entity to authPolicy.
//      The return value is the hash algorithm for the policy.
//
TPMI_ALG_HASH
EntityGetAuthPolicy(
    TPMI_DH_ENTITY       handle,             // IN: handle of entity
    TPM2B_DIGEST        *authPolicy          // OUT: authPolicy of the entity
    )
{
    TPMI_ALG_HASH            hashAlg = TPM_ALG_NULL;
    switch(HandleGetType(handle))
    {
        case TPM_HT_PERMANENT:
            switch(handle)
            {
                case TPM_RH_OWNER:
//
                      // ownerPolicy for TPM_RH_OWNER
                      *authPolicy = gp.ownerPolicy;
                      hashAlg = gp.ownerAlg;
                      break;
                  case TPM_RH_ENDORSEMENT:
                      // endorsementPolicy for TPM_RH_ENDORSEMENT
                      *authPolicy = gp.endorsementPolicy;
                      hashAlg = gp.endorsementAlg;
                      break;
                  case TPM_RH_PLATFORM:
                      // platformPolicy for TPM_RH_PLATFORM
                      *authPolicy = gc.platformPolicy;
                      hashAlg = gc.platformAlg;
                      break;
                  case TPM_RH_LOCKOUT:
                      // lockoutPolicy for TPM_RH_LOCKOUT
                      *authPolicy = gp.lockoutPolicy;
                      hashAlg = gp.lockoutAlg;
                      break;
                  default:
                      // If any other permanent handle is present it is
                      // a code defect.
                      pAssert(FALSE);
                      break;
             }
             break;
         case TPM_HT_TRANSIENT:
             // authPolicy for an object
             {
                  OBJECT *object = ObjectGet(handle);
                  *authPolicy = object->publicArea.authPolicy;
                  hashAlg = object->publicArea.nameAlg;
             }
             break;
         case TPM_HT_NV_INDEX:
             // authPolicy for a NV index
             {
                  NV_INDEX        nvIndex;
                  NvGetIndexInfo(handle, &nvIndex);
                  *authPolicy = nvIndex.publicArea.authPolicy;
                  hashAlg = nvIndex.publicArea.nameAlg;
             }
             break;
         case TPM_HT_PCR:
             // authPolicy for a PCR
             hashAlg = PCRGetAuthPolicy(handle, authPolicy);
             break;
         default:
             // If any other handle type is present it is a code defect.
             pAssert(FALSE);
             break;
   }
   return hashAlg;
}
//
//
//           EntityGetName()
//
//      This function returns the Name associated with a handle. It will set name to the Name and return the size
//      of the Name string.
//
UINT16
EntityGetName(
   TPMI_DH_ENTITY       handle,           // IN: handle of entity
   NAME                *name              // OUT: name of entity
    )
{
    UINT16              nameSize;
    switch(HandleGetType(handle))
    {
        case TPM_HT_TRANSIENT:
            // Name for an object
            nameSize = ObjectGetName(handle, name);
            break;
        case TPM_HT_NV_INDEX:
            // Name for a NV index
            nameSize = NvGetName(handle, name);
            break;
        default:
            // For all other types, the handle is the Name
            nameSize = TPM_HANDLE_Marshal(&handle, (BYTE **)&name, NULL);
            break;
    }
    return nameSize;
}
//
//
//           EntityGetHierarchy()
//
//      This function returns the hierarchy handle associated with an entity.
//      a) A handle that is a hierarchy handle is associated with itself.
//      b) An NV index belongs to TPM_RH_PLATFORM if TPMA_NV_PLATFORMCREATE, is SET,
//         otherwise it belongs to TPM_RH_OWNER
//      c) An object handle belongs to its hierarchy. All other handles belong to the platform hierarchy. or an NV
//         Index.
//
TPMI_RH_HIERARCHY
EntityGetHierarchy(
    TPMI_DH_ENTITY       handle             // IN :handle of entity
    )
{
    TPMI_RH_HIERARCHY             hierarcy = TPM_RH_NULL;
    switch(HandleGetType(handle))
    {
        case TPM_HT_PERMANENT:
            // hierarchy for a permanent handle
            switch(handle)
            {
                case TPM_RH_PLATFORM:
                case TPM_RH_ENDORSEMENT:
                case TPM_RH_NULL:
                    hierarcy = handle;
                    break;
                // all other permanent handles are associated with the owner
                // hierarchy. (should only be TPM_RH_OWNER and TPM_RH_LOCKOUT)
                default:
                    hierarcy = TPM_RH_OWNER;
                    break;
            }
            break;
        case TPM_HT_NV_INDEX:
            // hierarchy for NV index
            {
                NV_INDEX        nvIndex;
                NvGetIndexInfo(handle, &nvIndex);
                // If only the platform can delete the index, then it is
                  // considered to be in the platform hierarchy, otherwise it
                  // is in the owner hierarchy.
                  if(nvIndex.publicArea.attributes.TPMA_NV_PLATFORMCREATE == SET)
                      hierarcy = TPM_RH_PLATFORM;
                  else
                      hierarcy = TPM_RH_OWNER;
             }
             break;
         case TPM_HT_TRANSIENT:
             // hierarchy for an object
             {
                 OBJECT          *object;
                 object = ObjectGet(handle);
                 if(object->attributes.ppsHierarchy)
                 {
                     hierarcy = TPM_RH_PLATFORM;
                 }
                 else if(object->attributes.epsHierarchy)
                 {
                     hierarcy = TPM_RH_ENDORSEMENT;
                 }
                 else if(object->attributes.spsHierarchy)
                 {
                     hierarcy = TPM_RH_OWNER;
                 }
             }
             break;
         case TPM_HT_PCR:
             hierarcy = TPM_RH_OWNER;
             break;
         default:
             pAssert(0);
             break;
     }
     // this is unreachable but it provides a return value for the default
     // case which makes the complier happy
     return hierarcy;
}
