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