]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/DxeImageVerificationLib/Measurement.c
SecurityPkg: Apply uncrustify changes
[mirror_edk2.git] / SecurityPkg / Library / DxeImageVerificationLib / Measurement.c
CommitLineData
c1d93242 1/** @file\r
9d77acf1 2 Measure TCG required variable.\r
c1d93242 3\r
b3548d32 4Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>\r
289b714b 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
c1d93242
JY
6\r
7**/\r
8\r
9#include <PiDxe.h>\r
10#include <Guid/ImageAuthentication.h>\r
11#include <IndustryStandard/UefiTcgPlatform.h>\r
c1d93242
JY
12\r
13#include <Library/UefiBootServicesTableLib.h>\r
14#include <Library/UefiRuntimeServicesTableLib.h>\r
15#include <Library/MemoryAllocationLib.h>\r
16#include <Library/BaseMemoryLib.h>\r
17#include <Library/DebugLib.h>\r
18#include <Library/BaseLib.h>\r
19#include <Library/TpmMeasurementLib.h>\r
20\r
21typedef struct {\r
c411b485
MK
22 CHAR16 *VariableName;\r
23 EFI_GUID *VendorGuid;\r
c1d93242
JY
24} VARIABLE_TYPE;\r
25\r
26typedef struct {\r
c411b485
MK
27 CHAR16 *VariableName;\r
28 EFI_GUID *VendorGuid;\r
29 VOID *Data;\r
30 UINTN Size;\r
c1d93242
JY
31} VARIABLE_RECORD;\r
32\r
33#define MEASURED_AUTHORITY_COUNT_MAX 0x100\r
34\r
35UINTN mMeasuredAuthorityCount = 0;\r
36UINTN mMeasuredAuthorityCountMax = 0;\r
37VARIABLE_RECORD *mMeasuredAuthorityList = NULL;\r
38\r
39VARIABLE_TYPE mVariableType[] = {\r
c411b485 40 { EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid },\r
c1d93242
JY
41};\r
42\r
43/**\r
44 This function will check if VarName should be recorded and return the address of VarName if it is needed.\r
45\r
46 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
47\r
48 @return the address of VarName.\r
49**/\r
50CHAR16 *\r
51AssignVarName (\r
c411b485 52 IN CHAR16 *VarName\r
c1d93242
JY
53 )\r
54{\r
55 UINTN Index;\r
56\r
c411b485 57 for (Index = 0; Index < sizeof (mVariableType)/sizeof (mVariableType[0]); Index++) {\r
c1d93242
JY
58 if (StrCmp (VarName, mVariableType[Index].VariableName) == 0) {\r
59 return mVariableType[Index].VariableName;\r
60 }\r
61 }\r
62\r
63 return NULL;\r
64}\r
65\r
66/**\r
67 This function will check if VendorGuid should be recorded and return the address of VendorGuid if it is needed.\r
68\r
69 @param[in] VendorGuid A unique identifier for the vendor.\r
70\r
71 @return the address of VendorGuid.\r
72**/\r
73EFI_GUID *\r
74AssignVendorGuid (\r
c411b485 75 IN EFI_GUID *VendorGuid\r
c1d93242
JY
76 )\r
77{\r
78 UINTN Index;\r
79\r
c411b485 80 for (Index = 0; Index < sizeof (mVariableType)/sizeof (mVariableType[0]); Index++) {\r
c1d93242
JY
81 if (CompareGuid (VendorGuid, mVariableType[Index].VendorGuid)) {\r
82 return mVariableType[Index].VendorGuid;\r
83 }\r
84 }\r
85\r
86 return NULL;\r
87}\r
88\r
89/**\r
90 This function will add variable information to MeasuredAuthorityList.\r
91\r
92 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
93 @param[in] VendorGuid A unique identifier for the vendor.\r
b3548d32
LG
94 @param[in] VarData The content of the variable data.\r
95 @param[in] VarSize The size of the variable data.\r
96\r
c1d93242
JY
97 @retval EFI_SUCCESS Operation completed successfully.\r
98 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
99**/\r
100EFI_STATUS\r
101AddDataMeasured (\r
c411b485
MK
102 IN CHAR16 *VarName,\r
103 IN EFI_GUID *VendorGuid,\r
104 IN VOID *Data,\r
105 IN UINTN Size\r
c1d93242
JY
106 )\r
107{\r
108 VARIABLE_RECORD *NewMeasuredAuthorityList;\r
109\r
110 ASSERT (mMeasuredAuthorityCount <= mMeasuredAuthorityCountMax);\r
111 if (mMeasuredAuthorityCount == mMeasuredAuthorityCountMax) {\r
112 //\r
113 // Need enlarge\r
114 //\r
c411b485 115 NewMeasuredAuthorityList = AllocateZeroPool (sizeof (VARIABLE_RECORD) * (mMeasuredAuthorityCountMax + MEASURED_AUTHORITY_COUNT_MAX));\r
c1d93242
JY
116 if (NewMeasuredAuthorityList == NULL) {\r
117 return EFI_OUT_OF_RESOURCES;\r
118 }\r
c411b485 119\r
c1d93242 120 if (mMeasuredAuthorityList != NULL) {\r
c411b485 121 CopyMem (NewMeasuredAuthorityList, mMeasuredAuthorityList, sizeof (VARIABLE_RECORD) * mMeasuredAuthorityCount);\r
c1d93242
JY
122 FreePool (mMeasuredAuthorityList);\r
123 }\r
c411b485
MK
124\r
125 mMeasuredAuthorityList = NewMeasuredAuthorityList;\r
c1d93242
JY
126 mMeasuredAuthorityCountMax += MEASURED_AUTHORITY_COUNT_MAX;\r
127 }\r
128\r
129 //\r
130 // Add new entry\r
131 //\r
132 mMeasuredAuthorityList[mMeasuredAuthorityCount].VariableName = AssignVarName (VarName);\r
133 mMeasuredAuthorityList[mMeasuredAuthorityCount].VendorGuid = AssignVendorGuid (VendorGuid);\r
134 mMeasuredAuthorityList[mMeasuredAuthorityCount].Size = Size;\r
135 mMeasuredAuthorityList[mMeasuredAuthorityCount].Data = AllocatePool (Size);\r
136 if (mMeasuredAuthorityList[mMeasuredAuthorityCount].Data == NULL) {\r
137 return EFI_OUT_OF_RESOURCES;\r
138 }\r
c411b485 139\r
c1d93242
JY
140 CopyMem (mMeasuredAuthorityList[mMeasuredAuthorityCount].Data, Data, Size);\r
141 mMeasuredAuthorityCount++;\r
142\r
143 return EFI_SUCCESS;\r
144}\r
145\r
146/**\r
147 This function will return if this variable is already measured.\r
148\r
149 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
150 @param[in] VendorGuid A unique identifier for the vendor.\r
b3548d32
LG
151 @param[in] VarData The content of the variable data.\r
152 @param[in] VarSize The size of the variable data.\r
c1d93242
JY
153\r
154 @retval TRUE The data is already measured.\r
155 @retval FALSE The data is not measured yet.\r
156**/\r
157BOOLEAN\r
158IsDataMeasured (\r
c411b485
MK
159 IN CHAR16 *VarName,\r
160 IN EFI_GUID *VendorGuid,\r
161 IN VOID *Data,\r
162 IN UINTN Size\r
c1d93242
JY
163 )\r
164{\r
165 UINTN Index;\r
166\r
167 for (Index = 0; Index < mMeasuredAuthorityCount; Index++) {\r
168 if ((StrCmp (VarName, mMeasuredAuthorityList[Index].VariableName) == 0) &&\r
169 (CompareGuid (VendorGuid, mMeasuredAuthorityList[Index].VendorGuid)) &&\r
170 (CompareMem (Data, mMeasuredAuthorityList[Index].Data, Size) == 0) &&\r
c411b485
MK
171 (Size == mMeasuredAuthorityList[Index].Size))\r
172 {\r
c1d93242
JY
173 return TRUE;\r
174 }\r
175 }\r
176\r
177 return FALSE;\r
178}\r
179\r
180/**\r
181 This function will return if this variable is SecureAuthority Variable.\r
182\r
183 @param[in] VariableName A Null-terminated string that is the name of the vendor's variable.\r
184 @param[in] VendorGuid A unique identifier for the vendor.\r
185\r
186 @retval TRUE This is SecureAuthority Variable\r
187 @retval FALSE This is not SecureAuthority Variable\r
188**/\r
189BOOLEAN\r
190IsSecureAuthorityVariable (\r
c411b485
MK
191 IN CHAR16 *VariableName,\r
192 IN EFI_GUID *VendorGuid\r
c1d93242
JY
193 )\r
194{\r
c411b485 195 UINTN Index;\r
c1d93242 196\r
c411b485 197 for (Index = 0; Index < sizeof (mVariableType)/sizeof (mVariableType[0]); Index++) {\r
b3548d32 198 if ((StrCmp (VariableName, mVariableType[Index].VariableName) == 0) &&\r
c411b485
MK
199 (CompareGuid (VendorGuid, mVariableType[Index].VendorGuid)))\r
200 {\r
c1d93242
JY
201 return TRUE;\r
202 }\r
203 }\r
c411b485 204\r
c1d93242
JY
205 return FALSE;\r
206}\r
207\r
208/**\r
209 Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
210\r
211 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
212 @param[in] VendorGuid A unique identifier for the vendor.\r
b3548d32
LG
213 @param[in] VarData The content of the variable data.\r
214 @param[in] VarSize The size of the variable data.\r
215\r
c1d93242
JY
216 @retval EFI_SUCCESS Operation completed successfully.\r
217 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
218 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
219\r
220**/\r
221EFI_STATUS\r
222EFIAPI\r
223MeasureVariable (\r
c411b485
MK
224 IN CHAR16 *VarName,\r
225 IN EFI_GUID *VendorGuid,\r
226 IN VOID *VarData,\r
227 IN UINTN VarSize\r
c1d93242
JY
228 )\r
229{\r
c411b485
MK
230 EFI_STATUS Status;\r
231 UINTN VarNameLength;\r
232 UEFI_VARIABLE_DATA *VarLog;\r
233 UINT32 VarLogSize;\r
c1d93242
JY
234\r
235 //\r
9d77acf1 236 // The UEFI_VARIABLE_DATA.VariableData value shall be the EFI_SIGNATURE_DATA value\r
c1d93242
JY
237 // from the EFI_SIGNATURE_LIST that contained the authority that was used to validate the image\r
238 //\r
c411b485
MK
239 VarNameLength = StrLen (VarName);\r
240 VarLogSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize\r
241 - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));\r
c1d93242 242\r
c411b485 243 VarLog = (UEFI_VARIABLE_DATA *)AllocateZeroPool (VarLogSize);\r
c1d93242
JY
244 if (VarLog == NULL) {\r
245 return EFI_OUT_OF_RESOURCES;\r
246 }\r
247\r
c411b485 248 CopyMem (&VarLog->VariableName, VendorGuid, sizeof (VarLog->VariableName));\r
c1d93242
JY
249 VarLog->UnicodeNameLength = VarNameLength;\r
250 VarLog->VariableDataLength = VarSize;\r
251 CopyMem (\r
c411b485
MK
252 VarLog->UnicodeName,\r
253 VarName,\r
254 VarNameLength * sizeof (*VarName)\r
255 );\r
c1d93242 256 CopyMem (\r
c411b485
MK
257 (CHAR16 *)VarLog->UnicodeName + VarNameLength,\r
258 VarData,\r
259 VarSize\r
260 );\r
c1d93242 261\r
e905fbb0
MK
262 DEBUG ((DEBUG_INFO, "DxeImageVerification: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)7, (UINTN)EV_EFI_VARIABLE_AUTHORITY));\r
263 DEBUG ((DEBUG_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));\r
c1d93242
JY
264\r
265 Status = TpmMeasureAndLogData (\r
266 7,\r
267 EV_EFI_VARIABLE_AUTHORITY,\r
268 VarLog,\r
269 VarLogSize,\r
270 VarLog,\r
271 VarLogSize\r
272 );\r
273 FreePool (VarLog);\r
274\r
275 return Status;\r
276}\r
277\r
278/**\r
279 SecureBoot Hook for processing image verification.\r
280\r
281 @param[in] VariableName Name of Variable to be found.\r
282 @param[in] VendorGuid Variable vendor GUID.\r
283 @param[in] DataSize Size of Data found. If size is less than the\r
284 data, this value contains the required size.\r
285 @param[in] Data Data pointer.\r
286\r
287**/\r
288VOID\r
289EFIAPI\r
290SecureBootHook (\r
c411b485
MK
291 IN CHAR16 *VariableName,\r
292 IN EFI_GUID *VendorGuid,\r
293 IN UINTN DataSize,\r
294 IN VOID *Data\r
c1d93242
JY
295 )\r
296{\r
c411b485 297 EFI_STATUS Status;\r
c1d93242
JY
298\r
299 if (!IsSecureAuthorityVariable (VariableName, VendorGuid)) {\r
c411b485 300 return;\r
c1d93242
JY
301 }\r
302\r
303 if (IsDataMeasured (VariableName, VendorGuid, Data, DataSize)) {\r
e905fbb0 304 DEBUG ((DEBUG_ERROR, "MeasureSecureAuthorityVariable - IsDataMeasured\n"));\r
c411b485 305 return;\r
c1d93242
JY
306 }\r
307\r
308 Status = MeasureVariable (\r
309 VariableName,\r
310 VendorGuid,\r
311 Data,\r
312 DataSize\r
313 );\r
e905fbb0 314 DEBUG ((DEBUG_INFO, "MeasureBootPolicyVariable - %r\n", Status));\r
c1d93242
JY
315\r
316 if (!EFI_ERROR (Status)) {\r
317 AddDataMeasured (VariableName, VendorGuid, Data, DataSize);\r
318 }\r
319\r
c411b485 320 return;\r
c1d93242 321}\r