/** @file EDKII Device Security library for SPDM device. It follows the SPDM Specification. Copyright (c) 2024, Intel Corporation. All rights reserved.
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); }