diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c index b020ce50ce..64284ac825 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c @@ -8,7 +8,7 @@ PCI Root Bridges. So it means platform needs install PCI Root Bridge IO protocol for each PCI Root Bus and install PCI Host Bridge Resource Allocation Protocol. -Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -37,7 +37,7 @@ UINT64 gAllZero = 0; EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol; EFI_PCI_OVERRIDE_PROTOCOL *gPciOverrideProtocol; EDKII_IOMMU_PROTOCOL *mIoMmuProtocol; - +EDKII_DEVICE_SECURITY_PROTOCOL *mDeviceSecurityProtocol; GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL mPciHotPlugRequest = { PciHotPlugRequestNotify @@ -293,6 +293,14 @@ PciBusDriverBindingStart ( ); } + if (mDeviceSecurityProtocol == NULL) { + gBS->LocateProtocol ( + &gEdkiiDeviceSecurityProtocolGuid, + NULL, + (VOID **) &mDeviceSecurityProtocol + ); + } + if (PcdGetBool (PcdPciDisableBusEnumeration)) { gFullEnumeration = FALSE; } else { diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h index 504a1b1c12..d4113993c8 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h @@ -27,6 +27,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf index 05c22025b8..9284998f36 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf @@ -2,7 +2,7 @@ # The PCI bus driver will probe all PCI devices and allocate MMIO and IO space for these devices. # Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable hot plug supporting. # -# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -90,6 +90,8 @@ gEfiIncompatiblePciDeviceSupportProtocolGuid ## SOMETIMES_CONSUMES gEfiLoadFile2ProtocolGuid ## SOMETIMES_PRODUCES gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES + gEdkiiDeviceSecurityProtocolGuid ## SOMETIMES_CONSUMES + gEdkiiDeviceIdentifierTypePciGuid ## SOMETIMES_CONSUMES gEfiLoadedImageDevicePathProtocolGuid ## CONSUMES [FeaturePcd] diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c index c7eafff593..f8020f4e72 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c @@ -10,6 +10,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "PciBus.h" extern CHAR16 *mBarTypeStr[]; +extern EDKII_DEVICE_SECURITY_PROTOCOL *mDeviceSecurityProtocol; #define OLD_ALIGN 0xFFFFFFFFFFFFFFFFULL #define EVEN_ALIGN 0xFFFFFFFFFFFFFFFEULL @@ -2070,6 +2071,67 @@ InitializeP2C ( PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero); } +/* + Authenticate the PCI device by using DeviceSecurityProtocol. + + @param PciIoDevice PCI device. + + @retval EFI_SUCCESS The device passes the authentication. + @return not EFI_SUCCESS The device failes the authentication or + unexpected error happen during authentication. +*/ +EFI_STATUS +AuthenticatePciDevice ( + IN PCI_IO_DEVICE *PciIoDevice + ) +{ + EDKII_DEVICE_IDENTIFIER DeviceIdentifier; + EFI_STATUS Status; + + if (mDeviceSecurityProtocol != NULL) { + // + // Prepare the parameter + // + DeviceIdentifier.Version = EDKII_DEVICE_IDENTIFIER_REVISION; + CopyGuid (&DeviceIdentifier.DeviceType, &gEdkiiDeviceIdentifierTypePciGuid); + DeviceIdentifier.DeviceHandle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &DeviceIdentifier.DeviceHandle, + &gEfiDevicePathProtocolGuid, + PciIoDevice->DevicePath, + &gEdkiiDeviceIdentifierTypePciGuid, + &PciIoDevice->PciIo, + NULL + ); + if (EFI_ERROR(Status)) { + return Status; + } + + // + // Do DeviceAuthentication + // + Status = mDeviceSecurityProtocol->DeviceAuthenticate (mDeviceSecurityProtocol, &DeviceIdentifier); + // + // Always uninstall, because they are only for Authentication. + // No need to check return Status. + // + gBS->UninstallMultipleProtocolInterfaces ( + DeviceIdentifier.DeviceHandle, + &gEfiDevicePathProtocolGuid, + PciIoDevice->DevicePath, + &gEdkiiDeviceIdentifierTypePciGuid, + &PciIoDevice->PciIo, + NULL + ); + return Status; + } + + // + // Device Security Protocol is not found, just return success + // + return EFI_SUCCESS; +} + /** Create and initialize general PCI I/O device instance for PCI device/bridge device/hotplug bridge device. @@ -2156,6 +2218,21 @@ CreatePciIoDevice ( PciIoDevice->IsPciExp = TRUE; } + // + // Now we can do the authentication check for the device. + // + Status = AuthenticatePciDevice (PciIoDevice); + // + // If authentication fails, skip this device. + // + if (EFI_ERROR(Status)) { + if (PciIoDevice->DevicePath != NULL) { + FreePool (PciIoDevice->DevicePath); + } + FreePool (PciIoDevice); + return NULL; + } + if (PcdGetBool (PcdAriSupport)) { // // Check if the device is an ARI device. diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c index 5b55fb5d3b..72690ab647 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c @@ -1054,7 +1054,9 @@ PciScanBus ( &PciDevice ); - ASSERT (!EFI_ERROR (Status)); + if (EFI_ERROR (Status)) { + continue; + } PciAddress = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0);