// 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     "ExecCommand_fp.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
   INT32                      bufferSize;          // size of 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;
   }
#ifndef EMBEDDED_MODE
   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;
   }
#endif  // EMBEDDED_MODE   ^^^ not defined
   // 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();
#ifndef EMBEDDED_MODE
Fail:
#endif  // EMBEDDED_MODE  ^^^ not defined
   // 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);
#ifdef EMBEDDED_MODE
	      // Make sure we pass errors along
	      result = TPM_RC_FAILURE;
	      resTag = TPM_ST_NO_SESSIONS;
#endif
	 }
     }
     // Marshal the response header.
     buffer = MemoryGetResponseBuffer(commandCode);
     bufferSize = 10;
     TPM_ST_Marshal(&resTag, &buffer, &bufferSize);
     UINT32_Marshal((UINT32 *)responseSize, &buffer, &bufferSize);
     pAssert(*responseSize <= MAX_RESPONSE_SIZE);
     TPM_RC_Marshal(&result, &buffer, &bufferSize);
     *response = MemoryGetResponseBuffer(commandCode);
     // Clear unused bit in response buffer.
     MemorySet(*response + *responseSize, 0, MAX_RESPONSE_SIZE - *responseSize);
     return;
}
