]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/DxeImageVerificationLib/Measurement.c
SecurityPkg: Tcg2Dxe: Use UEFI_VARIABLE_DATA
[mirror_edk2.git] / SecurityPkg / Library / DxeImageVerificationLib / Measurement.c
CommitLineData
c1d93242 1/** @file\r
9d77acf1 2 Measure TCG required variable.\r
c1d93242 3\r
9d77acf1 4Copyright (c) 2013 - 2017, 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
c1d93242
JY
18\r
19#include <Library/UefiBootServicesTableLib.h>\r
20#include <Library/UefiRuntimeServicesTableLib.h>\r
21#include <Library/MemoryAllocationLib.h>\r
22#include <Library/BaseMemoryLib.h>\r
23#include <Library/DebugLib.h>\r
24#include <Library/BaseLib.h>\r
25#include <Library/TpmMeasurementLib.h>\r
26\r
27typedef struct {\r
28 CHAR16 *VariableName;\r
29 EFI_GUID *VendorGuid;\r
30} VARIABLE_TYPE;\r
31\r
32typedef struct {\r
33 CHAR16 *VariableName;\r
34 EFI_GUID *VendorGuid;\r
35 VOID *Data;\r
36 UINTN Size;\r
37} VARIABLE_RECORD;\r
38\r
39#define MEASURED_AUTHORITY_COUNT_MAX 0x100\r
40\r
41UINTN mMeasuredAuthorityCount = 0;\r
42UINTN mMeasuredAuthorityCountMax = 0;\r
43VARIABLE_RECORD *mMeasuredAuthorityList = NULL;\r
44\r
45VARIABLE_TYPE mVariableType[] = {\r
46 {EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid},\r
47};\r
48\r
49/**\r
50 This function will check if VarName should be recorded and return the address of VarName if it is needed.\r
51\r
52 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
53\r
54 @return the address of VarName.\r
55**/\r
56CHAR16 *\r
57AssignVarName (\r
58 IN CHAR16 *VarName\r
59 )\r
60{\r
61 UINTN Index;\r
62\r
63 for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {\r
64 if (StrCmp (VarName, mVariableType[Index].VariableName) == 0) {\r
65 return mVariableType[Index].VariableName;\r
66 }\r
67 }\r
68\r
69 return NULL;\r
70}\r
71\r
72/**\r
73 This function will check if VendorGuid should be recorded and return the address of VendorGuid if it is needed.\r
74\r
75 @param[in] VendorGuid A unique identifier for the vendor.\r
76\r
77 @return the address of VendorGuid.\r
78**/\r
79EFI_GUID *\r
80AssignVendorGuid (\r
81 IN EFI_GUID *VendorGuid\r
82 )\r
83{\r
84 UINTN Index;\r
85\r
86 for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {\r
87 if (CompareGuid (VendorGuid, mVariableType[Index].VendorGuid)) {\r
88 return mVariableType[Index].VendorGuid;\r
89 }\r
90 }\r
91\r
92 return NULL;\r
93}\r
94\r
95/**\r
96 This function will add variable information to MeasuredAuthorityList.\r
97\r
98 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
99 @param[in] VendorGuid A unique identifier for the vendor.\r
100 @param[in] VarData The content of the variable data. \r
101 @param[in] VarSize The size of the variable data. \r
102 \r
103 @retval EFI_SUCCESS Operation completed successfully.\r
104 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
105**/\r
106EFI_STATUS\r
107AddDataMeasured (\r
108 IN CHAR16 *VarName,\r
109 IN EFI_GUID *VendorGuid,\r
110 IN VOID *Data,\r
111 IN UINTN Size\r
112 )\r
113{\r
114 VARIABLE_RECORD *NewMeasuredAuthorityList;\r
115\r
116 ASSERT (mMeasuredAuthorityCount <= mMeasuredAuthorityCountMax);\r
117 if (mMeasuredAuthorityCount == mMeasuredAuthorityCountMax) {\r
118 //\r
119 // Need enlarge\r
120 //\r
121 NewMeasuredAuthorityList = AllocateZeroPool (sizeof(VARIABLE_RECORD) * (mMeasuredAuthorityCountMax + MEASURED_AUTHORITY_COUNT_MAX));\r
122 if (NewMeasuredAuthorityList == NULL) {\r
123 return EFI_OUT_OF_RESOURCES;\r
124 }\r
125 if (mMeasuredAuthorityList != NULL) {\r
126 CopyMem (NewMeasuredAuthorityList, mMeasuredAuthorityList, sizeof(VARIABLE_RECORD) * mMeasuredAuthorityCount);\r
127 FreePool (mMeasuredAuthorityList);\r
128 }\r
129 mMeasuredAuthorityList = NewMeasuredAuthorityList;\r
130 mMeasuredAuthorityCountMax += MEASURED_AUTHORITY_COUNT_MAX;\r
131 }\r
132\r
133 //\r
134 // Add new entry\r
135 //\r
136 mMeasuredAuthorityList[mMeasuredAuthorityCount].VariableName = AssignVarName (VarName);\r
137 mMeasuredAuthorityList[mMeasuredAuthorityCount].VendorGuid = AssignVendorGuid (VendorGuid);\r
138 mMeasuredAuthorityList[mMeasuredAuthorityCount].Size = Size;\r
139 mMeasuredAuthorityList[mMeasuredAuthorityCount].Data = AllocatePool (Size);\r
140 if (mMeasuredAuthorityList[mMeasuredAuthorityCount].Data == NULL) {\r
141 return EFI_OUT_OF_RESOURCES;\r
142 }\r
143 CopyMem (mMeasuredAuthorityList[mMeasuredAuthorityCount].Data, Data, Size);\r
144 mMeasuredAuthorityCount++;\r
145\r
146 return EFI_SUCCESS;\r
147}\r
148\r
149/**\r
150 This function will return if this variable is already measured.\r
151\r
152 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
153 @param[in] VendorGuid A unique identifier for the vendor.\r
154 @param[in] VarData The content of the variable data. \r
155 @param[in] VarSize The size of the variable data. \r
156\r
157 @retval TRUE The data is already measured.\r
158 @retval FALSE The data is not measured yet.\r
159**/\r
160BOOLEAN\r
161IsDataMeasured (\r
162 IN CHAR16 *VarName,\r
163 IN EFI_GUID *VendorGuid,\r
164 IN VOID *Data,\r
165 IN UINTN Size\r
166 )\r
167{\r
168 UINTN Index;\r
169\r
170 for (Index = 0; Index < mMeasuredAuthorityCount; Index++) {\r
171 if ((StrCmp (VarName, mMeasuredAuthorityList[Index].VariableName) == 0) &&\r
172 (CompareGuid (VendorGuid, mMeasuredAuthorityList[Index].VendorGuid)) &&\r
173 (CompareMem (Data, mMeasuredAuthorityList[Index].Data, Size) == 0) &&\r
174 (Size == mMeasuredAuthorityList[Index].Size)) {\r
175 return TRUE;\r
176 }\r
177 }\r
178\r
179 return FALSE;\r
180}\r
181\r
182/**\r
183 This function will return if this variable is SecureAuthority Variable.\r
184\r
185 @param[in] VariableName A Null-terminated string that is the name of the vendor's variable.\r
186 @param[in] VendorGuid A unique identifier for the vendor.\r
187\r
188 @retval TRUE This is SecureAuthority Variable\r
189 @retval FALSE This is not SecureAuthority Variable\r
190**/\r
191BOOLEAN\r
192IsSecureAuthorityVariable (\r
193 IN CHAR16 *VariableName,\r
194 IN EFI_GUID *VendorGuid\r
195 )\r
196{\r
197 UINTN Index;\r
198\r
199 for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {\r
200 if ((StrCmp (VariableName, mVariableType[Index].VariableName) == 0) && \r
201 (CompareGuid (VendorGuid, mVariableType[Index].VendorGuid))) {\r
202 return TRUE;\r
203 }\r
204 }\r
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
213 @param[in] VarData The content of the variable data. \r
214 @param[in] VarSize The size of the variable data. \r
215 \r
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
224 IN CHAR16 *VarName,\r
225 IN EFI_GUID *VendorGuid,\r
226 IN VOID *VarData,\r
227 IN UINTN VarSize\r
228 )\r
229{\r
230 EFI_STATUS Status;\r
231 UINTN VarNameLength;\r
9d77acf1 232 UEFI_VARIABLE_DATA *VarLog;\r
c1d93242
JY
233 UINT32 VarLogSize;\r
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
239 VarNameLength = StrLen (VarName);\r
240 VarLogSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize\r
241 - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));\r
242\r
9d77acf1 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
248 CopyMem (&VarLog->VariableName, VendorGuid, sizeof(VarLog->VariableName));\r
249 VarLog->UnicodeNameLength = VarNameLength;\r
250 VarLog->VariableDataLength = VarSize;\r
251 CopyMem (\r
252 VarLog->UnicodeName,\r
253 VarName,\r
254 VarNameLength * sizeof (*VarName)\r
255 );\r
256 CopyMem (\r
257 (CHAR16 *)VarLog->UnicodeName + VarNameLength,\r
258 VarData,\r
259 VarSize\r
260 );\r
261\r
262 DEBUG ((EFI_D_INFO, "DxeImageVerification: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)7, (UINTN)EV_EFI_VARIABLE_AUTHORITY));\r
263 DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));\r
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
291 IN CHAR16 *VariableName,\r
292 IN EFI_GUID *VendorGuid,\r
293 IN UINTN DataSize,\r
294 IN VOID *Data\r
295 )\r
296{\r
297 EFI_STATUS Status;\r
298\r
299 if (!IsSecureAuthorityVariable (VariableName, VendorGuid)) {\r
300 return ;\r
301 }\r
302\r
303 if (IsDataMeasured (VariableName, VendorGuid, Data, DataSize)) {\r
304 DEBUG ((EFI_D_ERROR, "MeasureSecureAuthorityVariable - IsDataMeasured\n"));\r
305 return ;\r
306 }\r
307\r
308 Status = MeasureVariable (\r
309 VariableName,\r
310 VendorGuid,\r
311 Data,\r
312 DataSize\r
313 );\r
33985e3b 314 DEBUG ((EFI_D_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
320 return ;\r
321}\r