// 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 SESSION_PROCESS_C
#include "InternalRoutines.h"
#include "SessionProcess_fp.h"
#include "Platform.h"
//
//
//          Authorization Support Functions
//
//           IsDAExempted()
//
//     This function indicates if a handle is exempted from DA logic. A handle is exempted if it is
//     a) a primary seed handle,
//     b) an object with noDA bit SET,
//     c) an NV Index with TPMA_NV_NO_DA bit SET, or
//     d) a PCR handle.
//
//     Return Value                      Meaning
//
//     TRUE                              handle is exempted from DA logic
//     FALSE                             handle is not exempted from DA logic
//
BOOL
IsDAExempted(
     TPM_HANDLE          handle              // IN: entity handle
     )
{
     BOOL          result = FALSE;
     switch(HandleGetType(handle))
     {
         case TPM_HT_PERMANENT:
             // All permanent handles, other than TPM_RH_LOCKOUT, are exempt from
             // DA protection.
             result = (handle != TPM_RH_LOCKOUT);
             break;
         // When this function is called, a persistent object will have been loaded
         // into an object slot and assigned a transient handle.
         case TPM_HT_TRANSIENT:
         {
             OBJECT      *object;
             object = ObjectGet(handle);
             result = (object->publicArea.objectAttributes.noDA == SET);
             break;
         }
         case TPM_HT_NV_INDEX:
         {
             NV_INDEX        nvIndex;
                NvGetIndexInfo(handle, &nvIndex);
                result = (nvIndex.publicArea.attributes.TPMA_NV_NO_DA == SET);
                break;
         }
         case TPM_HT_PCR:
             // PCRs are always exempted from DA.
             result = TRUE;
             break;
         default:
             break;
   }
   return result;
}
//
//
//          IncrementLockout()
//
//     This function is called after an authorization failure that involves use of an authValue. If the entity
//     referenced by the handle is not exempt from DA protection, then the failedTries counter will be
//     incremented.
//
//     Error Returns                  Meaning
//
//     TPM_RC_AUTH_FAIL               authorization failure that caused DA lockout to increment
//     TPM_RC_BAD_AUTH                authorization failure did not cause DA lockout to increment
//
static TPM_RC
IncrementLockout(
   UINT32                sessionIndex
   )
{
   TPM_HANDLE            handle = s_associatedHandles[sessionIndex];
   TPM_HANDLE            sessionHandle = s_sessionHandles[sessionIndex];
   TPM_RC                result;
   SESSION              *session = NULL;
   // Don't increment lockout unless the handle associated with the session
   // is DA protected or the session is bound to a DA protected entity.
   if(sessionHandle == TPM_RS_PW)
   {
       if(IsDAExempted(handle))
           return TPM_RC_BAD_AUTH;
   }
   else
   {
       session = SessionGet(sessionHandle);
       // If the session is bound to lockout, then use that as the relevant
       // handle. This means that an auth failure with a bound session
       // bound to lockoutAuth will take precedence over any other
       // lockout check
       if(session->attributes.isLockoutBound == SET)
           handle = TPM_RH_LOCKOUT;
         if(      session->attributes.isDaBound == CLEAR
               && IsDAExempted(handle)
           )
               // If the handle was changed to TPM_RH_LOCKOUT, this will not return
               // TPM_RC_BAD_AUTH
                return TPM_RC_BAD_AUTH;
   }
   if(handle == TPM_RH_LOCKOUT)
    {
         pAssert(gp.lockOutAuthEnabled);
         gp.lockOutAuthEnabled = FALSE;
         // For TPM_RH_LOCKOUT, if lockoutRecovery is 0, no need to update NV since
         // the lockout auth will be reset at startup.
         if(gp.lockoutRecovery != 0)
         {
             result = NvIsAvailable();
             if(result != TPM_RC_SUCCESS)
             {
                 // No NV access for now. Put the TPM in pending mode.
                 s_DAPendingOnNV = TRUE;
             }
             else
             {
                 // Update NV.
                 NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
                 g_updateNV = TRUE;
             }
         }
    }
    else
    {
        if(gp.recoveryTime != 0)
        {
            gp.failedTries++;
            result = NvIsAvailable();
            if(result != TPM_RC_SUCCESS)
            {
                // No NV access for now. Put the TPM in pending mode.
                s_DAPendingOnNV = TRUE;
            }
            else
            {
                // Record changes to NV.
                NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
                g_updateNV = TRUE;
            }
        }
    }
    // Register a DA failure and reset the timers.
    DARegisterFailure(handle);
    return TPM_RC_AUTH_FAIL;
}
//
//
//           IsSessionBindEntity()
//
//      This function indicates if the entity associated with the handle is the entity, to which this session is bound.
//      The binding would occur by making the bind parameter in TPM2_StartAuthSession() not equal to
//      TPM_RH_NULL. The binding only occurs if the session is an HMAC session. The bind value is a
//      combination of the Name and the authValue of the entity.
//
//      Return Value                      Meaning
//
//      TRUE                              handle points to the session start entity
//      FALSE                             handle does not point to the session start entity
//
static BOOL
IsSessionBindEntity(
    TPM_HANDLE           associatedHandle,         // IN: handle to be authorized
    SESSION             *session                   // IN: associated session
    )
{
    TPM2B_NAME        entity;                    // The bind value for the entity
    // If the session is not bound, return FALSE.
    if(!session->attributes.isBound)
        return FALSE;
    // Compute the bind value for the entity.
    SessionComputeBoundEntity(associatedHandle, &entity);
    // Compare to the bind value in the session.
    session->attributes.requestWasBound =
            Memory2BEqual(&entity.b, &session->u1.boundEntity.b);
    return session->attributes.requestWasBound;
}
//
//
//           IsPolicySessionRequired()
//
//      Checks if a policy session is required for a command. If a command requires DUP or ADMIN role
//      authorization, then the handle that requires that role is the first handle in the command. This simplifies
//      this checking. If a new command is created that requires multiple ADMIN role authorizations, then it will
//      have to be special-cased in this function. A policy session is required if:
//      a) the command requires the DUP role,
//      b) the command requires the ADMIN role and the authorized entity is an object and its adminWithPolicy
//         bit is SET, or
//      c) the command requires the ADMIN role and the authorized entity is a permanent handle or an NV
//         Index.
//      d) The authorized entity is a PCR belonging to a policy group, and has its policy initialized
//
//      Return Value                     Meaning
//
//      TRUE                             policy session is required
//      FALSE                            policy session is not required
//
static BOOL
IsPolicySessionRequired(
    TPM_CC               commandCode,        // IN: command code
    UINT32               sessionIndex        // IN: session index
    )
{
    AUTH_ROLE           role = CommandAuthRole(commandCode, sessionIndex);
    TPM_HT              type = HandleGetType(s_associatedHandles[sessionIndex]);
    if(role == AUTH_DUP)
        return TRUE;
    if(role == AUTH_ADMIN)
    {
        if(type == TPM_HT_TRANSIENT)
        {
            OBJECT      *object = ObjectGet(s_associatedHandles[sessionIndex]);
              if(object->publicArea.objectAttributes.adminWithPolicy == CLEAR)
                  return FALSE;
         }
         return TRUE;
    }
//
    if(type == TPM_HT_PCR)
    {
        if(PCRPolicyIsAvailable(s_associatedHandles[sessionIndex]))
        {
            TPM2B_DIGEST        policy;
            TPMI_ALG_HASH       policyAlg;
            policyAlg = PCRGetAuthPolicy(s_associatedHandles[sessionIndex],
                                          &policy);
            if(policyAlg != TPM_ALG_NULL)
                return TRUE;
        }
    }
    return FALSE;
}
//
//
//           IsAuthValueAvailable()
//
//      This function indicates if authValue is available and allowed for USER role authorization of an entity.
//      This function is similar to IsAuthPolicyAvailable() except that it does not check the size of the authValue
//      as IsAuthPolicyAvailable() does (a null authValue is a valid auth, but a null policy is not a valid policy).
//      This function does not check that the handle reference is valid or if the entity is in an enabled hierarchy.
//      Those checks are assumed to have been performed during the handle unmarshaling.
//
//      Return Value                      Meaning
//
//      TRUE                              authValue is available
//      FALSE                             authValue is not available
//
static BOOL
IsAuthValueAvailable(
    TPM_HANDLE           handle,             // IN: handle of entity
    TPM_CC               commandCode,        // IN: commandCode
    UINT32               sessionIndex        // IN: session index
    )
{
    BOOL             result = FALSE;
    // If a policy session is required, the entity can not be authorized by
    // authValue. However, at this point, the policy session requirement should
    // already have been checked.
    pAssert(!IsPolicySessionRequired(commandCode, sessionIndex));
   switch(HandleGetType(handle))
   {
       case TPM_HT_PERMANENT:
           switch(handle)
           {
                   // At this point hierarchy availability has already been
                   // checked so primary seed handles are always available here
               case TPM_RH_OWNER:
               case TPM_RH_ENDORSEMENT:
               case TPM_RH_PLATFORM:
#ifdef VENDOR_PERMANENT
                   // This vendor defined handle associated with the
                   // manufacturer's shared secret
               case VENDOR_PERMANENT:
#endif
                   // NullAuth is always available.
               case TPM_RH_NULL:
                    // At the point when authValue availability is checked, control
                   // path has already passed the DA check so LockOut auth is
                   // always available here
               case TPM_RH_LOCKOUT:
                      result = TRUE;
                      break;
                  default:
                      // Otherwise authValue is not available.
                      break;
            }
            break;
        case TPM_HT_TRANSIENT:
            // A persistent object has already been loaded and the internal
            // handle changed.
            {
                OBJECT          *object;
                object = ObjectGet(handle);
                  // authValue is always available for a sequence object.
                  if(ObjectIsSequence(object))
                  {
                       result = TRUE;
                       break;
                  }
                  // authValue is available for an object if it has its sensitive
                  // portion loaded and
                  // 1. userWithAuth bit is SET, or
                  // 2. ADMIN role is required
                  if(    object->attributes.publicOnly == CLEAR
                      &&    (object->publicArea.objectAttributes.userWithAuth == SET
                         || (CommandAuthRole(commandCode, sessionIndex) == AUTH_ADMIN
                            && object->publicArea.objectAttributes.adminWithPolicy
                               == CLEAR)))
                       result = TRUE;
            }
            break;
        case TPM_HT_NV_INDEX:
            // NV Index.
            {
                NV_INDEX         nvIndex;
                NvGetIndexInfo(handle, &nvIndex);
                if(IsWriteOperation(commandCode))
                {
                    if (nvIndex.publicArea.attributes.TPMA_NV_AUTHWRITE == SET)
                         result = TRUE;
                  }
                  else
                  {
                      if (nvIndex.publicArea.attributes.TPMA_NV_AUTHREAD == SET)
                          result = TRUE;
                  }
            }
            break;
        case TPM_HT_PCR:
            // PCR handle.
            // authValue is always allowed for PCR
            result = TRUE;
            break;
        default:
            // Otherwise, authValue is not available
            break;
   }
   return result;
}
//
//
//
//           IsAuthPolicyAvailable()
//
//      This function indicates if an authPolicy is available and allowed.
//      This function does not check that the handle reference is valid or if the entity is in an enabled hierarchy.
//      Those checks are assumed to have been performed during the handle unmarshaling.
//
//      Return Value                      Meaning
//
//      TRUE                              authPolicy is available
//      FALSE                             authPolicy is not available
//
static BOOL
IsAuthPolicyAvailable(
    TPM_HANDLE           handle,              // IN: handle of entity
    TPM_CC               commandCode,         // IN: commandCode
    UINT32               sessionIndex         // IN: session index
    )
{
    BOOL            result = FALSE;
    switch(HandleGetType(handle))
    {
        case TPM_HT_PERMANENT:
            switch(handle)
            {
                // At this point hierarchy availability has already been checked.
                case TPM_RH_OWNER:
                    if (gp.ownerPolicy.t.size != 0)
                        result = TRUE;
                    break;
                   case TPM_RH_ENDORSEMENT:
                       if (gp.endorsementPolicy.t.size != 0)
                           result = TRUE;
                       break;
                   case TPM_RH_PLATFORM:
                       if (gc.platformPolicy.t.size != 0)
                            result = TRUE;
                       break;
                   case TPM_RH_LOCKOUT:
                       if(gp.lockoutPolicy.t.size != 0)
                            result = TRUE;
                       break;
                   default:
                       break;
             }
             break;
         case TPM_HT_TRANSIENT:
             {
                 // Object handle.
                 // An evict object would already have been loaded and given a
                 // transient object handle by this point.
                 OBJECT *object = ObjectGet(handle);
                 // Policy authorization is not available for an object with only
                 // public portion loaded.
                 if(object->attributes.publicOnly == CLEAR)
                 {
                     // Policy authorization is always available for an object but
                     // is never available for a sequence.
                     if(!ObjectIsSequence(object))
                         result = TRUE;
                 }
                 break;
             }
         case TPM_HT_NV_INDEX:
             // An NV Index.
             {
                  NV_INDEX          nvIndex;
                  NvGetIndexInfo(handle, &nvIndex);
                  // If the policy size is not zero, check if policy can be used.
                  if(nvIndex.publicArea.authPolicy.t.size != 0)
                  {
                      // If policy session is required for this handle, always
                      // uses policy regardless of the attributes bit setting
                      if(IsPolicySessionRequired(commandCode, sessionIndex))
                           result = TRUE;
                      // Otherwise, the presence of the policy depends on the NV
                      // attributes.
                      else if(IsWriteOperation(commandCode))
                      {
                           if (   nvIndex.publicArea.attributes.TPMA_NV_POLICYWRITE
                               == SET)
                               result = TRUE;
                      }
                      else
                      {
                           if (    nvIndex.publicArea.attributes.TPMA_NV_POLICYREAD
                               == SET)
                               result = TRUE;
                      }
                  }
             }
             break;
         case TPM_HT_PCR:
             // PCR handle.
             if(PCRPolicyIsAvailable(handle))
                  result = TRUE;
             break;
         default:
             break;
   }
   return result;
}
//
//
//           Session Parsing Functions
//
//           ComputeCpHash()
//
//      This function computes the cpHash as defined in Part 2 and described in Part 1.
//
static void
ComputeCpHash(
   TPMI_ALG_HASH        hashAlg,               //   IN: hash algorithm
   TPM_CC               commandCode,           //   IN: command code
   UINT32               handleNum,             //   IN: number of handle
   TPM_HANDLE           handles[],             //   IN: array of handle
   UINT32               parmBufferSize,        //   IN: size of input parameter area
   BYTE                *parmBuffer,            //   IN: input parameter area
   TPM2B_DIGEST        *cpHash,                //   OUT: cpHash
   TPM2B_DIGEST        *nameHash               //   OUT: name hash of command
   )
{
   UINT32               i;
   HASH_STATE           hashState;
   TPM2B_NAME           name;
//
   // cpHash = hash(commandCode [ || authName1
   //                           [ || authName2
   //                           [ || authName 3 ]]]
   //                           [ || parameters])
   // A cpHash can contain just a commandCode only if the lone session is
   // an audit session.
   // Start cpHash.
   cpHash->t.size = CryptStartHash(hashAlg, &hashState);
   // Add commandCode.
   CryptUpdateDigestInt(&hashState, sizeof(TPM_CC), &commandCode);
   // Add authNames for each of the handles.
   for(i = 0; i < handleNum; i++)
   {
       name.t.size = EntityGetName(handles[i], &name.t.name);
       CryptUpdateDigest2B(&hashState, &name.b);
   }
   // Add the parameters.
   CryptUpdateDigest(&hashState, parmBufferSize, parmBuffer);
   // Complete the hash.
   CryptCompleteHash2B(&hashState, &cpHash->b);
   // If the nameHash is needed, compute it here.
   if(nameHash != NULL)
   {
       // Start name hash. hashState may be reused.
       nameHash->t.size = CryptStartHash(hashAlg, &hashState);
         // Adding names.
         for(i = 0; i < handleNum; i++)
         {
             name.t.size = EntityGetName(handles[i], &name.t.name);
             CryptUpdateDigest2B(&hashState, &name.b);
         }
         // Complete hash.
         CryptCompleteHash2B(&hashState, &nameHash->b);
   }
   return;
}
//
//
//           CheckPWAuthSession()
//
//      This function validates the authorization provided in a PWAP session. It compares the input value to
//      authValue of the authorized entity. Argument sessionIndex is used to get handles handle of the
//      referenced entities from s_inputAuthValues[] and s_associatedHandles[].
//
//      Error Returns                     Meaning
//
//      TPM_RC_AUTH_FAIL                  auth fails and increments DA failure count
//      TPM_RC_BAD_AUTH                   auth fails but DA does not apply
//
static TPM_RC
CheckPWAuthSession(
   UINT32              sessionIndex          // IN: index of session to be processed
   )
{
   TPM2B_AUTH         authValue;
   TPM_HANDLE         associatedHandle = s_associatedHandles[sessionIndex];
   // Strip trailing zeros from the password.
   MemoryRemoveTrailingZeros(&s_inputAuthValues[sessionIndex]);
   // Get the auth value and size.
   authValue.t.size = EntityGetAuthValue(associatedHandle, &authValue.t.buffer);
   // Success if the digests are identical.
   if(Memory2BEqual(&s_inputAuthValues[sessionIndex].b, &authValue.b))
   {
       return TPM_RC_SUCCESS;
   }
   else                    // if the digests are not identical
   {
       // Invoke DA protection if applicable.
       return IncrementLockout(sessionIndex);
   }
}
//
//
//          ComputeCommandHMAC()
//
//      This function computes the HMAC for an authorization session in a command.
//
static void
ComputeCommandHMAC(
   UINT32              sessionIndex,    // IN: index of session to be processed
   TPM2B_DIGEST       *cpHash,          // IN: cpHash
   TPM2B_DIGEST       *hmac             // OUT: authorization HMAC
   )
{
   TPM2B_TYPE(KEY,    (sizeof(AUTH_VALUE) * 2));
   TPM2B_KEY           key;
   BYTE                marshalBuffer[sizeof(TPMA_SESSION)];
   BYTE               *buffer;
   UINT32              marshalSize;
   HMAC_STATE          hmacState;
   TPM2B_NONCE        *nonceDecrypt;
   TPM2B_NONCE        *nonceEncrypt;
   SESSION            *session;
   TPM_HT              sessionHandleType =
                               HandleGetType(s_sessionHandles[sessionIndex]);
   nonceDecrypt = NULL;
   nonceEncrypt = NULL;
   // Determine if extra nonceTPM values are going to be required.
   // If this is the first session (sessionIndex = 0) and it is an authorization
   // session that uses an HMAC, then check if additional session nonces are to be
   // included.
   if(   sessionIndex == 0
      && s_associatedHandles[sessionIndex] != TPM_RH_UNASSIGNED)
   {
       // If there is a decrypt session and if this is not the decrypt session,
       // then an extra nonce may be needed.
       if(    s_decryptSessionIndex != UNDEFINED_INDEX
           && s_decryptSessionIndex != sessionIndex)
       {
            // Will add the nonce for the decrypt session.
            SESSION *decryptSession
                        = SessionGet(s_sessionHandles[s_decryptSessionIndex]);
            nonceDecrypt = &decryptSession->nonceTPM;
       }
       // Now repeat for the encrypt session.
       if(    s_encryptSessionIndex != UNDEFINED_INDEX
           && s_encryptSessionIndex != sessionIndex
//
             && s_encryptSessionIndex != s_decryptSessionIndex)
         {
             // Have to have the nonce for the encrypt session.
             SESSION *encryptSession
                         = SessionGet(s_sessionHandles[s_encryptSessionIndex]);
             nonceEncrypt = &encryptSession->nonceTPM;
         }
   }
   // Continue with the HMAC processing.
   session = SessionGet(s_sessionHandles[sessionIndex]);
   // Generate HMAC key.
   MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer));
   //   Check if the session has an associated handle and if the associated entity
   //   is the one to which the session is bound. If not, add the authValue of
   //   this entity to the HMAC key.
   //   If the session is bound to the object or the session is a policy session
   //   with no authValue required, do not include the authValue in the HMAC key.
   //   Note: For a policy session, its isBound attribute is CLEARED.
   // If the session isn't used for authorization, then there is no auth value
   // to add
   if(s_associatedHandles[sessionIndex] != TPM_RH_UNASSIGNED)
   {
       // used for auth so see if this is a policy session with authValue needed
       // or an hmac session that is not bound
       if(         sessionHandleType == TPM_HT_POLICY_SESSION
               && session->attributes.isAuthValueNeeded == SET
           ||      sessionHandleType == TPM_HT_HMAC_SESSION
               && !IsSessionBindEntity(s_associatedHandles[sessionIndex], session)
         )
       {
           // add the authValue to the HMAC key
           pAssert((sizeof(AUTH_VALUE) + key.t.size) <= sizeof(key.t.buffer));
           key.t.size =   key.t.size
                        + EntityGetAuthValue(s_associatedHandles[sessionIndex],
                                        (AUTH_VALUE *)&(key.t.buffer[key.t.size]));
       }
   }
    // if the HMAC key size is 0, a NULL string HMAC is allowed
    if(    key.t.size == 0
        && s_inputAuthValues[sessionIndex].t.size == 0)
    {
        hmac->t.size = 0;
        return;
    }
   // Start HMAC
   hmac->t.size = CryptStartHMAC2B(session->authHashAlg, &key.b, &hmacState);
   // Add cpHash
   CryptUpdateDigest2B(&hmacState, &cpHash->b);
   // Add nonceCaller
   CryptUpdateDigest2B(&hmacState, &s_nonceCaller[sessionIndex].b);
   // Add nonceTPM
   CryptUpdateDigest2B(&hmacState, &session->nonceTPM.b);
   // If needed, add nonceTPM for decrypt session
   if(nonceDecrypt != NULL)
       CryptUpdateDigest2B(&hmacState, &nonceDecrypt->b);
    // If needed, add nonceTPM for encrypt session
    if(nonceEncrypt != NULL)
        CryptUpdateDigest2B(&hmacState, &nonceEncrypt->b);
    // Add sessionAttributes
    buffer = marshalBuffer;
    marshalSize = TPMA_SESSION_Marshal(&(s_attributes[sessionIndex]),
                                       &buffer, NULL);
    CryptUpdateDigest(&hmacState, marshalSize, marshalBuffer);
    // Complete the HMAC computation
    CryptCompleteHMAC2B(&hmacState, &hmac->b);
    return;
}
//
//
//           CheckSessionHMAC()
//
//      This function checks the HMAC of in a session. It uses ComputeCommandHMAC() to compute the
//      expected HMAC value and then compares the result with the HMAC in the authorization session. The
//      authorization is successful if they are the same.
//      If the authorizations are not the same, IncrementLockout() is called. It will return TPM_RC_AUTH_FAIL if
//      the failure caused the failureCount to increment. Otherwise, it will return TPM_RC_BAD_AUTH.
//
//      Error Returns                    Meaning
//
//      TPM_RC_AUTH_FAIL                 auth failure caused failureCount increment
//      TPM_RC_BAD_AUTH                  auth failure did not cause failureCount increment
//
static TPM_RC
CheckSessionHMAC(
    UINT32               sessionIndex,      // IN: index of session to be processed
    TPM2B_DIGEST        *cpHash             // IN: cpHash of the command
    )
{
    TPM2B_DIGEST             hmac;                // authHMAC for comparing
    // Compute authHMAC
    ComputeCommandHMAC(sessionIndex, cpHash, &hmac);
    // Compare the input HMAC with the authHMAC computed above.
    if(!Memory2BEqual(&s_inputAuthValues[sessionIndex].b, &hmac.b))
    {
        // If an HMAC session has a failure, invoke the anti-hammering
        // if it applies to the authorized entity or the session.
        // Otherwise, just indicate that the authorization is bad.
        return IncrementLockout(sessionIndex);
    }
    return TPM_RC_SUCCESS;
}
//
//
//           CheckPolicyAuthSession()
//
//      This function is used to validate the authorization in a policy session. This function performs the following
//      comparisons to see if a policy authorization is properly provided. The check are:
//      a) compare policyDigest in session with authPolicy associated with the entity to be authorized;
//      b) compare timeout if applicable;
//      c) compare commandCode if applicable;
//
//      d) compare cpHash if applicable; and
//      e) see if PCR values have changed since computed.
//      If all the above checks succeed, the handle is authorized. The order of these comparisons is not
//      important because any failure will result in the same error code.
//
//      Error Returns                     Meaning
//
//      TPM_RC_PCR_CHANGED                PCR value is not current
//      TPM_RC_POLICY_FAIL                policy session fails
//      TPM_RC_LOCALITY                   command locality is not allowed
//      TPM_RC_POLICY_CC                  CC doesn't match
//      TPM_RC_EXPIRED                    policy session has expired
//      TPM_RC_PP                         PP is required but not asserted
//      TPM_RC_NV_UNAVAILABLE             NV is not available for write
//      TPM_RC_NV_RATE                    NV is rate limiting
//
static TPM_RC
CheckPolicyAuthSession(
   UINT32              sessionIndex,          //   IN: index of session to be processed
   TPM_CC              commandCode,           //   IN: command code
   TPM2B_DIGEST       *cpHash,                //   IN: cpHash using the algorithm of this
                                              //       session
   TPM2B_DIGEST       *nameHash               //   IN: nameHash using the session algorithm
   )
{
   TPM_RC              result = TPM_RC_SUCCESS;
   SESSION            *session;
   TPM2B_DIGEST        authPolicy;
   TPMI_ALG_HASH       policyAlg;
   UINT8               locality;
   // Initialize pointer to the auth session.
   session = SessionGet(s_sessionHandles[sessionIndex]);
   // If the command is TPM_RC_PolicySecret(), make sure that
   // either password or authValue is required
   if(     commandCode == TPM_CC_PolicySecret
       && session->attributes.isPasswordNeeded == CLEAR
       && session->attributes.isAuthValueNeeded == CLEAR)
       return TPM_RC_MODE;
   // See if the PCR counter for the session is still valid.
   if( !SessionPCRValueIsCurrent(s_sessionHandles[sessionIndex]) )
       return TPM_RC_PCR_CHANGED;
   // Get authPolicy.
   policyAlg = EntityGetAuthPolicy(s_associatedHandles[sessionIndex],
                                   &authPolicy);
   // Compare authPolicy.
   if(!Memory2BEqual(&session->u2.policyDigest.b, &authPolicy.b))
       return TPM_RC_POLICY_FAIL;
   // Policy is OK so check if the other factors are correct
   // Compare policy hash algorithm.
   if(policyAlg != session->authHashAlg)
       return TPM_RC_POLICY_FAIL;
   // Compare timeout.
   if(session->timeOut != 0)
   {
       // Cannot compare time if clock stop advancing. An TPM_RC_NV_UNAVAILABLE
       // or TPM_RC_NV_RATE error may be returned here.
       result = NvIsAvailable();
       if(result != TPM_RC_SUCCESS)
           return result;
        if(session->timeOut < go.clock)
            return TPM_RC_EXPIRED;
   }
   // If command code is provided it must match
   if(session->commandCode != 0)
   {
       if(session->commandCode != commandCode)
            return TPM_RC_POLICY_CC;
   }
   else
   {
       // If command requires a DUP or ADMIN authorization, the session must have
       // command code set.
       AUTH_ROLE    role = CommandAuthRole(commandCode, sessionIndex);
       if(role == AUTH_ADMIN || role == AUTH_DUP)
            return TPM_RC_POLICY_FAIL;
   }
   // Check command locality.
   {
       BYTE          sessionLocality[sizeof(TPMA_LOCALITY)];
       BYTE         *buffer = sessionLocality;
        // Get existing locality setting in canonical form
        TPMA_LOCALITY_Marshal(&session->commandLocality, &buffer, NULL);
       // See if the locality has been set
       if(sessionLocality[0] != 0)
       {
           // If so, get the current locality
           locality = _plat__LocalityGet();
           if (locality < 5)
           {
               if(    ((sessionLocality[0] & (1 << locality)) == 0)
                   || sessionLocality[0] > 31)
                   return TPM_RC_LOCALITY;
           }
           else if (locality > 31)
           {
               if(sessionLocality[0] != locality)
                   return TPM_RC_LOCALITY;
           }
           else
           {
               // Could throw an assert here but a locality error is just
               // as good. It just means that, whatever the locality is, it isn't
               // the locality requested so...
               return TPM_RC_LOCALITY;
           }
       }
   } // end of locality check
   // Check physical presence.
   if(   session->attributes.isPPRequired == SET
      && !_plat__PhysicalPresenceAsserted())
       return TPM_RC_PP;
   // Compare cpHash/nameHash if defined, or if the command requires an ADMIN or
   // DUP role for this handle.
   if(session->u1.cpHash.b.size != 0)
   {
       if(session->attributes.iscpHashDefined)
       {
            // Compare cpHash.
            if(!Memory2BEqual(&session->u1.cpHash.b, &cpHash->b))
                return TPM_RC_POLICY_FAIL;
       }
       else
       {
            // Compare nameHash.
            // When cpHash is not defined, nameHash is placed in its space.
            if(!Memory2BEqual(&session->u1.cpHash.b, &nameHash->b))
                return TPM_RC_POLICY_FAIL;
       }
   }
   if(session->attributes.checkNvWritten)
   {
       NV_INDEX         nvIndex;
         // If this is not an NV index, the policy makes no sense so fail it.
         if(HandleGetType(s_associatedHandles[sessionIndex])!= TPM_HT_NV_INDEX)
             return TPM_RC_POLICY_FAIL;
         // Get the index data
         NvGetIndexInfo(s_associatedHandles[sessionIndex], &nvIndex);
         // Make sure that the TPMA_WRITTEN_ATTRIBUTE has the desired state
         if(    (nvIndex.publicArea.attributes.TPMA_NV_WRITTEN == SET)
             != (session->attributes.nvWrittenState == SET))
             return TPM_RC_POLICY_FAIL;
   }
   return TPM_RC_SUCCESS;
}
//
//
//           RetrieveSessionData()
//
//      This function will unmarshal the sessions in the session area of a command. The values are placed in the
//      arrays that are defined at the beginning of this file. The normal unmarshaling errors are possible.
//
//      Error Returns                     Meaning
//
//      TPM_RC_SUCCSS                     unmarshaled without error
//      TPM_RC_SIZE                       the number of bytes unmarshaled is not the same as the value for
//                                        authorizationSize in the command
//
static TPM_RC
RetrieveSessionData (
   TPM_CC               commandCode,         //   IN: command   code
   UINT32              *sessionCount,        //   OUT: number   of sessions found
   BYTE                *sessionBuffer,       //   IN: pointer   to the session buffer
   INT32                bufferSize           //   IN: size of   the session buffer
   )
{
   int             sessionIndex;
   int             i;
   TPM_RC          result;
   SESSION        *session;
   TPM_HT          sessionType;
   s_decryptSessionIndex = UNDEFINED_INDEX;
   s_encryptSessionIndex = UNDEFINED_INDEX;
   s_auditSessionIndex = UNDEFINED_INDEX;
   for(sessionIndex = 0; bufferSize > 0; sessionIndex++)
   {
       // If maximum allowed number of sessions has been parsed, return a size
       // error with a session number that is larger than the number of allowed
       // sessions
       if(sessionIndex == MAX_SESSION_NUM)
           return TPM_RC_SIZE + TPM_RC_S + g_rcIndex[sessionIndex+1];
        // make sure that the associated handle for each session starts out
        // unassigned
        s_associatedHandles[sessionIndex] = TPM_RH_UNASSIGNED;
        // First parameter: Session handle.
        result = TPMI_SH_AUTH_SESSION_Unmarshal(&s_sessionHandles[sessionIndex],
                                                &sessionBuffer, &bufferSize, TRUE);
        if(result != TPM_RC_SUCCESS)
            return result + TPM_RC_S + g_rcIndex[sessionIndex];
        // Second parameter: Nonce.
        result = TPM2B_NONCE_Unmarshal(&s_nonceCaller[sessionIndex],
                                       &sessionBuffer, &bufferSize);
        if(result != TPM_RC_SUCCESS)
            return result + TPM_RC_S + g_rcIndex[sessionIndex];
        // Third parameter: sessionAttributes.
        result = TPMA_SESSION_Unmarshal(&s_attributes[sessionIndex],
                                        &sessionBuffer, &bufferSize);
        if(result != TPM_RC_SUCCESS)
            return result + TPM_RC_S + g_rcIndex[sessionIndex];
        // Fourth parameter: authValue (PW or HMAC).
        result = TPM2B_AUTH_Unmarshal(&s_inputAuthValues[sessionIndex],
                                      &sessionBuffer, &bufferSize);
        if(result != TPM_RC_SUCCESS)
            return result + TPM_RC_S + g_rcIndex[sessionIndex];
        if(s_sessionHandles[sessionIndex] == TPM_RS_PW)
        {
            // A PWAP session needs additional processing.
            //      Can't have any attributes set other than continueSession bit
            if(    s_attributes[sessionIndex].encrypt
                || s_attributes[sessionIndex].decrypt
                || s_attributes[sessionIndex].audit
                || s_attributes[sessionIndex].auditExclusive
                || s_attributes[sessionIndex].auditReset
              )
                 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex];
              //     The nonce size must be zero.
              if(s_nonceCaller[sessionIndex].t.size != 0)
                  return TPM_RC_NONCE + TPM_RC_S + g_rcIndex[sessionIndex];
            continue;
        }
        // For not password sessions...
        // Find out if the session is loaded.
        if(!SessionIsLoaded(s_sessionHandles[sessionIndex]))
            return TPM_RC_REFERENCE_S0 + sessionIndex;
        sessionType = HandleGetType(s_sessionHandles[sessionIndex]);
        session = SessionGet(s_sessionHandles[sessionIndex]);
        // Check if the session is an HMAC/policy session.
         if(        (   session->attributes.isPolicy == SET
                     && sessionType == TPM_HT_HMAC_SESSION
                    )
                 || (    session->attributes.isPolicy == CLEAR
                      && sessionType == TPM_HT_POLICY_SESSION
                    )
             )
                  return TPM_RC_HANDLE + TPM_RC_S + g_rcIndex[sessionIndex];
         // Check that this handle has not previously been used.
         for(i = 0; i < sessionIndex; i++)
         {
             if(s_sessionHandles[i] == s_sessionHandles[sessionIndex])
                 return TPM_RC_HANDLE + TPM_RC_S + g_rcIndex[sessionIndex];
         }
         // If the session is used for parameter encryption or audit as well, set
         // the corresponding indices.
         // First process decrypt.
         if(s_attributes[sessionIndex].decrypt)
         {
             // Check if the commandCode allows command parameter encryption.
             if(DecryptSize(commandCode) == 0)
                 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex];
                  // Encrypt attribute can only appear in one session
                  if(s_decryptSessionIndex != UNDEFINED_INDEX)
                      return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex];
                  // Can't decrypt if the session's symmetric algorithm is TPM_ALG_NULL
                  if(session->symmetric.algorithm == TPM_ALG_NULL)
                      return TPM_RC_SYMMETRIC + TPM_RC_S + g_rcIndex[sessionIndex];
                  // All checks passed, so set the index for the session used to decrypt
                  // a command parameter.
                  s_decryptSessionIndex = sessionIndex;
         }
         // Now process encrypt.
         if(s_attributes[sessionIndex].encrypt)
         {
             // Check if the commandCode allows response parameter encryption.
             if(EncryptSize(commandCode) == 0)
                 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex];
                  // Encrypt attribute can only appear in one session.
                  if(s_encryptSessionIndex != UNDEFINED_INDEX)
                      return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex];
                  // Can't encrypt if the session's symmetric algorithm is TPM_ALG_NULL
                  if(session->symmetric.algorithm == TPM_ALG_NULL)
                      return TPM_RC_SYMMETRIC + TPM_RC_S + g_rcIndex[sessionIndex];
                  // All checks passed, so set the index for the session used to encrypt
                  // a response parameter.
                  s_encryptSessionIndex = sessionIndex;
         }
         // At last process audit.
         if(s_attributes[sessionIndex].audit)
         {
             // Audit attribute can only appear in one session.
             if(s_auditSessionIndex != UNDEFINED_INDEX)
                 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex];
               // An audit session can not be policy session.
               if(    HandleGetType(s_sessionHandles[sessionIndex])
                   == TPM_HT_POLICY_SESSION)
                    return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex];
               // If this is a reset of the audit session, or the first use
               // of the session as an audit session, it doesn't matter what
               // the exclusive state is. The session will become exclusive.
               if(    s_attributes[sessionIndex].auditReset == CLEAR
                   && session->attributes.isAudit == SET)
               {
                    // Not first use or reset. If auditExlusive is SET, then this
                    // session must be the current exclusive session.
                    if(    s_attributes[sessionIndex].auditExclusive == SET
                        && g_exclusiveAuditSession != s_sessionHandles[sessionIndex])
                        return TPM_RC_EXCLUSIVE;
               }
               s_auditSessionIndex = sessionIndex;
         }
         // Initialize associated handle as undefined. This will be changed when
         // the handles are processed.
         s_associatedHandles[sessionIndex] = TPM_RH_UNASSIGNED;
    }
    // Set the number of sessions found.
    *sessionCount = sessionIndex;
    return TPM_RC_SUCCESS;
}
//
//
//             CheckLockedOut()
//
//      This function checks to see if the TPM is in lockout. This function should only be called if the entity being
//      checked is subject to DA protection. The TPM is in lockout if the NV is not available and a DA write is
//      pending. Otherwise the TPM is locked out if checking for lockoutAuth (lockoutAuthCheck == TRUE) and
//      use of lockoutAuth is disabled, or failedTries >= maxTries
//
//      Error Returns                    Meaning
//
//      TPM_RC_NV_RATE                   NV is rate limiting
//      TPM_RC_NV_UNAVAILABLE            NV is not available at this time
//      TPM_RC_LOCKOUT                   TPM is in lockout
//
static TPM_RC
CheckLockedOut(
    BOOL                 lockoutAuthCheck             // IN: TRUE if checking is for lockoutAuth
    )
{
    TPM_RC         result;
    // If NV is unavailable, and current cycle state recorded in NV is not
    // SHUTDOWN_NONE, refuse to check any authorization because we would
    // not be able to handle a DA failure.
    result = NvIsAvailable();
    if(result != TPM_RC_SUCCESS && gp.orderlyState != SHUTDOWN_NONE)
        return result;
    // Check if DA info needs to be updated in NV.
    if(s_DAPendingOnNV)
    {
         // If NV is accessible, ...
         if(result == TPM_RC_SUCCESS)
         {
              // ... write the pending DA data and proceed.
              NvWriteReserved(NV_LOCKOUT_AUTH_ENABLED,
                              &gp.lockOutAuthEnabled);
              NvWriteReserved(NV_FAILED_TRIES, &gp.failedTries);
              g_updateNV = TRUE;
              s_DAPendingOnNV = FALSE;
         }
         else
         {
              // Otherwise no authorization can be checked.
              return result;
         }
   }
   // Lockout is in effect if checking for lockoutAuth and use of lockoutAuth
   // is disabled...
   if(lockoutAuthCheck)
   {
       if(gp.lockOutAuthEnabled == FALSE)
           return TPM_RC_LOCKOUT;
   }
   else
   {
       // ... or if the number of failed tries has been maxed out.
       if(gp.failedTries >= gp.maxTries)
           return TPM_RC_LOCKOUT;
   }
   return TPM_RC_SUCCESS;
}
//
//
//           CheckAuthSession()
//
//      This function checks that the authorization session properly authorizes the use of the associated handle.
//
//      Error Returns                     Meaning
//
//      TPM_RC_LOCKOUT                    entity is protected by DA and TPM is in lockout, or TPM is locked out
//                                        on NV update pending on DA parameters
//      TPM_RC_PP                         Physical Presence is required but not provided
//      TPM_RC_AUTH_FAIL                  HMAC or PW authorization failed with DA side-effects (can be a
//                                        policy session)
//      TPM_RC_BAD_AUTH                   HMAC or PW authorization failed without DA side-effects (can be a
//                                        policy session)
//      TPM_RC_POLICY_FAIL                if policy session fails
//      TPM_RC_POLICY_CC                  command code of policy was wrong
//      TPM_RC_EXPIRED                    the policy session has expired
//      TPM_RC_PCR                        ???
//      TPM_RC_AUTH_UNAVAILABLE           authValue or authPolicy unavailable
//
static TPM_RC
CheckAuthSession(
   TPM_CC               commandCode,           //   IN:    commandCode
   UINT32               sessionIndex,          //   IN:    index of session to be processed
   TPM2B_DIGEST        *cpHash,                //   IN:    cpHash
   TPM2B_DIGEST        *nameHash               //   IN:    nameHash
//
   )
{
   TPM_RC              result;
   SESSION            *session = NULL;
   TPM_HANDLE          sessionHandle = s_sessionHandles[sessionIndex];
   TPM_HANDLE          associatedHandle = s_associatedHandles[sessionIndex];
   TPM_HT              sessionHandleType = HandleGetType(sessionHandle);
   pAssert(sessionHandle != TPM_RH_UNASSIGNED);
   if(sessionHandle != TPM_RS_PW)
       session = SessionGet(sessionHandle);
   pAssert(sessionHandleType != TPM_HT_POLICY_SESSION || session != NULL);
   // If the authorization session is not a policy session, or if the policy
   // session requires authorization, then check lockout.
   if(    sessionHandleType != TPM_HT_POLICY_SESSION
      || session->attributes.isAuthValueNeeded
      || session->attributes.isPasswordNeeded)
   {
       // See if entity is subject to lockout.
       if(!IsDAExempted(associatedHandle))
       {
           // If NV is unavailable, and current cycle state recorded in NV is not
           // SHUTDOWN_NONE, refuse to check any authorization because we would
           // not be able to handle a DA failure.
           result = CheckLockedOut(associatedHandle == TPM_RH_LOCKOUT);
           if(result != TPM_RC_SUCCESS)
               return result;
       }
   }
   if(associatedHandle == TPM_RH_PLATFORM)
   {
       // If the physical presence is required for this command, check for PP
       // assertion. If it isn't asserted, no point going any further.
       if(    PhysicalPresenceIsRequired(commandCode)
           && !_plat__PhysicalPresenceAsserted()
         )
            return TPM_RC_PP;
   }
   // If a policy session is required, make sure that it is being used.
   if(   IsPolicySessionRequired(commandCode, sessionIndex)
      && sessionHandleType != TPM_HT_POLICY_SESSION)
       return TPM_RC_AUTH_TYPE;
   // If this is a PW authorization, check it and return.
   if(sessionHandle == TPM_RS_PW)
   {
       if(IsAuthValueAvailable(associatedHandle, commandCode, sessionIndex))
            return CheckPWAuthSession(sessionIndex);
       else
            return TPM_RC_AUTH_UNAVAILABLE;
   }
   // If this is a policy session, ...
   if(sessionHandleType == TPM_HT_POLICY_SESSION)
   {
       // ... see if the entity has a policy, ...
       if( !IsAuthPolicyAvailable(associatedHandle, commandCode, sessionIndex))
            return TPM_RC_AUTH_UNAVAILABLE;
       // ... and check the policy session.
       result = CheckPolicyAuthSession(sessionIndex, commandCode,
                                        cpHash, nameHash);
       if (result != TPM_RC_SUCCESS)
            return result;
   }
   else
   {
       // For non policy, the entity being accessed must allow authorization
       // with an auth value. This is required even if the auth value is not
       // going to be used in an HMAC because it is bound.
       if(!IsAuthValueAvailable(associatedHandle, commandCode, sessionIndex))
           return TPM_RC_AUTH_UNAVAILABLE;
   }
   // At this point, the session must be either a policy or an HMAC session.
   session = SessionGet(s_sessionHandles[sessionIndex]);
   if(         sessionHandleType == TPM_HT_POLICY_SESSION
         &&    session->attributes.isPasswordNeeded == SET)
   {
         // For policy session that requires a password, check it as PWAP session.
         return CheckPWAuthSession(sessionIndex);
   }
   else
   {
       // For other policy or HMAC sessions, have its HMAC checked.
       return CheckSessionHMAC(sessionIndex, cpHash);
   }
}
#ifdef    TPM_CC_GetCommandAuditDigest
//
//
//            CheckCommandAudit()
//
//       This function checks if the current command may trigger command audit, and if it is safe to perform the
//       action.
//
//       Error Returns                     Meaning
//
//       TPM_RC_NV_UNAVAILABLE             NV is not available for write
//       TPM_RC_NV_RATE                    NV is rate limiting
//
static TPM_RC
CheckCommandAudit(
   TPM_CC               commandCode,                   //   IN:   Command code
   UINT32               handleNum,                     //   IN:   number of element in handle array
   TPM_HANDLE           handles[],                     //   IN:   array of handle
   BYTE                *parmBufferStart,               //   IN:   start of parameter buffer
   UINT32               parmBufferSize                 //   IN:   size of parameter buffer
   )
{
   TPM_RC          result = TPM_RC_SUCCESS;
   // If audit is implemented, need to check to see if auditing is being done
   // for this command.
   if(CommandAuditIsRequired(commandCode))
   {
       // If the audit digest is clear and command audit is required, NV must be
       // available so that TPM2_GetCommandAuditDigest() is able to increment
       // audit counter. If NV is not available, the function bails out to prevent
       // the TPM from attempting an operation that would fail anyway.
       if(     gr.commandAuditDigest.t.size == 0
           || commandCode == TPM_CC_GetCommandAuditDigest)
       {
            result = NvIsAvailable();
            if(result != TPM_RC_SUCCESS)
                return result;
       }
       ComputeCpHash(gp.auditHashAlg, commandCode, handleNum,
                         handles, parmBufferSize, parmBufferStart,
                         &s_cpHashForCommandAudit, NULL);
    }
   return TPM_RC_SUCCESS;
}
#endif
//
//
//           ParseSessionBuffer()
//
//       This function is the entry function for command session processing. It iterates sessions in session area
//       and reports if the required authorization has been properly provided. It also processes audit session and
//       passes the information of encryption sessions to parameter encryption module.
//
//       Error Returns                   Meaning
//
//       various                         parsing failure or authorization failure
//
TPM_RC
ParseSessionBuffer(
    TPM_CC              commandCode,                    //   IN:   Command code
    UINT32              handleNum,                      //   IN:   number of element in handle array
    TPM_HANDLE          handles[],                      //   IN:   array of handle
    BYTE               *sessionBufferStart,             //   IN:   start of session buffer
    UINT32              sessionBufferSize,              //   IN:   size of session buffer
    BYTE               *parmBufferStart,                //   IN:   start of parameter buffer
    UINT32              parmBufferSize                  //   IN:   size of parameter buffer
    )
{
    TPM_RC              result;
    UINT32              i;
    INT32               size = 0;
    TPM2B_AUTH          extraKey;
    UINT32              sessionIndex;
    SESSION            *session;
    TPM2B_DIGEST        cpHash;
    TPM2B_DIGEST        nameHash;
    TPM_ALG_ID          cpHashAlg = TPM_ALG_NULL;             // algID for the last computed
                                                              // cpHash
    // Check if a command allows any session in its session area.
    if(!IsSessionAllowed(commandCode))
        return TPM_RC_AUTH_CONTEXT;
    // Default-initialization.
    s_sessionNum = 0;
    cpHash.t.size = 0;
    result = RetrieveSessionData(commandCode, &s_sessionNum,
                                 sessionBufferStart, sessionBufferSize);
    if(result != TPM_RC_SUCCESS)
        return result;
    // There is no command in the TPM spec that has more handles than
    // MAX_SESSION_NUM.
    pAssert(handleNum <= MAX_SESSION_NUM);
    // Associate the session with an authorization handle.
    for(i = 0; i < handleNum; i++)
    {
        if(CommandAuthRole(commandCode, i) != AUTH_NONE)
        {
            // If the received session number is less than the number of handle
            // that requires authorization, an error should be returned.
             // Note: for all the TPM 2.0 commands, handles requiring
             // authorization come first in a command input.
             if(i > (s_sessionNum - 1))
                 return TPM_RC_AUTH_MISSING;
             // Record the handle associated with the authorization session
             s_associatedHandles[i] = handles[i];
         }
   }
   // Consistency checks are done first to avoid auth failure when the command
   // will not be executed anyway.
   for(sessionIndex = 0; sessionIndex < s_sessionNum; sessionIndex++)
   {
       // PW session must be an authorization session
       if(s_sessionHandles[sessionIndex] == TPM_RS_PW )
       {
            if(s_associatedHandles[sessionIndex] == TPM_RH_UNASSIGNED)
                return TPM_RC_HANDLE + g_rcIndex[sessionIndex];
       }
       else
       {
            session = SessionGet(s_sessionHandles[sessionIndex]);
             // A trial session can not appear in session area, because it cannot
             // be used for authorization, audit or encrypt/decrypt.
             if(session->attributes.isTrialPolicy == SET)
                 return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex];
             // See if the session is bound to a DA protected entity
             // NOTE: Since a policy session is never bound, a policy is still
             // usable even if the object is DA protected and the TPM is in
             // lockout.
             if(session->attributes.isDaBound == SET)
             {
                 result = CheckLockedOut(session->attributes.isLockoutBound == SET);
                 if(result != TPM_RC_SUCCESS)
                     return result;
             }
             // If the current cpHash is the right one, don't re-compute.
             if(cpHashAlg != session->authHashAlg)    // different so compute
             {
                 cpHashAlg = session->authHashAlg;    // save this new algID
                 ComputeCpHash(session->authHashAlg, commandCode, handleNum,
                               handles, parmBufferSize, parmBufferStart,
                               &cpHash, &nameHash);
             }
             // If this session is for auditing, save the cpHash.
             if(s_attributes[sessionIndex].audit)
                 s_cpHashForAudit = cpHash;
         }
         // if the session has an associated handle, check the auth
         if(s_associatedHandles[sessionIndex] != TPM_RH_UNASSIGNED)
         {
              result = CheckAuthSession(commandCode, sessionIndex,
                                        &cpHash, &nameHash);
              if(result != TPM_RC_SUCCESS)
                  return RcSafeAddToResult(result,
                                           TPM_RC_S + g_rcIndex[sessionIndex]);
         }
         else
         {
              // a session that is not for authorization must either be encrypt,
              // decrypt, or audit
              if(     s_attributes[sessionIndex].audit == CLEAR
                   && s_attributes[sessionIndex].encrypt == CLEAR
                   && s_attributes[sessionIndex].decrypt == CLEAR)
                   return TPM_RC_ATTRIBUTES + TPM_RC_S + g_rcIndex[sessionIndex];
               // check HMAC for encrypt/decrypt/audit only sessions
               result = CheckSessionHMAC(sessionIndex, &cpHash);
               if(result != TPM_RC_SUCCESS)
                   return RcSafeAddToResult(result,
                                            TPM_RC_S + g_rcIndex[sessionIndex]);
          }
   }
