/* Microsoft Reference Implementation for TPM 2.0
 *
 *  The copyright in this software is being made available under the BSD License,
 *  included below. This software may be subject to other third party and
 *  contributor rights, including patent rights, and no such rights are granted
 *  under this license.
 *
 *  Copyright (c) Microsoft Corporation
 *
 *  All rights reserved.
 *
 *  BSD License
 *
 *  Redistribution and use in source and binary forms, with or without modification,
 *  are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice, this list
 *  of conditions and the following disclaimer.
 *
 *  Redistributions in binary form must reproduce the above copyright notice, this
 *  list of conditions and the following disclaimer in the documentation and/or
 *  other materials provided with the distribution.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 *  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
//**  Introduction
// This file contains the subsystem that process the authorization sessions
// including implementation of the Dictionary Attack logic. ExecCommand() uses
// ParseSessionBuffer() to process the authorization session area of a command and
// BuildResponseSession() to create the authorization session area of a response.

//**  Includes and Data Definitions

#define SESSION_PROCESS_C

#include "Tpm.h"
#include "ACT.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 Type: BOOL
//      TRUE(1)         handle is exempted from DA logic
//      FALSE(0)        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:
        {
            TPMA_OBJECT     attributes = ObjectGetPublicAttributes(handle);
            result = IS_ATTRIBUTE(attributes, TPMA_OBJECT, noDA);
            break;
        }
        case TPM_HT_NV_INDEX:
        {
            NV_INDEX            *nvIndex = NvGetIndexInfo(handle, NULL);
            result = IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, NO_DA);
            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.
//
//  Return Type: TPM_RC
//      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];
    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 authorization 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) || session->attributes.includeAuth == CLEAR))
           // 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 == TRUE);

        // lockout is no longer enabled
        gp.lockOutAuthEnabled = FALSE;

        // For TPM_RH_LOCKOUT, if lockoutRecovery is 0, no need to update NV since
        // the lockout authorization will be reset at startup.
        if(gp.lockoutRecovery != 0)
        {
            if(NV_IS_AVAILABLE)
                // Update NV.
                NV_SYNC_PERSISTENT(lockOutAuthEnabled);
            else
                // No NV access for now. Put the TPM in pending mode.
                s_DAPendingOnNV = TRUE;
        }
    }
    else
    {
        if(gp.recoveryTime != 0)
        {
            gp.failedTries++;
            if(NV_IS_AVAILABLE)
                // Record changes to NV. NvWrite will SET g_updateNV
                NV_SYNC_PERSISTENT(failedTries);
            else
                // No NV access for now.  Put the TPM in pending mode.
                s_DAPendingOnNV = 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 Type: BOOL
//      TRUE(1)         handle points to the session start entity
//      FALSE(0)        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)
    {
        // Compute the bind value for the entity.
        SessionComputeBoundEntity(associatedHandle, &entity);

        // Compare to the bind value in the session.
        return MemoryEqual2B(&entity.b, &session->u1.boundEntity.b);
    }
    return FALSE;
}

//*** 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;
// c) the command requires the ADMIN role and the authorized entity
//    is a permanent handle or an NV Index; or
// d) the authorized entity is a PCR belonging to a policy group, and
//    has its policy initialized
//  Return Type: BOOL
//      TRUE(1)         policy session is required
//      FALSE(0)        policy session is not required
static BOOL
IsPolicySessionRequired(
    COMMAND_INDEX    commandIndex,  // IN: command index
    UINT32           sessionIndex   // IN: session index
    )
{
    AUTH_ROLE       role = CommandAuthRole(commandIndex, sessionIndex);
    TPM_HT          type = HandleGetType(s_associatedHandles[sessionIndex]);
//
    if(role == AUTH_DUP)
        return TRUE;
    if(role == AUTH_ADMIN)
    {
        // We allow an exception for ADMIN role in a transient object. If the object
        // allows ADMIN role actions with authorization, then policy is not
        // required. For all other cases, there is no way to override the command
        // requirement that a policy be used
        if(type == TPM_HT_TRANSIENT)
        {
            OBJECT      *object = HandleToObject(s_associatedHandles[sessionIndex]);

            if(!IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, 
                             adminWithPolicy))
                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 authorization, 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 Type: BOOL
//      TRUE(1)         authValue is available
//      FALSE(0)        authValue is not available
static BOOL
IsAuthValueAvailable(
    TPM_HANDLE       handle,        // IN: handle of entity
    COMMAND_INDEX    commandIndex,  // IN: command index
    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 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
                    // The DA checking has been performed on LockoutAuth but we
                    // bypass the DA logic if we are using lockout policy. The
                    // policy would allow execution to continue an lockoutAuth
                    // could be used, even if direct use of lockoutAuth is disabled
                case TPM_RH_LOCKOUT:
                    // NullAuth is always available.
                case TPM_RH_NULL:
                    result = TRUE;
                    break;
                FOR_EACH_ACT(CASE_ACT_HANDLE)
                {
                    // The ACT auth value is not available if the platform is disabled
                     result = g_phEnable == SET;
                     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;
            TPMA_OBJECT      attributes;
//
            object = HandleToObject(handle);
            attributes = object->publicArea.objectAttributes;

            // authValue is always available for a sequence object.
            // An alternative for this is to 
            // SET_ATTRIBUTE(object->publicArea, TPMA_OBJECT, userWithAuth) when the
            // sequence is started.
            if(ObjectIsSequence(object))
            {
                result = TRUE;
                break;
            }
            // authValue is available for an object if it has its sensitive
            // portion loaded and
            //  a) userWithAuth bit is SET, or
            //  b) ADMIN role is required
            if(object->attributes.publicOnly == CLEAR
               && (IS_ATTRIBUTE(attributes, TPMA_OBJECT, userWithAuth)
                   || (CommandAuthRole(commandIndex, sessionIndex) == AUTH_ADMIN
                       && !IS_ATTRIBUTE(attributes, TPMA_OBJECT, adminWithPolicy))))
                result = TRUE;
        }
        break;
        case TPM_HT_NV_INDEX:
            // NV Index.
        {
            NV_REF           locator;
            NV_INDEX        *nvIndex = NvGetIndexInfo(handle, &locator);
            TPMA_NV          nvAttributes;
//
            pAssert(nvIndex != 0);
            
            nvAttributes = nvIndex->publicArea.attributes;

            if(IsWriteOperation(commandIndex))
            {
                // AuthWrite can't be set for a PIN index
                if(IS_ATTRIBUTE(nvAttributes, TPMA_NV, AUTHWRITE))
                    result = TRUE;
            }
            else
            {
                // A "read" operation
                // For a PIN Index, the authValue is available as long as the
                // Index has been written and the pinCount is less than pinLimit
                if(IsNvPinFailIndex(nvAttributes)
                   || IsNvPinPassIndex(nvAttributes))
                {
                    NV_PIN          pin;
                    if(!IS_ATTRIBUTE(nvAttributes, TPMA_NV, WRITTEN))
                        break; // return false
                    // get the index values
                    pin.intVal = NvGetUINT64Data(nvIndex, locator);
                    if(pin.pin.pinCount < pin.pin.pinLimit)
                        result = TRUE;
                }
                // For non-PIN Indexes, need to allow use of the authValue
                else if(IS_ATTRIBUTE(nvAttributes, TPMA_NV, AUTHREAD))
                    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 Type: BOOL
//      TRUE(1)         authPolicy is available
//      FALSE(0)        authPolicy is not available
static BOOL
IsAuthPolicyAvailable(
    TPM_HANDLE       handle,        // IN: handle of entity
    COMMAND_INDEX    commandIndex,  // IN: command index
    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;
#define ACT_GET_POLICY(N)                                                           \
                case TPM_RH_ACT_##N:                                                \
                    if(go.ACT_##N.authPolicy.t.size != 0)                           \
                        result = TRUE;                                              \
                    break;
					
                FOR_EACH_ACT(ACT_GET_POLICY)

                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 = HandleToObject(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, NULL);
            TPMA_NV           nvAttributes = nvIndex->publicArea.attributes;
//
            // 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(commandIndex, sessionIndex))
                    result = TRUE;
                // Otherwise, the presence of the policy depends on the NV
                // attributes.
                else if(IsWriteOperation(commandIndex))
                {
                    if(IS_ATTRIBUTE(nvAttributes, TPMA_NV, POLICYWRITE))
                        result = TRUE;
                }
                else
                {
                    if(IS_ATTRIBUTE(nvAttributes, TPMA_NV, POLICYREAD))
                        result = TRUE;
                }
            }
        }
        break;
        case TPM_HT_PCR:
            // PCR handle.
            if(PCRPolicyIsAvailable(handle))
                result = TRUE;
            break;
        default:
            break;
    }
    return result;
}

//**  Session Parsing Functions

//*** ClearCpRpHashes()
void
ClearCpRpHashes(
    COMMAND         *command
    )
{
    // The macros expand according to the implemented hash algorithms. An IDE may 
    // complain that COMMAND does not contain SHA1CpHash or SHA1RpHash because of the
    // complexity of the macro expansion where the data space is defined; but, if SHA1
    // is implemented, it actually does  and the compiler is happy.
#define CLEAR_CP_HASH(HASH, Hash)     command->Hash##CpHash.b.size = 0;
    FOR_EACH_HASH(CLEAR_CP_HASH)
#define CLEAR_RP_HASH(HASH, Hash)     command->Hash##RpHash.b.size = 0;
    FOR_EACH_HASH(CLEAR_RP_HASH)
}


//*** GetCpHashPointer()
// Function to get a pointer to the cpHash of the command
static TPM2B_DIGEST *
GetCpHashPointer(
    COMMAND         *command,
    TPMI_ALG_HASH    hashAlg
    )
{
    TPM2B_DIGEST     *retVal;
//
    // Define the macro that will expand for each implemented algorithm in the switch
    // statement below.
#define GET_CP_HASH_POINTER(HASH, Hash)                                                   \
        case ALG_##HASH##_VALUE:                                                    \
            retVal = (TPM2B_DIGEST *)&command->Hash##CpHash;                        \
            break;

    switch(hashAlg)
    {
        // For each implemented hash, this will expand as defined above 
        // by GET_CP_HASH_POINTER. Your IDE may complain that
        // 'struct "COMMAND" has no field "SHA1CpHash"' but the compiler says
        // it does, so...
        FOR_EACH_HASH(GET_CP_HASH_POINTER)
        default:
            retVal = NULL;
            break;
    }
    return retVal;
}

//*** GetRpHashPointer()
// Function to get a pointer to the RpHash of the command
static TPM2B_DIGEST *
GetRpHashPointer(
    COMMAND         *command,
    TPMI_ALG_HASH    hashAlg
    )
{
    TPM2B_DIGEST    *retVal;
//
    // Define the macro that will expand for each implemented algorithm in the switch
    // statement below.
#define GET_RP_HASH_POINTER(HASH, Hash)                                             \
        case ALG_##HASH##_VALUE:                                                    \
            retVal = (TPM2B_DIGEST *)&command->Hash##RpHash;                        \
            break;

    switch(hashAlg)
    {
        // For each implemented hash, this will expand as defined above 
        // by GET_RP_HASH_POINTER. Your IDE may complain that
        // 'struct "COMMAND" has no field 'SHA1RpHash'" but the compiler says
        // it does, so...
        FOR_EACH_HASH(GET_RP_HASH_POINTER)
        default:
            retVal = NULL;
            break;
    }
    return retVal;
}


//*** ComputeCpHash()
// This function computes the cpHash as defined in Part 2 and described in Part 1.
static TPM2B_DIGEST *
ComputeCpHash(
    COMMAND         *command,       // IN: command parsing structure
    TPMI_ALG_HASH    hashAlg        // IN: hash algorithm
    )
{
    UINT32               i;
    HASH_STATE           hashState;
    TPM2B_NAME           name;
    TPM2B_DIGEST        *cpHash;
//
    // cpHash = hash(commandCode [ || authName1
    //                           [ || authName2
    //                           [ || authName 3 ]]]
    //                           [ || parameters])
    // A cpHash can contain just a commandCode only if the lone session is
    // an audit session.
    // Get pointer to the hash value
    cpHash = GetCpHashPointer(command, hashAlg);
    if(cpHash->t.size == 0)
    {
        cpHash->t.size = CryptHashStart(&hashState, hashAlg);
            //  Add commandCode.
        CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), command->code);
            //  Add authNames for each of the handles.
        for(i = 0; i < command->handleNum; i++)
            CryptDigestUpdate2B(&hashState, &EntityGetName(command->handles[i],
                                                           &name)->b);
            //  Add the parameters.
        CryptDigestUpdate(&hashState, command->parameterSize, 
                          command->parameterBuffer);
            //  Complete the hash.
        CryptHashEnd2B(&hashState, &cpHash->b);
    }
    return cpHash;
}

//*** GetCpHash()
// This function is used to access a precomputed cpHash.
static TPM2B_DIGEST *
GetCpHash(
    COMMAND         *command,
    TPMI_ALG_HASH    hashAlg
    )
{
    TPM2B_DIGEST        *cpHash = GetCpHashPointer(command, hashAlg);
 //
    pAssert(cpHash->t.size != 0);
    return cpHash;
}

//*** CompareTemplateHash()
// This function computes the template hash and compares it to the session
// templateHash. It is the hash of the second parameter
// assuming that the command is TPM2_Create(), TPM2_CreatePrimary(), or
// TPM2_CreateLoaded()
//  Return Type: BOOL
//      TRUE(1)         template hash equal to session->templateHash
//      FALSE(0)        template hash not equal to session->templateHash
static BOOL
CompareTemplateHash(
    COMMAND         *command,       // IN: parsing structure
    SESSION         *session        // IN: session data
    )
{
    BYTE                *pBuffer = command->parameterBuffer;
    INT32                pSize = command->parameterSize;
    TPM2B_DIGEST         tHash;
    UINT16               size;
//
    // Only try this for the three commands for which it is intended
    if(command->code != TPM_CC_Create
       && command->code != TPM_CC_CreatePrimary
#if CC_CreateLoaded
       && command->code != TPM_CC_CreateLoaded
#endif
       )
        return FALSE;
    // Assume that the first parameter is a TPM2B and unmarshal the size field
    // Note: this will not affect the parameter buffer and size in the calling
    // function.
    if(UINT16_Unmarshal(&size, &pBuffer, &pSize) != TPM_RC_SUCCESS)
        return FALSE;
    // reduce the space in the buffer.
    // NOTE: this could make pSize go negative if the parameters are not correct but
    // the unmarshaling code does not try to unmarshal if the remaining size is
    // negative.
    pSize -= size;

    // Advance the pointer
    pBuffer += size;

    // Get the size of what should be the template
    if(UINT16_Unmarshal(&size, &pBuffer, &pSize) != TPM_RC_SUCCESS)
        return FALSE;
    // See if this is reasonable
    if(size > pSize)
        return FALSE;
    // Hash the template data
    tHash.t.size = CryptHashBlock(session->authHashAlg, size, pBuffer, 
                                  sizeof(tHash.t.buffer), tHash.t.buffer);
    return(MemoryEqual2B(&session->u1.templateHash.b, &tHash.b));
}

//*** CompareNameHash()
// This function computes the name hash and compares it to the nameHash in the
// session data.
BOOL
CompareNameHash(
    COMMAND         *command,       // IN: main parsing structure
    SESSION         *session        // IN: session structure with nameHash
    )
{
    HASH_STATE           hashState;
    TPM2B_DIGEST         nameHash;
    UINT32               i;
    TPM2B_NAME           name;
//
    nameHash.t.size = CryptHashStart(&hashState, session->authHashAlg);
    //  Add names.
    for(i = 0; i < command->handleNum; i++)
        CryptDigestUpdate2B(&hashState, &EntityGetName(command->handles[i],
                                                       &name)->b);
    //  Complete hash.
    CryptHashEnd2B(&hashState, &nameHash.b);
    // and compare
    return MemoryEqual(session->u1.nameHash.t.buffer, nameHash.t.buffer,
                       nameHash.t.size);
}

//*** 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[].
//
//  Return Type: TPM_RC
//        TPM_RC_AUTH_FAIL          authorization fails and increments DA failure
//                                  count
//        TPM_RC_BAD_AUTH           authorization 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 authValue with trailing zeros removed
    EntityGetAuthValue(associatedHandle, &authValue);

    // Success if the values are identical.
    if(MemoryEqual2B(&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.
/*(See part 1 specification -- this tag keeps this comment from showing up in
// merged document which is probably good because this comment doesn't look right.
//      The sessionAuth value
//      authHMAC := HMACsHash((sessionKey | authValue),
//                  (pHash | nonceNewer | nonceOlder  | nonceTPMencrypt-only
//                   | nonceTPMaudit   | sessionAttributes))
// Where:
//      HMACsHash()     The HMAC algorithm using the hash algorithm specified
//                      when the session was started.
//
//      sessionKey      A value that is computed in a protocol-dependent way,
//                      using KDFa. When used in an HMAC or KDF, the size field
//                      for this value is not included.
//
//      authValue       A value that is found in the sensitive area of an entity.
//                      When used in an HMAC or KDF, the size field for this
//                      value is not included.
//
//      pHash           Hash of the command (cpHash) using the session hash.
//                      When using a pHash in an HMAC computation, only the
//                      digest is used.
//
//      nonceNewer      A value that is generated by the entity using the
//                      session. A new nonce is generated on each use of the
//                      session. For a command, this will be nonceCaller.
//                      When used in an HMAC or KDF, the size field is not used.
//
//      nonceOlder      A TPM2B_NONCE that was received the previous time the
//                      session was used. For a command, this is nonceTPM.
//                      When used in an HMAC or KDF, the size field is not used.
//
//      nonceTPMdecrypt     The nonceTPM of the decrypt session is included in
//                          the HMAC, but only in the command.
//
//      nonceTPMencrypt     The nonceTPM of the encrypt session is included in
//                          the HMAC but only in the command.
//
//      sessionAttributes   A byte indicating the attributes associated with the
//                          particular use of the session.
*/
static TPM2B_DIGEST *
ComputeCommandHMAC(
    COMMAND         *command,       // IN: primary control structure
    UINT32           sessionIndex,  // IN: index of session to be processed
    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;
//
    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.
    //
    // Include the entity authValue if it is needed
    if(session->attributes.includeAuth == SET)
    {
        TPM2B_AUTH          authValue;
        // Get the entity authValue with trailing zeros removed
        EntityGetAuthValue(s_associatedHandles[sessionIndex], &authValue);
        // add the authValue to the HMAC key
        MemoryConcat2B(&key.b, &authValue.b, sizeof(key.t.buffer));
    }
     // 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 hmac;
    }
    // Start HMAC
    hmac->t.size = CryptHmacStart2B(&hmacState, session->authHashAlg, &key.b);

        //  Add cpHash
    CryptDigestUpdate2B(&hmacState.hashState,
                        &ComputeCpHash(command, session->authHashAlg)->b);
        //  Add nonces as required
    CryptDigestUpdate2B(&hmacState.hashState, &s_nonceCaller[sessionIndex].b);
    CryptDigestUpdate2B(&hmacState.hashState, &session->nonceTPM.b);
    if(nonceDecrypt != NULL)
        CryptDigestUpdate2B(&hmacState.hashState, &nonceDecrypt->b);
    if(nonceEncrypt != NULL)
        CryptDigestUpdate2B(&hmacState.hashState, &nonceEncrypt->b);
        //  Add sessionAttributes
    buffer = marshalBuffer;
    marshalSize = TPMA_SESSION_Marshal(&(s_attributes[sessionIndex]),
                                       &buffer, NULL);
    CryptDigestUpdate(&hmacState.hashState, marshalSize, marshalBuffer);
        // Complete the HMAC computation
    CryptHmacEnd2B(&hmacState, &hmac->b);

    return hmac;
}

