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