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