1 /** @file
2
3 Execute pending TPM requests from OS or BIOS and Lock TPM.
4
5 Caution: This module requires additional review when modified.
6 This driver will have external input - variable.
7 This external input must be validated carefully to avoid security issue.
8
9 ExecutePendingTpmRequest() will receive untrusted input and do validation.
10
11 Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
12 This program and the accompanying materials
13 are licensed and made available under the terms and conditions of the BSD License
14 which accompanies this distribution. The full text of the license may be found at
15 http://opensource.org/licenses/bsd-license.php
16
17 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
18 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19
20 **/
21
22 #include <PiDxe.h>
23
24 #include <Protocol/TcgService.h>
25 #include <Protocol/VariableLock.h>
26 #include <Library/DebugLib.h>
27 #include <Library/BaseMemoryLib.h>
28 #include <Library/UefiRuntimeServicesTableLib.h>
29 #include <Library/UefiDriverEntryPoint.h>
30 #include <Library/UefiBootServicesTableLib.h>
31 #include <Library/UefiLib.h>
32 #include <Library/MemoryAllocationLib.h>
33 #include <Library/PrintLib.h>
34 #include <Library/HiiLib.h>
35 #include <Guid/EventGroup.h>
36 #include <Guid/PhysicalPresenceData.h>
37 #include <Library/TcgPpVendorLib.h>
38
39 #define CONFIRM_BUFFER_SIZE 4096
40
41 EFI_HII_HANDLE mPpStringPackHandle;
42
43 /**
44 Get string by string id from HII Interface.
45
46 @param[in] Id String ID.
47
48 @retval CHAR16 * String from ID.
49 @retval NULL If error occurs.
50
51 **/
52 CHAR16 *
PhysicalPresenceGetStringById(IN EFI_STRING_ID Id)53 PhysicalPresenceGetStringById (
54 IN EFI_STRING_ID Id
55 )
56 {
57 return HiiGetString (mPpStringPackHandle, Id, NULL);
58 }
59
60 /**
61 Get TPM physical presence permanent flags.
62
63 @param[in] TcgProtocol EFI TCG Protocol instance.
64 @param[out] LifetimeLock physicalPresenceLifetimeLock permanent flag.
65 @param[out] CmdEnable physicalPresenceCMDEnable permanent flag.
66
67 @retval EFI_SUCCESS Flags were returns successfully.
68 @retval other Failed to locate EFI TCG Protocol.
69
70 **/
71 EFI_STATUS
GetTpmCapability(IN EFI_TCG_PROTOCOL * TcgProtocol,OUT BOOLEAN * LifetimeLock,OUT BOOLEAN * CmdEnable)72 GetTpmCapability (
73 IN EFI_TCG_PROTOCOL *TcgProtocol,
74 OUT BOOLEAN *LifetimeLock,
75 OUT BOOLEAN *CmdEnable
76 )
77 {
78 EFI_STATUS Status;
79 TPM_RQU_COMMAND_HDR *TpmRqu;
80 TPM_RSP_COMMAND_HDR *TpmRsp;
81 UINT32 *SendBufPtr;
82 UINT8 SendBuffer[sizeof (*TpmRqu) + sizeof (UINT32) * 3];
83 TPM_PERMANENT_FLAGS *TpmPermanentFlags;
84 UINT8 RecvBuffer[40];
85
86 //
87 // Fill request header
88 //
89 TpmRsp = (TPM_RSP_COMMAND_HDR*)RecvBuffer;
90 TpmRqu = (TPM_RQU_COMMAND_HDR*)SendBuffer;
91
92 TpmRqu->tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
93 TpmRqu->paramSize = SwapBytes32 (sizeof (SendBuffer));
94 TpmRqu->ordinal = SwapBytes32 (TPM_ORD_GetCapability);
95
96 //
97 // Set request parameter
98 //
99 SendBufPtr = (UINT32*)(TpmRqu + 1);
100 WriteUnaligned32 (SendBufPtr++, SwapBytes32 (TPM_CAP_FLAG));
101 WriteUnaligned32 (SendBufPtr++, SwapBytes32 (sizeof (TPM_CAP_FLAG_PERMANENT)));
102 WriteUnaligned32 (SendBufPtr, SwapBytes32 (TPM_CAP_FLAG_PERMANENT));
103
104 Status = TcgProtocol->PassThroughToTpm (
105 TcgProtocol,
106 sizeof (SendBuffer),
107 (UINT8*)TpmRqu,
108 sizeof (RecvBuffer),
109 (UINT8*)&RecvBuffer
110 );
111 ASSERT_EFI_ERROR (Status);
112 ASSERT (TpmRsp->tag == SwapBytes16 (TPM_TAG_RSP_COMMAND));
113 ASSERT (TpmRsp->returnCode == 0);
114
115 TpmPermanentFlags = (TPM_PERMANENT_FLAGS *)&RecvBuffer[sizeof (TPM_RSP_COMMAND_HDR) + sizeof (UINT32)];
116
117 if (LifetimeLock != NULL) {
118 *LifetimeLock = TpmPermanentFlags->physicalPresenceLifetimeLock;
119 }
120
121 if (CmdEnable != NULL) {
122 *CmdEnable = TpmPermanentFlags->physicalPresenceCMDEnable;
123 }
124
125 return Status;
126 }
127
128 /**
129 Issue TSC_PhysicalPresence command to TPM.
130
131 @param[in] TcgProtocol EFI TCG Protocol instance.
132 @param[in] PhysicalPresence The state to set the TPM's Physical Presence flags.
133
134 @retval EFI_SUCCESS TPM executed the command successfully.
135 @retval EFI_SECURITY_VIOLATION TPM returned error when executing the command.
136 @retval other Failed to locate EFI TCG Protocol.
137
138 **/
139 EFI_STATUS
TpmPhysicalPresence(IN EFI_TCG_PROTOCOL * TcgProtocol,IN TPM_PHYSICAL_PRESENCE PhysicalPresence)140 TpmPhysicalPresence (
141 IN EFI_TCG_PROTOCOL *TcgProtocol,
142 IN TPM_PHYSICAL_PRESENCE PhysicalPresence
143 )
144 {
145 EFI_STATUS Status;
146 TPM_RQU_COMMAND_HDR *TpmRqu;
147 TPM_PHYSICAL_PRESENCE *TpmPp;
148 TPM_RSP_COMMAND_HDR TpmRsp;
149 UINT8 Buffer[sizeof (*TpmRqu) + sizeof (*TpmPp)];
150
151 TpmRqu = (TPM_RQU_COMMAND_HDR*)Buffer;
152 TpmPp = (TPM_PHYSICAL_PRESENCE*)(TpmRqu + 1);
153
154 TpmRqu->tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
155 TpmRqu->paramSize = SwapBytes32 (sizeof (Buffer));
156 TpmRqu->ordinal = SwapBytes32 (TSC_ORD_PhysicalPresence);
157 WriteUnaligned16 (TpmPp, (TPM_PHYSICAL_PRESENCE) SwapBytes16 (PhysicalPresence));
158
159 Status = TcgProtocol->PassThroughToTpm (
160 TcgProtocol,
161 sizeof (Buffer),
162 (UINT8*)TpmRqu,
163 sizeof (TpmRsp),
164 (UINT8*)&TpmRsp
165 );
166 ASSERT_EFI_ERROR (Status);
167 ASSERT (TpmRsp.tag == SwapBytes16 (TPM_TAG_RSP_COMMAND));
168 if (TpmRsp.returnCode != 0) {
169 //
170 // If it fails, some requirements may be needed for this command.
171 //
172 return EFI_SECURITY_VIOLATION;
173 }
174
175 return Status;
176 }
177
178 /**
179 Issue a TPM command for which no additional output data will be returned.
180
181 @param[in] TcgProtocol EFI TCG Protocol instance.
182 @param[in] Ordinal TPM command code.
183 @param[in] AdditionalParameterSize Additional parameter size.
184 @param[in] AdditionalParameters Pointer to the Additional paramaters.
185
186 @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Error occurred during sending command to TPM or
187 receiving response from TPM.
188 @retval Others Return code from the TPM device after command execution.
189
190 **/
191 UINT32
TpmCommandNoReturnData(IN EFI_TCG_PROTOCOL * TcgProtocol,IN TPM_COMMAND_CODE Ordinal,IN UINTN AdditionalParameterSize,IN VOID * AdditionalParameters)192 TpmCommandNoReturnData (
193 IN EFI_TCG_PROTOCOL *TcgProtocol,
194 IN TPM_COMMAND_CODE Ordinal,
195 IN UINTN AdditionalParameterSize,
196 IN VOID *AdditionalParameters
197 )
198 {
199 EFI_STATUS Status;
200 TPM_RQU_COMMAND_HDR *TpmRqu;
201 TPM_RSP_COMMAND_HDR TpmRsp;
202 UINT32 Size;
203
204 TpmRqu = (TPM_RQU_COMMAND_HDR*) AllocatePool (sizeof (*TpmRqu) + AdditionalParameterSize);
205 if (TpmRqu == NULL) {
206 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
207 }
208
209 TpmRqu->tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
210 Size = (UINT32)(sizeof (*TpmRqu) + AdditionalParameterSize);
211 TpmRqu->paramSize = SwapBytes32 (Size);
212 TpmRqu->ordinal = SwapBytes32 (Ordinal);
213 CopyMem (TpmRqu + 1, AdditionalParameters, AdditionalParameterSize);
214
215 Status = TcgProtocol->PassThroughToTpm (
216 TcgProtocol,
217 Size,
218 (UINT8*)TpmRqu,
219 (UINT32)sizeof (TpmRsp),
220 (UINT8*)&TpmRsp
221 );
222 FreePool (TpmRqu);
223 if (EFI_ERROR (Status) || (TpmRsp.tag != SwapBytes16 (TPM_TAG_RSP_COMMAND))) {
224 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
225 }
226 return SwapBytes32 (TpmRsp.returnCode);
227 }
228
229 /**
230 Execute physical presence operation requested by the OS.
231
232 @param[in] TcgProtocol EFI TCG Protocol instance.
233 @param[in] CommandCode Physical presence operation value.
234 @param[in, out] PpiFlags The physical presence interface flags.
235
236 @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Unknown physical presence operation.
237 @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Error occurred during sending command to TPM or
238 receiving response from TPM.
239 @retval Others Return code from the TPM device after command execution.
240
241 **/
242 UINT32
ExecutePhysicalPresence(IN EFI_TCG_PROTOCOL * TcgProtocol,IN UINT32 CommandCode,IN OUT EFI_PHYSICAL_PRESENCE_FLAGS * PpiFlags)243 ExecutePhysicalPresence (
244 IN EFI_TCG_PROTOCOL *TcgProtocol,
245 IN UINT32 CommandCode,
246 IN OUT EFI_PHYSICAL_PRESENCE_FLAGS *PpiFlags
247 )
248 {
249 BOOLEAN BoolVal;
250 UINT32 TpmResponse;
251 UINT32 InData[5];
252
253 switch (CommandCode) {
254 case PHYSICAL_PRESENCE_ENABLE:
255 return TpmCommandNoReturnData (
256 TcgProtocol,
257 TPM_ORD_PhysicalEnable,
258 0,
259 NULL
260 );
261
262 case PHYSICAL_PRESENCE_DISABLE:
263 return TpmCommandNoReturnData (
264 TcgProtocol,
265 TPM_ORD_PhysicalDisable,
266 0,
267 NULL
268 );
269
270 case PHYSICAL_PRESENCE_ACTIVATE:
271 BoolVal = FALSE;
272 return TpmCommandNoReturnData (
273 TcgProtocol,
274 TPM_ORD_PhysicalSetDeactivated,
275 sizeof (BoolVal),
276 &BoolVal
277 );
278
279 case PHYSICAL_PRESENCE_DEACTIVATE:
280 BoolVal = TRUE;
281 return TpmCommandNoReturnData (
282 TcgProtocol,
283 TPM_ORD_PhysicalSetDeactivated,
284 sizeof (BoolVal),
285 &BoolVal
286 );
287
288 case PHYSICAL_PRESENCE_CLEAR:
289 return TpmCommandNoReturnData (
290 TcgProtocol,
291 TPM_ORD_ForceClear,
292 0,
293 NULL
294 );
295
296 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE:
297 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE, PpiFlags);
298 if (TpmResponse == 0) {
299 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ACTIVATE, PpiFlags);
300 }
301 return TpmResponse;
302
303 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE:
304 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_DEACTIVATE, PpiFlags);
305 if (TpmResponse == 0) {
306 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_DISABLE, PpiFlags);
307 }
308 return TpmResponse;
309
310 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE:
311 BoolVal = TRUE;
312 return TpmCommandNoReturnData (
313 TcgProtocol,
314 TPM_ORD_SetOwnerInstall,
315 sizeof (BoolVal),
316 &BoolVal
317 );
318
319 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE:
320 BoolVal = FALSE;
321 return TpmCommandNoReturnData (
322 TcgProtocol,
323 TPM_ORD_SetOwnerInstall,
324 sizeof (BoolVal),
325 &BoolVal
326 );
327
328 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE:
329 //
330 // PHYSICAL_PRESENCE_ENABLE_ACTIVATE + PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE
331 // PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE will be executed after reboot
332 //
333 if ((PpiFlags->PPFlags & TCG_VENDOR_LIB_FLAG_RESET_TRACK) == 0) {
334 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE_ACTIVATE, PpiFlags);
335 PpiFlags->PPFlags |= TCG_VENDOR_LIB_FLAG_RESET_TRACK;
336 } else {
337 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE, PpiFlags);
338 PpiFlags->PPFlags &= ~TCG_VENDOR_LIB_FLAG_RESET_TRACK;
339 }
340 return TpmResponse;
341
342 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE:
343 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE, PpiFlags);
344 if (TpmResponse == 0) {
345 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_DEACTIVATE_DISABLE, PpiFlags);
346 }
347 return TpmResponse;
348
349 case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:
350 InData[0] = SwapBytes32 (TPM_SET_STCLEAR_DATA); // CapabilityArea
351 InData[1] = SwapBytes32 (sizeof(UINT32)); // SubCapSize
352 InData[2] = SwapBytes32 (TPM_SD_DEFERREDPHYSICALPRESENCE); // SubCap
353 InData[3] = SwapBytes32 (sizeof(UINT32)); // SetValueSize
354 InData[4] = SwapBytes32 (1); // UnownedFieldUpgrade; bit0
355 return TpmCommandNoReturnData (
356 TcgProtocol,
357 TPM_ORD_SetCapability,
358 sizeof (UINT32) * 5,
359 InData
360 );
361
362 case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH:
363 //
364 // TPM_SetOperatorAuth
365 // This command requires UI to prompt user for Auth data
366 // Here it is NOT implemented
367 //
368 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
369
370 case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE:
371 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_CLEAR, PpiFlags);
372 if (TpmResponse == 0) {
373 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE_ACTIVATE, PpiFlags);
374 }
375 return TpmResponse;
376
377 case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_FALSE:
378 PpiFlags->PPFlags &= ~TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION;
379 return 0;
380
381 case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_TRUE:
382 PpiFlags->PPFlags |= TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION;
383 return 0;
384
385 case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE:
386 PpiFlags->PPFlags &= ~TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR;
387 return 0;
388
389 case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE:
390 PpiFlags->PPFlags |= TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR;
391 return 0;
392
393 case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_FALSE:
394 PpiFlags->PPFlags &= ~TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_MAINTENANCE;
395 return 0;
396
397 case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_TRUE:
398 PpiFlags->PPFlags |= TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_MAINTENANCE;
399 return 0;
400
401 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR:
402 //
403 // PHYSICAL_PRESENCE_ENABLE_ACTIVATE + PHYSICAL_PRESENCE_CLEAR
404 // PHYSICAL_PRESENCE_CLEAR will be executed after reboot.
405 //
406 if ((PpiFlags->PPFlags & TCG_VENDOR_LIB_FLAG_RESET_TRACK) == 0) {
407 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE_ACTIVATE, PpiFlags);
408 PpiFlags->PPFlags |= TCG_VENDOR_LIB_FLAG_RESET_TRACK;
409 } else {
410 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_CLEAR, PpiFlags);
411 PpiFlags->PPFlags &= ~TCG_VENDOR_LIB_FLAG_RESET_TRACK;
412 }
413 return TpmResponse;
414
415 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:
416 //
417 // PHYSICAL_PRESENCE_ENABLE_ACTIVATE + PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE
418 // PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE will be executed after reboot.
419 //
420 if ((PpiFlags->PPFlags & TCG_VENDOR_LIB_FLAG_RESET_TRACK) == 0) {
421 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE_ACTIVATE, PpiFlags);
422 PpiFlags->PPFlags |= TCG_VENDOR_LIB_FLAG_RESET_TRACK;
423 } else {
424 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE, PpiFlags);
425 PpiFlags->PPFlags &= ~TCG_VENDOR_LIB_FLAG_RESET_TRACK;
426 }
427 return TpmResponse;
428
429 default:
430 ;
431 }
432 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
433 }
434
435
436 /**
437 Read the specified key for user confirmation.
438
439 @param[in] CautionKey If true, F12 is used as confirm key;
440 If false, F10 is used as confirm key.
441
442 @retval TRUE User confirmed the changes by input.
443 @retval FALSE User discarded the changes or device error.
444
445 **/
446 BOOLEAN
ReadUserKey(IN BOOLEAN CautionKey)447 ReadUserKey (
448 IN BOOLEAN CautionKey
449 )
450 {
451 EFI_STATUS Status;
452 EFI_INPUT_KEY Key;
453 UINT16 InputKey;
454 UINTN Index;
455
456 InputKey = 0;
457 do {
458 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
459 if (Status == EFI_NOT_READY) {
460 gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index);
461 continue;
462 }
463
464 if (Status == EFI_DEVICE_ERROR) {
465 return FALSE;
466 }
467
468 if (Key.ScanCode == SCAN_ESC) {
469 InputKey = Key.ScanCode;
470 }
471 if ((Key.ScanCode == SCAN_F10) && !CautionKey) {
472 InputKey = Key.ScanCode;
473 }
474 if ((Key.ScanCode == SCAN_F12) && CautionKey) {
475 InputKey = Key.ScanCode;
476 }
477 } while (InputKey == 0);
478
479 if (InputKey != SCAN_ESC) {
480 return TRUE;
481 }
482
483 return FALSE;
484 }
485
486 /**
487 The constructor function register UNI strings into imageHandle.
488
489 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
490
491 @param ImageHandle The firmware allocated handle for the EFI image.
492 @param SystemTable A pointer to the EFI System Table.
493
494 @retval EFI_SUCCESS The constructor successfully added string package.
495 @retval Other value The constructor can't add string package.
496
497 **/
498 EFI_STATUS
499 EFIAPI
TcgPhysicalPresenceLibConstructor(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)500 TcgPhysicalPresenceLibConstructor (
501 IN EFI_HANDLE ImageHandle,
502 IN EFI_SYSTEM_TABLE *SystemTable
503 )
504 {
505 mPpStringPackHandle = HiiAddPackages (&gEfiPhysicalPresenceGuid, ImageHandle, DxeTcgPhysicalPresenceLibStrings, NULL);
506 ASSERT (mPpStringPackHandle != NULL);
507
508 return EFI_SUCCESS;
509 }
510
511 /**
512 Display the confirm text and get user confirmation.
513
514 @param[in] TpmPpCommand The requested TPM physical presence command.
515
516 @retval TRUE The user has confirmed the changes.
517 @retval FALSE The user doesn't confirm the changes.
518 **/
519 BOOLEAN
UserConfirm(IN UINT32 TpmPpCommand)520 UserConfirm (
521 IN UINT32 TpmPpCommand
522 )
523 {
524 CHAR16 *ConfirmText;
525 CHAR16 *TmpStr1;
526 CHAR16 *TmpStr2;
527 UINTN BufSize;
528 BOOLEAN CautionKey;
529 UINT16 Index;
530 CHAR16 DstStr[81];
531
532 TmpStr2 = NULL;
533 CautionKey = FALSE;
534 BufSize = CONFIRM_BUFFER_SIZE;
535 ConfirmText = AllocateZeroPool (BufSize);
536 ASSERT (ConfirmText != NULL);
537
538 switch (TpmPpCommand) {
539 case PHYSICAL_PRESENCE_ENABLE:
540 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE));
541
542 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
543 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
544 FreePool (TmpStr1);
545
546 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
547 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
548 FreePool (TmpStr1);
549 break;
550
551 case PHYSICAL_PRESENCE_DISABLE:
552 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DISABLE));
553
554 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
555 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
556 FreePool (TmpStr1);
557
558 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING));
559 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
560 FreePool (TmpStr1);
561
562 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
563 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
564 FreePool (TmpStr1);
565 break;
566
567 case PHYSICAL_PRESENCE_ACTIVATE:
568 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACTIVATE));
569
570 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
571 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
572 FreePool (TmpStr1);
573
574 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
575 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
576 FreePool (TmpStr1);
577 break;
578
579 case PHYSICAL_PRESENCE_DEACTIVATE:
580 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DEACTIVATE));
581
582 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
583 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
584 FreePool (TmpStr1);
585
586 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING));
587 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
588 FreePool (TmpStr1);
589
590 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
591 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
592 FreePool (TmpStr1);
593 break;
594
595 case PHYSICAL_PRESENCE_CLEAR:
596 CautionKey = TRUE;
597 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));
598
599 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
600 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
601 FreePool (TmpStr1);
602
603 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
604 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
605 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
606 FreePool (TmpStr1);
607
608 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
609 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
610 FreePool (TmpStr1);
611 break;
612
613 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE:
614 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_ACTIVATE));
615
616 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
617 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
618 FreePool (TmpStr1);
619
620 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON));
621 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
622 FreePool (TmpStr1);
623
624 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
625 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
626 FreePool (TmpStr1);
627 break;
628
629 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE:
630 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DEACTIVATE_DISABLE));
631
632 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
633 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
634 FreePool (TmpStr1);
635
636 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_OFF));
637 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
638 FreePool (TmpStr1);
639
640 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING));
641 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
642 FreePool (TmpStr1);
643
644 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
645 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
646 FreePool (TmpStr1);
647 break;
648
649 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE:
650 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ALLOW_TAKE_OWNERSHIP));
651
652 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
653 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
654 FreePool (TmpStr1);
655
656 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
657 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
658 FreePool (TmpStr1);
659 break;
660
661 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE:
662 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DISALLOW_TAKE_OWNERSHIP));
663
664 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
665 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
666 FreePool (TmpStr1);
667
668 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
669 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
670 FreePool (TmpStr1);
671 break;
672
673 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE:
674 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_TURN_ON));
675
676 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
677 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
678 FreePool (TmpStr1);
679
680 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON));
681 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
682 FreePool (TmpStr1);
683
684 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
685 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
686 FreePool (TmpStr1);
687 break;
688
689 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE:
690 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_TURN_OFF));
691
692 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
693 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
694 FreePool (TmpStr1);
695
696 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_OFF));
697 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
698 FreePool (TmpStr1);
699
700 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING));
701 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
702 FreePool (TmpStr1);
703
704 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
705 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
706 FreePool (TmpStr1);
707 break;
708
709 case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:
710 CautionKey = TRUE;
711 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_UNOWNED_FIELD_UPGRADE));
712
713 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_UPGRADE_HEAD_STR));
714 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
715 FreePool (TmpStr1);
716
717 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_MAINTAIN));
718 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
719 FreePool (TmpStr1);
720
721 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
722 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
723 FreePool (TmpStr1);
724 break;
725
726 case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH:
727 //
728 // TPM_SetOperatorAuth
729 // This command requires UI to prompt user for Auth data
730 // Here it is NOT implemented
731 //
732 break;
733
734 case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE:
735 CautionKey = TRUE;
736 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR_TURN_ON));
737
738 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
739 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
740 FreePool (TmpStr1);
741
742 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON));
743 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
744 FreePool (TmpStr1);
745
746 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
747 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
748 FreePool (TmpStr1);
749
750 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR_CONT));
751 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
752 FreePool (TmpStr1);
753
754 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
755 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
756 FreePool (TmpStr1);
757 break;
758
759 case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_TRUE:
760 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_PROVISION));
761
762 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));
763 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
764 FreePool (TmpStr1);
765
766 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
767 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
768 FreePool (TmpStr1);
769
770 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));
771 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
772 FreePool (TmpStr1);
773 break;
774
775 case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE:
776 CautionKey = TRUE;
777 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));
778
779 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));
780 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
781 FreePool (TmpStr1);
782
783 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_CLEAR));
784 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
785 FreePool (TmpStr1);
786
787 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
788 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
789 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
790 FreePool (TmpStr1);
791
792 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
793 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
794 FreePool (TmpStr1);
795
796 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));
797 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
798 FreePool (TmpStr1);
799 break;
800
801 case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_TRUE:
802 CautionKey = TRUE;
803 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_MAINTAIN));
804
805 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));
806 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
807 FreePool (TmpStr1);
808
809 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_MAINTAIN));
810 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
811 FreePool (TmpStr1);
812
813 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
814 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
815 FreePool (TmpStr1);
816
817 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));
818 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
819 FreePool (TmpStr1);
820 break;
821
822 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR:
823 CautionKey = TRUE;
824 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_ACTIVATE_CLEAR));
825
826 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
827 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
828 FreePool (TmpStr1);
829
830 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
831 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
832 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
833 FreePool (TmpStr1);
834
835 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
836 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
837 FreePool (TmpStr1);
838 break;
839
840 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:
841 CautionKey = TRUE;
842 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE));
843
844 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
845 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
846 FreePool (TmpStr1);
847
848 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON));
849 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
850 FreePool (TmpStr1);
851
852 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
853 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
854 FreePool (TmpStr1);
855
856 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR_CONT));
857 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
858 FreePool (TmpStr1);
859
860 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
861 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
862 FreePool (TmpStr1);
863 break;
864
865 default:
866 ;
867 }
868
869 if (TmpStr2 == NULL) {
870 FreePool (ConfirmText);
871 return FALSE;
872 }
873
874 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY));
875 BufSize -= StrSize (ConfirmText);
876 UnicodeSPrint (ConfirmText + StrLen (ConfirmText), BufSize, TmpStr1, TmpStr2);
877
878 DstStr[80] = L'\0';
879 for (Index = 0; Index < StrLen (ConfirmText); Index += 80) {
880 StrnCpyS(DstStr, sizeof (DstStr) / sizeof (CHAR16), ConfirmText + Index, sizeof (DstStr) / sizeof (CHAR16) - 1);
881 Print (DstStr);
882 }
883
884 FreePool (TmpStr1);
885 FreePool (TmpStr2);
886 FreePool (ConfirmText);
887
888 if (ReadUserKey (CautionKey)) {
889 return TRUE;
890 }
891
892 return FALSE;
893 }
894
895 /**
896 Check if there is a valid physical presence command request. Also updates parameter value
897 to whether the requested physical presence command already confirmed by user
898
899 @param[in] TcgPpData EFI TCG Physical Presence request data.
900 @param[in] Flags The physical presence interface flags.
901 @param[out] RequestConfirmed If the physical presence operation command required user confirm from UI.
902 True, it indicates the command doesn't require user confirm, or already confirmed
903 in last boot cycle by user.
904 False, it indicates the command need user confirm from UI.
905
906 @retval TRUE Physical Presence operation command is valid.
907 @retval FALSE Physical Presence operation command is invalid.
908
909 **/
910 BOOLEAN
HaveValidTpmRequest(IN EFI_PHYSICAL_PRESENCE * TcgPpData,IN EFI_PHYSICAL_PRESENCE_FLAGS Flags,OUT BOOLEAN * RequestConfirmed)911 HaveValidTpmRequest (
912 IN EFI_PHYSICAL_PRESENCE *TcgPpData,
913 IN EFI_PHYSICAL_PRESENCE_FLAGS Flags,
914 OUT BOOLEAN *RequestConfirmed
915 )
916 {
917 BOOLEAN IsRequestValid;
918
919 *RequestConfirmed = FALSE;
920
921 switch (TcgPpData->PPRequest) {
922 case PHYSICAL_PRESENCE_NO_ACTION:
923 *RequestConfirmed = TRUE;
924 return TRUE;
925 case PHYSICAL_PRESENCE_ENABLE:
926 case PHYSICAL_PRESENCE_DISABLE:
927 case PHYSICAL_PRESENCE_ACTIVATE:
928 case PHYSICAL_PRESENCE_DEACTIVATE:
929 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE:
930 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE:
931 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE:
932 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE:
933 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE:
934 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE:
935 case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH:
936 if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION) != 0) {
937 *RequestConfirmed = TRUE;
938 }
939 break;
940
941 case PHYSICAL_PRESENCE_CLEAR:
942 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR:
943 if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR) != 0) {
944 *RequestConfirmed = TRUE;
945 }
946 break;
947
948 case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:
949 if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_MAINTENANCE) != 0) {
950 *RequestConfirmed = TRUE;
951 }
952 break;
953
954 case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE:
955 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:
956 if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR) != 0 && (Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION) != 0) {
957 *RequestConfirmed = TRUE;
958 }
959 break;
960
961 case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_FALSE:
962 case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE:
963 case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_FALSE:
964 *RequestConfirmed = TRUE;
965 break;
966
967 case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_TRUE:
968 case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE:
969 case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_TRUE:
970 break;
971
972 default:
973 if (TcgPpData->PPRequest >= TCG_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
974 IsRequestValid = TcgPpVendorLibHasValidRequest (TcgPpData->PPRequest, Flags.PPFlags, RequestConfirmed);
975 if (!IsRequestValid) {
976 return FALSE;
977 } else {
978 break;
979 }
980 } else {
981 //
982 // Wrong Physical Presence command
983 //
984 return FALSE;
985 }
986 }
987
988 if ((Flags.PPFlags & TCG_VENDOR_LIB_FLAG_RESET_TRACK) != 0) {
989 //
990 // It had been confirmed in last boot, it doesn't need confirm again.
991 //
992 *RequestConfirmed = TRUE;
993 }
994
995 //
996 // Physical Presence command is correct
997 //
998 return TRUE;
999 }
1000
1001
1002 /**
1003 Check and execute the requested physical presence command.
1004
1005 Caution: This function may receive untrusted input.
1006 TcgPpData variable is external input, so this function will validate
1007 its data structure to be valid value.
1008
1009 @param[in] TcgProtocol EFI TCG Protocol instance.
1010 @param[in] TcgPpData Point to the physical presence NV variable.
1011 @param[in] Flags The physical presence interface flags.
1012
1013 **/
1014 VOID
ExecutePendingTpmRequest(IN EFI_TCG_PROTOCOL * TcgProtocol,IN EFI_PHYSICAL_PRESENCE * TcgPpData,IN EFI_PHYSICAL_PRESENCE_FLAGS Flags)1015 ExecutePendingTpmRequest (
1016 IN EFI_TCG_PROTOCOL *TcgProtocol,
1017 IN EFI_PHYSICAL_PRESENCE *TcgPpData,
1018 IN EFI_PHYSICAL_PRESENCE_FLAGS Flags
1019 )
1020 {
1021 EFI_STATUS Status;
1022 UINTN DataSize;
1023 BOOLEAN RequestConfirmed;
1024 EFI_PHYSICAL_PRESENCE_FLAGS NewFlags;
1025 BOOLEAN ResetRequired;
1026 UINT32 NewPPFlags;
1027
1028 if (!HaveValidTpmRequest(TcgPpData, Flags, &RequestConfirmed)) {
1029 //
1030 // Invalid operation request.
1031 //
1032 TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
1033 TcgPpData->LastPPRequest = TcgPpData->PPRequest;
1034 TcgPpData->PPRequest = PHYSICAL_PRESENCE_NO_ACTION;
1035 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
1036 Status = gRT->SetVariable (
1037 PHYSICAL_PRESENCE_VARIABLE,
1038 &gEfiPhysicalPresenceGuid,
1039 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
1040 DataSize,
1041 TcgPpData
1042 );
1043 return;
1044 }
1045
1046 ResetRequired = FALSE;
1047 if (TcgPpData->PPRequest >= TCG_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
1048 NewFlags = Flags;
1049 NewPPFlags = NewFlags.PPFlags;
1050 TcgPpData->PPResponse = TcgPpVendorLibExecutePendingRequest (TcgPpData->PPRequest, &NewPPFlags, &ResetRequired);
1051 NewFlags.PPFlags = (UINT8)NewPPFlags;
1052 } else {
1053 if (!RequestConfirmed) {
1054 //
1055 // Print confirm text and wait for approval.
1056 //
1057 RequestConfirmed = UserConfirm (TcgPpData->PPRequest);
1058 }
1059
1060 //
1061 // Execute requested physical presence command
1062 //
1063 TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_USER_ABORT;
1064 NewFlags = Flags;
1065 if (RequestConfirmed) {
1066 TcgPpData->PPResponse = ExecutePhysicalPresence (TcgProtocol, TcgPpData->PPRequest, &NewFlags);
1067 }
1068 }
1069
1070 //
1071 // Save the flags if it is updated.
1072 //
1073 if (CompareMem (&Flags, &NewFlags, sizeof(EFI_PHYSICAL_PRESENCE_FLAGS)) != 0) {
1074 Status = gRT->SetVariable (
1075 PHYSICAL_PRESENCE_FLAGS_VARIABLE,
1076 &gEfiPhysicalPresenceGuid,
1077 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
1078 sizeof (EFI_PHYSICAL_PRESENCE_FLAGS),
1079 &NewFlags
1080 );
1081 if (EFI_ERROR (Status)) {
1082 return;
1083 }
1084 }
1085
1086 //
1087 // Clear request
1088 //
1089 if ((NewFlags.PPFlags & TCG_VENDOR_LIB_FLAG_RESET_TRACK) == 0) {
1090 TcgPpData->LastPPRequest = TcgPpData->PPRequest;
1091 TcgPpData->PPRequest = PHYSICAL_PRESENCE_NO_ACTION;
1092 }
1093
1094 //
1095 // Save changes
1096 //
1097 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
1098 Status = gRT->SetVariable (
1099 PHYSICAL_PRESENCE_VARIABLE,
1100 &gEfiPhysicalPresenceGuid,
1101 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
1102 DataSize,
1103 TcgPpData
1104 );
1105 if (EFI_ERROR (Status)) {
1106 return;
1107 }
1108
1109 if (TcgPpData->PPResponse == TCG_PP_OPERATION_RESPONSE_USER_ABORT) {
1110 return;
1111 }
1112
1113 //
1114 // Reset system to make new TPM settings in effect
1115 //
1116 switch (TcgPpData->LastPPRequest) {
1117 case PHYSICAL_PRESENCE_ACTIVATE:
1118 case PHYSICAL_PRESENCE_DEACTIVATE:
1119 case PHYSICAL_PRESENCE_CLEAR:
1120 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE:
1121 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE:
1122 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE:
1123 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE:
1124 case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:
1125 case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE:
1126 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR:
1127 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:
1128 break;
1129 default:
1130 if (TcgPpData->LastPPRequest >= TCG_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
1131 if (ResetRequired) {
1132 break;
1133 } else {
1134 return ;
1135 }
1136 }
1137 if (TcgPpData->PPRequest != PHYSICAL_PRESENCE_NO_ACTION) {
1138 break;
1139 }
1140 return;
1141 }
1142
1143 Print (L"Rebooting system to make TPM settings in effect\n");
1144 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
1145 ASSERT (FALSE);
1146 }
1147
1148 /**
1149 Check and execute the pending TPM request and Lock TPM.
1150
1151 The TPM request may come from OS or BIOS. This API will display request information and wait
1152 for user confirmation if TPM request exists. The TPM request will be sent to TPM device after
1153 the TPM request is confirmed, and one or more reset may be required to make TPM request to
1154 take effect. At last, it will lock TPM to prevent TPM state change by malware.
1155
1156 This API should be invoked after console in and console out are all ready as they are required
1157 to display request information and get user input to confirm the request. This API should also
1158 be invoked as early as possible as TPM is locked in this function.
1159
1160 **/
1161 VOID
1162 EFIAPI
TcgPhysicalPresenceLibProcessRequest(VOID)1163 TcgPhysicalPresenceLibProcessRequest (
1164 VOID
1165 )
1166 {
1167 EFI_STATUS Status;
1168 BOOLEAN LifetimeLock;
1169 BOOLEAN CmdEnable;
1170 UINTN DataSize;
1171 EFI_PHYSICAL_PRESENCE TcgPpData;
1172 EFI_TCG_PROTOCOL *TcgProtocol;
1173 EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol;
1174 EFI_PHYSICAL_PRESENCE_FLAGS PpiFlags;
1175
1176 Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol);
1177 if (EFI_ERROR (Status)) {
1178 return ;
1179 }
1180
1181 //
1182 // Initialize physical presence flags.
1183 //
1184 DataSize = sizeof (EFI_PHYSICAL_PRESENCE_FLAGS);
1185 Status = gRT->GetVariable (
1186 PHYSICAL_PRESENCE_FLAGS_VARIABLE,
1187 &gEfiPhysicalPresenceGuid,
1188 NULL,
1189 &DataSize,
1190 &PpiFlags
1191 );
1192 if (EFI_ERROR (Status)) {
1193 PpiFlags.PPFlags = TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION;
1194 Status = gRT->SetVariable (
1195 PHYSICAL_PRESENCE_FLAGS_VARIABLE,
1196 &gEfiPhysicalPresenceGuid,
1197 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
1198 sizeof (EFI_PHYSICAL_PRESENCE_FLAGS),
1199 &PpiFlags
1200 );
1201 if (EFI_ERROR (Status)) {
1202 DEBUG ((EFI_D_ERROR, "[TPM] Set physical presence flag failed, Status = %r\n", Status));
1203 return ;
1204 }
1205 }
1206 DEBUG ((EFI_D_INFO, "[TPM] PpiFlags = %x\n", PpiFlags.PPFlags));
1207
1208 //
1209 // This flags variable controls whether physical presence is required for TPM command.
1210 // It should be protected from malicious software. We set it as read-only variable here.
1211 //
1212 Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);
1213 if (!EFI_ERROR (Status)) {
1214 Status = VariableLockProtocol->RequestToLock (
1215 VariableLockProtocol,
1216 PHYSICAL_PRESENCE_FLAGS_VARIABLE,
1217 &gEfiPhysicalPresenceGuid
1218 );
1219 if (EFI_ERROR (Status)) {
1220 DEBUG ((EFI_D_ERROR, "[TPM] Error when lock variable %s, Status = %r\n", PHYSICAL_PRESENCE_FLAGS_VARIABLE, Status));
1221 ASSERT_EFI_ERROR (Status);
1222 }
1223 }
1224
1225 //
1226 // Initialize physical presence variable.
1227 //
1228 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
1229 Status = gRT->GetVariable (
1230 PHYSICAL_PRESENCE_VARIABLE,
1231 &gEfiPhysicalPresenceGuid,
1232 NULL,
1233 &DataSize,
1234 &TcgPpData
1235 );
1236 if (EFI_ERROR (Status)) {
1237 ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData));
1238 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
1239 Status = gRT->SetVariable (
1240 PHYSICAL_PRESENCE_VARIABLE,
1241 &gEfiPhysicalPresenceGuid,
1242 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
1243 DataSize,
1244 &TcgPpData
1245 );
1246 if (EFI_ERROR (Status)) {
1247 DEBUG ((EFI_D_ERROR, "[TPM] Set physical presence variable failed, Status = %r\n", Status));
1248 return;
1249 }
1250 }
1251
1252 DEBUG ((EFI_D_INFO, "[TPM] Flags=%x, PPRequest=%x\n", PpiFlags.PPFlags, TcgPpData.PPRequest));
1253
1254 if (TcgPpData.PPRequest == PHYSICAL_PRESENCE_NO_ACTION) {
1255 //
1256 // No operation request
1257 //
1258 return;
1259 }
1260
1261 Status = GetTpmCapability (TcgProtocol, &LifetimeLock, &CmdEnable);
1262 if (EFI_ERROR (Status)) {
1263 return ;
1264 }
1265
1266 if (!CmdEnable) {
1267 if (LifetimeLock) {
1268 //
1269 // physicalPresenceCMDEnable is locked, can't execute physical presence command.
1270 //
1271 return ;
1272 }
1273 Status = TpmPhysicalPresence (TcgProtocol, TPM_PHYSICAL_PRESENCE_CMD_ENABLE);
1274 if (EFI_ERROR (Status)) {
1275 return ;
1276 }
1277 }
1278
1279 //
1280 // Set operator physical presence flags
1281 //
1282 TpmPhysicalPresence (TcgProtocol, TPM_PHYSICAL_PRESENCE_PRESENT);
1283
1284 //
1285 // Execute pending TPM request.
1286 //
1287 ExecutePendingTpmRequest (TcgProtocol, &TcgPpData, PpiFlags);
1288 DEBUG ((EFI_D_INFO, "[TPM] PPResponse = %x\n", TcgPpData.PPResponse));
1289
1290 //
1291 // Lock physical presence.
1292 //
1293 TpmPhysicalPresence (TcgProtocol, TPM_PHYSICAL_PRESENCE_NOTPRESENT | TPM_PHYSICAL_PRESENCE_LOCK);
1294 }
1295
1296 /**
1297 Check if the pending TPM request needs user input to confirm.
1298
1299 The TPM request may come from OS. This API will check if TPM request exists and need user
1300 input to confirmation.
1301
1302 @retval TRUE TPM needs input to confirm user physical presence.
1303 @retval FALSE TPM doesn't need input to confirm user physical presence.
1304
1305 **/
1306 BOOLEAN
1307 EFIAPI
TcgPhysicalPresenceLibNeedUserConfirm(VOID)1308 TcgPhysicalPresenceLibNeedUserConfirm(
1309 VOID
1310 )
1311 {
1312 EFI_STATUS Status;
1313 EFI_PHYSICAL_PRESENCE TcgPpData;
1314 UINTN DataSize;
1315 BOOLEAN RequestConfirmed;
1316 BOOLEAN LifetimeLock;
1317 BOOLEAN CmdEnable;
1318 EFI_TCG_PROTOCOL *TcgProtocol;
1319 EFI_PHYSICAL_PRESENCE_FLAGS PpiFlags;
1320
1321 Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol);
1322 if (EFI_ERROR (Status)) {
1323 return FALSE;
1324 }
1325
1326 //
1327 // Check Tpm requests
1328 //
1329 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
1330 Status = gRT->GetVariable (
1331 PHYSICAL_PRESENCE_VARIABLE,
1332 &gEfiPhysicalPresenceGuid,
1333 NULL,
1334 &DataSize,
1335 &TcgPpData
1336 );
1337 if (EFI_ERROR (Status)) {
1338 return FALSE;
1339 }
1340
1341 DataSize = sizeof (EFI_PHYSICAL_PRESENCE_FLAGS);
1342 Status = gRT->GetVariable (
1343 PHYSICAL_PRESENCE_FLAGS_VARIABLE,
1344 &gEfiPhysicalPresenceGuid,
1345 NULL,
1346 &DataSize,
1347 &PpiFlags
1348 );
1349 if (EFI_ERROR (Status)) {
1350 return FALSE;
1351 }
1352
1353 if (TcgPpData.PPRequest == PHYSICAL_PRESENCE_NO_ACTION) {
1354 //
1355 // No operation request
1356 //
1357 return FALSE;
1358 }
1359
1360 if (!HaveValidTpmRequest(&TcgPpData, PpiFlags, &RequestConfirmed)) {
1361 //
1362 // Invalid operation request.
1363 //
1364 return FALSE;
1365 }
1366
1367 //
1368 // Check Tpm Capability
1369 //
1370 Status = GetTpmCapability (TcgProtocol, &LifetimeLock, &CmdEnable);
1371 if (EFI_ERROR (Status)) {
1372 return FALSE;
1373 }
1374
1375 if (!CmdEnable) {
1376 if (LifetimeLock) {
1377 //
1378 // physicalPresenceCMDEnable is locked, can't execute physical presence command.
1379 //
1380 return FALSE;
1381 }
1382 }
1383
1384 if (!RequestConfirmed) {
1385 //
1386 // Need UI to confirm
1387 //
1388 return TRUE;
1389 }
1390
1391 return FALSE;
1392 }
1393
1394