]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Library / DxeCrc32GuidedSectionExtractLib / DxeCrc32GuidedSectionExtractLib.c
CommitLineData
504214c4 1/** @file\r
d51ffc1f 2\r
d1102dba 3 This library registers CRC32 guided section handler\r
109e9a61
LG
4 to parse CRC32 encapsulation section and extract raw data.\r
5 It uses UEFI boot service CalculateCrc32 to authenticate 32 bit CRC value.\r
504214c4 6\r
d1102dba 7Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 8SPDX-License-Identifier: BSD-2-Clause-Patent\r
d51ffc1f 9\r
504214c4 10**/\r
d51ffc1f
LG
11\r
12#include <PiDxe.h>\r
76f1dde2 13#include <Guid/Crc32GuidedSectionExtraction.h>\r
d51ffc1f
LG
14#include <Protocol/SecurityPolicy.h>\r
15#include <Library/ExtractGuidedSectionLib.h>\r
16#include <Library/DebugLib.h>\r
e6c560aa 17#include <Library/BaseMemoryLib.h>\r
d51ffc1f
LG
18#include <Library/UefiBootServicesTableLib.h>\r
19\r
109e9a61
LG
20///\r
21/// CRC32 Guided Section header\r
22///\r
d51ffc1f 23typedef struct {\r
109e9a61
LG
24 EFI_GUID_DEFINED_SECTION GuidedSectionHeader; ///< EFI guided section header\r
25 UINT32 CRC32Checksum; ///< 32bit CRC check sum\r
d51ffc1f
LG
26} CRC32_SECTION_HEADER;\r
27\r
30f001ca
SZ
28typedef struct {\r
29 EFI_GUID_DEFINED_SECTION2 GuidedSectionHeader; ///< EFI guided section header\r
30 UINT32 CRC32Checksum; ///< 32bit CRC check sum\r
31} CRC32_SECTION2_HEADER;\r
32\r
5d69642d
LG
33/**\r
34\r
109e9a61 35 GetInfo gets raw data size and attribute of the input guided section.\r
d1102dba 36 It first checks whether the input guid section is supported.\r
109e9a61 37 If not, EFI_INVALID_PARAMETER will return.\r
5d69642d
LG
38\r
39 @param InputSection Buffer containing the input GUIDed section to be processed.\r
40 @param OutputBufferSize The size of OutputBuffer.\r
41 @param ScratchBufferSize The size of ScratchBuffer.\r
42 @param SectionAttribute The attribute of the input guided section.\r
43\r
d1102dba 44 @retval EFI_SUCCESS The size of destination buffer, the size of scratch buffer and\r
3b28e744 45 the attribute of the input section are successfully retrieved.\r
5d69642d
LG
46 @retval EFI_INVALID_PARAMETER The GUID in InputSection does not match this instance guid.\r
47\r
48**/\r
d51ffc1f
LG
49EFI_STATUS\r
50EFIAPI\r
51Crc32GuidedSectionGetInfo (\r
52 IN CONST VOID *InputSection,\r
53 OUT UINT32 *OutputBufferSize,\r
54 OUT UINT32 *ScratchBufferSize,\r
55 OUT UINT16 *SectionAttribute\r
56 )\r
d51ffc1f 57{\r
30f001ca
SZ
58 if (IS_SECTION2 (InputSection)) {\r
59 //\r
60 // Check whether the input guid section is recognized.\r
61 //\r
62 if (!CompareGuid (\r
63 &gEfiCrc32GuidedSectionExtractionGuid,\r
64 &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid))) {\r
65 return EFI_INVALID_PARAMETER;\r
66 }\r
67 //\r
68 // Retrieve the size and attribute of the input section data.\r
69 //\r
70 *SectionAttribute = ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->Attributes;\r
71 *ScratchBufferSize = 0;\r
72 *OutputBufferSize = SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset;\r
73 } else {\r
74 //\r
75 // Check whether the input guid section is recognized.\r
76 //\r
77 if (!CompareGuid (\r
78 &gEfiCrc32GuidedSectionExtractionGuid,\r
e6c560aa 79 &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {\r
30f001ca
SZ
80 return EFI_INVALID_PARAMETER;\r
81 }\r
82 //\r
83 // Retrieve the size and attribute of the input section data.\r
84 //\r
85 *SectionAttribute = ((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes;\r
86 *ScratchBufferSize = 0;\r
87 *OutputBufferSize = SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset;\r
e6c560aa 88 }\r
d51ffc1f
LG
89\r
90 return EFI_SUCCESS;\r
91}\r
92\r
5d69642d
LG
93/**\r
94\r
109e9a61
LG
95 Extraction handler tries to extract raw data from the input guided section.\r
96 It also does authentication check for 32bit CRC value in the input guided section.\r
d1102dba 97 It first checks whether the input guid section is supported.\r
109e9a61 98 If not, EFI_INVALID_PARAMETER will return.\r
5d69642d
LG
99\r
100 @param InputSection Buffer containing the input GUIDed section to be processed.\r
109e9a61 101 @param OutputBuffer Buffer to contain the output raw data allocated by the caller.\r
5d69642d
LG
102 @param ScratchBuffer A pointer to a caller-allocated buffer for function internal use.\r
103 @param AuthenticationStatus A pointer to a caller-allocated UINT32 that indicates the\r
109e9a61 104 authentication status of the output buffer.\r
5d69642d
LG
105\r
106 @retval EFI_SUCCESS Section Data and Auth Status is extracted successfully.\r
107 @retval EFI_INVALID_PARAMETER The GUID in InputSection does not match this instance guid.\r
108\r
109**/\r
d51ffc1f
LG
110EFI_STATUS\r
111EFIAPI\r
112Crc32GuidedSectionHandler (\r
113 IN CONST VOID *InputSection,\r
114 OUT VOID **OutputBuffer,\r
115 IN VOID *ScratchBuffer, OPTIONAL\r
116 OUT UINT32 *AuthenticationStatus\r
117 )\r
d51ffc1f
LG
118{\r
119 EFI_STATUS Status;\r
30f001ca 120 UINT32 SectionCrc32Checksum;\r
d51ffc1f
LG
121 UINT32 Crc32Checksum;\r
122 UINT32 OutputBufferSize;\r
123 VOID *DummyInterface;\r
124\r
30f001ca
SZ
125 if (IS_SECTION2 (InputSection)) {\r
126 //\r
127 // Check whether the input guid section is recognized.\r
128 //\r
129 if (!CompareGuid (\r
130 &gEfiCrc32GuidedSectionExtractionGuid,\r
131 &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid))) {\r
132 return EFI_INVALID_PARAMETER;\r
133 }\r
d1102dba 134\r
30f001ca
SZ
135 //\r
136 // Get section Crc32 checksum.\r
137 //\r
138 SectionCrc32Checksum = ((CRC32_SECTION2_HEADER *) InputSection)->CRC32Checksum;\r
139 *OutputBuffer = (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset;\r
140 OutputBufferSize = SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset;\r
141\r
142 //\r
143 // Implicitly CRC32 GUIDed section should have STATUS_VALID bit set\r
144 //\r
145 ASSERT (((EFI_GUID_DEFINED_SECTION2 *) InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID);\r
146 *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED;\r
147 } else {\r
148 //\r
149 // Check whether the input guid section is recognized.\r
150 //\r
151 if (!CompareGuid (\r
152 &gEfiCrc32GuidedSectionExtractionGuid,\r
e6c560aa 153 &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {\r
30f001ca
SZ
154 return EFI_INVALID_PARAMETER;\r
155 }\r
d1102dba 156\r
30f001ca
SZ
157 //\r
158 // Get section Crc32 checksum.\r
159 //\r
160 SectionCrc32Checksum = ((CRC32_SECTION_HEADER *) InputSection)->CRC32Checksum;\r
161 *OutputBuffer = (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset;\r
162 OutputBufferSize = SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset;\r
163\r
164 //\r
165 // Implicitly CRC32 GUIDed section should have STATUS_VALID bit set\r
166 //\r
167 ASSERT (((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID);\r
168 *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED;\r
169 }\r
170\r
5d69642d
LG
171 //\r
172 // Init Checksum value to Zero.\r
173 //\r
d51ffc1f 174 Crc32Checksum = 0;\r
d51ffc1f
LG
175\r
176 //\r
177 // Check whether there exists EFI_SECURITY_POLICY_PROTOCOL_GUID.\r
178 //\r
179 Status = gBS->LocateProtocol (&gEfiSecurityPolicyProtocolGuid, NULL, &DummyInterface);\r
180 if (!EFI_ERROR (Status)) {\r
5d69642d
LG
181 //\r
182 // If SecurityPolicy Protocol exist, AUTH platform override bit is set.\r
183 //\r
d51ffc1f
LG
184 *AuthenticationStatus |= EFI_AUTH_STATUS_PLATFORM_OVERRIDE;\r
185 } else {\r
186 //\r
187 // Calculate CRC32 Checksum of Image\r
188 //\r
189 Status = gBS->CalculateCrc32 (*OutputBuffer, OutputBufferSize, &Crc32Checksum);\r
190 if (Status == EFI_SUCCESS) {\r
30f001ca 191 if (Crc32Checksum != SectionCrc32Checksum) {\r
5d69642d
LG
192 //\r
193 // If Crc32 checksum is not matched, AUTH tested failed bit is set.\r
194 //\r
d51ffc1f
LG
195 *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;\r
196 }\r
197 } else {\r
5d69642d
LG
198 //\r
199 // If Crc32 checksum is not calculated, AUTH not tested bit is set.\r
200 //\r
d51ffc1f
LG
201 *AuthenticationStatus |= EFI_AUTH_STATUS_NOT_TESTED;\r
202 }\r
203 }\r
204\r
205 return EFI_SUCCESS;\r
206}\r
207\r
5d69642d 208/**\r
109e9a61 209 Register the handler to extract CRC32 guided section.\r
5d69642d 210\r
cebc8d48
LG
211 @param ImageHandle ImageHandle of the loaded driver.\r
212 @param SystemTable Pointer to the EFI System Table.\r
213\r
109e9a61
LG
214 @retval EFI_SUCCESS Register successfully.\r
215 @retval EFI_OUT_OF_RESOURCES No enough memory to register this handler.\r
d51ffc1f
LG
216**/\r
217EFI_STATUS\r
218EFIAPI\r
219DxeCrc32GuidedSectionExtractLibConstructor (\r
a5ff00a6 220 IN EFI_HANDLE ImageHandle,\r
221 IN EFI_SYSTEM_TABLE *SystemTable\r
d51ffc1f
LG
222 )\r
223{\r
224 return ExtractGuidedSectionRegisterHandlers (\r
76f1dde2 225 &gEfiCrc32GuidedSectionExtractionGuid,\r
d51ffc1f
LG
226 Crc32GuidedSectionGetInfo,\r
227 Crc32GuidedSectionHandler\r
228 );\r
229}\r
230\r