blob: f438c16563a791ad443d612550e93d7bc6869185 [file] [log] [blame]
/** @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);
}