]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.c
SecurityPkg Tcg2PPLib: Support BlockSID related actions
[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
6d7c4a25 13Copyright (c) 2015 - 2016, 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
30#include <Library/DebugLib.h>\r
87c04781 31#include <Library/BaseMemoryLib.h>\r
1abfa4ce
JY
32#include <Library/Tcg2PpVendorLib.h>\r
33#include <Library/SmmServicesTableLib.h>\r
34\r
35EFI_SMM_VARIABLE_PROTOCOL *mTcg2PpSmmVariable;\r
36\r
37/**\r
38 The handler for TPM physical presence function:\r
39 Return TPM Operation Response to OS Environment.\r
40\r
41 This API should be invoked in OS runtime phase to interface with ACPI method.\r
42\r
43 @param[out] MostRecentRequest Most recent operation request.\r
44 @param[out] Response Response to the most recent operation request.\r
45\r
46 @return Return Code for Return TPM Operation Response to OS Environment.\r
47**/\r
48UINT32\r
49EFIAPI\r
50Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (\r
51 OUT UINT32 *MostRecentRequest,\r
52 OUT UINT32 *Response\r
53 )\r
54{\r
55 EFI_STATUS Status;\r
56 UINTN DataSize;\r
57 EFI_TCG2_PHYSICAL_PRESENCE PpData;\r
58\r
59 DEBUG ((EFI_D_INFO, "[TPM2] ReturnOperationResponseToOsFunction\n"));\r
60\r
61 //\r
62 // Get the Physical Presence variable\r
63 //\r
64 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
65 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
66 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
67 &gEfiTcg2PhysicalPresenceGuid,\r
68 NULL,\r
69 &DataSize,\r
70 &PpData\r
71 );\r
72 if (EFI_ERROR (Status)) {\r
73 *MostRecentRequest = 0;\r
74 *Response = 0;\r
75 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
76 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE;\r
77 }\r
78\r
79 *MostRecentRequest = PpData.LastPPRequest;\r
80 *Response = PpData.PPResponse;\r
81\r
82 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS;\r
83}\r
84\r
85/**\r
86 The handler for TPM physical presence function:\r
87 Submit TPM Operation Request to Pre-OS Environment and\r
88 Submit TPM Operation Request to Pre-OS Environment 2.\r
89\r
90 This API should be invoked in OS runtime phase to interface with ACPI method.\r
91\r
92 Caution: This function may receive untrusted input.\r
edb0fda2 93\r
3e14edf8
ZC
94 @param[in, out] Pointer to OperationRequest TPM physical presence operation request.\r
95 @param[in, out] Pointer to RequestParameter TPM physical presence operation request parameter.\r
1abfa4ce
JY
96\r
97 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and\r
edb0fda2
ZC
98 Submit TPM Operation Request to Pre-OS Environment 2.\r
99 **/\r
1abfa4ce 100UINT32\r
edb0fda2
ZC
101Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (\r
102 IN OUT UINT32 *OperationRequest,\r
103 IN OUT UINT32 *RequestParameter\r
1abfa4ce
JY
104 )\r
105{\r
106 EFI_STATUS Status;\r
edb0fda2 107 UINT32 ReturnCode;\r
1abfa4ce
JY
108 UINTN DataSize;\r
109 EFI_TCG2_PHYSICAL_PRESENCE PpData;\r
110 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;\r
111\r
edb0fda2
ZC
112 DEBUG ((EFI_D_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", *OperationRequest, *RequestParameter));\r
113 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;\r
1abfa4ce
JY
114\r
115 //\r
116 // Get the Physical Presence variable\r
117 //\r
118 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
119 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
120 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
121 &gEfiTcg2PhysicalPresenceGuid,\r
122 NULL,\r
123 &DataSize,\r
124 &PpData\r
125 );\r
126 if (EFI_ERROR (Status)) {\r
127 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
edb0fda2
ZC
128 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
129 goto EXIT;\r
1abfa4ce
JY
130 }\r
131\r
252b891b 132 if ((*OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&\r
e92ddda2 133 (*OperationRequest < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN) ) {\r
edb0fda2
ZC
134 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;\r
135 goto EXIT;\r
1abfa4ce
JY
136 }\r
137\r
edb0fda2
ZC
138 if ((PpData.PPRequest != *OperationRequest) ||\r
139 (PpData.PPRequestParameter != *RequestParameter)) {\r
140 PpData.PPRequest = (UINT8)*OperationRequest;\r
141 PpData.PPRequestParameter = *RequestParameter;\r
1abfa4ce
JY
142 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
143 Status = mTcg2PpSmmVariable->SmmSetVariable (\r
144 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
145 &gEfiTcg2PhysicalPresenceGuid,\r
146 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
147 DataSize,\r
148 &PpData\r
149 );\r
e92ddda2
SZ
150 if (EFI_ERROR (Status)) { \r
151 DEBUG ((EFI_D_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));\r
152 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
153 goto EXIT;\r
154 }\r
1abfa4ce
JY
155 }\r
156\r
edb0fda2 157 if (*OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
1abfa4ce
JY
158 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
159 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
160 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
161 &gEfiTcg2PhysicalPresenceGuid,\r
162 NULL,\r
163 &DataSize,\r
164 &Flags\r
165 );\r
166 if (EFI_ERROR (Status)) {\r
e92ddda2 167 Flags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT | TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_DEFAULT;\r
1abfa4ce 168 }\r
edb0fda2
ZC
169 ReturnCode = Tcg2PpVendorLibSubmitRequestToPreOSFunction (*OperationRequest, Flags.PPFlags, *RequestParameter);\r
170 }\r
171\r
172EXIT:\r
173 //\r
174 // Sync PPRQ/PPRM from PP Variable if PP submission fails\r
175 //\r
176 if (ReturnCode != TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {\r
177 DEBUG ((EFI_D_ERROR, "[TPM2] Submit PP Request failure! Sync PPRQ/PPRM with PP variable.\n", Status));\r
178 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
179 ZeroMem(&PpData, DataSize);\r
180 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
181 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
182 &gEfiTcg2PhysicalPresenceGuid,\r
183 NULL,\r
184 &DataSize,\r
185 &PpData\r
186 );\r
187 *OperationRequest = (UINT32)PpData.PPRequest;\r
188 *RequestParameter = PpData.PPRequestParameter;\r
1abfa4ce
JY
189 }\r
190\r
edb0fda2
ZC
191 return ReturnCode;\r
192}\r
193\r
194/**\r
195 The handler for TPM physical presence function:\r
196 Submit TPM Operation Request to Pre-OS Environment and\r
197 Submit TPM Operation Request to Pre-OS Environment 2.\r
198\r
199 This API should be invoked in OS runtime phase to interface with ACPI method.\r
200\r
201 Caution: This function may receive untrusted input.\r
202 \r
203 @param[in] OperationRequest TPM physical presence operation request.\r
204 @param[in] RequestParameter TPM physical presence operation request parameter.\r
205\r
206 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and\r
207 Submit TPM Operation Request to Pre-OS Environment 2.\r
208**/\r
209UINT32\r
210EFIAPI\r
211Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (\r
212 IN UINT32 OperationRequest,\r
213 IN UINT32 RequestParameter\r
214 )\r
215{\r
216 UINT32 TempOperationRequest;\r
217 UINT32 TempRequestParameter;\r
218\r
219 TempOperationRequest = OperationRequest;\r
220 TempRequestParameter = RequestParameter;\r
221\r
222 return Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx(&TempOperationRequest, &TempRequestParameter);\r
1abfa4ce
JY
223}\r
224\r
225/**\r
226 The handler for TPM physical presence function:\r
227 Get User Confirmation Status for Operation.\r
228\r
229 This API should be invoked in OS runtime phase to interface with ACPI method.\r
230\r
231 Caution: This function may receive untrusted input.\r
232 \r
233 @param[in] OperationRequest TPM physical presence operation request.\r
234\r
235 @return Return Code for Get User Confirmation Status for Operation.\r
236**/\r
237UINT32\r
238EFIAPI\r
239Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (\r
240 IN UINT32 OperationRequest\r
241 )\r
242{\r
252b891b
ED
243 EFI_STATUS Status;\r
244 UINTN DataSize;\r
245 EFI_TCG2_PHYSICAL_PRESENCE PpData;\r
246 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;\r
247 BOOLEAN RequestConfirmed;\r
248 \r
1abfa4ce
JY
249 DEBUG ((EFI_D_INFO, "[TPM2] GetUserConfirmationStatusFunction, Request = %x\n", OperationRequest));\r
250\r
251 //\r
252 // Get the Physical Presence variable\r
253 //\r
254 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
255 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
256 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
257 &gEfiTcg2PhysicalPresenceGuid,\r
258 NULL,\r
259 &DataSize,\r
260 &PpData\r
261 );\r
262 if (EFI_ERROR (Status)) {\r
263 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
264 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;\r
265 }\r
266 //\r
267 // Get the Physical Presence flags\r
268 //\r
269 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
270 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
271 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
272 &gEfiTcg2PhysicalPresenceGuid,\r
273 NULL,\r
274 &DataSize,\r
275 &Flags\r
276 );\r
277 if (EFI_ERROR (Status)) {\r
278 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP flags failure! Status = %r\n", Status));\r
279 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;\r
280 }\r
281\r
282 RequestConfirmed = FALSE;\r
283\r
284 switch (OperationRequest) {\r
285 case TCG2_PHYSICAL_PRESENCE_CLEAR:\r
286 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:\r
287 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:\r
288 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:\r
289 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR) == 0) {\r
290 RequestConfirmed = TRUE;\r
291 }\r
292 break;\r
293\r
294 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:\r
295 RequestConfirmed = TRUE;\r
296 break;\r
297\r
298 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:\r
299 break;\r
300\r
301 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:\r
302 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS) == 0) {\r
303 RequestConfirmed = TRUE;\r
304 }\r
305 break;\r
306\r
307 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:\r
308 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS) == 0) {\r
309 RequestConfirmed = TRUE;\r
310 }\r
311 break;\r
312 \r
313 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:\r
314 RequestConfirmed = TRUE;\r
315 break;\r
316\r
e92ddda2
SZ
317 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID:\r
318 if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) == 0) {\r
319 RequestConfirmed = TRUE;\r
320 }\r
321 break;\r
322\r
323 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID:\r
324 if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) == 0) {\r
325 RequestConfirmed = TRUE;\r
326 }\r
327 break;\r
328\r
329 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE:\r
330 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE:\r
331 RequestConfirmed = TRUE;\r
332 break;\r
333\r
334 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE:\r
335 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE:\r
336 break;\r
337\r
1abfa4ce
JY
338 default:\r
339 if (OperationRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {\r
340 RequestConfirmed = TRUE;\r
341 } else {\r
342 if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
343 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;\r
344 }\r
345 }\r
346 break;\r
347 }\r
348\r
349 if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
350 return Tcg2PpVendorLibGetUserConfirmationStatusFunction (OperationRequest, Flags.PPFlags);\r
351 }\r
352\r
353 if (RequestConfirmed) {\r
354 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_NOT_REQUIRED;\r
355 } else {\r
356 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_REQUIRED;\r
357 } \r
358}\r
359\r
360/**\r
e92ddda2 361 The constructor function locates SmmVariable protocol.\r
1abfa4ce
JY
362 \r
363 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. \r
364\r
365 @param ImageHandle The firmware allocated handle for the EFI image.\r
366 @param SystemTable A pointer to the EFI System Table.\r
367 \r
368 @retval EFI_SUCCESS The constructor successfully added string package.\r
369 @retval Other value The constructor can't add string package.\r
370**/\r
371EFI_STATUS\r
372EFIAPI\r
373Tcg2PhysicalPresenceLibConstructor (\r
374 IN EFI_HANDLE ImageHandle,\r
375 IN EFI_SYSTEM_TABLE *SystemTable\r
376 )\r
377{\r
378 EFI_STATUS Status;\r
379\r
380 //\r
381 // Locate SmmVariableProtocol.\r
382 //\r
383 Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&mTcg2PpSmmVariable);\r
384 ASSERT_EFI_ERROR (Status);\r
385\r
386 return EFI_SUCCESS;\r
387}\r