/** Retrieves a GUID from a GUIDed section and uses that GUID to select an associated handler of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers(). The selected handler is used to retrieve and return the size of the decoded buffer and the size of an optional scratch buffer required to actually decode the data in a GUIDed section. Examines a GUIDed section specified by InputSection. If GUID for InputSection does not match any of the GUIDs registered through ExtractGuidedSectionRegisterHandlers(), then RETURN_UNSUPPORTED is returned. If the GUID of InputSection does match the GUID that this handler supports, then the the associated handler of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers() is used to retrieve the OututBufferSize, ScratchSize, and Attributes values. The return status from the handler of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER is returned. If InputSection is NULL, then ASSERT(). If OutputBufferSize is NULL, then ASSERT(). If ScratchBufferSize is NULL, then ASSERT(). If SectionAttribute is NULL, then ASSERT(). @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file. @param[out] OutputBufferSize A pointer to the size, in bytes, of an output buffer required if the buffer specified by InputSection were decoded. @param[out] ScratchBufferSize A pointer to the size, in bytes, required as scratch space if the buffer specified by InputSection were decoded. @param[out] SectionAttribute A pointer to the attributes of the GUIDed section. See the Attributes field of EFI_GUID_DEFINED_SECTION in the PI Specification. @retval RETURN_SUCCESS Get the required information successfully. @retval RETURN_UNSUPPORTED The GUID from the section specified by InputSection does not match any of the GUIDs registered with ExtractGuidedSectionRegisterHandlers(). @retval Others The return status from the handler associated with the GUID retrieved from the section specified by InputSection. **/ RETURN_STATUS EFIAPI ExtractGuidedSectionGetInfo ( IN CONST VOID *InputSection, OUT UINT32 *OutputBufferSize, OUT UINT32 *ScratchBufferSize, OUT UINT16 *SectionAttribute ) { UINT32 Index; EFI_STATUS Status; PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo; EFI_GUID *SectionDefinitionGuid; // // Check input parameter // ASSERT (InputSection != NULL); ASSERT (OutputBufferSize != NULL); ASSERT (ScratchBufferSize != NULL); ASSERT (SectionAttribute != NULL); // // Get all registered handler information. // Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo); if (EFI_ERROR (Status)) { return Status; } if (IS_SECTION2 (InputSection)) { SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid); } else { SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid); } // // Search the match registered GetInfo handler for the input guided section. // ASSERT (HandlerInfo != NULL); for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) { if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionDefinitionGuid)) { // // Call the match handler to get information for the input section data. // return HandlerInfo->ExtractGetInfoHandlerTable [Index] ( InputSection, OutputBufferSize, ScratchBufferSize, SectionAttribute ); } } // // Not found, the input guided section is not supported. // return RETURN_UNSUPPORTED; }
/** Retrieves the GUID from a GUIDed section and uses that GUID to select an associated handler of type EXTRACT_GUIDED_SECTION_DECODE_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers(). The selected handler is used to decode the data in a GUIDed section and return the result in a caller allocated output buffer. Decodes the GUIDed section specified by InputSection. If GUID for InputSection does not match any of the GUIDs registered through ExtractGuidedSectionRegisterHandlers(), then RETURN_UNSUPPORTED is returned. If the GUID of InputSection does match the GUID that this handler supports, then the the associated handler of type EXTRACT_GUIDED_SECTION_DECODE_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers() is used to decode InputSection into the buffer specified by OutputBuffer and the authentication status of this decode operation is returned in AuthenticationStatus. If the decoded buffer is identical to the data in InputSection, then OutputBuffer is set to point at the data in InputSection. Otherwise, the decoded data will be placed in a caller allocated buffer specified by OutputBuffer. This function is responsible for computing the EFI_AUTH_STATUS_PLATFORM_OVERRIDE bit of in AuthenticationStatus. The return status from the handler of type EXTRACT_GUIDED_SECTION_DECODE_HANDLER is returned. If InputSection is NULL, then ASSERT(). If OutputBuffer is NULL, then ASSERT(). If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT(). If AuthenticationStatus is NULL, then ASSERT(). @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file. @param[out] OutputBuffer A pointer to a buffer that contains the result of a decode operation. @param[in] ScratchBuffer A caller allocated buffer that may be required by this function as a scratch buffer to perform the decode operation. @param[out] AuthenticationStatus A pointer to the authentication status of the decoded output buffer. See the definition of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI section of the PI Specification. @retval RETURN_SUCCESS The buffer specified by InputSection was decoded. @retval RETURN_UNSUPPORTED The section specified by InputSection does not match the GUID this handler supports. @retval RETURN_INVALID_PARAMETER The section specified by InputSection can not be decoded. **/ RETURN_STATUS EFIAPI ExtractGuidedSectionDecode ( IN CONST VOID *InputSection, OUT VOID **OutputBuffer, IN VOID *ScratchBuffer, OPTIONAL OUT UINT32 *AuthenticationStatus ) { UINT32 Index; RETURN_STATUS Status; EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo; EFI_GUID *SectionDefinitionGuid; // // Check input parameter // ASSERT (InputSection != NULL); ASSERT (OutputBuffer != NULL); ASSERT (AuthenticationStatus != NULL); // // Get all registered handler information. // Status = GetExtractGuidedSectionHandlerInfo (&HandlerInfo); if (RETURN_ERROR (Status)) { return Status; } if (IS_SECTION2 (InputSection)) { SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid); } else { SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid); } // // Search the match registered Extract handler for the input guided section. // ASSERT (HandlerInfo != NULL); for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) { if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionDefinitionGuid)) { // // Call the match handler to extract raw data for the input guided section. // return HandlerInfo->ExtractDecodeHandlerTable [Index] ( InputSection, OutputBuffer, ScratchBuffer, AuthenticationStatus ); } } // // Not found, the input guided section is not supported. // return RETURN_UNSUPPORTED; }
RETURN_STATUS EFIAPI ExtractGuidedSectionGetInfo ( IN CONST VOID *InputSection, OUT UINT32 *OutputBufferSize, OUT UINT32 *ScratchBufferSize, OUT UINT16 *SectionAttribute ) { PRE_PI_EXTRACT_GUIDED_SECTION_DATA *SavedData; UINT32 Index; EFI_GUID *SectionDefinitionGuid; if (InputSection == NULL) { return RETURN_INVALID_PARAMETER; } ASSERT (OutputBufferSize != NULL); ASSERT (ScratchBufferSize != NULL); ASSERT (SectionAttribute != NULL); SavedData = GetSavedData(); if (IS_SECTION2 (InputSection)) { SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid); } else { SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid); } // // Search the match registered GetInfo handler for the input guided section. // for (Index = 0; Index < SavedData->NumberOfExtractHandler; Index ++) { if (CompareGuid (&SavedData->ExtractHandlerGuidTable[Index], SectionDefinitionGuid)) { break; } } // // Not found, the input guided section is not supported. // if (Index == SavedData->NumberOfExtractHandler) { return RETURN_INVALID_PARAMETER; } // // Call the match handler to getinfo for the input section data. // return SavedData->ExtractGetInfoHandlerTable [Index] ( InputSection, OutputBufferSize, ScratchBufferSize, SectionAttribute ); }
/** Get Section buffer pointer by SectionType and SectionInstance. @param[in] SectionBuffer The buffer of section @param[in] SectionBufferSize The size of SectionBuffer in bytes @param[in] SectionType The SectionType of Section to be found @param[in] SectionInstance The Instance of Section to be found @param[out] OutSectionBuffer The section found, including SECTION_HEADER @param[out] OutSectionSize The size of section found, including SECTION_HEADER @retval TRUE The FFS buffer is found. @retval FALSE The FFS buffer is not found. **/ BOOLEAN GetSectionByType ( IN VOID *SectionBuffer, IN UINT32 SectionBufferSize, IN EFI_SECTION_TYPE SectionType, IN UINTN SectionInstance, OUT VOID **OutSectionBuffer, OUT UINTN *OutSectionSize ) { EFI_COMMON_SECTION_HEADER *SectionHeader; UINTN SectionSize; UINTN Instance; DEBUG ((DEBUG_INFO, "GetSectionByType - Buffer: 0x%08x - 0x%08x\n", SectionBuffer, SectionBufferSize)); // // Find Section // SectionHeader = SectionBuffer; Instance = 0; while ((UINTN)SectionHeader < (UINTN)SectionBuffer + SectionBufferSize) { DEBUG ((DEBUG_INFO, "GetSectionByType - Section: 0x%08x\n", SectionHeader)); if (IS_SECTION2(SectionHeader)) { SectionSize = SECTION2_SIZE(SectionHeader); } else { SectionSize = SECTION_SIZE(SectionHeader); } if (SectionHeader->Type == SectionType) { if (Instance == SectionInstance) { *OutSectionBuffer = (UINT8 *)SectionHeader; *OutSectionSize = SectionSize; DEBUG((DEBUG_INFO, "GetSectionByType - 0x%x - 0x%x\n", *OutSectionBuffer, *OutSectionSize)); return TRUE; } else { DEBUG((DEBUG_INFO, "GetSectionByType - find section instance %x\n", Instance)); Instance++; } } else { // // Skip other section type // DEBUG ((DEBUG_INFO, "GetSectionByType - other section type 0x%x\n", SectionHeader->Type)); } // // Next Section // SectionHeader = (EFI_COMMON_SECTION_HEADER *)((UINTN)SectionHeader + ALIGN_VALUE(SectionSize, 4)); } return FALSE; }
/** Decompress a LZAM compressed GUIDed section into a caller allocated output buffer. Decodes the GUIDed section specified by InputSection. If GUID for InputSection does not match the GUID that this handler supports, then RETURN_UNSUPPORTED is returned. If the data in InputSection can not be decoded, then RETURN_INVALID_PARAMETER is returned. If the GUID of InputSection does match the GUID that this handler supports, then InputSection is decoded into the buffer specified by OutputBuffer and the authentication status of this decode operation is returned in AuthenticationStatus. If the decoded buffer is identical to the data in InputSection, then OutputBuffer is set to point at the data in InputSection. Otherwise, the decoded data will be placed in caller allocated buffer specified by OutputBuffer. If InputSection is NULL, then ASSERT(). If OutputBuffer is NULL, then ASSERT(). If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT(). If AuthenticationStatus is NULL, then ASSERT(). @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file. @param[out] OutputBuffer A pointer to a buffer that contains the result of a decode operation. @param[out] ScratchBuffer A caller allocated buffer that may be required by this function as a scratch buffer to perform the decode operation. @param[out] AuthenticationStatus A pointer to the authentication status of the decoded output buffer. See the definition of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI section of the PI Specification. EFI_AUTH_STATUS_PLATFORM_OVERRIDE must never be set by this handler. @retval RETURN_SUCCESS The buffer specified by InputSection was decoded. @retval RETURN_UNSUPPORTED The section specified by InputSection does not match the GUID this handler supports. @retval RETURN_INVALID_PARAMETER The section specified by InputSection can not be decoded. **/ RETURN_STATUS EFIAPI LzmaGuidedSectionExtraction ( IN CONST VOID *InputSection, OUT VOID **OutputBuffer, OUT VOID *ScratchBuffer, OPTIONAL OUT UINT32 *AuthenticationStatus ) { ASSERT (OutputBuffer != NULL); ASSERT (InputSection != NULL); if (IS_SECTION2 (InputSection)) { if (!CompareGuid ( &gLzmaCustomDecompressGuid, &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid))) { return RETURN_INVALID_PARAMETER; } // // Authentication is set to Zero, which may be ignored. // *AuthenticationStatus = 0; return LzmaUefiDecompress ( (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset, SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset, *OutputBuffer, ScratchBuffer ); } else { if (!CompareGuid ( &gLzmaCustomDecompressGuid, &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) { return RETURN_INVALID_PARAMETER; } // // Authentication is set to Zero, which may be ignored. // *AuthenticationStatus = 0; return LzmaUefiDecompress ( (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset, SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset, *OutputBuffer, ScratchBuffer ); } }
/** Examines a GUIDed section and returns the size of the decoded buffer and the size of an scratch buffer required to actually decode the data in a GUIDed section. Examines a GUIDed section specified by InputSection. If GUID for InputSection does not match the GUID that this handler supports, then RETURN_UNSUPPORTED is returned. If the required information can not be retrieved from InputSection, then RETURN_INVALID_PARAMETER is returned. If the GUID of InputSection does match the GUID that this handler supports, then the size required to hold the decoded buffer is returned in OututBufferSize, the size of an optional scratch buffer is returned in ScratchSize, and the Attributes field from EFI_GUID_DEFINED_SECTION header of InputSection is returned in SectionAttribute. If InputSection is NULL, then ASSERT(). If OutputBufferSize is NULL, then ASSERT(). If ScratchBufferSize is NULL, then ASSERT(). If SectionAttribute is NULL, then ASSERT(). @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file. @param[out] OutputBufferSize A pointer to the size, in bytes, of an output buffer required if the buffer specified by InputSection were decoded. @param[out] ScratchBufferSize A pointer to the size, in bytes, required as scratch space if the buffer specified by InputSection were decoded. @param[out] SectionAttribute A pointer to the attributes of the GUIDed section. See the Attributes field of EFI_GUID_DEFINED_SECTION in the PI Specification. @retval RETURN_SUCCESS The information about InputSection was returned. @retval RETURN_UNSUPPORTED The section specified by InputSection does not match the GUID this handler supports. @retval RETURN_INVALID_PARAMETER The information can not be retrieved from the section specified by InputSection. **/ RETURN_STATUS EFIAPI LzmaGuidedSectionGetInfo ( IN CONST VOID *InputSection, OUT UINT32 *OutputBufferSize, OUT UINT32 *ScratchBufferSize, OUT UINT16 *SectionAttribute ) { ASSERT (InputSection != NULL); ASSERT (OutputBufferSize != NULL); ASSERT (ScratchBufferSize != NULL); ASSERT (SectionAttribute != NULL); if (IS_SECTION2 (InputSection)) { if (!CompareGuid ( &gLzmaCustomDecompressGuid, &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid))) { return RETURN_INVALID_PARAMETER; } *SectionAttribute = ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->Attributes; return LzmaUefiDecompressGetInfo ( (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset, SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset, OutputBufferSize, ScratchBufferSize ); } else { if (!CompareGuid ( &gLzmaCustomDecompressGuid, &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) { return RETURN_INVALID_PARAMETER; } *SectionAttribute = ((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes; return LzmaUefiDecompressGetInfo ( (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset, SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset, OutputBufferSize, ScratchBufferSize ); } }
/** GetInfo gets raw data size and attribute of the input guided section. It first checks whether the input guid section is supported. If not, EFI_INVALID_PARAMETER will return. @param InputSection Buffer containing the input GUIDed section to be processed. @param OutputBufferSize The size of OutputBuffer. @param ScratchBufferSize The size of ScratchBuffer. @param SectionAttribute The attribute of the input guided section. @retval EFI_SUCCESS The size of destination buffer, the size of scratch buffer and the attribute of the input section are successull retrieved. @retval EFI_INVALID_PARAMETER The GUID in InputSection does not match this instance guid. **/ EFI_STATUS EFIAPI Rsa2048Sha256GuidedSectionGetInfo ( IN CONST VOID *InputSection, OUT UINT32 *OutputBufferSize, OUT UINT32 *ScratchBufferSize, OUT UINT16 *SectionAttribute ) { if (IS_SECTION2 (InputSection)) { // // Check whether the input guid section is recognized. // if (!CompareGuid ( &gEfiCertTypeRsa2048Sha256Guid, &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid))) { return EFI_INVALID_PARAMETER; } // // Retrieve the size and attribute of the input section data. // *SectionAttribute = ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->Attributes; *ScratchBufferSize = 0; *OutputBufferSize = SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset; } else { // // Check whether the input guid section is recognized. // if (!CompareGuid ( &gEfiCertTypeRsa2048Sha256Guid, &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) { return EFI_INVALID_PARAMETER; } // // Retrieve the size and attribute of the input section data. // *SectionAttribute = ((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes; *ScratchBufferSize = 0; *OutputBufferSize = SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset; } return EFI_SUCCESS; }
/** Extract ImageFmpInfo from system firmware. @param[in] SystemFirmwareImage The System Firmware image. @param[in] SystemFirmwareImageSize The size of the System Firmware image in bytes. @param[out] ImageFmpInfo The ImageFmpInfo. @param[out] ImageFmpInfoSize The size of the ImageFmpInfo in bytes. @retval TRUE The ImageFmpInfo is extracted. @retval FALSE The ImageFmpInfo is not extracted. **/ BOOLEAN EFIAPI ExtractSystemFirmwareImageFmpInfo ( IN VOID *SystemFirmwareImage, IN UINTN SystemFirmwareImageSize, OUT EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR **ImageFmpInfo, OUT UINTN *ImageFmpInfoSize ) { BOOLEAN Result; UINT32 SectionHeaderSize; UINT32 FileHeaderSize; *ImageFmpInfo = NULL; *ImageFmpInfoSize = 0; Result = GetFfsByName(SystemFirmwareImage, SystemFirmwareImageSize, &gEdkiiSystemFirmwareImageDescriptorFileGuid, EFI_FV_FILETYPE_ALL, (VOID **)ImageFmpInfo, ImageFmpInfoSize); if (!Result) { return FALSE; } if (IS_FFS_FILE2 (*ImageFmpInfo)) { FileHeaderSize = sizeof(EFI_FFS_FILE_HEADER2); } else { FileHeaderSize = sizeof(EFI_FFS_FILE_HEADER); } *ImageFmpInfo = (VOID *)((UINT8 *)*ImageFmpInfo + FileHeaderSize); *ImageFmpInfoSize = *ImageFmpInfoSize - FileHeaderSize; Result = GetSectionByType(*ImageFmpInfo, (UINT32)*ImageFmpInfoSize, EFI_SECTION_RAW, 0, (VOID **)ImageFmpInfo, ImageFmpInfoSize); if (!Result) { return FALSE; } if (IS_SECTION2(*ImageFmpInfo)) { SectionHeaderSize = sizeof(EFI_RAW_SECTION2); } else { SectionHeaderSize = sizeof(EFI_RAW_SECTION); } *ImageFmpInfo = (VOID *)((UINT8 *)*ImageFmpInfo + SectionHeaderSize); *ImageFmpInfoSize = *ImageFmpInfoSize - SectionHeaderSize; return TRUE; }
/** Decompresses a section to the output buffer. This function looks up the compression type field in the input section and applies the appropriate compression algorithm to compress the section to a callee allocated buffer. @param This Points to this instance of the EFI_PEI_DECOMPRESS_PEI PPI. @param CompressionSection Points to the compressed section. @param OutputBuffer Holds the returned pointer to the decompressed sections. @param OutputSize Holds the returned size of the decompress section streams. @retval EFI_SUCCESS The section was decompressed successfully. OutputBuffer contains the resulting data and OutputSize contains the resulting size. **/ EFI_STATUS EFIAPI Decompress ( IN CONST EFI_PEI_DECOMPRESS_PPI *This, IN CONST EFI_COMPRESSION_SECTION *CompressionSection, OUT VOID **OutputBuffer, OUT UINTN *OutputSize ) { EFI_STATUS Status; UINT8 *DstBuffer; UINT8 *ScratchBuffer; UINT32 DstBufferSize; UINT32 ScratchBufferSize; VOID *CompressionSource; UINT32 CompressionSourceSize; UINT32 UncompressedLength; UINT8 CompressionType; if (CompressionSection->CommonHeader.Type != EFI_SECTION_COMPRESSION) { ASSERT (FALSE); return EFI_INVALID_PARAMETER; } if (IS_SECTION2 (CompressionSection)) { CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION2)); CompressionSourceSize = (UINT32) (SECTION2_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION2)); UncompressedLength = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->UncompressedLength; CompressionType = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->CompressionType; } else { CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION)); CompressionSourceSize = (UINT32) (SECTION_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION)); UncompressedLength = CompressionSection->UncompressedLength; CompressionType = CompressionSection->CompressionType; } // // This is a compression set, expand it // switch (CompressionType) { case EFI_STANDARD_COMPRESSION: if (FeaturePcdGet(PcdDxeIplSupportUefiDecompress)) { // // Load EFI standard compression. // For compressed data, decompress them to destination buffer. // Status = UefiDecompressGetInfo ( CompressionSource, CompressionSourceSize, &DstBufferSize, &ScratchBufferSize ); if (EFI_ERROR (Status)) { // // GetInfo failed // DEBUG ((DEBUG_ERROR, "Decompress GetInfo Failed - %r\n", Status)); return EFI_NOT_FOUND; } // // Allocate scratch buffer // ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize)); if (ScratchBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } // // Allocate destination buffer, extra one page for adjustment // DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1); if (DstBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } // // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header // to make section data at page alignment. // DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER); // // Call decompress function // Status = UefiDecompress ( CompressionSource, DstBuffer, ScratchBuffer ); if (EFI_ERROR (Status)) { // // Decompress failed // DEBUG ((DEBUG_ERROR, "Decompress Failed - %r\n", Status)); return EFI_NOT_FOUND; } break; } else { // // PcdDxeIplSupportUefiDecompress is FALSE // Don't support UEFI decompression algorithm. // ASSERT (FALSE); return EFI_NOT_FOUND; } case EFI_NOT_COMPRESSED: // // Allocate destination buffer // DstBufferSize = UncompressedLength; DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1); if (DstBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } // // Adjust DstBuffer offset, skip EFI section header // to make section data at page alignment. // DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER); // // stream is not actually compressed, just encapsulated. So just copy it. // CopyMem (DstBuffer, CompressionSource, DstBufferSize); break; default: // // Don't support other unknown compression type. // ASSERT (FALSE); return EFI_NOT_FOUND; } *OutputSize = DstBufferSize; *OutputBuffer = DstBuffer; return EFI_SUCCESS; }
/** Extraction handler tries to extract raw data from the input guided section. It also does authentication check for RSA 2048 SHA 256 signature in the input guided section. It first checks whether the input guid section is supported. If not, EFI_INVALID_PARAMETER will return. @param InputSection Buffer containing the input GUIDed section to be processed. @param OutputBuffer Buffer to contain the output raw data allocated by the caller. @param ScratchBuffer A pointer to a caller-allocated buffer for function internal use. @param AuthenticationStatus A pointer to a caller-allocated UINT32 that indicates the authentication status of the output buffer. @retval EFI_SUCCESS Section Data and Auth Status is extracted successfully. @retval EFI_INVALID_PARAMETER The GUID in InputSection does not match this instance guid. **/ EFI_STATUS EFIAPI Rsa2048Sha256GuidedSectionHandler ( IN CONST VOID *InputSection, OUT VOID **OutputBuffer, IN VOID *ScratchBuffer, OPTIONAL OUT UINT32 *AuthenticationStatus ) { EFI_STATUS Status; UINT32 OutputBufferSize; VOID *DummyInterface; EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlockRsa2048Sha256; BOOLEAN CryptoStatus; UINT8 Digest[SHA256_DIGEST_SIZE]; UINT8 *PublicKey; UINTN PublicKeyBufferSize; VOID *HashContext; VOID *Rsa; HashContext = NULL; Rsa = NULL; if (IS_SECTION2 (InputSection)) { // // Check whether the input guid section is recognized. // if (!CompareGuid ( &gEfiCertTypeRsa2048Sha256Guid, &(((EFI_GUID_DEFINED_SECTION2 *)InputSection)->SectionDefinitionGuid))) { return EFI_INVALID_PARAMETER; } // // Get the RSA 2048 SHA 256 information. // CertBlockRsa2048Sha256 = &((RSA_2048_SHA_256_SECTION2_HEADER *) InputSection)->CertBlockRsa2048Sha256; OutputBufferSize = SECTION2_SIZE (InputSection) - sizeof (RSA_2048_SHA_256_SECTION2_HEADER); if ((((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) { PERF_START (NULL, "RsaCopy", "DXE", 0); CopyMem (*OutputBuffer, (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION2_HEADER), OutputBufferSize); PERF_END (NULL, "RsaCopy", "DXE", 0); } else { *OutputBuffer = (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION2_HEADER); } // // Implicitly RSA 2048 SHA 256 GUIDed section should have STATUS_VALID bit set // ASSERT ((((EFI_GUID_DEFINED_SECTION2 *)InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0); *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED; } else { // // Check whether the input guid section is recognized. // if (!CompareGuid ( &gEfiCertTypeRsa2048Sha256Guid, &(((EFI_GUID_DEFINED_SECTION *)InputSection)->SectionDefinitionGuid))) { return EFI_INVALID_PARAMETER; } // // Get the RSA 2048 SHA 256 information. // CertBlockRsa2048Sha256 = &((RSA_2048_SHA_256_SECTION_HEADER *)InputSection)->CertBlockRsa2048Sha256; OutputBufferSize = SECTION_SIZE (InputSection) - sizeof (RSA_2048_SHA_256_SECTION_HEADER); if ((((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) { PERF_START (NULL, "RsaCopy", "DXE", 0); CopyMem (*OutputBuffer, (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION_HEADER), OutputBufferSize); PERF_END (NULL, "RsaCopy", "DXE", 0); } else { *OutputBuffer = (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION_HEADER); } // // Implicitly RSA 2048 SHA 256 GUIDed section should have STATUS_VALID bit set // ASSERT ((((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0); *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED; } // // Check whether there exists EFI_SECURITY_POLICY_PROTOCOL_GUID. // Status = gBS->LocateProtocol (&gEfiSecurityPolicyProtocolGuid, NULL, &DummyInterface); if (!EFI_ERROR (Status)) { // // If SecurityPolicy Protocol exist, AUTH platform override bit is set. // *AuthenticationStatus |= EFI_AUTH_STATUS_PLATFORM_OVERRIDE; return EFI_SUCCESS; } // // All paths from here return EFI_SUCESS and result is returned in AuthenticationStatus // Status = EFI_SUCCESS; // // Fail if the HashType is not SHA 256 // if (!CompareGuid (&gEfiHashAlgorithmSha256Guid, &CertBlockRsa2048Sha256->HashType)) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: HASH type of section is not supported\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Allocate hash context buffer required for SHA 256 // HashContext = AllocatePool (Sha256GetContextSize ()); if (HashContext == NULL) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Can not allocate hash context\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Hash public key from data payload with SHA256. // ZeroMem (Digest, SHA256_DIGEST_SIZE); CryptoStatus = Sha256Init (HashContext); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Init() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } CryptoStatus = Sha256Update (HashContext, &CertBlockRsa2048Sha256->PublicKey, sizeof(CertBlockRsa2048Sha256->PublicKey)); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Update() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } CryptoStatus = Sha256Final (HashContext, Digest); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Final() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Fail if the PublicKey is not one of the public keys in PcdRsa2048Sha256PublicKeyBuffer // PublicKey = (UINT8 *)PcdGetPtr (PcdRsa2048Sha256PublicKeyBuffer); DEBUG ((DEBUG_VERBOSE, "DxePcdRsa2048Sha256: PublicKeyBuffer = %p\n", PublicKey)); ASSERT (PublicKey != NULL); DEBUG ((DEBUG_VERBOSE, "DxePcdRsa2048Sha256: PublicKeyBuffer Token = %08x\n", PcdToken (PcdRsa2048Sha256PublicKeyBuffer))); PublicKeyBufferSize = LibPcdGetExSize (&gEfiSecurityPkgTokenSpaceGuid, PcdToken (PcdRsa2048Sha256PublicKeyBuffer)); DEBUG ((DEBUG_VERBOSE, "DxePcdRsa2048Sha256: PublicKeyBuffer Size = %08x\n", PublicKeyBufferSize)); ASSERT ((PublicKeyBufferSize % SHA256_DIGEST_SIZE) == 0); CryptoStatus = FALSE; while (PublicKeyBufferSize != 0) { if (CompareMem (Digest, PublicKey, SHA256_DIGEST_SIZE) == 0) { CryptoStatus = TRUE; break; } PublicKey = PublicKey + SHA256_DIGEST_SIZE; PublicKeyBufferSize = PublicKeyBufferSize - SHA256_DIGEST_SIZE; } if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Public key in section is not supported\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Generate & Initialize RSA Context. // Rsa = RsaNew (); if (Rsa == NULL) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaNew() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Set RSA Key Components. // NOTE: Only N and E are needed to be set as RSA public key for signature verification. // CryptoStatus = RsaSetKey (Rsa, RsaKeyN, CertBlockRsa2048Sha256->PublicKey, sizeof(CertBlockRsa2048Sha256->PublicKey)); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaSetKey(RsaKeyN) failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } CryptoStatus = RsaSetKey (Rsa, RsaKeyE, mRsaE, sizeof (mRsaE)); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaSetKey(RsaKeyE) failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Hash data payload with SHA256. // ZeroMem (Digest, SHA256_DIGEST_SIZE); CryptoStatus = Sha256Init (HashContext); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Init() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } PERF_START (NULL, "RsaShaData", "DXE", 0); CryptoStatus = Sha256Update (HashContext, *OutputBuffer, OutputBufferSize); PERF_END (NULL, "RsaShaData", "DXE", 0); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Update() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } CryptoStatus = Sha256Final (HashContext, Digest); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Final() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Verify the RSA 2048 SHA 256 signature. // PERF_START (NULL, "RsaVerify", "DXE", 0); CryptoStatus = RsaPkcs1Verify ( Rsa, Digest, SHA256_DIGEST_SIZE, CertBlockRsa2048Sha256->Signature, sizeof (CertBlockRsa2048Sha256->Signature) ); PERF_END (NULL, "RsaVerify", "DXE", 0); if (!CryptoStatus) { // // If RSA 2048 SHA 256 signature verification fails, AUTH tested failed bit is set. // DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaPkcs1Verify() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; } Done: // // Free allocated resources used to perform RSA 2048 SHA 256 signature verification // if (Rsa != NULL) { RsaFree (Rsa); } if (HashContext != NULL) { FreePool (HashContext); } DEBUG ((DEBUG_VERBOSE, "DxeRsa2048Sha256: Status = %r AuthenticationStatus = %08x\n", Status, *AuthenticationStatus)); return Status; }
/** Find core image base. @param[in] BootFirmwareVolumePtr Point to the boot firmware volume. @param[out] SecCoreImageBase The base address of the SEC core image. @param[out] PeiCoreImageBase The base address of the PEI core image. **/ EFI_STATUS EFIAPI FindImageBase ( IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr, OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase, OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase ) { EFI_PHYSICAL_ADDRESS CurrentAddress; EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume; EFI_FFS_FILE_HEADER *File; UINT32 Size; EFI_PHYSICAL_ADDRESS EndOfFile; EFI_COMMON_SECTION_HEADER *Section; EFI_PHYSICAL_ADDRESS EndOfSection; *SecCoreImageBase = 0; *PeiCoreImageBase = 0; CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) BootFirmwareVolumePtr; EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr->FvLength; // // Loop through the FFS files in the Boot Firmware Volume // for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; ) { CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL; if (CurrentAddress > EndOfFirmwareVolume) { return EFI_NOT_FOUND; } File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress; if (IS_FFS_FILE2 (File)) { Size = FFS_FILE2_SIZE (File); if (Size <= 0x00FFFFFF) { return EFI_NOT_FOUND; } } else { Size = FFS_FILE_SIZE (File); if (Size < sizeof (EFI_FFS_FILE_HEADER)) { return EFI_NOT_FOUND; } } EndOfFile = CurrentAddress + Size; if (EndOfFile > EndOfFirmwareVolume) { return EFI_NOT_FOUND; } // // Look for SEC Core / PEI Core files // if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE && File->Type != EFI_FV_FILETYPE_PEI_CORE) { continue; } // // Loop through the FFS file sections within the FFS file // if (IS_FFS_FILE2 (File)) { EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof (EFI_FFS_FILE_HEADER2)); } else { EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof (EFI_FFS_FILE_HEADER)); } for (;;) { CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL; Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress; if (IS_SECTION2 (Section)) { Size = SECTION2_SIZE (Section); if (Size <= 0x00FFFFFF) { return EFI_NOT_FOUND; } } else { Size = SECTION_SIZE (Section); if (Size < sizeof (EFI_COMMON_SECTION_HEADER)) { return EFI_NOT_FOUND; } } EndOfSection = CurrentAddress + Size; if (EndOfSection > EndOfFile) { return EFI_NOT_FOUND; } // // Look for executable sections // if (Section->Type == EFI_SECTION_PE32 || Section->Type == EFI_SECTION_TE) { if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) { if (IS_SECTION2 (Section)) { *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2)); } else { *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER)); } } else { if (IS_SECTION2 (Section)) { *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2)); } else { *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER)); } } break; } } // // Both SEC Core and PEI Core images found // if (*SecCoreImageBase != 0 && *PeiCoreImageBase != 0) { return EFI_SUCCESS; } } }
/** Extraction handler tries to extract raw data from the input guided section. It also does authentication check for 32bit CRC value in the input guided section. It first checks whether the input guid section is supported. If not, EFI_INVALID_PARAMETER will return. @param InputSection Buffer containing the input GUIDed section to be processed. @param OutputBuffer Buffer to contain the output raw data allocated by the caller. @param ScratchBuffer A pointer to a caller-allocated buffer for function internal use. @param AuthenticationStatus A pointer to a caller-allocated UINT32 that indicates the authentication status of the output buffer. @retval EFI_SUCCESS Section Data and Auth Status is extracted successfully. @retval EFI_INVALID_PARAMETER The GUID in InputSection does not match this instance guid. **/ EFI_STATUS EFIAPI Crc32GuidedSectionHandler ( IN CONST VOID *InputSection, OUT VOID **OutputBuffer, IN VOID *ScratchBuffer, OPTIONAL OUT UINT32 *AuthenticationStatus ) { EFI_STATUS Status; UINT32 SectionCrc32Checksum; UINT32 Crc32Checksum; UINT32 OutputBufferSize; VOID *DummyInterface; if (IS_SECTION2 (InputSection)) { // // Check whether the input guid section is recognized. // if (!CompareGuid ( &gEfiCrc32GuidedSectionExtractionGuid, &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid))) { return EFI_INVALID_PARAMETER; } // // Get section Crc32 checksum. // SectionCrc32Checksum = ((CRC32_SECTION2_HEADER *) InputSection)->CRC32Checksum; *OutputBuffer = (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset; OutputBufferSize = SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset; // // Implicitly CRC32 GUIDed section should have STATUS_VALID bit set // ASSERT (((EFI_GUID_DEFINED_SECTION2 *) InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID); *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED; } else { // // Check whether the input guid section is recognized. // if (!CompareGuid ( &gEfiCrc32GuidedSectionExtractionGuid, &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) { return EFI_INVALID_PARAMETER; } // // Get section Crc32 checksum. // SectionCrc32Checksum = ((CRC32_SECTION_HEADER *) InputSection)->CRC32Checksum; *OutputBuffer = (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset; OutputBufferSize = SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset; // // Implicitly CRC32 GUIDed section should have STATUS_VALID bit set // ASSERT (((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID); *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED; } // // Init Checksum value to Zero. // Crc32Checksum = 0; // // Check whether there exists EFI_SECURITY_POLICY_PROTOCOL_GUID. // Status = gBS->LocateProtocol (&gEfiSecurityPolicyProtocolGuid, NULL, &DummyInterface); if (!EFI_ERROR (Status)) { // // If SecurityPolicy Protocol exist, AUTH platform override bit is set. // *AuthenticationStatus |= EFI_AUTH_STATUS_PLATFORM_OVERRIDE; } else { // // Calculate CRC32 Checksum of Image // Status = gBS->CalculateCrc32 (*OutputBuffer, OutputBufferSize, &Crc32Checksum); if (Status == EFI_SUCCESS) { if (Crc32Checksum != SectionCrc32Checksum) { // // If Crc32 checksum is not matched, AUTH tested failed bit is set. // *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; } } else { // // If Crc32 checksum is not calculated, AUTH not tested bit is set. // *AuthenticationStatus |= EFI_AUTH_STATUS_NOT_TESTED; } } return EFI_SUCCESS; }
/** Extraction handler tries to extract raw data from the input guided section. It also does authentication check for 32bit CRC value in the input guided section. It first checks whether the input guid section is supported. If not, EFI_INVALID_PARAMETER will return. @param InputSection Buffer containing the input GUIDed section to be processed. @param OutputBuffer Buffer to contain the output raw data allocated by the caller. @param ScratchBuffer A pointer to a caller-allocated buffer for function internal use. @param AuthenticationStatus A pointer to a caller-allocated UINT32 that indicates the authentication status of the output buffer. @retval EFI_SUCCESS Section Data and Auth Status is extracted successfully. @retval EFI_INVALID_PARAMETER The GUID in InputSection does not match this instance guid. **/ EFI_STATUS EFIAPI Crc32GuidedSectionHandler ( IN CONST VOID *InputSection, OUT VOID **OutputBuffer, IN VOID *ScratchBuffer, OPTIONAL OUT UINT32 *AuthenticationStatus ) { UINT32 SectionCrc32Checksum; UINT32 Crc32Checksum; UINT32 OutputBufferSize; if (IS_SECTION2 (InputSection)) { // // Check whether the input guid section is recognized. // if (!CompareGuid ( &gEfiCrc32GuidedSectionExtractionGuid, &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid))) { return EFI_INVALID_PARAMETER; } // // Get section Crc32 checksum. // SectionCrc32Checksum = ((CRC32_SECTION2_HEADER *) InputSection)->CRC32Checksum; *OutputBuffer = (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset; OutputBufferSize = SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset; // // Implicitly CRC32 GUIDed section should have STATUS_VALID bit set // ASSERT (((EFI_GUID_DEFINED_SECTION2 *) InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID); *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED; } else { // // Check whether the input guid section is recognized. // if (!CompareGuid ( &gEfiCrc32GuidedSectionExtractionGuid, &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) { return EFI_INVALID_PARAMETER; } // // Get section Crc32 checksum. // SectionCrc32Checksum = ((CRC32_SECTION_HEADER *) InputSection)->CRC32Checksum; *OutputBuffer = (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset; OutputBufferSize = SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset; // // Implicitly CRC32 GUIDed section should have STATUS_VALID bit set // ASSERT (((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID); *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED; } // // Calculate CRC32 Checksum of Image // Crc32Checksum = CalculateCrc32 (*OutputBuffer, OutputBufferSize); if (Crc32Checksum != SectionCrc32Checksum) { // // If Crc32 checksum is not matched, AUTH tested failed bit is set. // *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; } // // Temp solution until PeiCore checks AUTH Status. // if ((*AuthenticationStatus & (EFI_AUTH_STATUS_TEST_FAILED | EFI_AUTH_STATUS_NOT_TESTED)) != 0) { return EFI_ACCESS_DENIED; } return EFI_SUCCESS; }