]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.c
SecurityPkg Tpm2DeviceLibDTpm: Update enum type name to match the one in lib
[mirror_edk2.git] / SecurityPkg / Library / SmmTcg2PhysicalPresenceLib / SmmTcg2PhysicalPresenceLib.c
CommitLineData
1abfa4ce
JY
1/** @file\r
2 Handle TPM 2.0 physical presence requests from OS.\r
3 \r
4 This library will handle TPM 2.0 physical presence request from OS.\r
5\r
6 Caution: This module requires additional review when modified.\r
7 This driver will have external input - variable.\r
8 This external input must be validated carefully to avoid security issue.\r
9\r
10 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction() and Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction()\r
11 will receive untrusted input and do validation.\r
12\r
84391f57 13Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
1abfa4ce
JY
14This program and the accompanying materials \r
15are licensed and made available under the terms and conditions of the BSD License \r
16which accompanies this distribution. The full text of the license may be found at \r
17http://opensource.org/licenses/bsd-license.php\r
18\r
19THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
20WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
21\r
22**/\r
23\r
24#include <PiSmm.h>\r
25\r
26#include <Guid/Tcg2PhysicalPresenceData.h>\r
27\r
28#include <Protocol/SmmVariable.h>\r
29\r
84391f57 30#include <Library/BaseLib.h>\r
1abfa4ce 31#include <Library/DebugLib.h>\r
87c04781 32#include <Library/BaseMemoryLib.h>\r
1abfa4ce
JY
33#include <Library/Tcg2PpVendorLib.h>\r
34#include <Library/SmmServicesTableLib.h>\r
35\r
84391f57
ZC
36#define PP_INF_VERSION_1_2 "1.2"\r
37\r
1abfa4ce 38EFI_SMM_VARIABLE_PROTOCOL *mTcg2PpSmmVariable;\r
84391f57 39BOOLEAN mIsTcg2PPVerLowerThan_1_3 = FALSE;\r
1abfa4ce
JY
40\r
41/**\r
42 The handler for TPM physical presence function:\r
43 Return TPM Operation Response to OS Environment.\r
44\r
45 This API should be invoked in OS runtime phase to interface with ACPI method.\r
46\r
47 @param[out] MostRecentRequest Most recent operation request.\r
48 @param[out] Response Response to the most recent operation request.\r
49\r
50 @return Return Code for Return TPM Operation Response to OS Environment.\r
51**/\r
52UINT32\r
53EFIAPI\r
54Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (\r
55 OUT UINT32 *MostRecentRequest,\r
56 OUT UINT32 *Response\r
57 )\r
58{\r
59 EFI_STATUS Status;\r
60 UINTN DataSize;\r
61 EFI_TCG2_PHYSICAL_PRESENCE PpData;\r
62\r
63 DEBUG ((EFI_D_INFO, "[TPM2] ReturnOperationResponseToOsFunction\n"));\r
64\r
65 //\r
66 // Get the Physical Presence variable\r
67 //\r
68 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
69 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
70 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
71 &gEfiTcg2PhysicalPresenceGuid,\r
72 NULL,\r
73 &DataSize,\r
74 &PpData\r
75 );\r
76 if (EFI_ERROR (Status)) {\r
77 *MostRecentRequest = 0;\r
78 *Response = 0;\r
79 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
80 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE;\r
81 }\r
82\r
83 *MostRecentRequest = PpData.LastPPRequest;\r
84 *Response = PpData.PPResponse;\r
85\r
86 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS;\r
87}\r
88\r
89/**\r
90 The handler for TPM physical presence function:\r
91 Submit TPM Operation Request to Pre-OS Environment and\r
92 Submit TPM Operation Request to Pre-OS Environment 2.\r
93\r
94 This API should be invoked in OS runtime phase to interface with ACPI method.\r
95\r
96 Caution: This function may receive untrusted input.\r
edb0fda2 97\r
3e14edf8
ZC
98 @param[in, out] Pointer to OperationRequest TPM physical presence operation request.\r
99 @param[in, out] Pointer to RequestParameter TPM physical presence operation request parameter.\r
1abfa4ce
JY
100\r
101 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and\r
edb0fda2
ZC
102 Submit TPM Operation Request to Pre-OS Environment 2.\r
103 **/\r
1abfa4ce 104UINT32\r
edb0fda2
ZC
105Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (\r
106 IN OUT UINT32 *OperationRequest,\r
107 IN OUT UINT32 *RequestParameter\r
1abfa4ce
JY
108 )\r
109{\r
110 EFI_STATUS Status;\r
edb0fda2 111 UINT32 ReturnCode;\r
1abfa4ce
JY
112 UINTN DataSize;\r
113 EFI_TCG2_PHYSICAL_PRESENCE PpData;\r
114 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;\r
115\r
edb0fda2
ZC
116 DEBUG ((EFI_D_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", *OperationRequest, *RequestParameter));\r
117 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;\r
1abfa4ce
JY
118\r
119 //\r
120 // Get the Physical Presence variable\r
121 //\r
122 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
123 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
124 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
125 &gEfiTcg2PhysicalPresenceGuid,\r
126 NULL,\r
127 &DataSize,\r
128 &PpData\r
129 );\r
130 if (EFI_ERROR (Status)) {\r
131 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
edb0fda2
ZC
132 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
133 goto EXIT;\r
1abfa4ce
JY
134 }\r
135\r
252b891b 136 if ((*OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&\r
e92ddda2 137 (*OperationRequest < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN) ) {\r
edb0fda2
ZC
138 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;\r
139 goto EXIT;\r
1abfa4ce
JY
140 }\r
141\r
edb0fda2
ZC
142 if ((PpData.PPRequest != *OperationRequest) ||\r
143 (PpData.PPRequestParameter != *RequestParameter)) {\r
144 PpData.PPRequest = (UINT8)*OperationRequest;\r
145 PpData.PPRequestParameter = *RequestParameter;\r
1abfa4ce
JY
146 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
147 Status = mTcg2PpSmmVariable->SmmSetVariable (\r
148 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
149 &gEfiTcg2PhysicalPresenceGuid,\r
150 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
151 DataSize,\r
152 &PpData\r
153 );\r
e92ddda2
SZ
154 if (EFI_ERROR (Status)) { \r
155 DEBUG ((EFI_D_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));\r
156 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
157 goto EXIT;\r
158 }\r
1abfa4ce
JY
159 }\r
160\r
edb0fda2 161 if (*OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
1abfa4ce
JY
162 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
163 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
164 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
165 &gEfiTcg2PhysicalPresenceGuid,\r
166 NULL,\r
167 &DataSize,\r
168 &Flags\r
169 );\r
170 if (EFI_ERROR (Status)) {\r
e92ddda2 171 Flags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT | TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_DEFAULT;\r
1abfa4ce 172 }\r
edb0fda2
ZC
173 ReturnCode = Tcg2PpVendorLibSubmitRequestToPreOSFunction (*OperationRequest, Flags.PPFlags, *RequestParameter);\r
174 }\r
175\r
176EXIT:\r
177 //\r
178 // Sync PPRQ/PPRM from PP Variable if PP submission fails\r
179 //\r
180 if (ReturnCode != TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {\r
181 DEBUG ((EFI_D_ERROR, "[TPM2] Submit PP Request failure! Sync PPRQ/PPRM with PP variable.\n", Status));\r
182 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
183 ZeroMem(&PpData, DataSize);\r
184 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
185 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
186 &gEfiTcg2PhysicalPresenceGuid,\r
187 NULL,\r
188 &DataSize,\r
189 &PpData\r
190 );\r
191 *OperationRequest = (UINT32)PpData.PPRequest;\r
192 *RequestParameter = PpData.PPRequestParameter;\r
1abfa4ce
JY
193 }\r
194\r
edb0fda2
ZC
195 return ReturnCode;\r
196}\r
197\r
198/**\r
199 The handler for TPM physical presence function:\r
200 Submit TPM Operation Request to Pre-OS Environment and\r
201 Submit TPM Operation Request to Pre-OS Environment 2.\r
202\r
203 This API should be invoked in OS runtime phase to interface with ACPI method.\r
204\r
205 Caution: This function may receive untrusted input.\r
206 \r
207 @param[in] OperationRequest TPM physical presence operation request.\r
208 @param[in] RequestParameter TPM physical presence operation request parameter.\r
209\r
210 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and\r
211 Submit TPM Operation Request to Pre-OS Environment 2.\r
212**/\r
213UINT32\r
214EFIAPI\r
215Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (\r
216 IN UINT32 OperationRequest,\r
217 IN UINT32 RequestParameter\r
218 )\r
219{\r
220 UINT32 TempOperationRequest;\r
221 UINT32 TempRequestParameter;\r
222\r
223 TempOperationRequest = OperationRequest;\r
224 TempRequestParameter = RequestParameter;\r
225\r
226 return Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx(&TempOperationRequest, &TempRequestParameter);\r
1abfa4ce
JY
227}\r
228\r
229/**\r
230 The handler for TPM physical presence function:\r
231 Get User Confirmation Status for Operation.\r
232\r
233 This API should be invoked in OS runtime phase to interface with ACPI method.\r
234\r
235 Caution: This function may receive untrusted input.\r
236 \r
237 @param[in] OperationRequest TPM physical presence operation request.\r
238\r
239 @return Return Code for Get User Confirmation Status for Operation.\r
240**/\r
241UINT32\r
242EFIAPI\r
243Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (\r
244 IN UINT32 OperationRequest\r
245 )\r
246{\r
252b891b
ED
247 EFI_STATUS Status;\r
248 UINTN DataSize;\r
249 EFI_TCG2_PHYSICAL_PRESENCE PpData;\r
250 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;\r
251 BOOLEAN RequestConfirmed;\r
252 \r
1abfa4ce
JY
253 DEBUG ((EFI_D_INFO, "[TPM2] GetUserConfirmationStatusFunction, Request = %x\n", OperationRequest));\r
254\r
255 //\r
256 // Get the Physical Presence variable\r
257 //\r
258 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
259 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
260 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
261 &gEfiTcg2PhysicalPresenceGuid,\r
262 NULL,\r
263 &DataSize,\r
264 &PpData\r
265 );\r
266 if (EFI_ERROR (Status)) {\r
267 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
268 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;\r
269 }\r
270 //\r
271 // Get the Physical Presence flags\r
272 //\r
273 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
274 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
275 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
276 &gEfiTcg2PhysicalPresenceGuid,\r
277 NULL,\r
278 &DataSize,\r
279 &Flags\r
280 );\r
281 if (EFI_ERROR (Status)) {\r
282 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP flags failure! Status = %r\n", Status));\r
283 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;\r
284 }\r
285\r
286 RequestConfirmed = FALSE;\r
287\r
288 switch (OperationRequest) {\r
289 case TCG2_PHYSICAL_PRESENCE_CLEAR:\r
290 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:\r
291 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:\r
292 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:\r
293 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR) == 0) {\r
294 RequestConfirmed = TRUE;\r
295 }\r
296 break;\r
297\r
265e5c82 298 case TCG2_PHYSICAL_PRESENCE_NO_ACTION:\r
1abfa4ce
JY
299 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:\r
300 RequestConfirmed = TRUE;\r
301 break;\r
302\r
303 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:\r
304 break;\r
305\r
306 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:\r
307 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS) == 0) {\r
308 RequestConfirmed = TRUE;\r
309 }\r
310 break;\r
311\r
312 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:\r
313 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS) == 0) {\r
314 RequestConfirmed = TRUE;\r
315 }\r
316 break;\r
317 \r
318 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:\r
319 RequestConfirmed = TRUE;\r
320 break;\r
321\r
e92ddda2
SZ
322 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID:\r
323 if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) == 0) {\r
324 RequestConfirmed = TRUE;\r
325 }\r
326 break;\r
327\r
328 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID:\r
329 if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) == 0) {\r
330 RequestConfirmed = TRUE;\r
331 }\r
332 break;\r
333\r
334 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE:\r
335 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE:\r
336 RequestConfirmed = TRUE;\r
337 break;\r
338\r
339 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE:\r
340 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE:\r
341 break;\r
342\r
1abfa4ce 343 default:\r
3d1872b7 344 if (!mIsTcg2PPVerLowerThan_1_3) {\r
84391f57
ZC
345 if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
346 //\r
347 // TCG2 PP1.3 spec defined operations that are reserved or un-implemented\r
348 //\r
349 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;\r
350 }\r
351 } else {\r
352 //\r
353 // TCG PP lower than 1.3. (1.0, 1.1, 1.2)\r
354 //\r
355 if (OperationRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {\r
356 RequestConfirmed = TRUE;\r
357 } else if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
358 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;\r
359 }\r
1abfa4ce
JY
360 }\r
361 break;\r
362 }\r
363\r
364 if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
365 return Tcg2PpVendorLibGetUserConfirmationStatusFunction (OperationRequest, Flags.PPFlags);\r
366 }\r
367\r
368 if (RequestConfirmed) {\r
369 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_NOT_REQUIRED;\r
370 } else {\r
371 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_REQUIRED;\r
372 } \r
373}\r
374\r
375/**\r
e92ddda2 376 The constructor function locates SmmVariable protocol.\r
1abfa4ce
JY
377 \r
378 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. \r
379\r
380 @param ImageHandle The firmware allocated handle for the EFI image.\r
381 @param SystemTable A pointer to the EFI System Table.\r
382 \r
383 @retval EFI_SUCCESS The constructor successfully added string package.\r
384 @retval Other value The constructor can't add string package.\r
385**/\r
386EFI_STATUS\r
387EFIAPI\r
388Tcg2PhysicalPresenceLibConstructor (\r
389 IN EFI_HANDLE ImageHandle,\r
390 IN EFI_SYSTEM_TABLE *SystemTable\r
391 )\r
392{\r
393 EFI_STATUS Status;\r
394\r
84391f57
ZC
395 if (AsciiStrnCmp(PP_INF_VERSION_1_2, (CHAR8 *)PcdGetPtr(PcdTcgPhysicalPresenceInterfaceVer), sizeof(PP_INF_VERSION_1_2) - 1) <= 0) {\r
396 mIsTcg2PPVerLowerThan_1_3 = TRUE;\r
397 }\r
398\r
1abfa4ce
JY
399 //\r
400 // Locate SmmVariableProtocol.\r
401 //\r
402 Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&mTcg2PpSmmVariable);\r
403 ASSERT_EFI_ERROR (Status);\r
404\r
405 return EFI_SUCCESS;\r
406}\r