/** @file EDKII Device Security library for PCI device Copyright (c) 2019, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #include #include #include EDKII_DEVICE_SECURITY_POLICY mDeviceSecurityPolicyNone = { EDKII_DEVICE_SECURITY_POLICY_REVISION, 0, 0, }; EDKII_DEVICE_SECURITY_POLICY mDeviceSecurityPolicyMeasurement = { EDKII_DEVICE_SECURITY_POLICY_REVISION, EDKII_DEVICE_MEASUREMENT_REQUIRED, 0, }; /** This function returns the device security policy associated with the device. The device security driver may call this interface to get the platform policy for the specific device and determine if the measurement or authentication is required. @param[in] This The protocol instance pointer. @param[in] DeviceId The Identifier for the device. @param[out] DeviceSecurityPolicy The Device Security Policy associated with the device. @retval EFI_SUCCESS The device security policy is returned @retval EFI_UNSUPPORTED The function is unsupported for the specific Device. **/ EFI_STATUS EFIAPI GetDevicePolicy ( IN EDKII_DEVICE_SECURITY_POLICY_PROTOCOL *This, IN EDKII_DEVICE_IDENTIFIER *DeviceId, OUT EDKII_DEVICE_SECURITY_POLICY *DeviceSecurityPolicy ) { EFI_STATUS Status; EFI_PCI_IO_PROTOCOL *PciIo; UINT16 PciVendorId; UINT16 PciDeviceId; CopyMem (DeviceSecurityPolicy, &mDeviceSecurityPolicyNone, sizeof(EDKII_DEVICE_SECURITY_POLICY)); DEBUG ((DEBUG_INFO, "GetDevicePolicy - 0x%g\n", &DeviceId->DeviceType)); if (!CompareGuid (&DeviceId->DeviceType, &gEdkiiDeviceIdentifierTypePciGuid)) { return EFI_SUCCESS; } Status = gBS->HandleProtocol ( DeviceId->DeviceHandle, &gEdkiiDeviceIdentifierTypePciGuid, (VOID **)&PciIo ); if (EFI_ERROR(Status)) { DEBUG ((DEBUG_ERROR, "Locate - DeviceIdentifierTypePci - %r\n", Status)); return EFI_SUCCESS; } Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_VENDOR_ID_OFFSET, 1, &PciVendorId); ASSERT_EFI_ERROR(Status); Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_DEVICE_ID_OFFSET, 1, &PciDeviceId); ASSERT_EFI_ERROR(Status); DEBUG ((DEBUG_INFO, "PCI Info - %04x:%04x\n", PciVendorId, PciDeviceId)); if ((PciVendorId == 0x8086) && (PciDeviceId == 0x0B60)) { CopyMem (DeviceSecurityPolicy, &mDeviceSecurityPolicyMeasurement, sizeof(EDKII_DEVICE_SECURITY_POLICY)); } return EFI_SUCCESS; } /** This function sets the device state based upon the authentication result. The device security driver may call this interface to give the platform a notify based upon the measurement or authentication result. If the authentication or measurement fails, the platform may choose: 1) Do nothing. 2) Disable this device or slot temporarily and continue boot. 3) Reset the platform and retry again. 4) Disable this device or slot permanently. 5) Any other platform specific action. @param[in] This The protocol instance pointer. @param[in] DeviceId The Identifier for the device. @param[in] DeviceSecurityState The Device Security state associated with the device. @retval EFI_SUCCESS The device state is set @retval EFI_UNSUPPORTED The function is unsupported for the specific Device. **/ EFI_STATUS EFIAPI NotifyDeviceState ( IN EDKII_DEVICE_SECURITY_POLICY_PROTOCOL *This, IN EDKII_DEVICE_IDENTIFIER *DeviceId, IN EDKII_DEVICE_SECURITY_STATE *DeviceSecurityState ) { EFI_STATUS Status; EFI_PCI_IO_PROTOCOL *PciIo; UINT16 PciVendorId; UINT16 PciDeviceId; UINTN Segment; UINTN Bus; UINTN Device; UINTN Function; DEBUG ((DEBUG_INFO, "NotifyDeviceState - 0x%g\n", &DeviceId->DeviceType)); if (!CompareGuid (&DeviceId->DeviceType, &gEdkiiDeviceIdentifierTypePciGuid)) { return EFI_SUCCESS; } Status = gBS->HandleProtocol ( DeviceId->DeviceHandle, &gEdkiiDeviceIdentifierTypePciGuid, (VOID **)&PciIo ); if (EFI_ERROR(Status)) { DEBUG ((DEBUG_ERROR, "Locate - DeviceIdentifierTypePci - %r\n", Status)); return EFI_SUCCESS; } Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_VENDOR_ID_OFFSET, 1, &PciVendorId); ASSERT_EFI_ERROR(Status); Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_DEVICE_ID_OFFSET, 1, &PciDeviceId); ASSERT_EFI_ERROR(Status); DEBUG ((DEBUG_INFO, "PCI Info - %04x:%04x\n", PciVendorId, PciDeviceId)); Status = PciIo->GetLocation ( PciIo, &Segment, &Bus, &Device, &Function ); if (!EFI_ERROR(Status)) { DEBUG ((DEBUG_INFO, "PCI Loc - %04x:%02x:%02x:%02x\n", Segment, Bus, Device, Function)); } DEBUG ((DEBUG_INFO, "State - Measurement - 0x%08x, Authentication - 0x%08x\n", DeviceSecurityState->MeasurementState, DeviceSecurityState->AuthenticationState )); return EFI_SUCCESS; } EDKII_DEVICE_SECURITY_POLICY_PROTOCOL mDeviceSecurityPolicy = { EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_REVISION, GetDevicePolicy, NotifyDeviceState, }; /** Entrypoint of the device security driver. @param[in] ImageHandle ImageHandle of the loaded driver @param[in] SystemTable Pointer to the System Table @retval EFI_SUCCESS The Protocol is installed. @retval EFI_OUT_OF_RESOURCES Not enough resources available to initialize driver. @retval EFI_DEVICE_ERROR A device error occurred attempting to initialize the driver. **/ EFI_STATUS EFIAPI MainEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_HANDLE Handle; EFI_STATUS Status; Handle = NULL; Status = gBS->InstallProtocolInterface ( &Handle, &gEdkiiDeviceSecurityPolicyProtocolGuid, EFI_NATIVE_INTERFACE, &mDeviceSecurityPolicy ); ASSERT_EFI_ERROR(Status); return Status; }