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