You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
167 lines
5.2 KiB
167 lines
5.2 KiB
// 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; |
|
}
|
|
|