]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.c
SignedCapsulePkg: Update EdkiiSystemCapsuleLib to check PCD value
[mirror_edk2.git] / SignedCapsulePkg / Library / EdkiiSystemCapsuleLib / EdkiiSystemCapsuleLib.c
index 27c6f4c0b4d6b256cd74eeb05dda7ff99b47124f..876d2257b36548e1cab08066a194ad9d75b2faf5 100644 (file)
@@ -6,7 +6,7 @@
   CapsuleAuthenticateSystemFirmware(), ExtractAuthenticatedImage() will receive\r
   untrusted input and do basic validation.\r
 \r
-  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
@@ -29,6 +29,7 @@
 #include <Library/BaseLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/EdkiiSystemCapsuleLib.h>\r
 #include <Library/FmpAuthenticationLib.h>\r
@@ -386,7 +387,7 @@ ExtractAuthenticatedImage (
     DEBUG((DEBUG_ERROR, "ExtractAuthenticatedImage - dwLength too small\n"));\r
     return FALSE;\r
   }\r
-  if (ImageAuth->AuthInfo.Hdr.dwLength > MAX_UINTN - sizeof(UINT64)) {\r
+  if ((UINTN) ImageAuth->AuthInfo.Hdr.dwLength > MAX_UINTN - sizeof(UINT64)) {\r
     DEBUG((DEBUG_ERROR, "ExtractAuthenticatedImage - dwLength too big\n"));\r
     return FALSE;\r
   }\r
@@ -415,6 +416,8 @@ ExtractAuthenticatedImage (
   } else {\r
     return FALSE;\r
   }\r
+  ASSERT (PublicKeyData != NULL);\r
+  ASSERT (PublicKeyDataLength != 0);\r
 \r
   Status = AuthenticateFmpImage(\r
              ImageAuth,\r
@@ -598,6 +601,10 @@ CapsuleAuthenticateSystemFirmware (
   // NOTE: This function need run in an isolated environment.\r
   // Do not touch FMP protocol and its private structure.\r
   //\r
+  if (mImageFmpInfo == NULL) {\r
+    DEBUG((DEBUG_INFO, "ImageFmpInfo is not set\n"));\r
+    return EFI_SECURITY_VIOLATION;\r
+  }\r
 \r
   Result = ExtractAuthenticatedImage((VOID *)Image, ImageSize, LastAttemptStatus, AuthenticatedImage, AuthenticatedImageSize);\r
   if (!Result) {\r
@@ -641,7 +648,7 @@ CapsuleAuthenticateSystemFirmware (
       return EFI_SECURITY_VIOLATION;\r
     }\r
   } else {\r
-    if (CurrentImageFmpInfo->Version < ImageFmpInfo->LowestSupportedImageVersion) {\r
+    if (ImageFmpInfo->Version < CurrentImageFmpInfo->LowestSupportedImageVersion) {\r
       *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION;\r
       DEBUG((DEBUG_INFO, "LowestSupportedImageVersion check - fail\n"));\r
       return EFI_SECURITY_VIOLATION;\r
@@ -652,6 +659,53 @@ CapsuleAuthenticateSystemFirmware (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  PcdCallBack gets the real set PCD value\r
+\r
+  @param[in]      CallBackGuid    The PCD token GUID being set.\r
+  @param[in]      CallBackToken   The PCD token number being set.\r
+  @param[in, out] TokenData       A pointer to the token data being set.\r
+  @param[in]      TokenDataSize   The size, in bytes, of the data being set.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+EdkiiSystemCapsuleLibPcdCallBack (\r
+  IN        CONST GUID        *CallBackGuid, OPTIONAL\r
+  IN        UINTN             CallBackToken,\r
+  IN  OUT   VOID              *TokenData,\r
+  IN        UINTN             TokenDataSize\r
+  )\r
+{\r
+  if (CompareGuid (CallBackGuid, &gEfiSignedCapsulePkgTokenSpaceGuid) &&\r
+      CallBackToken == PcdToken (PcdEdkiiSystemFirmwareImageDescriptor)) {\r
+    mImageFmpInfoSize = TokenDataSize;\r
+    mImageFmpInfo = AllocateCopyPool (mImageFmpInfoSize, TokenData);\r
+    ASSERT(mImageFmpInfo != NULL);\r
+    //\r
+    // Cancel Callback after get the real set value\r
+    //\r
+    LibPcdCancelCallback (\r
+      &gEfiSignedCapsulePkgTokenSpaceGuid,\r
+      PcdToken (PcdEdkiiSystemFirmwareImageDescriptor),\r
+      EdkiiSystemCapsuleLibPcdCallBack\r
+      );\r
+  }\r
+\r
+  if (CompareGuid (CallBackGuid, &gEfiSignedCapsulePkgTokenSpaceGuid) &&\r
+      CallBackToken == PcdToken (PcdEdkiiSystemFirmwareFileGuid)) {\r
+    CopyGuid(&mEdkiiSystemFirmwareFileGuid, TokenData);\r
+    //\r
+    // Cancel Callback after get the real set value\r
+    //\r
+    LibPcdCancelCallback (\r
+      &gEfiSignedCapsulePkgTokenSpaceGuid,\r
+      PcdToken (PcdEdkiiSystemFirmwareFileGuid),\r
+      EdkiiSystemCapsuleLibPcdCallBack\r
+      );\r
+  }\r
+}\r
+\r
 /**\r
   The constructor function.\r
 \r
@@ -664,8 +718,38 @@ EdkiiSystemCapsuleLibConstructor (
   )\r
 {\r
   mImageFmpInfoSize = PcdGetSize(PcdEdkiiSystemFirmwareImageDescriptor);\r
-  mImageFmpInfo = AllocateCopyPool (mImageFmpInfoSize, PcdGetPtr(PcdEdkiiSystemFirmwareImageDescriptor));\r
-  ASSERT(mImageFmpInfo != NULL);\r
+  mImageFmpInfo     = PcdGetPtr(PcdEdkiiSystemFirmwareImageDescriptor);\r
+  //\r
+  // Verify Firmware Image Descriptor first\r
+  //\r
+  if (mImageFmpInfoSize < sizeof (EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR) ||\r
+      mImageFmpInfo->Signature != EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR_SIGNATURE) {\r
+    //\r
+    // SystemFirmwareImageDescriptor is not set.\r
+    // Register PCD set callback to hook PCD value set.\r
+    //\r
+    mImageFmpInfo     = NULL;\r
+    mImageFmpInfoSize = 0;\r
+    LibPcdCallbackOnSet (\r
+      &gEfiSignedCapsulePkgTokenSpaceGuid,\r
+      PcdToken (PcdEdkiiSystemFirmwareImageDescriptor),\r
+      EdkiiSystemCapsuleLibPcdCallBack\r
+      );\r
+  } else {\r
+    mImageFmpInfo = AllocateCopyPool (mImageFmpInfoSize, mImageFmpInfo);\r
+    ASSERT(mImageFmpInfo != NULL);\r
+  }\r
+\r
   CopyGuid(&mEdkiiSystemFirmwareFileGuid, PcdGetPtr(PcdEdkiiSystemFirmwareFileGuid));\r
+  //\r
+  // Verify GUID value first\r
+  //\r
+  if (CompareGuid (&mEdkiiSystemFirmwareFileGuid, &gZeroGuid)) {\r
+    LibPcdCallbackOnSet (\r
+      &gEfiSignedCapsulePkgTokenSpaceGuid,\r
+      PcdToken (PcdEdkiiSystemFirmwareFileGuid),\r
+      EdkiiSystemCapsuleLibPcdCallBack\r
+      );\r
+  }\r
   return EFI_SUCCESS;\r
 }\r