SecurityPkg: add DeviceSecurity support
This patch implement the SpdmSecurityLib, which is the core of DeviceSecurity. And the SpdmSecurityLib include Device Authentication and Measurement. The other library is to support SpdmSecurityLib. Cc: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Wenxing Hou <wenxing.hou@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
This commit is contained in:
committed by
mergify[bot]
parent
c3f615a1bd
commit
750d763623
148
SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.c
Normal file
148
SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.c
Normal file
@@ -0,0 +1,148 @@
|
||||
/** @file
|
||||
EDKII Device Security library for SPDM device.
|
||||
It follows the SPDM Specification.
|
||||
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "SpdmSecurityLibInternal.h"
|
||||
|
||||
/**
|
||||
Helper function to quickly determine whether device authentication boot is enabled.
|
||||
|
||||
@retval TRUE device authentication boot is verifiably enabled.
|
||||
@retval FALSE device authentication boot is either disabled or an error prevented checking.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
IsDeviceAuthBootEnabled (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT8 *DeviceAuthBootMode;
|
||||
|
||||
DeviceAuthBootMode = NULL;
|
||||
|
||||
Status = GetEfiGlobalVariable2 (EFI_DEVICE_AUTH_BOOT_MODE_NAME, (VOID **)&DeviceAuthBootMode, NULL);
|
||||
//
|
||||
// Skip verification if DeviceAuthBootMode variable doesn't exist.
|
||||
//
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "Cannot check DeviceAuthBootMode variable %r \n ", Status));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Skip verification if DeviceAuthBootMode is disabled but not AuditMode
|
||||
//
|
||||
if (*DeviceAuthBootMode == DEVICE_AUTH_BOOT_MODE_DISABLE) {
|
||||
FreePool (DeviceAuthBootMode);
|
||||
return FALSE;
|
||||
} else {
|
||||
FreePool (DeviceAuthBootMode);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
The device driver uses this service to authenticate and measure an SPDM device.
|
||||
|
||||
@param[in] SpdmDeviceInfo The SPDM context for the device.
|
||||
@param[in] SecurityPolicy The security policy of this device.
|
||||
@param[out] SecurityState A pointer to security state if this device.
|
||||
|
||||
@retval EFI_SUCCESS The TCG SPDM device measurement context is returned.
|
||||
@retval EFI_UNSUPPORTED The TCG SPDM device measurement context is unsupported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SpdmDeviceAuthenticationAndMeasurement (
|
||||
IN EDKII_SPDM_DEVICE_INFO *SpdmDeviceInfo,
|
||||
IN EDKII_DEVICE_SECURITY_POLICY *SecurityPolicy,
|
||||
OUT EDKII_DEVICE_SECURITY_STATE *SecurityState
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
SPDM_DEVICE_CONTEXT *SpdmDeviceContext;
|
||||
UINT8 AuthState;
|
||||
UINT8 SlotId;
|
||||
BOOLEAN IsValidCertChain;
|
||||
BOOLEAN RootCertMatch;
|
||||
|
||||
if ((PcdGet32 (PcdTcgPfpMeasurementRevision) < TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_106) ||
|
||||
(PcdGet8 (PcdEnableSpdmDeviceAuthentication) == 0))
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
SpdmDeviceContext = CreateSpdmDeviceContext (SpdmDeviceInfo, SecurityState);
|
||||
if (SpdmDeviceContext == NULL) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS;
|
||||
SlotId = 0;
|
||||
IsValidCertChain = FALSE;
|
||||
RootCertMatch = FALSE;
|
||||
|
||||
if (((SecurityPolicy->AuthenticationPolicy & EDKII_DEVICE_AUTHENTICATION_REQUIRED) != 0) ||
|
||||
((SecurityPolicy->MeasurementPolicy & EDKII_DEVICE_MEASUREMENT_REQUIRED) != 0))
|
||||
{
|
||||
Status = DoDeviceCertificate (SpdmDeviceContext, &AuthState, &SlotId, SecurityState, &IsValidCertChain, &RootCertMatch);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "DoDeviceCertificate failed - %r\n", Status));
|
||||
goto Ret;
|
||||
} else if ((AuthState == TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG) ||
|
||||
(AuthState == TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID))
|
||||
{
|
||||
goto Ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (((SecurityPolicy->AuthenticationPolicy & EDKII_DEVICE_AUTHENTICATION_REQUIRED) != 0) && (IsDeviceAuthBootEnabled ())) {
|
||||
Status = DoDeviceAuthentication (SpdmDeviceContext, &AuthState, SlotId, IsValidCertChain, RootCertMatch, SecurityState);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "DoDeviceAuthentication failed - %r\n", Status));
|
||||
goto Ret;
|
||||
} else if ((AuthState == TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG) ||
|
||||
(AuthState == TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID))
|
||||
{
|
||||
goto Ret;
|
||||
}
|
||||
}
|
||||
|
||||
if ((SecurityPolicy->MeasurementPolicy & EDKII_DEVICE_MEASUREMENT_REQUIRED) != 0) {
|
||||
Status = DoDeviceMeasurement (SpdmDeviceContext, SlotId, SecurityState);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "DoDeviceMeasurement failed - %r\n", Status));
|
||||
}
|
||||
}
|
||||
|
||||
Ret:
|
||||
DestroySpdmDeviceContext (SpdmDeviceContext);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
This function will get SpdmIoProtocol via Context.
|
||||
|
||||
@param[in] SpdmContext The SPDM context for the device.
|
||||
|
||||
return the pointer of Spdm Io protocol
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
SpdmGetIoProtocolViaSpdmContext (
|
||||
IN VOID *SpdmContext
|
||||
)
|
||||
{
|
||||
return GetSpdmIoProtocolViaSpdmContext (SpdmContext);
|
||||
}
|
Reference in New Issue
Block a user