//*** 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.
//
//  Return Type: TPM_RC
//      TPM_RC_AUTH_FAIL        authorization failure caused failureCount increment
//      TPM_RC_BAD_AUTH         authorization failure did not cause failureCount
//                              increment
//
static TPM_RC
CheckSessionHMAC(
    COMMAND         *command,       // IN: primary control structure
    UINT32           sessionIndex   // IN: index of session to be processed
    )
{
    TPM2B_DIGEST        hmac;           // authHMAC for comparing
//
    // Compute authHMAC
    ComputeCommandHMAC(command, sessionIndex, &hmac);

    // Compare the input HMAC with the authHMAC computed above.
    if(!MemoryEqual2B(&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.
//
//  Return Type: TPM_RC
//      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(
    COMMAND         *command,       // IN: primary parsing structure
    UINT32           sessionIndex   // IN: index of session to be processed
    )
{
    SESSION             *session;
    TPM2B_DIGEST         authPolicy;
    TPMI_ALG_HASH        policyAlg;
    UINT8                locality;
//
    // Initialize pointer to the authorization session.
    session = SessionGet(s_sessionHandles[sessionIndex]);

    // If the command is TPM2_PolicySecret(), make sure that
    // either password or authValue is required
    if(command->code == 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(session))
        return TPM_RC_PCR_CHANGED;
    // Get authPolicy.
    policyAlg = EntityGetAuthPolicy(s_associatedHandles[sessionIndex],
                                    &authPolicy);
    // Compare authPolicy.
    if(!MemoryEqual2B(&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. This doesn't mean that
        // a new nonce will be created just that, because TPM time can't advance
        // we can't do time-based operations.
        RETURN_IF_NV_IS_NOT_AVAILABLE;

        if((session->timeout < g_time)
           || (session->epoch != g_timeEpoch))
            return TPM_RC_EXPIRED;
    }
    // If command code is provided it must match
    if(session->commandCode != 0)
    {
        if(session->commandCode != command->code)
            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(command->index, 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
        sessionLocality[0] = 0;
        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)
    {
        BOOL        OK;
        if(session->attributes.isCpHashDefined)
            // Compare cpHash.
            OK = MemoryEqual2B(&session->u1.cpHash.b,
                               &ComputeCpHash(command, session->authHashAlg)->b);
        else if(session->attributes.isTemplateSet)
            OK = CompareTemplateHash(command, session);
        else
            OK = CompareNameHash(command, session);
        if(!OK)
            return TPM_RCS_POLICY_FAIL;
    }
    if(session->attributes.checkNvWritten)
    {
        NV_REF           locator;
        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
        nvIndex = NvGetIndexInfo(s_associatedHandles[sessionIndex], &locator);

        // Make sure that the TPMA_WRITTEN_ATTRIBUTE has the desired state
        if((IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, WRITTEN))
           != (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.
//
//  Return Type: TPM_RC
//      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(
    COMMAND         *command        // IN: main parsing structure for command
    )
{
    int              i;
    TPM_RC           result;
    SESSION         *session;
    TPMA_SESSION     sessionAttributes;
    TPM_HT           sessionType;
    INT32            sessionIndex;
    TPM_RC           errorIndex;
//
    s_decryptSessionIndex = UNDEFINED_INDEX;
    s_encryptSessionIndex = UNDEFINED_INDEX;
    s_auditSessionIndex = UNDEFINED_INDEX;

    for(sessionIndex = 0; command->authSize > 0; sessionIndex++)
    {
        errorIndex = TPM_RC_S + g_rcIndex[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_RCS_SIZE + errorIndex;
        // 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],
            &command->parameterBuffer,
            &command->authSize, TRUE);
        if(result != TPM_RC_SUCCESS)
            return result + TPM_RC_S + g_rcIndex[sessionIndex];
        // Second parameter: Nonce.
        result = TPM2B_NONCE_Unmarshal(&s_nonceCaller[sessionIndex],
                                       &command->parameterBuffer,
                                       &command->authSize);
        if(result != TPM_RC_SUCCESS)
            return result + TPM_RC_S + g_rcIndex[sessionIndex];
        // Third parameter: sessionAttributes.
        result = TPMA_SESSION_Unmarshal(&s_attributes[sessionIndex],
                                        &command->parameterBuffer,
                                        &command->authSize);
        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],
                                      &command->parameterBuffer,
                                      &command->authSize);
        if(result != TPM_RC_SUCCESS)
            return result + errorIndex;

        sessionAttributes = s_attributes[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(IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, encrypt)
               || IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, decrypt)
               || IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, audit)
               || IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, auditExclusive)
               || IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, auditReset))
                return TPM_RCS_ATTRIBUTES + errorIndex;
            //     The nonce size must be zero.
            if(s_nonceCaller[sessionIndex].t.size != 0)
                return TPM_RCS_NONCE + errorIndex;
            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_RCS_HANDLE + errorIndex;
        // Check that this handle has not previously been used.
        for(i = 0; i < sessionIndex; i++)
        {
            if(s_sessionHandles[i] == s_sessionHandles[sessionIndex])
                return TPM_RCS_HANDLE + errorIndex;
        }
        // If the session is used for parameter encryption or audit as well, set
        // the corresponding Indexes.

        // First process decrypt.
        if(IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, decrypt))
        {
            // Check if the commandCode allows command parameter encryption.
            if(DecryptSize(command->index) == 0)
                return TPM_RCS_ATTRIBUTES + errorIndex;
            // Encrypt attribute can only appear in one session
            if(s_decryptSessionIndex != UNDEFINED_INDEX)
                return TPM_RCS_ATTRIBUTES + errorIndex;
            // Can't decrypt if the session's symmetric algorithm is TPM_ALG_NULL
            if(session->symmetric.algorithm == TPM_ALG_NULL)
                return TPM_RCS_SYMMETRIC + errorIndex;
            // All checks passed, so set the index for the session used to decrypt
            // a command parameter.
            s_decryptSessionIndex = sessionIndex;
        }
        // Now process encrypt.
        if(IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, encrypt))
        {
            // Check if the commandCode allows response parameter encryption.
            if(EncryptSize(command->index) == 0)
                return TPM_RCS_ATTRIBUTES + errorIndex;
            // Encrypt attribute can only appear in one session.
            if(s_encryptSessionIndex != UNDEFINED_INDEX)
                return TPM_RCS_ATTRIBUTES + errorIndex;
            // Can't encrypt if the session's symmetric algorithm is TPM_ALG_NULL
            if(session->symmetric.algorithm == TPM_ALG_NULL)
                return TPM_RCS_SYMMETRIC + errorIndex;
            // All checks passed, so set the index for the session used to encrypt
            // a response parameter.
            s_encryptSessionIndex = sessionIndex;
        }
        // At last process audit.
        if(IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, audit))
        {
            // Audit attribute can only appear in one session.
            if(s_auditSessionIndex != UNDEFINED_INDEX)
                return TPM_RCS_ATTRIBUTES + errorIndex;
            // An audit session can not be policy session.
            if(HandleGetType(s_sessionHandles[sessionIndex])
               == TPM_HT_POLICY_SESSION)
                return TPM_RCS_ATTRIBUTES + errorIndex;
            // 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(!IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, auditReset)
               && session->attributes.isAudit == SET)
            {
                // Not first use or reset. If auditExlusive is SET, then this
                // session must be the current exclusive session.
                if(IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, auditExclusive)
                   && 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;
    }
    command->sessionNum = 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'
