]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
SecurityPkg/DxeImageVerificationLib: change IsCertHashFoundInDatabase name (CVE-2019...
[mirror_edk2.git] / SecurityPkg / Library / DxeImageVerificationLib / DxeImageVerificationLib.c
index 66d96a9396b9137cd4a7bb3367c82affc9f59389..b7fa8ea8c55c52b8ea0835c403f1143a923cda98 100644 (file)
 \r
 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<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
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -710,7 +704,7 @@ GetImageExeInfoTableSize (
   @param[in]  Name            Input a null-terminated, user-friendly name.\r
   @param[in]  DevicePath      Input device path pointer.\r
   @param[in]  Signature       Input signature info in EFI_SIGNATURE_LIST data structure.\r
-  @param[in]  SignatureSize   Size of signature.\r
+  @param[in]  SignatureSize   Size of signature. Must be zero if Signature is NULL.\r
 \r
 **/\r
 VOID\r
@@ -751,7 +745,7 @@ AddImageExeInfo (
   if (ImageExeInfoTable != NULL) {\r
     //\r
     // The table has been found!\r
-    // We must enlarge the table to accomodate the new exe info entry.\r
+    // We must enlarge the table to accommodate the new exe info entry.\r
     //\r
     ImageExeInfoTableSize = GetImageExeInfoTableSize (ImageExeInfoTable);\r
   } else {\r
@@ -767,6 +761,7 @@ AddImageExeInfo (
   //\r
   // Signature size can be odd. Pad after signature to ensure next EXECUTION_INFO entry align\r
   //\r
+  ASSERT (Signature != NULL || SignatureSize == 0);\r
   NewImageExeInfoEntrySize = sizeof (EFI_IMAGE_EXECUTION_INFO) + NameStringLen + DevicePathSize + SignatureSize;\r
 \r
   NewImageExeInfoTable      = (EFI_IMAGE_EXECUTION_INFO_TABLE *) AllocateRuntimePool (ImageExeInfoTableSize + NewImageExeInfoEntrySize);\r
@@ -827,22 +822,23 @@ AddImageExeInfo (
   @param[in]  SignatureList     Pointer to the Signature List in forbidden database.\r
   @param[in]  SignatureListSize Size of Signature List.\r
   @param[out] RevocationTime    Return the time that the certificate was revoked.\r
+  @param[out] IsFound           Search result. Only valid if EFI_SUCCESS returned.\r
 \r
-  @return TRUE   The certificate hash is found in the forbidden database.\r
-  @return FALSE  The certificate hash is not found in the forbidden database.\r
+  @retval EFI_SUCCESS           Finished the search without any error.\r
+  @retval Others                Error occurred in the search of database.\r
 \r
 **/\r
-BOOLEAN\r
-IsCertHashFoundInDatabase (\r
+EFI_STATUS\r
+IsCertHashFoundInDbx (\r
   IN  UINT8               *Certificate,\r
   IN  UINTN               CertSize,\r
   IN  EFI_SIGNATURE_LIST  *SignatureList,\r
   IN  UINTN               SignatureListSize,\r
-  OUT EFI_TIME            *RevocationTime\r
+  OUT EFI_TIME            *RevocationTime,\r
+  OUT BOOLEAN             *IsFound\r
   )\r
 {\r
-  BOOLEAN             IsFound;\r
-  BOOLEAN             Status;\r
+  EFI_STATUS          Status;\r
   EFI_SIGNATURE_LIST  *DbxList;\r
   UINTN               DbxSize;\r
   EFI_SIGNATURE_DATA  *CertHash;\r
@@ -856,21 +852,22 @@ IsCertHashFoundInDatabase (
   UINT8               *TBSCert;\r
   UINTN               TBSCertSize;\r
 \r
-  IsFound  = FALSE;\r
+  Status   = EFI_ABORTED;\r
+  *IsFound = FALSE;\r
   DbxList  = SignatureList;\r
   DbxSize  = SignatureListSize;\r
   HashCtx  = NULL;\r
   HashAlg  = HASHALG_MAX;\r
 \r
   if ((RevocationTime == NULL) || (DbxList == NULL)) {\r
-    return FALSE;\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   //\r
   // Retrieve the TBSCertificate from the X.509 Certificate.\r
   //\r
   if (!X509GetTBSCert (Certificate, CertSize, &TBSCert, &TBSCertSize)) {\r
-    return FALSE;\r
+    return Status;\r
   }\r
 \r
   while ((DbxSize > 0) && (SignatureListSize >= DbxList->SignatureListSize)) {\r
@@ -900,19 +897,19 @@ IsCertHashFoundInDatabase (
     if (HashCtx == NULL) {\r
       goto Done;\r
     }\r
-    Status = mHash[HashAlg].HashInit (HashCtx);\r
-    if (!Status) {\r
+    if (!mHash[HashAlg].HashInit (HashCtx)) {\r
       goto Done;\r
     }\r
-    Status = mHash[HashAlg].HashUpdate (HashCtx, TBSCert, TBSCertSize);\r
-    if (!Status) {\r
+    if (!mHash[HashAlg].HashUpdate (HashCtx, TBSCert, TBSCertSize)) {\r
       goto Done;\r
     }\r
-    Status = mHash[HashAlg].HashFinal (HashCtx, CertDigest);\r
-    if (!Status) {\r
+    if (!mHash[HashAlg].HashFinal (HashCtx, CertDigest)) {\r
       goto Done;\r
     }\r
 \r
+    FreePool (HashCtx);\r
+    HashCtx = NULL;\r
+\r
     SiglistHeaderSize = sizeof (EFI_SIGNATURE_LIST) + DbxList->SignatureHeaderSize;\r
     CertHash          = (EFI_SIGNATURE_DATA *) ((UINT8 *) DbxList + SiglistHeaderSize);\r
     CertHashCount     = (DbxList->SignatureListSize - SiglistHeaderSize) / DbxList->SignatureSize;\r
@@ -925,7 +922,8 @@ IsCertHashFoundInDatabase (
         //\r
         // Hash of Certificate is found in forbidden database.\r
         //\r
-        IsFound = TRUE;\r
+        Status   = EFI_SUCCESS;\r
+        *IsFound = TRUE;\r
 \r
         //\r
         // Return the revocation time.\r
@@ -940,12 +938,14 @@ IsCertHashFoundInDatabase (
     DbxList  = (EFI_SIGNATURE_LIST *) ((UINT8 *) DbxList + DbxList->SignatureListSize);\r
   }\r
 \r
+  Status = EFI_SUCCESS;\r
+\r
 Done:\r
   if (HashCtx != NULL) {\r
     FreePool (HashCtx);\r
   }\r
 \r
-  return IsFound;\r
+  return Status;\r
 }\r
 \r
 /**\r
@@ -953,19 +953,21 @@ Done:
 \r
   @param[in]  VariableName        Name of database variable that is searched in.\r
   @param[in]  Signature           Pointer to signature that is searched for.\r
-  @param[in]  CertType            Pointer to hash algrithom.\r
+  @param[in]  CertType            Pointer to hash algorithm.\r
   @param[in]  SignatureSize       Size of Signature.\r
+  @param[out] IsFound             Search result. Only valid if EFI_SUCCESS returned\r
 \r
-  @return TRUE                    Found the signature in the variable database.\r
-  @return FALSE                   Not found the signature in the variable database.\r
+  @retval EFI_SUCCESS             Finished the search without any error.\r
+  @retval Others                  Error occurred in the search of database.\r
 \r
 **/\r
-BOOLEAN\r
+EFI_STATUS\r
 IsSignatureFoundInDatabase (\r
-  IN CHAR16             *VariableName,\r
-  IN UINT8              *Signature,\r
-  IN EFI_GUID           *CertType,\r
-  IN UINTN              SignatureSize\r
+  IN  CHAR16            *VariableName,\r
+  IN  UINT8             *Signature,\r
+  IN  EFI_GUID          *CertType,\r
+  IN  UINTN             SignatureSize,\r
+  OUT BOOLEAN           *IsFound\r
   )\r
 {\r
   EFI_STATUS          Status;\r
@@ -975,22 +977,28 @@ IsSignatureFoundInDatabase (
   UINT8               *Data;\r
   UINTN               Index;\r
   UINTN               CertCount;\r
-  BOOLEAN             IsFound;\r
 \r
   //\r
   // Read signature database variable.\r
   //\r
-  IsFound   = FALSE;\r
+  *IsFound  = FALSE;\r
   Data      = NULL;\r
   DataSize  = 0;\r
   Status    = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);\r
   if (Status != EFI_BUFFER_TOO_SMALL) {\r
-    return FALSE;\r
+    if (Status == EFI_NOT_FOUND) {\r
+      //\r
+      // No database, no need to search.\r
+      //\r
+      Status = EFI_SUCCESS;\r
+    }\r
+\r
+    return Status;\r
   }\r
 \r
   Data = (UINT8 *) AllocateZeroPool (DataSize);\r
   if (Data == NULL) {\r
-    return FALSE;\r
+    return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
   Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, Data);\r
@@ -998,7 +1006,7 @@ IsSignatureFoundInDatabase (
     goto Done;\r
   }\r
   //\r
-  // Enumerate all signature data in SigDB to check if executable's signature exists.\r
+  // Enumerate all signature data in SigDB to check if signature exists for executable.\r
   //\r
   CertList = (EFI_SIGNATURE_LIST *) Data;\r
   while ((DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {\r
@@ -1010,7 +1018,7 @@ IsSignatureFoundInDatabase (
           //\r
           // Find the signature in database.\r
           //\r
-          IsFound = TRUE;\r
+          *IsFound = TRUE;\r
           //\r
           // Entries in UEFI_IMAGE_SECURITY_DATABASE that are used to validate image should be measured\r
           //\r
@@ -1023,7 +1031,7 @@ IsSignatureFoundInDatabase (
         Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);\r
       }\r
 \r
-      if (IsFound) {\r
+      if (*IsFound) {\r
         break;\r
       }\r
     }\r
@@ -1037,7 +1045,7 @@ Done:
     FreePool (Data);\r
   }\r
 \r
-  return IsFound;\r
+  return Status;\r
 }\r
 \r
 /**\r
@@ -1218,6 +1226,7 @@ IsForbiddenByDbx (
 {\r
   EFI_STATUS                Status;\r
   BOOLEAN                   IsForbidden;\r
+  BOOLEAN                   IsFound;\r
   UINT8                     *Data;\r
   UINTN                     DataSize;\r
   EFI_SIGNATURE_LIST        *CertList;\r
@@ -1239,7 +1248,7 @@ IsForbiddenByDbx (
   //\r
   // Variable Initialization\r
   //\r
-  IsForbidden       = FALSE;\r
+  IsForbidden       = TRUE;\r
   Data              = NULL;\r
   CertList          = NULL;\r
   CertData          = NULL;\r
@@ -1256,7 +1265,14 @@ IsForbiddenByDbx (
   //\r
   DataSize = 0;\r
   Status   = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);\r
+  ASSERT (EFI_ERROR (Status));\r
   if (Status != EFI_BUFFER_TOO_SMALL) {\r
+    if (Status == EFI_NOT_FOUND) {\r
+      //\r
+      // Evidently not in dbx if the database doesn't exist.\r
+      //\r
+      IsForbidden = FALSE;\r
+    }\r
     return IsForbidden;\r
   }\r
   Data = (UINT8 *) AllocateZeroPool (DataSize);\r
@@ -1266,7 +1282,7 @@ IsForbiddenByDbx (
 \r
   Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, (VOID *) Data);\r
   if (EFI_ERROR (Status)) {\r
-    return IsForbidden;\r
+    goto Done;\r
   }\r
 \r
   //\r
@@ -1328,7 +1344,7 @@ IsForbiddenByDbx (
   //       UINT8  Certn[];\r
   //\r
   Pkcs7GetSigners (AuthData, AuthDataSize, &CertBuffer, &BufferLength, &TrustedCert, &TrustedCertLength);\r
-  if ((BufferLength == 0) || (CertBuffer == NULL)) {\r
+  if ((BufferLength == 0) || (CertBuffer == NULL) || (*CertBuffer) == 0) {\r
     IsForbidden = TRUE;\r
     goto Done;\r
   }\r
@@ -1346,24 +1362,35 @@ IsForbiddenByDbx (
     //\r
     CertPtr = CertPtr + sizeof (UINT32) + CertSize;\r
 \r
-    if (IsCertHashFoundInDatabase (Cert, CertSize, (EFI_SIGNATURE_LIST *)Data, DataSize, &RevocationTime)) {\r
+    Status = IsCertHashFoundInDbx (Cert, CertSize, (EFI_SIGNATURE_LIST *)Data, DataSize, &RevocationTime, &IsFound);\r
+    if (EFI_ERROR (Status)) {\r
       //\r
-      // Check the timestamp signature and signing time to determine if the image can be trusted.\r
+      // Error in searching dbx. Consider it as 'found'. RevocationTime might\r
+      // not be valid in such situation.\r
       //\r
       IsForbidden = TRUE;\r
+    } else if (IsFound) {\r
+      //\r
+      // Found Cert in dbx successfully. Check the timestamp signature and\r
+      // signing time to determine if the image can be trusted.\r
+      //\r
       if (PassTimestampCheck (AuthData, AuthDataSize, &RevocationTime)) {\r
         IsForbidden = FALSE;\r
         //\r
         // Pass DBT check. Continue to check other certs in image signer's cert list against DBX, DBT\r
         //\r
         continue;\r
+      } else {\r
+        IsForbidden = TRUE;\r
+        DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but signature failed the timestamp check.\n"));\r
+        goto Done;\r
       }\r
-      DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but signature failed the timestamp check.\n"));\r
-      goto Done;\r
     }\r
 \r
   }\r
 \r
+  IsForbidden = FALSE;\r
+\r
 Done:\r
   if (Data != NULL) {\r
     FreePool (Data);\r
@@ -1394,6 +1421,7 @@ IsAllowedByDb (
 {\r
   EFI_STATUS                Status;\r
   BOOLEAN                   VerifyStatus;\r
+  BOOLEAN                   IsFound;\r
   EFI_SIGNATURE_LIST        *CertList;\r
   EFI_SIGNATURE_DATA        *CertData;\r
   UINTN                     DataSize;\r
@@ -1414,65 +1442,100 @@ IsAllowedByDb (
   RootCertSize      = 0;\r
   VerifyStatus      = FALSE;\r
 \r
+  //\r
+  // Fetch 'db' content. If 'db' doesn't exist or encounters problem to get the\r
+  // data, return not-allowed-by-db (FALSE).\r
+  //\r
   DataSize = 0;\r
   Status   = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);\r
-  if (Status == EFI_BUFFER_TOO_SMALL) {\r
-    Data = (UINT8 *) AllocateZeroPool (DataSize);\r
-    if (Data == NULL) {\r
-      return VerifyStatus;\r
+  ASSERT (EFI_ERROR (Status));\r
+  if (Status != EFI_BUFFER_TOO_SMALL) {\r
+    return VerifyStatus;\r
+  }\r
+\r
+  Data = (UINT8 *) AllocateZeroPool (DataSize);\r
+  if (Data == NULL) {\r
+    return VerifyStatus;\r
+  }\r
+\r
+  Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, (VOID *) Data);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Fetch 'dbx' content. If 'dbx' doesn't exist, continue to check 'db'.\r
+  // If any other errors occured, no need to check 'db' but just return\r
+  // not-allowed-by-db (FALSE) to avoid bypass.\r
+  //\r
+  DbxDataSize = 0;\r
+  Status      = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DbxDataSize, NULL);\r
+  ASSERT (EFI_ERROR (Status));\r
+  if (Status != EFI_BUFFER_TOO_SMALL) {\r
+    if (Status != EFI_NOT_FOUND) {\r
+      goto Done;\r
+    }\r
+    //\r
+    // 'dbx' does not exist. Continue to check 'db'.\r
+    //\r
+  } else {\r
+    //\r
+    // 'dbx' exists. Get its content.\r
+    //\r
+    DbxData = (UINT8 *) AllocateZeroPool (DbxDataSize);\r
+    if (DbxData == NULL) {\r
+      goto Done;\r
     }\r
 \r
-    Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, (VOID *) Data);\r
+    Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DbxDataSize, (VOID *) DbxData);\r
     if (EFI_ERROR (Status)) {\r
       goto Done;\r
     }\r
+  }\r
 \r
-    //\r
-    // Find X509 certificate in Signature List to verify the signature in pkcs7 signed data.\r
-    //\r
-    CertList = (EFI_SIGNATURE_LIST *) Data;\r
-    while ((DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {\r
-      if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {\r
-        CertData  = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
-        CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
+  //\r
+  // Find X509 certificate in Signature List to verify the signature in pkcs7 signed data.\r
+  //\r
+  CertList = (EFI_SIGNATURE_LIST *) Data;\r
+  while ((DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {\r
+    if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {\r
+      CertData  = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
+      CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
 \r
-        for (Index = 0; Index < CertCount; Index++) {\r
-          //\r
-          // Iterate each Signature Data Node within this CertList for verify.\r
-          //\r
-          RootCert     = CertData->SignatureData;\r
-          RootCertSize = CertList->SignatureSize - sizeof (EFI_GUID);\r
+      for (Index = 0; Index < CertCount; Index++) {\r
+        //\r
+        // Iterate each Signature Data Node within this CertList for verify.\r
+        //\r
+        RootCert     = CertData->SignatureData;\r
+        RootCertSize = CertList->SignatureSize - sizeof (EFI_GUID);\r
 \r
+        //\r
+        // Call AuthenticodeVerify library to Verify Authenticode struct.\r
+        //\r
+        VerifyStatus = AuthenticodeVerify (\r
+                         AuthData,\r
+                         AuthDataSize,\r
+                         RootCert,\r
+                         RootCertSize,\r
+                         mImageDigest,\r
+                         mImageDigestSize\r
+                         );\r
+        if (VerifyStatus) {\r
           //\r
-          // Call AuthenticodeVerify library to Verify Authenticode struct.\r
+          // The image is signed and its signature is found in 'db'.\r
           //\r
-          VerifyStatus = AuthenticodeVerify (\r
-                           AuthData,\r
-                           AuthDataSize,\r
-                           RootCert,\r
-                           RootCertSize,\r
-                           mImageDigest,\r
-                           mImageDigestSize\r
-                           );\r
-          if (VerifyStatus) {\r
+          if (DbxData != NULL) {\r
             //\r
             // Here We still need to check if this RootCert's Hash is revoked\r
             //\r
-            Status   = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DbxDataSize, NULL);\r
-            if (Status == EFI_BUFFER_TOO_SMALL) {\r
-              goto Done;\r
-            }\r
-            DbxData = (UINT8 *) AllocateZeroPool (DbxDataSize);\r
-            if (DbxData == NULL) {\r
-              goto Done;\r
-            }\r
-\r
-            Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DbxDataSize, (VOID *) DbxData);\r
+            Status = IsCertHashFoundInDbx (RootCert, RootCertSize, (EFI_SIGNATURE_LIST *)DbxData, DbxDataSize, &RevocationTime, &IsFound);\r
             if (EFI_ERROR (Status)) {\r
-              goto Done;\r
-            }\r
-\r
-            if (IsCertHashFoundInDatabase (RootCert, RootCertSize, (EFI_SIGNATURE_LIST *)DbxData, DbxDataSize, &RevocationTime)) {\r
+              //\r
+              // Error in searching dbx. Consider it as 'found'. RevocationTime might\r
+              // not be valid in such situation.\r
+              //\r
+              VerifyStatus = FALSE;\r
+            } else if (IsFound) {\r
               //\r
               // Check the timestamp signature and signing time to determine if the RootCert can be trusted.\r
               //\r
@@ -1481,17 +1544,23 @@ IsAllowedByDb (
                 DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed and signature is accepted by DB, but its root cert failed the timestamp check.\n"));\r
               }\r
             }\r
-\r
-            goto Done;\r
           }\r
 \r
-          CertData = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertData + CertList->SignatureSize);\r
+          //\r
+          // There's no 'dbx' to check revocation time against (must-be pass),\r
+          // or, there's revocation time found in 'dbx' and checked againt 'dbt'\r
+          // (maybe pass or fail, depending on timestamp compare result). Either\r
+          // way the verification job has been completed at this point.\r
+          //\r
+          goto Done;\r
         }\r
-      }\r
 \r
-      DataSize -= CertList->SignatureListSize;\r
-      CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
+        CertData = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertData + CertList->SignatureSize);\r
+      }\r
     }\r
+\r
+    DataSize -= CertList->SignatureListSize;\r
+    CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
   }\r
 \r
 Done:\r
@@ -1547,14 +1616,14 @@ Done:
                                  and non-NULL FileBuffer did authenticate, and the platform\r
                                  policy dictates that the DXE Foundation may execute the image in\r
                                  FileBuffer.\r
-  @retval EFI_OUT_RESOURCE       Fail to allocate memory.\r
   @retval EFI_SECURITY_VIOLATION The file specified by File did not authenticate, and\r
                                  the platform policy dictates that File should be placed\r
                                  in the untrusted state. The image has been added to the file\r
                                  execution table.\r
   @retval EFI_ACCESS_DENIED      The file specified by File and FileBuffer did not\r
                                  authenticate, and the platform policy dictates that the DXE\r
-                                 Foundation many not use File.\r
+                                 Foundation may not use File. The image has\r
+                                 been added to the file execution table.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1567,9 +1636,8 @@ DxeImageVerificationHandler (
   IN  BOOLEAN                          BootPolicy\r
   )\r
 {\r
-  EFI_STATUS                           Status;\r
   EFI_IMAGE_DOS_HEADER                 *DosHdr;\r
-  EFI_STATUS                           VerifyStatus;\r
+  BOOLEAN                              IsVerified;\r
   EFI_SIGNATURE_LIST                   *SignatureList;\r
   UINTN                                SignatureListSize;\r
   EFI_SIGNATURE_DATA                   *Signature;\r
@@ -1586,6 +1654,10 @@ DxeImageVerificationHandler (
   EFI_IMAGE_DATA_DIRECTORY             *SecDataDir;\r
   UINT32                               OffSet;\r
   CHAR16                               *NameStr;\r
+  RETURN_STATUS                        PeCoffStatus;\r
+  EFI_STATUS                           HashStatus;\r
+  EFI_STATUS                           DbStatus;\r
+  BOOLEAN                              IsFound;\r
 \r
   SignatureList     = NULL;\r
   SignatureListSize = 0;\r
@@ -1593,9 +1665,8 @@ DxeImageVerificationHandler (
   SecDataDir        = NULL;\r
   PkcsCertData      = NULL;\r
   Action            = EFI_IMAGE_EXECUTION_AUTH_UNTESTED;\r
-  Status            = EFI_ACCESS_DENIED;\r
-  VerifyStatus      = EFI_ACCESS_DENIED;\r
-\r
+  IsVerified        = FALSE;\r
+  IsFound           = FALSE;\r
 \r
   //\r
   // Check the image type and get policy setting.\r
@@ -1627,7 +1698,8 @@ DxeImageVerificationHandler (
   //\r
   if (Policy == ALWAYS_EXECUTE) {\r
     return EFI_SUCCESS;\r
-  } else if (Policy == NEVER_EXECUTE) {\r
+  }\r
+  if (Policy == NEVER_EXECUTE) {\r
     return EFI_ACCESS_DENIED;\r
   }\r
 \r
@@ -1661,7 +1733,7 @@ DxeImageVerificationHandler (
   // Read the Dos header.\r
   //\r
   if (FileBuffer == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
+    return EFI_ACCESS_DENIED;\r
   }\r
 \r
   mImageBase  = (UINT8 *) FileBuffer;\r
@@ -1674,17 +1746,15 @@ DxeImageVerificationHandler (
   //\r
   // Get information about the image being loaded\r
   //\r
-  Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
-  if (EFI_ERROR (Status)) {\r
+  PeCoffStatus = PeCoffLoaderGetImageInfo (&ImageContext);\r
+  if (RETURN_ERROR (PeCoffStatus)) {\r
     //\r
     // The information can't be got from the invalid PeImage\r
     //\r
     DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: PeImage invalid. Cannot retrieve image information.\n"));\r
-    goto Done;\r
+    goto Failed;\r
   }\r
 \r
-  Status = EFI_ACCESS_DENIED;\r
-\r
   DosHdr = (EFI_IMAGE_DOS_HEADER *) mImageBase;\r
   if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
     //\r
@@ -1704,7 +1774,7 @@ DxeImageVerificationHandler (
     // It is not a valid Pe/Coff file.\r
     //\r
     DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Not a valid PE/COFF image.\n"));\r
-    goto Done;\r
+    goto Failed;\r
   }\r
 \r
   if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
@@ -1735,18 +1805,32 @@ DxeImageVerificationHandler (
     //\r
     if (!HashPeImage (HASHALG_SHA256)) {\r
       DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Failed to hash this image using %s.\n", mHashTypeStr));\r
-      goto Done;\r
+      goto Failed;\r
     }\r
 \r
-    if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE1, mImageDigest, &mCertType, mImageDigestSize)) {\r
+    DbStatus = IsSignatureFoundInDatabase (\r
+                 EFI_IMAGE_SECURITY_DATABASE1,\r
+                 mImageDigest,\r
+                 &mCertType,\r
+                 mImageDigestSize,\r
+                 &IsFound\r
+                 );\r
+    if (EFI_ERROR (DbStatus) || IsFound) {\r
       //\r
       // Image Hash is in forbidden database (DBX).\r
       //\r
       DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed and %s hash of image is forbidden by DBX.\n", mHashTypeStr));\r
-      goto Done;\r
+      goto Failed;\r
     }\r
 \r
-    if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE, mImageDigest, &mCertType, mImageDigestSize)) {\r
+    DbStatus = IsSignatureFoundInDatabase (\r
+                 EFI_IMAGE_SECURITY_DATABASE,\r
+                 mImageDigest,\r
+                 &mCertType,\r
+                 mImageDigestSize,\r
+                 &IsFound\r
+                 );\r
+    if (!EFI_ERROR (DbStatus) && IsFound) {\r
       //\r
       // Image Hash is in allowed database (DB).\r
       //\r
@@ -1757,7 +1841,7 @@ DxeImageVerificationHandler (
     // Image Hash is not found in both forbidden and allowed database.\r
     //\r
     DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed and %s hash of image is not found in DB/DBX.\n", mHashTypeStr));\r
-    goto Done;\r
+    goto Failed;\r
   }\r
 \r
   //\r
@@ -1808,8 +1892,8 @@ DxeImageVerificationHandler (
       continue;\r
     }\r
 \r
-    Status = HashPeImageByType (AuthData, AuthDataSize);\r
-    if (EFI_ERROR (Status)) {\r
+    HashStatus = HashPeImageByType (AuthData, AuthDataSize);\r
+    if (EFI_ERROR (HashStatus)) {\r
       continue;\r
     }\r
 \r
@@ -1818,30 +1902,46 @@ DxeImageVerificationHandler (
     //\r
     if (IsForbiddenByDbx (AuthData, AuthDataSize)) {\r
       Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED;\r
-      VerifyStatus = EFI_ACCESS_DENIED;\r
+      IsVerified = FALSE;\r
       break;\r
     }\r
 \r
     //\r
     // Check the digital signature against the valid certificate in allowed database (db).\r
     //\r
-    if (EFI_ERROR (VerifyStatus)) {\r
+    if (!IsVerified) {\r
       if (IsAllowedByDb (AuthData, AuthDataSize)) {\r
-        VerifyStatus = EFI_SUCCESS;\r
+        IsVerified = TRUE;\r
       }\r
     }\r
 \r
     //\r
     // Check the image's hash value.\r
     //\r
-    if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE1, mImageDigest, &mCertType, mImageDigestSize)) {\r
+    DbStatus = IsSignatureFoundInDatabase (\r
+                 EFI_IMAGE_SECURITY_DATABASE1,\r
+                 mImageDigest,\r
+                 &mCertType,\r
+                 mImageDigestSize,\r
+                 &IsFound\r
+                 );\r
+    if (EFI_ERROR (DbStatus) || IsFound) {\r
       Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND;\r
       DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but %s hash of image is found in DBX.\n", mHashTypeStr));\r
-      VerifyStatus = EFI_ACCESS_DENIED;\r
+      IsVerified = FALSE;\r
       break;\r
-    } else if (EFI_ERROR (VerifyStatus)) {\r
-      if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE, mImageDigest, &mCertType, mImageDigestSize)) {\r
-        VerifyStatus = EFI_SUCCESS;\r
+    }\r
+\r
+    if (!IsVerified) {\r
+      DbStatus = IsSignatureFoundInDatabase (\r
+                   EFI_IMAGE_SECURITY_DATABASE,\r
+                   mImageDigest,\r
+                   &mCertType,\r
+                   mImageDigestSize,\r
+                   &IsFound\r
+                   );\r
+      if (!EFI_ERROR (DbStatus) && IsFound) {\r
+        IsVerified = TRUE;\r
       } else {\r
         DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but signature is not allowed by DB and %s hash of image is not found in DB/DBX.\n", mHashTypeStr));\r
       }\r
@@ -1850,53 +1950,52 @@ DxeImageVerificationHandler (
 \r
   if (OffSet != (SecDataDir->VirtualAddress + SecDataDir->Size)) {\r
     //\r
-    // The Size in Certificate Table or the attribute certicate table is corrupted.\r
+    // The Size in Certificate Table or the attribute certificate table is corrupted.\r
     //\r
-    VerifyStatus = EFI_ACCESS_DENIED;\r
+    IsVerified = FALSE;\r
   }\r
 \r
-  if (!EFI_ERROR (VerifyStatus)) {\r
+  if (IsVerified) {\r
     return EFI_SUCCESS;\r
-  } else {\r
-    Status = EFI_ACCESS_DENIED;\r
-    if (Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED || Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND) {\r
-      //\r
-      // Get image hash value as executable's signature.\r
-      //\r
-      SignatureListSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + mImageDigestSize;\r
-      SignatureList     = (EFI_SIGNATURE_LIST *) AllocateZeroPool (SignatureListSize);\r
-      if (SignatureList == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        goto Done;\r
-      }\r
-      SignatureList->SignatureHeaderSize  = 0;\r
-      SignatureList->SignatureListSize    = (UINT32) SignatureListSize;\r
-      SignatureList->SignatureSize        = (UINT32) (sizeof (EFI_SIGNATURE_DATA) - 1 + mImageDigestSize);\r
-      CopyMem (&SignatureList->SignatureType, &mCertType, sizeof (EFI_GUID));\r
-      Signature = (EFI_SIGNATURE_DATA *) ((UINT8 *) SignatureList + sizeof (EFI_SIGNATURE_LIST));\r
-      CopyMem (Signature->SignatureData, mImageDigest, mImageDigestSize);\r
-    }\r
   }\r
-\r
-Done:\r
-  if (Status != EFI_SUCCESS) {\r
+  if (Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED || Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND) {\r
     //\r
-    // Policy decides to defer or reject the image; add its information in image executable information table.\r
+    // Get image hash value as signature of executable.\r
     //\r
-    NameStr = ConvertDevicePathToText (File, FALSE, TRUE);\r
-    AddImageExeInfo (Action, NameStr, File, SignatureList, SignatureListSize);\r
-    if (NameStr != NULL) {\r
-      DEBUG((EFI_D_INFO, "The image doesn't pass verification: %s\n", NameStr));\r
-      FreePool(NameStr);\r
+    SignatureListSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + mImageDigestSize;\r
+    SignatureList     = (EFI_SIGNATURE_LIST *) AllocateZeroPool (SignatureListSize);\r
+    if (SignatureList == NULL) {\r
+      SignatureListSize = 0;\r
+      goto Failed;\r
     }\r
-    Status = EFI_SECURITY_VIOLATION;\r
+    SignatureList->SignatureHeaderSize  = 0;\r
+    SignatureList->SignatureListSize    = (UINT32) SignatureListSize;\r
+    SignatureList->SignatureSize        = (UINT32) (sizeof (EFI_SIGNATURE_DATA) - 1 + mImageDigestSize);\r
+    CopyMem (&SignatureList->SignatureType, &mCertType, sizeof (EFI_GUID));\r
+    Signature = (EFI_SIGNATURE_DATA *) ((UINT8 *) SignatureList + sizeof (EFI_SIGNATURE_LIST));\r
+    CopyMem (Signature->SignatureData, mImageDigest, mImageDigestSize);\r
+  }\r
+\r
+Failed:\r
+  //\r
+  // Policy decides to defer or reject the image; add its information in image\r
+  // executable information table in either case.\r
+  //\r
+  NameStr = ConvertDevicePathToText (File, FALSE, TRUE);\r
+  AddImageExeInfo (Action, NameStr, File, SignatureList, SignatureListSize);\r
+  if (NameStr != NULL) {\r
+    DEBUG ((DEBUG_INFO, "The image doesn't pass verification: %s\n", NameStr));\r
+    FreePool(NameStr);\r
   }\r
 \r
   if (SignatureList != NULL) {\r
     FreePool (SignatureList);\r
   }\r
 \r
-  return Status;\r
+  if (Policy == DEFER_EXECUTE_ON_SECURITY_VIOLATION) {\r
+    return EFI_SECURITY_VIOLATION;\r
+  }\r
+  return EFI_ACCESS_DENIED;\r
 }\r
 \r
 /**\r