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