]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/Pci: Add DeviceSecurity support.
authorJiewen Yao <jiewen.yao@intel.com>
Sun, 29 Sep 2019 08:37:14 +0000 (16:37 +0800)
committerJiewen Yao <jiewen.yao@intel.com>
Mon, 11 Nov 2019 11:04:05 +0000 (19:04 +0800)
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>
MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c
MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c

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