1e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao/** @file 2e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao EDKII System Capsule library. 3e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 4e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao EDKII System Capsule library instance. 5e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 6e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao CapsuleAuthenticateSystemFirmware(), ExtractAuthenticatedImage() will receive 7e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao untrusted input and do basic validation. 8e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 9e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> 10e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao This program and the accompanying materials 11e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao are licensed and made available under the terms and conditions of the BSD License 12e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao which accompanies this distribution. The full text of the license may be found at 13e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao http://opensource.org/licenses/bsd-license.php 14e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 15e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 16e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 17e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 18e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao**/ 19e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 20e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao#include <PiDxe.h> 21e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 22e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao#include <Guid/SystemResourceTable.h> 23e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao#include <Guid/FirmwareContentsSigned.h> 24e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao#include <Guid/WinCertificate.h> 25e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao#include <Guid/EdkiiSystemFmpCapsule.h> 26e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao#include <Guid/WinCertificate.h> 27e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao#include <Guid/ImageAuthentication.h> 28e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 29e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao#include <Library/BaseLib.h> 30e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao#include <Library/BaseMemoryLib.h> 31e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao#include <Library/DebugLib.h> 32e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao#include <Library/MemoryAllocationLib.h> 33e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao#include <Library/EdkiiSystemCapsuleLib.h> 34e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao#include <Library/FmpAuthenticationLib.h> 35e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 36e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao#include <Protocol/FirmwareManagement.h> 37e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 38e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoEDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR *mImageFmpInfo; 39e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoUINTN mImageFmpInfoSize; 40e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoEFI_GUID mEdkiiSystemFirmwareFileGuid; 41e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 42e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao/** 43e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Check if a block of buffer is erased. 44e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 45e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] ErasePolarity Erase polarity attribute of the firmware volume 46e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] InBuffer The buffer to be checked 47e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] BufferSize Size of the buffer in bytes 48e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 49e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @retval TRUE The block of buffer is erased 50e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @retval FALSE The block of buffer is not erased 51e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao**/ 52e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoBOOLEAN 53e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoIsBufferErased ( 54e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN UINT8 ErasePolarity, 55e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN VOID *InBuffer, 56e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN UINTN BufferSize 57e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao ) 58e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao{ 59e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao UINTN Count; 60e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao UINT8 EraseByte; 61e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao UINT8 *Buffer; 62e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 63e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if(ErasePolarity == 1) { 64e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao EraseByte = 0xFF; 65e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } else { 66e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao EraseByte = 0; 67e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 68e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 69e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Buffer = InBuffer; 70e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao for (Count = 0; Count < BufferSize; Count++) { 71e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (Buffer[Count] != EraseByte) { 72e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return FALSE; 73e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 74e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 75e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 76e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return TRUE; 77e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao} 78e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 79e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao/** 80e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Get Section buffer pointer by SectionType and SectionInstance. 81e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 82e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] SectionBuffer The buffer of section 83e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] SectionBufferSize The size of SectionBuffer in bytes 84e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] SectionType The SectionType of Section to be found 85e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] SectionInstance The Instance of Section to be found 86e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[out] OutSectionBuffer The section found, including SECTION_HEADER 87e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[out] OutSectionSize The size of section found, including SECTION_HEADER 88e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 89e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @retval TRUE The FFS buffer is found. 90e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @retval FALSE The FFS buffer is not found. 91e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao**/ 92e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoBOOLEAN 93e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoGetSectionByType ( 94e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN VOID *SectionBuffer, 95e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN UINT32 SectionBufferSize, 96e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN EFI_SECTION_TYPE SectionType, 97e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN UINTN SectionInstance, 98e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao OUT VOID **OutSectionBuffer, 99e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao OUT UINTN *OutSectionSize 100e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao ) 101e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao{ 102e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao EFI_COMMON_SECTION_HEADER *SectionHeader; 103e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao UINTN SectionSize; 104e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao UINTN Instance; 105e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 106e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG ((DEBUG_INFO, "GetSectionByType - Buffer: 0x%08x - 0x%08x\n", SectionBuffer, SectionBufferSize)); 107e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 108e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // 109e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // Find Section 110e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // 111e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao SectionHeader = SectionBuffer; 112e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 113e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Instance = 0; 114e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao while ((UINTN)SectionHeader < (UINTN)SectionBuffer + SectionBufferSize) { 115e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG ((DEBUG_INFO, "GetSectionByType - Section: 0x%08x\n", SectionHeader)); 116e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (IS_SECTION2(SectionHeader)) { 117e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao SectionSize = SECTION2_SIZE(SectionHeader); 118e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } else { 119e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao SectionSize = SECTION_SIZE(SectionHeader); 120e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 121e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 122e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (SectionHeader->Type == SectionType) { 123e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (Instance == SectionInstance) { 124e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *OutSectionBuffer = (UINT8 *)SectionHeader; 125e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *OutSectionSize = SectionSize; 126e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_INFO, "GetSectionByType - 0x%x - 0x%x\n", *OutSectionBuffer, *OutSectionSize)); 127e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return TRUE; 128e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } else { 129e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_INFO, "GetSectionByType - find section instance %x\n", Instance)); 130e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Instance++; 131e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 132e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } else { 133e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // 134e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // Skip other section type 135e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // 136e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG ((DEBUG_INFO, "GetSectionByType - other section type 0x%x\n", SectionHeader->Type)); 137e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 138e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 139e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // 140e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // Next Section 141e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // 142e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao SectionHeader = (EFI_COMMON_SECTION_HEADER *)((UINTN)SectionHeader + ALIGN_VALUE(SectionSize, 4)); 143e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 144e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 145e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return FALSE; 146e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao} 147e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 148e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao/** 149e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Get FFS buffer pointer by FileName GUID and FileType. 150e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 151e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] FdStart The System Firmware FD image 152e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] FdSize The size of System Firmware FD image 153e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] FileName The FileName GUID of FFS to be found 154e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] Type The FileType of FFS to be found 155e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[out] OutFfsBuffer The FFS buffer found, including FFS_FILE_HEADER 156e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[out] OutFfsBufferSize The size of FFS buffer found, including FFS_FILE_HEADER 157e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 158e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @retval TRUE The FFS buffer is found. 159e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @retval FALSE The FFS buffer is not found. 160e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao**/ 161e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoBOOLEAN 162e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoGetFfsByName ( 163e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN VOID *FdStart, 164e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN UINTN FdSize, 165e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN EFI_GUID *FileName, 166e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN EFI_FV_FILETYPE Type, 167e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao OUT VOID **OutFfsBuffer, 168e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao OUT UINTN *OutFfsBufferSize 169e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao ) 170e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao{ 171e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao UINTN FvSize; 172e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao EFI_FIRMWARE_VOLUME_HEADER *FvHeader; 173e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader; 174e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao EFI_FFS_FILE_HEADER *FfsHeader; 175e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao UINT32 FfsSize; 176e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao UINTN TestLength; 177e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao BOOLEAN FvFound; 178e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 179e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG ((DEBUG_INFO, "GetFfsByName - FV: 0x%08x - 0x%08x\n", (UINTN)FdStart, (UINTN)FdSize)); 180e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 181e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FvFound = FALSE; 182e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FdStart; 183e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao while ((UINTN)FvHeader < (UINTN)FdStart + FdSize - 1) { 184e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FvSize = (UINTN)FdStart + FdSize - (UINTN)FvHeader; 185e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 186e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (FvHeader->Signature != EFI_FVH_SIGNATURE) { 187e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)FvHeader + SIZE_4KB); 188e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao continue; 189e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 190e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_ERROR, "checking FV....0x%08x - 0x%x\n", FvHeader, FvHeader->FvLength)); 191e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FvFound = TRUE; 192e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (FvHeader->FvLength > FvSize) { 193e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_ERROR, "GetFfsByName - FvSize: 0x%08x, MaxSize - 0x%08x\n", (UINTN)FvHeader->FvLength, (UINTN)FvSize)); 194e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return FALSE; 195e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 196e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FvSize = (UINTN)FvHeader->FvLength; 197e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 198e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // 199e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // Find FFS 200e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // 201e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (FvHeader->ExtHeaderOffset != 0) { 202e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)((UINT8 *)FvHeader + FvHeader->ExtHeaderOffset); 203e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FfsHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FvExtHeader + FvExtHeader->ExtHeaderSize); 204e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } else { 205e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FfsHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FvHeader + FvHeader->HeaderLength); 206e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 207e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FfsHeader = (EFI_FFS_FILE_HEADER *)((UINTN)FvHeader + ALIGN_VALUE((UINTN)FfsHeader - (UINTN)FvHeader, 8)); 208e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 209e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao while ((UINTN)FfsHeader < (UINTN)FvHeader + FvSize - 1) { 210e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_INFO, "GetFfsByName - FFS: 0x%08x\n", FfsHeader)); 211e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao TestLength = (UINTN)((UINTN)FvHeader + FvSize - (UINTN)FfsHeader); 212e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (TestLength > sizeof(EFI_FFS_FILE_HEADER)) { 213e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao TestLength = sizeof(EFI_FFS_FILE_HEADER); 214e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 215e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (IsBufferErased(1, FfsHeader, TestLength)) { 216e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao break; 217e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 218e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 219e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (IS_FFS_FILE2(FfsHeader)) { 220e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FfsSize = FFS_FILE2_SIZE(FfsHeader); 221e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } else { 222e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FfsSize = FFS_FILE_SIZE(FfsHeader); 223e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 224e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 225e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (CompareGuid(FileName, &FfsHeader->Name) && 226e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao ((Type == EFI_FV_FILETYPE_ALL) || (FfsHeader->Type == Type))) { 227e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // 228e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // Check section 229e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // 230e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *OutFfsBuffer = FfsHeader; 231e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *OutFfsBufferSize = FfsSize; 232e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return TRUE; 233e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } else { 234e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // 235e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // Any other type is not allowed 236e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // 237e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_INFO, "GetFfsByName - other FFS type 0x%x, name %g\n", FfsHeader->Type, &FfsHeader->Name)); 238e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 239e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 240e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // 241e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // Next File 242e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // 243e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FfsHeader = (EFI_FFS_FILE_HEADER *)((UINTN)FfsHeader + ALIGN_VALUE(FfsSize, 8)); 244e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 245e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 246e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // 247e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // Next FV 248e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // 249e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FvHeader = (VOID *)(UINTN)((UINTN)FvHeader + FvHeader->FvLength); 250e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_ERROR, "Next FV....0x%08x - 0x%x\n", FvHeader, FvHeader->FvLength)); 251e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 252e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 253e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (!FvFound) { 254e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_ERROR, "GetFfsByName - NO FV Found\n")); 255e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 256e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return FALSE; 257e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao} 258e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 259e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao/** 260e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Extract the driver FV from an authenticated image. 261e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 262e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] AuthenticatedImage The authenticated capsule image. 263e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] AuthenticatedImageSize The size of the authenticated capsule image in bytes. 264e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[out] DriverFvImage The driver FV image. 265e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[out] DriverFvImageSize The size of the driver FV image in bytes. 266e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 267e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @retval TRUE The driver Fv is extracted. 268e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @retval FALSE The driver Fv is not extracted. 269e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao**/ 270e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoBOOLEAN 271e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoEFIAPI 272e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoExtractDriverFvImage ( 273e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN VOID *AuthenticatedImage, 274e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN UINTN AuthenticatedImageSize, 275e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao OUT VOID **DriverFvImage, 276e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao OUT UINTN *DriverFvImageSize 277e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao ) 278e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao{ 279e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao BOOLEAN Result; 280e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao UINT32 FileHeaderSize; 281e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 282e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *DriverFvImage = NULL; 283e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *DriverFvImageSize = 0; 284e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 285e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Result = GetFfsByName(AuthenticatedImage, AuthenticatedImageSize, &gEdkiiSystemFmpCapsuleDriverFvFileGuid, EFI_FV_FILETYPE_RAW, DriverFvImage, DriverFvImageSize); 286e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (!Result) { 287e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return FALSE; 288e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 289e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 290e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (IS_FFS_FILE2(*DriverFvImage)) { 291e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FileHeaderSize = sizeof(EFI_FFS_FILE_HEADER2); 292e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } else { 293e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FileHeaderSize = sizeof(EFI_FFS_FILE_HEADER); 294e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 295e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *DriverFvImage = (UINT8 *)*DriverFvImage + FileHeaderSize; 296e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *DriverFvImageSize = *DriverFvImageSize - FileHeaderSize; 297e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 298e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return Result; 299e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao} 300e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 301e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao/** 302e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Extract the config image from an authenticated image. 303e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 304e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] AuthenticatedImage The authenticated capsule image. 305e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] AuthenticatedImageSize The size of the authenticated capsule image in bytes. 306e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[out] ConfigImage The config image. 307e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[out] ConfigImageSize The size of the config image in bytes. 308e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 309e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @retval TRUE The config image is extracted. 310e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @retval FALSE The config image is not extracted. 311e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao**/ 312e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoBOOLEAN 313e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoEFIAPI 314e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoExtractConfigImage ( 315e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN VOID *AuthenticatedImage, 316e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN UINTN AuthenticatedImageSize, 317e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao OUT VOID **ConfigImage, 318e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao OUT UINTN *ConfigImageSize 319e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao ) 320e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao{ 321e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao BOOLEAN Result; 322e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao UINT32 FileHeaderSize; 323e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 324e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *ConfigImage = NULL; 325e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *ConfigImageSize = 0; 326e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 327e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Result = GetFfsByName(AuthenticatedImage, AuthenticatedImageSize, &gEdkiiSystemFmpCapsuleConfigFileGuid, EFI_FV_FILETYPE_RAW, ConfigImage, ConfigImageSize); 328e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (!Result) { 329e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return FALSE; 330e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 331e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 332e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (IS_FFS_FILE2(*ConfigImage)) { 333e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FileHeaderSize = sizeof(EFI_FFS_FILE_HEADER2); 334e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } else { 335e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FileHeaderSize = sizeof(EFI_FFS_FILE_HEADER); 336e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 337e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *ConfigImage = (UINT8 *)*ConfigImage + FileHeaderSize; 338e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *ConfigImageSize = *ConfigImageSize - FileHeaderSize; 339e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 340e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return Result; 341e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao} 342e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 343e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao/** 344e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Extract the authenticated image from an FMP capsule image. 345e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 346e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Caution: This function may receive untrusted input. 347e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 348e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] Image The FMP capsule image, including EFI_FIRMWARE_IMAGE_AUTHENTICATION. 349e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] ImageSize The size of FMP capsule image in bytes. 350e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. 351e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[out] AuthenticatedImage The authenticated capsule image, excluding EFI_FIRMWARE_IMAGE_AUTHENTICATION. 352e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[out] AuthenticatedImageSize The size of the authenticated capsule image in bytes. 353e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 354e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @retval TRUE The authenticated image is extracted. 355e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @retval FALSE The authenticated image is not extracted. 356e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao**/ 357e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoBOOLEAN 358e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoEFIAPI 359e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoExtractAuthenticatedImage ( 360e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN VOID *Image, 361e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN UINTN ImageSize, 362e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao OUT UINT32 *LastAttemptStatus, 363e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao OUT VOID **AuthenticatedImage, 364e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao OUT UINTN *AuthenticatedImageSize 365e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao ) 366e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao{ 367e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao EFI_FIRMWARE_IMAGE_AUTHENTICATION *ImageAuth; 368e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao EFI_STATUS Status; 369e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao GUID *CertType; 370e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao VOID *PublicKeyData; 371e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao UINTN PublicKeyDataLength; 372e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 373e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_INFO, "ExtractAuthenticatedImage - Image: 0x%08x - 0x%08x\n", (UINTN)Image, (UINTN)ImageSize)); 374e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 375e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; 376e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if ((Image == NULL) || (ImageSize == 0)) { 377e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return FALSE; 378e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 379e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 380e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao ImageAuth = (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image; 381e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (ImageSize < sizeof(EFI_FIRMWARE_IMAGE_AUTHENTICATION)) { 382e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_ERROR, "ExtractAuthenticatedImage - ImageSize too small\n")); 383e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return FALSE; 384e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 385e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (ImageAuth->AuthInfo.Hdr.dwLength <= OFFSET_OF(WIN_CERTIFICATE_UEFI_GUID, CertData)) { 386e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_ERROR, "ExtractAuthenticatedImage - dwLength too small\n")); 387e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return FALSE; 388e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 389e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (ImageAuth->AuthInfo.Hdr.dwLength > MAX_UINTN - sizeof(UINT64)) { 390e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_ERROR, "ExtractAuthenticatedImage - dwLength too big\n")); 391e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return FALSE; 392e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 393e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (ImageSize <= sizeof(ImageAuth->MonotonicCount) + ImageAuth->AuthInfo.Hdr.dwLength) { 394e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_ERROR, "ExtractAuthenticatedImage - ImageSize too small\n")); 395e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return FALSE; 396e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 397e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (ImageAuth->AuthInfo.Hdr.wRevision != 0x0200) { 398e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_ERROR, "ExtractAuthenticatedImage - wRevision: 0x%02x, expect - 0x%02x\n", (UINTN)ImageAuth->AuthInfo.Hdr.wRevision, (UINTN)0x0200)); 399e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return FALSE; 400e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 401e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (ImageAuth->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) { 402e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_ERROR, "ExtractAuthenticatedImage - wCertificateType: 0x%02x, expect - 0x%02x\n", (UINTN)ImageAuth->AuthInfo.Hdr.wCertificateType, (UINTN)WIN_CERT_TYPE_EFI_GUID)); 403e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return FALSE; 404e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 405e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 406e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao CertType = &ImageAuth->AuthInfo.CertType; 407e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_INFO, "ExtractAuthenticatedImage - CertType: %g\n", CertType)); 408e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 409e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (CompareGuid(&gEfiCertPkcs7Guid, CertType)) { 410e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao PublicKeyData = PcdGetPtr(PcdPkcs7CertBuffer); 411e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao PublicKeyDataLength = PcdGetSize(PcdPkcs7CertBuffer); 412e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } else if (CompareGuid(&gEfiCertTypeRsa2048Sha256Guid, CertType)) { 413e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao PublicKeyData = PcdGetPtr(PcdRsa2048Sha256PublicKeyBuffer); 414e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao PublicKeyDataLength = PcdGetSize(PcdRsa2048Sha256PublicKeyBuffer); 415e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } else { 416e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return FALSE; 417e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 4187e6e4f96069464ed6ee0669e181abe7cb6801223Jiewen Yao ASSERT (PublicKeyData != NULL); 4197e6e4f96069464ed6ee0669e181abe7cb6801223Jiewen Yao ASSERT (PublicKeyDataLength != 0); 420e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 421e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Status = AuthenticateFmpImage( 422e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao ImageAuth, 423e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao ImageSize, 424e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao PublicKeyData, 425e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao PublicKeyDataLength 426e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao ); 427e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao switch (Status) { 428e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao case RETURN_SUCCESS: 429e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS; 430e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao break; 431e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao case RETURN_SECURITY_VIOLATION: 432e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR; 433e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao break; 434e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao case RETURN_INVALID_PARAMETER: 435e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; 436e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao break; 437e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao case RETURN_UNSUPPORTED: 438e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; 439e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao break; 440e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao case RETURN_OUT_OF_RESOURCES: 441e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES; 442e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao break; 443e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao default: 444e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL; 445e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao break; 446e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 447e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (EFI_ERROR(Status)) { 448e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return FALSE; 449e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 450e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 451e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (AuthenticatedImage != NULL) { 452e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *AuthenticatedImage = (UINT8 *)ImageAuth + ImageAuth->AuthInfo.Hdr.dwLength + sizeof(ImageAuth->MonotonicCount); 453e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 454e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (AuthenticatedImageSize != NULL) { 455e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *AuthenticatedImageSize = ImageSize - ImageAuth->AuthInfo.Hdr.dwLength - sizeof(ImageAuth->MonotonicCount); 456e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 457e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return TRUE; 458e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao} 459e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 460e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao/** 461e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Extract ImageFmpInfo from system firmware. 462e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 463e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] SystemFirmwareImage The System Firmware image. 464e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] SystemFirmwareImageSize The size of the System Firmware image in bytes. 465e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[out] ImageFmpInfo The ImageFmpInfo. 466e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[out] ImageFmpInfoSize The size of the ImageFmpInfo in bytes. 467e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 468e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @retval TRUE The ImageFmpInfo is extracted. 469e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @retval FALSE The ImageFmpInfo is not extracted. 470e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao**/ 471e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoBOOLEAN 472e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoEFIAPI 473e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoExtractSystemFirmwareImageFmpInfo ( 474e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN VOID *SystemFirmwareImage, 475e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN UINTN SystemFirmwareImageSize, 476e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao OUT EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR **ImageFmpInfo, 477e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao OUT UINTN *ImageFmpInfoSize 478e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao ) 479e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao{ 480e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao BOOLEAN Result; 481e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao UINT32 SectionHeaderSize; 482e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao UINT32 FileHeaderSize; 483e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 484e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *ImageFmpInfo = NULL; 485e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *ImageFmpInfoSize = 0; 486e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 487e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Result = GetFfsByName(SystemFirmwareImage, SystemFirmwareImageSize, &gEdkiiSystemFirmwareImageDescriptorFileGuid, EFI_FV_FILETYPE_ALL, (VOID **)ImageFmpInfo, ImageFmpInfoSize); 488e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (!Result) { 489e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return FALSE; 490e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 491e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (IS_FFS_FILE2 (*ImageFmpInfo)) { 492e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FileHeaderSize = sizeof(EFI_FFS_FILE_HEADER2); 493e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } else { 494e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FileHeaderSize = sizeof(EFI_FFS_FILE_HEADER); 495e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 496e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *ImageFmpInfo = (VOID *)((UINT8 *)*ImageFmpInfo + FileHeaderSize); 497e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *ImageFmpInfoSize = *ImageFmpInfoSize - FileHeaderSize; 498e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 499e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Result = GetSectionByType(*ImageFmpInfo, (UINT32)*ImageFmpInfoSize, EFI_SECTION_RAW, 0, (VOID **)ImageFmpInfo, ImageFmpInfoSize); 500e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (!Result) { 501e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return FALSE; 502e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 503e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (IS_SECTION2(*ImageFmpInfo)) { 504e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao SectionHeaderSize = sizeof(EFI_RAW_SECTION2); 505e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } else { 506e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao SectionHeaderSize = sizeof(EFI_RAW_SECTION); 507e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 508e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *ImageFmpInfo = (VOID *)((UINT8 *)*ImageFmpInfo + SectionHeaderSize); 509e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *ImageFmpInfoSize = *ImageFmpInfoSize - SectionHeaderSize; 510e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 511e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return TRUE; 512e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao} 513e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 514e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao/** 515e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Extract the System Firmware image from an authenticated image. 516e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 517e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] AuthenticatedImage The authenticated capsule image. 518e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] AuthenticatedImageSize The size of the authenticated capsule image in bytes. 519e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[out] SystemFirmwareImage The System Firmware image. 520e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[out] SystemFirmwareImageSize The size of the System Firmware image in bytes. 521e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 522e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @retval TRUE The System Firmware image is extracted. 523e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @retval FALSE The System Firmware image is not extracted. 524e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao**/ 525e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoBOOLEAN 526e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoEFIAPI 527e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoExtractSystemFirmwareImage ( 528e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN VOID *AuthenticatedImage, 529e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN UINTN AuthenticatedImageSize, 530e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao OUT VOID **SystemFirmwareImage, 531e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao OUT UINTN *SystemFirmwareImageSize 532e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao ) 533e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao{ 534e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao BOOLEAN Result; 535e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao UINT32 FileHeaderSize; 536e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 537e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *SystemFirmwareImage = NULL; 538e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *SystemFirmwareImageSize = 0; 539e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 540e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Result = GetFfsByName(AuthenticatedImage, AuthenticatedImageSize, &mEdkiiSystemFirmwareFileGuid, EFI_FV_FILETYPE_RAW, SystemFirmwareImage, SystemFirmwareImageSize); 541e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (!Result) { 542e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // no nested FV, just return all data. 543e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *SystemFirmwareImage = AuthenticatedImage; 544e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *SystemFirmwareImageSize = AuthenticatedImageSize; 545e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 546e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return TRUE; 547e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 548e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (IS_FFS_FILE2 (*SystemFirmwareImage)) { 549e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FileHeaderSize = sizeof(EFI_FFS_FILE_HEADER2); 550e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } else { 551e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FileHeaderSize = sizeof(EFI_FFS_FILE_HEADER); 552e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 553e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *SystemFirmwareImage = (UINT8 *)*SystemFirmwareImage + FileHeaderSize; 554e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *SystemFirmwareImageSize = *SystemFirmwareImageSize - FileHeaderSize; 555e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 556e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return Result; 557e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao} 558e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 559e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao/** 560e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Authenticated system firmware FMP capsule image. 561e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 562e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Caution: This function may receive untrusted input. 563e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 564e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] Image The FMP capsule image, including EFI_FIRMWARE_IMAGE_AUTHENTICATION. 565e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] ImageSize The size of FMP capsule image in bytes. 566e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[in] ForceVersionMatch TRUE: The version of capsule must be as same as the version of current image. 567e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao FALSE: The version of capsule must be as same as greater than the lowest 568e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao supported version of current image. 569e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[out] LastAttemptVersion The last attempt version, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. 570e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. 571e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[out] AuthenticatedImage The authenticated capsule image, excluding EFI_FIRMWARE_IMAGE_AUTHENTICATION. 572e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @param[out] AuthenticatedImageSize The size of the authenticated capsule image in bytes. 573e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 574e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @retval TRUE Authentication passes and the authenticated image is extracted. 575e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @retval FALSE Authentication fails and the authenticated image is not extracted. 576e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao**/ 577e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoEFI_STATUS 578e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoEFIAPI 579e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoCapsuleAuthenticateSystemFirmware ( 580e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN VOID *Image, 581e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN UINTN ImageSize, 582e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao IN BOOLEAN ForceVersionMatch, 583e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao OUT UINT32 *LastAttemptVersion, 584e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao OUT UINT32 *LastAttemptStatus, 585e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao OUT VOID **AuthenticatedImage, 586e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao OUT UINTN *AuthenticatedImageSize 587e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao ) 588e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao{ 589e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao BOOLEAN Result; 590e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR *ImageFmpInfo; 591e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao UINTN ImageFmpInfoSize; 592e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR *CurrentImageFmpInfo; 593e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao UINTN CurrentImageFmpInfoSize; 594e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao VOID *SystemFirmwareImage; 595e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao UINTN SystemFirmwareImageSize; 596e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 597e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *LastAttemptVersion = 0; 598e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 599e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // 600e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // NOTE: This function need run in an isolated environment. 601e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // Do not touch FMP protocol and its private structure. 602e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao // 603e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 604e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Result = ExtractAuthenticatedImage((VOID *)Image, ImageSize, LastAttemptStatus, AuthenticatedImage, AuthenticatedImageSize); 605e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (!Result) { 606e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_INFO, "ExtractAuthenticatedImage - fail\n")); 607e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return EFI_SECURITY_VIOLATION; 608e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 609e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 610e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_INFO, "AuthenticatedImage - 0x%x - 0x%x\n", *AuthenticatedImage, *AuthenticatedImageSize)); 611e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 612e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Result = ExtractSystemFirmwareImage(*AuthenticatedImage, *AuthenticatedImageSize, &SystemFirmwareImage, &SystemFirmwareImageSize); 613e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (!Result) { 614e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; 615e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_INFO, "ExtractSystemFirmwareImage - fail\n")); 616e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return EFI_SECURITY_VIOLATION; 617e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 618e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_INFO, "SystemFirmwareImage - 0x%x - 0x%x\n", SystemFirmwareImage, SystemFirmwareImageSize)); 619e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 620e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao Result = ExtractSystemFirmwareImageFmpInfo(SystemFirmwareImage, SystemFirmwareImageSize, &ImageFmpInfo, &ImageFmpInfoSize); 621e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (!Result) { 622e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; 623e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_INFO, "ExtractSystemFirmwareImageFmpInfo - fail\n")); 624e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return EFI_SECURITY_VIOLATION; 625e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 626e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 627e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *LastAttemptVersion = ImageFmpInfo->Version; 628e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_INFO, "ImageFmpInfo - 0x%x - 0x%x\n", ImageFmpInfo, ImageFmpInfoSize)); 629e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_INFO, "NewImage Version - 0x%x\n", ImageFmpInfo->Version)); 630e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_INFO, "NewImage LowestSupportedImageVersion - 0x%x\n", ImageFmpInfo->LowestSupportedImageVersion)); 631e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 632e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao CurrentImageFmpInfo = mImageFmpInfo; 633e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao CurrentImageFmpInfoSize = mImageFmpInfoSize; 634e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 635e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_INFO, "ImageFmpInfo - 0x%x - 0x%x\n", CurrentImageFmpInfo, CurrentImageFmpInfoSize)); 636e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_INFO, "Current Version - 0x%x\n", CurrentImageFmpInfo->Version)); 637e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_INFO, "Current LowestSupportedImageVersion - 0x%x\n", CurrentImageFmpInfo->LowestSupportedImageVersion)); 638e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 639e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (ForceVersionMatch) { 640e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (CurrentImageFmpInfo->Version != ImageFmpInfo->Version) { 641e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION; 642e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_INFO, "ForceVersionMatch check - fail\n")); 643e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return EFI_SECURITY_VIOLATION; 644e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 645e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } else { 646e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao if (CurrentImageFmpInfo->Version < ImageFmpInfo->LowestSupportedImageVersion) { 647e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION; 648e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao DEBUG((DEBUG_INFO, "LowestSupportedImageVersion check - fail\n")); 649e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return EFI_SECURITY_VIOLATION; 650e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 651e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao } 652e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 653e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao *LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS; 654e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return EFI_SUCCESS; 655e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao} 656e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 657e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao/** 658e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao The constructor function. 659e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao 660e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao @retval EFI_SUCCESS The constructor successfully . 661e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao**/ 662e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoEFI_STATUS 663e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoEFIAPI 664e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen YaoEdkiiSystemCapsuleLibConstructor ( 665e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao VOID 666e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao ) 667e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao{ 668e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao mImageFmpInfoSize = PcdGetSize(PcdEdkiiSystemFirmwareImageDescriptor); 669e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao mImageFmpInfo = AllocateCopyPool (mImageFmpInfoSize, PcdGetPtr(PcdEdkiiSystemFirmwareImageDescriptor)); 670e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao ASSERT(mImageFmpInfo != NULL); 671e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao CopyGuid(&mEdkiiSystemFirmwareFileGuid, PcdGetPtr(PcdEdkiiSystemFirmwareFileGuid)); 672e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao return EFI_SUCCESS; 673e29caef253e1cffe2a94ec40a549e5771eb28b80Jiewen Yao} 674