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