15679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This file was extracted from the TCG Published
25679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Trusted Platform Module Library
35679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Part 3: Commands
45679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Family "2.0"
55679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Level 00 Revision 01.16
65679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// October 30, 2014
75679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
85679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "InternalRoutines.h"
95679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "Startup_fp.h"
10523b0eb19d9a9397b2f817caf41766a478b05d43Vadim Bendebury#include "Unique_fp.h"
115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     Error Returns                     Meaning
145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_LOCALITY                   a Startup(STATE) does not have the same H-CRTM state as the
165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                       previous Startup() or the locality of the startup is not 0 pr 3
175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_NV_UNINITIALIZED           the saved state cannot be recovered and a Startup(CLEAR) is
185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                       requried.
195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_VALUE                      start up type is not compatible with previous shutdown sequence
205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
215679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
225679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM2_Startup(
235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   Startup_In        *in                 // IN: input parameter list
245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   STARTUP_TYPE            startup;
275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_RC                  result;
285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BOOL                    prevDrtmPreStartup;
295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BOOL                    prevStartupLoc3;
305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                    locality = _plat__LocalityGet();
315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // In the PC Client specification, only locality 0 and 3 are allowed
335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(locality != 0 && locality != 3)
345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_LOCALITY;
355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Indicate that the locality was 3 unless there was an H-CRTM
365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(g_DrtmPreStartup)
375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       locality = 0;
385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   g_StartupLocality3 = (locality == 3);
395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // The command needs NV update. Check if NV is available.
415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // this point
435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   result = NvIsAvailable();
445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(result != TPM_RC_SUCCESS)
455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return result;
465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Input Validation
475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Read orderly shutdown states from previous power cycle
495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_ORDERLY, &g_prevOrderlyState);
505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // See if the orderly state indicates that state was saved
525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(     (g_prevOrderlyState & ~(PRE_STARTUP_FLAG | STARTUP_LOCALITY_3))
535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       == TPM_SU_STATE)
545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // If so, extrat the saved flags (HACK)
565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       prevDrtmPreStartup = (g_prevOrderlyState & PRE_STARTUP_FLAG) != 0;
575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       prevStartupLoc3 = (g_prevOrderlyState & STARTUP_LOCALITY_3) != 0;
585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       g_prevOrderlyState = TPM_SU_STATE;
595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   else
615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       prevDrtmPreStartup = 0;
635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       prevStartupLoc3 = 0;
645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // if this startup is a TPM Resume, then the H-CRTM states have to match.
665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(in->startupType == TPM_SU_STATE)
675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  {
685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         if(g_DrtmPreStartup != prevDrtmPreStartup)
695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             return TPM_RC_VALUE + RC_Startup_startupType;
705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         if(g_StartupLocality3 != prevStartupLoc3)
715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             return TPM_RC_LOCALITY;
725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  }
735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // if the previous power cycle was shut down with no StateSave command, or
745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // with StateSave command for CLEAR, or the part of NV used for TPM_SU_STATE
755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // cannot be recovered, then this cycle can not startup up with STATE
765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  if(in->startupType == TPM_SU_STATE)
775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  {
785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      if(     g_prevOrderlyState == SHUTDOWN_NONE
795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         ||   g_prevOrderlyState == TPM_SU_CLEAR)
805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          return TPM_RC_VALUE + RC_Startup_startupType;
815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         if(g_nvOk == FALSE)
835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             return TPM_RC_NV_UNINITIALIZED;
845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  }
855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Internal Date Update
875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // Translate the TPM2_ShutDown and TPM2_Startup sequence into the startup
895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // types. Will only be a SU_RESTART if the NV is OK
905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  if(     in->startupType == TPM_SU_CLEAR
915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      && g_prevOrderlyState == TPM_SU_STATE
925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      && g_nvOk == TRUE)
935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  {
945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      startup = SU_RESTART;
955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      // Read state reset data
965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      NvReadReserved(NV_STATE_RESET, &gr);
975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  }
985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // In this check, we don't need to look at g_nvOk because that was checked
995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // above
1005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  else if(in->startupType == TPM_SU_STATE && g_prevOrderlyState == TPM_SU_STATE)
1015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  {
1025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      // Read state clear and state reset data
1035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      NvReadReserved(NV_STATE_CLEAR, &gc);
1045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      NvReadReserved(NV_STATE_RESET, &gr);
1055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      startup = SU_RESUME;
1065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  }
1075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  else
1085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  {
1095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      startup = SU_RESET;
1105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  }
1115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // Read persistent data from NV
1135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  NvReadPersistent();
1145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // Crypto Startup
1165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  CryptUtilStartup(startup);
1175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // Read the platform unique value that is used as VENDOR_PERMANENT auth value
1195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  g_platformUniqueDetails.t.size = (UINT16)_plat__GetUnique(1,
1205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     sizeof(g_platformUniqueDetails.t.buffer),
1215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     g_platformUniqueDetails.t.buffer);
1225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // Start up subsystems
1245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // Start counters and timers
1255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  TimeStartup(startup);
1265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // Start dictionary attack subsystem
1285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  DAStartup(startup);
1295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // Enable hierarchies
1315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  HierarchyStartup(startup);
1325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Restore/Initialize PCR
1345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   PCRStartup(startup, locality);
1355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Restore/Initialize command audit information
1375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   CommandAuditStartup(startup);
1385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Object context variables
1405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(startup == SU_RESET)
1415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
1425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Reset object context ID to 0
1435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       gr.objectContextID = 0;
1445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Reset clearCount to 0
1455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       gr.clearCount= 0;
1465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
1475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Initialize session table
1495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   SessionStartup(startup);
1505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Initialize index/evict data.   This function clear read/write locks
1525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // in NV index
1535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvEntityStartup(startup);
1545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Initialize the orderly shut down flag for this cycle to SHUTDOWN_NONE.
1565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   gp.orderlyState = SHUTDOWN_NONE;
1575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvWriteReserved(NV_ORDERLY, &gp.orderlyState);
1585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Update TPM internal states if command succeeded.
1605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Record a TPM2_Startup command has been received.
1615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMRegisterStartup();
1625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // The H-CRTM state no longer matters
1645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   g_DrtmPreStartup = FALSE;
1655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TPM_RC_SUCCESS;
1675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
168