[edk2] [Patch 3/5] SecurityPkg/EdkiiSystemCapsuleLib: Use PcdPkcs7CertBufferXdr

Kinney, Michael D posted 5 patches 7 years, 11 months ago
[edk2] [Patch 3/5] SecurityPkg/EdkiiSystemCapsuleLib: Use PcdPkcs7CertBufferXdr
Posted by Kinney, Michael D 7 years, 11 months ago
https://bugzilla.tianocore.org/show_bug.cgi?id=891

Use both PcdPkcs7CertBuffer and PcdPkcs7CertBufferXdr to authenticate
a capsule.  The capsule fails authentication if none of the certificates
in PcdPkcs7CertBuffer or PcdPkcs7CertBufferXdr pass.

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
---
 .../EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.c  | 77 +++++++++++++++++++---
 .../EdkiiSystemCapsuleLib.inf                      |  3 +-
 2 files changed, 70 insertions(+), 10 deletions(-)

diff --git a/SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.c b/SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.c
index 876d2257b3..5217a63082 100644
--- a/SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.c
+++ b/SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.c
@@ -6,7 +6,7 @@
   CapsuleAuthenticateSystemFirmware(), ExtractAuthenticatedImage() will receive
   untrusted input and do basic validation.
 
-  Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
   which accompanies this distribution.  The full text of the license may be found at
