1 /** @file
2   LZMA Decompress GUIDed Section Extraction Library.
3   It wraps Lzma decompress interfaces to GUIDed Section Extraction interfaces
4   and registers them into GUIDed handler table.
5 
6   Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
7   SPDX-License-Identifier: BSD-2-Clause-Patent
8 
9 **/
10 
11 #include "LzmaDecompressLibInternal.h"
12 
13 /**
14   Examines a GUIDed section and returns the size of the decoded buffer and the
15   size of an scratch buffer required to actually decode the data in a GUIDed section.
16 
17   Examines a GUIDed section specified by InputSection.
18   If GUID for InputSection does not match the GUID that this handler supports,
19   then RETURN_UNSUPPORTED is returned.
20   If the required information can not be retrieved from InputSection,
21   then RETURN_INVALID_PARAMETER is returned.
22   If the GUID of InputSection does match the GUID that this handler supports,
23   then the size required to hold the decoded buffer is returned in OututBufferSize,
24   the size of an optional scratch buffer is returned in ScratchSize, and the Attributes field
25   from EFI_GUID_DEFINED_SECTION header of InputSection is returned in SectionAttribute.
26 
27   If InputSection is NULL, then ASSERT().
28   If OutputBufferSize is NULL, then ASSERT().
29   If ScratchBufferSize is NULL, then ASSERT().
30   If SectionAttribute is NULL, then ASSERT().
31 
32 
33   @param[in]  InputSection       A pointer to a GUIDed section of an FFS formatted file.
34   @param[out] OutputBufferSize   A pointer to the size, in bytes, of an output buffer required
35                                  if the buffer specified by InputSection were decoded.
36   @param[out] ScratchBufferSize  A pointer to the size, in bytes, required as scratch space
37                                  if the buffer specified by InputSection were decoded.
38   @param[out] SectionAttribute   A pointer to the attributes of the GUIDed section. See the Attributes
39                                  field of EFI_GUID_DEFINED_SECTION in the PI Specification.
40 
41   @retval  RETURN_SUCCESS            The information about InputSection was returned.
42   @retval  RETURN_UNSUPPORTED        The section specified by InputSection does not match the GUID this handler supports.
43   @retval  RETURN_INVALID_PARAMETER  The information can not be retrieved from the section specified by InputSection.
44 
45 **/
46 RETURN_STATUS
47 EFIAPI
LzmaGuidedSectionGetInfo(IN CONST VOID * InputSection,OUT UINT32 * OutputBufferSize,OUT UINT32 * ScratchBufferSize,OUT UINT16 * SectionAttribute)48 LzmaGuidedSectionGetInfo (
49   IN  CONST VOID  *InputSection,
50   OUT UINT32      *OutputBufferSize,
51   OUT UINT32      *ScratchBufferSize,
52   OUT UINT16      *SectionAttribute
53   )
54 {
55   ASSERT (InputSection != NULL);
56   ASSERT (OutputBufferSize != NULL);
57   ASSERT (ScratchBufferSize != NULL);
58   ASSERT (SectionAttribute != NULL);
59 
60   if (IS_SECTION2 (InputSection)) {
61     if (!CompareGuid (
62         &gLzmaCustomDecompressGuid,
63         &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid))) {
64       return RETURN_INVALID_PARAMETER;
65     }
66 
67     *SectionAttribute = ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->Attributes;
68 
69     return LzmaUefiDecompressGetInfo (
70              (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,
71              SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,
72              OutputBufferSize,
73              ScratchBufferSize
74              );
75   } else {
76     if (!CompareGuid (
77         &gLzmaCustomDecompressGuid,
78         &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {
79       return RETURN_INVALID_PARAMETER;
80     }
81 
82     *SectionAttribute = ((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes;
83 
84     return LzmaUefiDecompressGetInfo (
85              (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,
86              SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,
87              OutputBufferSize,
88              ScratchBufferSize
89              );
90   }
91 }
92 
93 /**
94   Decompress a LZAM compressed GUIDed section into a caller allocated output buffer.
95 
96   Decodes the GUIDed section specified by InputSection.
97   If GUID for InputSection does not match the GUID that this handler supports, then RETURN_UNSUPPORTED is returned.
98   If the data in InputSection can not be decoded, then RETURN_INVALID_PARAMETER is returned.
99   If the GUID of InputSection does match the GUID that this handler supports, then InputSection
100   is decoded into the buffer specified by OutputBuffer and the authentication status of this
101   decode operation is returned in AuthenticationStatus.  If the decoded buffer is identical to the
102   data in InputSection, then OutputBuffer is set to point at the data in InputSection.  Otherwise,
103   the decoded data will be placed in caller allocated buffer specified by OutputBuffer.
104 
105   If InputSection is NULL, then ASSERT().
106   If OutputBuffer is NULL, then ASSERT().
107   If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT().
108   If AuthenticationStatus is NULL, then ASSERT().
109 
110 
111   @param[in]  InputSection  A pointer to a GUIDed section of an FFS formatted file.
112   @param[out] OutputBuffer  A pointer to a buffer that contains the result of a decode operation.
113   @param[out] ScratchBuffer A caller allocated buffer that may be required by this function
114                             as a scratch buffer to perform the decode operation.
115   @param[out] AuthenticationStatus
116                             A pointer to the authentication status of the decoded output buffer.
117                             See the definition of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
118                             section of the PI Specification. EFI_AUTH_STATUS_PLATFORM_OVERRIDE must
119                             never be set by this handler.
120 
121   @retval  RETURN_SUCCESS            The buffer specified by InputSection was decoded.
122   @retval  RETURN_UNSUPPORTED        The section specified by InputSection does not match the GUID this handler supports.
123   @retval  RETURN_INVALID_PARAMETER  The section specified by InputSection can not be decoded.
124 
125 **/
126 RETURN_STATUS
127 EFIAPI
LzmaGuidedSectionExtraction(IN CONST VOID * InputSection,OUT VOID ** OutputBuffer,OUT VOID * ScratchBuffer,OPTIONAL OUT UINT32 * AuthenticationStatus)128 LzmaGuidedSectionExtraction (
129   IN CONST  VOID    *InputSection,
130   OUT       VOID    **OutputBuffer,
131   OUT       VOID    *ScratchBuffer,        OPTIONAL
132   OUT       UINT32  *AuthenticationStatus
133   )
134 {
135   ASSERT (OutputBuffer != NULL);
136   ASSERT (InputSection != NULL);
137 
138   if (IS_SECTION2 (InputSection)) {
139     if (!CompareGuid (
140         &gLzmaCustomDecompressGuid,
141         &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid))) {
142       return RETURN_INVALID_PARAMETER;
143     }
144 
145     //
146     // Authentication is set to Zero, which may be ignored.
147     //
148     *AuthenticationStatus = 0;
149 
150     return LzmaUefiDecompress (
151              (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,
152              SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,
153              *OutputBuffer,
154              ScratchBuffer
155              );
156   } else {
157     if (!CompareGuid (
158         &gLzmaCustomDecompressGuid,
159         &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {
160       return RETURN_INVALID_PARAMETER;
161     }
162 
163     //
164     // Authentication is set to Zero, which may be ignored.
165     //
166     *AuthenticationStatus = 0;
167 
168     return LzmaUefiDecompress (
169              (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,
170              SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,
171              *OutputBuffer,
172              ScratchBuffer
173     );
174   }
175 }
176 
177 
178 /**
179   Register LzmaDecompress and LzmaDecompressGetInfo handlers with LzmaCustomerDecompressGuid.
180 
181   @retval  RETURN_SUCCESS            Register successfully.
182   @retval  RETURN_OUT_OF_RESOURCES   No enough memory to store this handler.
183 **/
184 EFI_STATUS
185 EFIAPI
LzmaDecompressLibConstructor(VOID)186 LzmaDecompressLibConstructor (
187   VOID
188   )
189 {
190   return ExtractGuidedSectionRegisterHandlers (
191           &gLzmaCustomDecompressGuid,
192           LzmaGuidedSectionGetInfo,
193           LzmaGuidedSectionExtraction
194           );
195 }
196 
197