]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/SectionExtractionDxe/SectionExtractionDxe.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / SectionExtractionDxe / SectionExtractionDxe.c
1 /** @file
2 Section Extraction DXE Driver
3
4 Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <PiDxe.h>
10 #include <Protocol/GuidedSectionExtraction.h>
11 #include <Library/DebugLib.h>
12 #include <Library/ExtractGuidedSectionLib.h>
13 #include <Library/MemoryAllocationLib.h>
14 #include <Library/BaseMemoryLib.h>
15 #include <Library/UefiBootServicesTableLib.h>
16
17 /**
18 The ExtractSection() function processes the input section and
19 allocates a buffer from the pool in which it returns the section
20 contents. If the section being extracted contains
21 authentication information (the section's
22 GuidedSectionHeader.Attributes field has the
23 EFI_GUIDED_SECTION_AUTH_STATUS_VALID bit set), the values
24 returned in AuthenticationStatus must reflect the results of
25 the authentication operation. Depending on the algorithm and
26 size of the encapsulated data, the time that is required to do
27 a full authentication may be prohibitively long for some
28 classes of systems. To indicate this, use
29 EFI_SECURITY_POLICY_PROTOCOL_GUID, which may be published by
30 the security policy driver (see the Platform Initialization
31 Driver Execution Environment Core Interface Specification for
32 more details and the GUID definition). If the
33 EFI_SECURITY_POLICY_PROTOCOL_GUID exists in the handle
34 database, then, if possible, full authentication should be
35 skipped and the section contents simply returned in the
36 OutputBuffer. In this case, the
37 EFI_AUTH_STATUS_PLATFORM_OVERRIDE bit AuthenticationStatus
38 must be set on return. ExtractSection() is callable only from
39 TPL_NOTIFY and below. Behavior of ExtractSection() at any
40 EFI_TPL above TPL_NOTIFY is undefined. Type EFI_TPL is
41 defined in RaiseTPL() in the UEFI 2.0 specification.
42
43
44 @param This Indicates the
45 EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL instance.
46 @param InputSection Buffer containing the input GUIDed section
47 to be processed. OutputBuffer OutputBuffer
48 is allocated from boot services pool
49 memory and contains the new section
50 stream. The caller is responsible for
51 freeing this buffer.
52 @param OutputBuffer *OutputBuffer is allocated from boot services
53 pool memory and contains the new section stream.
54 The caller is responsible for freeing this buffer.
55 @param OutputSize A pointer to a caller-allocated UINTN in
56 which the size of OutputBuffer allocation
57 is stored. If the function returns
58 anything other than EFI_SUCCESS, the value
59 of OutputSize is undefined.
60
61 @param AuthenticationStatus A pointer to a caller-allocated
62 UINT32 that indicates the
63 authentication status of the
64 output buffer. If the input
65 section's
66 GuidedSectionHeader.Attributes
67 field has the
68 EFI_GUIDED_SECTION_AUTH_STATUS_VAL
69 bit as clear, AuthenticationStatus
70 must return zero. Both local bits
71 (19:16) and aggregate bits (3:0)
72 in AuthenticationStatus are
73 returned by ExtractSection().
74 These bits reflect the status of
75 the extraction operation. The bit
76 pattern in both regions must be
77 the same, as the local and
78 aggregate authentication statuses
79 have equivalent meaning at this
80 level. If the function returns
81 anything other than EFI_SUCCESS,
82 the value of AuthenticationStatus
83 is undefined.
84
85
86 @retval EFI_SUCCESS The InputSection was successfully
87 processed and the section contents were
88 returned.
89
90 @retval EFI_OUT_OF_RESOURCES The system has insufficient
91 resources to process the
92 request.
93
94 @retval EFI_INVALID_PARAMETER The GUID in InputSection does
95 not match this instance of the
96 GUIDed Section Extraction
97 Protocol.
98
99 **/
100 EFI_STATUS
101 EFIAPI
102 CustomGuidedSectionExtract (
103 IN CONST EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This,
104 IN CONST VOID *InputSection,
105 OUT VOID **OutputBuffer,
106 OUT UINTN *OutputSize,
107 OUT UINT32 *AuthenticationStatus
108 );
109
110 //
111 // Module global for the Section Extraction Protocol handle
112 //
113 EFI_HANDLE mSectionExtractionHandle = NULL;
114
115 //
116 // Module global for the Section Extraction Protocol instance
117 //
118 EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL mCustomGuidedSectionExtractionProtocol = {
119 CustomGuidedSectionExtract
120 };
121
122 /**
123 The ExtractSection() function processes the input section and
124 allocates a buffer from the pool in which it returns the section
125 contents. If the section being extracted contains
126 authentication information (the section's
127 GuidedSectionHeader.Attributes field has the
128 EFI_GUIDED_SECTION_AUTH_STATUS_VALID bit set), the values
129 returned in AuthenticationStatus must reflect the results of
130 the authentication operation. Depending on the algorithm and
131 size of the encapsulated data, the time that is required to do
132 a full authentication may be prohibitively long for some
133 classes of systems. To indicate this, use
134 EFI_SECURITY_POLICY_PROTOCOL_GUID, which may be published by
135 the security policy driver (see the Platform Initialization
136 Driver Execution Environment Core Interface Specification for
137 more details and the GUID definition). If the
138 EFI_SECURITY_POLICY_PROTOCOL_GUID exists in the handle
139 database, then, if possible, full authentication should be
140 skipped and the section contents simply returned in the
141 OutputBuffer. In this case, the
142 EFI_AUTH_STATUS_PLATFORM_OVERRIDE bit AuthenticationStatus
143 must be set on return. ExtractSection() is callable only from
144 TPL_NOTIFY and below. Behavior of ExtractSection() at any
145 EFI_TPL above TPL_NOTIFY is undefined. Type EFI_TPL is
146 defined in RaiseTPL() in the UEFI 2.0 specification.
147
148
149 @param This Indicates the
150 EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL instance.
151 @param InputSection Buffer containing the input GUIDed section
152 to be processed. OutputBuffer OutputBuffer
153 is allocated from boot services pool
154 memory and contains the new section
155 stream. The caller is responsible for
156 freeing this buffer.
157 @param OutputBuffer *OutputBuffer is allocated from boot services
158 pool memory and contains the new section stream.
159 The caller is responsible for freeing this buffer.
160 @param OutputSize A pointer to a caller-allocated UINTN in
161 which the size of OutputBuffer allocation
162 is stored. If the function returns
163 anything other than EFI_SUCCESS, the value
164 of OutputSize is undefined.
165
166 @param AuthenticationStatus A pointer to a caller-allocated
167 UINT32 that indicates the
168 authentication status of the
169 output buffer. If the input
170 section's
171 GuidedSectionHeader.Attributes
172 field has the
173 EFI_GUIDED_SECTION_AUTH_STATUS_VAL
174 bit as clear, AuthenticationStatus
175 must return zero. Both local bits
176 (19:16) and aggregate bits (3:0)
177 in AuthenticationStatus are
178 returned by ExtractSection().
179 These bits reflect the status of
180 the extraction operation. The bit
181 pattern in both regions must be
182 the same, as the local and
183 aggregate authentication statuses
184 have equivalent meaning at this
185 level. If the function returns
186 anything other than EFI_SUCCESS,
187 the value of AuthenticationStatus
188 is undefined.
189
190
191 @retval EFI_SUCCESS The InputSection was successfully
192 processed and the section contents were
193 returned.
194
195 @retval EFI_OUT_OF_RESOURCES The system has insufficient
196 resources to process the
197 request.
198
199 @retval EFI_INVALID_PARAMETER The GUID in InputSection does
200 not match this instance of the
201 GUIDed Section Extraction
202 Protocol.
203
204 **/
205 EFI_STATUS
206 EFIAPI
207 CustomGuidedSectionExtract (
208 IN CONST EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This,
209 IN CONST VOID *InputSection,
210 OUT VOID **OutputBuffer,
211 OUT UINTN *OutputSize,
212 OUT UINT32 *AuthenticationStatus
213 )
214 {
215 EFI_STATUS Status;
216 VOID *ScratchBuffer;
217 VOID *AllocatedOutputBuffer;
218 UINT32 OutputBufferSize;
219 UINT32 ScratchBufferSize;
220 UINT16 SectionAttribute;
221
222 //
223 // Init local variable
224 //
225 ScratchBuffer = NULL;
226 AllocatedOutputBuffer = NULL;
227
228 //
229 // Call GetInfo to get the size and attribute of input guided section data.
230 //
231 Status = ExtractGuidedSectionGetInfo (
232 InputSection,
233 &OutputBufferSize,
234 &ScratchBufferSize,
235 &SectionAttribute
236 );
237
238 if (EFI_ERROR (Status)) {
239 DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status));
240 return Status;
241 }
242
243 if (ScratchBufferSize > 0) {
244 //
245 // Allocate scratch buffer
246 //
247 ScratchBuffer = AllocatePool (ScratchBufferSize);
248 if (ScratchBuffer == NULL) {
249 return EFI_OUT_OF_RESOURCES;
250 }
251 }
252
253 if (OutputBufferSize > 0) {
254 //
255 // Allocate output buffer
256 //
257 AllocatedOutputBuffer = AllocatePool (OutputBufferSize);
258 if (AllocatedOutputBuffer == NULL) {
259 FreePool (ScratchBuffer);
260 return EFI_OUT_OF_RESOURCES;
261 }
262 *OutputBuffer = AllocatedOutputBuffer;
263 }
264
265 //
266 // Call decode function to extract raw data from the guided section.
267 //
268 Status = ExtractGuidedSectionDecode (
269 InputSection,
270 OutputBuffer,
271 ScratchBuffer,
272 AuthenticationStatus
273 );
274 if (EFI_ERROR (Status)) {
275 //
276 // Decode failed
277 //
278 if (AllocatedOutputBuffer != NULL) {
279 FreePool (AllocatedOutputBuffer);
280 }
281 if (ScratchBuffer != NULL) {
282 FreePool (ScratchBuffer);
283 }
284 DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status));
285 return Status;
286 }
287
288 if (*OutputBuffer != AllocatedOutputBuffer) {
289 //
290 // OutputBuffer was returned as a different value,
291 // so copy section contents to the allocated memory buffer.
292 //
293 CopyMem (AllocatedOutputBuffer, *OutputBuffer, OutputBufferSize);
294 *OutputBuffer = AllocatedOutputBuffer;
295 }
296
297 //
298 // Set real size of output buffer.
299 //
300 *OutputSize = (UINTN) OutputBufferSize;
301
302 //
303 // Free unused scratch buffer.
304 //
305 if (ScratchBuffer != NULL) {
306 FreePool (ScratchBuffer);
307 }
308
309 return EFI_SUCCESS;
310 }
311
312 /**
313 Main entry for the Section Extraction DXE module.
314
315 This routine registers the Section Extraction Protocols that have been registered
316 with the Section Extraction Library.
317
318 @param[in] ImageHandle The firmware allocated handle for the EFI image.
319 @param[in] SystemTable A pointer to the EFI System Table.
320
321 @retval EFI_SUCCESS The entry point is executed successfully.
322 @retval other Some error occurs when executing this entry point.
323
324 **/
325 EFI_STATUS
326 EFIAPI
327 SectionExtractionDxeEntry (
328 IN EFI_HANDLE ImageHandle,
329 IN EFI_SYSTEM_TABLE *SystemTable
330 )
331 {
332 EFI_STATUS Status;
333 EFI_GUID *ExtractHandlerGuidTable;
334 UINTN ExtractHandlerNumber;
335
336 //
337 // Get custom extract guided section method guid list
338 //
339 ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);
340
341 //
342 // Install custom guided extraction protocol
343 //
344 while (ExtractHandlerNumber-- > 0) {
345 Status = gBS->InstallMultipleProtocolInterfaces (
346 &mSectionExtractionHandle,
347 &ExtractHandlerGuidTable [ExtractHandlerNumber], &mCustomGuidedSectionExtractionProtocol,
348 NULL
349 );
350 ASSERT_EFI_ERROR (Status);
351 }
352
353 return EFI_SUCCESS;
354 }