// This file was extracted from the TCG Published
// Trusted Platform Module Library
// Part 4: Supporting Routines
// Family "2.0"
// Level 00 Revision 01.16
// October 30, 2014

#include     "InternalRoutines.h"
#include     "HandleProcess_fp.h"
#include     "SessionProcess_fp.h"
#include     "CommandDispatcher_fp.h"
//
//     Uncomment this next #include if doing static command/response buffer sizing
//
// #include "CommandResponseSizes_fp.h"
//
//
//           ExecuteCommand()
//
//     The function performs the following steps.
//     a) Parses the command header from input buffer.
//     b) Calls ParseHandleBuffer() to parse the handle area of the command.
//     c) Validates that each of the handles references a loaded entity.
//
//     d) Calls ParseSessionBuffer() () to:
//          1) unmarshal and parse the session area;
//          2) check the authorizations; and
//          3) when necessary, decrypt a parameter.
//     e) Calls CommandDispatcher() to:
//          1) unmarshal the command parameters from the command buffer;
//          2) call the routine that performs the command actions; and
//          3) marshal the responses into the response buffer.
//     f)   If any error occurs in any of the steps above create the error response and return.
//     g) Calls BuildResponseSession() to:
//          1) when necessary, encrypt a parameter
//          2) build the response authorization sessions
//          3) update the audit sessions and nonces
//     h) Assembles handle, parameter and session buffers for response and return.
//
LIB_EXPORT void
ExecuteCommand(
    unsigned    int      requestSize,       //   IN: command buffer size
    unsigned    char    *request,           //   IN: command buffer
    unsigned    int     *responseSize,      //   OUT: response buffer size
    unsigned    char    **response          //   OUT: response buffer
    )
{
    // Command local variables
    TPM_ST               tag;                         // these first three variables are the
    UINT32               commandSize;
    TPM_CC               commandCode = 0;
    BYTE                     *parmBufferStart;        // pointer to the first byte of an
                                                      // optional parameter buffer
    UINT32                    parmBufferSize = 0;// number of bytes in parameter area
    UINT32                    handleNum = 0;          // number of handles unmarshaled into
                                                      // the handles array
    TPM_HANDLE                handles[MAX_HANDLE_NUM];// array to hold handles in the
                                                 // command. Only handles in the handle
                                                 // area are stored here, not handles
                                                 // passed as parameters.
    // Response local variables
    TPM_RC               result;                      // return code for the command
    TPM_ST                    resTag;                 // tag for the response
    UINT32                    resHandleSize = 0; //       size of the handle area in the
                                                 //       response. This is needed so that the
                                                 //       handle area can be skipped when
                                                 //       generating the rpHash.
    UINT32                    resParmSize = 0;        // the size of the response parameters
                                                      // These values go in the rpHash.
    UINT32                    resAuthSize = 0;        // size of authorization area in the
//
                                                   // response
   INT32                      size;                // remaining data to be unmarshaled
                                                   // or remaining space in the marshaling
                                                   // buffer
   BYTE                      *buffer;              // pointer into the buffer being used
                                                   // for marshaling or unmarshaling
   UINT32                     i;                    // local temp
// This next function call is used in development to size the command and response
// buffers. The values printed are the sizes of the internal structures and
// not the sizes of the canonical forms of the command response structures. Also,
// the sizes do not include the tag, commandCode, requestSize, or the authorization
// fields.
//CommandResponseSizes();
   // Set flags for NV access state. This should happen before any other
   // operation that may require a NV write. Note, that this needs to be done
   // even when in failure mode. Otherwise, g_updateNV would stay SET while in
   // Failure mode and the NB would be written on each call.
   g_updateNV = FALSE;
   g_clearOrderly = FALSE;
   // As of Sept 25, 2013, the failure mode handling has been incorporated in the
   // reference code. This implementation requires that the system support
   // setjmp/longjmp. This code is put here because of the complexity being
   // added to the platform and simulator code to deal with all the variations
   // of errors.
   if(g_inFailureMode)
   {
       // Do failure mode processing
       TpmFailureMode (requestSize, request, responseSize, response);
       return;
   }
   if(setjmp(g_jumpBuffer) != 0)
   {
       // Get here if we got a longjump putting us into failure mode
       g_inFailureMode = TRUE;
       result = TPM_RC_FAILURE;
       goto Fail;
   }
   // Assume that everything is going to work.
   result = TPM_RC_SUCCESS;
   // Query platform to get the NV state. The result state is saved internally
   // and will be reported by NvIsAvailable(). The reference code requires that
   // accessibility of NV does not change during the execution of a command.
   // Specifically, if NV is available when the command execution starts and then
   // is not available later when it is necessary to write to NV, then the TPM
   // will go into failure mode.
   NvCheckState();
   // Due to the limitations of the simulation, TPM clock must be explicitly
   // synchronized with the system clock whenever a command is received.
   // This function call is not necessary in a hardware TPM. However, taking
   // a snapshot of the hardware timer at the beginning of the command allows
   // the time value to be consistent for the duration of the command execution.
   TimeUpdateToCurrent();
   // Any command through this function will unceremoniously end the
   // _TPM_Hash_Data/_TPM_Hash_End sequence.
   if(g_DRTMHandle != TPM_RH_UNASSIGNED)
       ObjectTerminateEvent();
     // Get command buffer size and command buffer.
     size = requestSize;
     buffer = request;
     // Parse command header: tag, commandSize and commandCode.
     // First parse the tag. The unmarshaling routine will validate
     // that it is either TPM_ST_SESSIONS or TPM_ST_NO_SESSIONS.
     result = TPMI_ST_COMMAND_TAG_Unmarshal(&tag, &buffer, &size);
     if(result != TPM_RC_SUCCESS)
         goto Cleanup;
     // Unmarshal the commandSize indicator.
     result = UINT32_Unmarshal(&commandSize, &buffer, &size);
     if(result != TPM_RC_SUCCESS)
         goto Cleanup;
     // On a TPM that receives bytes on a port, the number of bytes that were
     // received on that port is requestSize it must be identical to commandSize.
     // In addition, commandSize must not be larger than MAX_COMMAND_SIZE allowed
     // by the implementation. The check against MAX_COMMAND_SIZE may be redundant
     // as the input processing (the function that receives the command bytes and
     // places them in the input buffer) would likely have the input truncated when
     // it reaches MAX_COMMAND_SIZE, and requestSize would not equal commandSize.
     if(commandSize != requestSize || commandSize > MAX_COMMAND_SIZE)
     {
         result = TPM_RC_COMMAND_SIZE;
         goto Cleanup;
     }
     // Unmarshal the command code.
     result = TPM_CC_Unmarshal(&commandCode, &buffer, &size);
     if(result != TPM_RC_SUCCESS)
         goto Cleanup;
     // Check to see if the command is implemented.
     if(!CommandIsImplemented(commandCode))
     {
         result = TPM_RC_COMMAND_CODE;
         goto Cleanup;
     }
#if   FIELD_UPGRADE_IMPLEMENTED == YES
   // If the TPM is in FUM, then the only allowed command is
   // TPM_CC_FieldUpgradeData.
   if(IsFieldUgradeMode() && (commandCode != TPM_CC_FieldUpgradeData))
   {
        result = TPM_RC_UPGRADE;
        goto Cleanup;
   }
   else
#endif
        // Excepting FUM, the TPM only accepts TPM2_Startup() after
        // _TPM_Init. After getting a TPM2_Startup(), TPM2_Startup()
        // is no longer allowed.
        if((    !TPMIsStarted() && commandCode != TPM_CC_Startup)
             || (TPMIsStarted() && commandCode == TPM_CC_Startup))
        {
             result = TPM_RC_INITIALIZE;
             goto Cleanup;
        }
     // Start regular command process.
     // Parse Handle buffer.
     result = ParseHandleBuffer(commandCode, &buffer, &size, handles, &handleNum);
     if(result != TPM_RC_SUCCESS)
        goto Cleanup;
   // Number of handles retrieved from handle area should be less than
   // MAX_HANDLE_NUM.
   pAssert(handleNum <= MAX_HANDLE_NUM);
   // All handles in the handle area are required to reference TPM-resident
   // entities.
   for(i = 0; i < handleNum; i++)
   {
       result = EntityGetLoadStatus(&handles[i], commandCode);
       if(result != TPM_RC_SUCCESS)
       {
           if(result == TPM_RC_REFERENCE_H0)
               result = result + i;
           else
               result = RcSafeAddToResult(result, TPM_RC_H + g_rcIndex[i]);
           goto Cleanup;
       }
   }
   // Authorization session handling for the command.
   if(tag == TPM_ST_SESSIONS)
   {
       BYTE        *sessionBufferStart;// address of the session area first byte
                                       // in the input buffer
        UINT32        authorizationSize;   // number of bytes in the session area
        // Find out session buffer size.
        result = UINT32_Unmarshal(&authorizationSize, &buffer, &size);
        if(result != TPM_RC_SUCCESS)
            goto Cleanup;
        // Perform sanity check on the unmarshaled    value. If it is smaller than
        // the smallest possible session or larger    than the remaining size of
        // the command, then it is an error. NOTE:    This check could pass but the
        // session size could still be wrong. That    will be determined after the
        // sessions are unmarshaled.
        if(    authorizationSize < 9
            || authorizationSize > (UINT32) size)
        {
             result = TPM_RC_SIZE;
             goto Cleanup;
        }
        // The sessions, if any, follows authorizationSize.
        sessionBufferStart = buffer;
        // The parameters follow the session area.
        parmBufferStart = sessionBufferStart + authorizationSize;
        // Any data left over after removing the authorization sessions is
        // parameter data. If the command does not have parameters, then an
        // error will be returned if the remaining size is not zero. This is
        // checked later.
        parmBufferSize = size - authorizationSize;
        // The actions of ParseSessionBuffer() are described in the introduction.
        result = ParseSessionBuffer(commandCode,
                                    handleNum,
                                    handles,
                                    sessionBufferStart,
                                    authorizationSize,
                                    parmBufferStart,
                                    parmBufferSize);
         if(result != TPM_RC_SUCCESS)
             goto Cleanup;
   }
   else
   {
       // Whatever remains in the input buffer is used for the parameters of the
       // command.
       parmBufferStart = buffer;
       parmBufferSize = size;
         // The command has no authorization sessions.
         // If the command requires authorizations, then CheckAuthNoSession() will
         // return an error.
         result = CheckAuthNoSession(commandCode, handleNum, handles,
                                      parmBufferStart, parmBufferSize);
         if(result != TPM_RC_SUCCESS)
             goto Cleanup;
   }
   // CommandDispatcher returns a response handle buffer and a response parameter
   // buffer if it succeeds. It will also set the parameterSize field in the
   // buffer if the tag is TPM_RC_SESSIONS.
   result = CommandDispatcher(tag,
                              commandCode,
                              (INT32 *) &parmBufferSize,
                              parmBufferStart,
                              handles,
                              &resHandleSize,
                              &resParmSize);
   if(result != TPM_RC_SUCCESS)
       goto Cleanup;
   // Build the session area at the end of the parameter area.
   BuildResponseSession(tag,
                        commandCode,
                        resHandleSize,
                        resParmSize,
                        &resAuthSize);
Cleanup:
   // This implementation loads an "evict" object to a transient object slot in
   // RAM whenever an "evict" object handle is used in a command so that the
   // access to any object is the same. These temporary objects need to be
   // cleared from RAM whether the command succeeds or fails.
   ObjectCleanupEvict();
Fail:
   // The response will contain at least a response header.
   *responseSize = sizeof(TPM_ST) + sizeof(UINT32) + sizeof(TPM_RC);
   // If the command completed successfully, then build the rest of the response.
   if(result == TPM_RC_SUCCESS)
   {
       // Outgoing tag will be the same as the incoming tag.
       resTag = tag;
       // The overall response will include the handles, parameters,
       // and authorizations.
       *responseSize += resHandleSize + resParmSize + resAuthSize;
         // Adding parameter size field.
         if(tag == TPM_ST_SESSIONS)
             *responseSize += sizeof(UINT32);
         if(      g_clearOrderly == TRUE
               && gp.orderlyState != SHUTDOWN_NONE)
         {
                gp.orderlyState = SHUTDOWN_NONE;
                NvWriteReserved(NV_ORDERLY, &gp.orderlyState);
                g_updateNV = TRUE;
         }
     }
     else
     {
         // The command failed.
         // If this was a failure due to a bad command tag, then need to return
         // a TPM 1.2 compatible response
         if(result == TPM_RC_BAD_TAG)
              resTag = TPM_ST_RSP_COMMAND;
         else
              // return 2.0 compatible response
              resTag = TPM_ST_NO_SESSIONS;
     }
     // Try to commit all the writes to NV if any NV write happened during this
     // command execution. This check should be made for both succeeded and failed
     // commands, because a failed one may trigger a NV write in DA logic as well.
     // This is the only place in the command execution path that may call the NV
     // commit. If the NV commit fails, the TPM should be put in failure mode.
     if(g_updateNV && !g_inFailureMode)
     {
         g_updateNV = FALSE;
         if(!NvCommit())
              FAIL(FATAL_ERROR_INTERNAL);
     }
     // Marshal the response header.
     buffer = MemoryGetResponseBuffer(commandCode);
     TPM_ST_Marshal(&resTag, &buffer, NULL);
     UINT32_Marshal((UINT32 *)responseSize, &buffer, NULL);
     pAssert(*responseSize <= MAX_RESPONSE_SIZE);
     TPM_RC_Marshal(&result, &buffer, NULL);
     *response = MemoryGetResponseBuffer(commandCode);
     // Clear unused bit in response buffer.
     MemorySet(*response + *responseSize, 0, MAX_RESPONSE_SIZE - *responseSize);
     return;
}
