]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.c
MdeModulePkg/DxeNetLib: Allow the IPv4/prefix case when AsciiStrToIp4
[mirror_edk2.git] / SecurityPkg / Library / DxeTcg2PhysicalPresenceLib / DxeTcg2PhysicalPresenceLib.c
CommitLineData
1abfa4ce
JY
1/** @file\r
2 Execute pending TPM2 requests from OS or BIOS.\r
3\r
4 Caution: This module requires additional review when modified.\r
5 This driver will have external input - variable.\r
6 This external input must be validated carefully to avoid security issue.\r
7\r
8 Tpm2ExecutePendingTpmRequest() will receive untrusted input and do validation.\r
9\r
6d7c4a25 10Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>\r
1abfa4ce
JY
11This program and the accompanying materials \r
12are licensed and made available under the terms and conditions of the BSD License \r
13which accompanies this distribution. The full text of the license may be found at \r
14http://opensource.org/licenses/bsd-license.php\r
15\r
16THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
17WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
18\r
19**/\r
20\r
21#include <PiDxe.h>\r
22\r
23#include <Protocol/Tcg2Protocol.h>\r
24#include <Protocol/VariableLock.h>\r
25#include <Library/DebugLib.h>\r
26#include <Library/BaseMemoryLib.h>\r
27#include <Library/UefiRuntimeServicesTableLib.h>\r
28#include <Library/UefiDriverEntryPoint.h>\r
29#include <Library/UefiBootServicesTableLib.h>\r
30#include <Library/UefiLib.h>\r
31#include <Library/MemoryAllocationLib.h>\r
32#include <Library/PrintLib.h>\r
33#include <Library/HiiLib.h>\r
34#include <Library/HobLib.h>\r
35#include <Guid/EventGroup.h>\r
36#include <Guid/Tcg2PhysicalPresenceData.h>\r
37#include <Library/Tpm2CommandLib.h>\r
38#include <Library/Tcg2PhysicalPresenceLib.h>\r
39#include <Library/Tcg2PpVendorLib.h>\r
d6b02b79 40#include <Library/TcgPhysicalPresenceStorageLib.h>\r
1abfa4ce
JY
41\r
42#define CONFIRM_BUFFER_SIZE 4096\r
43\r
44EFI_HII_HANDLE mTcg2PpStringPackHandle;\r
45\r
46/**\r
47 Get string by string id from HII Interface.\r
48\r
49 @param[in] Id String ID.\r
50\r
51 @retval CHAR16 * String from ID.\r
52 @retval NULL If error occurs.\r
53\r
54**/\r
55CHAR16 *\r
56Tcg2PhysicalPresenceGetStringById (\r
57 IN EFI_STRING_ID Id\r
58 )\r
59{\r
60 return HiiGetString (mTcg2PpStringPackHandle, Id, NULL);\r
61}\r
62\r
63/**\r
64 Send ClearControl and Clear command to TPM.\r
65\r
66 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.\r
67\r
68 @retval EFI_SUCCESS Operation completed successfully.\r
69 @retval EFI_TIMEOUT The register can't run into the expected status in time.\r
70 @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.\r
71 @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
72\r
73**/\r
74EFI_STATUS\r
75EFIAPI\r
76Tpm2CommandClear (\r
77 IN TPM2B_AUTH *PlatformAuth OPTIONAL\r
78 )\r
79{\r
80 EFI_STATUS Status;\r
81 TPMS_AUTH_COMMAND *AuthSession;\r
82 TPMS_AUTH_COMMAND LocalAuthSession;\r
83\r
84 if (PlatformAuth == NULL) {\r
85 AuthSession = NULL;\r
86 } else {\r
87 AuthSession = &LocalAuthSession;\r
88 ZeroMem (&LocalAuthSession, sizeof(LocalAuthSession));\r
89 LocalAuthSession.sessionHandle = TPM_RS_PW;\r
90 LocalAuthSession.hmac.size = PlatformAuth->size;\r
91 CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);\r
92 }\r
93\r
94 DEBUG ((EFI_D_INFO, "Tpm2ClearControl ... \n"));\r
95 Status = Tpm2ClearControl (TPM_RH_PLATFORM, AuthSession, NO);\r
96 DEBUG ((EFI_D_INFO, "Tpm2ClearControl - %r\n", Status));\r
97 if (EFI_ERROR (Status)) {\r
98 goto Done;\r
99 }\r
100 DEBUG ((EFI_D_INFO, "Tpm2Clear ... \n"));\r
101 Status = Tpm2Clear (TPM_RH_PLATFORM, AuthSession);\r
102 DEBUG ((EFI_D_INFO, "Tpm2Clear - %r\n", Status));\r
103\r
104Done:\r
105 ZeroMem (&LocalAuthSession.hmac, sizeof(LocalAuthSession.hmac));\r
106 return Status;\r
107}\r
108\r
1abfa4ce
JY
109/**\r
110 Change EPS.\r
111\r
112 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.\r
113 \r
114 @retval EFI_SUCCESS Operation completed successfully.\r
115**/\r
116EFI_STATUS\r
117Tpm2CommandChangeEps (\r
118 IN TPM2B_AUTH *PlatformAuth OPTIONAL\r
119 )\r
120{\r
121 EFI_STATUS Status;\r
122 TPMS_AUTH_COMMAND *AuthSession;\r
123 TPMS_AUTH_COMMAND LocalAuthSession;\r
124\r
125 if (PlatformAuth == NULL) {\r
126 AuthSession = NULL;\r
127 } else {\r
128 AuthSession = &LocalAuthSession;\r
129 ZeroMem (&LocalAuthSession, sizeof(LocalAuthSession));\r
130 LocalAuthSession.sessionHandle = TPM_RS_PW;\r
131 LocalAuthSession.hmac.size = PlatformAuth->size;\r
132 CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);\r
133 }\r
134\r
135 Status = Tpm2ChangeEPS (TPM_RH_PLATFORM, AuthSession);\r
136 DEBUG ((EFI_D_INFO, "Tpm2ChangeEPS - %r\n", Status));\r
c31313da
JY
137\r
138 ZeroMem(&LocalAuthSession.hmac, sizeof(LocalAuthSession.hmac));\r
1abfa4ce
JY
139 return Status;\r
140}\r
141\r
142/**\r
143 Execute physical presence operation requested by the OS.\r
144\r
145 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.\r
146 @param[in] CommandCode Physical presence operation value.\r
147 @param[in] CommandParameter Physical presence operation parameter.\r
148 @param[in, out] PpiFlags The physical presence interface flags.\r
149 \r
150 @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Unknown physical presence operation.\r
151 @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Error occurred during sending command to TPM or \r
152 receiving response from TPM.\r
153 @retval Others Return code from the TPM device after command execution.\r
154**/\r
155UINT32\r
156Tcg2ExecutePhysicalPresence (\r
157 IN TPM2B_AUTH *PlatformAuth, OPTIONAL\r
158 IN UINT32 CommandCode,\r
159 IN UINT32 CommandParameter,\r
160 IN OUT EFI_TCG2_PHYSICAL_PRESENCE_FLAGS *PpiFlags\r
161 )\r
162{\r
163 EFI_STATUS Status;\r
07cdba18
JY
164 EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap;\r
165 UINT32 ActivePcrBanks;\r
1abfa4ce 166\r
07cdba18 167 Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePcrBanks);\r
1abfa4ce
JY
168 ASSERT_EFI_ERROR (Status);\r
169\r
170 switch (CommandCode) {\r
171 case TCG2_PHYSICAL_PRESENCE_CLEAR:\r
172 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:\r
173 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:\r
174 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:\r
175 Status = Tpm2CommandClear (PlatformAuth);\r
176 if (EFI_ERROR (Status)) {\r
177 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
178 } else {\r
179 return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
180 }\r
181\r
182 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:\r
183 PpiFlags->PPFlags |= TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR;\r
184 return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
185\r
186 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:\r
187 PpiFlags->PPFlags &= ~TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR;\r
188 return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
189\r
190 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:\r
07cdba18 191 Status = Tpm2PcrAllocateBanks (PlatformAuth, TpmHashAlgorithmBitmap, CommandParameter);\r
1abfa4ce
JY
192 if (EFI_ERROR (Status)) {\r
193 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
194 } else {\r
195 return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
196 }\r
197\r
198 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:\r
199 Status = Tpm2CommandChangeEps (PlatformAuth);\r
200 if (EFI_ERROR (Status)) {\r
201 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
202 } else {\r
203 return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
204 }\r
205\r
206 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:\r
07cdba18 207 Status = Tpm2PcrAllocateBanks (PlatformAuth, TpmHashAlgorithmBitmap, TpmHashAlgorithmBitmap);\r
1abfa4ce
JY
208 if (EFI_ERROR (Status)) {\r
209 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
210 } else {\r
211 return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
212 }\r
213\r
214 default:\r
215 if (CommandCode <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {\r
216 return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
217 } else {\r
218 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
219 }\r
220 }\r
221}\r
222\r
223\r
224/**\r
225 Read the specified key for user confirmation.\r
226\r
227 @param[in] CautionKey If true, F12 is used as confirm key;\r
228 If false, F10 is used as confirm key.\r
229\r
230 @retval TRUE User confirmed the changes by input.\r
231 @retval FALSE User discarded the changes.\r
232**/\r
233BOOLEAN\r
234Tcg2ReadUserKey (\r
235 IN BOOLEAN CautionKey\r
236 )\r
237{\r
238 EFI_STATUS Status;\r
239 EFI_INPUT_KEY Key;\r
240 UINT16 InputKey;\r
241 \r
242 InputKey = 0; \r
243 do {\r
244 Status = gBS->CheckEvent (gST->ConIn->WaitForKey);\r
245 if (!EFI_ERROR (Status)) {\r
246 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
247 if (Key.ScanCode == SCAN_ESC) {\r
248 InputKey = Key.ScanCode;\r
249 }\r
250 if ((Key.ScanCode == SCAN_F10) && !CautionKey) {\r
251 InputKey = Key.ScanCode;\r
252 }\r
253 if ((Key.ScanCode == SCAN_F12) && CautionKey) {\r
254 InputKey = Key.ScanCode;\r
255 }\r
256 } \r
257 } while (InputKey == 0);\r
258\r
259 if (InputKey != SCAN_ESC) {\r
260 return TRUE;\r
261 }\r
262 \r
263 return FALSE;\r
264}\r
265\r
266/**\r
267 Fill Buffer With BootHashAlg.\r
268\r
269 @param[in] Buffer Buffer to be filled.\r
270 @param[in] BufferSize Size of buffer.\r
271 @param[in] BootHashAlg BootHashAlg.\r
272\r
273**/\r
274VOID\r
275Tcg2FillBufferWithBootHashAlg (\r
276 IN UINT16 *Buffer,\r
277 IN UINTN BufferSize,\r
278 IN UINT32 BootHashAlg\r
279 )\r
280{\r
281 Buffer[0] = 0;\r
282 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
283 if (Buffer[0] != 0) {\r
284 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
285 }\r
286 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA1", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
287 }\r
288 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
289 if (Buffer[0] != 0) {\r
290 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
291 }\r
292 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
293 }\r
294 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
295 if (Buffer[0] != 0) {\r
296 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
297 }\r
298 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA384", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
299 }\r
300 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
301 if (Buffer[0] != 0) {\r
302 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
303 }\r
304 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA512", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
305 }\r
306 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
307 if (Buffer[0] != 0) {\r
308 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
309 }\r
310 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SM3_256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
311 }\r
312}\r
313\r
314/**\r
315 Display the confirm text and get user confirmation.\r
316\r
317 @param[in] TpmPpCommand The requested TPM physical presence command.\r
318 @param[in] TpmPpCommandParameter The requested TPM physical presence command parameter.\r
319\r
320 @retval TRUE The user has confirmed the changes.\r
321 @retval FALSE The user doesn't confirm the changes.\r
322**/\r
323BOOLEAN\r
324Tcg2UserConfirm (\r
325 IN UINT32 TpmPpCommand,\r
326 IN UINT32 TpmPpCommandParameter\r
327 )\r
328{\r
329 CHAR16 *ConfirmText;\r
330 CHAR16 *TmpStr1;\r
331 CHAR16 *TmpStr2; \r
332 UINTN BufSize;\r
333 BOOLEAN CautionKey;\r
334 BOOLEAN NoPpiInfo;\r
335 UINT16 Index;\r
336 CHAR16 DstStr[81];\r
337 CHAR16 TempBuffer[1024];\r
338 CHAR16 TempBuffer2[1024];\r
339 EFI_TCG2_PROTOCOL *Tcg2Protocol;\r
340 EFI_TCG2_BOOT_SERVICE_CAPABILITY ProtocolCapability;\r
341 UINT32 CurrentPCRBanks;\r
342 EFI_STATUS Status;\r
343\r
344 Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &Tcg2Protocol);\r
345 ASSERT_EFI_ERROR (Status);\r
346\r
347 ProtocolCapability.Size = sizeof(ProtocolCapability);\r
348 Status = Tcg2Protocol->GetCapability (\r
349 Tcg2Protocol,\r
350 &ProtocolCapability\r
351 );\r
352 ASSERT_EFI_ERROR (Status);\r
353\r
354 Status = Tcg2Protocol->GetActivePcrBanks (\r
355 Tcg2Protocol,\r
356 &CurrentPCRBanks\r
357 );\r
358 ASSERT_EFI_ERROR (Status);\r
359 \r
360 TmpStr2 = NULL;\r
361 CautionKey = FALSE;\r
362 NoPpiInfo = FALSE;\r
363 BufSize = CONFIRM_BUFFER_SIZE;\r
364 ConfirmText = AllocateZeroPool (BufSize);\r
365 ASSERT (ConfirmText != NULL);\r
366\r
367 switch (TpmPpCommand) {\r
368\r
369 case TCG2_PHYSICAL_PRESENCE_CLEAR:\r
370 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:\r
371 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:\r
372 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:\r
373 CautionKey = TRUE;\r
374 TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));\r
375\r
376 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
377 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
378 FreePool (TmpStr1);\r
379\r
380 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));\r
381 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
382 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
383 FreePool (TmpStr1); \r
384\r
385 break;\r
386\r
387 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:\r
388 CautionKey = TRUE;\r
389 NoPpiInfo = TRUE;\r
390 TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));\r
391\r
392 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));\r
393 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
394 FreePool (TmpStr1);\r
395\r
396 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_CLEAR));\r
397 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
398 FreePool (TmpStr1);\r
399\r
400 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));\r
401 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
402 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
403 FreePool (TmpStr1); \r
404\r
405 break;\r
406\r
407 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:\r
408 CautionKey = TRUE;\r
409 TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_SET_PCR_BANKS));\r
410\r
411 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
412 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
413 FreePool (TmpStr1);\r
414\r
415 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_1));\r
416 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
417 FreePool (TmpStr1); \r
418\r
419 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_2));\r
420 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
421 FreePool (TmpStr1); \r
422\r
423 Tcg2FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), TpmPpCommandParameter);\r
424 Tcg2FillBufferWithBootHashAlg (TempBuffer2, sizeof(TempBuffer2), CurrentPCRBanks);\r
425\r
426 TmpStr1 = AllocateZeroPool (BufSize);\r
427 ASSERT (TmpStr1 != NULL);\r
428 UnicodeSPrint (TmpStr1, BufSize, L"Current PCRBanks is 0x%x. (%s)\nNew PCRBanks is 0x%x. (%s)\n", CurrentPCRBanks, TempBuffer2, TpmPpCommandParameter, TempBuffer);\r
429\r
430 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
431 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
432 FreePool (TmpStr1); \r
433\r
434 break;\r
435\r
436 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:\r
437 CautionKey = TRUE;\r
438 TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CHANGE_EPS));\r
439\r
440 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
441 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
442 FreePool (TmpStr1);\r
443\r
444 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_1));\r
445 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
446 FreePool (TmpStr1); \r
447 \r
448 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_2));\r
449 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
450 FreePool (TmpStr1); \r
451\r
452 break;\r
453 \r
454\r
455 default:\r
456 ;\r
457 }\r
458\r
459 if (TmpStr2 == NULL) {\r
460 FreePool (ConfirmText);\r
461 return FALSE;\r
462 }\r
463\r
464 if (TpmPpCommand < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN) {\r
465 if (CautionKey) {\r
466 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));\r
467 } else {\r
468 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));\r
469 }\r
470 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
471 FreePool (TmpStr1);\r
472\r
473 if (NoPpiInfo) {\r
474 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));\r
475 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
476 FreePool (TmpStr1);\r
477 }\r
478\r
479 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY));\r
480 } else {\r
481 if (CautionKey) {\r
482 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_CAUTION_KEY));\r
483 } else {\r
484 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ACCEPT_KEY));\r
485 }\r
486 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
487 FreePool (TmpStr1);\r
488\r
489 if (NoPpiInfo) {\r
490 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_NO_PPI_INFO));\r
491 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
492 FreePool (TmpStr1);\r
493 }\r
494\r
495 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_REJECT_KEY));\r
496 }\r
497 BufSize -= StrSize (ConfirmText);\r
498 UnicodeSPrint (ConfirmText + StrLen (ConfirmText), BufSize, TmpStr1, TmpStr2);\r
499\r
500 DstStr[80] = L'\0';\r
501 for (Index = 0; Index < StrLen (ConfirmText); Index += 80) {\r
502 StrnCpyS (DstStr, sizeof (DstStr) / sizeof (CHAR16), ConfirmText + Index, sizeof (DstStr) / sizeof (CHAR16) - 1); \r
503 Print (DstStr); \r
504 }\r
505 \r
506 FreePool (TmpStr1);\r
507 FreePool (TmpStr2);\r
508 FreePool (ConfirmText);\r
509\r
510 if (Tcg2ReadUserKey (CautionKey)) {\r
511 return TRUE;\r
512 }\r
513\r
514 return FALSE; \r
515}\r
516\r
517/**\r
518 Check if there is a valid physical presence command request. Also updates parameter value \r
519 to whether the requested physical presence command already confirmed by user\r
520 \r
521 @param[in] TcgPpData EFI Tcg2 Physical Presence request data. \r
522 @param[in] Flags The physical presence interface flags.\r
523 @param[out] RequestConfirmed If the physical presence operation command required user confirm from UI.\r
524 True, it indicates the command doesn't require user confirm, or already confirmed \r
525 in last boot cycle by user.\r
526 False, it indicates the command need user confirm from UI.\r
527\r
528 @retval TRUE Physical Presence operation command is valid.\r
529 @retval FALSE Physical Presence operation command is invalid.\r
530\r
531**/\r
532BOOLEAN\r
533Tcg2HaveValidTpmRequest (\r
534 IN EFI_TCG2_PHYSICAL_PRESENCE *TcgPpData,\r
535 IN EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags,\r
536 OUT BOOLEAN *RequestConfirmed\r
537 )\r
538{\r
539 BOOLEAN IsRequestValid;\r
540\r
541 *RequestConfirmed = FALSE;\r
542\r
543 switch (TcgPpData->PPRequest) {\r
544 case TCG2_PHYSICAL_PRESENCE_NO_ACTION:\r
545 *RequestConfirmed = TRUE;\r
546 return TRUE;\r
547\r
548 case TCG2_PHYSICAL_PRESENCE_CLEAR:\r
549 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:\r
550 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:\r
551 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:\r
552 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR) == 0) {\r
553 *RequestConfirmed = TRUE;\r
554 }\r
555 break;\r
556\r
557 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:\r
558 *RequestConfirmed = TRUE;\r
559 break;\r
560\r
561 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:\r
562 break;\r
563\r
564 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:\r
565 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS) == 0) {\r
566 *RequestConfirmed = TRUE;\r
567 }\r
568 break;\r
569\r
570 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:\r
571 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS) == 0) {\r
572 *RequestConfirmed = TRUE;\r
573 }\r
574 break;\r
575 \r
576 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:\r
577 *RequestConfirmed = TRUE;\r
578 break;\r
579\r
580 default:\r
581 if (TcgPpData->PPRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
582 IsRequestValid = Tcg2PpVendorLibHasValidRequest (TcgPpData->PPRequest, Flags.PPFlags, RequestConfirmed);\r
583 if (!IsRequestValid) {\r
584 return FALSE;\r
585 } else {\r
586 break;\r
587 }\r
588 } else {\r
589 //\r
590 // Wrong Physical Presence command\r
591 //\r
592 return FALSE;\r
593 }\r
594 }\r
595\r
596 if ((Flags.PPFlags & TCG2_LIB_PP_FLAG_RESET_TRACK) != 0) {\r
597 //\r
598 // It had been confirmed in last boot, it doesn't need confirm again.\r
599 //\r
600 *RequestConfirmed = TRUE;\r
601 }\r
602\r
603 //\r
604 // Physical Presence command is correct\r
605 //\r
606 return TRUE;\r
607}\r
608\r
609\r
610/**\r
611 Check and execute the requested physical presence command.\r
612\r
613 Caution: This function may receive untrusted input.\r
614 TcgPpData variable is external input, so this function will validate\r
615 its data structure to be valid value.\r
616\r
617 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.\r
618 @param[in] TcgPpData Point to the physical presence NV variable.\r
619 @param[in] Flags The physical presence interface flags.\r
620**/\r
621VOID\r
622Tcg2ExecutePendingTpmRequest (\r
623 IN TPM2B_AUTH *PlatformAuth, OPTIONAL\r
624 IN EFI_TCG2_PHYSICAL_PRESENCE *TcgPpData,\r
625 IN EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags\r
626 )\r
627{\r
628 EFI_STATUS Status;\r
629 UINTN DataSize;\r
630 BOOLEAN RequestConfirmed;\r
631 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS NewFlags;\r
632 BOOLEAN ResetRequired;\r
633 UINT32 NewPPFlags;\r
634\r
635 if (TcgPpData->PPRequest == TCG2_PHYSICAL_PRESENCE_NO_ACTION) {\r
636 //\r
637 // No operation request\r
638 //\r
639 return;\r
640 }\r
641\r
642 if (!Tcg2HaveValidTpmRequest(TcgPpData, Flags, &RequestConfirmed)) {\r
643 //\r
644 // Invalid operation request.\r
645 //\r
646 if (TcgPpData->PPRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {\r
647 TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
648 } else {\r
649 TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
650 }\r
651 TcgPpData->LastPPRequest = TcgPpData->PPRequest;\r
652 TcgPpData->PPRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;\r
653 TcgPpData->PPRequestParameter = 0;\r
654\r
655 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
656 Status = gRT->SetVariable (\r
657 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
658 &gEfiTcg2PhysicalPresenceGuid,\r
659 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
660 DataSize,\r
661 TcgPpData\r
662 );\r
663 return;\r
664 }\r
665\r
666 ResetRequired = FALSE;\r
667 if (TcgPpData->PPRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
668 NewFlags = Flags;\r
669 NewPPFlags = NewFlags.PPFlags;\r
670 TcgPpData->PPResponse = Tcg2PpVendorLibExecutePendingRequest (PlatformAuth, TcgPpData->PPRequest, &NewPPFlags, &ResetRequired);\r
671 NewFlags.PPFlags = NewPPFlags;\r
672 } else {\r
673 if (!RequestConfirmed) {\r
674 //\r
675 // Print confirm text and wait for approval. \r
676 //\r
677 RequestConfirmed = Tcg2UserConfirm (TcgPpData->PPRequest, TcgPpData->PPRequestParameter);\r
678 }\r
679\r
680 //\r
681 // Execute requested physical presence command\r
682 //\r
683 TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_USER_ABORT;\r
684 NewFlags = Flags;\r
685 if (RequestConfirmed) {\r
686 TcgPpData->PPResponse = Tcg2ExecutePhysicalPresence (\r
687 PlatformAuth,\r
688 TcgPpData->PPRequest, \r
689 TcgPpData->PPRequestParameter, \r
690 &NewFlags\r
691 );\r
692 }\r
693 }\r
694\r
695 //\r
696 // Save the flags if it is updated.\r
697 //\r
698 if (CompareMem (&Flags, &NewFlags, sizeof(EFI_TCG2_PHYSICAL_PRESENCE_FLAGS)) != 0) {\r
699 Status = gRT->SetVariable (\r
700 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
701 &gEfiTcg2PhysicalPresenceGuid,\r
702 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
703 sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS),\r
704 &NewFlags\r
705 ); \r
706 }\r
707\r
708 //\r
709 // Clear request\r
710 //\r
711 if ((NewFlags.PPFlags & TCG2_LIB_PP_FLAG_RESET_TRACK) == 0) {\r
712 TcgPpData->LastPPRequest = TcgPpData->PPRequest;\r
713 TcgPpData->PPRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION; \r
714 TcgPpData->PPRequestParameter = 0;\r
715 }\r
716\r
717 //\r
718 // Save changes\r
719 //\r
720 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
721 Status = gRT->SetVariable (\r
722 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
723 &gEfiTcg2PhysicalPresenceGuid,\r
724 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
725 DataSize,\r
726 TcgPpData\r
727 );\r
728 if (EFI_ERROR (Status)) {\r
729 return;\r
730 }\r
731\r
732 if (TcgPpData->PPResponse == TCG_PP_OPERATION_RESPONSE_USER_ABORT) {\r
733 return;\r
734 }\r
735\r
736 //\r
737 // Reset system to make new TPM settings in effect\r
738 //\r
739 switch (TcgPpData->LastPPRequest) {\r
740 case TCG2_PHYSICAL_PRESENCE_CLEAR:\r
741 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:\r
742 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:\r
743 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:\r
744 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:\r
745 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:\r
746 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:\r
747 break;\r
748\r
749 default:\r
750 if (TcgPpData->LastPPRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
751 if (ResetRequired) {\r
752 break;\r
753 } else {\r
754 return ;\r
755 }\r
756 }\r
757 if (TcgPpData->PPRequest != TCG2_PHYSICAL_PRESENCE_NO_ACTION) {\r
758 break;\r
759 }\r
760 return;\r
761 }\r
762\r
763 Print (L"Rebooting system to make TPM2 settings in effect\n");\r
764 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
765 ASSERT (FALSE); \r
766}\r
767\r
768/**\r
769 Check and execute the pending TPM request.\r
770\r
771 The TPM request may come from OS or BIOS. This API will display request information and wait \r
772 for user confirmation if TPM request exists. The TPM request will be sent to TPM device after\r
773 the TPM request is confirmed, and one or more reset may be required to make TPM request to \r
774 take effect.\r
775 \r
776 This API should be invoked after console in and console out are all ready as they are required\r
777 to display request information and get user input to confirm the request. \r
778\r
779 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.\r
780**/\r
781VOID\r
782EFIAPI\r
783Tcg2PhysicalPresenceLibProcessRequest (\r
784 IN TPM2B_AUTH *PlatformAuth OPTIONAL\r
785 )\r
786{\r
787 EFI_STATUS Status;\r
788 UINTN DataSize;\r
789 EFI_TCG2_PHYSICAL_PRESENCE TcgPpData;\r
790 EFI_TCG2_PROTOCOL *Tcg2Protocol;\r
791 EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol;\r
792 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags;\r
793\r
d6b02b79
ED
794 //\r
795 // Process the storage related action first.\r
796 //\r
797 TcgPhysicalPresenceStorageLibProcessRequest();\r
798\r
1abfa4ce
JY
799 Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &Tcg2Protocol);\r
800 if (EFI_ERROR (Status)) {\r
801 return ;\r
802 }\r
803 \r
804 //\r
805 // Check S4 resume\r
806 //\r
807 if (GetBootModeHob () == BOOT_ON_S4_RESUME) {\r
808 DEBUG ((EFI_D_INFO, "S4 Resume, Skip TPM PP process!\n"));\r
809 return ;\r
810 }\r
811\r
812 mTcg2PpStringPackHandle = HiiAddPackages (&gEfiTcg2PhysicalPresenceGuid, gImageHandle, DxeTcg2PhysicalPresenceLibStrings, NULL);\r
813 ASSERT (mTcg2PpStringPackHandle != NULL);\r
814\r
815 //\r
816 // Initialize physical presence flags.\r
817 //\r
818 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
819 Status = gRT->GetVariable (\r
820 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
821 &gEfiTcg2PhysicalPresenceGuid,\r
822 NULL,\r
823 &DataSize,\r
824 &PpiFlags\r
825 );\r
826 if (EFI_ERROR (Status)) {\r
827 PpiFlags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT;\r
828 Status = gRT->SetVariable (\r
829 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
830 &gEfiTcg2PhysicalPresenceGuid,\r
831 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
832 sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS),\r
833 &PpiFlags\r
834 );\r
835 if (EFI_ERROR (Status)) {\r
836 DEBUG ((EFI_D_ERROR, "[TPM2] Set physical presence flag failed, Status = %r\n", Status));\r
837 return ;\r
838 }\r
839 }\r
840 DEBUG ((EFI_D_INFO, "[TPM2] PpiFlags = %x\n", PpiFlags.PPFlags));\r
841\r
842 //\r
843 // This flags variable controls whether physical presence is required for TPM command. \r
844 // It should be protected from malicious software. We set it as read-only variable here.\r
845 //\r
846 Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);\r
847 if (!EFI_ERROR (Status)) {\r
848 Status = VariableLockProtocol->RequestToLock (\r
849 VariableLockProtocol,\r
850 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
851 &gEfiTcg2PhysicalPresenceGuid\r
852 );\r
853 if (EFI_ERROR (Status)) {\r
854 DEBUG ((EFI_D_ERROR, "[TPM2] Error when lock variable %s, Status = %r\n", TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, Status));\r
855 ASSERT_EFI_ERROR (Status);\r
856 }\r
857 }\r
858 \r
859 //\r
860 // Initialize physical presence variable.\r
861 //\r
862 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
863 Status = gRT->GetVariable (\r
864 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
865 &gEfiTcg2PhysicalPresenceGuid,\r
866 NULL,\r
867 &DataSize,\r
868 &TcgPpData\r
869 );\r
870 if (EFI_ERROR (Status)) {\r
871 ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData));\r
872 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
873 Status = gRT->SetVariable (\r
874 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
875 &gEfiTcg2PhysicalPresenceGuid,\r
876 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
877 DataSize,\r
878 &TcgPpData\r
879 );\r
880 if (EFI_ERROR (Status)) {\r
881 DEBUG ((EFI_D_ERROR, "[TPM2] Set physical presence variable failed, Status = %r\n", Status));\r
882 return ;\r
883 }\r
884 }\r
885\r
886 DEBUG ((EFI_D_INFO, "[TPM2] Flags=%x, PPRequest=%x (LastPPRequest=%x)\n", PpiFlags.PPFlags, TcgPpData.PPRequest, TcgPpData.LastPPRequest));\r
887\r
888 //\r
889 // Execute pending TPM request.\r
890 // \r
891 Tcg2ExecutePendingTpmRequest (PlatformAuth, &TcgPpData, PpiFlags);\r
892 DEBUG ((EFI_D_INFO, "[TPM2] PPResponse = %x (LastPPRequest=%x, Flags=%x)\n", TcgPpData.PPResponse, TcgPpData.LastPPRequest, PpiFlags.PPFlags));\r
893\r
894}\r
895\r
896/**\r
897 Check if the pending TPM request needs user input to confirm.\r
898\r
899 The TPM request may come from OS. This API will check if TPM request exists and need user\r
900 input to confirmation.\r
901 \r
902 @retval TRUE TPM needs input to confirm user physical presence.\r
903 @retval FALSE TPM doesn't need input to confirm user physical presence.\r
904\r
905**/\r
906BOOLEAN\r
907EFIAPI\r
908Tcg2PhysicalPresenceLibNeedUserConfirm(\r
909 VOID\r
910 )\r
911{\r
912 EFI_STATUS Status;\r
913 EFI_TCG2_PHYSICAL_PRESENCE TcgPpData;\r
914 UINTN DataSize;\r
915 BOOLEAN RequestConfirmed;\r
916 EFI_TCG2_PROTOCOL *Tcg2Protocol;\r
917 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags;\r
918\r
d6b02b79
ED
919 //\r
920 // Process the storage related action first.\r
921 // If confirm need user confirm, just return TRUE.\r
922 // else continue check other actions.\r
923 //\r
924 if (TcgPhysicalPresenceStorageLibNeedUserConfirm()) {\r
925 return TRUE;\r
926 }\r
927\r
1abfa4ce
JY
928 Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &Tcg2Protocol);\r
929 if (EFI_ERROR (Status)) {\r
930 return FALSE;\r
931 }\r
932\r
933 //\r
934 // Check S4 resume\r
935 //\r
936 if (GetBootModeHob () == BOOT_ON_S4_RESUME) {\r
937 DEBUG ((EFI_D_INFO, "S4 Resume, Skip TPM PP process!\n"));\r
938 return FALSE;\r
939 }\r
940\r
941 //\r
942 // Check Tpm requests\r
943 //\r
944 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
945 Status = gRT->GetVariable (\r
946 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
947 &gEfiTcg2PhysicalPresenceGuid,\r
948 NULL,\r
949 &DataSize,\r
950 &TcgPpData\r
951 );\r
952 if (EFI_ERROR (Status)) {\r
953 return FALSE;\r
954 }\r
955\r
956 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
957 Status = gRT->GetVariable (\r
958 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
959 &gEfiTcg2PhysicalPresenceGuid,\r
960 NULL,\r
961 &DataSize,\r
962 &PpiFlags\r
963 );\r
964 if (EFI_ERROR (Status)) {\r
965 return FALSE;\r
966 }\r
967 \r
968 if (TcgPpData.PPRequest == TCG2_PHYSICAL_PRESENCE_NO_ACTION) {\r
969 //\r
970 // No operation request\r
971 //\r
972 return FALSE;\r
973 }\r
974\r
975 if (!Tcg2HaveValidTpmRequest(&TcgPpData, PpiFlags, &RequestConfirmed)) {\r
976 //\r
977 // Invalid operation request.\r
978 //\r
979 return FALSE;\r
980 }\r
981\r
982 if (!RequestConfirmed) {\r
983 //\r
984 // Need UI to confirm\r
985 //\r
986 return TRUE;\r
987 }\r
988\r
989 return FALSE;\r
990}\r
991\r
992\r
993/**\r
994 The handler for TPM physical presence function:\r
995 Return TPM Operation Response to OS Environment.\r
996\r
997 @param[out] MostRecentRequest Most recent operation request.\r
998 @param[out] Response Response to the most recent operation request.\r
999\r
1000 @return Return Code for Return TPM Operation Response to OS Environment.\r
1001**/\r
1002UINT32\r
1003EFIAPI\r
1004Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (\r
1005 OUT UINT32 *MostRecentRequest,\r
1006 OUT UINT32 *Response\r
1007 )\r
1008{\r
1009 EFI_STATUS Status;\r
1010 UINTN DataSize;\r
1011 EFI_TCG2_PHYSICAL_PRESENCE PpData;\r
1012 \r
1013 DEBUG ((EFI_D_INFO, "[TPM2] ReturnOperationResponseToOsFunction\n"));\r
1014\r
1015 //\r
1016 // Get the Physical Presence variable\r
1017 //\r
1018 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
1019 Status = gRT->GetVariable (\r
1020 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
1021 &gEfiTcg2PhysicalPresenceGuid,\r
1022 NULL,\r
1023 &DataSize,\r
1024 &PpData\r
1025 );\r
1026 if (EFI_ERROR (Status)) {\r
1027 *MostRecentRequest = 0;\r
1028 *Response = 0;\r
1029 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
1030 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE;\r
1031 }\r
1032 \r
1033 *MostRecentRequest = PpData.LastPPRequest;\r
1034 *Response = PpData.PPResponse;\r
1035\r
1036 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS;\r
1037}\r
1038\r
1039/**\r
1040 The handler for TPM physical presence function:\r
1041 Submit TPM Operation Request to Pre-OS Environment and\r
1042 Submit TPM Operation Request to Pre-OS Environment 2.\r
1043\r
1044 Caution: This function may receive untrusted input.\r
1045 \r
1046 @param[in] OperationRequest TPM physical presence operation request.\r
1047 @param[in] RequestParameter TPM physical presence operation request parameter.\r
1048\r
1049 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and\r
1050 Submit TPM Operation Request to Pre-OS Environment 2.\r
1051**/\r
1052UINT32\r
1053EFIAPI\r
1054Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (\r
1055 IN UINT32 OperationRequest,\r
1056 IN UINT32 RequestParameter\r
1057 )\r
1058{\r
1059 EFI_STATUS Status;\r
1060 UINTN DataSize;\r
1061 EFI_TCG2_PHYSICAL_PRESENCE PpData;\r
1062 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;\r
d6b02b79 1063\r
1abfa4ce 1064 DEBUG ((EFI_D_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest, RequestParameter));\r
d6b02b79 1065\r
1abfa4ce
JY
1066 //\r
1067 // Get the Physical Presence variable\r
1068 //\r
1069 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
1070 Status = gRT->GetVariable (\r
1071 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
1072 &gEfiTcg2PhysicalPresenceGuid,\r
1073 NULL,\r
1074 &DataSize,\r
1075 &PpData\r
1076 );\r
1077 if (EFI_ERROR (Status)) {\r
1078 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
1079 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
1080 }\r
1081\r
d6b02b79
ED
1082 if (((OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&\r
1083 (OperationRequest < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN)) ||\r
1084 ((OperationRequest > TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE) &&\r
1085 (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION))) {\r
1abfa4ce
JY
1086 //\r
1087 // This command requires UI to prompt user for Auth data.\r
1088 //\r
1089 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;\r
1090 }\r
1091\r
6d7c4a25
JY
1092 if ((PpData.PPRequest != OperationRequest) ||\r
1093 (PpData.PPRequestParameter != RequestParameter)) {\r
1abfa4ce
JY
1094 PpData.PPRequest = (UINT8)OperationRequest;\r
1095 PpData.PPRequestParameter = RequestParameter;\r
1096 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
1097 Status = gRT->SetVariable (\r
1098 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
1099 &gEfiTcg2PhysicalPresenceGuid,\r
1100 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
1101 DataSize,\r
1102 &PpData\r
1103 );\r
1104 }\r
1105\r
1106 if (EFI_ERROR (Status)) { \r
1107 DEBUG ((EFI_D_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));\r
1108 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
1109 }\r
1110\r
1111 if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
1112 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
1113 Status = gRT->GetVariable (\r
1114 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
1115 &gEfiTcg2PhysicalPresenceGuid,\r
1116 NULL,\r
1117 &DataSize,\r
1118 &Flags\r
1119 );\r
1120 if (EFI_ERROR (Status)) {\r
1121 Flags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT;\r
1122 }\r
1123 return Tcg2PpVendorLibSubmitRequestToPreOSFunction (OperationRequest, Flags.PPFlags, RequestParameter);\r
1124 }\r
1125\r
1126 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;\r
1127}\r