DxeCrc32GuidedSectionExtractLib.c revision e6c560aad63b09e6aaee3ccc65be462651772fe5
1/*++
2
3Copyright (c) 2007, Intel Corporation
4All rights reserved. This program and the accompanying materials
5are licensed and made available under the terms and conditions of the BSD License
6which accompanies this distribution.  The full text of the license may be found at
7http://opensource.org/licenses/bsd-license.php
8
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12Module Name:
13
14  DxeCrc32GuidedSectionExtractLib.c
15
16Abstract:
17
18  Implements GUIDed section extraction protocol interface with
19  a specific GUID: CRC32.
20
21  Please refer to the Framewokr Firmware Volume Specification 0.9.
22
23--*/
24
25#include <PiDxe.h>
26#include <Protocol/Crc32GuidedSectionExtraction.h>
27#include <Protocol/SecurityPolicy.h>
28#include <Library/ExtractGuidedSectionLib.h>
29#include <Library/DebugLib.h>
30#include <Library/BaseMemoryLib.h>
31#include <Library/UefiBootServicesTableLib.h>
32
33typedef struct {
34  EFI_GUID_DEFINED_SECTION  GuidedSectionHeader;
35  UINT32                    CRC32Checksum;
36} CRC32_SECTION_HEADER;
37
38EFI_STATUS
39EFIAPI
40Crc32GuidedSectionGetInfo (
41  IN  CONST VOID  *InputSection,
42  OUT UINT32      *OutputBufferSize,
43  OUT UINT32      *ScratchBufferSize,
44  OUT UINT16      *SectionAttribute
45  )
46/*++
47
48Routine Description:
49
50  The implementation of Crc32 guided section GetInfo().
51
52Arguments:
53  InputSection          Buffer containing the input GUIDed section to be processed.
54  OutputBufferSize      The size of OutputBuffer.
55  ScratchBufferSize     The size of ScratchBuffer.
56  SectionAttribute      The attribute of the input guided section.
57
58Returns:
59
60  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.
61  EFI_INVALID_PARAMETER - The source data is corrupted, or
62                          The GUID in InputSection does not match this instance guid.
63
64--*/
65{
66  if (!CompareGuid (
67        &gEfiCrc32GuidedSectionExtractionProtocolGuid,
68        &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {
69    return EFI_INVALID_PARAMETER;
70  }
71  //
72  // Retrieve the size and attribute of the input section data.
73  //
74  *SectionAttribute  = ((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes;
75  *ScratchBufferSize = 0;
76  *OutputBufferSize  = *(UINT32 *) (((EFI_COMMON_SECTION_HEADER *) InputSection)->Size) & 0x00ffffff;
77  *OutputBufferSize  -= ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset;
78
79  return EFI_SUCCESS;
80}
81
82EFI_STATUS
83EFIAPI
84Crc32GuidedSectionHandler (
85  IN CONST  VOID    *InputSection,
86  OUT       VOID    **OutputBuffer,
87  IN        VOID    *ScratchBuffer,        OPTIONAL
88  OUT       UINT32  *AuthenticationStatus
89  )
90/*++
91
92Routine Description:
93
94  The implementation of Crc32 Guided section extraction.
95
96Arguments:
97  InputSection           Buffer containing the input GUIDed section to be processed.
98  OutputBuffer           OutputBuffer to point to the start of the section's contents.
99                         if guided data is not prcessed. Otherwise,
100                         OutputBuffer to contain the output data, which is allocated by the caller.
101  ScratchBuffer          A pointer to a caller-allocated buffer for function internal use.
102  AuthenticationStatus   A pointer to a caller-allocated UINT32 that indicates the
103                         authentication status of the output buffer.
104
105Returns:
106
107  RETURN_SUCCESS           - Decompression is successfull
108  RETURN_INVALID_PARAMETER - The source data is corrupted, or
109                             The GUID in InputSection does not match this instance guid.
110
111--*/
112{
113  EFI_STATUS                Status;
114  CRC32_SECTION_HEADER      *Crc32SectionHeader;
115  UINT32                    Crc32Checksum;
116  UINT32                    OutputBufferSize;
117  VOID                      *DummyInterface;
118
119  if (!CompareGuid (
120        &gEfiCrc32GuidedSectionExtractionProtocolGuid,
121        &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {
122    return EFI_INVALID_PARAMETER;
123  }
124
125  Crc32Checksum = 0;
126  //
127  // Points to the Crc32 section header
128  //
129  Crc32SectionHeader = (CRC32_SECTION_HEADER *) InputSection;
130  *OutputBuffer      = (UINT8 *) InputSection + Crc32SectionHeader->GuidedSectionHeader.DataOffset;
131  OutputBufferSize   = *(UINT32 *) (((EFI_COMMON_SECTION_HEADER *) InputSection)->Size) & 0x00ffffff;
132  OutputBufferSize   -= Crc32SectionHeader->GuidedSectionHeader.DataOffset;
133
134  //
135  // Implictly CRC32 GUIDed section should have STATUS_VALID bit set
136  //
137  ASSERT (Crc32SectionHeader->GuidedSectionHeader.Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID);
138  *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED;
139
140  //
141  // Check whether there exists EFI_SECURITY_POLICY_PROTOCOL_GUID.
142  //
143  Status = gBS->LocateProtocol (&gEfiSecurityPolicyProtocolGuid, NULL, &DummyInterface);
144  if (!EFI_ERROR (Status)) {
145    *AuthenticationStatus |= EFI_AUTH_STATUS_PLATFORM_OVERRIDE;
146  } else {
147    //
148    // Calculate CRC32 Checksum of Image
149    //
150    Status = gBS->CalculateCrc32 (*OutputBuffer, OutputBufferSize, &Crc32Checksum);
151    if (Status == EFI_SUCCESS) {
152      if (Crc32Checksum != Crc32SectionHeader->CRC32Checksum) {
153        *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
154      }
155    } else {
156      *AuthenticationStatus |= EFI_AUTH_STATUS_NOT_TESTED;
157    }
158  }
159
160  return EFI_SUCCESS;
161}
162
163/**
164  Register Crc32 section handler.
165
166  @retval  RETURN_SUCCESS            Register successfully.
167  @retval  RETURN_OUT_OF_RESOURCES   No enough memory to store this handler.
168**/
169EFI_STATUS
170EFIAPI
171DxeCrc32GuidedSectionExtractLibConstructor (
172  )
173{
174  return ExtractGuidedSectionRegisterHandlers (
175          &gEfiCrc32GuidedSectionExtractionProtocolGuid,
176          Crc32GuidedSectionGetInfo,
177          Crc32GuidedSectionHandler
178          );
179}
180
181