SecurityPkg: Tcg2: Fix TCG2 PP issues

Several issues exist in TCG2 PP
1. TCG2 PP use NVS PPRQ/PPRM as PP parameter as well as current
PP state cache. But it doesn't handle PP set failure case
2. TCG2 PP Submit TPM Operation Request to Pre-OS Environment forgets
to clean PPRM
3. Potential alignment issue

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chao Zhang <chao.b.zhang@intel.com>
Reviewed-by: Qin Long <qin.long@intel.com>
This commit is contained in:
Zhang, Chao B
2016-09-27 09:46:40 +08:00
parent ab970515d2
commit edb0fda25e
4 changed files with 111 additions and 27 deletions

View File

@@ -28,6 +28,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/SmmVariable.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemorylib.h>
#include <Library/Tcg2PpVendorLib.h>
#include <Library/SmmServicesTableLib.h>
@@ -89,26 +90,27 @@ Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
This API should be invoked in OS runtime phase to interface with ACPI method.
Caution: This function may receive untrusted input.
@param[in] OperationRequest TPM physical presence operation request.
@param[in] RequestParameter TPM physical presence operation request parameter.
@param[in out] Pointer to OperationRequest TPM physical presence operation request.
@param[in out] Pointer to RequestParameter TPM physical presence operation request parameter.
@return Return Code for Submit TPM Operation Request to Pre-OS Environment and
Submit TPM Operation Request to Pre-OS Environment 2.
**/
Submit TPM Operation Request to Pre-OS Environment 2.
**/
UINT32
EFIAPI
Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
IN UINT32 OperationRequest,
IN UINT32 RequestParameter
Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (
IN OUT UINT32 *OperationRequest,
IN OUT UINT32 *RequestParameter
)
{
EFI_STATUS Status;
UINT32 ReturnCode;
UINTN DataSize;
EFI_TCG2_PHYSICAL_PRESENCE PpData;
EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;
DEBUG ((EFI_D_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest, RequestParameter));
DEBUG ((EFI_D_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", *OperationRequest, *RequestParameter));
ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;
//
// Get the Physical Presence variable
@@ -123,21 +125,23 @@ Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
goto EXIT;
}
if ((OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&
(OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) ) {
if ((*OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&
(*OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) ) {
//
// This command requires UI to prompt user for Auth data.
//
return TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;
ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;
goto EXIT;
}
if ((PpData.PPRequest != OperationRequest) ||
(PpData.PPRequestParameter != RequestParameter)) {
PpData.PPRequest = (UINT8)OperationRequest;
PpData.PPRequestParameter = RequestParameter;
if ((PpData.PPRequest != *OperationRequest) ||
(PpData.PPRequestParameter != *RequestParameter)) {
PpData.PPRequest = (UINT8)*OperationRequest;
PpData.PPRequestParameter = *RequestParameter;
DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
Status = mTcg2PpSmmVariable->SmmSetVariable (
TCG2_PHYSICAL_PRESENCE_VARIABLE,
@@ -150,10 +154,11 @@ Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));
return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
goto EXIT;
}
if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
if (*OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
Status = mTcg2PpSmmVariable->SmmGetVariable (
TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
@@ -165,10 +170,60 @@ Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
if (EFI_ERROR (Status)) {
Flags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT;
}
return Tcg2PpVendorLibSubmitRequestToPreOSFunction (OperationRequest, Flags.PPFlags, RequestParameter);
ReturnCode = Tcg2PpVendorLibSubmitRequestToPreOSFunction (*OperationRequest, Flags.PPFlags, *RequestParameter);
}
return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;
EXIT:
//
// Sync PPRQ/PPRM from PP Variable if PP submission fails
//
if (ReturnCode != TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {
DEBUG ((EFI_D_ERROR, "[TPM2] Submit PP Request failure! Sync PPRQ/PPRM with PP variable.\n", Status));
DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
ZeroMem(&PpData, DataSize);
Status = mTcg2PpSmmVariable->SmmGetVariable (
TCG2_PHYSICAL_PRESENCE_VARIABLE,
&gEfiTcg2PhysicalPresenceGuid,
NULL,
&DataSize,
&PpData
);
*OperationRequest = (UINT32)PpData.PPRequest;
*RequestParameter = PpData.PPRequestParameter;
}
return ReturnCode;
}
/**
The handler for TPM physical presence function:
Submit TPM Operation Request to Pre-OS Environment and
Submit TPM Operation Request to Pre-OS Environment 2.
This API should be invoked in OS runtime phase to interface with ACPI method.
Caution: This function may receive untrusted input.
@param[in] OperationRequest TPM physical presence operation request.
@param[in] RequestParameter TPM physical presence operation request parameter.
@return Return Code for Submit TPM Operation Request to Pre-OS Environment and
Submit TPM Operation Request to Pre-OS Environment 2.
**/
UINT32
EFIAPI
Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
IN UINT32 OperationRequest,
IN UINT32 RequestParameter
)
{
UINT32 TempOperationRequest;
UINT32 TempRequestParameter;
TempOperationRequest = OperationRequest;
TempRequestParameter = RequestParameter;
return Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx(&TempOperationRequest, &TempRequestParameter);
}
/**