//  Return Type: TPM_RC
//      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
    )
{
    // If NV is unavailable, and current cycle state recorded in NV is not
    // SU_NONE_VALUE, refuse to check any authorization because we would
    // not be able to handle a DA failure.
    if(!NV_IS_AVAILABLE && NV_IS_ORDERLY)
        return g_NvStatus;
    // Check if DA info needs to be updated in NV.
    if(s_DAPendingOnNV)
    {
        // If NV is accessible,
        RETURN_IF_NV_IS_NOT_AVAILABLE;

        // ... write the pending DA data and proceed.
        NV_SYNC_PERSISTENT(lockOutAuthEnabled);
        NV_SYNC_PERSISTENT(failedTries);
        s_DAPendingOnNV = FALSE;
    }
    // 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;
#if USE_DA_USED
        // If the daUsed flag is not SET, then no DA validation until the
        // daUsed state is written to NV
        if(!g_daUsed)
        {
            RETURN_IF_NV_IS_NOT_AVAILABLE;
            g_daUsed = TRUE;
            gp.orderlyState = SU_DA_USED_VALUE;
            NV_SYNC_PERSISTENT(orderlyState);
            return TPM_RC_RETRY;
        }
#endif
    }
    return TPM_RC_SUCCESS;
}

//*** CheckAuthSession()
// This function checks that the authorization session properly authorizes the
// use of the associated handle.
//
//  Return Type: TPM_RC
//      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(
    COMMAND         *command,       // IN: primary parsing structure
    UINT32           sessionIndex   // IN: index of session to be processed
    )
{
    TPM_RC           result = TPM_RC_SUCCESS;
    SESSION         *session = NULL;
    TPM_HANDLE       sessionHandle = s_sessionHandles[sessionIndex];
    TPM_HANDLE       associatedHandle = s_associatedHandles[sessionIndex];
    TPM_HT           sessionHandleType = HandleGetType(sessionHandle);
    BOOL             authUsed;
//
    pAssert(sessionHandle != TPM_RH_UNASSIGNED);

    // Take care of physical presence
    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(command->index)
           && !_plat__PhysicalPresenceAsserted())
            return TPM_RC_PP;
    }
    if(sessionHandle != TPM_RS_PW)
    {
        session = SessionGet(sessionHandle);

        // Set includeAuth to indicate if DA checking will be required and if the
        // authValue will be included in any HMAC.
        if(sessionHandleType == TPM_HT_POLICY_SESSION)
        {
            // For a policy session, will check the DA status of the entity if either
            // isAuthValueNeeded or isPasswordNeeded is SET.
            session->attributes.includeAuth =
                session->attributes.isAuthValueNeeded
                || session->attributes.isPasswordNeeded;
        }
        else
        {
            // For an HMAC session, need to check unless the session
            // is bound.
            session->attributes.includeAuth =
                !IsSessionBindEntity(s_associatedHandles[sessionIndex], session);
        }
        authUsed = session->attributes.includeAuth;
    }
    else
        // Password session
        authUsed = TRUE;
    // If the authorization session is going to use an authValue, then make sure
    // that access to that authValue isn't locked out.
    if(authUsed)
    {
        // See if entity is subject to lockout.
        if(!IsDAExempted(associatedHandle))
        {
            // See if in lockout 
            result = CheckLockedOut(associatedHandle == TPM_RH_LOCKOUT);
            if(result != TPM_RC_SUCCESS)
                return result;
        }
    }
    // Policy or HMAC+PW?
    if(sessionHandleType != TPM_HT_POLICY_SESSION)
    {
        // for non-policy session make sure that a policy session is not required
        if(IsPolicySessionRequired(command->index, sessionIndex))
            return TPM_RC_AUTH_TYPE;
        // The authValue must be available.
        // Note: The authValue is going to be "used" even if it is an EmptyAuth.
        // and the session is bound.
        if(!IsAuthValueAvailable(associatedHandle, command->index, sessionIndex))
            return TPM_RC_AUTH_UNAVAILABLE;
    }
    else
    {
        // ... see if the entity has a policy, ...
        // Note: IsAuthPolicyAvalable will return FALSE if the sensitive area of the
        // object is not loaded
        if(!IsAuthPolicyAvailable(associatedHandle, command->index, sessionIndex))
            return TPM_RC_AUTH_UNAVAILABLE;
        // ... and check the policy session.
        result = CheckPolicyAuthSession(command, sessionIndex);
        if(result != TPM_RC_SUCCESS)
            return result;
    }
    // Check authorization according to the type
    if((TPM_RS_PW == sessionHandle) || (session->attributes.isPasswordNeeded == SET))
        result = CheckPWAuthSession(sessionIndex);
    else
        result = CheckSessionHMAC(command, sessionIndex);
    // Do processing for PIN Indexes are only three possibilities for 'result' at
    // this point: TPM_RC_SUCCESS, TPM_RC_AUTH_FAIL, and TPM_RC_BAD_AUTH.
    // For all these cases, we would have to process a PIN index if the
    // authValue of the index was used for authorization.
    if((TPM_HT_NV_INDEX == HandleGetType(associatedHandle)) && authUsed)
    {
        NV_REF           locator;
        NV_INDEX        *nvIndex = NvGetIndexInfo(associatedHandle, &locator);
        NV_PIN           pinData;
        TPMA_NV          nvAttributes;
//
        pAssert(nvIndex != NULL);
        nvAttributes = nvIndex->publicArea.attributes;
        // If this is a PIN FAIL index and the value has been written
        // then we can update the counter (increment or clear)
        if(IsNvPinFailIndex(nvAttributes)
           && IS_ATTRIBUTE(nvAttributes, TPMA_NV, WRITTEN))
        {
            pinData.intVal = NvGetUINT64Data(nvIndex, locator);
            if(result != TPM_RC_SUCCESS)
                pinData.pin.pinCount++;
            else
                pinData.pin.pinCount = 0;
            NvWriteUINT64Data(nvIndex, pinData.intVal);
        }
        // If this is a PIN PASS Index, increment if we have used the
        // authorization value.
        // NOTE: If the counter has already hit the limit, then we
        // would not get here because the authorization value would not
        // be available and the TPM would have returned before it gets here
        else if(IsNvPinPassIndex(nvAttributes)
                && IS_ATTRIBUTE(nvAttributes, TPMA_NV, WRITTEN)
                && result == TPM_RC_SUCCESS)
        {
            // If the access is valid, then increment the use counter
            pinData.intVal = NvGetUINT64Data(nvIndex, locator);
            pinData.pin.pinCount++;
            NvWriteUINT64Data(nvIndex, pinData.intVal);
        }
    }
    return result;
}

