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