2 Tcg PP storage library instance that does support any storage specific PPI.
4 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Guid/PhysicalPresenceData.h>
17 #include <Guid/TcgPhysicalPresenceStorageData.h>
19 #include <IndustryStandard/TcgPhysicalPresence.h>
22 #include <Protocol/VariableLock.h>
24 #include <Library/DebugLib.h>
25 #include <Library/BaseMemoryLib.h>
26 #include <Library/UefiRuntimeServicesTableLib.h>
27 #include <Library/UefiDriverEntryPoint.h>
28 #include <Library/UefiBootServicesTableLib.h>
29 #include <Library/UefiLib.h>
30 #include <Library/MemoryAllocationLib.h>
31 #include <Library/PrintLib.h>
32 #include <Library/HiiLib.h>
33 #include <Library/HobLib.h>
34 #include <Library/TcgPhysicalPresenceStorageLib.h>
36 #include "DxeTcgPhysicalPresenceStorageLibInternal.h"
39 Display the confirm text and get user confirmation.
41 @param[in] OperationRequest TPM physical presence operation request.
42 @param[in] ManagementFlags BIOS TPM Management Flags.
45 @retval TRUE The user need to confirme the changes.
46 @retval FALSE The user doesn't need to confirme the changes.
49 TcgPpNeedUserConfirm (
50 IN UINT8 OperationRequest
,
51 IN UINT32 ManagementFlags
54 BOOLEAN NeedUserConfirm
;
56 NeedUserConfirm
= FALSE
;
58 switch (OperationRequest
) {
59 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
:
60 if ((ManagementFlags
& TCG_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID
) != 0) {
61 NeedUserConfirm
= TRUE
;
65 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
:
66 if ((ManagementFlags
& TCG_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID
) != 0) {
67 NeedUserConfirm
= TRUE
;
71 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE
:
72 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE
:
73 NeedUserConfirm
= TRUE
;
80 return NeedUserConfirm
;
84 The handler for TPM physical presence function:
85 Submit TPM Operation Request to Pre-OS Environment and
86 Submit TPM Operation Request to Pre-OS Environment 2.
88 Caution: This function may receive untrusted input.
90 @param[in] OperationRequest TPM physical presence operation request.
91 @param[in] RequestParameter TPM physical presence operation request parameter.
93 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
94 Submit TPM Operation Request to Pre-OS Environment 2.
98 TcgSubmitStorageRequest (
99 IN UINT32 OperationRequest
,
100 IN UINT32 RequestParameter
105 EFI_PHYSICAL_PRESENCE PpData
;
107 DEBUG ((EFI_D_INFO
, "[TPM Storage] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest
, RequestParameter
));
110 // Get the Physical Presence storage variable
112 DataSize
= sizeof (EFI_PHYSICAL_PRESENCE
);
113 Status
= gRT
->GetVariable (
114 PHYSICAL_PRESENCE_VARIABLE
,
115 &gEfiPhysicalPresenceGuid
,
120 if (EFI_ERROR (Status
)) {
121 DEBUG ((EFI_D_ERROR
, "[TPM Storage] Get PP variable failure! Status = %r\n", Status
));
122 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
;
125 if ((OperationRequest
>= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) &&
126 (OperationRequest
< TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN
) ) {
128 // This library only support storage related actions.
130 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED
;
133 if (PpData
.PPRequest
!= OperationRequest
) {
134 PpData
.PPRequest
= (UINT8
)OperationRequest
;
135 DataSize
= sizeof (EFI_PHYSICAL_PRESENCE
);
136 Status
= gRT
->SetVariable (
137 PHYSICAL_PRESENCE_VARIABLE
,
138 &gEfiPhysicalPresenceGuid
,
139 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
145 if (EFI_ERROR (Status
)) {
146 DEBUG ((EFI_D_ERROR
, "[TPM Storage] Set PP variable failure! Status = %r\n", Status
));
147 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
;
150 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS
;
154 Check if the pending TPM request needs user input to confirm.
156 The TPM request may come from OS. This API will check if TPM request exists and need user
157 input to confirmation.
159 @retval TRUE TPM needs input to confirm user physical presence.
160 @retval FALSE TPM doesn't need input to confirm user physical presence.
170 EFI_PHYSICAL_PRESENCE TcgPpData
;
172 EFI_TCG_PHYSICAL_PRESENCE_STORAGE_FLAGS PpiFlags
;
177 if (GetBootModeHob () == BOOT_ON_S4_RESUME
) {
178 DEBUG ((EFI_D_INFO
, "S4 Resume, Skip TPM PP process!\n"));
183 // Check Tpm requests
185 DataSize
= sizeof (EFI_PHYSICAL_PRESENCE
);
186 Status
= gRT
->GetVariable (
187 PHYSICAL_PRESENCE_VARIABLE
,
188 &gEfiPhysicalPresenceGuid
,
193 if (EFI_ERROR (Status
)) {
197 DataSize
= sizeof (EFI_TCG_PHYSICAL_PRESENCE_STORAGE_FLAGS
);
198 Status
= gRT
->GetVariable (
199 TCG_PHYSICAL_PRESENCE_STORAGE_FLAGS_VARIABLE
,
200 &gEfiTcgPhysicalPresenceStorageGuid
,
205 if (EFI_ERROR (Status
)) {
206 PpiFlags
.PPFlags
= TCG_BIOS_STORAGE_MANAGEMENT_FLAG_DEFAULT
;
209 if ((TcgPpData
.PPRequest
>= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) &&
210 (TcgPpData
.PPRequest
< TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN
) ) {
212 // This library only support storage related actions.
217 return TcgPpNeedUserConfirm(TcgPpData
.PPRequest
, PpiFlags
.PPFlags
);
221 The handler for TPM physical presence function:
222 Return TPM Operation Response to OS Environment.
224 @param[out] MostRecentRequest Most recent operation request.
225 @param[out] Response Response to the most recent operation request.
227 @return Return Code for Return TPM Operation Response to OS Environment.
231 TcgReturnOperationResponseToOsFunction (
232 OUT UINT32
*MostRecentRequest
,
238 EFI_PHYSICAL_PRESENCE PpData
;
240 DEBUG ((EFI_D_INFO
, "[TPM Storage] ReturnOperationResponseToOsFunction\n"));
243 // Get the Physical Presence variable
245 DataSize
= sizeof (EFI_PHYSICAL_PRESENCE
);
246 Status
= gRT
->GetVariable (
247 PHYSICAL_PRESENCE_VARIABLE
,
248 &gEfiPhysicalPresenceGuid
,
253 if (EFI_ERROR (Status
)) {
254 *MostRecentRequest
= 0;
256 DEBUG ((EFI_D_ERROR
, "[TPM Storage] Get PP variable failure! Status = %r\n", Status
));
257 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE
;
260 *MostRecentRequest
= PpData
.LastPPRequest
;
261 *Response
= PpData
.PPResponse
;
263 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS
;
267 Check and execute the requested physical presence command.
269 This API should be invoked in BIOS boot phase to process pending request.
271 Caution: This function may receive untrusted input.
273 If OperationRequest < 128, then ASSERT().
275 @param[in] OperationRequest TPM physical presence operation request.
276 @param[in, out] ManagementFlags BIOS TPM Management Flags.
277 @param[out] ResetRequired If reset is required to vendor settings in effect.
278 True, it indicates the reset is required.
279 False, it indicates the reset is not required.
281 @return TPM Operation Response to OS Environment.
284 TcgExecutePendingRequest (
285 IN UINT8 OperationRequest
,
286 IN OUT UINT8
*ManagementFlags
,
287 OUT BOOLEAN
*ResetRequired
290 ASSERT ((OperationRequest
>= TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN
) &&
291 (OperationRequest
< TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
));
293 if (TcgPpNeedUserConfirm(OperationRequest
, *ManagementFlags
)) {
294 if (!TcgPpUserConfirm (OperationRequest
)) {
295 return TCG_PP_OPERATION_RESPONSE_USER_ABORT
;
299 switch (OperationRequest
) {
300 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE
:
301 *ManagementFlags
|= TCG_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID
;
302 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
304 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE
:
305 *ManagementFlags
&= ~TCG_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID
;
306 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
308 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE
:
309 *ManagementFlags
|= TCG_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID
;
310 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
312 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE
:
313 *ManagementFlags
&= ~TCG_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID
;
314 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
316 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
:
317 *ManagementFlags
|= TCG_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID
;
318 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
320 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
:
321 *ManagementFlags
&= ~TCG_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID
;
322 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
328 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
332 Check and execute the pending TPM request.
334 The TPM request may come from OS or BIOS. This API will display request information and wait
335 for user confirmation if TPM request exists. The TPM request will be sent to TPM device after
336 the TPM request is confirmed, and one or more reset may be required to make TPM request to
339 This API should be invoked after console in and console out are all ready as they are required
340 to display request information and get user input to confirm the request.
342 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
346 TcgProcessStorageRequest (
352 EFI_PHYSICAL_PRESENCE TcgPpData
;
353 EDKII_VARIABLE_LOCK_PROTOCOL
*VariableLockProtocol
;
354 EFI_PHYSICAL_PRESENCE_FLAGS PpiFlags
;
355 EFI_PHYSICAL_PRESENCE_FLAGS NewPpiFlags
;
356 BOOLEAN ResetRequired
;
361 if (GetBootModeHob () == BOOT_ON_S4_RESUME
) {
362 DEBUG ((EFI_D_INFO
, "S4 Resume, Skip TPM PP process!\n"));
367 // Initialize physical presence variable.
369 DataSize
= sizeof (EFI_PHYSICAL_PRESENCE
);
370 Status
= gRT
->GetVariable (
371 PHYSICAL_PRESENCE_VARIABLE
,
372 &gEfiPhysicalPresenceGuid
,
377 if (EFI_ERROR (Status
)) {
378 ZeroMem ((VOID
*)&TcgPpData
, sizeof (TcgPpData
));
379 DataSize
= sizeof (EFI_PHYSICAL_PRESENCE
);
380 Status
= gRT
->SetVariable (
381 PHYSICAL_PRESENCE_VARIABLE
,
382 &gEfiPhysicalPresenceGuid
,
383 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
387 if (EFI_ERROR (Status
)) {
388 DEBUG ((EFI_D_ERROR
, "[TPM Storage] Set physical presence variable failed, Status = %r\n", Status
));
393 if ((TcgPpData
.PPRequest
>= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) ||
394 (TcgPpData
.PPRequest
< TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN
) ) {
396 // This library only support storage related actions.
398 DEBUG ((EFI_D_INFO
, "[TPM Storage] Only support TCG storage related PP actions, not support PPRequest=%x\n", TcgPpData
.PPRequest
));
403 // Initialize physical presence storage flags.
405 DataSize
= sizeof (EFI_TCG_PHYSICAL_PRESENCE_STORAGE_FLAGS
);
406 Status
= gRT
->GetVariable (
407 TCG_PHYSICAL_PRESENCE_STORAGE_FLAGS_VARIABLE
,
408 &gEfiTcgPhysicalPresenceStorageGuid
,
413 if (EFI_ERROR (Status
)) {
414 PpiFlags
.PPFlags
= TCG_BIOS_STORAGE_MANAGEMENT_FLAG_DEFAULT
;
415 Status
= gRT
->SetVariable (
416 TCG_PHYSICAL_PRESENCE_STORAGE_FLAGS_VARIABLE
,
417 &gEfiTcgPhysicalPresenceStorageGuid
,
418 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
419 sizeof (EFI_TCG_PHYSICAL_PRESENCE_STORAGE_FLAGS
),
422 if (EFI_ERROR (Status
)) {
423 DEBUG ((EFI_D_ERROR
, "[TPM Storage] Set physical presence flag failed, Status = %r\n", Status
));
427 DEBUG ((EFI_D_INFO
, "[TPM Storage] PpiFlags = %x\n", PpiFlags
.PPFlags
));
430 // This flags variable controls whether physical presence is required for TPM command.
431 // It should be protected from malicious software. We set it as read-only variable here.
433 Status
= gBS
->LocateProtocol (&gEdkiiVariableLockProtocolGuid
, NULL
, (VOID
**)&VariableLockProtocol
);
434 if (!EFI_ERROR (Status
)) {
435 Status
= VariableLockProtocol
->RequestToLock (
436 VariableLockProtocol
,
437 TCG_PHYSICAL_PRESENCE_STORAGE_FLAGS_VARIABLE
,
438 &gEfiTcgPhysicalPresenceStorageGuid
440 if (EFI_ERROR (Status
)) {
441 DEBUG ((EFI_D_ERROR
, "[TPM Storage] Error when lock variable %s, Status = %r\n", TCG_PHYSICAL_PRESENCE_STORAGE_FLAGS_VARIABLE
, Status
));
442 ASSERT_EFI_ERROR (Status
);
446 DEBUG ((EFI_D_INFO
, "[TPM Storage] Flags=%x, PPRequest=%x (LastPPRequest=%x)\n", PpiFlags
.PPFlags
, TcgPpData
.PPRequest
, TcgPpData
.LastPPRequest
));
448 NewPpiFlags
.PPFlags
= PpiFlags
.PPFlags
;
449 ResetRequired
= FALSE
;
450 TcgPpData
.PPResponse
= TCG_PP_OPERATION_RESPONSE_USER_ABORT
;
452 TcgPpData
.PPResponse
= TcgExecutePendingRequest (TcgPpData
.PPRequest
, &NewPpiFlags
.PPFlags
, &ResetRequired
);
453 DEBUG ((EFI_D_INFO
, "[TPM Storage] PPResponse = %x (LastPPRequest=%x, Flags=%x)\n", TcgPpData
.PPResponse
, TcgPpData
.LastPPRequest
, PpiFlags
.PPFlags
));
455 if (TcgPpData
.PPResponse
== TCG_PP_OPERATION_RESPONSE_USER_ABORT
) {
460 // Save the flags if it is updated.
462 if (CompareMem (&PpiFlags
, &NewPpiFlags
, sizeof(EFI_TCG_PHYSICAL_PRESENCE_STORAGE_FLAGS
)) != 0) {
463 Status
= gRT
->SetVariable (
464 TCG_PHYSICAL_PRESENCE_STORAGE_FLAGS_VARIABLE
,
465 &gEfiTcgPhysicalPresenceStorageGuid
,
466 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
467 sizeof (EFI_TCG_PHYSICAL_PRESENCE_STORAGE_FLAGS
),
475 TcgPpData
.LastPPRequest
= TcgPpData
.PPRequest
;
476 TcgPpData
.PPRequest
= TCG_PHYSICAL_PRESENCE_NO_ACTION
;
481 DataSize
= sizeof (EFI_PHYSICAL_PRESENCE
);
482 Status
= gRT
->SetVariable (
483 PHYSICAL_PRESENCE_VARIABLE
,
484 &gEfiPhysicalPresenceGuid
,
485 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
489 if (EFI_ERROR (Status
)) {
493 if (!ResetRequired
) {
497 Print (L
"Rebooting system to make TPM2 settings in effect\n");
498 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);