#ifdef TPM_CC_GetCommandAuditDigest
   // Check if the command should be audited.
   result = CheckCommandAudit(commandCode, handleNum, handles,
                              parmBufferStart, parmBufferSize);
   if(result != TPM_RC_SUCCESS)
       return result;              // No session number to reference
#endif
   // Decrypt the first parameter if applicable. This should be the last operation
   // in session processing.
   // If the encrypt session is associated with a handle and the handle's
   // authValue is available, then authValue is concatenated with sessionAuth to
   // generate encryption key, no matter if the handle is the session bound entity
   // or not.
   if(s_decryptSessionIndex != UNDEFINED_INDEX)
   {
       // Get size of the leading size field in decrypt parameter
       if(    s_associatedHandles[s_decryptSessionIndex] != TPM_RH_UNASSIGNED
           && IsAuthValueAvailable(s_associatedHandles[s_decryptSessionIndex],
                                   commandCode,
                                   s_decryptSessionIndex)
         )
       {
            extraKey.b.size=
                EntityGetAuthValue(s_associatedHandles[s_decryptSessionIndex],
                                   &extraKey.t.buffer);
       }
       else
       {
            extraKey.b.size = 0;
       }
       size = DecryptSize(commandCode);
       result = CryptParameterDecryption(
                     s_sessionHandles[s_decryptSessionIndex],
                     &s_nonceCaller[s_decryptSessionIndex].b,
                     parmBufferSize, (UINT16)size,
                     &extraKey,
                     parmBufferStart);
       if(result != TPM_RC_SUCCESS)
            return RcSafeAddToResult(result,
                                     TPM_RC_S + g_rcIndex[s_decryptSessionIndex]);
   }
   return TPM_RC_SUCCESS;
}
//
//
//              CheckAuthNoSession()
//
//       Function to process a command with no session associated. The function makes sure all the handles in
//       the command require no authorization.
//
//
//
//       Error Returns                     Meaning
//
//       TPM_RC_AUTH_MISSING               failure - one or more handles require auth
//
TPM_RC
CheckAuthNoSession(
   TPM_CC               commandCode,               //   IN:   Command Code
   UINT32               handleNum,                 //   IN:   number of handles in command
   TPM_HANDLE           handles[],                 //   IN:   array of handle
   BYTE                *parmBufferStart,           //   IN:   start of parameter buffer
   UINT32               parmBufferSize             //   IN:   size of parameter buffer
   )
{
   UINT32 i;
   TPM_RC                result = TPM_RC_SUCCESS;
   // Check if the commandCode requires authorization
   for(i = 0; i < handleNum; i++)
   {
       if(CommandAuthRole(commandCode, i) != AUTH_NONE)
           return TPM_RC_AUTH_MISSING;
   }
#ifdef TPM_CC_GetCommandAuditDigest
   // Check if the command should be audited.
   result = CheckCommandAudit(commandCode, handleNum, handles,
                              parmBufferStart, parmBufferSize);
   if(result != TPM_RC_SUCCESS) return result;
#endif
   // Initialize number of sessions to be 0
   s_sessionNum = 0;
   return TPM_RC_SUCCESS;
}
//
//
//            Response Session Processing
//
//            Introduction
//
//       The following functions build the session area in a response, and handle the audit sessions (if present).
//
//            ComputeRpHash()
//
//       Function to compute rpHash (Response Parameter Hash). The rpHash is only computed if there is an
//       HMAC authorization session and the return code is TPM_RC_SUCCESS.
//
static void
ComputeRpHash(
   TPM_ALG_ID           hashAlg,                   //   IN: hash algorithm to compute rpHash
   TPM_CC               commandCode,               //   IN: commandCode
   UINT32               resParmBufferSize,         //   IN: size of response parameter buffer
   BYTE                *resParmBuffer,             //   IN: response parameter buffer
   TPM2B_DIGEST        *rpHash                     //   OUT: rpHash
   )
{
   // The command result in rpHash is always TPM_RC_SUCCESS.
   TPM_RC      responseCode = TPM_RC_SUCCESS;
   HASH_STATE hashState;
   //     rpHash := hash(responseCode || commandCode || parameters)
    // Initiate hash creation.
    rpHash->t.size = CryptStartHash(hashAlg, &hashState);
    // Add hash constituents.
    CryptUpdateDigestInt(&hashState, sizeof(TPM_RC), &responseCode);
    CryptUpdateDigestInt(&hashState, sizeof(TPM_CC), &commandCode);
    CryptUpdateDigest(&hashState, resParmBufferSize, resParmBuffer);
    // Complete hash computation.
    CryptCompleteHash2B(&hashState, &rpHash->b);
    return;
}
//
//
//             InitAuditSession()
//
//       This function initializes the audit data in an audit session.
//
static void
InitAuditSession(
    SESSION              *session             // session to be initialized
    )
{
    // Mark session as an audit session.
    session->attributes.isAudit = SET;
    // Audit session can not be bound.
    session->attributes.isBound = CLEAR;
    // Size of the audit log is the size of session hash algorithm digest.
    session->u2.auditDigest.t.size = CryptGetHashDigestSize(session->authHashAlg);
    // Set the original digest value to be 0.
    MemorySet(&session->u2.auditDigest.t.buffer,
              0,
              session->u2.auditDigest.t.size);
    return;
}
//
//
//             Audit()
//
//       This function updates the audit digest in an audit session.
//
static void
Audit(
    SESSION              *auditSession,            //   IN:    loaded audit session
    TPM_CC                commandCode,             //   IN:    commandCode
    UINT32                resParmBufferSize,       //   IN:    size of response parameter buffer
    BYTE                 *resParmBuffer            //   IN:    response parameter buffer
    )
{
    TPM2B_DIGEST          rpHash;                  // rpHash for response
    HASH_STATE            hashState;
    // Compute rpHash
    ComputeRpHash(auditSession->authHashAlg,
                  commandCode,
                  resParmBufferSize,
                  resParmBuffer,
                  &rpHash);
   // auditDigestnew :=      hash (auditDigestold || cpHash || rpHash)
   // Start hash computation.
   CryptStartHash(auditSession->authHashAlg, &hashState);
   // Add old digest.
   CryptUpdateDigest2B(&hashState, &auditSession->u2.auditDigest.b);
   // Add cpHash and rpHash.
   CryptUpdateDigest2B(&hashState, &s_cpHashForAudit.b);
   CryptUpdateDigest2B(&hashState, &rpHash.b);
   // Finalize the hash.
   CryptCompleteHash2B(&hashState, &auditSession->u2.auditDigest.b);
   return;
}
#ifdef TPM_CC_GetCommandAuditDigest
//
//
//            CommandAudit()
//
//       This function updates the command audit digest.
//
static void
CommandAudit(
   TPM_CC              commandCode,       // IN: commandCode
   UINT32              resParmBufferSize, // IN: size of response parameter buffer
   BYTE               *resParmBuffer      // IN: response parameter buffer
   )
{
   if(CommandAuditIsRequired(commandCode))
   {
       TPM2B_DIGEST    rpHash;        // rpHash for response
       HASH_STATE      hashState;
         // Compute rpHash.
         ComputeRpHash(gp.auditHashAlg, commandCode, resParmBufferSize,
                       resParmBuffer, &rpHash);
         // If the digest.size is one, it indicates the special case of changing
         // the audit hash algorithm. For this case, no audit is done on exit.
         // NOTE: When the hash algorithm is changed, g_updateNV is set in order to
         // force an update to the NV on exit so that the change in digest will
         // be recorded. So, it is safe to exit here without setting any flags
         // because the digest change will be written to NV when this code exits.
         if(gr.commandAuditDigest.t.size == 1)
         {
             gr.commandAuditDigest.t.size = 0;
             return;
         }
         // If the digest size is zero, need to start a new digest and increment
         // the audit counter.
         if(gr.commandAuditDigest.t.size == 0)
         {
             gr.commandAuditDigest.t.size = CryptGetHashDigestSize(gp.auditHashAlg);
             MemorySet(gr.commandAuditDigest.t.buffer,
                       0,
                       gr.commandAuditDigest.t.size);
             // Bump the counter and save its value to NV.
             gp.auditCounter++;
             NvWriteReserved(NV_AUDIT_COUNTER, &gp.auditCounter);
             g_updateNV = TRUE;
//
         }
         // auditDigestnew :=         hash (auditDigestold || cpHash || rpHash)
         // Start hash computation.
         CryptStartHash(gp.auditHashAlg, &hashState);
         // Add old digest.
         CryptUpdateDigest2B(&hashState, &gr.commandAuditDigest.b);
         // Add cpHash
         CryptUpdateDigest2B(&hashState, &s_cpHashForCommandAudit.b);
         // Add rpHash
         CryptUpdateDigest2B(&hashState, &rpHash.b);
         // Finalize the hash.
         CryptCompleteHash2B(&hashState, &gr.commandAuditDigest.b);
    }
    return;
}
#endif
//
//
//              UpdateAuditSessionStatus()
//
//       Function to update the internal audit related states of a session. It
//       a) initializes the session as audit session and sets it to be exclusive if this is the first time it is used for
//          audit or audit reset was requested;
//       b) reports exclusive audit session;
//       c) extends audit log; and
//       d) clears exclusive audit session if no audit session found in the command.
//
static void
UpdateAuditSessionStatus(
    TPM_CC                commandCode,       // IN: commandCode
    UINT32                resParmBufferSize, // IN: size of response parameter buffer
    BYTE                 *resParmBuffer      // IN: response parameter buffer
    )
{
    UINT32                i;
    TPM_HANDLE            auditSession = TPM_RH_UNASSIGNED;
    // Iterate through sessions
    for (i = 0; i < s_sessionNum; i++)
    {
        SESSION     *session;
         // PW session do not have a loaded session and can not be an audit
         // session either. Skip it.
         if(s_sessionHandles[i] == TPM_RS_PW) continue;
         session = SessionGet(s_sessionHandles[i]);
         // If a session is used for audit
         if(s_attributes[i].audit == SET)
         {
             // An audit session has been found
             auditSession = s_sessionHandles[i];
              // If the session has not been an audit session yet, or
              // the auditSetting bits indicate a reset, initialize it and set
              // it to be the exclusive session
              if(    session->attributes.isAudit == CLEAR
                  || s_attributes[i].auditReset == SET
                )
              {
                   InitAuditSession(session);
                   g_exclusiveAuditSession = auditSession;
              }
              else
              {
                   // Check if the audit session is the current exclusive audit
                   // session and, if not, clear previous exclusive audit session.
                   if(g_exclusiveAuditSession != auditSession)
                       g_exclusiveAuditSession = TPM_RH_UNASSIGNED;
              }
              // Report audit session exclusivity.
              if(g_exclusiveAuditSession == auditSession)
              {
                  s_attributes[i].auditExclusive = SET;
              }
              else
              {
                  s_attributes[i].auditExclusive = CLEAR;
              }
              // Extend audit log.
              Audit(session, commandCode, resParmBufferSize, resParmBuffer);
         }
   }
   // If no audit session is found in the command, and the command allows
   // a session then, clear the current exclusive
   // audit session.
   if(auditSession == TPM_RH_UNASSIGNED && IsSessionAllowed(commandCode))
   {
       g_exclusiveAuditSession = TPM_RH_UNASSIGNED;
   }
   return;
}
//
//
//              ComputeResponseHMAC()
//
//       Function to compute HMAC for authorization session in a response.
//
static void
ComputeResponseHMAC(
   UINT32              sessionIndex,         //   IN: session index to be processed
   SESSION            *session,              //   IN: loaded session
   TPM_CC              commandCode,          //   IN: commandCode
   TPM2B_NONCE        *nonceTPM,             //   IN: nonceTPM
   UINT32              resParmBufferSize,    //   IN: size of response parameter buffer
   BYTE               *resParmBuffer,        //   IN: response parameter buffer
   TPM2B_DIGEST       *hmac                  //   OUT: authHMAC
   )
{
   TPM2B_TYPE(KEY, (sizeof(AUTH_VALUE) * 2));
   TPM2B_KEY        key;       // HMAC key
   BYTE             marshalBuffer[sizeof(TPMA_SESSION)];
   BYTE            *buffer;
   UINT32           marshalSize;
   HMAC_STATE       hmacState;
   TPM2B_DIGEST     rp_hash;
//
   // Compute rpHash.
   ComputeRpHash(session->authHashAlg, commandCode, resParmBufferSize,
                 resParmBuffer, &rp_hash);
   // Generate HMAC key
   MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer));
   // Check if the session has an associated handle and the associated entity is
   // the one that the session is bound to.
   // If not bound, add the authValue of this entity to the HMAC key.
   if(   s_associatedHandles[sessionIndex] != TPM_RH_UNASSIGNED
      &&    !( HandleGetType(s_sessionHandles[sessionIndex])
                 == TPM_HT_POLICY_SESSION
         &&   session->attributes.isAuthValueNeeded == CLEAR)
      && !session->attributes.requestWasBound)
   {
       pAssert((sizeof(AUTH_VALUE) + key.t.size) <= sizeof(key.t.buffer));
       key.t.size = key.t.size +
                       EntityGetAuthValue(s_associatedHandles[sessionIndex],
                                          (AUTH_VALUE *)&key.t.buffer[key.t.size]);
   }
   // if the HMAC key size for a policy session is 0, the response HMAC is
   // computed according to the input HMAC
   if(HandleGetType(s_sessionHandles[sessionIndex]) == TPM_HT_POLICY_SESSION
       && key.t.size == 0
       && s_inputAuthValues[sessionIndex].t.size == 0)
   {
       hmac->t.size = 0;
       return;
   }
   // Start HMAC computation.
   hmac->t.size = CryptStartHMAC2B(session->authHashAlg, &key.b, &hmacState);
   // Add hash components.
   CryptUpdateDigest2B(&hmacState, &rp_hash.b);
   CryptUpdateDigest2B(&hmacState, &nonceTPM->b);
   CryptUpdateDigest2B(&hmacState, &s_nonceCaller[sessionIndex].b);
   // Add session attributes.
   buffer = marshalBuffer;
   marshalSize = TPMA_SESSION_Marshal(&s_attributes[sessionIndex], &buffer, NULL);
   CryptUpdateDigest(&hmacState, marshalSize, marshalBuffer);
   // Finalize HMAC.
   CryptCompleteHMAC2B(&hmacState, &hmac->b);
   return;
}
//
//
//           BuildSingleResponseAuth()
//
//       Function to compute response for an authorization session.
//
static void
BuildSingleResponseAuth(
   UINT32              sessionIndex,          //   IN: session index to be processed
   TPM_CC              commandCode,           //   IN: commandCode
   UINT32              resParmBufferSize,     //   IN: size of response parameter buffer
   BYTE               *resParmBuffer,         //   IN: response parameter buffer
   TPM2B_AUTH         *auth                   //   OUT: authHMAC
   )
