mirror of https://github.com/acidanthera/audk.git
149 lines
4.6 KiB
C
149 lines
4.6 KiB
C
/** @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);
|
|
}
|