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 - 2020, Intel Corporation. All rights reserved.<BR>
14 SPDX-License-Identifier: BSD-2-Clause-Patent
20 #include <Guid/Tcg2PhysicalPresenceData.h>
22 #include <Protocol/SmmVariable.h>
24 #include <Library/BaseLib.h>
25 #include <Library/DebugLib.h>
26 #include <Library/BaseMemoryLib.h>
27 #include <Library/Tcg2PpVendorLib.h>
28 #include <Library/MmServicesTableLib.h>
30 #define PP_INF_VERSION_1_2 "1.2"
32 EFI_SMM_VARIABLE_PROTOCOL
*mTcg2PpSmmVariable
;
33 BOOLEAN mIsTcg2PPVerLowerThan_1_3
= FALSE
;
34 UINT32 mTcg2PhysicalPresenceFlags
;
37 The handler for TPM physical presence function:
38 Return TPM Operation Response to OS Environment.
40 This API should be invoked in OS runtime phase to interface with ACPI method.
42 @param[out] MostRecentRequest Most recent operation request.
43 @param[out] Response Response to the most recent operation request.
45 @return Return Code for Return TPM Operation Response to OS Environment.
49 Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
50 OUT UINT32
*MostRecentRequest
,
56 EFI_TCG2_PHYSICAL_PRESENCE PpData
;
58 DEBUG ((DEBUG_INFO
, "[TPM2] ReturnOperationResponseToOsFunction\n"));
61 // Get the Physical Presence variable
63 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
64 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
65 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
66 &gEfiTcg2PhysicalPresenceGuid
,
71 if (EFI_ERROR (Status
)) {
72 *MostRecentRequest
= 0;
74 DEBUG ((DEBUG_ERROR
, "[TPM2] Get PP variable failure! Status = %r\n", Status
));
75 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE
;
78 *MostRecentRequest
= PpData
.LastPPRequest
;
79 *Response
= PpData
.PPResponse
;
81 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS
;
85 The handler for TPM physical presence function:
86 Submit TPM Operation Request to Pre-OS Environment and
87 Submit TPM Operation Request to Pre-OS Environment 2.
89 This API should be invoked in OS runtime phase to interface with ACPI method.
91 Caution: This function may receive untrusted input.
93 @param[in, out] Pointer to OperationRequest TPM physical presence operation request.
94 @param[in, out] Pointer to RequestParameter TPM physical presence operation request parameter.
96 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
97 Submit TPM Operation Request to Pre-OS Environment 2.
100 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (
101 IN OUT UINT32
*OperationRequest
,
102 IN OUT UINT32
*RequestParameter
108 EFI_TCG2_PHYSICAL_PRESENCE PpData
;
109 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags
;
111 DEBUG ((DEBUG_INFO
, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", *OperationRequest
, *RequestParameter
));
112 ReturnCode
= TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS
;
115 // Get the Physical Presence variable
117 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
118 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
119 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
120 &gEfiTcg2PhysicalPresenceGuid
,
125 if (EFI_ERROR (Status
)) {
126 DEBUG ((DEBUG_ERROR
, "[TPM2] Get PP variable failure! Status = %r\n", Status
));
127 ReturnCode
= TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
;
131 if ((*OperationRequest
> TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) &&
132 (*OperationRequest
< TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN
))
134 ReturnCode
= TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED
;
138 if ((PpData
.PPRequest
!= *OperationRequest
) ||
139 (PpData
.PPRequestParameter
!= *RequestParameter
))
141 PpData
.PPRequest
= (UINT8
)*OperationRequest
;
142 PpData
.PPRequestParameter
= *RequestParameter
;
143 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
144 Status
= mTcg2PpSmmVariable
->SmmSetVariable (
145 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
146 &gEfiTcg2PhysicalPresenceGuid
,
147 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
151 if (EFI_ERROR (Status
)) {
152 DEBUG ((DEBUG_ERROR
, "[TPM2] Set PP variable failure! Status = %r\n", Status
));
153 ReturnCode
= TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
;
158 if (*OperationRequest
>= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
159 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
);
160 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
161 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
162 &gEfiTcg2PhysicalPresenceGuid
,
167 if (EFI_ERROR (Status
)) {
168 Flags
.PPFlags
= mTcg2PhysicalPresenceFlags
;
171 ReturnCode
= Tcg2PpVendorLibSubmitRequestToPreOSFunction (*OperationRequest
, Flags
.PPFlags
, *RequestParameter
);
176 // Sync PPRQ/PPRM from PP Variable if PP submission fails
178 if (ReturnCode
!= TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS
) {
179 DEBUG ((DEBUG_ERROR
, "[TPM2] Submit PP Request failure! Sync PPRQ/PPRM with PP variable. Status = %r\n", Status
));
180 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
181 ZeroMem (&PpData
, DataSize
);
182 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
183 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
184 &gEfiTcg2PhysicalPresenceGuid
,
189 *OperationRequest
= (UINT32
)PpData
.PPRequest
;
190 *RequestParameter
= PpData
.PPRequestParameter
;
197 The handler for TPM physical presence function:
198 Submit TPM Operation Request to Pre-OS Environment and
199 Submit TPM Operation Request to Pre-OS Environment 2.
201 This API should be invoked in OS runtime phase to interface with ACPI method.
203 Caution: This function may receive untrusted input.
205 @param[in] OperationRequest TPM physical presence operation request.
206 @param[in] RequestParameter TPM physical presence operation request parameter.
208 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
209 Submit TPM Operation Request to Pre-OS Environment 2.
213 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
214 IN UINT32 OperationRequest
,
215 IN UINT32 RequestParameter
218 UINT32 TempOperationRequest
;
219 UINT32 TempRequestParameter
;
221 TempOperationRequest
= OperationRequest
;
222 TempRequestParameter
= RequestParameter
;
224 return Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (&TempOperationRequest
, &TempRequestParameter
);
228 The handler for TPM physical presence function:
229 Get User Confirmation Status for Operation.
231 This API should be invoked in OS runtime phase to interface with ACPI method.
233 Caution: This function may receive untrusted input.
235 @param[in] OperationRequest TPM physical presence operation request.
237 @return Return Code for Get User Confirmation Status for Operation.
241 Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (
242 IN UINT32 OperationRequest
247 EFI_TCG2_PHYSICAL_PRESENCE PpData
;
248 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags
;
249 BOOLEAN RequestConfirmed
;
251 DEBUG ((DEBUG_INFO
, "[TPM2] GetUserConfirmationStatusFunction, Request = %x\n", OperationRequest
));
254 // Get the Physical Presence variable
256 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
257 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
258 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
259 &gEfiTcg2PhysicalPresenceGuid
,
264 if (EFI_ERROR (Status
)) {
265 DEBUG ((DEBUG_ERROR
, "[TPM2] Get PP variable failure! Status = %r\n", Status
));
266 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION
;
270 // Get the Physical Presence flags
272 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
);
273 Status
= mTcg2PpSmmVariable
->SmmGetVariable (
274 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
275 &gEfiTcg2PhysicalPresenceGuid
,
280 if (EFI_ERROR (Status
)) {
281 DEBUG ((DEBUG_ERROR
, "[TPM2] Get PP flags failure! Status = %r\n", Status
));
282 return TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION
;
285 RequestConfirmed
= FALSE
;
287 switch (OperationRequest
) {
288 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
289 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
290 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
291 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
292 if ((Flags
.PPFlags
& TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR
) == 0) {
293 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
;
313 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
314 if ((Flags
.PPFlags
& TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS
) == 0) {
315 RequestConfirmed
= TRUE
;
320 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
321 RequestConfirmed
= TRUE
;
324 case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID
:
325 if ((Flags
.PPFlags
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID
) == 0) {
326 RequestConfirmed
= TRUE
;
331 case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID
:
332 if ((Flags
.PPFlags
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID
) == 0) {
333 RequestConfirmed
= TRUE
;
338 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE
:
339 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE
:
340 RequestConfirmed
= TRUE
;
343 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE
:
344 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE
:
348 if (!mIsTcg2PPVerLowerThan_1_3
) {
349 if (OperationRequest
< TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
351 // TCG2 PP1.3 spec defined operations that are reserved or un-implemented
353 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED
;
357 // TCG PP lower than 1.3. (1.0, 1.1, 1.2)
359 if (OperationRequest
<= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
360 RequestConfirmed
= TRUE
;
361 } else if (OperationRequest
< TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
362 return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED
;
369 if (OperationRequest
>= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
370 return Tcg2PpVendorLibGetUserConfirmationStatusFunction (OperationRequest
, Flags
.PPFlags
);
373 if (RequestConfirmed
) {
374 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_NOT_REQUIRED
;
376 return TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_REQUIRED
;
381 The constructor function locates SmmVariable protocol.
383 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
385 @retval EFI_SUCCESS The constructor successfully added string package.
386 @retval Other value The constructor can't add string package.
389 Tcg2PhysicalPresenceLibCommonConstructor (
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
= gMmst
->MmLocateProtocol (&gEfiSmmVariableProtocolGuid
, NULL
, (VOID
**)&mTcg2PpSmmVariable
);
403 ASSERT_EFI_ERROR (Status
);
405 mTcg2PhysicalPresenceFlags
= PcdGet32 (PcdTcg2PhysicalPresenceFlags
);