]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Library / DxeCrc32GuidedSectionExtractLib / DxeCrc32GuidedSectionExtractLib.c
1 /** @file
2
3 This library registers CRC32 guided section handler
4 to parse CRC32 encapsulation section and extract raw data.
5 It uses UEFI boot service CalculateCrc32 to authenticate 32 bit CRC value.
6
7 Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
8 SPDX-License-Identifier: BSD-2-Clause-Patent
9
10 **/
11
12 #include <PiDxe.h>
13 #include <Guid/Crc32GuidedSectionExtraction.h>
14 #include <Protocol/SecurityPolicy.h>
15 #include <Library/ExtractGuidedSectionLib.h>
16 #include <Library/DebugLib.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/UefiBootServicesTableLib.h>
19
20 ///
21 /// CRC32 Guided Section header
22 ///
23 typedef struct {
24 EFI_GUID_DEFINED_SECTION GuidedSectionHeader; ///< EFI guided section header
25 UINT32 CRC32Checksum; ///< 32bit CRC check sum
26 } CRC32_SECTION_HEADER;
27
28 typedef struct {
29 EFI_GUID_DEFINED_SECTION2 GuidedSectionHeader; ///< EFI guided section header
30 UINT32 CRC32Checksum; ///< 32bit CRC check sum
31 } CRC32_SECTION2_HEADER;
32
33 /**
34
35 GetInfo gets raw data size and attribute of the input guided section.
36 It first checks whether the input guid section is supported.
37 If not, EFI_INVALID_PARAMETER will return.
38
39 @param InputSection Buffer containing the input GUIDed section to be processed.
40 @param OutputBufferSize The size of OutputBuffer.
41 @param ScratchBufferSize The size of ScratchBuffer.
42 @param SectionAttribute The attribute of the input guided section.
43
44 @retval EFI_SUCCESS The size of destination buffer, the size of scratch buffer and
45 the attribute of the input section are successfully retrieved.
46 @retval EFI_INVALID_PARAMETER The GUID in InputSection does not match this instance guid.
47
48 **/
49 EFI_STATUS
50 EFIAPI
51 Crc32GuidedSectionGetInfo (
52 IN CONST VOID *InputSection,
53 OUT UINT32 *OutputBufferSize,
54 OUT UINT32 *ScratchBufferSize,
55 OUT UINT16 *SectionAttribute
56 )
57 {
58 if (IS_SECTION2 (InputSection)) {
59 //
60 // Check whether the input guid section is recognized.
61 //
62 if (!CompareGuid (
63 &gEfiCrc32GuidedSectionExtractionGuid,
64 &(((EFI_GUID_DEFINED_SECTION2 *)InputSection)->SectionDefinitionGuid)
65 ))
66 {
67 return EFI_INVALID_PARAMETER;
68 }
69
70 //
71 // Retrieve the size and attribute of the input section data.
72 //
73 *SectionAttribute = ((EFI_GUID_DEFINED_SECTION2 *)InputSection)->Attributes;
74 *ScratchBufferSize = 0;
75 *OutputBufferSize = SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *)InputSection)->DataOffset;
76 } else {
77 //
78 // Check whether the input guid section is recognized.
79 //
80 if (!CompareGuid (
81 &gEfiCrc32GuidedSectionExtractionGuid,
82 &(((EFI_GUID_DEFINED_SECTION *)InputSection)->SectionDefinitionGuid)
83 ))
84 {
85 return EFI_INVALID_PARAMETER;
86 }
87
88 //
89 // Retrieve the size and attribute of the input section data.
90 //
91 *SectionAttribute = ((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes;
92 *ScratchBufferSize = 0;
93 *OutputBufferSize = SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *)InputSection)->DataOffset;
94 }
95
96 return EFI_SUCCESS;
97 }
98
99 /**
100
101 Extraction handler tries to extract raw data from the input guided section.
102 It also does authentication check for 32bit CRC value in the input guided section.
103 It first checks whether the input guid section is supported.
104 If not, EFI_INVALID_PARAMETER will return.
105
106 @param InputSection Buffer containing the input GUIDed section to be processed.
107 @param OutputBuffer Buffer to contain the output raw data allocated by the caller.
108 @param ScratchBuffer A pointer to a caller-allocated buffer for function internal use.
109 @param AuthenticationStatus A pointer to a caller-allocated UINT32 that indicates the
110 authentication status of the output buffer.
111
112 @retval EFI_SUCCESS Section Data and Auth Status is extracted successfully.
113 @retval EFI_INVALID_PARAMETER The GUID in InputSection does not match this instance guid.
114
115 **/
116 EFI_STATUS
117 EFIAPI
118 Crc32GuidedSectionHandler (
119 IN CONST VOID *InputSection,
120 OUT VOID **OutputBuffer,
121 IN VOID *ScratchBuffer OPTIONAL,
122 OUT UINT32 *AuthenticationStatus
123 )
124 {
125 EFI_STATUS Status;
126 UINT32 SectionCrc32Checksum;
127 UINT32 Crc32Checksum;
128 UINT32 OutputBufferSize;
129 VOID *DummyInterface;
130
131 if (IS_SECTION2 (InputSection)) {
132 //
133 // Check whether the input guid section is recognized.
134 //
135 if (!CompareGuid (
136 &gEfiCrc32GuidedSectionExtractionGuid,
137 &(((EFI_GUID_DEFINED_SECTION2 *)InputSection)->SectionDefinitionGuid)
138 ))
139 {
140 return EFI_INVALID_PARAMETER;
141 }
142
143 //
144 // Get section Crc32 checksum.
145 //
146 SectionCrc32Checksum = ((CRC32_SECTION2_HEADER *)InputSection)->CRC32Checksum;
147 *OutputBuffer = (UINT8 *)InputSection + ((EFI_GUID_DEFINED_SECTION2 *)InputSection)->DataOffset;
148 OutputBufferSize = SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *)InputSection)->DataOffset;
149
150 //
151 // Implicitly CRC32 GUIDed section should have STATUS_VALID bit set
152 //
153 ASSERT (((EFI_GUID_DEFINED_SECTION2 *)InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID);
154 *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED;
155 } else {
156 //
157 // Check whether the input guid section is recognized.
158 //
159 if (!CompareGuid (
160 &gEfiCrc32GuidedSectionExtractionGuid,
161 &(((EFI_GUID_DEFINED_SECTION *)InputSection)->SectionDefinitionGuid)
162 ))
163 {
164 return EFI_INVALID_PARAMETER;
165 }
166
167 //
168 // Get section Crc32 checksum.
169 //
170 SectionCrc32Checksum = ((CRC32_SECTION_HEADER *)InputSection)->CRC32Checksum;
171 *OutputBuffer = (UINT8 *)InputSection + ((EFI_GUID_DEFINED_SECTION *)InputSection)->DataOffset;
172 OutputBufferSize = SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *)InputSection)->DataOffset;
173
174 //
175 // Implicitly CRC32 GUIDed section should have STATUS_VALID bit set
176 //
177 ASSERT (((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID);
178 *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED;
179 }
180
181 //
182 // Init Checksum value to Zero.
183 //
184 Crc32Checksum = 0;
185
186 //
187 // Check whether there exists EFI_SECURITY_POLICY_PROTOCOL_GUID.
188 //
189 Status = gBS->LocateProtocol (&gEfiSecurityPolicyProtocolGuid, NULL, &DummyInterface);
190 if (!EFI_ERROR (Status)) {
191 //
192 // If SecurityPolicy Protocol exist, AUTH platform override bit is set.
193 //
194 *AuthenticationStatus |= EFI_AUTH_STATUS_PLATFORM_OVERRIDE;
195 } else {
196 //
197 // Calculate CRC32 Checksum of Image
198 //
199 Status = gBS->CalculateCrc32 (*OutputBuffer, OutputBufferSize, &Crc32Checksum);
200 if (Status == EFI_SUCCESS) {
201 if (Crc32Checksum != SectionCrc32Checksum) {
202 //
203 // If Crc32 checksum is not matched, AUTH tested failed bit is set.
204 //
205 *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
206 }
207 } else {
208 //
209 // If Crc32 checksum is not calculated, AUTH not tested bit is set.
210 //
211 *AuthenticationStatus |= EFI_AUTH_STATUS_NOT_TESTED;
212 }
213 }
214
215 return EFI_SUCCESS;
216 }
217
218 /**
219 Register the handler to extract CRC32 guided section.
220
221 @param ImageHandle ImageHandle of the loaded driver.
222 @param SystemTable Pointer to the EFI System Table.
223
224 @retval EFI_SUCCESS Register successfully.
225 @retval EFI_OUT_OF_RESOURCES No enough memory to register this handler.
226 **/
227 EFI_STATUS
228 EFIAPI
229 DxeCrc32GuidedSectionExtractLibConstructor (
230 IN EFI_HANDLE ImageHandle,
231 IN EFI_SYSTEM_TABLE *SystemTable
232 )
233 {
234 return ExtractGuidedSectionRegisterHandlers (
235 &gEfiCrc32GuidedSectionExtractionGuid,
236 Crc32GuidedSectionGetInfo,
237 Crc32GuidedSectionHandler
238 );
239 }