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 |
|
---|
263 | *OutputBuffer = AllocatedOutputBuffer;
|
---|
264 | }
|
---|
265 |
|
---|
266 | //
|
---|
267 | // Call decode function to extract raw data from the guided section.
|
---|
268 | //
|
---|
269 | Status = ExtractGuidedSectionDecode (
|
---|
270 | InputSection,
|
---|
271 | OutputBuffer,
|
---|
272 | ScratchBuffer,
|
---|
273 | AuthenticationStatus
|
---|
274 | );
|
---|
275 | if (EFI_ERROR (Status)) {
|
---|
276 | //
|
---|
277 | // Decode failed
|
---|
278 | //
|
---|
279 | if (AllocatedOutputBuffer != NULL) {
|
---|
280 | FreePool (AllocatedOutputBuffer);
|
---|
281 | }
|
---|
282 |
|
---|
283 | if (ScratchBuffer != NULL) {
|
---|
284 | FreePool (ScratchBuffer);
|
---|
285 | }
|
---|
286 |
|
---|
287 | DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status));
|
---|
288 | return Status;
|
---|
289 | }
|
---|
290 |
|
---|
291 | if (*OutputBuffer != AllocatedOutputBuffer) {
|
---|
292 | //
|
---|
293 | // OutputBuffer was returned as a different value,
|
---|
294 | // so copy section contents to the allocated memory buffer.
|
---|
295 | //
|
---|
296 | CopyMem (AllocatedOutputBuffer, *OutputBuffer, OutputBufferSize);
|
---|
297 | *OutputBuffer = AllocatedOutputBuffer;
|
---|
298 | }
|
---|
299 |
|
---|
300 | //
|
---|
301 | // Set real size of output buffer.
|
---|
302 | //
|
---|
303 | *OutputSize = (UINTN)OutputBufferSize;
|
---|
304 |
|
---|
305 | //
|
---|
306 | // Free unused scratch buffer.
|
---|
307 | //
|
---|
308 | if (ScratchBuffer != NULL) {
|
---|
309 | FreePool (ScratchBuffer);
|
---|
310 | }
|
---|
311 |
|
---|
312 | return EFI_SUCCESS;
|
---|
313 | }
|
---|
314 |
|
---|
315 | /**
|
---|
316 | Main entry for the Section Extraction DXE module.
|
---|
317 |
|
---|
318 | This routine registers the Section Extraction Protocols that have been registered
|
---|
319 | with the Section Extraction Library.
|
---|
320 |
|
---|
321 | @param[in] ImageHandle The firmware allocated handle for the EFI image.
|
---|
322 | @param[in] SystemTable A pointer to the EFI System Table.
|
---|
323 |
|
---|
324 | @retval EFI_SUCCESS The entry point is executed successfully.
|
---|
325 | @retval other Some error occurs when executing this entry point.
|
---|
326 |
|
---|
327 | **/
|
---|
328 | EFI_STATUS
|
---|
329 | EFIAPI
|
---|
330 | SectionExtractionDxeEntry (
|
---|
331 | IN EFI_HANDLE ImageHandle,
|
---|
332 | IN EFI_SYSTEM_TABLE *SystemTable
|
---|
333 | )
|
---|
334 | {
|
---|
335 | EFI_STATUS Status;
|
---|
336 | EFI_GUID *ExtractHandlerGuidTable;
|
---|
337 | UINTN ExtractHandlerNumber;
|
---|
338 |
|
---|
339 | //
|
---|
340 | // Get custom extract guided section method guid list
|
---|
341 | //
|
---|
342 | ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);
|
---|
343 |
|
---|
344 | //
|
---|
345 | // Install custom guided extraction protocol
|
---|
346 | //
|
---|
347 | while (ExtractHandlerNumber-- > 0) {
|
---|
348 | Status = gBS->InstallMultipleProtocolInterfaces (
|
---|
349 | &mSectionExtractionHandle,
|
---|
350 | &ExtractHandlerGuidTable[ExtractHandlerNumber],
|
---|
351 | &mCustomGuidedSectionExtractionProtocol,
|
---|
352 | NULL
|
---|
353 | );
|
---|
354 | ASSERT_EFI_ERROR (Status);
|
---|
355 | }
|
---|
356 |
|
---|
357 | return EFI_SUCCESS;
|
---|
358 | }
|
---|