2 Handle TPM 2.0 physical presence requests from OS.
4 This library will handle TPM 2.0 physical presence request from OS.
6 Caution: This module requires additional review when modified.
7 This driver will have external input - variable.
8 This external input must be validated carefully to avoid security issue.
10 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction() and Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction()
11 will receive untrusted input and do validation.
13 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
14 This program and the accompanying materials
15 are licensed and made available under the terms and conditions of the BSD License
16 which accompanies this distribution. The full text of the license may be found at
17 http://opensource.org/licenses/bsd-license.php
19 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
20 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
26 #include <Guid/Tcg2PhysicalPresenceData.h>
28 #include <Protocol/SmmVariable.h>
30 #include <Library/BaseLib.h>
31 #include <Library/DebugLib.h>
32 #include <Library/BaseMemoryLib.h>
33 #include <Library/Tcg2PpVendorLib.h>
34 #include <Library/SmmServicesTableLib.h>
36 #define PP_INF_VERSION_1_2 "1.2"
38 EFI_SMM_VARIABLE_PROTOCOL
*mTcg2PpSmmVariable
;
39 BOOLEAN mIsTcg2PPVerLowerThan_1_3
= FALSE
;
42 The handler for TPM physical presence function:
43 Return TPM Operation Response to OS Environment.
45 This API should be invoked in OS runtime phase to interface with ACPI method.
47 @param[out] MostRecentRequest Most recent operation request.
48 @param[out] Response Response to the most recent operation request.
50 @return Return Code for Return TPM Operation Response to OS Environment.
54 Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
55 OUT UINT32
*MostRecentRequest
,
61 EFI_TCG2_PHYSICAL_PRESENCE PpData
;
63 DEBUG ((EFI_D_INFO
, "[TPM2] ReturnOperationResponseToOsFunction\n"));
66 // Get the Physical Presence variable
68 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
69 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
70 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
71 &gEfiTcg2PhysicalPresenceGuid
,
76 if (EFI_ERROR (Status
)) {
77 *MostRecentRequest
= 0;
79 DEBUG ((EFI_D_ERROR
, "[TPM2] Get PP variable failure! Status = %r\n", Status
));
80 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE
;
83 *MostRecentRequest
= PpData
.LastPPRequest
;
84 *Response
= PpData
.PPResponse
;
86 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS
;
90 The handler for TPM physical presence function:
91 Submit TPM Operation Request to Pre-OS Environment and
92 Submit TPM Operation Request to Pre-OS Environment 2.
94 This API should be invoked in OS runtime phase to interface with ACPI method.
96 Caution: This function may receive untrusted input.
98 @param[in, out] Pointer to OperationRequest TPM physical presence operation request.
99 @param[in, out] Pointer to RequestParameter TPM physical presence operation request parameter.
101 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
102 Submit TPM Operation Request to Pre-OS Environment 2.
105 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (
106 IN OUT UINT32
*OperationRequest
,
107 IN OUT UINT32
*RequestParameter
113 EFI_TCG2_PHYSICAL_PRESENCE PpData
;
114 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags
;
116 DEBUG ((EFI_D_INFO
, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", *OperationRequest
, *RequestParameter
));
117 ReturnCode
= TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS
;
120 // Get the Physical Presence variable
122 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
123 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
124 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
125 &gEfiTcg2PhysicalPresenceGuid
,
130 if (EFI_ERROR (Status
)) {
131 DEBUG ((EFI_D_ERROR
, "[TPM2] Get PP variable failure! Status = %r\n", Status
));
132 ReturnCode
= TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
;
136 if ((*OperationRequest
> TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) &&
137 (*OperationRequest
< TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN
) ) {
138 ReturnCode
= TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED
;
142 if ((PpData
.PPRequest
!= *OperationRequest
) ||
143 (PpData
.PPRequestParameter
!= *RequestParameter
)) {
144 PpData
.PPRequest
= (UINT8
)*OperationRequest
;
145 PpData
.PPRequestParameter
= *RequestParameter
;
146 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
147 Status
= mTcg2PpSmmVariable
->SmmSetVariable (
148 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
149 &gEfiTcg2PhysicalPresenceGuid
,
150 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
154 if (EFI_ERROR (Status
)) {
155 DEBUG ((EFI_D_ERROR
, "[TPM2] Set PP variable failure! Status = %r\n", Status
));
156 ReturnCode
= TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
;
161 if (*OperationRequest
>= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
162 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
);
163 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
164 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
165 &gEfiTcg2PhysicalPresenceGuid
,
170 if (EFI_ERROR (Status
)) {
171 Flags
.PPFlags
= TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT
| TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_DEFAULT
;
173 ReturnCode
= Tcg2PpVendorLibSubmitRequestToPreOSFunction (*OperationRequest
, Flags
.PPFlags
, *RequestParameter
);
178 // Sync PPRQ/PPRM from PP Variable if PP submission fails
180 if (ReturnCode
!= TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS
) {
181 DEBUG ((EFI_D_ERROR
, "[TPM2] Submit PP Request failure! Sync PPRQ/PPRM with PP variable.\n", Status
));
182 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
183 ZeroMem(&PpData
, DataSize
);
184 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
185 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
186 &gEfiTcg2PhysicalPresenceGuid
,
191 *OperationRequest
= (UINT32
)PpData
.PPRequest
;
192 *RequestParameter
= PpData
.PPRequestParameter
;
199 The handler for TPM physical presence function:
200 Submit TPM Operation Request to Pre-OS Environment and
201 Submit TPM Operation Request to Pre-OS Environment 2.
203 This API should be invoked in OS runtime phase to interface with ACPI method.
205 Caution: This function may receive untrusted input.
207 @param[in] OperationRequest TPM physical presence operation request.
208 @param[in] RequestParameter TPM physical presence operation request parameter.
210 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
211 Submit TPM Operation Request to Pre-OS Environment 2.
215 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
216 IN UINT32 OperationRequest
,
217 IN UINT32 RequestParameter
220 UINT32 TempOperationRequest
;
221 UINT32 TempRequestParameter
;
223 TempOperationRequest
= OperationRequest
;
224 TempRequestParameter
= RequestParameter
;
226 return Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx(&TempOperationRequest
, &TempRequestParameter
);
230 The handler for TPM physical presence function:
231 Get User Confirmation Status for Operation.
233 This API should be invoked in OS runtime phase to interface with ACPI method.
235 Caution: This function may receive untrusted input.
237 @param[in] OperationRequest TPM physical presence operation request.
239 @return Return Code for Get User Confirmation Status for Operation.
243 Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (
244 IN UINT32 OperationRequest
249 EFI_TCG2_PHYSICAL_PRESENCE PpData
;
250 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags
;
251 BOOLEAN RequestConfirmed
;
253 DEBUG ((EFI_D_INFO
, "[TPM2] GetUserConfirmationStatusFunction, Request = %x\n", OperationRequest
));
256 // Get the Physical Presence variable
258 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
259 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
260 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
261 &gEfiTcg2PhysicalPresenceGuid
,
266 if (EFI_ERROR (Status
)) {
267 DEBUG ((EFI_D_ERROR
, "[TPM2] Get PP variable failure! Status = %r\n", Status
));
268 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION
;
271 // Get the Physical Presence flags
273 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
);
274 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
275 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
276 &gEfiTcg2PhysicalPresenceGuid
,
281 if (EFI_ERROR (Status
)) {
282 DEBUG ((EFI_D_ERROR
, "[TPM2] Get PP flags failure! Status = %r\n", Status
));
283 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION
;
286 RequestConfirmed
= FALSE
;
288 switch (OperationRequest
) {
289 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
290 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
291 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
292 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
293 if ((Flags
.PPFlags
& TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR
) == 0) {
294 RequestConfirmed
= TRUE
;
298 case TCG2_PHYSICAL_PRESENCE_NO_ACTION
:
299 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE
:
300 RequestConfirmed
= TRUE
;
303 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE
:
306 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
307 if ((Flags
.PPFlags
& TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS
) == 0) {
308 RequestConfirmed
= TRUE
;
312 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
313 if ((Flags
.PPFlags
& TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS
) == 0) {
314 RequestConfirmed
= TRUE
;
318 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
319 RequestConfirmed
= TRUE
;
322 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
:
323 if ((Flags
.PPFlags
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID
) == 0) {
324 RequestConfirmed
= TRUE
;
328 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
:
329 if ((Flags
.PPFlags
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID
) == 0) {
330 RequestConfirmed
= TRUE
;
334 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE
:
335 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE
:
336 RequestConfirmed
= TRUE
;
339 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE
:
340 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE
:
344 if (mIsTcg2PPVerLowerThan_1_3
== FALSE
) {
345 if (OperationRequest
< TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
347 // TCG2 PP1.3 spec defined operations that are reserved or un-implemented
349 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED
;
353 // TCG PP lower than 1.3. (1.0, 1.1, 1.2)
355 if (OperationRequest
<= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
356 RequestConfirmed
= TRUE
;
357 } else if (OperationRequest
< TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
358 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED
;
364 if (OperationRequest
>= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
365 return Tcg2PpVendorLibGetUserConfirmationStatusFunction (OperationRequest
, Flags
.PPFlags
);
368 if (RequestConfirmed
) {
369 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_NOT_REQUIRED
;
371 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_REQUIRED
;
376 The constructor function locates SmmVariable protocol.
378 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
380 @param ImageHandle The firmware allocated handle for the EFI image.
381 @param SystemTable A pointer to the EFI System Table.
383 @retval EFI_SUCCESS The constructor successfully added string package.
384 @retval Other value The constructor can't add string package.
388 Tcg2PhysicalPresenceLibConstructor (
389 IN EFI_HANDLE ImageHandle
,
390 IN EFI_SYSTEM_TABLE
*SystemTable
395 if (AsciiStrnCmp(PP_INF_VERSION_1_2
, (CHAR8
*)PcdGetPtr(PcdTcgPhysicalPresenceInterfaceVer
), sizeof(PP_INF_VERSION_1_2
) - 1) <= 0) {
396 mIsTcg2PPVerLowerThan_1_3
= TRUE
;
400 // Locate SmmVariableProtocol.
402 Status
= gSmst
->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid
, NULL
, (VOID
**)&mTcg2PpSmmVariable
);
403 ASSERT_EFI_ERROR (Status
);