]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/DxeImageVerificationLib/Measurement.c
SecurityPkg: Replace BSD License with BSD+Patent License
[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
22 CHAR16 *VariableName;\r
23 EFI_GUID *VendorGuid;\r
24} VARIABLE_TYPE;\r
25\r
26typedef struct {\r
27 CHAR16 *VariableName;\r
28 EFI_GUID *VendorGuid;\r
29 VOID *Data;\r
30 UINTN Size;\r
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
40 {EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid},\r
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
52 IN CHAR16 *VarName\r
53 )\r
54{\r
55 UINTN Index;\r
56\r
57 for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {\r
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
75 IN EFI_GUID *VendorGuid\r
76 )\r
77{\r
78 UINTN Index;\r
79\r
80 for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {\r
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
102 IN CHAR16 *VarName,\r
103 IN EFI_GUID *VendorGuid,\r
104 IN VOID *Data,\r
105 IN UINTN Size\r
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
115 NewMeasuredAuthorityList = AllocateZeroPool (sizeof(VARIABLE_RECORD) * (mMeasuredAuthorityCountMax + MEASURED_AUTHORITY_COUNT_MAX));\r
116 if (NewMeasuredAuthorityList == NULL) {\r
117 return EFI_OUT_OF_RESOURCES;\r
118 }\r
119 if (mMeasuredAuthorityList != NULL) {\r
120 CopyMem (NewMeasuredAuthorityList, mMeasuredAuthorityList, sizeof(VARIABLE_RECORD) * mMeasuredAuthorityCount);\r
121 FreePool (mMeasuredAuthorityList);\r
122 }\r
123 mMeasuredAuthorityList = NewMeasuredAuthorityList;\r
124 mMeasuredAuthorityCountMax += MEASURED_AUTHORITY_COUNT_MAX;\r
125 }\r
126\r
127 //\r
128 // Add new entry\r
129 //\r
130 mMeasuredAuthorityList[mMeasuredAuthorityCount].VariableName = AssignVarName (VarName);\r
131 mMeasuredAuthorityList[mMeasuredAuthorityCount].VendorGuid = AssignVendorGuid (VendorGuid);\r
132 mMeasuredAuthorityList[mMeasuredAuthorityCount].Size = Size;\r
133 mMeasuredAuthorityList[mMeasuredAuthorityCount].Data = AllocatePool (Size);\r
134 if (mMeasuredAuthorityList[mMeasuredAuthorityCount].Data == NULL) {\r
135 return EFI_OUT_OF_RESOURCES;\r
136 }\r
137 CopyMem (mMeasuredAuthorityList[mMeasuredAuthorityCount].Data, Data, Size);\r
138 mMeasuredAuthorityCount++;\r
139\r
140 return EFI_SUCCESS;\r
141}\r
142\r
143/**\r
144 This function will return if this variable is already measured.\r
145\r
146 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
147 @param[in] VendorGuid A unique identifier for the vendor.\r
b3548d32
LG
148 @param[in] VarData The content of the variable data.\r
149 @param[in] VarSize The size of the variable data.\r
c1d93242
JY
150\r
151 @retval TRUE The data is already measured.\r
152 @retval FALSE The data is not measured yet.\r
153**/\r
154BOOLEAN\r
155IsDataMeasured (\r
156 IN CHAR16 *VarName,\r
157 IN EFI_GUID *VendorGuid,\r
158 IN VOID *Data,\r
159 IN UINTN Size\r
160 )\r
161{\r
162 UINTN Index;\r
163\r
164 for (Index = 0; Index < mMeasuredAuthorityCount; Index++) {\r
165 if ((StrCmp (VarName, mMeasuredAuthorityList[Index].VariableName) == 0) &&\r
166 (CompareGuid (VendorGuid, mMeasuredAuthorityList[Index].VendorGuid)) &&\r
167 (CompareMem (Data, mMeasuredAuthorityList[Index].Data, Size) == 0) &&\r
168 (Size == mMeasuredAuthorityList[Index].Size)) {\r
169 return TRUE;\r
170 }\r
171 }\r
172\r
173 return FALSE;\r
174}\r
175\r
176/**\r
177 This function will return if this variable is SecureAuthority Variable.\r
178\r
179 @param[in] VariableName A Null-terminated string that is the name of the vendor's variable.\r
180 @param[in] VendorGuid A unique identifier for the vendor.\r
181\r
182 @retval TRUE This is SecureAuthority Variable\r
183 @retval FALSE This is not SecureAuthority Variable\r
184**/\r
185BOOLEAN\r
186IsSecureAuthorityVariable (\r
187 IN CHAR16 *VariableName,\r
188 IN EFI_GUID *VendorGuid\r
189 )\r
190{\r
191 UINTN Index;\r
192\r
193 for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {\r
b3548d32 194 if ((StrCmp (VariableName, mVariableType[Index].VariableName) == 0) &&\r
c1d93242
JY
195 (CompareGuid (VendorGuid, mVariableType[Index].VendorGuid))) {\r
196 return TRUE;\r
197 }\r
198 }\r
199 return FALSE;\r
200}\r
201\r
202/**\r
203 Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
204\r
205 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
206 @param[in] VendorGuid A unique identifier for the vendor.\r
b3548d32
LG
207 @param[in] VarData The content of the variable data.\r
208 @param[in] VarSize The size of the variable data.\r
209\r
c1d93242
JY
210 @retval EFI_SUCCESS Operation completed successfully.\r
211 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
212 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
213\r
214**/\r
215EFI_STATUS\r
216EFIAPI\r
217MeasureVariable (\r
218 IN CHAR16 *VarName,\r
219 IN EFI_GUID *VendorGuid,\r
220 IN VOID *VarData,\r
221 IN UINTN VarSize\r
222 )\r
223{\r
224 EFI_STATUS Status;\r
225 UINTN VarNameLength;\r
9d77acf1 226 UEFI_VARIABLE_DATA *VarLog;\r
c1d93242
JY
227 UINT32 VarLogSize;\r
228\r
229 //\r
9d77acf1 230 // The UEFI_VARIABLE_DATA.VariableData value shall be the EFI_SIGNATURE_DATA value\r
c1d93242
JY
231 // from the EFI_SIGNATURE_LIST that contained the authority that was used to validate the image\r
232 //\r
233 VarNameLength = StrLen (VarName);\r
234 VarLogSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize\r
235 - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));\r
236\r
9d77acf1 237 VarLog = (UEFI_VARIABLE_DATA *) AllocateZeroPool (VarLogSize);\r
c1d93242
JY
238 if (VarLog == NULL) {\r
239 return EFI_OUT_OF_RESOURCES;\r
240 }\r
241\r
242 CopyMem (&VarLog->VariableName, VendorGuid, sizeof(VarLog->VariableName));\r
243 VarLog->UnicodeNameLength = VarNameLength;\r
244 VarLog->VariableDataLength = VarSize;\r
245 CopyMem (\r
246 VarLog->UnicodeName,\r
247 VarName,\r
248 VarNameLength * sizeof (*VarName)\r
249 );\r
250 CopyMem (\r
251 (CHAR16 *)VarLog->UnicodeName + VarNameLength,\r
252 VarData,\r
253 VarSize\r
254 );\r
255\r
256 DEBUG ((EFI_D_INFO, "DxeImageVerification: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)7, (UINTN)EV_EFI_VARIABLE_AUTHORITY));\r
257 DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));\r
258\r
259 Status = TpmMeasureAndLogData (\r
260 7,\r
261 EV_EFI_VARIABLE_AUTHORITY,\r
262 VarLog,\r
263 VarLogSize,\r
264 VarLog,\r
265 VarLogSize\r
266 );\r
267 FreePool (VarLog);\r
268\r
269 return Status;\r
270}\r
271\r
272/**\r
273 SecureBoot Hook for processing image verification.\r
274\r
275 @param[in] VariableName Name of Variable to be found.\r
276 @param[in] VendorGuid Variable vendor GUID.\r
277 @param[in] DataSize Size of Data found. If size is less than the\r
278 data, this value contains the required size.\r
279 @param[in] Data Data pointer.\r
280\r
281**/\r
282VOID\r
283EFIAPI\r
284SecureBootHook (\r
285 IN CHAR16 *VariableName,\r
286 IN EFI_GUID *VendorGuid,\r
287 IN UINTN DataSize,\r
288 IN VOID *Data\r
289 )\r
290{\r
291 EFI_STATUS Status;\r
292\r
293 if (!IsSecureAuthorityVariable (VariableName, VendorGuid)) {\r
294 return ;\r
295 }\r
296\r
297 if (IsDataMeasured (VariableName, VendorGuid, Data, DataSize)) {\r
298 DEBUG ((EFI_D_ERROR, "MeasureSecureAuthorityVariable - IsDataMeasured\n"));\r
299 return ;\r
300 }\r
301\r
302 Status = MeasureVariable (\r
303 VariableName,\r
304 VendorGuid,\r
305 Data,\r
306 DataSize\r
307 );\r
33985e3b 308 DEBUG ((EFI_D_INFO, "MeasureBootPolicyVariable - %r\n", Status));\r
c1d93242
JY
309\r
310 if (!EFI_ERROR (Status)) {\r
311 AddDataMeasured (VariableName, VendorGuid, Data, DataSize);\r
312 }\r
313\r
314 return ;\r
315}\r