#ifdef  TPM_CC_GetCommandAuditDigest
//*** CheckCommandAudit()
// This function is called before the command is processed if audit is enabled
// for the command. It will check to see if the audit can be performed and
// will ensure that the cpHash is available for the audit.
//  Return Type: TPM_RC
//      TPM_RC_NV_UNAVAILABLE       NV is not available for write
//      TPM_RC_NV_RATE              NV is rate limiting
static TPM_RC
CheckCommandAudit(
    COMMAND         *command
    )
{
    // 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
       || GetCommandCode(command->index) == TPM_CC_GetCommandAuditDigest)
    {
        RETURN_IF_NV_IS_NOT_AVAILABLE;
    }
    // Make sure that the cpHash is computed for the algorithm
    ComputeCpHash(command, gp.auditHashAlg);
    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.
//
//  Return Type: TPM_RC
//        various           parsing failure or authorization failure
//
TPM_RC
ParseSessionBuffer(
    COMMAND         *command        // IN: the structure that contains
    )
{
    TPM_RC               result;
    UINT32               i;
    INT32                size = 0;
    TPM2B_AUTH           extraKey;
    UINT32               sessionIndex;
    TPM_RC               errorIndex;
    SESSION             *session = NULL;
//
    // Check if a command allows any session in its session area.
    if(!IsSessionAllowed(command->index))
        return TPM_RC_AUTH_CONTEXT;
    // Default-initialization.
    command->sessionNum = 0;

    result = RetrieveSessionData(command);
    if(result != TPM_RC_SUCCESS)
        return result;
    // There is no command in the TPM spec that has more handles than
    // MAX_SESSION_NUM.
    pAssert(command->handleNum <= MAX_SESSION_NUM);

    // Associate the session with an authorization handle.
    for(i = 0; i < command->handleNum; i++)
    {
        if(CommandAuthRole(command->index, i) != AUTH_NONE)
        {
            // If the received session number is less than the number of handles
            // 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 and there are only ever
            // two values requiring authorization
            if(i > (command->sessionNum - 1))
                return TPM_RC_AUTH_MISSING;
            // Record the handle associated with the authorization session
            s_associatedHandles[i] = command->handles[i];
        }
    }
    // Consistency checks are done first to avoid authorization failure when the
    // command will not be executed anyway.
    for(sessionIndex = 0; sessionIndex < command->sessionNum; sessionIndex++)
    {
        errorIndex = TPM_RC_S + g_rcIndex[sessionIndex];
        // PW session must be an authorization session
        if(s_sessionHandles[sessionIndex] == TPM_RS_PW)
        {
            if(s_associatedHandles[sessionIndex] == TPM_RH_UNASSIGNED)
                return TPM_RCS_HANDLE + errorIndex;
            // a password session can't be audit, encrypt or decrypt
            if(IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, audit)
               || IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, encrypt)
               || IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, decrypt))
                return TPM_RCS_ATTRIBUTES + errorIndex;
            session = NULL;
        }
        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_RCS_ATTRIBUTES + errorIndex;

            // 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 this session is for auditing, make sure the cpHash is computed.
            if(IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, audit))
                ComputeCpHash(command, session->authHashAlg);
        }

        // if the session has an associated handle, check the authorization
        if(s_associatedHandles[sessionIndex] != TPM_RH_UNASSIGNED)
        {
            result = CheckAuthSession(command, sessionIndex);
            if(result != TPM_RC_SUCCESS)
                return RcSafeAddToResult(result, errorIndex);
        }
        else
        {
            // a session that is not for authorization must either be encrypt,
            // decrypt, or audit
            if(!IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, audit)
               &&  !IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, encrypt)
               &&  !IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, decrypt))
                return TPM_RCS_ATTRIBUTES + errorIndex;

            // no authValue included in any of the HMAC computations
            pAssert(session != NULL);
            session->attributes.includeAuth = CLEAR;

            // check HMAC for encrypt/decrypt/audit only sessions
            result = CheckSessionHMAC(command, sessionIndex);
            if(result != TPM_RC_SUCCESS)
                return RcSafeAddToResult(result, errorIndex);
        }
    }
