X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FLibrary%2FDxeCrc32GuidedSectionExtractLib%2FDxeCrc32GuidedSectionExtractLib.c;h=048b4ff389645067e47577b557f0f6b1bd1d82ff;hb=9d510e61fceee7b92955ef9a3c20343752d8ce3f;hp=8e2cc0201f55d1a4a41d5eb3733ed7b2986a85de;hpb=e6c560aad63b09e6aaee3ccc65be462651772fe5;p=mirror_edk2.git diff --git a/MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.c b/MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.c index 8e2cc0201f..048b4ff389 100644 --- a/MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.c +++ b/MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.c @@ -1,40 +1,51 @@ -/*++ +/** @file -Copyright (c) 2007, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + This library registers CRC32 guided section handler + to parse CRC32 encapsulation section and extract raw data. + It uses UEFI boot service CalculateCrc32 to authenticate 32 bit CRC value. -Module Name: +Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent - DxeCrc32GuidedSectionExtractLib.c - -Abstract: - - Implements GUIDed section extraction protocol interface with - a specific GUID: CRC32. - - Please refer to the Framewokr Firmware Volume Specification 0.9. - ---*/ +**/ #include -#include +#include #include #include #include #include #include +/// +/// CRC32 Guided Section header +/// typedef struct { - EFI_GUID_DEFINED_SECTION GuidedSectionHeader; - UINT32 CRC32Checksum; + EFI_GUID_DEFINED_SECTION GuidedSectionHeader; ///< EFI guided section header + UINT32 CRC32Checksum; ///< 32bit CRC check sum } CRC32_SECTION_HEADER; +typedef struct { + EFI_GUID_DEFINED_SECTION2 GuidedSectionHeader; ///< EFI guided section header + UINT32 CRC32Checksum; ///< 32bit CRC check sum +} CRC32_SECTION2_HEADER; + +/** + + 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 successfully retrieved. + @retval EFI_INVALID_PARAMETER The GUID in InputSection does not match this instance guid. + +**/ EFI_STATUS EFIAPI Crc32GuidedSectionGetInfo ( @@ -43,42 +54,59 @@ Crc32GuidedSectionGetInfo ( OUT UINT32 *ScratchBufferSize, OUT UINT16 *SectionAttribute ) -/*++ - -Routine Description: - - The implementation of Crc32 guided section GetInfo(). - -Arguments: - InputSection Buffer containing the input GUIDed section to be processed. - OutputBufferSize The size of OutputBuffer. - ScratchBufferSize The size of ScratchBuffer. - SectionAttribute The attribute of the input guided section. - -Returns: - - EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved. - EFI_INVALID_PARAMETER - The source data is corrupted, or - The GUID in InputSection does not match this instance guid. - ---*/ { - if (!CompareGuid ( - &gEfiCrc32GuidedSectionExtractionProtocolGuid, + 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; + } + // + // 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 ( + &gEfiCrc32GuidedSectionExtractionGuid, &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) { - return EFI_INVALID_PARAMETER; + 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; } - // - // Retrieve the size and attribute of the input section data. - // - *SectionAttribute = ((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes; - *ScratchBufferSize = 0; - *OutputBufferSize = *(UINT32 *) (((EFI_COMMON_SECTION_HEADER *) InputSection)->Size) & 0x00ffffff; - *OutputBufferSize -= ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset; 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 ( @@ -87,61 +115,72 @@ Crc32GuidedSectionHandler ( IN VOID *ScratchBuffer, OPTIONAL OUT UINT32 *AuthenticationStatus ) -/*++ - -Routine Description: - - The implementation of Crc32 Guided section extraction. - -Arguments: - InputSection Buffer containing the input GUIDed section to be processed. - OutputBuffer OutputBuffer to point to the start of the section's contents. - if guided data is not prcessed. Otherwise, - OutputBuffer to contain the output data, which is allocated by the caller. - ScratchBuffer A pointer to a caller-allocated buffer for function internal use. - AuthenticationStatus A pointer to a caller-allocated UINT32 that indicates the - authentication status of the output buffer. - -Returns: - - RETURN_SUCCESS - Decompression is successfull - RETURN_INVALID_PARAMETER - The source data is corrupted, or - The GUID in InputSection does not match this instance guid. - ---*/ { EFI_STATUS Status; - CRC32_SECTION_HEADER *Crc32SectionHeader; + UINT32 SectionCrc32Checksum; UINT32 Crc32Checksum; UINT32 OutputBufferSize; VOID *DummyInterface; - if (!CompareGuid ( - &gEfiCrc32GuidedSectionExtractionProtocolGuid, + 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; - } + return EFI_INVALID_PARAMETER; + } - Crc32Checksum = 0; - // - // Points to the Crc32 section header - // - Crc32SectionHeader = (CRC32_SECTION_HEADER *) InputSection; - *OutputBuffer = (UINT8 *) InputSection + Crc32SectionHeader->GuidedSectionHeader.DataOffset; - OutputBufferSize = *(UINT32 *) (((EFI_COMMON_SECTION_HEADER *) InputSection)->Size) & 0x00ffffff; - OutputBufferSize -= Crc32SectionHeader->GuidedSectionHeader.DataOffset; + // + // 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; + } // - // Implictly CRC32 GUIDed section should have STATUS_VALID bit set + // Init Checksum value to Zero. // - ASSERT (Crc32SectionHeader->GuidedSectionHeader.Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID); - *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED; + 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 { // @@ -149,10 +188,16 @@ Returns: // Status = gBS->CalculateCrc32 (*OutputBuffer, OutputBufferSize, &Crc32Checksum); if (Status == EFI_SUCCESS) { - if (Crc32Checksum != Crc32SectionHeader->CRC32Checksum) { + 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; } } @@ -160,19 +205,24 @@ Returns: return EFI_SUCCESS; } -/** - Register Crc32 section handler. - - @retval RETURN_SUCCESS Register successfully. - @retval RETURN_OUT_OF_RESOURCES No enough memory to store this handler. +/** + Register the handler to extract CRC32 guided section. + + @param ImageHandle ImageHandle of the loaded driver. + @param SystemTable Pointer to the EFI System Table. + + @retval EFI_SUCCESS Register successfully. + @retval EFI_OUT_OF_RESOURCES No enough memory to register this handler. **/ EFI_STATUS EFIAPI DxeCrc32GuidedSectionExtractLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) { return ExtractGuidedSectionRegisterHandlers ( - &gEfiCrc32GuidedSectionExtractionProtocolGuid, + &gEfiCrc32GuidedSectionExtractionGuid, Crc32GuidedSectionGetInfo, Crc32GuidedSectionHandler );