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