#ifdef  TPM_CC_GetCommandAuditDigest
    // Check if the command should be audited. Need to do this before any parameter
    // encryption so that the cpHash for the audit is correct
    if(CommandAuditIsRequired(command->index))
    {
        result = CheckCommandAudit(command);
        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 sessionKey to
    // generate encryption key, no matter if the handle is the session bound entity
    // or not.
    if(s_decryptSessionIndex != UNDEFINED_INDEX)
    {
        // If this is an authorization session, include the authValue in the
        // generation of the decryption key
        if(s_associatedHandles[s_decryptSessionIndex] != TPM_RH_UNASSIGNED)
        {
            EntityGetAuthValue(s_associatedHandles[s_decryptSessionIndex], 
                               &extraKey);
        }
        else
        {
            extraKey.b.size = 0;
        }
        size = DecryptSize(command->index);
        result = CryptParameterDecryption(s_sessionHandles[s_decryptSessionIndex],
                                          &s_nonceCaller[s_decryptSessionIndex].b,
                                          command->parameterSize, (UINT16)size,
                                          &extraKey,
                                          command->parameterBuffer);
        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.
//
//  Return Type: TPM_RC
//      TPM_RC_AUTH_MISSING         failure - one or more handles require
//                                  authorization
TPM_RC
CheckAuthNoSession(
    COMMAND         *command        // IN: command parsing structure
    )
{
    UINT32 i;
    TPM_RC           result = TPM_RC_SUCCESS;
//
    // Check if the command requires authorization
    for(i = 0; i < command->handleNum; i++)
    {
        if(CommandAuthRole(command->index, i) != AUTH_NONE)
            return TPM_RC_AUTH_MISSING;
    }
#ifdef  TPM_CC_GetCommandAuditDigest
    // Check if the command should be audited.
    if(CommandAuditIsRequired(command->index))
    {
        result = CheckCommandAudit(command);
        if(result != TPM_RC_SUCCESS)
            return result;
    }
#endif
    // Initialize number of sessions to be 0
    command->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 TPM2B_DIGEST *
ComputeRpHash(
    COMMAND         *command,       // IN: command structure
    TPM_ALG_ID       hashAlg        // IN: hash algorithm to compute rpHash
    )
{
    TPM2B_DIGEST    *rpHash = GetRpHashPointer(command, hashAlg);
    HASH_STATE       hashState;
//
    if(rpHash->t.size == 0)
    {
    //   rpHash := hash(responseCode || commandCode || parameters)

    // Initiate hash creation.
        rpHash->t.size = CryptHashStart(&hashState, hashAlg);

        // Add hash constituents.
        CryptDigestUpdateInt(&hashState, sizeof(TPM_RC), TPM_RC_SUCCESS);
        CryptDigestUpdateInt(&hashState, sizeof(TPM_CC), command->code);
        CryptDigestUpdate(&hashState, command->parameterSize, 
                          command->parameterBuffer);
        // Complete hash computation.
        CryptHashEnd2B(&hashState, &rpHash->b);
    }
    return rpHash;
}

//*** 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 = CryptHashGetDigestSize(session->authHashAlg);

    // Set the original digest value to be 0.
    MemorySet(&session->u2.auditDigest.t.buffer,
              0,
              session->u2.auditDigest.t.size);
    return;
}

//*** UpdateAuditDigest
// Function to update an audit digest
static void
UpdateAuditDigest(
    COMMAND         *command,
    TPMI_ALG_HASH    hashAlg,
    TPM2B_DIGEST    *digest
    )
{
    HASH_STATE       hashState;
    TPM2B_DIGEST    *cpHash = GetCpHash(command, hashAlg);
    TPM2B_DIGEST    *rpHash = ComputeRpHash(command, hashAlg);
//
    pAssert(cpHash != NULL);

    // digestNew :=  hash (digestOld || cpHash || rpHash)
        // Start hash computation.
    digest->t.size = CryptHashStart(&hashState, hashAlg);
        // Add old digest.
    CryptDigestUpdate2B(&hashState, &digest->b);
        // Add cpHash 
    CryptDigestUpdate2B(&hashState, &cpHash->b);
        // Add rpHash
    CryptDigestUpdate2B(&hashState, &rpHash->b);
        // Finalize the hash.
    CryptHashEnd2B(&hashState, &digest->b);
}


//*** Audit()
//This function updates the audit digest in an audit session.
static void
Audit(
    COMMAND         *command,       // IN: primary control structure
    SESSION         *auditSession   // IN: loaded audit session
    )
{
    UpdateAuditDigest(command, auditSession->authHashAlg,
                      &auditSession->u2.auditDigest);
    return;
}

#ifdef  TPM_CC_GetCommandAuditDigest
//*** CommandAudit()
// This function updates the command audit digest.
static void
CommandAudit(
    COMMAND         *command        // IN:
    )
{
    // 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 = CryptHashGetDigestSize(gp.auditHashAlg);
        MemorySet(gr.commandAuditDigest.t.buffer,
                  0,
                  gr.commandAuditDigest.t.size);

        // Bump the counter and save its value to NV.
        gp.auditCounter++;
        NV_SYNC_PERSISTENT(auditCounter);
    }
    UpdateAuditDigest(command, gp.auditHashAlg, &gr.commandAuditDigest);
    return;
}
#endif

//*** UpdateAuditSessionStatus()
// This function updates the internal audit related states of a session. It will:
//  a) initialize the session as audit session and set it to be exclusive if this
//     is the first time it is used for audit or audit reset was requested;
//  b) report exclusive audit session;
//  c) extend audit log; and
//  d) clear exclusive audit session if no audit session found in the command.
static void
UpdateAuditSessionStatus(
    COMMAND         *command        // IN: primary control structure
    )
{
    UINT32           i;
    TPM_HANDLE       auditSession = TPM_RH_UNASSIGNED;
//
    // Iterate through sessions
    for(i = 0; i < command->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(IS_ATTRIBUTE(s_attributes[i], TPMA_SESSION, audit))
        {
            // 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
               || IS_ATTRIBUTE(s_attributes[i], TPMA_SESSION, auditReset))
            {
                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)
            {
                SET_ATTRIBUTE(s_attributes[i], TPMA_SESSION, auditExclusive);
            }
            else
            {
                CLEAR_ATTRIBUTE(s_attributes[i], TPMA_SESSION, auditExclusive);
            }
            // Extend audit log.
            Audit(command, session);
        }
    }
    // 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(command->index))
    {
        g_exclusiveAuditSession = TPM_RH_UNASSIGNED;
    }
    return;
}

