// 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_FIRST)
                            && ((TPM_RH)*handle <= TPM_RH_LAST))
                            // 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 = {};
   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;
}
