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 *
Tcg2PhysicalPresenceGetStringById(IN EFI_STRING_ID Id)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
Tpm2CommandClear(IN TPM2B_AUTH * PlatformAuth OPTIONAL)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
Tpm2CommandChangeEps(IN TPM2B_AUTH * PlatformAuth OPTIONAL)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
Tcg2ExecutePhysicalPresence(IN TPM2B_AUTH * PlatformAuth,OPTIONAL IN UINT32 CommandCode,IN UINT32 CommandParameter,IN OUT EFI_TCG2_PHYSICAL_PRESENCE_FLAGS * PpiFlags)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
Tcg2ReadUserKey(IN BOOLEAN CautionKey)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
Tcg2FillBufferWithBootHashAlg(IN UINT16 * Buffer,IN UINTN BufferSize,IN UINT32 BootHashAlg)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
Tcg2UserConfirm(IN UINT32 TpmPpCommand,IN UINT32 TpmPpCommandParameter)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
Tcg2HaveValidTpmRequest(IN EFI_TCG2_PHYSICAL_PRESENCE * TcgPpData,IN EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags,OUT BOOLEAN * RequestConfirmed)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
Tcg2ExecutePendingTpmRequest(IN TPM2B_AUTH * PlatformAuth,OPTIONAL IN OUT EFI_TCG2_PHYSICAL_PRESENCE * TcgPpData,IN OUT EFI_TCG2_PHYSICAL_PRESENCE_FLAGS * Flags)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
Tcg2PhysicalPresenceLibProcessRequest(IN TPM2B_AUTH * PlatformAuth OPTIONAL)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 = PcdGet32(PcdTcg2PhysicalPresenceFlags);
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 DEBUG((DEBUG_INFO, "[TPM2] Initial physical presence flags value is 0x%x\n", PpiFlags.PPFlags));
948 }
949
950 //
951 // Initialize physical presence variable.
952 //
953 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
954 Status = gRT->GetVariable (
955 TCG2_PHYSICAL_PRESENCE_VARIABLE,
956 &gEfiTcg2PhysicalPresenceGuid,
957 NULL,
958 &DataSize,
959 &TcgPpData
960 );
961 if (EFI_ERROR (Status)) {
962 ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData));
963 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
964 Status = gRT->SetVariable (
965 TCG2_PHYSICAL_PRESENCE_VARIABLE,
966 &gEfiTcg2PhysicalPresenceGuid,
967 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
968 DataSize,
969 &TcgPpData
970 );
971 if (EFI_ERROR (Status)) {
972 DEBUG ((EFI_D_ERROR, "[TPM2] Set physical presence variable failed, Status = %r\n", Status));
973 return ;
974 }
975 }
976
977 DEBUG ((EFI_D_INFO, "[TPM2] Flags=%x, PPRequest=%x (LastPPRequest=%x)\n", PpiFlags.PPFlags, TcgPpData.PPRequest, TcgPpData.LastPPRequest));
978
979 //
980 // Execute pending TPM request.
981 //
982 Tcg2ExecutePendingTpmRequest (PlatformAuth, &TcgPpData, &PpiFlags);
983 DEBUG ((EFI_D_INFO, "[TPM2] PPResponse = %x (LastPPRequest=%x, Flags=%x)\n", TcgPpData.PPResponse, TcgPpData.LastPPRequest, PpiFlags.PPFlags));
984
985 }
986
987 /**
988 Check if the pending TPM request needs user input to confirm.
989
990 The TPM request may come from OS. This API will check if TPM request exists and need user
991 input to confirmation.
992
993 @retval TRUE TPM needs input to confirm user physical presence.
994 @retval FALSE TPM doesn't need input to confirm user physical presence.
995
996 **/
997 BOOLEAN
998 EFIAPI
Tcg2PhysicalPresenceLibNeedUserConfirm(VOID)999 Tcg2PhysicalPresenceLibNeedUserConfirm(
1000 VOID
1001 )
1002 {
1003 EFI_STATUS Status;
1004 EFI_TCG2_PHYSICAL_PRESENCE TcgPpData;
1005 UINTN DataSize;
1006 BOOLEAN RequestConfirmed;
1007 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags;
1008
1009 //
1010 // Check S4 resume
1011 //
1012 if (GetBootModeHob () == BOOT_ON_S4_RESUME) {
1013 DEBUG ((EFI_D_INFO, "S4 Resume, Skip TPM PP process!\n"));
1014 return FALSE;
1015 }
1016
1017 //
1018 // Check Tpm requests
1019 //
1020 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
1021 Status = gRT->GetVariable (
1022 TCG2_PHYSICAL_PRESENCE_VARIABLE,
1023 &gEfiTcg2PhysicalPresenceGuid,
1024 NULL,
1025 &DataSize,
1026 &TcgPpData
1027 );
1028 if (EFI_ERROR (Status)) {
1029 return FALSE;
1030 }
1031
1032 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
1033 Status = gRT->GetVariable (
1034 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
1035 &gEfiTcg2PhysicalPresenceGuid,
1036 NULL,
1037 &DataSize,
1038 &PpiFlags
1039 );
1040 if (EFI_ERROR (Status)) {
1041 return FALSE;
1042 }
1043
1044 if (TcgPpData.PPRequest == TCG2_PHYSICAL_PRESENCE_NO_ACTION) {
1045 //
1046 // No operation request
1047 //
1048 return FALSE;
1049 }
1050
1051 if (!Tcg2HaveValidTpmRequest(&TcgPpData, PpiFlags, &RequestConfirmed)) {
1052 //
1053 // Invalid operation request.
1054 //
1055 return FALSE;
1056 }
1057
1058 if (!RequestConfirmed) {
1059 //
1060 // Need UI to confirm
1061 //
1062 return TRUE;
1063 }
1064
1065 return FALSE;
1066 }
1067
1068
1069 /**
1070 The handler for TPM physical presence function:
1071 Return TPM Operation Response to OS Environment.
1072
1073 @param[out] MostRecentRequest Most recent operation request.
1074 @param[out] Response Response to the most recent operation request.
1075
1076 @return Return Code for Return TPM Operation Response to OS Environment.
1077 **/
1078 UINT32
1079 EFIAPI
Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction(OUT UINT32 * MostRecentRequest,OUT UINT32 * Response)1080 Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
1081 OUT UINT32 *MostRecentRequest,
1082 OUT UINT32 *Response
1083 )
1084 {
1085 EFI_STATUS Status;
1086 UINTN DataSize;
1087 EFI_TCG2_PHYSICAL_PRESENCE PpData;
1088
1089 DEBUG ((EFI_D_INFO, "[TPM2] ReturnOperationResponseToOsFunction\n"));
1090
1091 //
1092 // Get the Physical Presence variable
1093 //
1094 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
1095 Status = gRT->GetVariable (
1096 TCG2_PHYSICAL_PRESENCE_VARIABLE,
1097 &gEfiTcg2PhysicalPresenceGuid,
1098 NULL,
1099 &DataSize,
1100 &PpData
1101 );
1102 if (EFI_ERROR (Status)) {
1103 *MostRecentRequest = 0;
1104 *Response = 0;
1105 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
1106 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE;
1107 }
1108
1109 *MostRecentRequest = PpData.LastPPRequest;
1110 *Response = PpData.PPResponse;
1111
1112 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS;
1113 }
1114
1115 /**
1116 The handler for TPM physical presence function:
1117 Submit TPM Operation Request to Pre-OS Environment and
1118 Submit TPM Operation Request to Pre-OS Environment 2.
1119
1120 Caution: This function may receive untrusted input.
1121
1122 @param[in] OperationRequest TPM physical presence operation request.
1123 @param[in] RequestParameter TPM physical presence operation request parameter.
1124
1125 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
1126 Submit TPM Operation Request to Pre-OS Environment 2.
1127 **/
1128 UINT32
1129 EFIAPI
Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction(IN UINT32 OperationRequest,IN UINT32 RequestParameter)1130 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
1131 IN UINT32 OperationRequest,
1132 IN UINT32 RequestParameter
1133 )
1134 {
1135 EFI_STATUS Status;
1136 UINTN DataSize;
1137 EFI_TCG2_PHYSICAL_PRESENCE PpData;
1138 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;
1139
1140 DEBUG ((EFI_D_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest, RequestParameter));
1141
1142 //
1143 // Get the Physical Presence variable
1144 //
1145 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
1146 Status = gRT->GetVariable (
1147 TCG2_PHYSICAL_PRESENCE_VARIABLE,
1148 &gEfiTcg2PhysicalPresenceGuid,
1149 NULL,
1150 &DataSize,
1151 &PpData
1152 );
1153 if (EFI_ERROR (Status)) {
1154 DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
1155 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
1156 }
1157
1158 if ((OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&
1159 (OperationRequest < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN) ) {
1160 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;
1161 }
1162
1163 if ((PpData.PPRequest != OperationRequest) ||
1164 (PpData.PPRequestParameter != RequestParameter)) {
1165 PpData.PPRequest = (UINT8)OperationRequest;
1166 PpData.PPRequestParameter = RequestParameter;
1167 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
1168 Status = gRT->SetVariable (
1169 TCG2_PHYSICAL_PRESENCE_VARIABLE,
1170 &gEfiTcg2PhysicalPresenceGuid,
1171 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
1172 DataSize,
1173 &PpData
1174 );
1175 if (EFI_ERROR (Status)) {
1176 DEBUG ((EFI_D_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));
1177 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
1178 }
1179 }
1180
1181 if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
1182 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
1183 Status = gRT->GetVariable (
1184 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
1185 &gEfiTcg2PhysicalPresenceGuid,
1186 NULL,
1187 &DataSize,
1188 &Flags
1189 );
1190 if (EFI_ERROR (Status)) {
1191 Flags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT | TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_DEFAULT;
1192 }
1193 return Tcg2PpVendorLibSubmitRequestToPreOSFunction (OperationRequest, Flags.PPFlags, RequestParameter);
1194 }
1195
1196 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;
1197 }
1198
1199 /**
1200 Return TPM2 ManagementFlags set by PP interface.
1201
1202 @retval ManagementFlags TPM2 Management Flags.
1203 **/
1204 UINT32
1205 EFIAPI
Tcg2PhysicalPresenceLibGetManagementFlags(VOID)1206 Tcg2PhysicalPresenceLibGetManagementFlags (
1207 VOID
1208 )
1209 {
1210 EFI_STATUS Status;
1211 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags;
1212 UINTN DataSize;
1213
1214 DEBUG ((EFI_D_INFO, "[TPM2] GetManagementFlags\n"));
1215
1216 DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
1217 Status = gRT->GetVariable (
1218 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
1219 &gEfiTcg2PhysicalPresenceGuid,
1220 NULL,
1221 &DataSize,
1222 &PpiFlags
1223 );
1224 if (EFI_ERROR (Status)) {
1225 PpiFlags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT | TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_DEFAULT;
1226 }
1227 return PpiFlags.PPFlags;
1228 }
1229