summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg/Bus
diff options
context:
space:
mode:
authorJiewen Yao <jiewen.yao@intel.com>2019-09-29 16:37:14 +0800
committerJiewen Yao <jiewen.yao@intel.com>2019-11-11 19:04:05 +0800
commit995d8b8568fe67afffdaac3012d7b990e7314d0b (patch)
treeba3a2d3b4f1aa00dfc7e476c6b5d9bcac99966a7 /MdeModulePkg/Bus
parent985e0a6de7482868c18d298f08db54d4339f2ea7 (diff)
downloadedk2-995d8b8568fe67afffdaac3012d7b990e7314d0b.tar.gz
edk2-995d8b8568fe67afffdaac3012d7b990e7314d0b.tar.bz2
edk2-995d8b8568fe67afffdaac3012d7b990e7314d0b.zip
MdeModulePkg/Pci: Add DeviceSecurity support.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2303 Whenever a PCI device is discovered, PCI bus calls the EDKII_DEVICE_SECURITY_PROTOCOL to authenticate it. If the function returns success, the PCI bus allocates the resource and installs the PCI_IO for the device. If the function returns fail, the PCI bus skips the device. It is similar to EFI_SECURITY_ARCH_PROTOCOL, which is used to verify an EFI image. Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Hao A Wu <hao.a.wu@intel.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Yun Lou <yun.lou@intel.com> Signed-off-by: Jiewen Yao <jiewen.yao@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
Diffstat (limited to 'MdeModulePkg/Bus')
-rw-r--r--MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c12
-rw-r--r--MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h1
-rw-r--r--MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf4
-rw-r--r--MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c77
-rw-r--r--MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c4
5 files changed, 94 insertions, 4 deletions
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.<BR>
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
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 <Protocol/PciOverride.h>
#include <Protocol/PciEnumerationComplete.h>
#include <Protocol/IoMmu.h>
+#include <Protocol/DeviceSecurity.h>
#include <Library/DebugLib.h>
#include <Library/UefiDriverEntryPoint.h>
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.<BR>
+# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
#
# 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);