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