//*** ComputeResponseHMAC()
// Function to compute HMAC for authorization session in a response.
/*(See part 1 specification)
// Function: Compute HMAC for response sessions
//      The sessionAuth value
//          authHMAC := HMACsHASH((sessionAuth | authValue),
//                    (pHash | nonceTPM | nonceCaller | sessionAttributes))
//  Where:
//      HMACsHASH()     The HMAC algorithm using the hash algorithm specified when
//                      the session was started.
//
//      sessionAuth     A TPMB_MEDIUM computed in a protocol-dependent way, using
//                      KDFa. In an HMAC or KDF, only sessionAuth.buffer is used.
//
//      authValue       A TPM2B_AUTH that is found in the sensitive area of an
//                      object. In an HMAC or KDF, only authValue.buffer is used
//                      and all trailing zeros are removed.
//
//      pHash           Response parameters (rpHash) using the session hash. When
//                      using a pHash in an HMAC computation, both the algorithm ID
//                      and the digest are included.
//
//      nonceTPM        A TPM2B_NONCE that is generated by the entity using the
//                      session. In an HMAC or KDF, only nonceTPM.buffer is used.
//
//      nonceCaller     a TPM2B_NONCE that was received the previous time the
//                      session was used. In an HMAC or KDF, only
//                      nonceCaller.buffer is used.
//
//      sessionAttributes   A TPMA_SESSION that indicates the attributes associated
//                          with a particular use of the session.
*/
static void
ComputeResponseHMAC(
    COMMAND         *command,       // IN: command structure
    UINT32           sessionIndex,  // IN: session index to be processed
    SESSION         *session,       // IN: loaded session
    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    *rpHash = ComputeRpHash(command, session->authHashAlg);
//
    // Generate HMAC key
    MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer));

    // Add the object authValue if required
    if(session->attributes.includeAuth == SET)
    {
        // Note: includeAuth may be SET for a policy that is used in
        // UndefineSpaceSpecial(). At this point, the Index has been deleted
        // so the includeAuth will have no meaning. However, the
        // s_associatedHandles[] value for the session is now set to TPM_RH_NULL so
        // this will return the authValue associated with TPM_RH_NULL and that is
        // and empty buffer.
        TPM2B_AUTH          authValue;
//
        // Get the authValue with trailing zeros removed
        EntityGetAuthValue(s_associatedHandles[sessionIndex], &authValue);

        // Add it to the key
        MemoryConcat2B(&key.b, &authValue.b, sizeof(key.t.buffer));
    }

    // if the HMAC key size is 0, the response HMAC is computed according to the
    // input HMAC
    if(key.t.size == 0
       && s_inputAuthValues[sessionIndex].t.size == 0)
    {
        hmac->t.size = 0;
        return;
    }
    // Start HMAC computation.
    hmac->t.size = CryptHmacStart2B(&hmacState, session->authHashAlg, &key.b);

    // Add hash components.
    CryptDigestUpdate2B(&hmacState.hashState, &rpHash->b);
    CryptDigestUpdate2B(&hmacState.hashState, &session->nonceTPM.b);
    CryptDigestUpdate2B(&hmacState.hashState, &s_nonceCaller[sessionIndex].b);

    // Add session attributes.
    buffer = marshalBuffer;
    marshalSize = TPMA_SESSION_Marshal(&s_attributes[sessionIndex], &buffer, NULL);
    CryptDigestUpdate(&hmacState.hashState, marshalSize, marshalBuffer);

    // Finalize HMAC.
    CryptHmacEnd2B(&hmacState, &hmac->b);

    return;
}

