From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga04.intel.com (mga04.intel.com []) by mx.groups.io with SMTP id smtpd.web09.4093.1573133872202967224 for ; Thu, 07 Nov 2019 05:37:54 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: jiewen.yao@intel.com) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Nov 2019 05:37:53 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,278,1569308400"; d="scan'208";a="205678538" Received: from jyao1-mobl2.ccr.corp.intel.com ([10.254.209.46]) by orsmga003.jf.intel.com with ESMTP; 07 Nov 2019 05:37:52 -0800 From: "Yao, Jiewen" To: devel@edk2.groups.io Cc: Jian J Wang , Hao A Wu , Ray Ni , Yun Lou Subject: [PATCH V3 4/4] MdeModulePkg/Pci: Add DeviceSecurity support. Date: Thu, 7 Nov 2019 21:37:38 +0800 Message-Id: <20191107133738.23824-5-jiewen.yao@intel.com> X-Mailer: git-send-email 2.19.2.windows.1 In-Reply-To: <20191107133738.23824-1-jiewen.yao@intel.com> References: <20191107133738.23824-1-jiewen.yao@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 Cc: Hao A Wu Cc: Ray Ni Cc: Yun Lou Signed-off-by: Jiewen Yao Reviewed-by: Ray Ni --- MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c | 12 ++- MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 1 + MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf | 4 +- .../Bus/Pci/PciBusDxe/PciEnumeratorSupport.c | 77 +++++++++++++++++++ MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c | 4 +- 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.
+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); -- 2.19.2.windows.1