]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.c
SecurityPkg/TPM2: Move CopyDigestListToBuffer() to Tpm2CommandLib
[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
163 EFI_TCG2_PROTOCOL *Tcg2Protocol;\r
164 EFI_TCG2_BOOT_SERVICE_CAPABILITY ProtocolCapability;\r
165\r
166 Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &Tcg2Protocol);\r
167 ASSERT_EFI_ERROR (Status);\r
168\r
169 ProtocolCapability.Size = sizeof(ProtocolCapability);\r
170 Status = Tcg2Protocol->GetCapability (\r
171 Tcg2Protocol,\r
172 &ProtocolCapability\r
173 );\r
174 ASSERT_EFI_ERROR (Status);\r
175\r
176 switch (CommandCode) {\r
177 case TCG2_PHYSICAL_PRESENCE_CLEAR:\r
178 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:\r
179 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:\r
180 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:\r
181 Status = Tpm2CommandClear (PlatformAuth);\r
182 if (EFI_ERROR (Status)) {\r
183 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
184 } else {\r
185 return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
186 }\r
187\r
188 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:\r
189 PpiFlags->PPFlags |= TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR;\r
190 return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
191\r
192 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:\r
193 PpiFlags->PPFlags &= ~TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR;\r
194 return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
195\r
196 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:\r
f9c9a140 197 Status = Tpm2PcrAllocateBanks (PlatformAuth, ProtocolCapability.HashAlgorithmBitmap, CommandParameter);\r
1abfa4ce
JY
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_CHANGE_EPS:\r
205 Status = Tpm2CommandChangeEps (PlatformAuth);\r
206 if (EFI_ERROR (Status)) {\r
207 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
208 } else {\r
209 return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
210 }\r
211\r
212 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:\r
f9c9a140 213 Status = Tpm2PcrAllocateBanks (PlatformAuth, ProtocolCapability.HashAlgorithmBitmap, ProtocolCapability.HashAlgorithmBitmap);\r
1abfa4ce
JY
214 if (EFI_ERROR (Status)) {\r
215 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
216 } else {\r
217 return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
218 }\r
219\r
220 default:\r
221 if (CommandCode <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {\r
222 return TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
223 } else {\r
224 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
225 }\r
226 }\r
227}\r
228\r
229\r
230/**\r
231 Read the specified key for user confirmation.\r
232\r
233 @param[in] CautionKey If true, F12 is used as confirm key;\r
234 If false, F10 is used as confirm key.\r
235\r
236 @retval TRUE User confirmed the changes by input.\r
237 @retval FALSE User discarded the changes.\r
238**/\r
239BOOLEAN\r
240Tcg2ReadUserKey (\r
241 IN BOOLEAN CautionKey\r
242 )\r
243{\r
244 EFI_STATUS Status;\r
245 EFI_INPUT_KEY Key;\r
246 UINT16 InputKey;\r
247 \r
248 InputKey = 0; \r
249 do {\r
250 Status = gBS->CheckEvent (gST->ConIn->WaitForKey);\r
251 if (!EFI_ERROR (Status)) {\r
252 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
253 if (Key.ScanCode == SCAN_ESC) {\r
254 InputKey = Key.ScanCode;\r
255 }\r
256 if ((Key.ScanCode == SCAN_F10) && !CautionKey) {\r
257 InputKey = Key.ScanCode;\r
258 }\r
259 if ((Key.ScanCode == SCAN_F12) && CautionKey) {\r
260 InputKey = Key.ScanCode;\r
261 }\r
262 } \r
263 } while (InputKey == 0);\r
264\r
265 if (InputKey != SCAN_ESC) {\r
266 return TRUE;\r
267 }\r
268 \r
269 return FALSE;\r
270}\r
271\r
272/**\r
273 Fill Buffer With BootHashAlg.\r
274\r
275 @param[in] Buffer Buffer to be filled.\r
276 @param[in] BufferSize Size of buffer.\r
277 @param[in] BootHashAlg BootHashAlg.\r
278\r
279**/\r
280VOID\r
281Tcg2FillBufferWithBootHashAlg (\r
282 IN UINT16 *Buffer,\r
283 IN UINTN BufferSize,\r
284 IN UINT32 BootHashAlg\r
285 )\r
286{\r
287 Buffer[0] = 0;\r
288 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
289 if (Buffer[0] != 0) {\r
290 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
291 }\r
292 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA1", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
293 }\r
294 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
295 if (Buffer[0] != 0) {\r
296 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
297 }\r
298 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
299 }\r
300 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
301 if (Buffer[0] != 0) {\r
302 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
303 }\r
304 StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA384", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
305 }\r
306 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 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"SHA512", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
311 }\r
312 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 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"SM3_256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);\r
317 }\r
318}\r
319\r
320/**\r
321 Display the confirm text and get user confirmation.\r
322\r
323 @param[in] TpmPpCommand The requested TPM physical presence command.\r
324 @param[in] TpmPpCommandParameter The requested TPM physical presence command parameter.\r
325\r
326 @retval TRUE The user has confirmed the changes.\r
327 @retval FALSE The user doesn't confirm the changes.\r
328**/\r
329BOOLEAN\r
330Tcg2UserConfirm (\r
331 IN UINT32 TpmPpCommand,\r
332 IN UINT32 TpmPpCommandParameter\r
333 )\r
334{\r
335 CHAR16 *ConfirmText;\r
336 CHAR16 *TmpStr1;\r
337 CHAR16 *TmpStr2; \r
338 UINTN BufSize;\r
339 BOOLEAN CautionKey;\r
340 BOOLEAN NoPpiInfo;\r
341 UINT16 Index;\r
342 CHAR16 DstStr[81];\r
343 CHAR16 TempBuffer[1024];\r
344 CHAR16 TempBuffer2[1024];\r
345 EFI_TCG2_PROTOCOL *Tcg2Protocol;\r
346 EFI_TCG2_BOOT_SERVICE_CAPABILITY ProtocolCapability;\r
347 UINT32 CurrentPCRBanks;\r
348 EFI_STATUS Status;\r
349\r
350 Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &Tcg2Protocol);\r
351 ASSERT_EFI_ERROR (Status);\r
352\r
353 ProtocolCapability.Size = sizeof(ProtocolCapability);\r
354 Status = Tcg2Protocol->GetCapability (\r
355 Tcg2Protocol,\r
356 &ProtocolCapability\r
357 );\r
358 ASSERT_EFI_ERROR (Status);\r
359\r
360 Status = Tcg2Protocol->GetActivePcrBanks (\r
361 Tcg2Protocol,\r
362 &CurrentPCRBanks\r
363 );\r
364 ASSERT_EFI_ERROR (Status);\r
365 \r
366 TmpStr2 = NULL;\r
367 CautionKey = FALSE;\r
368 NoPpiInfo = FALSE;\r
369 BufSize = CONFIRM_BUFFER_SIZE;\r
370 ConfirmText = AllocateZeroPool (BufSize);\r
371 ASSERT (ConfirmText != NULL);\r
372\r
373 switch (TpmPpCommand) {\r
374\r
375 case TCG2_PHYSICAL_PRESENCE_CLEAR:\r
376 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:\r
377 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:\r
378 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:\r
379 CautionKey = TRUE;\r
380 TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));\r
381\r
382 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
383 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
384 FreePool (TmpStr1);\r
385\r
386 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));\r
387 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
388 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
389 FreePool (TmpStr1); \r
390\r
391 break;\r
392\r
393 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:\r
394 CautionKey = TRUE;\r
395 NoPpiInfo = TRUE;\r
396 TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));\r
397\r
398 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));\r
399 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
400 FreePool (TmpStr1);\r
401\r
402 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_CLEAR));\r
403 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
404 FreePool (TmpStr1);\r
405\r
406 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));\r
407 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
408 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
409 FreePool (TmpStr1); \r
410\r
411 break;\r
412\r
413 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:\r
414 CautionKey = TRUE;\r
415 TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_SET_PCR_BANKS));\r
416\r
417 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
418 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
419 FreePool (TmpStr1);\r
420\r
421 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_1));\r
422 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
423 FreePool (TmpStr1); \r
424\r
425 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_2));\r
426 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
427 FreePool (TmpStr1); \r
428\r
429 Tcg2FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), TpmPpCommandParameter);\r
430 Tcg2FillBufferWithBootHashAlg (TempBuffer2, sizeof(TempBuffer2), CurrentPCRBanks);\r
431\r
432 TmpStr1 = AllocateZeroPool (BufSize);\r
433 ASSERT (TmpStr1 != NULL);\r
434 UnicodeSPrint (TmpStr1, BufSize, L"Current PCRBanks is 0x%x. (%s)\nNew PCRBanks is 0x%x. (%s)\n", CurrentPCRBanks, TempBuffer2, TpmPpCommandParameter, TempBuffer);\r
435\r
436 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
437 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
438 FreePool (TmpStr1); \r
439\r
440 break;\r
441\r
442 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:\r
443 CautionKey = TRUE;\r
444 TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CHANGE_EPS));\r
445\r
446 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
447 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
448 FreePool (TmpStr1);\r
449\r
450 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_1));\r
451 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
452 FreePool (TmpStr1); \r
453 \r
454 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_2));\r
455 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
456 FreePool (TmpStr1); \r
457\r
458 break;\r
459 \r
460\r
461 default:\r
462 ;\r
463 }\r
464\r
465 if (TmpStr2 == NULL) {\r
466 FreePool (ConfirmText);\r
467 return FALSE;\r
468 }\r
469\r
470 if (TpmPpCommand < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN) {\r
471 if (CautionKey) {\r
472 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));\r
473 } else {\r
474 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));\r
475 }\r
476 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
477 FreePool (TmpStr1);\r
478\r
479 if (NoPpiInfo) {\r
480 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));\r
481 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
482 FreePool (TmpStr1);\r
483 }\r
484\r
485 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY));\r
486 } else {\r
487 if (CautionKey) {\r
488 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_CAUTION_KEY));\r
489 } else {\r
490 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ACCEPT_KEY));\r
491 }\r
492 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
493 FreePool (TmpStr1);\r
494\r
495 if (NoPpiInfo) {\r
496 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_NO_PPI_INFO));\r
497 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);\r
498 FreePool (TmpStr1);\r
499 }\r
500\r
501 TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_REJECT_KEY));\r
502 }\r
503 BufSize -= StrSize (ConfirmText);\r
504 UnicodeSPrint (ConfirmText + StrLen (ConfirmText), BufSize, TmpStr1, TmpStr2);\r
505\r
506 DstStr[80] = L'\0';\r
507 for (Index = 0; Index < StrLen (ConfirmText); Index += 80) {\r
508 StrnCpyS (DstStr, sizeof (DstStr) / sizeof (CHAR16), ConfirmText + Index, sizeof (DstStr) / sizeof (CHAR16) - 1); \r
509 Print (DstStr); \r
510 }\r
511 \r
512 FreePool (TmpStr1);\r
513 FreePool (TmpStr2);\r
514 FreePool (ConfirmText);\r
515\r
516 if (Tcg2ReadUserKey (CautionKey)) {\r
517 return TRUE;\r
518 }\r
519\r
520 return FALSE; \r
521}\r
522\r
523/**\r
524 Check if there is a valid physical presence command request. Also updates parameter value \r
525 to whether the requested physical presence command already confirmed by user\r
526 \r
527 @param[in] TcgPpData EFI Tcg2 Physical Presence request data. \r
528 @param[in] Flags The physical presence interface flags.\r
529 @param[out] RequestConfirmed If the physical presence operation command required user confirm from UI.\r
530 True, it indicates the command doesn't require user confirm, or already confirmed \r
531 in last boot cycle by user.\r
532 False, it indicates the command need user confirm from UI.\r
533\r
534 @retval TRUE Physical Presence operation command is valid.\r
535 @retval FALSE Physical Presence operation command is invalid.\r
536\r
537**/\r
538BOOLEAN\r
539Tcg2HaveValidTpmRequest (\r
540 IN EFI_TCG2_PHYSICAL_PRESENCE *TcgPpData,\r
541 IN EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags,\r
542 OUT BOOLEAN *RequestConfirmed\r
543 )\r
544{\r
545 BOOLEAN IsRequestValid;\r
546\r
547 *RequestConfirmed = FALSE;\r
548\r
549 switch (TcgPpData->PPRequest) {\r
550 case TCG2_PHYSICAL_PRESENCE_NO_ACTION:\r
551 *RequestConfirmed = TRUE;\r
552 return TRUE;\r
553\r
554 case TCG2_PHYSICAL_PRESENCE_CLEAR:\r
555 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:\r
556 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:\r
557 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:\r
558 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR) == 0) {\r
559 *RequestConfirmed = TRUE;\r
560 }\r
561 break;\r
562\r
563 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:\r
564 *RequestConfirmed = TRUE;\r
565 break;\r
566\r
567 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:\r
568 break;\r
569\r
570 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:\r
571 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS) == 0) {\r
572 *RequestConfirmed = TRUE;\r
573 }\r
574 break;\r
575\r
576 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:\r
577 if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS) == 0) {\r
578 *RequestConfirmed = TRUE;\r
579 }\r
580 break;\r
581 \r
582 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:\r
583 *RequestConfirmed = TRUE;\r
584 break;\r
585\r
586 default:\r
587 if (TcgPpData->PPRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
588 IsRequestValid = Tcg2PpVendorLibHasValidRequest (TcgPpData->PPRequest, Flags.PPFlags, RequestConfirmed);\r
589 if (!IsRequestValid) {\r
590 return FALSE;\r
591 } else {\r
592 break;\r
593 }\r
594 } else {\r
595 //\r
596 // Wrong Physical Presence command\r
597 //\r
598 return FALSE;\r
599 }\r
600 }\r
601\r
602 if ((Flags.PPFlags & TCG2_LIB_PP_FLAG_RESET_TRACK) != 0) {\r
603 //\r
604 // It had been confirmed in last boot, it doesn't need confirm again.\r
605 //\r
606 *RequestConfirmed = TRUE;\r
607 }\r
608\r
609 //\r
610 // Physical Presence command is correct\r
611 //\r
612 return TRUE;\r
613}\r
614\r
615\r
616/**\r
617 Check and execute the requested physical presence command.\r
618\r
619 Caution: This function may receive untrusted input.\r
620 TcgPpData variable is external input, so this function will validate\r
621 its data structure to be valid value.\r
622\r
623 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.\r
624 @param[in] TcgPpData Point to the physical presence NV variable.\r
625 @param[in] Flags The physical presence interface flags.\r
626**/\r
627VOID\r
628Tcg2ExecutePendingTpmRequest (\r
629 IN TPM2B_AUTH *PlatformAuth, OPTIONAL\r
630 IN EFI_TCG2_PHYSICAL_PRESENCE *TcgPpData,\r
631 IN EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags\r
632 )\r
633{\r
634 EFI_STATUS Status;\r
635 UINTN DataSize;\r
636 BOOLEAN RequestConfirmed;\r
637 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS NewFlags;\r
638 BOOLEAN ResetRequired;\r
639 UINT32 NewPPFlags;\r
640\r
641 if (TcgPpData->PPRequest == TCG2_PHYSICAL_PRESENCE_NO_ACTION) {\r
642 //\r
643 // No operation request\r
644 //\r
645 return;\r
646 }\r
647\r
648 if (!Tcg2HaveValidTpmRequest(TcgPpData, Flags, &RequestConfirmed)) {\r
649 //\r
650 // Invalid operation request.\r
651 //\r
652 if (TcgPpData->PPRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {\r
653 TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_SUCCESS;\r
654 } else {\r
655 TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
656 }\r
657 TcgPpData->LastPPRequest = TcgPpData->PPRequest;\r
658 TcgPpData->PPRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;\r
659 TcgPpData->PPRequestParameter = 0;\r
660\r
661 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
662 Status = gRT->SetVariable (\r
663 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
664 &gEfiTcg2PhysicalPresenceGuid,\r
665 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
666 DataSize,\r
667 TcgPpData\r
668 );\r
669 return;\r
670 }\r
671\r
672 ResetRequired = FALSE;\r
673 if (TcgPpData->PPRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
674 NewFlags = Flags;\r
675 NewPPFlags = NewFlags.PPFlags;\r
676 TcgPpData->PPResponse = Tcg2PpVendorLibExecutePendingRequest (PlatformAuth, TcgPpData->PPRequest, &NewPPFlags, &ResetRequired);\r
677 NewFlags.PPFlags = NewPPFlags;\r
678 } else {\r
679 if (!RequestConfirmed) {\r
680 //\r
681 // Print confirm text and wait for approval. \r
682 //\r
683 RequestConfirmed = Tcg2UserConfirm (TcgPpData->PPRequest, TcgPpData->PPRequestParameter);\r
684 }\r
685\r
686 //\r
687 // Execute requested physical presence command\r
688 //\r
689 TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_USER_ABORT;\r
690 NewFlags = Flags;\r
691 if (RequestConfirmed) {\r
692 TcgPpData->PPResponse = Tcg2ExecutePhysicalPresence (\r
693 PlatformAuth,\r
694 TcgPpData->PPRequest, \r
695 TcgPpData->PPRequestParameter, \r
696 &NewFlags\r
697 );\r
698 }\r
699 }\r
700\r
701 //\r
702 // Save the flags if it is updated.\r
703 //\r
704 if (CompareMem (&Flags, &NewFlags, sizeof(EFI_TCG2_PHYSICAL_PRESENCE_FLAGS)) != 0) {\r
705 Status = gRT->SetVariable (\r
706 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
707 &gEfiTcg2PhysicalPresenceGuid,\r
708 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
709 sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS),\r
710 &NewFlags\r
711 ); \r
712 }\r
713\r
714 //\r
715 // Clear request\r
716 //\r
717 if ((NewFlags.PPFlags & TCG2_LIB_PP_FLAG_RESET_TRACK) == 0) {\r
718 TcgPpData->LastPPRequest = TcgPpData->PPRequest;\r
719 TcgPpData->PPRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION; \r
720 TcgPpData->PPRequestParameter = 0;\r
721 }\r
722\r
723 //\r
724 // Save changes\r
725 //\r
726 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
727 Status = gRT->SetVariable (\r
728 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
729 &gEfiTcg2PhysicalPresenceGuid,\r
730 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
731 DataSize,\r
732 TcgPpData\r
733 );\r
734 if (EFI_ERROR (Status)) {\r
735 return;\r
736 }\r
737\r
738 if (TcgPpData->PPResponse == TCG_PP_OPERATION_RESPONSE_USER_ABORT) {\r
739 return;\r
740 }\r
741\r
742 //\r
743 // Reset system to make new TPM settings in effect\r
744 //\r
745 switch (TcgPpData->LastPPRequest) {\r
746 case TCG2_PHYSICAL_PRESENCE_CLEAR:\r
747 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:\r
748 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:\r
749 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:\r
750 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:\r
751 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:\r
752 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:\r
753 break;\r
754\r
755 default:\r
756 if (TcgPpData->LastPPRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
757 if (ResetRequired) {\r
758 break;\r
759 } else {\r
760 return ;\r
761 }\r
762 }\r
763 if (TcgPpData->PPRequest != TCG2_PHYSICAL_PRESENCE_NO_ACTION) {\r
764 break;\r
765 }\r
766 return;\r
767 }\r
768\r
769 Print (L"Rebooting system to make TPM2 settings in effect\n");\r
770 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
771 ASSERT (FALSE); \r
772}\r
773\r
774/**\r
775 Check and execute the pending TPM request.\r
776\r
777 The TPM request may come from OS or BIOS. This API will display request information and wait \r
778 for user confirmation if TPM request exists. The TPM request will be sent to TPM device after\r
779 the TPM request is confirmed, and one or more reset may be required to make TPM request to \r
780 take effect.\r
781 \r
782 This API should be invoked after console in and console out are all ready as they are required\r
783 to display request information and get user input to confirm the request. \r
784\r
785 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.\r
786**/\r
787VOID\r
788EFIAPI\r
789Tcg2PhysicalPresenceLibProcessRequest (\r
790 IN TPM2B_AUTH *PlatformAuth OPTIONAL\r
791 )\r
792{\r
793 EFI_STATUS Status;\r
794 UINTN DataSize;\r
795 EFI_TCG2_PHYSICAL_PRESENCE TcgPpData;\r
796 EFI_TCG2_PROTOCOL *Tcg2Protocol;\r
797 EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol;\r
798 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags;\r
799\r
800 Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &Tcg2Protocol);\r
801 if (EFI_ERROR (Status)) {\r
802 return ;\r
803 }\r
804 \r
805 //\r
806 // Check S4 resume\r
807 //\r
808 if (GetBootModeHob () == BOOT_ON_S4_RESUME) {\r
809 DEBUG ((EFI_D_INFO, "S4 Resume, Skip TPM PP process!\n"));\r
810 return ;\r
811 }\r
812\r
813 mTcg2PpStringPackHandle = HiiAddPackages (&gEfiTcg2PhysicalPresenceGuid, gImageHandle, DxeTcg2PhysicalPresenceLibStrings, NULL);\r
814 ASSERT (mTcg2PpStringPackHandle != NULL);\r
815\r
816 //\r
817 // Initialize physical presence flags.\r
818 //\r
819 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
820 Status = gRT->GetVariable (\r
821 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
822 &gEfiTcg2PhysicalPresenceGuid,\r
823 NULL,\r
824 &DataSize,\r
825 &PpiFlags\r
826 );\r
827 if (EFI_ERROR (Status)) {\r
828 PpiFlags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT;\r
829 Status = gRT->SetVariable (\r
830 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
831 &gEfiTcg2PhysicalPresenceGuid,\r
832 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
833 sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS),\r
834 &PpiFlags\r
835 );\r
836 if (EFI_ERROR (Status)) {\r
837 DEBUG ((EFI_D_ERROR, "[TPM2] Set physical presence flag failed, Status = %r\n", Status));\r
838 return ;\r
839 }\r
840 }\r
841 DEBUG ((EFI_D_INFO, "[TPM2] PpiFlags = %x\n", PpiFlags.PPFlags));\r
842\r
843 //\r
844 // This flags variable controls whether physical presence is required for TPM command. \r
845 // It should be protected from malicious software. We set it as read-only variable here.\r
846 //\r
847 Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);\r
848 if (!EFI_ERROR (Status)) {\r
849 Status = VariableLockProtocol->RequestToLock (\r
850 VariableLockProtocol,\r
851 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
852 &gEfiTcg2PhysicalPresenceGuid\r
853 );\r
854 if (EFI_ERROR (Status)) {\r
855 DEBUG ((EFI_D_ERROR, "[TPM2] Error when lock variable %s, Status = %r\n", TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, Status));\r
856 ASSERT_EFI_ERROR (Status);\r
857 }\r
858 }\r
859 \r
860 //\r
861 // Initialize physical presence variable.\r
862 //\r
863 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
864 Status = gRT->GetVariable (\r
865 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
866 &gEfiTcg2PhysicalPresenceGuid,\r
867 NULL,\r
868 &DataSize,\r
869 &TcgPpData\r
870 );\r
871 if (EFI_ERROR (Status)) {\r
872 ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData));\r
873 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
874 Status = gRT->SetVariable (\r
875 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
876 &gEfiTcg2PhysicalPresenceGuid,\r
877 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
878 DataSize,\r
879 &TcgPpData\r
880 );\r
881 if (EFI_ERROR (Status)) {\r
882 DEBUG ((EFI_D_ERROR, "[TPM2] Set physical presence variable failed, Status = %r\n", Status));\r
883 return ;\r
884 }\r
885 }\r
886\r
887 DEBUG ((EFI_D_INFO, "[TPM2] Flags=%x, PPRequest=%x (LastPPRequest=%x)\n", PpiFlags.PPFlags, TcgPpData.PPRequest, TcgPpData.LastPPRequest));\r
888\r
889 //\r
890 // Execute pending TPM request.\r
891 // \r
892 Tcg2ExecutePendingTpmRequest (PlatformAuth, &TcgPpData, PpiFlags);\r
893 DEBUG ((EFI_D_INFO, "[TPM2] PPResponse = %x (LastPPRequest=%x, Flags=%x)\n", TcgPpData.PPResponse, TcgPpData.LastPPRequest, PpiFlags.PPFlags));\r
894\r
895}\r
896\r
897/**\r
898 Check if the pending TPM request needs user input to confirm.\r
899\r
900 The TPM request may come from OS. This API will check if TPM request exists and need user\r
901 input to confirmation.\r
902 \r
903 @retval TRUE TPM needs input to confirm user physical presence.\r
904 @retval FALSE TPM doesn't need input to confirm user physical presence.\r
905\r
906**/\r
907BOOLEAN\r
908EFIAPI\r
909Tcg2PhysicalPresenceLibNeedUserConfirm(\r
910 VOID\r
911 )\r
912{\r
913 EFI_STATUS Status;\r
914 EFI_TCG2_PHYSICAL_PRESENCE TcgPpData;\r
915 UINTN DataSize;\r
916 BOOLEAN RequestConfirmed;\r
917 EFI_TCG2_PROTOCOL *Tcg2Protocol;\r
918 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags;\r
919\r
920 Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &Tcg2Protocol);\r
921 if (EFI_ERROR (Status)) {\r
922 return FALSE;\r
923 }\r
924\r
925 //\r
926 // Check S4 resume\r
927 //\r
928 if (GetBootModeHob () == BOOT_ON_S4_RESUME) {\r
929 DEBUG ((EFI_D_INFO, "S4 Resume, Skip TPM PP process!\n"));\r
930 return FALSE;\r
931 }\r
932\r
933 //\r
934 // Check Tpm requests\r
935 //\r
936 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
937 Status = gRT->GetVariable (\r
938 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
939 &gEfiTcg2PhysicalPresenceGuid,\r
940 NULL,\r
941 &DataSize,\r
942 &TcgPpData\r
943 );\r
944 if (EFI_ERROR (Status)) {\r
945 return FALSE;\r
946 }\r
947\r
948 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
949 Status = gRT->GetVariable (\r
950 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
951 &gEfiTcg2PhysicalPresenceGuid,\r
952 NULL,\r
953 &DataSize,\r
954 &PpiFlags\r
955 );\r
956 if (EFI_ERROR (Status)) {\r
957 return FALSE;\r
958 }\r
959 \r
960 if (TcgPpData.PPRequest == TCG2_PHYSICAL_PRESENCE_NO_ACTION) {\r
961 //\r
962 // No operation request\r
963 //\r
964 return FALSE;\r
965 }\r
966\r
967 if (!Tcg2HaveValidTpmRequest(&TcgPpData, PpiFlags, &RequestConfirmed)) {\r
968 //\r
969 // Invalid operation request.\r
970 //\r
971 return FALSE;\r
972 }\r
973\r
974 if (!RequestConfirmed) {\r
975 //\r
976 // Need UI to confirm\r
977 //\r
978 return TRUE;\r
979 }\r
980\r
981 return FALSE;\r
982}\r
983\r
984\r
985/**\r
986 The handler for TPM physical presence function:\r
987 Return TPM Operation Response to OS Environment.\r
988\r
989 @param[out] MostRecentRequest Most recent operation request.\r
990 @param[out] Response Response to the most recent operation request.\r
991\r
992 @return Return Code for Return TPM Operation Response to OS Environment.\r
993**/\r
994UINT32\r
995EFIAPI\r
996Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (\r
997 OUT UINT32 *MostRecentRequest,\r
998 OUT UINT32 *Response\r
999 )\r
1000{\r
1001 EFI_STATUS Status;\r
1002 UINTN DataSize;\r
1003 EFI_TCG2_PHYSICAL_PRESENCE PpData;\r
1004 \r
1005 DEBUG ((EFI_D_INFO, "[TPM2] ReturnOperationResponseToOsFunction\n"));\r
1006\r
1007 //\r
1008 // Get the Physical Presence variable\r
1009 //\r
1010 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
1011 Status = gRT->GetVariable (\r
1012 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
1013 &gEfiTcg2PhysicalPresenceGuid,\r
1014 NULL,\r
1015 &DataSize,\r
1016 &PpData\r
1017 );\r
1018 if (EFI_ERROR (Status)) {\r
1019 *MostRecentRequest = 0;\r
1020 *Response = 0;\r
1021 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
1022 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE;\r
1023 }\r
1024 \r
1025 *MostRecentRequest = PpData.LastPPRequest;\r
1026 *Response = PpData.PPResponse;\r
1027\r
1028 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS;\r
1029}\r
1030\r
1031/**\r
1032 The handler for TPM physical presence function:\r
1033 Submit TPM Operation Request to Pre-OS Environment and\r
1034 Submit TPM Operation Request to Pre-OS Environment 2.\r
1035\r
1036 Caution: This function may receive untrusted input.\r
1037 \r
1038 @param[in] OperationRequest TPM physical presence operation request.\r
1039 @param[in] RequestParameter TPM physical presence operation request parameter.\r
1040\r
1041 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and\r
1042 Submit TPM Operation Request to Pre-OS Environment 2.\r
1043**/\r
1044UINT32\r
1045EFIAPI\r
1046Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (\r
1047 IN UINT32 OperationRequest,\r
1048 IN UINT32 RequestParameter\r
1049 )\r
1050{\r
1051 EFI_STATUS Status;\r
1052 UINTN DataSize;\r
1053 EFI_TCG2_PHYSICAL_PRESENCE PpData;\r
1054 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;\r
1055 \r
1056 DEBUG ((EFI_D_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest, RequestParameter));\r
1057 \r
1058 //\r
1059 // Get the Physical Presence variable\r
1060 //\r
1061 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
1062 Status = gRT->GetVariable (\r
1063 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
1064 &gEfiTcg2PhysicalPresenceGuid,\r
1065 NULL,\r
1066 &DataSize,\r
1067 &PpData\r
1068 );\r
1069 if (EFI_ERROR (Status)) {\r
1070 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
1071 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
1072 }\r
1073\r
1074 if ((OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&\r
1075 (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) ) {\r
1076 //\r
1077 // This command requires UI to prompt user for Auth data.\r
1078 //\r
1079 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;\r
1080 }\r
1081\r
6d7c4a25
JY
1082 if ((PpData.PPRequest != OperationRequest) ||\r
1083 (PpData.PPRequestParameter != RequestParameter)) {\r
1abfa4ce
JY
1084 PpData.PPRequest = (UINT8)OperationRequest;\r
1085 PpData.PPRequestParameter = RequestParameter;\r
1086 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
1087 Status = gRT->SetVariable (\r
1088 TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
1089 &gEfiTcg2PhysicalPresenceGuid,\r
1090 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
1091 DataSize,\r
1092 &PpData\r
1093 );\r
1094 }\r
1095\r
1096 if (EFI_ERROR (Status)) { \r
1097 DEBUG ((EFI_D_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));\r
1098 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
1099 }\r
1100\r
1101 if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
1102 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
1103 Status = gRT->GetVariable (\r
1104 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
1105 &gEfiTcg2PhysicalPresenceGuid,\r
1106 NULL,\r
1107 &DataSize,\r
1108 &Flags\r
1109 );\r
1110 if (EFI_ERROR (Status)) {\r
1111 Flags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT;\r
1112 }\r
1113 return Tcg2PpVendorLibSubmitRequestToPreOSFunction (OperationRequest, Flags.PPFlags, RequestParameter);\r
1114 }\r
1115\r
1116 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;\r
1117}\r