//*** UpdateInternalSession()
// This function updates internal sessions by:
// a) restarting session time; and
// b) clearing a policy session since nonce is rolling.
static void
UpdateInternalSession(
    SESSION         *session,       // IN: the session structure
    UINT32           i              // IN: session number
    )
{
    // 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
       && IS_ATTRIBUTE(s_attributes[i], TPMA_SESSION, continueSession))
    {
        // When the nonce rolls it starts a new timing interval for the
        // policy session.
        SessionResetPolicyData(session);
        SessionSetStartTime(session);
    }
    return;
}

//*** BuildSingleResponseAuth()
//   Function to compute response HMAC value for a policy or HMAC session.
static TPM2B_NONCE *
BuildSingleResponseAuth(
    COMMAND         *command,       // IN: command structure
    UINT32           sessionIndex,  // IN: session index to be processed
    TPM2B_AUTH      *auth           // OUT: authHMAC
    )
{
    // Fill in policy/HMAC based session response.
    SESSION     *session = SessionGet(s_sessionHandles[sessionIndex]);
//
    // If the session is a policy session with isPasswordNeeded SET, the
    // authorization 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(command, sessionIndex, session, auth);

    UpdateInternalSession(session, sessionIndex);
    return &session->nonceTPM;
}

//*** UpdateAllNonceTPM()
// Updates TPM nonce for all sessions in command.
static void
UpdateAllNonceTPM(
    COMMAND         *command        // IN: controlling structure
    )
{
    UINT32      i;
    SESSION     *session;
//
    for(i = 0; i < command->sessionNum; i++)
    {
        // If not a PW session, compute the new nonceTPM.
        if(s_sessionHandles[i] != TPM_RS_PW)
        {
            session = SessionGet(s_sessionHandles[i]);
            // Update nonceTPM in both internal session and response.
            CryptRandomGenerate(session->nonceTPM.t.size,
                                session->nonceTPM.t.buffer);
        }
    }
    return;
}



