]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/MmTcg2PhysicalPresenceLibCommon.c
SecurityPkg: Apply uncrustify changes
[mirror_edk2.git] / SecurityPkg / Library / SmmTcg2PhysicalPresenceLib / MmTcg2PhysicalPresenceLibCommon.c
CommitLineData
45939255
KQ
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
13Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.<BR>\r
14SPDX-License-Identifier: BSD-2-Clause-Patent\r
15\r
16**/\r
17\r
18#include <PiMm.h>\r
19\r
20#include <Guid/Tcg2PhysicalPresenceData.h>\r
21\r
22#include <Protocol/SmmVariable.h>\r
23\r
24#include <Library/BaseLib.h>\r
25#include <Library/DebugLib.h>\r
26#include <Library/BaseMemoryLib.h>\r
27#include <Library/Tcg2PpVendorLib.h>\r
28#include <Library/MmServicesTableLib.h>\r
29\r
c411b485 30#define PP_INF_VERSION_1_2 "1.2"\r
45939255
KQ
31\r
32EFI_SMM_VARIABLE_PROTOCOL *mTcg2PpSmmVariable;\r
33BOOLEAN mIsTcg2PPVerLowerThan_1_3 = FALSE;\r
34UINT32 mTcg2PhysicalPresenceFlags;\r
35\r
36/**\r
37 The handler for TPM physical presence function:\r
38 Return TPM Operation Response to OS Environment.\r
39\r
40 This API should be invoked in OS runtime phase to interface with ACPI method.\r
41\r
42 @param[out] MostRecentRequest Most recent operation request.\r
43 @param[out] Response Response to the most recent operation request.\r
44\r
45 @return Return Code for Return TPM Operation Response to OS Environment.\r
46**/\r
47UINT32\r
48EFIAPI\r
49Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (\r
c411b485
MK
50 OUT UINT32 *MostRecentRequest,\r
51 OUT UINT32 *Response\r
45939255
KQ
52 )\r
53{\r
c411b485
MK
54 EFI_STATUS Status;\r
55 UINTN DataSize;\r
56 EFI_TCG2_PHYSICAL_PRESENCE PpData;\r
45939255
KQ
57\r
58 DEBUG ((DEBUG_INFO, "[TPM2] ReturnOperationResponseToOsFunction\n"));\r
59\r
60 //\r
61 // Get the Physical Presence variable\r
62 //\r
63 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
c411b485
MK
64 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
65 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
66 &gEfiTcg2PhysicalPresenceGuid,\r
67 NULL,\r
68 &DataSize,\r
69 &PpData\r
70 );\r
45939255
KQ
71 if (EFI_ERROR (Status)) {\r
72 *MostRecentRequest = 0;\r
73 *Response = 0;\r
74 DEBUG ((DEBUG_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
75 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE;\r
76 }\r
77\r
78 *MostRecentRequest = PpData.LastPPRequest;\r
79 *Response = PpData.PPResponse;\r
80\r
81 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS;\r
82}\r
83\r
84/**\r
85 The handler for TPM physical presence function:\r
86 Submit TPM Operation Request to Pre-OS Environment and\r
87 Submit TPM Operation Request to Pre-OS Environment 2.\r
88\r
89 This API should be invoked in OS runtime phase to interface with ACPI method.\r
90\r
91 Caution: This function may receive untrusted input.\r
92\r
93 @param[in, out] Pointer to OperationRequest TPM physical presence operation request.\r
94 @param[in, out] Pointer to RequestParameter TPM physical presence operation request parameter.\r
95\r
96 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and\r
97 Submit TPM Operation Request to Pre-OS Environment 2.\r
98 **/\r
99UINT32\r
100Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (\r
c411b485
MK
101 IN OUT UINT32 *OperationRequest,\r
102 IN OUT UINT32 *RequestParameter\r
45939255
KQ
103 )\r
104{\r
105 EFI_STATUS Status;\r
106 UINT32 ReturnCode;\r
107 UINTN DataSize;\r
108 EFI_TCG2_PHYSICAL_PRESENCE PpData;\r
109 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;\r
110\r
111 DEBUG ((DEBUG_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", *OperationRequest, *RequestParameter));\r
112 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;\r
113\r
114 //\r
115 // Get the Physical Presence variable\r
116 //\r
117 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
c411b485
MK
118 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
119 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
120 &gEfiTcg2PhysicalPresenceGuid,\r
121 NULL,\r
122 &DataSize,\r
123 &PpData\r
124 );\r
45939255
KQ
125 if (EFI_ERROR (Status)) {\r
126 DEBUG ((DEBUG_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
127 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
128 goto EXIT;\r
129 }\r
130\r
131 if ((*OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&\r
c411b485
MK
132 (*OperationRequest < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN))\r
133 {\r
45939255
KQ
134 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;\r
135 goto EXIT;\r
136 }\r
137\r
138 if ((PpData.PPRequest != *OperationRequest) ||\r
c411b485
MK
139 (PpData.PPRequestParameter != *RequestParameter))\r
140 {\r
141 PpData.PPRequest = (UINT8)*OperationRequest;\r
45939255 142 PpData.PPRequestParameter = *RequestParameter;\r
c411b485
MK
143 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
144 Status = mTcg2PpSmmVariable->SmmSetVariable (\r
145 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
146 &gEfiTcg2PhysicalPresenceGuid,\r
147 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
148 DataSize,\r
149 &PpData\r
150 );\r
45939255
KQ
151 if (EFI_ERROR (Status)) {\r
152 DEBUG ((DEBUG_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));\r
153 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
154 goto EXIT;\r
155 }\r
156 }\r
157\r
158 if (*OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
159 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
c411b485
MK
160 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
161 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
162 &gEfiTcg2PhysicalPresenceGuid,\r
163 NULL,\r
164 &DataSize,\r
165 &Flags\r
166 );\r
45939255
KQ
167 if (EFI_ERROR (Status)) {\r
168 Flags.PPFlags = mTcg2PhysicalPresenceFlags;\r
169 }\r
c411b485 170\r
45939255
KQ
171 ReturnCode = Tcg2PpVendorLibSubmitRequestToPreOSFunction (*OperationRequest, Flags.PPFlags, *RequestParameter);\r
172 }\r
173\r
174EXIT:\r
175 //\r
176 // Sync PPRQ/PPRM from PP Variable if PP submission fails\r
177 //\r
178 if (ReturnCode != TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {\r
179 DEBUG ((DEBUG_ERROR, "[TPM2] Submit PP Request failure! Sync PPRQ/PPRM with PP variable.\n", Status));\r
180 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
c411b485 181 ZeroMem (&PpData, DataSize);\r
45939255
KQ
182 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
183 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
184 &gEfiTcg2PhysicalPresenceGuid,\r
185 NULL,\r
186 &DataSize,\r
187 &PpData\r
188 );\r
189 *OperationRequest = (UINT32)PpData.PPRequest;\r
190 *RequestParameter = PpData.PPRequestParameter;\r
191 }\r
192\r
193 return ReturnCode;\r
194}\r
195\r
196/**\r
197 The handler for TPM physical presence function:\r
198 Submit TPM Operation Request to Pre-OS Environment and\r
199 Submit TPM Operation Request to Pre-OS Environment 2.\r
200\r
201 This API should be invoked in OS runtime phase to interface with ACPI method.\r
202\r
203 Caution: This function may receive untrusted input.\r
204\r
205 @param[in] OperationRequest TPM physical presence operation request.\r
206 @param[in] RequestParameter TPM physical presence operation request parameter.\r
207\r
208 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and\r
209 Submit TPM Operation Request to Pre-OS Environment 2.\r
210**/\r
211UINT32\r
212EFIAPI\r
213Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (\r
c411b485
MK
214 IN UINT32 OperationRequest,\r
215 IN UINT32 RequestParameter\r
45939255
KQ
216 )\r
217{\r
c411b485
MK
218 UINT32 TempOperationRequest;\r
219 UINT32 TempRequestParameter;\r
45939255
KQ
220\r
221 TempOperationRequest = OperationRequest;\r
222 TempRequestParameter = RequestParameter;\r
223\r
c411b485 224 return Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (&TempOperationRequest, &TempRequestParameter);\r
45939255
KQ
225}\r
226\r
227/**\r
228 The handler for TPM physical presence function:\r
229 Get User Confirmation Status for Operation.\r
230\r
231 This API should be invoked in OS runtime phase to interface with ACPI method.\r
232\r
233 Caution: This function may receive untrusted input.\r
234\r
235 @param[in] OperationRequest TPM physical presence operation request.\r
236\r
237 @return Return Code for Get User Confirmation Status for Operation.\r
238**/\r
239UINT32\r
240EFIAPI\r
241Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (\r
c411b485 242 IN UINT32 OperationRequest\r
45939255
KQ
243 )\r
244{\r
245 EFI_STATUS Status;\r
246 UINTN DataSize;\r
247 EFI_TCG2_PHYSICAL_PRESENCE PpData;\r
248 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;\r
249 BOOLEAN RequestConfirmed;\r
250\r
251 DEBUG ((DEBUG_INFO, "[TPM2] GetUserConfirmationStatusFunction, Request = %x\n", OperationRequest));\r
252\r
253 //\r
254 // Get the Physical Presence variable\r
255 //\r
256 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
c411b485
MK
257 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
258 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
259 &gEfiTcg2PhysicalPresenceGuid,\r
260 NULL,\r
261 &DataSize,\r
262 &PpData\r
263 );\r
45939255
KQ
264 if (EFI_ERROR (Status)) {\r
265 DEBUG ((DEBUG_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
266 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;\r
267 }\r
c411b485 268\r
45939255
KQ
269 //\r
270 // Get the Physical Presence flags\r
271 //\r
272 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
c411b485
MK
273 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
274 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
275 &gEfiTcg2PhysicalPresenceGuid,\r
276 NULL,\r
277 &DataSize,\r
278 &Flags\r
279 );\r
45939255
KQ
280 if (EFI_ERROR (Status)) {\r
281 DEBUG ((DEBUG_ERROR, "[TPM2] Get PP flags failure! Status = %r\n", Status));\r
282 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;\r
283 }\r
284\r
285 RequestConfirmed = FALSE;\r
286\r
287 switch (OperationRequest) {\r
288 case TCG2_PHYSICAL_PRESENCE_CLEAR:\r
289 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:\r
290 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:\r
291 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:\r
292 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR) == 0) {\r
293 RequestConfirmed = TRUE;\r
294 }\r
c411b485 295\r
45939255
KQ
296 break;\r
297\r
298 case TCG2_PHYSICAL_PRESENCE_NO_ACTION:\r
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
c411b485 310\r
45939255
KQ
311 break;\r
312\r
313 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:\r
314 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS) == 0) {\r
315 RequestConfirmed = TRUE;\r
316 }\r
c411b485 317\r
45939255
KQ
318 break;\r
319\r
320 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:\r
321 RequestConfirmed = TRUE;\r
322 break;\r
323\r
324 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID:\r
325 if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) == 0) {\r
326 RequestConfirmed = TRUE;\r
327 }\r
c411b485 328\r
45939255
KQ
329 break;\r
330\r
331 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID:\r
332 if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) == 0) {\r
333 RequestConfirmed = TRUE;\r
334 }\r
c411b485 335\r
45939255
KQ
336 break;\r
337\r
338 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE:\r
339 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE:\r
340 RequestConfirmed = TRUE;\r
341 break;\r
342\r
343 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE:\r
344 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE:\r
345 break;\r
346\r
347 default:\r
348 if (!mIsTcg2PPVerLowerThan_1_3) {\r
349 if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
350 //\r
351 // TCG2 PP1.3 spec defined operations that are reserved or un-implemented\r
352 //\r
353 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;\r
354 }\r
355 } else {\r
c411b485
MK
356 //\r
357 // TCG PP lower than 1.3. (1.0, 1.1, 1.2)\r
358 //\r
359 if (OperationRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {\r
360 RequestConfirmed = TRUE;\r
361 } else if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
362 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;\r
363 }\r
45939255 364 }\r
c411b485 365\r
45939255
KQ
366 break;\r
367 }\r
368\r
369 if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
370 return Tcg2PpVendorLibGetUserConfirmationStatusFunction (OperationRequest, Flags.PPFlags);\r
371 }\r
372\r
373 if (RequestConfirmed) {\r
374 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_NOT_REQUIRED;\r
375 } else {\r
376 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_REQUIRED;\r
377 }\r
378}\r
379\r
380/**\r
381 The constructor function locates SmmVariable protocol.\r
382\r
383 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.\r
384\r
385 @retval EFI_SUCCESS The constructor successfully added string package.\r
386 @retval Other value The constructor can't add string package.\r
387**/\r
388EFI_STATUS\r
389Tcg2PhysicalPresenceLibCommonConstructor (\r
390 VOID\r
391 )\r
392{\r
393 EFI_STATUS Status;\r
394\r
c411b485 395 if (AsciiStrnCmp (PP_INF_VERSION_1_2, (CHAR8 *)PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer), sizeof (PP_INF_VERSION_1_2) - 1) >= 0) {\r
45939255
KQ
396 mIsTcg2PPVerLowerThan_1_3 = TRUE;\r
397 }\r
398\r
399 //\r
400 // Locate SmmVariableProtocol.\r
401 //\r
c411b485 402 Status = gMmst->MmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&mTcg2PpSmmVariable);\r
45939255
KQ
403 ASSERT_EFI_ERROR (Status);\r
404\r
c411b485 405 mTcg2PhysicalPresenceFlags = PcdGet32 (PcdTcg2PhysicalPresenceFlags);\r
45939255
KQ
406\r
407 return EFI_SUCCESS;\r
408}\r