From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga18.intel.com (mga18.intel.com []) by mx.groups.io with SMTP id smtpd.web12.7281.1588080337996700375 for ; Tue, 28 Apr 2020 06:25:48 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: wei6.xu@intel.com) IronPort-SDR: 0ZB6wWq29efEPlnE+nI44KHA6CTldtKoPzqSP9tFLY9taqkt10t/LZpOK/UXI8/PBpg0qFjU2B 3uKkeQ9R1GMg== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Apr 2020 06:25:47 -0700 IronPort-SDR: vw5KxS4h//6E99/yn6HaObhkCgvQTpPl5QyMj/dV+T4rF1ZqkFGv+1KMXorWh1qUJa+4T9PdKs WaK0jhFAOVuQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,327,1583222400"; d="scan'208";a="302706824" Received: from shwdeopenpsi174.ccr.corp.intel.com ([10.239.157.39]) by FMSMGA003.fm.intel.com with ESMTP; 28 Apr 2020 06:25:45 -0700 From: "Xu, Wei6" To: devel@edk2.groups.io Cc: Michael D Kinney , Liming Gao , Sean Brogan Subject: [edk2-devel] [PATCH 4/4] FmpDevicePkg/FmpDxe: Use FmpDependencyLib and FmpDependencyCheckLib Date: Tue, 28 Apr 2020 21:25:30 +0800 Message-Id: <20200428132530.4068-5-wei6.xu@intel.com> X-Mailer: git-send-email 2.16.2.windows.1 In-Reply-To: <20200428132530.4068-1-wei6.xu@intel.com> References: <20200428132530.4068-1-wei6.xu@intel.com> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2696 Remove the orginal Fmp Capsule Dependency implement, and use new FmpDependencyLib and FmpDependencyCheckLib APIs instead. A platform can perform the dependency check in a platform specific manner by implementing its own FmpDependencyCheckLib. Cc: Michael D Kinney Cc: Liming Gao Cc: Sean Brogan Signed-off-by: Wei6 Xu --- FmpDevicePkg/FmpDxe/Dependency.c | 679 -------------------------------------- FmpDevicePkg/FmpDxe/Dependency.h | 63 ---- FmpDevicePkg/FmpDxe/FmpDxe.c | 255 +++----------- FmpDevicePkg/FmpDxe/FmpDxe.h | 3 + FmpDevicePkg/FmpDxe/FmpDxe.inf | 4 +- FmpDevicePkg/FmpDxe/FmpDxeLib.inf | 4 +- 6 files changed, 60 insertions(+), 948 deletions(-) delete mode 100644 FmpDevicePkg/FmpDxe/Dependency.c delete mode 100644 FmpDevicePkg/FmpDxe/Dependency.h diff --git a/FmpDevicePkg/FmpDxe/Dependency.c b/FmpDevicePkg/FmpDxe/Dependency.c deleted file mode 100644 index 8f97c42916..0000000000 --- a/FmpDevicePkg/FmpDxe/Dependency.c +++ /dev/null @@ -1,679 +0,0 @@ -/** @file - Supports Capsule Dependency Expression. - - Copyright (c) 2020, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ -#include "FmpDxe.h" -#include "Dependency.h" - -// -// Define the initial size of the dependency expression evaluation stack -// -#define DEPEX_STACK_SIZE_INCREMENT 0x1000 - -// -// Type of stack element -// -typedef enum { - BooleanType, - VersionType -} ELEMENT_TYPE; - -// -// Value of stack element -// -typedef union { - BOOLEAN Boolean; - UINT32 Version; -} ELEMENT_VALUE; - -// -// Stack element used to evaluate dependency expressions -// -typedef struct { - ELEMENT_VALUE Value; - ELEMENT_TYPE Type; -} DEPEX_ELEMENT; - -// -// Global variable used to support dependency evaluation -// -UINTN mNumberOfFmpInstance = 0; -EFI_FIRMWARE_IMAGE_DESCRIPTOR **mFmpImageInfoBuf = NULL; - -// -// Indicates the status of dependency check, default value is DEPENDENCIES_SATISFIED. -// -UINT8 mDependenciesCheckStatus = DEPENDENCIES_SATISFIED; - -// -// Global stack used to evaluate dependency expressions -// -DEPEX_ELEMENT *mDepexEvaluationStack = NULL; -DEPEX_ELEMENT *mDepexEvaluationStackEnd = NULL; -DEPEX_ELEMENT *mDepexEvaluationStackPointer = NULL; - -/** - Grow size of the Depex stack - - @retval EFI_SUCCESS Stack successfully growed. - @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack. - -**/ -EFI_STATUS -GrowDepexStack ( - VOID - ) -{ - DEPEX_ELEMENT *NewStack; - UINTN Size; - - Size = DEPEX_STACK_SIZE_INCREMENT; - if (mDepexEvaluationStack != NULL) { - Size = Size + (mDepexEvaluationStackEnd - mDepexEvaluationStack); - } - - NewStack = AllocatePool (Size * sizeof (DEPEX_ELEMENT)); - if (NewStack == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - if (mDepexEvaluationStack != NULL) { - // - // Copy to Old Stack to the New Stack - // - CopyMem ( - NewStack, - mDepexEvaluationStack, - (mDepexEvaluationStackEnd - mDepexEvaluationStack) * sizeof (DEPEX_ELEMENT) - ); - - // - // Free The Old Stack - // - FreePool (mDepexEvaluationStack); - } - - // - // Make the Stack pointer point to the old data in the new stack - // - mDepexEvaluationStackPointer = NewStack + (mDepexEvaluationStackPointer - mDepexEvaluationStack); - mDepexEvaluationStack = NewStack; - mDepexEvaluationStackEnd = NewStack + Size; - - return EFI_SUCCESS; -} - -/** - Push an element onto the Stack. - - @param[in] Value Value to push. - @param[in] Type Element Type - - @retval EFI_SUCCESS The value was pushed onto the stack. - @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack. - @retval EFI_INVALID_PARAMETER Wrong stack element type. - -**/ -EFI_STATUS -Push ( - IN UINT32 Value, - IN UINTN Type - ) -{ - EFI_STATUS Status; - DEPEX_ELEMENT Element; - - // - // Check Type - // - if (Type != BooleanType && Type != VersionType) { - return EFI_INVALID_PARAMETER; - } - - // - // Check for a stack overflow condition - // - if (mDepexEvaluationStackPointer == mDepexEvaluationStackEnd) { - // - // Grow the stack - // - Status = GrowDepexStack (); - if (EFI_ERROR (Status)) { - return Status; - } - } - - Element.Value.Version = Value; - Element.Type = Type; - - // - // Push the item onto the stack - // - *mDepexEvaluationStackPointer = Element; - mDepexEvaluationStackPointer++; - - return EFI_SUCCESS; -} - - -/** - Pop an element from the stack. - - @param[out] Element Element to pop. - @param[in] Type Type of element. - - @retval EFI_SUCCESS The value was popped onto the stack. - @retval EFI_ACCESS_DENIED The pop operation underflowed the stack. - @retval EFI_INVALID_PARAMETER Type is mismatched. - -**/ -EFI_STATUS -Pop ( - OUT DEPEX_ELEMENT *Element, - IN ELEMENT_TYPE Type - ) -{ - // - // Check for a stack underflow condition - // - if (mDepexEvaluationStackPointer == mDepexEvaluationStack) { - return EFI_ACCESS_DENIED; - } - - // - // Pop the item off the stack - // - mDepexEvaluationStackPointer--; - *Element = *mDepexEvaluationStackPointer; - if ((*Element).Type != Type) { - return EFI_INVALID_PARAMETER; - } - return EFI_SUCCESS; -} - -/** - Evaluate the dependencies. - - @param[in] Dependencies Dependency expressions. - @param[in] DependenciesSize Size of Dependency expressions. - - @retval TRUE Dependency expressions evaluate to TRUE. - @retval FALSE Dependency expressions evaluate to FALSE. - -**/ -BOOLEAN -EvaluateDependencies ( - IN CONST EFI_FIRMWARE_IMAGE_DEP * Dependencies, - IN CONST UINTN DependenciesSize - ) -{ - EFI_STATUS Status; - UINT8 *Iterator; - UINT8 Index; - DEPEX_ELEMENT Element1; - DEPEX_ELEMENT Element2; - GUID ImageTypeId; - UINT32 Version; - - if (Dependencies == NULL || DependenciesSize == 0) { - return FALSE; - } - - // - // Clean out memory leaks in Depex Boolean stack. Leaks are only caused by - // incorrectly formed DEPEX expressions - // - mDepexEvaluationStackPointer = mDepexEvaluationStack; - - Iterator = (UINT8 *) Dependencies->Dependencies; - while (Iterator < (UINT8 *) Dependencies->Dependencies + DependenciesSize) { - switch (*Iterator) - { - case EFI_FMP_DEP_PUSH_GUID: - if (Iterator + sizeof (EFI_GUID) >= (UINT8 *) Dependencies->Dependencies + DependenciesSize) { - Status = EFI_INVALID_PARAMETER; - goto Error; - } - - CopyGuid (&ImageTypeId, (EFI_GUID *) (Iterator + 1)); - Iterator = Iterator + sizeof (EFI_GUID); - - for (Index = 0; Index < mNumberOfFmpInstance; Index ++){ - if (mFmpImageInfoBuf[Index] == NULL) { - continue; - } - if(CompareGuid (&mFmpImageInfoBuf[Index]->ImageTypeId, &ImageTypeId)){ - Status = Push (mFmpImageInfoBuf[Index]->Version, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - } - } - if (Index == mNumberOfFmpInstance) { - Status = EFI_NOT_FOUND; - goto Error; - } - break; - case EFI_FMP_DEP_PUSH_VERSION: - if (Iterator + sizeof (UINT32) >= (UINT8 *) Dependencies->Dependencies + DependenciesSize ) { - Status = EFI_INVALID_PARAMETER; - goto Error; - } - - Version = *(UINT32 *) (Iterator + 1); - Status = Push (Version, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Iterator = Iterator + sizeof (UINT32); - break; - case EFI_FMP_DEP_VERSION_STR: - Iterator += AsciiStrnLenS ((CHAR8 *) Iterator, DependenciesSize - (Iterator - Dependencies->Dependencies)); - break; - case EFI_FMP_DEP_AND: - Status = Pop (&Element1, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status = Pop (&Element2, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status = Push (Element1.Value.Boolean & Element2.Value.Boolean, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_OR: - Status = Pop (&Element1, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status = Pop(&Element2, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status = Push (Element1.Value.Boolean | Element2.Value.Boolean, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_NOT: - Status = Pop (&Element1, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status = Push (!(Element1.Value.Boolean), BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_TRUE: - Status = Push (TRUE, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_FALSE: - Status = Push (FALSE, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_EQ: - Status = Pop (&Element1, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status = Pop (&Element2, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status = (Element1.Value.Version == Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_GT: - Status = Pop (&Element1, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status = Pop (&Element2, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status = (Element1.Value.Version > Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_GTE: - Status = Pop (&Element1, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status = Pop (&Element2, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status = (Element1.Value.Version >= Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_LT: - Status = Pop (&Element1, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status = Pop (&Element2, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status = (Element1.Value.Version < Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_LTE: - Status = Pop (&Element1, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status = Pop (&Element2, VersionType); - if (EFI_ERROR (Status)) { - goto Error; - } - Status = (Element1.Value.Version <= Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - break; - case EFI_FMP_DEP_END: - Status = Pop (&Element1, BooleanType); - if (EFI_ERROR (Status)) { - goto Error; - } - return Element1.Value.Boolean; - default: - Status = EFI_INVALID_PARAMETER; - goto Error; - } - Iterator++; - } - -Error: - - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): EvaluateDependencies() - RESULT = FALSE (Status = %r)\n", mImageIdName, Status)); - return FALSE; -} - -/** - Validate the dependency expression and output its size. - - @param[in] ImageDepex Pointer to the EFI_FIRMWARE_IMAGE_DEP. - @param[in] MaxDepexSize Max size of the dependency. - @param[out] DepexSize Size of dependency. - - @retval TRUE The capsule is valid. - @retval FALSE The capsule is invalid. - -**/ -BOOLEAN -ValidateImageDepex ( - IN EFI_FIRMWARE_IMAGE_DEP *ImageDepex, - IN CONST UINTN MaxDepexSize, - OUT UINT32 *DepexSize - ) -{ - UINT8 *Depex; - - *DepexSize = 0; - Depex = ImageDepex->Dependencies; - while (Depex < ImageDepex->Dependencies + MaxDepexSize) { - switch (*Depex) - { - case EFI_FMP_DEP_PUSH_GUID: - Depex += sizeof (EFI_GUID) + 1; - break; - case EFI_FMP_DEP_PUSH_VERSION: - Depex += sizeof (UINT32) + 1; - break; - case EFI_FMP_DEP_VERSION_STR: - Depex += AsciiStrnLenS ((CHAR8 *) Depex, ImageDepex->Dependencies + MaxDepexSize - Depex) + 1; - break; - case EFI_FMP_DEP_AND: - case EFI_FMP_DEP_OR: - case EFI_FMP_DEP_NOT: - case EFI_FMP_DEP_TRUE: - case EFI_FMP_DEP_FALSE: - case EFI_FMP_DEP_EQ: - case EFI_FMP_DEP_GT: - case EFI_FMP_DEP_GTE: - case EFI_FMP_DEP_LT: - case EFI_FMP_DEP_LTE: - Depex += 1; - break; - case EFI_FMP_DEP_END: - Depex += 1; - *DepexSize = (UINT32)(Depex - ImageDepex->Dependencies); - return TRUE; - default: - return FALSE; - } - } - - return FALSE; -} - - -/** - Get the size of dependencies. Assume the dependencies is validated before - calling this function. - - @param[in] Dependencies Pointer to the EFI_FIRMWARE_IMAGE_DEP. - - @retval The size of dependencies. - -**/ -UINTN -GetDepexSize ( - IN CONST EFI_FIRMWARE_IMAGE_DEP *Dependencies - ) -{ - UINTN Index; - - if (Dependencies == NULL) { - return 0; - } - - Index = 0; - while (Dependencies->Dependencies[Index] != EFI_FMP_DEP_END) { - Index ++; - } - - return Index + 1; -} - -/** - Check dependency for firmware update. - - @param[in] ImageTypeId Image Type Id. - @param[in] Version New version. - @param[in] Dependencies The dependencies. - @param[in] DependenciesSize Size of the dependencies - @param[out] IsSatisfied Indicate the dependencies is satisfied or not. - - @retval EFI_SUCCESS Dependency Evaluation is successful. - @retval Others Dependency Evaluation fails with unexpected error. - -**/ -EFI_STATUS -EvaluateImageDependencies ( - IN CONST EFI_GUID ImageTypeId, - IN CONST UINT32 Version, - IN CONST EFI_FIRMWARE_IMAGE_DEP *Dependencies, - IN CONST UINT32 DependenciesSize, - OUT BOOLEAN *IsSatisfied - ) -{ - EFI_STATUS Status; - EFI_HANDLE *HandleBuffer; - UINTN Index; - EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp; - UINTN ImageInfoSize; - UINT32 FmpImageInfoDescriptorVer; - UINT8 FmpImageInfoCount; - UINTN DescriptorSize; - UINT32 PackageVersion; - CHAR16 *PackageVersionName; - UINTN DepexSize; - - *IsSatisfied = TRUE; - PackageVersionName = NULL; - - // - // Get ImageDescriptors of all FMP instances, and archive them for depex evaluation. - // - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiFirmwareManagementProtocolGuid, - NULL, - &mNumberOfFmpInstance, - &HandleBuffer - ); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - - mFmpImageInfoBuf = AllocatePool (sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR *) * mNumberOfFmpInstance); - if (mFmpImageInfoBuf == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - for (Index = 0; Index < mNumberOfFmpInstance; Index ++) { - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiFirmwareManagementProtocolGuid, - (VOID **) &Fmp - ); - if (EFI_ERROR(Status)) { - continue; - } - - ImageInfoSize = 0; - Status = Fmp->GetImageInfo ( - Fmp, - &ImageInfoSize, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL - ); - if (Status != EFI_BUFFER_TOO_SMALL) { - continue; - } - - mFmpImageInfoBuf[Index] = AllocateZeroPool (ImageInfoSize); - if (mFmpImageInfoBuf[Index] == NULL) { - continue; - } - - Status = Fmp->GetImageInfo ( - Fmp, - &ImageInfoSize, // ImageInfoSize - mFmpImageInfoBuf[Index], // ImageInfo - &FmpImageInfoDescriptorVer, // DescriptorVersion - &FmpImageInfoCount, // DescriptorCount - &DescriptorSize, // DescriptorSize - &PackageVersion, // PackageVersion - &PackageVersionName // PackageVersionName - ); - if (EFI_ERROR(Status)) { - FreePool (mFmpImageInfoBuf[Index]); - mFmpImageInfoBuf[Index] = NULL; - continue; - } - - if (PackageVersionName != NULL) { - FreePool (PackageVersionName); - PackageVersionName = NULL; - } - } - - // - // Step 1 - Evaluate firmware image's depex, against the version of other Fmp instances. - // - if (Dependencies != NULL) { - *IsSatisfied = EvaluateDependencies (Dependencies, DependenciesSize); - } - - if (!*IsSatisfied) { - goto cleanup; - } - - // - // Step 2 - Evaluate the depex of all other Fmp instances, against the new version in - // the firmware image. - // - - // - // Update the new version to mFmpImageInfoBuf. - // - for (Index = 0; Index < mNumberOfFmpInstance; Index ++) { - if (mFmpImageInfoBuf[Index] != NULL) { - if (CompareGuid (&ImageTypeId, &mFmpImageInfoBuf[Index]->ImageTypeId)) { - mFmpImageInfoBuf[Index]->Version = Version; - break; - } - } - } - - // - // Evaluate the Dependencies one by one. - // - for (Index = 0; Index < mNumberOfFmpInstance; Index ++) { - if (mFmpImageInfoBuf[Index] != NULL) { - // - // Skip the Fmp instance to be "SetImage". - // - if (CompareGuid (&ImageTypeId, &mFmpImageInfoBuf[Index]->ImageTypeId)) { - continue; - } - if ((mFmpImageInfoBuf[Index]->AttributesSupported & IMAGE_ATTRIBUTE_DEPENDENCY) && - mFmpImageInfoBuf[Index]->Dependencies != NULL) { - // - // Get the size of depex. - // Assume that the dependencies in EFI_FIRMWARE_IMAGE_DESCRIPTOR is validated when PopulateDescriptor(). - // - DepexSize = GetDepexSize (mFmpImageInfoBuf[Index]->Dependencies); - if (DepexSize > 0) { - *IsSatisfied = EvaluateDependencies (mFmpImageInfoBuf[Index]->Dependencies, DepexSize); - if (!*IsSatisfied) { - break; - } - } - } - } - } - -cleanup: - if (mFmpImageInfoBuf != NULL) { - for (Index = 0; Index < mNumberOfFmpInstance; Index ++) { - if (mFmpImageInfoBuf[Index] != NULL) { - FreePool (mFmpImageInfoBuf[Index]); - } - } - FreePool (mFmpImageInfoBuf); - } - - return EFI_SUCCESS; -} diff --git a/FmpDevicePkg/FmpDxe/Dependency.h b/FmpDevicePkg/FmpDxe/Dependency.h deleted file mode 100644 index badd2542d6..0000000000 --- a/FmpDevicePkg/FmpDxe/Dependency.h +++ /dev/null @@ -1,63 +0,0 @@ -/** @file - Fmp Capsule Dependency support functions for Firmware Management Protocol based - firmware updates. - - Copyright (c) 2020, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __DEPENDENCY_H__ -#define __DEPENDENCY_H__ - -#include -#include - -#define DEPENDENCIES_SATISFIED 0 -#define DEPENDENCIES_UNSATISFIED 1 -#define DEPENDENCIES_INVALID 2 - -extern UINT8 mDependenciesCheckStatus; - -/** - Validate the dependency expression and output its size. - - @param[in] ImageDepex Pointer to the EFI_FIRMWARE_IMAGE_DEP. - @param[in] MaxDepexSize Max size of the dependency. - @param[out] DepexSize Size of dependency. - - @retval TRUE The capsule is valid. - @retval FALSE The capsule is invalid. - -**/ -BOOLEAN -ValidateImageDepex ( - IN EFI_FIRMWARE_IMAGE_DEP *ImageDepex, - IN CONST UINTN MaxDepexSize, - OUT UINT32 *DepexSize - ); - -/** - Check dependency for firmware update. - - @param[in] ImageTypeId Image Type Id. - @param[in] Version New version. - @param[in] Dependencies The dependencies. - @param[in] DepexSize Size of the dependencies - @param[out] IsSatisfied Indicate the dependencies is satisfied or not. - - @retval EFI_SUCCESS Dependency Evaluation is successful. - @retval Others Dependency Evaluation fails with unexpected error. - -**/ -EFI_STATUS -EvaluateImageDependencies ( - IN CONST EFI_GUID ImageTypeId, - IN CONST UINT32 Version, - IN CONST EFI_FIRMWARE_IMAGE_DEP *Dependencies, - IN CONST UINT32 DepexSize, - OUT BOOLEAN *IsSatisfied - ); - -#endif diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.c b/FmpDevicePkg/FmpDxe/FmpDxe.c index 5b523291e4..d4ba53655d 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxe.c +++ b/FmpDevicePkg/FmpDxe/FmpDxe.c @@ -10,11 +10,10 @@ **/ #include "FmpDxe.h" #include "VariableSupport.h" -#include "Dependency.h" /// /// FILE_GUID from FmpDxe.inf. When FmpDxe.inf is used in a platform, the /// FILE_GUID must always be overridden in the section to provide /// the ESRT GUID value associated with the updatable firmware image. A @@ -79,11 +78,12 @@ const FIRMWARE_MANAGEMENT_PRIVATE_DATA mFirmwareManagementPrivateDataTemplate = NULL, // FmpDeviceContext NULL, // VersionVariableName NULL, // LsvVariableName NULL, // LastAttemptStatusVariableName NULL, // LastAttemptVersionVariableName - NULL // FmpStateVariableName + NULL, // FmpStateVariableName + TRUE // DependenciesSatisfied }; /// /// GUID that is used to create event used to lock the firmware storage device. /// @@ -274,17 +274,10 @@ VOID PopulateDescriptor ( FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private ) { EFI_STATUS Status; - VOID *Image; - UINTN ImageSize; - BOOLEAN IsDepexValid; - UINT32 DepexSize; - - Image = NULL; - ImageSize = 0; if (Private->DescriptorPopulated) { return; } @@ -385,50 +378,22 @@ PopulateDescriptor ( Private->Descriptor.LastAttemptVersion = GetLastAttemptVersionFromVariable (Private); Private->Descriptor.LastAttemptStatus = GetLastAttemptStatusFromVariable (Private); // - // Get the dependency from the FmpDeviceLib and populate it to the descriptor. + // Get the dependency from the FmpDependencyCheckLib. // Private->Descriptor.Dependencies = NULL; // // Check the attribute IMAGE_ATTRIBUTE_DEPENDENCY // - if (Private->Descriptor.AttributesSupported & IMAGE_ATTRIBUTE_DEPENDENCY) { - // - // The parameter "Image" of FmpDeviceGetImage() is extended to contain the dependency. - // Get the dependency from the Image. - // - ImageSize = Private->Descriptor.Size; - Image = AllocatePool (ImageSize); - if (Image != NULL) { - Status = FmpDeviceGetImage (Image, &ImageSize); - if (Status == EFI_BUFFER_TOO_SMALL) { - FreePool (Image); - Image = AllocatePool (ImageSize); - if (Image != NULL) { - Status = FmpDeviceGetImage (Image, &ImageSize); - } - } - } - if (!EFI_ERROR (Status) && Image != NULL) { - IsDepexValid = ValidateImageDepex ((EFI_FIRMWARE_IMAGE_DEP *) Image, ImageSize, &DepexSize); - if (IsDepexValid) { - Private->Descriptor.Dependencies = AllocatePool (DepexSize); - if (Private->Descriptor.Dependencies != NULL) { - CopyMem (Private->Descriptor.Dependencies->Dependencies, Image, DepexSize); - } - } - } + if (Private->Descriptor.AttributesSetting & IMAGE_ATTRIBUTE_DEPENDENCY) { + Private->Descriptor.Dependencies = GetFmpDependency (NULL); } Private->DescriptorPopulated = TRUE; - - if (Image != NULL) { - FreePool (Image); - } } /** Returns information about the current firmware image(s) of the device. @@ -586,21 +551,16 @@ GetTheImage ( ) { EFI_STATUS Status; FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private; UINTN Size; - UINT8 *ImageBuffer; - UINTN ImageBufferSize; - UINT32 DepexSize; if (!FeaturePcdGet (PcdFmpDeviceStorageAccessEnable)) { return EFI_UNSUPPORTED; } - Status = EFI_SUCCESS; - ImageBuffer = NULL; - DepexSize = 0; + Status = EFI_SUCCESS; // // Retrieve the private context structure // Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (This); @@ -626,49 +586,12 @@ GetTheImage ( // Status = FmpDeviceGetSize (&Size); if (EFI_ERROR (Status)) { Size = 0; } - - // - // The parameter "Image" of FmpDeviceGetImage() is extended to contain the dependency. - // Get the Fmp Payload from the Image. - // - ImageBufferSize = Size; - ImageBuffer = AllocatePool (ImageBufferSize); - if (ImageBuffer == NULL) { - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - AllocatePool fails.\n", mImageIdName)); - Status = EFI_NOT_FOUND; - goto cleanup; - } - Status = FmpDeviceGetImage (ImageBuffer, &ImageBufferSize); - if (Status == EFI_BUFFER_TOO_SMALL) { - FreePool (ImageBuffer); - ImageBuffer = AllocatePool (ImageBufferSize); - if (ImageBuffer == NULL) { - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - AllocatePool fails.\n", mImageIdName)); - Status = EFI_NOT_FOUND; - goto cleanup; - } - Status = FmpDeviceGetImage (ImageBuffer, &ImageBufferSize); - } - if (EFI_ERROR (Status)) { - goto cleanup; - } - - // - // Check the attribute IMAGE_ATTRIBUTE_DEPENDENCY - // - if (Private->Descriptor.AttributesSetting & IMAGE_ATTRIBUTE_DEPENDENCY) { - // - // Validate the dependency to get its size. - // - ValidateImageDepex ((EFI_FIRMWARE_IMAGE_DEP *) ImageBuffer, ImageBufferSize, &DepexSize); - } - - if (*ImageSize < ImageBufferSize - DepexSize) { - *ImageSize = ImageBufferSize - DepexSize; + if (*ImageSize < Size) { + *ImageSize = Size; DEBUG ((DEBUG_VERBOSE, "FmpDxe(%s): GetImage() - ImageSize is to small.\n", mImageIdName)); Status = EFI_BUFFER_TOO_SMALL; goto cleanup; } @@ -676,57 +599,50 @@ GetTheImage ( DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - Image Pointer Parameter is NULL.\n", mImageIdName)); Status = EFI_INVALID_PARAMETER; goto cleanup; } - // - // Image is after the dependency expression. - // - *ImageSize = ImageBufferSize - DepexSize; - CopyMem (Image, ImageBuffer + DepexSize, *ImageSize); - Status = EFI_SUCCESS; - + Status = FmpDeviceGetImage (Image, ImageSize); cleanup: - if (ImageBuffer != NULL) { - FreePool (ImageBuffer); - } return Status; } /** Helper function to safely retrieve the FMP header from within an EFI_FIRMWARE_IMAGE_AUTHENTICATION structure. - @param[in] Image Pointer to the image. - @param[in] ImageSize Size of the image. + @param[in] Image Pointer to the image. + @param[in] ImageSize Size of the image. + @param[in] AdditionalHeaderSize Size of any headers that cannot be calculated by this function. @param[out] PayloadSize @retval !NULL Valid pointer to the header. @retval NULL Structure is bad and pointer cannot be found. **/ VOID * GetFmpHeader ( IN CONST EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image, IN CONST UINTN ImageSize, + IN CONST UINTN AdditionalHeaderSize, OUT UINTN *PayloadSize ) { // // Check to make sure that operation can be safely performed. // - if (((UINTN)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength) < (UINTN)Image || \ - ((UINTN)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength) >= (UINTN)Image + ImageSize) { + if (((UINTN)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength) + AdditionalHeaderSize < (UINTN)Image || \ + ((UINTN)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength) + AdditionalHeaderSize >= (UINTN)Image + ImageSize) { // // Pointer overflow. Invalid image. // return NULL; } - *PayloadSize = ImageSize - (sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength); - return (VOID *)((UINT8 *)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength); + *PayloadSize = ImageSize - (sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength + AdditionalHeaderSize); + return (VOID *)((UINT8 *)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength + AdditionalHeaderSize); } /** Helper function to safely calculate the size of all headers within an EFI_FIRMWARE_IMAGE_AUTHENTICATION structure. @@ -809,12 +725,10 @@ CheckTheImage ( UINTN PublicKeyDataLength; UINT8 *PublicKeyDataXdr; UINT8 *PublicKeyDataXdrEnd; EFI_FIRMWARE_IMAGE_DEP *Dependencies; UINT32 DependenciesSize; - BOOLEAN IsDepexValid; - BOOLEAN IsDepexSatisfied; Status = EFI_SUCCESS; RawSize = 0; FmpPayloadHeader = NULL; FmpPayloadSize = 0; @@ -848,10 +762,15 @@ CheckTheImage ( // //Set to valid and then if any tests fail it will update this flag. // *ImageUpdatable = IMAGE_UPDATABLE_VALID; + // + // Set to satisfied and then if dependency evaluates to false it will update this flag. + // + Private->DependenciesSatisfied = TRUE; + if (Image == NULL) { DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckImage() - Image Pointer Parameter is NULL.\n", mImageIdName)); // // not sure if this is needed // @@ -933,49 +852,30 @@ CheckTheImage ( *ImageUpdatable = IMAGE_UPDATABLE_INVALID_TYPE; Status = EFI_SUCCESS; goto cleanup; } + // + // Get the dependency from Image. + // + Dependencies = GetImageDependency ((EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, ImageSize, &DependenciesSize); // // Check the FmpPayloadHeader // - FmpPayloadHeader = GetFmpHeader ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, ImageSize, &FmpPayloadSize ); + FmpPayloadHeader = GetFmpHeader ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, ImageSize, DependenciesSize, &FmpPayloadSize ); if (FmpPayloadHeader == NULL) { DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetFmpHeader failed.\n", mImageIdName)); Status = EFI_ABORTED; goto cleanup; } Status = GetFmpPayloadHeaderVersion (FmpPayloadHeader, FmpPayloadSize, &Version); if (EFI_ERROR (Status)) { - // - // Check if there is dependency expression - // - IsDepexValid = ValidateImageDepex ((EFI_FIRMWARE_IMAGE_DEP*) FmpPayloadHeader, FmpPayloadSize, &DependenciesSize); - if (IsDepexValid && (DependenciesSize < FmpPayloadSize)) { - // - // Fmp payload is after dependency expression - // - Dependencies = (EFI_FIRMWARE_IMAGE_DEP*) FmpPayloadHeader; - FmpPayloadHeader = (UINT8 *) Dependencies + DependenciesSize; - FmpPayloadSize = FmpPayloadSize - DependenciesSize; - Status = GetFmpPayloadHeaderVersion (FmpPayloadHeader, FmpPayloadSize, &Version); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetFmpPayloadHeaderVersion failed %r.\n", mImageIdName, Status)); - *ImageUpdatable = IMAGE_UPDATABLE_INVALID; - Status = EFI_SUCCESS; - goto cleanup; - } - } else { - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Dependency is invalid.\n", mImageIdName)); - mDependenciesCheckStatus = DEPENDENCIES_INVALID; - *ImageUpdatable = IMAGE_UPDATABLE_INVALID; - Status = EFI_SUCCESS; - goto cleanup; - } - } else { - DEBUG ((DEBUG_WARN, "FmpDxe(%s): CheckTheImage() - No dependency associated in image.\n", mImageIdName)); + DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetFmpPayloadHeaderVersion failed %r.\n", mImageIdName, Status)); + *ImageUpdatable = IMAGE_UPDATABLE_INVALID; + Status = EFI_SUCCESS; + goto cleanup; } // // Check the lowest supported version // @@ -991,18 +891,13 @@ CheckTheImage ( } // // Evaluate dependency expression // - Status = EvaluateImageDependencies (Private->Descriptor.ImageTypeId, Version, Dependencies, DependenciesSize, &IsDepexSatisfied); - if (!IsDepexSatisfied || EFI_ERROR (Status)) { - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Dependency check failed %r.\n", mImageIdName, Status)); - } else { - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Dependency is not satisfied.\n", mImageIdName)); - } - mDependenciesCheckStatus = DEPENDENCIES_UNSATISFIED; + Private->DependenciesSatisfied = CheckFmpDependency (Private->Descriptor.ImageTypeId, Version, Dependencies, DependenciesSize); + if (!Private->DependenciesSatisfied) { + DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Dependency check failed.\n", mImageIdName)); *ImageUpdatable = IMAGE_UPDATABLE_INVALID; Status = EFI_SUCCESS; goto cleanup; } @@ -1111,13 +1006,10 @@ SetTheImage ( UINT32 LastAttemptStatus; UINT32 Version; UINT32 LowestSupportedVersion; EFI_FIRMWARE_IMAGE_DEP *Dependencies; UINT32 DependenciesSize; - BOOLEAN IsDepexValid; - UINT8 *ImageBuffer; - UINTN ImageBufferSize; Status = EFI_SUCCESS; Updateable = 0; BooleanValue = FALSE; FmpHeaderSize = 0; @@ -1126,12 +1018,10 @@ SetTheImage ( AllHeaderSize = 0; IncomingFwVersion = 0; LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL; Dependencies = NULL; DependenciesSize = 0; - ImageBuffer = NULL; - ImageBufferSize = 0; if (!FeaturePcdGet (PcdFmpDeviceStorageAccessEnable)) { return EFI_UNSUPPORTED; } @@ -1159,15 +1049,10 @@ SetTheImage ( DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - Device is already locked. Can't update.\n", mImageIdName)); Status = EFI_UNSUPPORTED; goto cleanup; } - // - // Set check status to satisfied before CheckTheImage() - // - mDependenciesCheckStatus = DEPENDENCIES_SATISFIED; - // // Call check image to verify the image // Status = CheckTheImage (This, ImageIndex, Image, ImageSize, &Updateable); if (EFI_ERROR (Status)) { @@ -1176,36 +1061,26 @@ SetTheImage ( LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR; } goto cleanup; } + // + // Get the dependency from Image. + // + Dependencies = GetImageDependency ((EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, ImageSize, &DependenciesSize); + // // No functional error in CheckTheImage. Attempt to get the Version to // support better error reporting. // - FmpHeader = GetFmpHeader ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, ImageSize, &FmpPayloadSize ); + FmpHeader = GetFmpHeader ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, ImageSize, DependenciesSize, &FmpPayloadSize ); if (FmpHeader == NULL) { DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - GetFmpHeader failed.\n", mImageIdName)); Status = EFI_ABORTED; goto cleanup; } Status = GetFmpPayloadHeaderVersion (FmpHeader, FmpPayloadSize, &IncomingFwVersion); - if (EFI_ERROR (Status)) { - // - // Check if there is dependency expression - // - IsDepexValid = ValidateImageDepex ((EFI_FIRMWARE_IMAGE_DEP*) FmpHeader, FmpPayloadSize, &DependenciesSize); - if (IsDepexValid && (DependenciesSize < FmpPayloadSize)) { - // - // Fmp payload is after dependency expression - // - Dependencies = (EFI_FIRMWARE_IMAGE_DEP*) FmpHeader; - FmpHeader = (UINT8 *) FmpHeader + DependenciesSize; - FmpPayloadSize = FmpPayloadSize - DependenciesSize; - Status = GetFmpPayloadHeaderVersion (FmpHeader, FmpPayloadSize, &IncomingFwVersion); - } - } if (!EFI_ERROR (Status)) { // // Set to actual value // SetLastAttemptVersionInVariable (Private, IncomingFwVersion); @@ -1216,14 +1091,12 @@ SetTheImage ( DEBUG ( (DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - Check The Image returned that the Image was not valid for update. Updatable value = 0x%X.\n", mImageIdName, Updateable) ); - if (mDependenciesCheckStatus == DEPENDENCIES_UNSATISFIED) { + if (Private->DependenciesSatisfied == FALSE) { LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSATISFIED_DEPENDENCIES; - } else if (mDependenciesCheckStatus == DEPENDENCIES_INVALID) { - LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; } Status = EFI_ABORTED; goto cleanup; } @@ -1321,59 +1194,41 @@ SetTheImage ( DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - GetAllHeaderSize failed.\n", mImageIdName)); Status = EFI_ABORTED; goto cleanup; } - // - // Check the attribute IMAGE_ATTRIBUTE_DEPENDENCY - // - if (Private->Descriptor.AttributesSetting & IMAGE_ATTRIBUTE_DEPENDENCY) { - // - // To support saving dependency, extend param "Image" of FmpDeviceSetImage() to - // contain the dependency inside. FmpDeviceSetImage() is responsible for saving - // the dependency which can be used for future dependency check. - // - ImageBufferSize = DependenciesSize + ImageSize - AllHeaderSize; - ImageBuffer = AllocatePool (ImageBufferSize); - if (ImageBuffer == NULL) { - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - AllocatePool failed.\n", mImageIdName)); - Status = EFI_ABORTED; - goto cleanup; - } - CopyMem (ImageBuffer, Dependencies->Dependencies, DependenciesSize); - CopyMem (ImageBuffer + DependenciesSize, (UINT8 *)Image + AllHeaderSize, ImageBufferSize - DependenciesSize); - } else { - ImageBufferSize = ImageSize - AllHeaderSize; - ImageBuffer = AllocateCopyPool(ImageBufferSize, (UINT8 *)Image + AllHeaderSize); - if (ImageBuffer == NULL) { - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - AllocatePool failed.\n", mImageIdName)); - Status = EFI_ABORTED; - goto cleanup; - } - } - // // Indicate that control is handed off to FmpDeviceLib // Progress (5); // //Copy the requested image to the firmware using the FmpDeviceLib // Status = FmpDeviceSetImage ( - ImageBuffer, - ImageBufferSize, + (((UINT8 *)Image) + AllHeaderSize), + ImageSize - AllHeaderSize, VendorCode, FmpDxeProgress, IncomingFwVersion, AbortReason ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() SetImage from FmpDeviceLib failed. Status = %r.\n", mImageIdName, Status)); goto cleanup; } + // + // Store the dependency + // + if (Private->Descriptor.AttributesSetting & IMAGE_ATTRIBUTE_DEPENDENCY) { + Status = SaveFmpDependency (Dependencies, DependenciesSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() SaveFmpDependency from FmpDependencyCheckLib failed. (%r)\n", mImageIdName, Status)); + } + Status = EFI_SUCCESS; + } // // Finished the update without error // Indicate that control has been returned from FmpDeviceLib // @@ -1396,14 +1251,10 @@ SetTheImage ( SetLowestSupportedVersionInVariable (Private, LowestSupportedVersion); LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS; cleanup: - if (ImageBuffer != NULL) { - FreePool (ImageBuffer); - } - mProgressFunc = NULL; SetLastAttemptStatusInVariable (Private, LastAttemptStatus); if (Progress != NULL) { // diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.h b/FmpDevicePkg/FmpDxe/FmpDxe.h index 150f18b656..5f0643204f 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxe.h +++ b/FmpDevicePkg/FmpDxe/FmpDxe.h @@ -26,10 +26,12 @@ #include #include #include #include #include +#include +#include #include #include #include #include #include @@ -64,10 +66,11 @@ typedef struct { CHAR16 *VersionVariableName; CHAR16 *LsvVariableName; CHAR16 *LastAttemptStatusVariableName; CHAR16 *LastAttemptVersionVariableName; CHAR16 *FmpStateVariableName; + BOOLEAN DependenciesSatisfied; } FIRMWARE_MANAGEMENT_PRIVATE_DATA; /// /// /// diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.inf b/FmpDevicePkg/FmpDxe/FmpDxe.inf index 97b6518fa1..b42d6e5c01 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxe.inf +++ b/FmpDevicePkg/FmpDxe/FmpDxe.inf @@ -26,12 +26,10 @@ # [Sources] FmpDxe.c FmpDxe.h - Dependency.c - Dependency.h DetectTestKey.c VariableSupport.h VariableSupport.c [Packages] @@ -52,10 +50,12 @@ BaseCryptLib FmpAuthenticationLib FmpDeviceLib FmpPayloadHeaderLib CapsuleUpdatePolicyLib + FmpDependencyLib + FmpDependencyCheckLib [Guids] gEfiEndOfDxeEventGroupGuid [Protocols] diff --git a/FmpDevicePkg/FmpDxe/FmpDxeLib.inf b/FmpDevicePkg/FmpDxe/FmpDxeLib.inf index de005b6892..c309841e99 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxeLib.inf +++ b/FmpDevicePkg/FmpDxe/FmpDxeLib.inf @@ -27,12 +27,10 @@ # [Sources] FmpDxe.c FmpDxe.h - Dependency.c - Dependency.h DetectTestKey.c VariableSupport.h VariableSupport.c [Packages] @@ -52,10 +50,12 @@ BaseCryptLib FmpAuthenticationLib FmpDeviceLib FmpPayloadHeaderLib CapsuleUpdatePolicyLib + FmpDependencyLib + FmpDependencyCheckLib [Guids] gEfiEndOfDxeEventGroupGuid [Protocols] -- 2.16.2.windows.1