Home | History | Annotate | Download | only in tpm2
      1 // This file was extracted from the TCG Published
      2 // Trusted Platform Module Library
      3 // Part 3: Commands
      4 // Family "2.0"
      5 // Level 00 Revision 01.16
      6 // October 30, 2014
      7 
      8 #include "InternalRoutines.h"
      9 #include "Startup_fp.h"
     10 #include "Unique_fp.h"
     11 //
     12 //
     13 //     Error Returns                     Meaning
     14 //
     15 //     TPM_RC_LOCALITY                   a Startup(STATE) does not have the same H-CRTM state as the
     16 //                                       previous Startup() or the locality of the startup is not 0 pr 3
     17 //     TPM_RC_NV_UNINITIALIZED           the saved state cannot be recovered and a Startup(CLEAR) is
     18 //                                       requried.
     19 //     TPM_RC_VALUE                      start up type is not compatible with previous shutdown sequence
     20 //
     21 TPM_RC
     22 TPM2_Startup(
     23    Startup_In        *in                 // IN: input parameter list
     24    )
     25 {
     26    STARTUP_TYPE            startup;
     27    TPM_RC                  result;
     28    BOOL                    prevDrtmPreStartup;
     29    BOOL                    prevStartupLoc3;
     30    BYTE                    locality = _plat__LocalityGet();
     31 
     32    // In the PC Client specification, only locality 0 and 3 are allowed
     33    if(locality != 0 && locality != 3)
     34        return TPM_RC_LOCALITY;
     35    // Indicate that the locality was 3 unless there was an H-CRTM
     36    if(g_DrtmPreStartup)
     37        locality = 0;
     38    g_StartupLocality3 = (locality == 3);
     39 
     40    // The command needs NV update. Check if NV is available.
     41    // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
     42    // this point
     43    result = NvIsAvailable();
     44    if(result != TPM_RC_SUCCESS)
     45        return result;
     46 // Input Validation
     47 
     48    // Read orderly shutdown states from previous power cycle
     49    NvReadReserved(NV_ORDERLY, &g_prevOrderlyState);
     50 
     51    // See if the orderly state indicates that state was saved
     52    if(     (g_prevOrderlyState & ~(PRE_STARTUP_FLAG | STARTUP_LOCALITY_3))
     53        == TPM_SU_STATE)
     54    {
     55        // If so, extrat the saved flags (HACK)
     56        prevDrtmPreStartup = (g_prevOrderlyState & PRE_STARTUP_FLAG) != 0;
     57        prevStartupLoc3 = (g_prevOrderlyState & STARTUP_LOCALITY_3) != 0;
     58        g_prevOrderlyState = TPM_SU_STATE;
     59    }
     60    else
     61    {
     62        prevDrtmPreStartup = 0;
     63        prevStartupLoc3 = 0;
     64    }
     65    // if this startup is a TPM Resume, then the H-CRTM states have to match.
     66    if(in->startupType == TPM_SU_STATE)
     67   {
     68          if(g_DrtmPreStartup != prevDrtmPreStartup)
     69              return TPM_RC_VALUE + RC_Startup_startupType;
     70          if(g_StartupLocality3 != prevStartupLoc3)
     71              return TPM_RC_LOCALITY;
     72   }
     73   // if the previous power cycle was shut down with no StateSave command, or
     74   // with StateSave command for CLEAR, or the part of NV used for TPM_SU_STATE
     75   // cannot be recovered, then this cycle can not startup up with STATE
     76   if(in->startupType == TPM_SU_STATE)
     77   {
     78       if(     g_prevOrderlyState == SHUTDOWN_NONE
     79          ||   g_prevOrderlyState == TPM_SU_CLEAR)
     80           return TPM_RC_VALUE + RC_Startup_startupType;
     81 
     82          if(g_nvOk == FALSE)
     83              return TPM_RC_NV_UNINITIALIZED;
     84   }
     85 
     86 // Internal Date Update
     87 
     88   // Translate the TPM2_ShutDown and TPM2_Startup sequence into the startup
     89   // types. Will only be a SU_RESTART if the NV is OK
     90   if(     in->startupType == TPM_SU_CLEAR
     91       && g_prevOrderlyState == TPM_SU_STATE
     92       && g_nvOk == TRUE)
     93   {
     94       startup = SU_RESTART;
     95       // Read state reset data
     96       NvReadReserved(NV_STATE_RESET, &gr);
     97   }
     98   // In this check, we don't need to look at g_nvOk because that was checked
     99   // above
    100   else if(in->startupType == TPM_SU_STATE && g_prevOrderlyState == TPM_SU_STATE)
    101   {
    102       // Read state clear and state reset data
    103       NvReadReserved(NV_STATE_CLEAR, &gc);
    104       NvReadReserved(NV_STATE_RESET, &gr);
    105       startup = SU_RESUME;
    106   }
    107   else
    108   {
    109       startup = SU_RESET;
    110   }
    111 
    112   // Read persistent data from NV
    113   NvReadPersistent();
    114 
    115   // Crypto Startup
    116   CryptUtilStartup(startup);
    117 
    118   // Read the platform unique value that is used as VENDOR_PERMANENT auth value
    119   g_platformUniqueDetails.t.size = (UINT16)_plat__GetUnique(1,
    120                                      sizeof(g_platformUniqueDetails.t.buffer),
    121                                      g_platformUniqueDetails.t.buffer);
    122 
    123   // Start up subsystems
    124   // Start counters and timers
    125   TimeStartup(startup);
    126 
    127   // Start dictionary attack subsystem
    128   DAStartup(startup);
    129 
    130   // Enable hierarchies
    131   HierarchyStartup(startup);
    132 
    133    // Restore/Initialize PCR
    134    PCRStartup(startup, locality);
    135 
    136    // Restore/Initialize command audit information
    137    CommandAuditStartup(startup);
    138 
    139    // Object context variables
    140    if(startup == SU_RESET)
    141    {
    142        // Reset object context ID to 0
    143        gr.objectContextID = 0;
    144        // Reset clearCount to 0
    145        gr.clearCount= 0;
    146    }
    147 
    148    // Initialize session table
    149    SessionStartup(startup);
    150 
    151    // Initialize index/evict data.   This function clear read/write locks
    152    // in NV index
    153    NvEntityStartup(startup);
    154 
    155    // Initialize the orderly shut down flag for this cycle to SHUTDOWN_NONE.
    156    gp.orderlyState = SHUTDOWN_NONE;
    157    NvWriteReserved(NV_ORDERLY, &gp.orderlyState);
    158 
    159    // Update TPM internal states if command succeeded.
    160    // Record a TPM2_Startup command has been received.
    161    TPMRegisterStartup();
    162 
    163    // The H-CRTM state no longer matters
    164    g_DrtmPreStartup = FALSE;
    165 
    166    return TPM_RC_SUCCESS;
    167 }
    168