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