//
{
   // For password authorization, field is empty.
   if(s_sessionHandles[sessionIndex] == TPM_RS_PW)
   {
       auth->t.size = 0;
   }
   else
   {
       // Fill in policy/HMAC based session response.
       SESSION     *session = SessionGet(s_sessionHandles[sessionIndex]);
          // If the session is a policy session with isPasswordNeeded SET, the auth
          // field is empty.
          if(HandleGetType(s_sessionHandles[sessionIndex]) == TPM_HT_POLICY_SESSION
                   && session->attributes.isPasswordNeeded == SET)
               auth->t.size = 0;
          else
               // Compute response HMAC.
               ComputeResponseHMAC(sessionIndex,
                                   session,
                                   commandCode,
                                   &session->nonceTPM,
                                   resParmBufferSize,
                                   resParmBuffer,
                                   auth);
   }
   return;
}
//
//
//            UpdateTPMNonce()
//
//       Updates TPM nonce in both internal session or response if applicable.
//
static void
UpdateTPMNonce(
   UINT16               noncesSize,       // IN: number of elements in 'nonces' array
   TPM2B_NONCE          nonces[]          // OUT: nonceTPM
   )
{
   UINT32      i;
   pAssert(noncesSize >= s_sessionNum);
   for(i = 0; i < s_sessionNum; i++)
   {
       SESSION     *session;
       // For PW session, nonce is 0.
       if(s_sessionHandles[i] == TPM_RS_PW)
       {
           nonces[i].t.size = 0;
           continue;
       }
       session = SessionGet(s_sessionHandles[i]);
       // Update nonceTPM in both internal session and response.
       CryptGenerateRandom(session->nonceTPM.t.size, session->nonceTPM.t.buffer);
       nonces[i] = session->nonceTPM;
   }
   return;
}
//
//
//           UpdateInternalSession()
//
//       Updates internal sessions:
//
//
//       a) Restarts session time, and
//       b) Clears a policy session since nonce is rolling.
//
static void
UpdateInternalSession(
   void
   )
{
   UINT32      i;
   for(i = 0; i < s_sessionNum; i++)
   {
       // For PW session, no update.
       if(s_sessionHandles[i] == TPM_RS_PW) continue;
          if(s_attributes[i].continueSession == CLEAR)
          {
               // Close internal session.
               SessionFlush(s_sessionHandles[i]);
          }
          else
          {
               // If nonce is rolling in a policy session, the policy related data
               // will be re-initialized.
               if(HandleGetType(s_sessionHandles[i]) == TPM_HT_POLICY_SESSION)
               {
                   SESSION     *session = SessionGet(s_sessionHandles[i]);
                   // When the nonce rolls it starts a new timing interval for the
                   // policy session.
                   SessionResetPolicyData(session);
                   session->startTime = go.clock;
               }
          }
   }
   return;
}
//
//
//              BuildResponseSession()
//
//       Function to build Session buffer in a response.
//
void
BuildResponseSession(
   TPM_ST               tag,               //    IN: tag
   TPM_CC               commandCode,       //    IN: commandCode
   UINT32               resHandleSize,     //    IN: size of response handle buffer
   UINT32               resParmSize,       //    IN: size of response parameter buffer
   UINT32              *resSessionSize     //    OUT: response session area
   )
{
   BYTE                *resParmBuffer;
   TPM2B_NONCE      responseNonces[MAX_SESSION_NUM];
   // Compute response parameter buffer start.
   resParmBuffer = MemoryGetResponseBuffer(commandCode) + sizeof(TPM_ST) +
                   sizeof(UINT32) + sizeof(TPM_RC) + resHandleSize;
   // For TPM_ST_SESSIONS, there is parameterSize field.
   if(tag == TPM_ST_SESSIONS)
       resParmBuffer += sizeof(UINT32);
   // Session nonce should be updated before parameter encryption
   if(tag == TPM_ST_SESSIONS)
   {
         UpdateTPMNonce(MAX_SESSION_NUM, responseNonces);
         // Encrypt first parameter if applicable. Parameter encryption should
         // happen after nonce update and before any rpHash is computed.
         // If the encrypt session is associated with a handle, the authValue of
         // this handle will be concatenated with sessionAuth to generate
         // encryption key, no matter if the handle is the session bound entity
         // or not. The authValue is added to sessionAuth only when the authValue
         // is available.
         if(s_encryptSessionIndex != UNDEFINED_INDEX)
         {
             UINT32          size;
             TPM2B_AUTH      extraKey;
             // Get size of the leading size field
             if(    s_associatedHandles[s_encryptSessionIndex] != TPM_RH_UNASSIGNED
                 && IsAuthValueAvailable(s_associatedHandles[s_encryptSessionIndex],
                                         commandCode, s_encryptSessionIndex)
               )
             {
                  extraKey.b.size =
                      EntityGetAuthValue(s_associatedHandles[s_encryptSessionIndex],
                                         &extraKey.t.buffer);
             }
             else
             {
                  extraKey.b.size = 0;
             }
             size = EncryptSize(commandCode);
             CryptParameterEncryption(s_sessionHandles[s_encryptSessionIndex],
                                       &s_nonceCaller[s_encryptSessionIndex].b,
                                       (UINT16)size,
                                       &extraKey,
                                       resParmBuffer);
         }
   }
   // Audit session should be updated first regardless of the tag.
   // A command with no session may trigger a change of the exclusivity state.
   UpdateAuditSessionStatus(commandCode, resParmSize, resParmBuffer);
   // Audit command.
   CommandAudit(commandCode, resParmSize, resParmBuffer);
   // Process command with sessions.
   if(tag == TPM_ST_SESSIONS)
   {
       UINT32           i;
       BYTE            *buffer;
       TPM2B_DIGEST     responseAuths[MAX_SESSION_NUM];
         pAssert(s_sessionNum > 0);
         // Iterate over each session in the command session area, and create
         // corresponding sessions for response.
         for(i = 0; i < s_sessionNum; i++)
         {
             BuildSingleResponseAuth(
                                      i,
                                      commandCode,
                                      resParmSize,
                                      resParmBuffer,
                                      &responseAuths[i]);
             // Make sure that continueSession is SET on any Password session.
              // This makes it marginally easier for the management software
              // to keep track of the closed sessions.
              if(    s_attributes[i].continueSession == CLEAR
                  && s_sessionHandles[i] == TPM_RS_PW)
              {
                   s_attributes[i].continueSession = SET;
              }
        }
        // Assemble Response Sessions.
        *resSessionSize = 0;
        buffer = resParmBuffer + resParmSize;
        for(i = 0; i < s_sessionNum; i++)
        {
            *resSessionSize += TPM2B_NONCE_Marshal(&responseNonces[i],
                                                   &buffer, NULL);
            *resSessionSize += TPMA_SESSION_Marshal(&s_attributes[i],
                                                    &buffer, NULL);
            *resSessionSize += TPM2B_DIGEST_Marshal(&responseAuths[i],
                                                    &buffer, NULL);
        }
        // Update internal sessions after completing response buffer computation.
        UpdateInternalSession();
   }
   else
   {
       // Process command with no session.
       *resSessionSize = 0;
   }
   return;
}
