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
CustomGuidedSectionExtract(IN CONST EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL * This,IN CONST VOID * InputSection,OUT VOID ** OutputBuffer,OUT UINTN * OutputSize,OUT UINT32 * AuthenticationStatus)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
SectionExtractionDxeEntry(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)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 }
361