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