/** Dispatch system FMP images. Caution: This function may receive untrusted input. @param[in] Image The EDKII system FMP capsule image. @param[in] ImageSize The size of the EDKII system FMP capsule image in bytes. @param[out] LastAttemptVersion The last attempt version, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. @param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. @retval EFI_SUCESS Process Capsule Image successfully. @retval EFI_UNSUPPORTED Capsule image is not supported by the firmware. @retval EFI_VOLUME_CORRUPTED FV volume in the capsule is corrupted. @retval EFI_OUT_OF_RESOURCES Not enough memory. **/ EFI_STATUS DispatchSystemFmpImages ( IN VOID *Image, IN UINTN ImageSize, OUT UINT32 *LastAttemptVersion, OUT UINT32 *LastAttemptStatus ) { EFI_STATUS Status; VOID *AuthenticatedImage; UINTN AuthenticatedImageSize; VOID *DispatchFvImage; UINTN DispatchFvImageSize; EFI_HANDLE FvProtocolHandle; EFI_FIRMWARE_VOLUME_HEADER *FvImage; BOOLEAN Result; AuthenticatedImage = NULL; AuthenticatedImageSize = 0; DEBUG((DEBUG_INFO, "DispatchSystemFmpImages\n")); // // Verify // Status = CapsuleAuthenticateSystemFirmware(Image, ImageSize, FALSE, LastAttemptVersion, LastAttemptStatus, &AuthenticatedImage, &AuthenticatedImageSize); if (EFI_ERROR(Status)) { DEBUG((DEBUG_INFO, "SystemFirmwareAuthenticateImage - %r\n", Status)); return Status; } // // Get FV // Result = ExtractDriverFvImage(AuthenticatedImage, AuthenticatedImageSize, &DispatchFvImage, &DispatchFvImageSize); if (Result) { DEBUG((DEBUG_INFO, "ExtractDriverFvImage\n")); // // Dispatch // if (((EFI_FIRMWARE_VOLUME_HEADER *)DispatchFvImage)->FvLength == DispatchFvImageSize) { FvImage = AllocatePages(EFI_SIZE_TO_PAGES(DispatchFvImageSize)); if (FvImage != NULL) { CopyMem(FvImage, DispatchFvImage, DispatchFvImageSize); Status = gDS->ProcessFirmwareVolume( (VOID *)FvImage, (UINTN)FvImage->FvLength, &FvProtocolHandle ); DEBUG((DEBUG_INFO, "ProcessFirmwareVolume - %r\n", Status)); if (!EFI_ERROR(Status)) { gDS->Dispatch(); DEBUG((DEBUG_INFO, "Dispatch Done\n")); } } } } return EFI_SUCCESS; }
/** Authenticate and update System Firmware image. Caution: This function may receive untrusted input. @param[in] Image The EDKII system FMP capsule image. @param[in] ImageSize The size of the EDKII system FMP capsule image in bytes. @param[out] LastAttemptVersion The last attempt version, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. @param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. @retval EFI_SUCCESS EDKII system FMP capsule passes authentication and the System Firmware image is updated. @retval EFI_SECURITY_VIOLATION EDKII system FMP capsule fails authentication and the System Firmware image is not updated. @retval EFI_WRITE_PROTECTED The flash device is read only. **/ EFI_STATUS SystemFirmwareAuthenticatedUpdate ( IN VOID *Image, IN UINTN ImageSize, OUT UINT32 *LastAttemptVersion, OUT UINT32 *LastAttemptStatus ) { EFI_STATUS Status; VOID *SystemFirmwareImage; UINTN SystemFirmwareImageSize; VOID *ConfigImage; UINTN ConfigImageSize; VOID *AuthenticatedImage; UINTN AuthenticatedImageSize; AuthenticatedImage = NULL; AuthenticatedImageSize = 0; DEBUG((DEBUG_INFO, "SystemFirmwareAuthenticatedUpdate...\n")); Status = CapsuleAuthenticateSystemFirmware(Image, ImageSize, FALSE, LastAttemptVersion, LastAttemptStatus, &AuthenticatedImage, &AuthenticatedImageSize); if (EFI_ERROR(Status)) { DEBUG((DEBUG_INFO, "SystemFirmwareAuthenticateImage - %r\n", Status)); return Status; } DEBUG((DEBUG_INFO, "ExtractSystemFirmwareImage ...\n")); ExtractSystemFirmwareImage(AuthenticatedImage, AuthenticatedImageSize, &SystemFirmwareImage, &SystemFirmwareImageSize); DEBUG((DEBUG_INFO, "ExtractConfigImage ...\n")); ExtractConfigImage(AuthenticatedImage, AuthenticatedImageSize, &ConfigImage, &ConfigImageSize); DEBUG((DEBUG_INFO, "UpdateImage ...\n")); Status = UpdateImage(SystemFirmwareImage, SystemFirmwareImageSize, ConfigImage, ConfigImageSize, LastAttemptVersion, LastAttemptStatus); if (EFI_ERROR(Status)) { DEBUG((DEBUG_INFO, "UpdateImage - %r\n", Status)); return Status; } DEBUG((DEBUG_INFO, "SystemFirmwareAuthenticatedUpdate Done\n")); return EFI_SUCCESS; }