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 #ifdef EMBEDDED_MODE 167 if (startup == SU_RESET) 168 _plat__ResetCallback(); 169 #endif 170 171 return TPM_RC_SUCCESS; 172 } 173