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

#include "InternalRoutines.h"
#include "Startup_fp.h"
#include "Unique_fp.h"
//
//
//     Error Returns                     Meaning
//
//     TPM_RC_LOCALITY                   a Startup(STATE) does not have the same H-CRTM state as the
//                                       previous Startup() or the locality of the startup is not 0 pr 3
//     TPM_RC_NV_UNINITIALIZED           the saved state cannot be recovered and a Startup(CLEAR) is
//                                       requried.
//     TPM_RC_VALUE                      start up type is not compatible with previous shutdown sequence
//
TPM_RC
TPM2_Startup(
   Startup_In        *in                 // IN: input parameter list
   )
{
   STARTUP_TYPE            startup;
   TPM_RC                  result;
   BOOL                    prevDrtmPreStartup;
   BOOL                    prevStartupLoc3;
   BYTE                    locality = _plat__LocalityGet();

   // In the PC Client specification, only locality 0 and 3 are allowed
   if(locality != 0 && locality != 3)
       return TPM_RC_LOCALITY;
   // Indicate that the locality was 3 unless there was an H-CRTM
   if(g_DrtmPreStartup)
       locality = 0;
   g_StartupLocality3 = (locality == 3);

   // The command needs NV update. Check if NV is available.
   // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
   // this point
   result = NvIsAvailable();
   if(result != TPM_RC_SUCCESS)
       return result;
// Input Validation

   // Read orderly shutdown states from previous power cycle
   NvReadReserved(NV_ORDERLY, &g_prevOrderlyState);

   // See if the orderly state indicates that state was saved
   if(     (g_prevOrderlyState & ~(PRE_STARTUP_FLAG | STARTUP_LOCALITY_3))
       == TPM_SU_STATE)
   {
       // If so, extrat the saved flags (HACK)
       prevDrtmPreStartup = (g_prevOrderlyState & PRE_STARTUP_FLAG) != 0;
       prevStartupLoc3 = (g_prevOrderlyState & STARTUP_LOCALITY_3) != 0;
       g_prevOrderlyState = TPM_SU_STATE;
   }
   else
   {
       prevDrtmPreStartup = 0;
       prevStartupLoc3 = 0;
   }
   // if this startup is a TPM Resume, then the H-CRTM states have to match.
   if(in->startupType == TPM_SU_STATE)
  {
         if(g_DrtmPreStartup != prevDrtmPreStartup)
             return TPM_RC_VALUE + RC_Startup_startupType;
         if(g_StartupLocality3 != prevStartupLoc3)
             return TPM_RC_LOCALITY;
  }
  // if the previous power cycle was shut down with no StateSave command, or
  // with StateSave command for CLEAR, or the part of NV used for TPM_SU_STATE
  // cannot be recovered, then this cycle can not startup up with STATE
  if(in->startupType == TPM_SU_STATE)
  {
      if(     g_prevOrderlyState == SHUTDOWN_NONE
         ||   g_prevOrderlyState == TPM_SU_CLEAR)
          return TPM_RC_VALUE + RC_Startup_startupType;

         if(g_nvOk == FALSE)
             return TPM_RC_NV_UNINITIALIZED;
  }

// Internal Date Update

  // Translate the TPM2_ShutDown and TPM2_Startup sequence into the startup
  // types. Will only be a SU_RESTART if the NV is OK
  if(     in->startupType == TPM_SU_CLEAR
      && g_prevOrderlyState == TPM_SU_STATE
      && g_nvOk == TRUE)
  {
      startup = SU_RESTART;
      // Read state reset data
      NvReadReserved(NV_STATE_RESET, &gr);
  }
  // In this check, we don't need to look at g_nvOk because that was checked
  // above
  else if(in->startupType == TPM_SU_STATE && g_prevOrderlyState == TPM_SU_STATE)
  {
      // Read state clear and state reset data
      NvReadReserved(NV_STATE_CLEAR, &gc);
      NvReadReserved(NV_STATE_RESET, &gr);
      startup = SU_RESUME;
  }
  else
  {
      startup = SU_RESET;
  }

  // Read persistent data from NV
  NvReadPersistent();

  // After reading the dictionary attack parameters, disable DA mitigation by
  // calling `DAPreInstall_Init()`, if necessary.
  // Note that this is not TPM2-compliant (b/178365982).
  if (gp.recoveryTime != 0 || gp.lockoutRecovery != 0)
    DAPreInstall_Init();

  // Crypto Startup
  CryptUtilStartup(startup);

  // Read the platform unique value that is used as VENDOR_PERMANENT auth value
  g_platformUniqueDetails.t.size = (UINT16)_plat__GetUnique(1,
                                     sizeof(g_platformUniqueDetails.t.buffer),
                                     g_platformUniqueDetails.t.buffer);

  // Start up subsystems
  // Start counters and timers
  TimeStartup(startup);

  // Start dictionary attack subsystem
  DAStartup(startup);

  // Enable hierarchies
  HierarchyStartup(startup);

   // Restore/Initialize PCR
   PCRStartup(startup, locality);

   // Restore/Initialize command audit information
   CommandAuditStartup(startup);

   // Object context variables
   if(startup == SU_RESET)
   {
       // Reset object context ID to 0
       gr.objectContextID = 0;
       // Reset clearCount to 0
       gr.clearCount= 0;
   }

   // Initialize session table
   SessionStartup(startup);

   // Initialize index/evict data.   This function clear read/write locks
   // in NV index
   NvEntityStartup(startup);

   // Initialize the orderly shut down flag for this cycle to SHUTDOWN_NONE.
   gp.orderlyState = SHUTDOWN_NONE;
   NvWriteReserved(NV_ORDERLY, &gp.orderlyState);

   // Update TPM internal states if command succeeded.
   // Record a TPM2_Startup command has been received.
   TPMRegisterStartup();

   // The H-CRTM state no longer matters
   g_DrtmPreStartup = FALSE;

#ifdef EMBEDDED_MODE
   _plat__StartupCallback();
#endif

   return TPM_RC_SUCCESS;
}