//*** BuildResponseSession()
// Function to build Session buffer in a response. The authorization data is added
// to the end of command->responseBuffer. The size of the authorization area is
// accumulated in command->authSize.
// When this is called, command->responseBuffer is pointing at the next location
// in the response buffer to be filled. This is where the authorization sessions 
// will go, if any. command->parameterSize is the number of bytes that have been
// marshaled as parameters in the output buffer.
void
BuildResponseSession(
    COMMAND         *command        // IN: structure that has relevant command
                                    //     information
    )
{
    pAssert(command->authSize == 0);

    // Reset the parameter buffer to point to the start of the parameters so that
    // there is a starting point for any rpHash that might be generated and so there
    // is a place where parameter encryption would start
    command->parameterBuffer = command->responseBuffer - command->parameterSize;

    // Session nonces should be updated before parameter encryption
    if(command->tag == TPM_ST_SESSIONS)
    {
        UpdateAllNonceTPM(command);

        // 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 sessionKey to generate
        // encryption key, no matter if the handle is the session bound entity
        // or not. The authValue is added to sessionKey only when the authValue
        // is available.
        if(s_encryptSessionIndex != UNDEFINED_INDEX)
        {
            UINT32          size;
            TPM2B_AUTH      extraKey;
//
            extraKey.b.size = 0;
            // If this is an authorization session, include the authValue in the
            // generation of the encryption key
            if(s_associatedHandles[s_encryptSessionIndex] != TPM_RH_UNASSIGNED)
            {
                EntityGetAuthValue(s_associatedHandles[s_encryptSessionIndex], 
                                   &extraKey);
            }
            size = EncryptSize(command->index);
            CryptParameterEncryption(s_sessionHandles[s_encryptSessionIndex],
                                     &s_nonceCaller[s_encryptSessionIndex].b,
                                     (UINT16)size,
                                     &extraKey,
                                     command->parameterBuffer);
        }
    }
    // Audit sessions should be processed regardless of the tag because
    // a command with no session may cause a change of the exclusivity state.
    UpdateAuditSessionStatus(command);
#if CC_GetCommandAuditDigest
    // Command Audit
    if(CommandAuditIsRequired(command->index))
        CommandAudit(command);
#endif
    // Process command with sessions.
    if(command->tag == TPM_ST_SESSIONS)
    {
        UINT32           i;
//
        pAssert(command->sessionNum > 0);

        // Iterate over each session in the command session area, and create
        // corresponding sessions for response.
        for(i = 0; i < command->sessionNum; i++)
        {
            TPM2B_NONCE     *nonceTPM;
            TPM2B_DIGEST     responseAuth;
            // 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_sessionHandles[i] == TPM_RS_PW)
            {
                SET_ATTRIBUTE(s_attributes[i], TPMA_SESSION, continueSession);
                responseAuth.t.size = 0;
                nonceTPM = (TPM2B_NONCE *)&responseAuth;                
            }
            else
            {
                // Compute the response HMAC and get a pointer to the nonce used.
                // This function will also update the values if needed. Note, the
                nonceTPM = BuildSingleResponseAuth(command, i, &responseAuth);
            }
            command->authSize += TPM2B_NONCE_Marshal(nonceTPM,
                                                     &command->responseBuffer,
                                                     NULL);
            command->authSize += TPMA_SESSION_Marshal(&s_attributes[i],
                                                      &command->responseBuffer,
                                                      NULL);
            command->authSize += TPM2B_DIGEST_Marshal(&responseAuth,
                                                      &command->responseBuffer,
                                                      NULL);
            if(!IS_ATTRIBUTE(s_attributes[i], TPMA_SESSION, continueSession))
                SessionFlush(s_sessionHandles[i]);
        }
    }
    return;
}

//*** SessionRemoveAssociationToHandle()
// This function deals with the case where an entity associated with an authorization
// is deleted during command processing. The primary use of this is to support
// UndefineSpaceSpecial().
void
SessionRemoveAssociationToHandle(
    TPM_HANDLE       handle
    )
{
    UINT32               i;
//
    for(i = 0; i < MAX_SESSION_NUM; i++)
    {
        if(s_associatedHandles[i] == handle)
        {
            s_associatedHandles[i] = TPM_RH_NULL;
        }
    }
}