]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.c
SecurityPkg/Tcg2PhysicalPresenceLib: Fix incorrect TCG VER comparision
[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
1a2ad3ba 13Copyright (c) 2015 - 2020, 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
1a2ad3ba 34UINT32 mTcg2PhysicalPresenceFlags;\r
1abfa4ce
JY
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
50 OUT UINT32 *MostRecentRequest,\r
51 OUT UINT32 *Response\r
52 )\r
53{\r
54 EFI_STATUS Status;\r
55 UINTN DataSize;\r
56 EFI_TCG2_PHYSICAL_PRESENCE PpData;\r
57\r
58 DEBUG ((EFI_D_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
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
71 if (EFI_ERROR (Status)) {\r
72 *MostRecentRequest = 0;\r
73 *Response = 0;\r
74 DEBUG ((EFI_D_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
edb0fda2 92\r
3e14edf8
ZC
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
1abfa4ce
JY
95\r
96 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and\r
edb0fda2
ZC
97 Submit TPM Operation Request to Pre-OS Environment 2.\r
98 **/\r
1abfa4ce 99UINT32\r
edb0fda2
ZC
100Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (\r
101 IN OUT UINT32 *OperationRequest,\r
102 IN OUT UINT32 *RequestParameter\r
1abfa4ce
JY
103 )\r
104{\r
105 EFI_STATUS Status;\r
edb0fda2 106 UINT32 ReturnCode;\r
1abfa4ce
JY
107 UINTN DataSize;\r
108 EFI_TCG2_PHYSICAL_PRESENCE PpData;\r
109 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;\r
110\r
edb0fda2
ZC
111 DEBUG ((EFI_D_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", *OperationRequest, *RequestParameter));\r
112 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;\r
1abfa4ce
JY
113\r
114 //\r
115 // Get the Physical Presence variable\r
116 //\r
117 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
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
125 if (EFI_ERROR (Status)) {\r
126 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
edb0fda2
ZC
127 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
128 goto EXIT;\r
1abfa4ce
JY
129 }\r
130\r
252b891b 131 if ((*OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&\r
e92ddda2 132 (*OperationRequest < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN) ) {\r
edb0fda2
ZC
133 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;\r
134 goto EXIT;\r
1abfa4ce
JY
135 }\r
136\r
edb0fda2
ZC
137 if ((PpData.PPRequest != *OperationRequest) ||\r
138 (PpData.PPRequestParameter != *RequestParameter)) {\r
139 PpData.PPRequest = (UINT8)*OperationRequest;\r
140 PpData.PPRequestParameter = *RequestParameter;\r
1abfa4ce
JY
141 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
142 Status = mTcg2PpSmmVariable->SmmSetVariable (\r
143 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
144 &gEfiTcg2PhysicalPresenceGuid,\r
145 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
146 DataSize,\r
147 &PpData\r
148 );\r
b3548d32 149 if (EFI_ERROR (Status)) {\r
e92ddda2
SZ
150 DEBUG ((EFI_D_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));\r
151 ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
152 goto EXIT;\r
153 }\r
1abfa4ce
JY
154 }\r
155\r
edb0fda2 156 if (*OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
1abfa4ce
JY
157 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
158 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
159 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
160 &gEfiTcg2PhysicalPresenceGuid,\r
161 NULL,\r
162 &DataSize,\r
163 &Flags\r
164 );\r
165 if (EFI_ERROR (Status)) {\r
1a2ad3ba 166 Flags.PPFlags = mTcg2PhysicalPresenceFlags;\r
1abfa4ce 167 }\r
edb0fda2
ZC
168 ReturnCode = Tcg2PpVendorLibSubmitRequestToPreOSFunction (*OperationRequest, Flags.PPFlags, *RequestParameter);\r
169 }\r
170\r
171EXIT:\r
172 //\r
173 // Sync PPRQ/PPRM from PP Variable if PP submission fails\r
174 //\r
175 if (ReturnCode != TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {\r
176 DEBUG ((EFI_D_ERROR, "[TPM2] Submit PP Request failure! Sync PPRQ/PPRM with PP variable.\n", Status));\r
177 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
178 ZeroMem(&PpData, DataSize);\r
179 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
180 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
181 &gEfiTcg2PhysicalPresenceGuid,\r
182 NULL,\r
183 &DataSize,\r
184 &PpData\r
185 );\r
186 *OperationRequest = (UINT32)PpData.PPRequest;\r
187 *RequestParameter = PpData.PPRequestParameter;\r
1abfa4ce
JY
188 }\r
189\r
edb0fda2
ZC
190 return ReturnCode;\r
191}\r
192\r
193/**\r
194 The handler for TPM physical presence function:\r
195 Submit TPM Operation Request to Pre-OS Environment and\r
196 Submit TPM Operation Request to Pre-OS Environment 2.\r
197\r
198 This API should be invoked in OS runtime phase to interface with ACPI method.\r
199\r
200 Caution: This function may receive untrusted input.\r
b3548d32 201\r
edb0fda2
ZC
202 @param[in] OperationRequest TPM physical presence operation request.\r
203 @param[in] RequestParameter TPM physical presence operation request parameter.\r
204\r
205 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and\r
206 Submit TPM Operation Request to Pre-OS Environment 2.\r
207**/\r
208UINT32\r
209EFIAPI\r
210Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (\r
211 IN UINT32 OperationRequest,\r
212 IN UINT32 RequestParameter\r
213 )\r
214{\r
215 UINT32 TempOperationRequest;\r
216 UINT32 TempRequestParameter;\r
217\r
218 TempOperationRequest = OperationRequest;\r
219 TempRequestParameter = RequestParameter;\r
220\r
221 return Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx(&TempOperationRequest, &TempRequestParameter);\r
1abfa4ce
JY
222}\r
223\r
224/**\r
225 The handler for TPM physical presence function:\r
226 Get User Confirmation Status for Operation.\r
227\r
228 This API should be invoked in OS runtime phase to interface with ACPI method.\r
229\r
230 Caution: This function may receive untrusted input.\r
b3548d32 231\r
1abfa4ce
JY
232 @param[in] OperationRequest TPM physical presence operation request.\r
233\r
234 @return Return Code for Get User Confirmation Status for Operation.\r
235**/\r
236UINT32\r
237EFIAPI\r
238Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (\r
239 IN UINT32 OperationRequest\r
240 )\r
241{\r
252b891b
ED
242 EFI_STATUS Status;\r
243 UINTN DataSize;\r
244 EFI_TCG2_PHYSICAL_PRESENCE PpData;\r
245 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;\r
246 BOOLEAN RequestConfirmed;\r
b3548d32 247\r
1abfa4ce
JY
248 DEBUG ((EFI_D_INFO, "[TPM2] GetUserConfirmationStatusFunction, Request = %x\n", OperationRequest));\r
249\r
250 //\r
251 // Get the Physical Presence variable\r
252 //\r
253 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
254 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
255 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
256 &gEfiTcg2PhysicalPresenceGuid,\r
257 NULL,\r
258 &DataSize,\r
259 &PpData\r
260 );\r
261 if (EFI_ERROR (Status)) {\r
262 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
263 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;\r
264 }\r
265 //\r
266 // Get the Physical Presence flags\r
267 //\r
268 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
269 Status = mTcg2PpSmmVariable->SmmGetVariable (\r
270 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
271 &gEfiTcg2PhysicalPresenceGuid,\r
272 NULL,\r
273 &DataSize,\r
274 &Flags\r
275 );\r
276 if (EFI_ERROR (Status)) {\r
277 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP flags failure! Status = %r\n", Status));\r
278 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;\r
279 }\r
280\r
281 RequestConfirmed = FALSE;\r
282\r
283 switch (OperationRequest) {\r
284 case TCG2_PHYSICAL_PRESENCE_CLEAR:\r
285 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:\r
286 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:\r
287 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:\r
288 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR) == 0) {\r
289 RequestConfirmed = TRUE;\r
290 }\r
291 break;\r
292\r
265e5c82 293 case TCG2_PHYSICAL_PRESENCE_NO_ACTION:\r
1abfa4ce
JY
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
b3548d32 312\r
1abfa4ce
JY
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 338 default:\r
3d1872b7 339 if (!mIsTcg2PPVerLowerThan_1_3) {\r
84391f57
ZC
340 if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
341 //\r
342 // TCG2 PP1.3 spec defined operations that are reserved or un-implemented\r
343 //\r
344 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;\r
345 }\r
346 } else {\r
347 //\r
348 // TCG PP lower than 1.3. (1.0, 1.1, 1.2)\r
349 //\r
350 if (OperationRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {\r
351 RequestConfirmed = TRUE;\r
352 } else if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
353 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;\r
354 }\r
1abfa4ce
JY
355 }\r
356 break;\r
357 }\r
358\r
359 if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
360 return Tcg2PpVendorLibGetUserConfirmationStatusFunction (OperationRequest, Flags.PPFlags);\r
361 }\r
362\r
363 if (RequestConfirmed) {\r
364 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_NOT_REQUIRED;\r
365 } else {\r
366 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_REQUIRED;\r
b3548d32 367 }\r
1abfa4ce
JY
368}\r
369\r
370/**\r
e92ddda2 371 The constructor function locates SmmVariable protocol.\r
b3548d32
LG
372\r
373 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.\r
1abfa4ce
JY
374\r
375 @param ImageHandle The firmware allocated handle for the EFI image.\r
376 @param SystemTable A pointer to the EFI System Table.\r
b3548d32 377\r
1abfa4ce
JY
378 @retval EFI_SUCCESS The constructor successfully added string package.\r
379 @retval Other value The constructor can't add string package.\r
380**/\r
381EFI_STATUS\r
382EFIAPI\r
383Tcg2PhysicalPresenceLibConstructor (\r
384 IN EFI_HANDLE ImageHandle,\r
385 IN EFI_SYSTEM_TABLE *SystemTable\r
386 )\r
387{\r
388 EFI_STATUS Status;\r
389\r
709b1639 390 if (AsciiStrnCmp(PP_INF_VERSION_1_2, (CHAR8 *)PcdGetPtr(PcdTcgPhysicalPresenceInterfaceVer), sizeof(PP_INF_VERSION_1_2) - 1) >= 0) {\r
84391f57
ZC
391 mIsTcg2PPVerLowerThan_1_3 = TRUE;\r
392 }\r
393\r
1abfa4ce
JY
394 //\r
395 // Locate SmmVariableProtocol.\r
396 //\r
397 Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&mTcg2PpSmmVariable);\r
398 ASSERT_EFI_ERROR (Status);\r
399\r
1a2ad3ba
MC
400 mTcg2PhysicalPresenceFlags = PcdGet32(PcdTcg2PhysicalPresenceFlags);\r
401\r
1abfa4ce
JY
402 return EFI_SUCCESS;\r
403}\r