167 lines
5.2 KiB
C
167 lines
5.2 KiB
C
// 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();
|
|
|
|
// 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;
|
|
|
|
return TPM_RC_SUCCESS;
|
|
}
|