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