Line | Count | Source |
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 | 539 | { |
26 | 539 | STARTUP_TYPE startup; |
27 | 539 | TPM_RC result; |
28 | 539 | BOOL prevDrtmPreStartup; |
29 | 539 | BOOL prevStartupLoc3; |
30 | 539 | BYTE locality = _plat__LocalityGet(); |
31 | | |
32 | | // In the PC Client specification, only locality 0 and 3 are allowed |
33 | 539 | if(locality != 0 && locality != 3) |
34 | 0 | return TPM_RC_LOCALITY; |
35 | | // Indicate that the locality was 3 unless there was an H-CRTM |
36 | 539 | if(g_DrtmPreStartup) |
37 | 0 | locality = 0; |
38 | 539 | 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 | 539 | result = NvIsAvailable(); |
44 | 539 | if(result != TPM_RC_SUCCESS) |
45 | 0 | return result; |
46 | | // Input Validation |
47 | | |
48 | | // Read orderly shutdown states from previous power cycle |
49 | 539 | NvReadReserved(NV_ORDERLY, &g_prevOrderlyState); |
50 | | |
51 | | // See if the orderly state indicates that state was saved |
52 | 539 | if( (g_prevOrderlyState & ~(PRE_STARTUP_FLAG | STARTUP_LOCALITY_3)) |
53 | 539 | == TPM_SU_STATE) |
54 | 0 | { |
55 | | // If so, extrat the saved flags (HACK) |
56 | 0 | prevDrtmPreStartup = (g_prevOrderlyState & PRE_STARTUP_FLAG) != 0; |
57 | 0 | prevStartupLoc3 = (g_prevOrderlyState & STARTUP_LOCALITY_3) != 0; |
58 | 0 | g_prevOrderlyState = TPM_SU_STATE; |
59 | 0 | } |
60 | 539 | else |
61 | 539 | { |
62 | 539 | prevDrtmPreStartup = 0; |
63 | 539 | prevStartupLoc3 = 0; |
64 | 539 | } |
65 | | // if this startup is a TPM Resume, then the H-CRTM states have to match. |
66 | 539 | if(in->startupType == TPM_SU_STATE) |
67 | 0 | { |
68 | 0 | if(g_DrtmPreStartup != prevDrtmPreStartup) |
69 | 0 | return TPM_RC_VALUE + RC_Startup_startupType; |
70 | 0 | if(g_StartupLocality3 != prevStartupLoc3) |
71 | 0 | return TPM_RC_LOCALITY; |
72 | 0 | } |
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 | 539 | if(in->startupType == TPM_SU_STATE) |
77 | 0 | { |
78 | 0 | if( g_prevOrderlyState == SHUTDOWN_NONE |
79 | 0 | || g_prevOrderlyState == TPM_SU_CLEAR) |
80 | 0 | return TPM_RC_VALUE + RC_Startup_startupType; |
81 | | |
82 | 0 | if(g_nvOk == FALSE) |
83 | 0 | return TPM_RC_NV_UNINITIALIZED; |
84 | 0 | } |
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 | 539 | if( in->startupType == TPM_SU_CLEAR |
91 | 539 | && g_prevOrderlyState == TPM_SU_STATE |
92 | 0 | && g_nvOk == TRUE) |
93 | 0 | { |
94 | 0 | startup = SU_RESTART; |
95 | | // Read state reset data |
96 | 0 | NvReadReserved(NV_STATE_RESET, &gr); |
97 | 0 | } |
98 | | // In this check, we don't need to look at g_nvOk because that was checked |
99 | | // above |
100 | 539 | else if(in->startupType == TPM_SU_STATE && g_prevOrderlyState == TPM_SU_STATE) |
101 | 0 | { |
102 | | // Read state clear and state reset data |
103 | 0 | NvReadReserved(NV_STATE_CLEAR, &gc); |
104 | 0 | NvReadReserved(NV_STATE_RESET, &gr); |
105 | 0 | startup = SU_RESUME; |
106 | 0 | } |
107 | 539 | else |
108 | 539 | { |
109 | 539 | startup = SU_RESET; |
110 | 539 | } |
111 | | |
112 | | // Read persistent data from NV |
113 | 539 | NvReadPersistent(); |
114 | | |
115 | | // After reading the dictionary attack parameters, disable DA mitigation by |
116 | | // calling `DAPreInstall_Init()`, if necessary. |
117 | | // Note that this is not TPM2-compliant (b/178365982). |
118 | 539 | if (gp.recoveryTime != 0 || gp.lockoutRecovery != 0) |
119 | 0 | DAPreInstall_Init(); |
120 | | |
121 | | // Crypto Startup |
122 | 539 | CryptUtilStartup(startup); |
123 | | |
124 | | // Read the platform unique value that is used as VENDOR_PERMANENT auth value |
125 | 539 | g_platformUniqueDetails.t.size = (UINT16)_plat__GetUnique(1, |
126 | 539 | sizeof(g_platformUniqueDetails.t.buffer), |
127 | 539 | g_platformUniqueDetails.t.buffer); |
128 | | |
129 | | // Start up subsystems |
130 | | // Start counters and timers |
131 | 539 | TimeStartup(startup); |
132 | | |
133 | | // Start dictionary attack subsystem |
134 | 539 | DAStartup(startup); |
135 | | |
136 | | // Enable hierarchies |
137 | 539 | HierarchyStartup(startup); |
138 | | |
139 | | // Restore/Initialize PCR |
140 | 539 | PCRStartup(startup, locality); |
141 | | |
142 | | // Restore/Initialize command audit information |
143 | 539 | CommandAuditStartup(startup); |
144 | | |
145 | | // Object context variables |
146 | 539 | if(startup == SU_RESET) |
147 | 539 | { |
148 | | // Reset object context ID to 0 |
149 | 539 | gr.objectContextID = 0; |
150 | | // Reset clearCount to 0 |
151 | 539 | gr.clearCount= 0; |
152 | 539 | } |
153 | | |
154 | | // Initialize session table |
155 | 539 | SessionStartup(startup); |
156 | | |
157 | | // Initialize index/evict data. This function clear read/write locks |
158 | | // in NV index |
159 | 539 | NvEntityStartup(startup); |
160 | | |
161 | | // Initialize the orderly shut down flag for this cycle to SHUTDOWN_NONE. |
162 | 539 | gp.orderlyState = SHUTDOWN_NONE; |
163 | 539 | NvWriteReserved(NV_ORDERLY, &gp.orderlyState); |
164 | | |
165 | | // Update TPM internal states if command succeeded. |
166 | | // Record a TPM2_Startup command has been received. |
167 | 539 | TPMRegisterStartup(); |
168 | | |
169 | | // The H-CRTM state no longer matters |
170 | 539 | g_DrtmPreStartup = FALSE; |
171 | | |
172 | | #ifdef EMBEDDED_MODE |
173 | | _plat__StartupCallback((startup == SU_RESET) || (startup == SU_RESTART)); |
174 | | #endif |
175 | | |
176 | 539 | return TPM_RC_SUCCESS; |
177 | 539 | } |