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