From nobody Sat Apr 20 05:03:32 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+61535+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+61535+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=mellanox.com ARC-Seal: i=1; a=rsa-sha256; t=1592589358; cv=none; d=zohomail.com; s=zohoarc; b=TSR1wlODcukfjNbptiZoojwjGXtTRyOdTpGJaLhslZvTu0/munTgLlTSCX3A51Vmwn+w+Akex2OuEC7Y0wWM5fMSVTXxA6h6jMiqz/JS5NzOfRR+VdOhxFQhmqnXqHVHQaK8X0XZAZvFKpflE9p7RGhPg9S/0g/oqGselA7V2Hs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1592589358; h=Cc:Date:From:List-Id:List-Unsubscribe:Message-ID:Reply-To:Sender:Subject:To; bh=RiTBVUJSWT3Ri7HfHg2vf+R1KSY91RTCyQ9v6qV4zXE=; b=G84gXL+KCEwj1DfDoAj6RaWO5psEusXNFwTkXjbEFAsrupkYzn1eYrMrXhNGXTgHaWGjHzDwZ0s6dyCAuuqxBOcTjV0eioHOxxwzTLdw8JZCEh1fiMrY8B+SY6GFF7eJQSfy7FuT7MR0uad0M44GElCH9xdCTSym/iV9WBC2ims= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+61535+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1592589358080569.5100939834446; Fri, 19 Jun 2020 10:55:58 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id V6OCYY1788612xw0Q82jxw66; Fri, 19 Jun 2020 10:55:57 -0700 X-Received: from mellanox.co.il (mellanox.co.il [193.47.165.129]) by mx.groups.io with SMTP id smtpd.web12.148.1592588916847307028 for ; Fri, 19 Jun 2020 10:48:37 -0700 X-Received: from Internal Mail-Server by MTLPINE1 (envelope-from lsun@mellanox.com) with SMTP; 19 Jun 2020 20:48:31 +0300 X-Received: from bu-lab53.mtbu.labs.mlnx (bu-lab53.mtbu.labs.mlnx [10.15.8.107]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 05JHmUHx000412; Fri, 19 Jun 2020 20:48:31 +0300 X-Received: from bu-lab53.mtbu.labs.mlnx (localhost [127.0.0.1]) by bu-lab53.mtbu.labs.mlnx (8.14.7/8.14.7) with ESMTP id 05JHmUds011331; Fri, 19 Jun 2020 13:48:30 -0400 X-Received: (from lsun@localhost) by bu-lab53.mtbu.labs.mlnx (8.14.7/8.14.7/Submit) id 05JHmTCJ011330; Fri, 19 Jun 2020 13:48:29 -0400 From: "Liming Sun" To: Wei6 Xu , Liming Gao , Michael D Kinney Cc: Liming Sun , devel@edk2.groups.io, Sean Brogan Subject: [edk2-devel] [PATCH] FmpDevicePkg: Enhance capsule verification with secure boot keys Date: Fri, 19 Jun 2020 13:48:17 -0400 Message-Id: <5b42e8e089fb961766c639b733284413ccf03272.1592587621.git.lsun@mellanox.com> Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lsun@mellanox.com X-Gm-Message-State: krL3UAmN9WnAYbf1KIutd72Wx1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1592589357; bh=AiLvKGh5+0FdaxNZBtcmLQNimzECl/dtmwMm8CXDJeg=; h=Cc:Date:From:Reply-To:Subject:To; b=JAhvpSEqygVJQnAZcBBAxsXEFHYnJ6/yPOcJJ0Mxw3VSswTxtgUwAzr1kPE2OBgHrcc ME6vxqCIru0O6hiby7WCUkZkb8ktYPSUsLpeOye32SOSpGIyST1Z8QlpVMCNZVJwHouf8 ycVf0TreE495uytK4CylgiStz9rHJcFam2M= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This commit enhances the FmpDevicePkg package to optionally verify capsule with the secure boot keys when PcdFmpDevicePkcs7CertBufferXdr is not set and the new PCD variable PcdFmpDeviceAllowSecureBootKeys is configured. Below is the check logic: - Pass if verified with PK key, or PK key not set yet; - Deny if verified with the DBX keys; - Verified it against the DB keys; One purpose for this change is to auto-deploy the UEFI secure boot keys with UEFI capsule. Initially it's done in trusted environment. Once secure boot is enabled, the same keys will be used to verify the signed capsules as well for further updates. Signed-off-by: Liming Sun --- FmpDevicePkg/FmpDevicePkg.dec | 6 +++ FmpDevicePkg/FmpDxe/FmpDxe.c | 109 ++++++++++++++++++++++++++++++++++= ++-- FmpDevicePkg/FmpDxe/FmpDxe.h | 1 + FmpDevicePkg/FmpDxe/FmpDxe.inf | 3 ++ FmpDevicePkg/FmpDxe/FmpDxeLib.inf | 1 + 5 files changed, 117 insertions(+), 3 deletions(-) diff --git a/FmpDevicePkg/FmpDevicePkg.dec b/FmpDevicePkg/FmpDevicePkg.dec index cab63f5..3aeb89c 100644 --- a/FmpDevicePkg/FmpDevicePkg.dec +++ b/FmpDevicePkg/FmpDevicePkg.dec @@ -126,6 +126,12 @@ # @Prompt Firmware Device Image Type ID gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageTypeIdGuid|{0}|VOID*|0x4000= 0010 =20 + ## This option is used to verify the capsule using secure boot keys if t= he + # PcdFmpDevicePkcs7CertBufferXdr is not configured. In such case, the ch= eck + # will pass if secure boot hasn't been enabled yet. + # @A flag to tell whether to use secure boot keys when PcdFmpDevicePkcs7= CertBufferXdr is not set. + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceAllowSecureBootKeys|0x0|UINT8|0x= 40000012 + [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] ## One or more PKCS7 certificates used to verify a firmware device capsu= le # update image. Encoded using the Variable-Length Opaque Data format o= f RFC diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.c b/FmpDevicePkg/FmpDxe/FmpDxe.c index 5884177..6f82aee 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxe.c +++ b/FmpDevicePkg/FmpDxe/FmpDxe.c @@ -682,6 +682,102 @@ GetAllHeaderSize ( return CalculatedSize; } =20 +EFI_STATUS +CheckTheImageWithSecureBootVariable ( + IN CONST CHAR16 *Name, + IN CONST EFI_GUID *Guid, + IN CONST VOID *Image, + IN UINTN ImageSize + ) +{ + EFI_STATUS Status; + VOID *Data; + UINTN Length; + EFI_SIGNATURE_LIST *CertList; + EFI_SIGNATURE_DATA *CertData; + UINTN CertCount; + UINTN Index; + + Status =3D GetVariable2 (Name, Guid, &Data, &Length); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + CertList =3D (EFI_SIGNATURE_LIST *) Data; + while ((Length > 0) && (Length >=3D CertList->SignatureListSize)) { + if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) { + CertData =3D (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize); + CertCount =3D (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_L= IST) - + CertList->SignatureHeaderSize) / CertList->SignatureSize; + + for (Index =3D 0; Index < CertCount; Index++) { + Status =3D AuthenticateFmpImage ( + (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, + ImageSize, + CertData->SignatureData, + CertList->SignatureSize - sizeof (EFI_GUID) + ); + if (!EFI_ERROR (Status)) + goto Done; + + CertData =3D (EFI_SIGNATURE_DATA *) ((UINT8 *) CertData + CertList= ->SignatureSize); + } + } + + Length -=3D CertList->SignatureListSize; + CertList =3D (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->Si= gnatureListSize); + } + +Done: + FreePool (Data); + return Status; +} + +EFI_STATUS +CheckTheImageWithSecureBootKeys ( + IN CONST VOID *Image, + IN UINTN ImageSize + ) +{ + EFI_STATUS Status; + + // PK check. + Status =3D CheckTheImageWithSecureBootVariable( + EFI_PLATFORM_KEY_NAME, + &gEfiGlobalVariableGuid, + Image, + ImageSize + ); + if (!EFI_ERROR (Status) || Status =3D=3D EFI_NOT_FOUND) { + // Return SUCCESS if verified by PK key or PK key not configured. + DEBUG ((DEBUG_INFO, "FmpDxe: Verified capsule with PK key.\n")); + return EFI_SUCCESS; + } + + // DBX check. + Status =3D CheckTheImageWithSecureBootVariable( + EFI_IMAGE_SECURITY_DATABASE1, + &gEfiImageSecurityDatabaseGuid, + Image, + ImageSize + ); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "FmpDxe: Reject capsule with DBX key.\n")); + return EFI_SECURITY_VIOLATION; + } + + // DB check. + DEBUG ((DEBUG_INFO, "FmpDxe: Verify capsule with DB key.\n")); + Status =3D CheckTheImageWithSecureBootVariable( + EFI_IMAGE_SECURITY_DATABASE, + &gEfiImageSecurityDatabaseGuid, + Image, + ImageSize + ); + return Status; +} + /** Checks if the firmware image is valid for the device. =20 @@ -728,6 +824,7 @@ CheckTheImage ( UINT8 *PublicKeyDataXdrEnd; EFI_FIRMWARE_IMAGE_DEP *Dependencies; UINT32 DependenciesSize; + UINT8 AllowSecureBootKeys; =20 Status =3D EFI_SUCCESS; RawSize =3D 0; @@ -782,9 +879,15 @@ CheckTheImage ( PublicKeyDataXdr =3D PcdGetPtr (PcdFmpDevicePkcs7CertBufferXdr); PublicKeyDataXdrEnd =3D PublicKeyDataXdr + PcdGetSize (PcdFmpDevicePkcs7= CertBufferXdr); =20 - if (PublicKeyDataXdr =3D=3D NULL || (PublicKeyDataXdr =3D=3D PublicKeyDa= taXdrEnd)) { - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Invalid certificate, skipping it.\n"= , mImageIdName)); - Status =3D EFI_ABORTED; + if (PublicKeyDataXdr =3D=3D NULL || (PublicKeyDataXdrEnd - PublicKeyData= Xdr < sizeof (UINT32))) { + AllowSecureBootKeys =3D PcdGet8 (PcdFmpDeviceAllowSecureBootKeys); + if (AllowSecureBootKeys) { + DEBUG ((DEBUG_INFO, "FmpDxe: Use secure boot certs.\n")); + Status =3D CheckTheImageWithSecureBootKeys (Image, ImageSize); + } else { + DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Invalid certificate, skipping it.\= n", mImageIdName)); + Status =3D EFI_ABORTED; + } } else { // // Try each key from PcdFmpDevicePkcs7CertBufferXdr diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.h b/FmpDevicePkg/FmpDxe/FmpDxe.h index 30754de..72a6ce6 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxe.h +++ b/FmpDevicePkg/FmpDxe/FmpDxe.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include =20 diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.inf b/FmpDevicePkg/FmpDxe/FmpDxe.inf index eeb904a..60b02d4 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxe.inf +++ b/FmpDevicePkg/FmpDxe/FmpDxe.inf @@ -58,6 +58,8 @@ =20 [Guids] gEfiEndOfDxeEventGroupGuid + gEfiCertX509Guid + gEfiImageSecurityDatabaseGuid =20 [Protocols] gEdkiiVariableLockProtocolGuid ## CONSUMES @@ -74,6 +76,7 @@ gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr = ## CONSUMES gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceTestKeySha256Digest = ## CONSUMES gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageTypeIdGuid = ## CONSUMES + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceAllowSecureBootKeys = ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdTestKeyUsed = ## SOMETIMES_PRODUCES =20 [Depex] diff --git a/FmpDevicePkg/FmpDxe/FmpDxeLib.inf b/FmpDevicePkg/FmpDxe/FmpDxe= Lib.inf index 9a93b5e..1308cae 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxeLib.inf +++ b/FmpDevicePkg/FmpDxe/FmpDxeLib.inf @@ -74,6 +74,7 @@ gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr = ## CONSUMES gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceTestKeySha256Digest = ## CONSUMES gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageTypeIdGuid = ## CONSUMES + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceAllowSecureBootKeys = ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdTestKeyUsed = ## SOMETIMES_PRODUCES =20 [Depex] --=20 1.8.3.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#61535): https://edk2.groups.io/g/devel/message/61535 Mute This Topic: https://groups.io/mt/74985160/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-