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