]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[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
1436aea4
MK
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 28typedef struct {\r
1436aea4
MK
29 EFI_GUID_DEFINED_SECTION2 GuidedSectionHeader; ///< EFI guided section header\r
30 UINT32 CRC32Checksum; ///< 32bit CRC check sum\r
30f001ca
SZ
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
1436aea4
MK
63 &gEfiCrc32GuidedSectionExtractionGuid,\r
64 &(((EFI_GUID_DEFINED_SECTION2 *)InputSection)->SectionDefinitionGuid)\r
65 ))\r
66 {\r
30f001ca
SZ
67 return EFI_INVALID_PARAMETER;\r
68 }\r
1436aea4 69\r
30f001ca
SZ
70 //\r
71 // Retrieve the size and attribute of the input section data.\r
72 //\r
1436aea4 73 *SectionAttribute = ((EFI_GUID_DEFINED_SECTION2 *)InputSection)->Attributes;\r
30f001ca 74 *ScratchBufferSize = 0;\r
1436aea4 75 *OutputBufferSize = SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *)InputSection)->DataOffset;\r
30f001ca
SZ
76 } else {\r
77 //\r
78 // Check whether the input guid section is recognized.\r
79 //\r
80 if (!CompareGuid (\r
1436aea4
MK
81 &gEfiCrc32GuidedSectionExtractionGuid,\r
82 &(((EFI_GUID_DEFINED_SECTION *)InputSection)->SectionDefinitionGuid)\r
83 ))\r
84 {\r
30f001ca
SZ
85 return EFI_INVALID_PARAMETER;\r
86 }\r
1436aea4 87\r
30f001ca
SZ
88 //\r
89 // Retrieve the size and attribute of the input section data.\r
90 //\r
1436aea4 91 *SectionAttribute = ((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes;\r
30f001ca 92 *ScratchBufferSize = 0;\r
1436aea4 93 *OutputBufferSize = SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *)InputSection)->DataOffset;\r
e6c560aa 94 }\r
d51ffc1f
LG
95\r
96 return EFI_SUCCESS;\r
97}\r
98\r
5d69642d
LG
99/**\r
100\r
109e9a61
LG
101 Extraction handler tries to extract raw data from the input guided section.\r
102 It also does authentication check for 32bit CRC value in the input guided section.\r
d1102dba 103 It first checks whether the input guid section is supported.\r
109e9a61 104 If not, EFI_INVALID_PARAMETER will return.\r
5d69642d
LG
105\r
106 @param InputSection Buffer containing the input GUIDed section to be processed.\r
109e9a61 107 @param OutputBuffer Buffer to contain the output raw data allocated by the caller.\r
5d69642d
LG
108 @param ScratchBuffer A pointer to a caller-allocated buffer for function internal use.\r
109 @param AuthenticationStatus A pointer to a caller-allocated UINT32 that indicates the\r
109e9a61 110 authentication status of the output buffer.\r
5d69642d
LG
111\r
112 @retval EFI_SUCCESS Section Data and Auth Status is extracted successfully.\r
113 @retval EFI_INVALID_PARAMETER The GUID in InputSection does not match this instance guid.\r
114\r
115**/\r
d51ffc1f
LG
116EFI_STATUS\r
117EFIAPI\r
118Crc32GuidedSectionHandler (\r
119 IN CONST VOID *InputSection,\r
120 OUT VOID **OutputBuffer,\r
e3917e22 121 IN VOID *ScratchBuffer OPTIONAL,\r
d51ffc1f
LG
122 OUT UINT32 *AuthenticationStatus\r
123 )\r
d51ffc1f 124{\r
1436aea4
MK
125 EFI_STATUS Status;\r
126 UINT32 SectionCrc32Checksum;\r
127 UINT32 Crc32Checksum;\r
128 UINT32 OutputBufferSize;\r
129 VOID *DummyInterface;\r
d51ffc1f 130\r
30f001ca
SZ
131 if (IS_SECTION2 (InputSection)) {\r
132 //\r
133 // Check whether the input guid section is recognized.\r
134 //\r
135 if (!CompareGuid (\r
1436aea4
MK
136 &gEfiCrc32GuidedSectionExtractionGuid,\r
137 &(((EFI_GUID_DEFINED_SECTION2 *)InputSection)->SectionDefinitionGuid)\r
138 ))\r
139 {\r
30f001ca
SZ
140 return EFI_INVALID_PARAMETER;\r
141 }\r
d1102dba 142\r
30f001ca
SZ
143 //\r
144 // Get section Crc32 checksum.\r
145 //\r
1436aea4
MK
146 SectionCrc32Checksum = ((CRC32_SECTION2_HEADER *)InputSection)->CRC32Checksum;\r
147 *OutputBuffer = (UINT8 *)InputSection + ((EFI_GUID_DEFINED_SECTION2 *)InputSection)->DataOffset;\r
148 OutputBufferSize = SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *)InputSection)->DataOffset;\r
30f001ca
SZ
149\r
150 //\r
151 // Implicitly CRC32 GUIDed section should have STATUS_VALID bit set\r
152 //\r
1436aea4 153 ASSERT (((EFI_GUID_DEFINED_SECTION2 *)InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID);\r
30f001ca
SZ
154 *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED;\r
155 } else {\r
156 //\r
157 // Check whether the input guid section is recognized.\r
158 //\r
159 if (!CompareGuid (\r
1436aea4
MK
160 &gEfiCrc32GuidedSectionExtractionGuid,\r
161 &(((EFI_GUID_DEFINED_SECTION *)InputSection)->SectionDefinitionGuid)\r
162 ))\r
163 {\r
30f001ca
SZ
164 return EFI_INVALID_PARAMETER;\r
165 }\r
d1102dba 166\r
30f001ca
SZ
167 //\r
168 // Get section Crc32 checksum.\r
169 //\r
1436aea4
MK
170 SectionCrc32Checksum = ((CRC32_SECTION_HEADER *)InputSection)->CRC32Checksum;\r
171 *OutputBuffer = (UINT8 *)InputSection + ((EFI_GUID_DEFINED_SECTION *)InputSection)->DataOffset;\r
172 OutputBufferSize = SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *)InputSection)->DataOffset;\r
30f001ca
SZ
173\r
174 //\r
175 // Implicitly CRC32 GUIDed section should have STATUS_VALID bit set\r
176 //\r
1436aea4 177 ASSERT (((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID);\r
30f001ca
SZ
178 *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED;\r
179 }\r
180\r
5d69642d
LG
181 //\r
182 // Init Checksum value to Zero.\r
183 //\r
d51ffc1f 184 Crc32Checksum = 0;\r
d51ffc1f
LG
185\r
186 //\r
187 // Check whether there exists EFI_SECURITY_POLICY_PROTOCOL_GUID.\r
188 //\r
189 Status = gBS->LocateProtocol (&gEfiSecurityPolicyProtocolGuid, NULL, &DummyInterface);\r
190 if (!EFI_ERROR (Status)) {\r
5d69642d
LG
191 //\r
192 // If SecurityPolicy Protocol exist, AUTH platform override bit is set.\r
193 //\r
d51ffc1f
LG
194 *AuthenticationStatus |= EFI_AUTH_STATUS_PLATFORM_OVERRIDE;\r
195 } else {\r
196 //\r
197 // Calculate CRC32 Checksum of Image\r
198 //\r
199 Status = gBS->CalculateCrc32 (*OutputBuffer, OutputBufferSize, &Crc32Checksum);\r
200 if (Status == EFI_SUCCESS) {\r
30f001ca 201 if (Crc32Checksum != SectionCrc32Checksum) {\r
5d69642d
LG
202 //\r
203 // If Crc32 checksum is not matched, AUTH tested failed bit is set.\r
204 //\r
d51ffc1f
LG
205 *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;\r
206 }\r
207 } else {\r
5d69642d
LG
208 //\r
209 // If Crc32 checksum is not calculated, AUTH not tested bit is set.\r
210 //\r
d51ffc1f
LG
211 *AuthenticationStatus |= EFI_AUTH_STATUS_NOT_TESTED;\r
212 }\r
213 }\r
214\r
215 return EFI_SUCCESS;\r
216}\r
217\r
5d69642d 218/**\r
109e9a61 219 Register the handler to extract CRC32 guided section.\r
5d69642d 220\r
cebc8d48
LG
221 @param ImageHandle ImageHandle of the loaded driver.\r
222 @param SystemTable Pointer to the EFI System Table.\r
223\r
109e9a61
LG
224 @retval EFI_SUCCESS Register successfully.\r
225 @retval EFI_OUT_OF_RESOURCES No enough memory to register this handler.\r
d51ffc1f
LG
226**/\r
227EFI_STATUS\r
228EFIAPI\r
229DxeCrc32GuidedSectionExtractLibConstructor (\r
a5ff00a6 230 IN EFI_HANDLE ImageHandle,\r
231 IN EFI_SYSTEM_TABLE *SystemTable\r
d51ffc1f
LG
232 )\r
233{\r
234 return ExtractGuidedSectionRegisterHandlers (\r
1436aea4
MK
235 &gEfiCrc32GuidedSectionExtractionGuid,\r
236 Crc32GuidedSectionGetInfo,\r
237 Crc32GuidedSectionHandler\r
238 );\r
d51ffc1f 239}\r