@@ -370,6 +370,8 @@ ExtractAuthenticatedImage (
   GUID                                      *CertType;
   VOID                                      *PublicKeyData;
   UINTN                                     PublicKeyDataLength;
+  UINT8                                     *PublicKeyDataXdr;
+  UINT8                                     *PublicKeyDataXdrEnd;
 
   DEBUG((DEBUG_INFO, "ExtractAuthenticatedImage - Image: 0x%08x - 0x%08x\n", (UINTN)Image, (UINTN)ImageSize));
 
@@ -410,21 +412,78 @@ ExtractAuthenticatedImage (
   if (CompareGuid(&gEfiCertPkcs7Guid, CertType)) {
     PublicKeyData   = PcdGetPtr(PcdPkcs7CertBuffer);
     PublicKeyDataLength = PcdGetSize(PcdPkcs7CertBuffer);
+
+    ASSERT (PublicKeyData != NULL);
+    ASSERT (PublicKeyDataLength != 0);
+
+    Status = AuthenticateFmpImage(
+               ImageAuth,
+               ImageSize,
+               PublicKeyData,
+               PublicKeyDataLength
+               );
+    if (EFI_ERROR (Status)) {
+      PublicKeyDataXdr    = PcdGetPtr (PcdPkcs7CertBufferXdr);
+      PublicKeyDataXdrEnd = PublicKeyDataXdr + PcdGetSize (PcdPkcs7CertBufferXdr);
+
+      ASSERT (PublicKeyDataXdr != NULL);
+      ASSERT (PublicKeyDataXdr != PublicKeyDataXdrEnd);
+
+      //
+      // Try each key from PcdPkcs7CertBufferXdr
+      //
+      while (PublicKeyDataXdr < PublicKeyDataXdrEnd) {
+        if (PublicKeyDataXdr + sizeof (UINT32) > PublicKeyDataXdrEnd) {
+          //
+          // Key data extends beyond end of PCD
+          //
+          break;
+        }
+        //
+        // Read key length stored in big endian format
+        //
+        PublicKeyDataLength = SwapBytes32 (*(UINT32 *)(PublicKeyDataXdr));
+        //
+        // Point to the start of the key data
+        //
+        PublicKeyDataXdr += sizeof (UINT32);
+        if (PublicKeyDataXdr + PublicKeyDataLength > PublicKeyDataXdrEnd) {
+          //
+          // Key data extends beyond end of PCD
+          //
+          break;
+        }
+        PublicKeyData = PublicKeyDataXdr;
+        Status = AuthenticateFmpImage (
+                   ImageAuth,
+                   ImageSize,
+                   PublicKeyData,
+                   PublicKeyDataLength
+                   );
+        if (!EFI_ERROR (Status)) {
+          break;
+        }
+        PublicKeyDataXdr += PublicKeyDataLength;
+        PublicKeyDataXdr = (UINT8 *)ALIGN_POINTER (PublicKeyDataXdr, sizeof(UINT32));
+      }
+    }
   } else if (CompareGuid(&gEfiCertTypeRsa2048Sha256Guid, CertType)) {
     PublicKeyData = PcdGetPtr(PcdRsa2048Sha256PublicKeyBuffer);
     PublicKeyDataLength = PcdGetSize(PcdRsa2048Sha256PublicKeyBuffer);
+
+    ASSERT (PublicKeyData != NULL);
+    ASSERT (PublicKeyDataLength != 0);
+
+    Status = AuthenticateFmpImage(
+               ImageAuth,
+               ImageSize,
+               PublicKeyData,
+               PublicKeyDataLength
+               );
   } else {
     return FALSE;
   }
-  ASSERT (PublicKeyData != NULL);
-  ASSERT (PublicKeyDataLength != 0);
 
-  Status = AuthenticateFmpImage(
-             ImageAuth,
-             ImageSize,
-             PublicKeyData,
-             PublicKeyDataLength
-             );
   switch (Status) {
   case RETURN_SUCCESS:
     *LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
diff --git a/SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.inf b/SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.inf
index a721619a67..2b18d918d1 100644
--- a/SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.inf
+++ b/SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.inf
@@ -3,7 +3,7 @@
 #
 #  EDKII System Capsule library instance for DXE/PEI post memory phase.
 #
-#  Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
@@ -52,6 +52,7 @@ [Pcd]
   gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareFileGuid           ## CONSUMES
   gEfiSecurityPkgTokenSpaceGuid.PcdRsa2048Sha256PublicKeyBuffer               ## CONSUMES
   gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer                            ## CONSUMES
+  gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBufferXdr                         ## CONSUMES
 
 [Guids]
   gEdkiiSystemFirmwareImageDescriptorFileGuid          ## SOMETIMES_CONSUMES   ## GUID
-- 
2.14.2.windows.3

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [Patch 3/5] SecurityPkg/EdkiiSystemCapsuleLib: Use PcdPkcs7CertBufferXdr
Posted by Gao, Liming 7 years, 11 months ago
Mike: 
  The title should be SignedCapsulePkg EdkiiSystemCapsuleLib instead of SecurityPkg. 
  

> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Kinney, Michael D
> Sent: Tuesday, March 13, 2018 3:30 AM
> To: edk2-devel@lists.01.org
> Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Yao, Jiewen <jiewen.yao@intel.com>; Zhang, Chao B <chao.b.zhang@intel.com>
> Subject: [edk2] [Patch 3/5] SecurityPkg/EdkiiSystemCapsuleLib: Use PcdPkcs7CertBufferXdr
> 
> https://bugzilla.tianocore.org/show_bug.cgi?id=891
> 
> Use both PcdPkcs7CertBuffer and PcdPkcs7CertBufferXdr to authenticate
> a capsule.  The capsule fails authentication if none of the certificates
> in PcdPkcs7CertBuffer or PcdPkcs7CertBufferXdr pass.
> 
> Cc: Sean Brogan <sean.brogan@microsoft.com>
> Cc: Chao Zhang <chao.b.zhang@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
> ---
>  .../EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.c  | 77 +++++++++++++++++++---
>  .../EdkiiSystemCapsuleLib.inf                      |  3 +-
>  2 files changed, 70 insertions(+), 10 deletions(-)
> 
> diff --git a/SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.c
> b/SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.c
> index 876d2257b3..5217a63082 100644
> --- a/SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.c
> +++ b/SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.c
> @@ -6,7 +6,7 @@
>    CapsuleAuthenticateSystemFirmware(), ExtractAuthenticatedImage() will receive
>    untrusted input and do basic validation.
> 
> -  Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
>    This program and the accompanying materials
>    are licensed and made available under the terms and conditions of the BSD License
>    which accompanies this distribution.  The full text of the license may be found at
> @@ -370,6 +370,8 @@ ExtractAuthenticatedImage (
>    GUID                                      *CertType;
>    VOID                                      *PublicKeyData;
>    UINTN                                     PublicKeyDataLength;
> +  UINT8                                     *PublicKeyDataXdr;
> +  UINT8                                     *PublicKeyDataXdrEnd;
> 
>    DEBUG((DEBUG_INFO, "ExtractAuthenticatedImage - Image: 0x%08x - 0x%08x\n", (UINTN)Image, (UINTN)ImageSize));
> 
> @@ -410,21 +412,78 @@ ExtractAuthenticatedImage (
>    if (CompareGuid(&gEfiCertPkcs7Guid, CertType)) {
>      PublicKeyData   = PcdGetPtr(PcdPkcs7CertBuffer);
>      PublicKeyDataLength = PcdGetSize(PcdPkcs7CertBuffer);
> +
> +    ASSERT (PublicKeyData != NULL);
> +    ASSERT (PublicKeyDataLength != 0);
> +
> +    Status = AuthenticateFmpImage(
> +               ImageAuth,
> +               ImageSize,
> +               PublicKeyData,
> +               PublicKeyDataLength
> +               );
> +    if (EFI_ERROR (Status)) {
> +      PublicKeyDataXdr    = PcdGetPtr (PcdPkcs7CertBufferXdr);
> +      PublicKeyDataXdrEnd = PublicKeyDataXdr + PcdGetSize (PcdPkcs7CertBufferXdr);
> +
> +      ASSERT (PublicKeyDataXdr != NULL);
> +      ASSERT (PublicKeyDataXdr != PublicKeyDataXdrEnd);
> +
> +      //
> +      // Try each key from PcdPkcs7CertBufferXdr
> +      //
> +      while (PublicKeyDataXdr < PublicKeyDataXdrEnd) {
> +        if (PublicKeyDataXdr + sizeof (UINT32) > PublicKeyDataXdrEnd) {
> +          //
> +          // Key data extends beyond end of PCD
> +          //
> +          break;
> +        }
> +        //
> +        // Read key length stored in big endian format
> +        //
> +        PublicKeyDataLength = SwapBytes32 (*(UINT32 *)(PublicKeyDataXdr));
> +        //
> +        // Point to the start of the key data
> +        //
> +        PublicKeyDataXdr += sizeof (UINT32);
> +        if (PublicKeyDataXdr + PublicKeyDataLength > PublicKeyDataXdrEnd) {
> +          //
> +          // Key data extends beyond end of PCD
> +          //
> +          break;
> +        }
> +        PublicKeyData = PublicKeyDataXdr;
> +        Status = AuthenticateFmpImage (
> +                   ImageAuth,
> +                   ImageSize,
> +                   PublicKeyData,
> +                   PublicKeyDataLength
> +                   );
> +        if (!EFI_ERROR (Status)) {
> +          break;
> +        }
> +        PublicKeyDataXdr += PublicKeyDataLength;
> +        PublicKeyDataXdr = (UINT8 *)ALIGN_POINTER (PublicKeyDataXdr, sizeof(UINT32));
> +      }
> +    }
>    } else if (CompareGuid(&gEfiCertTypeRsa2048Sha256Guid, CertType)) {
>      PublicKeyData = PcdGetPtr(PcdRsa2048Sha256PublicKeyBuffer);
>      PublicKeyDataLength = PcdGetSize(PcdRsa2048Sha256PublicKeyBuffer);
> +
> +    ASSERT (PublicKeyData != NULL);
> +    ASSERT (PublicKeyDataLength != 0);
> +
> +    Status = AuthenticateFmpImage(
> +               ImageAuth,
> +               ImageSize,
> +               PublicKeyData,
> +               PublicKeyDataLength
> +               );
>    } else {
>      return FALSE;
>    }
> -  ASSERT (PublicKeyData != NULL);
> -  ASSERT (PublicKeyDataLength != 0);
> 
> -  Status = AuthenticateFmpImage(
> -             ImageAuth,
> -             ImageSize,
> -             PublicKeyData,
> -             PublicKeyDataLength
> -             );
>    switch (Status) {
>    case RETURN_SUCCESS:
>      *LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
> diff --git a/SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.inf
> b/SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.inf
> index a721619a67..2b18d918d1 100644
> --- a/SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.inf
> +++ b/SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.inf
> @@ -3,7 +3,7 @@
>  #
>  #  EDKII System Capsule library instance for DXE/PEI post memory phase.
>  #
> -#  Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
> +#  Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
>  #  This program and the accompanying materials
>  #  are licensed and made available under the terms and conditions of the BSD License
>  #  which accompanies this distribution.  The full text of the license may be found at
> @@ -52,6 +52,7 @@ [Pcd]
>    gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareFileGuid           ## CONSUMES
>    gEfiSecurityPkgTokenSpaceGuid.PcdRsa2048Sha256PublicKeyBuffer               ## CONSUMES
>    gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer                            ## CONSUMES
> +  gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBufferXdr                         ## CONSUMES
> 
>  [Guids]
>    gEdkiiSystemFirmwareImageDescriptorFileGuid          ## SOMETIMES_CONSUMES   ## GUID
> --
> 2.14.2.windows.3
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel