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