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