]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c
MdeModulePkg/dec: add PcdTcgPfpMeasurementRevision PCD
[mirror_edk2.git] / MdeModulePkg / Universal / SmbiosMeasurementDxe / SmbiosMeasurementDxe.c
CommitLineData
c00a0c87
JY
1/** @file\r
2 This driver measures SMBIOS table to TPM.\r
14c218b3 3\r
7f2f96f1 4Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
c00a0c87
JY
6\r
7**/\r
8\r
9#include <PiDxe.h>\r
10\r
11#include <Protocol/Smbios.h>\r
12#include <IndustryStandard/SmBios.h>\r
13#include <IndustryStandard/UefiTcgPlatform.h>\r
14#include <Guid/EventGroup.h>\r
15#include <Guid/SmBios.h>\r
16#include <Library/DebugLib.h>\r
17#include <Library/UefiDriverEntryPoint.h>\r
18#include <Library/UefiLib.h>\r
19#include <Library/BaseLib.h>\r
20#include <Library/BaseMemoryLib.h>\r
21#include <Library/MemoryAllocationLib.h>\r
22#include <Library/UefiBootServicesTableLib.h>\r
23#include <Library/TpmMeasurementLib.h>\r
24\r
25#define FIELD_SIZE_OF(TYPE, Field) ((UINTN)sizeof(((TYPE *)0)->Field))\r
26\r
27typedef struct {\r
28 UINT8 Type;\r
29 UINTN Offset;\r
30 UINTN Size;\r
31 UINT32 Flags;\r
32} SMBIOS_FILTER_TABLE;\r
33#define SMBIOS_FILTER_TABLE_FLAG_IS_STRING BIT0\r
34\r
35typedef struct {\r
36 UINT8 Type;\r
37 SMBIOS_FILTER_TABLE *Filter; // NULL means all fields\r
38 UINTN FilterCount;\r
39} SMBIOS_FILTER_STRUCT;\r
40\r
41//\r
42// Platform Specific Policy\r
43//\r
44SMBIOS_FILTER_TABLE mSmbiosFilterType1BlackList[] = {\r
45 {0x01, OFFSET_OF(SMBIOS_TABLE_TYPE1, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE1, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
46 {0x01, OFFSET_OF(SMBIOS_TABLE_TYPE1, Uuid), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE1, Uuid), 0},\r
47 {0x01, OFFSET_OF(SMBIOS_TABLE_TYPE1, WakeUpType), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE1, WakeUpType), 0},\r
48};\r
49SMBIOS_FILTER_TABLE mSmbiosFilterType2BlackList[] = {\r
50 {0x02, OFFSET_OF(SMBIOS_TABLE_TYPE2, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE2, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
51 {0x02, OFFSET_OF(SMBIOS_TABLE_TYPE2, LocationInChassis), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE2, LocationInChassis), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
52};\r
53SMBIOS_FILTER_TABLE mSmbiosFilterType3BlackList[] = {\r
54 {0x03, OFFSET_OF(SMBIOS_TABLE_TYPE3, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE3, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
55 {0x03, OFFSET_OF(SMBIOS_TABLE_TYPE3, AssetTag), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE3, AssetTag), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
56};\r
57SMBIOS_FILTER_TABLE mSmbiosFilterType4BlackList[] = {\r
58 {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
59 {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, AssetTag), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, AssetTag), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
60 {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, PartNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, PartNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
61 {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, CoreCount), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, CoreCount), 0},\r
62 {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, EnabledCoreCount), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, EnabledCoreCount), 0},\r
63 {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, ThreadCount), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, ThreadCount), 0},\r
64 {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, CoreCount2), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, CoreCount2), 0},\r
65 {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, EnabledCoreCount2), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, EnabledCoreCount2), 0},\r
66 {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, ThreadCount2), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, ThreadCount2), 0},\r
be0d1c17 67 {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, Voltage), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, Voltage), 0},\r
c00a0c87
JY
68};\r
69SMBIOS_FILTER_TABLE mSmbiosFilterType17BlackList[] = {\r
70 {0x11, OFFSET_OF(SMBIOS_TABLE_TYPE17, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE17, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
71 {0x11, OFFSET_OF(SMBIOS_TABLE_TYPE17, AssetTag), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE17, AssetTag), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
72 {0x11, OFFSET_OF(SMBIOS_TABLE_TYPE17, PartNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE17, PartNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
73};\r
74SMBIOS_FILTER_TABLE mSmbiosFilterType22BlackList[] = {\r
75 {0x16, OFFSET_OF(SMBIOS_TABLE_TYPE22, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE22, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
76 {0x16, OFFSET_OF(SMBIOS_TABLE_TYPE22, SBDSSerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE22, SBDSSerialNumber), 0},\r
77 {0x16, OFFSET_OF(SMBIOS_TABLE_TYPE22, SBDSManufactureDate), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE22, SBDSManufactureDate), 0},\r
78};\r
79SMBIOS_FILTER_TABLE mSmbiosFilterType23BlackList[] = {\r
80 {0x17, OFFSET_OF(SMBIOS_TABLE_TYPE23, ResetCount), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE23, ResetCount), 0},\r
81};\r
b8922094
SZ
82SMBIOS_FILTER_TABLE mSmbiosFilterType27BlackList[] = {\r
83 {0x1B, OFFSET_OF(SMBIOS_TABLE_TYPE27, NominalSpeed), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE27, NominalSpeed), 0},\r
84};\r
c00a0c87
JY
85SMBIOS_FILTER_TABLE mSmbiosFilterType39BlackList[] = {\r
86 {0x27, OFFSET_OF(SMBIOS_TABLE_TYPE39, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE39, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
87 {0x27, OFFSET_OF(SMBIOS_TABLE_TYPE39, AssetTagNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE39, AssetTagNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
88 {0x27, OFFSET_OF(SMBIOS_TABLE_TYPE39, ModelPartNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE39, ModelPartNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
89};\r
90\r
91SMBIOS_FILTER_STRUCT mSmbiosFilterStandardTableBlackList[] = {\r
92 {0x01, mSmbiosFilterType1BlackList, sizeof(mSmbiosFilterType1BlackList)/sizeof(mSmbiosFilterType1BlackList[0])},\r
93 {0x02, mSmbiosFilterType2BlackList, sizeof(mSmbiosFilterType2BlackList)/sizeof(mSmbiosFilterType2BlackList[0])},\r
94 {0x03, mSmbiosFilterType3BlackList, sizeof(mSmbiosFilterType3BlackList)/sizeof(mSmbiosFilterType3BlackList[0])},\r
95 {0x04, mSmbiosFilterType4BlackList, sizeof(mSmbiosFilterType4BlackList)/sizeof(mSmbiosFilterType4BlackList[0])},\r
96 {0x0B, NULL, 0},\r
97 {0x0F, NULL, 0},\r
98 {0x11, mSmbiosFilterType17BlackList, sizeof(mSmbiosFilterType17BlackList)/sizeof(mSmbiosFilterType17BlackList[0])},\r
99 {0x12, NULL, 0},\r
100 {0x16, mSmbiosFilterType22BlackList, sizeof(mSmbiosFilterType22BlackList)/sizeof(mSmbiosFilterType22BlackList[0])},\r
101 {0x17, mSmbiosFilterType23BlackList, sizeof(mSmbiosFilterType23BlackList)/sizeof(mSmbiosFilterType23BlackList[0])},\r
b8922094 102 {0x1B, mSmbiosFilterType27BlackList, sizeof(mSmbiosFilterType27BlackList)/sizeof(mSmbiosFilterType27BlackList[0])},\r
c00a0c87
JY
103 {0x1F, NULL, 0},\r
104 {0x21, NULL, 0},\r
105 {0x27, mSmbiosFilterType39BlackList, sizeof(mSmbiosFilterType39BlackList)/sizeof(mSmbiosFilterType39BlackList[0])},\r
106};\r
107\r
108EFI_SMBIOS_PROTOCOL *mSmbios;\r
109UINTN mMaxLen;\r
110\r
111/**\r
112\r
113 This function dump raw data.\r
114\r
115 @param Data raw data\r
116 @param Size raw data size\r
117\r
118**/\r
119VOID\r
120InternalDumpData (\r
121 IN UINT8 *Data,\r
122 IN UINTN Size\r
123 )\r
124{\r
125 UINTN Index;\r
126 for (Index = 0; Index < Size; Index++) {\r
e293bc24 127 DEBUG ((EFI_D_VERBOSE, "%02x", (UINTN)Data[Index]));\r
c00a0c87
JY
128 }\r
129}\r
130\r
131/**\r
132\r
133 This function dump raw data with colume format.\r
134\r
135 @param Data raw data\r
136 @param Size raw data size\r
137\r
138**/\r
139VOID\r
140InternalDumpHex (\r
141 IN UINT8 *Data,\r
142 IN UINTN Size\r
143 )\r
144{\r
145 UINTN Index;\r
146 UINTN Count;\r
147 UINTN Left;\r
148\r
149#define COLUME_SIZE (16 * 2)\r
150\r
151 Count = Size / COLUME_SIZE;\r
152 Left = Size % COLUME_SIZE;\r
153 for (Index = 0; Index < Count; Index++) {\r
e293bc24 154 DEBUG ((EFI_D_VERBOSE, "%04x: ", Index * COLUME_SIZE));\r
c00a0c87 155 InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE);\r
e293bc24 156 DEBUG ((EFI_D_VERBOSE, "\n"));\r
c00a0c87
JY
157 }\r
158\r
159 if (Left != 0) {\r
e293bc24 160 DEBUG ((EFI_D_VERBOSE, "%04x: ", Index * COLUME_SIZE));\r
c00a0c87 161 InternalDumpData (Data + Index * COLUME_SIZE, Left);\r
e293bc24 162 DEBUG ((EFI_D_VERBOSE, "\n"));\r
c00a0c87
JY
163 }\r
164}\r
165\r
166\r
167/**\r
168\r
169 This function get filter structure by SMBIOS type.\r
170\r
171 @param Type SMBIOS type\r
172\r
173**/\r
174SMBIOS_FILTER_STRUCT *\r
175GetFilterStructByType (\r
176 IN UINT8 Type\r
177 )\r
178{\r
179 UINTN Index;\r
180 for (Index = 0; Index < sizeof(mSmbiosFilterStandardTableBlackList)/sizeof(mSmbiosFilterStandardTableBlackList[0]); Index++) {\r
181 if (mSmbiosFilterStandardTableBlackList[Index].Type == Type) {\r
182 return &mSmbiosFilterStandardTableBlackList[Index];\r
183 }\r
184 }\r
185 return NULL;\r
186}\r
187\r
188/**\r
189\r
190 This function get SMBIOS string in SMBIOS table.\r
191\r
192 @param Head SMBIOS table head\r
193 @param StringId SMBIOS string ID\r
194 @param StringLen length of SMBIOS string\r
195\r
196 @return SMBIOS string data\r
197**/\r
198CHAR8 *\r
199GetSmbiosStringById (\r
200 IN EFI_SMBIOS_TABLE_HEADER *Head,\r
201 IN SMBIOS_TABLE_STRING StringId,\r
202 OUT UINTN *StringLen\r
203 )\r
204{\r
205 UINTN Size;\r
206 UINTN StrLen;\r
207 CHAR8 *CharInStr;\r
208 UINTN StringsNumber;\r
209 CHAR8 *String;\r
210\r
211 CharInStr = (CHAR8 *)Head + Head->Length;\r
212 Size = Head->Length;\r
213 StringsNumber = 0;\r
214 StrLen = 0;\r
215 //\r
216 // look for the two consecutive zeros, check the string limit by the way.\r
217 //\r
218 String = NULL;\r
14c218b3 219 while (*CharInStr != 0 || *(CharInStr+1) != 0) {\r
c00a0c87
JY
220 if (*CharInStr == 0) {\r
221 Size += 1;\r
222 CharInStr++;\r
223 }\r
224 String = CharInStr;\r
225\r
226 for (StrLen = 0 ; StrLen < mMaxLen; StrLen++) {\r
227 if (*(CharInStr+StrLen) == 0) {\r
228 break;\r
229 }\r
230 }\r
231 *StringLen = StrLen;\r
232\r
233 if (StrLen == mMaxLen) {\r
234 return NULL;\r
235 }\r
236\r
237 //\r
238 // forward the pointer\r
239 //\r
240 CharInStr += StrLen;\r
241 Size += StrLen;\r
242 StringsNumber += 1;\r
243 if (StringsNumber == StringId) {\r
244 break;\r
245 }\r
246 }\r
247\r
248 return String;\r
249}\r
250\r
251/**\r
252\r
253 This function update SMBIOS table based on policy.\r
254\r
255 @param TableEntry SMBIOS table\r
256 @param TableEntrySize SMBIOS table size\r
257\r
258**/\r
259VOID\r
260FilterSmbiosEntry (\r
261 IN OUT VOID *TableEntry,\r
262 IN UINTN TableEntrySize\r
263 )\r
264{\r
265 SMBIOS_FILTER_STRUCT *FilterStruct;\r
266 SMBIOS_FILTER_TABLE *Filter;\r
267 UINTN Index;\r
268 SMBIOS_TABLE_STRING StringId;\r
269 CHAR8 *String;\r
270 UINTN StringLen;\r
271\r
272 DEBUG ((EFI_D_INFO, "Smbios Table (Type - %d):\n", ((SMBIOS_STRUCTURE *)TableEntry)->Type));\r
e293bc24 273 DEBUG_CODE (InternalDumpHex (TableEntry, TableEntrySize););\r
c00a0c87 274\r
7f2f96f1
SZ
275 //\r
276 // Skip measurement for OEM types.\r
277 //\r
278 if (((SMBIOS_STRUCTURE *)TableEntry)->Type >= SMBIOS_OEM_BEGIN) {\r
279 // zero all table fields, except header\r
280 ZeroMem ((UINT8 *)TableEntry + sizeof(SMBIOS_STRUCTURE), TableEntrySize - sizeof(SMBIOS_STRUCTURE));\r
281 } else {\r
282 FilterStruct = GetFilterStructByType (((SMBIOS_STRUCTURE *)TableEntry)->Type);\r
283 if (FilterStruct != NULL) {\r
284 if (FilterStruct->Filter == NULL || FilterStruct->FilterCount == 0) {\r
285 // zero all table fields, except header\r
286 ZeroMem ((UINT8 *)TableEntry + sizeof(SMBIOS_STRUCTURE), TableEntrySize - sizeof(SMBIOS_STRUCTURE));\r
287 } else {\r
288 Filter = FilterStruct->Filter;\r
289 for (Index = 0; Index < FilterStruct->FilterCount; Index++) {\r
290 if (((SMBIOS_STRUCTURE *) TableEntry)->Length >= (Filter[Index].Offset + Filter[Index].Size)) {\r
291 //\r
292 // The field is present in the SMBIOS entry.\r
293 //\r
294 if ((Filter[Index].Flags & SMBIOS_FILTER_TABLE_FLAG_IS_STRING) != 0) {\r
295 CopyMem (&StringId, (UINT8 *)TableEntry + Filter[Index].Offset, sizeof(StringId));\r
296 if (StringId != 0) {\r
297 // set ' ' for string field\r
298 String = GetSmbiosStringById (TableEntry, StringId, &StringLen);\r
299 ASSERT (String != NULL);\r
300 //DEBUG ((EFI_D_INFO,"StrId(0x%x)-%a(%d)\n", StringId, String, StringLen));\r
301 SetMem (String, StringLen, ' ');\r
302 }\r
b8922094 303 }\r
7f2f96f1
SZ
304 // zero non-string field\r
305 ZeroMem ((UINT8 *)TableEntry + Filter[Index].Offset, Filter[Index].Size);\r
c00a0c87
JY
306 }\r
307 }\r
c00a0c87
JY
308 }\r
309 }\r
310 }\r
311\r
312 DEBUG ((EFI_D_INFO, "Filter Smbios Table (Type - %d):\n", ((SMBIOS_STRUCTURE *)TableEntry)->Type));\r
e293bc24 313 DEBUG_CODE (InternalDumpHex (TableEntry, TableEntrySize););\r
c00a0c87
JY
314}\r
315\r
316/**\r
317\r
318 Get the full size of SMBIOS structure including optional strings that follow the formatted structure.\r
319\r
320 @param Head Pointer to the beginning of SMBIOS structure.\r
321 @param NumberOfStrings The returned number of optional strings that follow the formatted structure.\r
14c218b3 322\r
c00a0c87
JY
323 @return Size The returned size.\r
324**/\r
325UINTN\r
326GetSmbiosStructureSize (\r
327 IN EFI_SMBIOS_TABLE_HEADER *Head,\r
328 OUT UINTN *NumberOfStrings\r
329 )\r
330{\r
331 UINTN Size;\r
332 UINTN StrLen;\r
333 CHAR8 *CharInStr;\r
334 UINTN StringsNumber;\r
335\r
336 CharInStr = (CHAR8 *)Head + Head->Length;\r
337 Size = Head->Length;\r
338 StringsNumber = 0;\r
339 StrLen = 0;\r
340 //\r
341 // look for the two consecutive zeros, check the string limit by the way.\r
342 //\r
14c218b3 343 while (*CharInStr != 0 || *(CharInStr+1) != 0) {\r
c00a0c87
JY
344 if (*CharInStr == 0) {\r
345 Size += 1;\r
346 CharInStr++;\r
347 }\r
348\r
349 for (StrLen = 0 ; StrLen < mMaxLen; StrLen++) {\r
350 if (*(CharInStr+StrLen) == 0) {\r
351 break;\r
352 }\r
353 }\r
354\r
355 if (StrLen == mMaxLen) {\r
356 return 0;\r
357 }\r
358\r
359 //\r
360 // forward the pointer\r
361 //\r
362 CharInStr += StrLen;\r
363 Size += StrLen;\r
364 StringsNumber += 1;\r
365 }\r
366\r
367 //\r
368 // count ending two zeros.\r
369 //\r
370 Size += 2;\r
371\r
372 if (NumberOfStrings != NULL) {\r
373 *NumberOfStrings = StringsNumber;\r
374 }\r
375 return Size;\r
376}\r
377\r
378/**\r
379\r
380 This function returns full SMBIOS table length.\r
381\r
382 @param TableAddress SMBIOS table based address\r
383 @param TableMaximumSize Maximum size of SMBIOS table\r
384\r
385 @return SMBIOS table length\r
386\r
387**/\r
388UINTN\r
389GetSmbiosTableLength (\r
390 IN VOID *TableAddress,\r
391 IN UINTN TableMaximumSize\r
392 )\r
393{\r
394 VOID *TableEntry;\r
395 VOID *TableAddressEnd;\r
396 UINTN TableEntryLength;\r
397\r
398 TableAddressEnd = (VOID *)((UINTN)TableAddress + TableMaximumSize);\r
399 TableEntry = TableAddress;\r
400 while (TableEntry < TableAddressEnd) {\r
401 TableEntryLength = GetSmbiosStructureSize (TableEntry, NULL);\r
402 if (TableEntryLength == 0) {\r
403 break;\r
404 }\r
405 if (((SMBIOS_STRUCTURE *)TableEntry)->Type == 127) {\r
406 TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength);\r
407 break;\r
408 }\r
409 TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength);\r
410 }\r
411\r
412 return ((UINTN)TableEntry - (UINTN)TableAddress);\r
413}\r
414\r
415/**\r
416\r
417 This function updatess full SMBIOS table length.\r
418\r
419 @param TableAddress SMBIOS table based address\r
420 @param TableLength SMBIOS table length\r
421\r
422**/\r
423VOID\r
424FilterSmbiosTable (\r
425 IN OUT VOID *TableAddress,\r
426 IN UINTN TableLength\r
427 )\r
428{\r
429 VOID *TableAddressEnd;\r
430 VOID *TableEntry;\r
431 UINTN TableEntryLength;\r
432\r
433 TableEntry = TableAddress;\r
434 TableAddressEnd = (VOID *)((UINTN)TableAddress + TableLength);\r
435 while ((UINTN)TableEntry < (UINTN)TableAddressEnd) {\r
436 TableEntryLength = GetSmbiosStructureSize (TableEntry, NULL);\r
437 if (TableEntryLength == 0) {\r
438 break;\r
439 }\r
440\r
441 FilterSmbiosEntry (TableEntry, TableEntryLength);\r
442\r
443 TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength);\r
444 }\r
445}\r
446\r
447/**\r
35a19d48
SZ
448 Measure SMBIOS with EV_EFI_HANDOFF_TABLES to PCR[1].\r
449\r
450 @param[in] Event Event whose notification function is being invoked.\r
451 @param[in] Context Pointer to the notification function's context.\r
452\r
c00a0c87
JY
453**/\r
454VOID\r
455EFIAPI\r
456MeasureSmbiosTable (\r
457 IN EFI_EVENT Event,\r
458 IN VOID *Context\r
459 )\r
460{\r
461 EFI_STATUS Status;\r
462 EFI_HANDOFF_TABLE_POINTERS HandoffTables;\r
463 SMBIOS_TABLE_ENTRY_POINT *SmbiosTable;\r
464 SMBIOS_TABLE_3_0_ENTRY_POINT *Smbios3Table;\r
465 VOID *SmbiosTableAddress;\r
466 VOID *TableAddress;\r
467 UINTN TableLength;\r
468\r
469 SmbiosTable = NULL;\r
470 Smbios3Table = NULL;\r
471 SmbiosTableAddress = NULL;\r
472 TableLength = 0;\r
473\r
474 if (mSmbios->MajorVersion >= 3) {\r
475 Status = EfiGetSystemConfigurationTable (\r
476 &gEfiSmbios3TableGuid,\r
477 (VOID **) &Smbios3Table\r
478 );\r
479 if (!EFI_ERROR (Status)) {\r
480 DEBUG ((EFI_D_INFO, "Smbios3Table:\n"));\r
481 DEBUG ((EFI_D_INFO, " AnchorString - '%c%c%c%c%c'\n",\r
482 Smbios3Table->AnchorString[0],\r
483 Smbios3Table->AnchorString[1],\r
484 Smbios3Table->AnchorString[2],\r
485 Smbios3Table->AnchorString[3],\r
486 Smbios3Table->AnchorString[4]\r
487 ));\r
488 DEBUG ((EFI_D_INFO, " EntryPointStructureChecksum - 0x%02x\n", Smbios3Table->EntryPointStructureChecksum));\r
489 DEBUG ((EFI_D_INFO, " EntryPointLength - 0x%02x\n", Smbios3Table->EntryPointLength));\r
490 DEBUG ((EFI_D_INFO, " MajorVersion - 0x%02x\n", Smbios3Table->MajorVersion));\r
491 DEBUG ((EFI_D_INFO, " MinorVersion - 0x%02x\n", Smbios3Table->MinorVersion));\r
492 DEBUG ((EFI_D_INFO, " DocRev - 0x%02x\n", Smbios3Table->DocRev));\r
493 DEBUG ((EFI_D_INFO, " EntryPointRevision - 0x%02x\n", Smbios3Table->EntryPointRevision));\r
494 DEBUG ((EFI_D_INFO, " TableMaximumSize - 0x%08x\n", Smbios3Table->TableMaximumSize));\r
495 DEBUG ((EFI_D_INFO, " TableAddress - 0x%016lx\n", Smbios3Table->TableAddress));\r
496 }\r
497 }\r
3c394a67
SZ
498\r
499 if (Smbios3Table == NULL) {\r
c00a0c87
JY
500 Status = EfiGetSystemConfigurationTable (\r
501 &gEfiSmbiosTableGuid,\r
502 (VOID **) &SmbiosTable\r
503 );\r
504 if (!EFI_ERROR (Status)) {\r
505 DEBUG ((EFI_D_INFO, "SmbiosTable:\n"));\r
506 DEBUG ((EFI_D_INFO, " AnchorString - '%c%c%c%c'\n",\r
3c394a67
SZ
507 SmbiosTable->AnchorString[0],\r
508 SmbiosTable->AnchorString[1],\r
509 SmbiosTable->AnchorString[2],\r
510 SmbiosTable->AnchorString[3]\r
c00a0c87
JY
511 ));\r
512 DEBUG ((EFI_D_INFO, " EntryPointStructureChecksum - 0x%02x\n", SmbiosTable->EntryPointStructureChecksum));\r
513 DEBUG ((EFI_D_INFO, " EntryPointLength - 0x%02x\n", SmbiosTable->EntryPointLength));\r
514 DEBUG ((EFI_D_INFO, " MajorVersion - 0x%02x\n", SmbiosTable->MajorVersion));\r
515 DEBUG ((EFI_D_INFO, " MinorVersion - 0x%02x\n", SmbiosTable->MinorVersion));\r
516 DEBUG ((EFI_D_INFO, " MaxStructureSize - 0x%08x\n", SmbiosTable->MaxStructureSize));\r
517 DEBUG ((EFI_D_INFO, " EntryPointRevision - 0x%02x\n", SmbiosTable->EntryPointRevision));\r
518 DEBUG ((EFI_D_INFO, " FormattedArea - '%c%c%c%c%c'\n",\r
519 SmbiosTable->FormattedArea[0],\r
520 SmbiosTable->FormattedArea[1],\r
521 SmbiosTable->FormattedArea[2],\r
522 SmbiosTable->FormattedArea[3],\r
523 SmbiosTable->FormattedArea[4]\r
524 ));\r
525 DEBUG ((EFI_D_INFO, " IntermediateAnchorString - '%c%c%c%c%c'\n",\r
526 SmbiosTable->IntermediateAnchorString[0],\r
527 SmbiosTable->IntermediateAnchorString[1],\r
528 SmbiosTable->IntermediateAnchorString[2],\r
529 SmbiosTable->IntermediateAnchorString[3],\r
530 SmbiosTable->IntermediateAnchorString[4]\r
531 ));\r
532 DEBUG ((EFI_D_INFO, " IntermediateChecksum - 0x%02x\n", SmbiosTable->IntermediateChecksum));\r
533 DEBUG ((EFI_D_INFO, " TableLength - 0x%04x\n", SmbiosTable->TableLength));\r
534 DEBUG ((EFI_D_INFO, " TableAddress - 0x%08x\n", SmbiosTable->TableAddress));\r
535 DEBUG ((EFI_D_INFO, " NumberOfSmbiosStructures - 0x%04x\n", SmbiosTable->NumberOfSmbiosStructures));\r
536 DEBUG ((EFI_D_INFO, " SmbiosBcdRevision - 0x%02x\n", SmbiosTable->SmbiosBcdRevision));\r
537 }\r
3c394a67 538 }\r
c00a0c87
JY
539\r
540 if (Smbios3Table != NULL) {\r
541 SmbiosTableAddress = (VOID *)(UINTN)Smbios3Table->TableAddress;\r
542 TableLength = GetSmbiosTableLength (SmbiosTableAddress, Smbios3Table->TableMaximumSize);\r
543 } else if (SmbiosTable != NULL) {\r
544 SmbiosTableAddress = (VOID *)(UINTN)SmbiosTable->TableAddress;\r
545 TableLength = SmbiosTable->TableLength;\r
546 }\r
547\r
548 if (SmbiosTableAddress != NULL) {\r
549 DEBUG ((DEBUG_INFO, "The Smbios Table starts at: 0x%x\n", SmbiosTableAddress));\r
550 DEBUG ((DEBUG_INFO, "The Smbios Table size: 0x%x\n", TableLength));\r
e293bc24 551 DEBUG_CODE (InternalDumpHex ((UINT8 *)(UINTN)SmbiosTableAddress, TableLength););\r
c00a0c87
JY
552\r
553 TableAddress = AllocateCopyPool ((UINTN)TableLength, (VOID *)(UINTN)SmbiosTableAddress);\r
554 if (TableAddress == NULL) {\r
555 return ;\r
556 }\r
557\r
558 FilterSmbiosTable (TableAddress, TableLength);\r
559\r
560 DEBUG ((DEBUG_INFO, "The final Smbios Table starts at: 0x%x\n", TableAddress));\r
561 DEBUG ((DEBUG_INFO, "The final Smbios Table size: 0x%x\n", TableLength));\r
e293bc24 562 DEBUG_CODE (InternalDumpHex (TableAddress, TableLength););\r
c00a0c87
JY
563\r
564 HandoffTables.NumberOfTables = 1;\r
3c394a67
SZ
565 if (Smbios3Table != NULL) {\r
566 CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), &gEfiSmbios3TableGuid);\r
567 HandoffTables.TableEntry[0].VendorTable = Smbios3Table;\r
568 } else {\r
569 CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), &gEfiSmbiosTableGuid);\r
570 HandoffTables.TableEntry[0].VendorTable = SmbiosTable;\r
571 }\r
c00a0c87
JY
572 Status = TpmMeasureAndLogData (\r
573 1, // PCRIndex\r
574 EV_EFI_HANDOFF_TABLES, // EventType\r
575 &HandoffTables, // EventLog\r
576 sizeof (HandoffTables), // LogLen\r
577 TableAddress, // HashData\r
578 TableLength // HashDataLen\r
579 );\r
f2739051
JY
580 if (!EFI_ERROR (Status)) {\r
581 gBS->CloseEvent (Event) ;\r
c00a0c87
JY
582 }\r
583 }\r
584\r
585 return ;\r
586}\r
587\r
588/**\r
589\r
14c218b3 590 Driver to produce Smbios measurement.\r
c00a0c87
JY
591\r
592 @param ImageHandle Module's image handle\r
593 @param SystemTable Pointer of EFI_SYSTEM_TABLE\r
594\r
35a19d48 595 @return Status returned from EfiCreateEventReadyToBootEx().\r
c00a0c87
JY
596\r
597**/\r
598EFI_STATUS\r
599EFIAPI\r
600SmbiosMeasurementDriverEntryPoint (\r
601 IN EFI_HANDLE ImageHandle,\r
602 IN EFI_SYSTEM_TABLE *SystemTable\r
603 )\r
604{\r
605 EFI_STATUS Status;\r
606 EFI_EVENT Event;\r
607\r
8c1d8735 608 Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **) &mSmbios);\r
c00a0c87
JY
609 ASSERT_EFI_ERROR (Status);\r
610 DEBUG ((DEBUG_INFO, "The Smbios Table Version: %x.%x\n", mSmbios->MajorVersion, mSmbios->MinorVersion));\r
14c218b3 611\r
c00a0c87
JY
612 if (mSmbios->MajorVersion < 2 || (mSmbios->MajorVersion == 2 && mSmbios->MinorVersion < 7)){\r
613 mMaxLen = SMBIOS_STRING_MAX_LENGTH;\r
614 } else if (mSmbios->MajorVersion < 3) {\r
615 //\r
616 // Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string.\r
617 // However, the length of the entire structure table (including all strings) must be reported\r
618 // in the Structure Table Length field of the SMBIOS Structure Table Entry Point,\r
619 // which is a WORD field limited to 65,535 bytes.\r
620 //\r
621 mMaxLen = SMBIOS_TABLE_MAX_LENGTH;\r
622 } else {\r
623 //\r
624 // SMBIOS 3.0 defines the Structure table maximum size as DWORD field limited to 0xFFFFFFFF bytes.\r
625 // Locate the end of string as long as possible.\r
626 //\r
627 mMaxLen = SMBIOS_3_0_TABLE_MAX_LENGTH;\r
628 }\r
629\r
630 //\r
631 // Measure Smbios tables\r
632 //\r
633 Status = EfiCreateEventReadyToBootEx (\r
634 TPL_CALLBACK,\r
635 MeasureSmbiosTable,\r
636 NULL,\r
637 &Event\r
638 );\r
639\r
640 return Status;\r
641}\r