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