]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c
MdeModulePkg/Smbios: Add TCG PFP rev 105 support.
[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 for (Index = 0; Index < Size; Index++) {
140 DEBUG ((EFI_D_VERBOSE, "%02x", (UINTN)Data[Index]));
141 }
142 }
143
144 /**
145
146 This function dump raw data with colume format.
147
148 @param Data raw data
149 @param Size raw data size
150
151 **/
152 VOID
153 InternalDumpHex (
154 IN UINT8 *Data,
155 IN UINTN Size
156 )
157 {
158 UINTN Index;
159 UINTN Count;
160 UINTN Left;
161
162 #define COLUME_SIZE (16 * 2)
163
164 Count = Size / COLUME_SIZE;
165 Left = Size % COLUME_SIZE;
166 for (Index = 0; Index < Count; Index++) {
167 DEBUG ((EFI_D_VERBOSE, "%04x: ", Index * COLUME_SIZE));
168 InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE);
169 DEBUG ((EFI_D_VERBOSE, "\n"));
170 }
171
172 if (Left != 0) {
173 DEBUG ((EFI_D_VERBOSE, "%04x: ", Index * COLUME_SIZE));
174 InternalDumpData (Data + Index * COLUME_SIZE, Left);
175 DEBUG ((EFI_D_VERBOSE, "\n"));
176 }
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 for (Index = 0; Index < sizeof(mSmbiosFilterStandardTableBlackList)/sizeof(mSmbiosFilterStandardTableBlackList[0]); Index++) {
194 if (mSmbiosFilterStandardTableBlackList[Index].Type == Type) {
195 return &mSmbiosFilterStandardTableBlackList[Index];
196 }
197 }
198 return NULL;
199 }
200
201 /**
202
203 This function get SMBIOS string in SMBIOS table.
204
205 @param Head SMBIOS table head
206 @param StringId SMBIOS string ID
207 @param StringLen length of SMBIOS string
208
209 @return SMBIOS string data
210 **/
211 CHAR8 *
212 GetSmbiosStringById (
213 IN EFI_SMBIOS_TABLE_HEADER *Head,
214 IN SMBIOS_TABLE_STRING StringId,
215 OUT UINTN *StringLen
216 )
217 {
218 UINTN Size;
219 UINTN StrLen;
220 CHAR8 *CharInStr;
221 UINTN StringsNumber;
222 CHAR8 *String;
223
224 CharInStr = (CHAR8 *)Head + Head->Length;
225 Size = Head->Length;
226 StringsNumber = 0;
227 StrLen = 0;
228 //
229 // look for the two consecutive zeros, check the string limit by the way.
230 //
231 String = NULL;
232 while (*CharInStr != 0 || *(CharInStr+1) != 0) {
233 if (*CharInStr == 0) {
234 Size += 1;
235 CharInStr++;
236 }
237 String = CharInStr;
238
239 for (StrLen = 0 ; StrLen < mMaxLen; StrLen++) {
240 if (*(CharInStr+StrLen) == 0) {
241 break;
242 }
243 }
244 *StringLen = StrLen;
245
246 if (StrLen == mMaxLen) {
247 return NULL;
248 }
249
250 //
251 // forward the pointer
252 //
253 CharInStr += StrLen;
254 Size += StrLen;
255 StringsNumber += 1;
256 if (StringsNumber == StringId) {
257 break;
258 }
259 }
260
261 return String;
262 }
263
264 /**
265
266 This function update SMBIOS table based on policy.
267
268 @param TableEntry SMBIOS table
269 @param TableEntrySize SMBIOS table size
270
271 **/
272 VOID
273 FilterSmbiosEntry (
274 IN OUT VOID *TableEntry,
275 IN UINTN TableEntrySize
276 )
277 {
278 SMBIOS_FILTER_STRUCT *FilterStruct;
279 SMBIOS_FILTER_TABLE *Filter;
280 UINTN Index;
281 SMBIOS_TABLE_STRING StringId;
282 CHAR8 *String;
283 UINTN StringLen;
284
285 DEBUG ((EFI_D_INFO, "Smbios Table (Type - %d):\n", ((SMBIOS_STRUCTURE *)TableEntry)->Type));
286 DEBUG_CODE (InternalDumpHex (TableEntry, TableEntrySize););
287
288 //
289 // Skip measurement for OEM types.
290 //
291 if (((SMBIOS_STRUCTURE *)TableEntry)->Type >= SMBIOS_OEM_BEGIN) {
292 // zero all table fields, except header
293 ZeroMem ((UINT8 *)TableEntry + sizeof(SMBIOS_STRUCTURE), TableEntrySize - sizeof(SMBIOS_STRUCTURE));
294 } else {
295 FilterStruct = GetFilterStructByType (((SMBIOS_STRUCTURE *)TableEntry)->Type);
296 if (FilterStruct != NULL) {
297 if (FilterStruct->Filter == NULL || FilterStruct->FilterCount == 0) {
298 // zero all table fields, except header
299 ZeroMem ((UINT8 *)TableEntry + sizeof(SMBIOS_STRUCTURE), TableEntrySize - sizeof(SMBIOS_STRUCTURE));
300 } else {
301 Filter = FilterStruct->Filter;
302 for (Index = 0; Index < FilterStruct->FilterCount; Index++) {
303 if (((SMBIOS_STRUCTURE *) TableEntry)->Length >= (Filter[Index].Offset + Filter[Index].Size)) {
304 //
305 // The field is present in the SMBIOS entry.
306 //
307 if ((Filter[Index].Flags & SMBIOS_FILTER_TABLE_FLAG_IS_STRING) != 0) {
308 CopyMem (&StringId, (UINT8 *)TableEntry + Filter[Index].Offset, sizeof(StringId));
309 if (StringId != 0) {
310 // set ' ' for string field
311 String = GetSmbiosStringById (TableEntry, StringId, &StringLen);
312 ASSERT (String != NULL);
313 //DEBUG ((EFI_D_INFO,"StrId(0x%x)-%a(%d)\n", StringId, String, StringLen));
314 SetMem (String, StringLen, ' ');
315 }
316 }
317 // zero non-string field
318 ZeroMem ((UINT8 *)TableEntry + Filter[Index].Offset, Filter[Index].Size);
319 }
320 }
321 }
322 }
323 }
324
325 DEBUG ((EFI_D_INFO, "Filter Smbios Table (Type - %d):\n", ((SMBIOS_STRUCTURE *)TableEntry)->Type));
326 DEBUG_CODE (InternalDumpHex (TableEntry, TableEntrySize););
327 }
328
329 /**
330
331 Get the full size of SMBIOS structure including optional strings that follow the formatted structure.
332
333 @param Head Pointer to the beginning of SMBIOS structure.
334 @param NumberOfStrings The returned number of optional strings that follow the formatted structure.
335
336 @return Size The returned size.
337 **/
338 UINTN
339 GetSmbiosStructureSize (
340 IN EFI_SMBIOS_TABLE_HEADER *Head,
341 OUT UINTN *NumberOfStrings
342 )
343 {
344 UINTN Size;
345 UINTN StrLen;
346 CHAR8 *CharInStr;
347 UINTN StringsNumber;
348
349 CharInStr = (CHAR8 *)Head + Head->Length;
350 Size = Head->Length;
351 StringsNumber = 0;
352 StrLen = 0;
353 //
354 // look for the two consecutive zeros, check the string limit by the way.
355 //
356 while (*CharInStr != 0 || *(CharInStr+1) != 0) {
357 if (*CharInStr == 0) {
358 Size += 1;
359 CharInStr++;
360 }
361
362 for (StrLen = 0 ; StrLen < mMaxLen; StrLen++) {
363 if (*(CharInStr+StrLen) == 0) {
364 break;
365 }
366 }
367
368 if (StrLen == mMaxLen) {
369 return 0;
370 }
371
372 //
373 // forward the pointer
374 //
375 CharInStr += StrLen;
376 Size += StrLen;
377 StringsNumber += 1;
378 }
379
380 //
381 // count ending two zeros.
382 //
383 Size += 2;
384
385 if (NumberOfStrings != NULL) {
386 *NumberOfStrings = StringsNumber;
387 }
388 return Size;
389 }
390
391 /**
392
393 This function returns full SMBIOS table length.
394
395 @param TableAddress SMBIOS table based address
396 @param TableMaximumSize Maximum size of SMBIOS table
397
398 @return SMBIOS table length
399
400 **/
401 UINTN
402 GetSmbiosTableLength (
403 IN VOID *TableAddress,
404 IN UINTN TableMaximumSize
405 )
406 {
407 VOID *TableEntry;
408 VOID *TableAddressEnd;
409 UINTN TableEntryLength;
410
411 TableAddressEnd = (VOID *)((UINTN)TableAddress + TableMaximumSize);
412 TableEntry = TableAddress;
413 while (TableEntry < TableAddressEnd) {
414 TableEntryLength = GetSmbiosStructureSize (TableEntry, NULL);
415 if (TableEntryLength == 0) {
416 break;
417 }
418 if (((SMBIOS_STRUCTURE *)TableEntry)->Type == 127) {
419 TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength);
420 break;
421 }
422 TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength);
423 }
424
425 return ((UINTN)TableEntry - (UINTN)TableAddress);
426 }
427
428 /**
429
430 This function updatess full SMBIOS table length.
431
432 @param TableAddress SMBIOS table based address
433 @param TableLength SMBIOS table length
434
435 **/
436 VOID
437 FilterSmbiosTable (
438 IN OUT VOID *TableAddress,
439 IN UINTN TableLength
440 )
441 {
442 VOID *TableAddressEnd;
443 VOID *TableEntry;
444 UINTN TableEntryLength;
445
446 TableEntry = TableAddress;
447 TableAddressEnd = (VOID *)((UINTN)TableAddress + TableLength);
448 while ((UINTN)TableEntry < (UINTN)TableAddressEnd) {
449 TableEntryLength = GetSmbiosStructureSize (TableEntry, NULL);
450 if (TableEntryLength == 0) {
451 break;
452 }
453
454 FilterSmbiosEntry (TableEntry, TableEntryLength);
455
456 TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength);
457 }
458 }
459
460 /**
461 Measure SMBIOS with EV_EFI_HANDOFF_TABLES to PCR[1].
462
463 @param[in] Event Event whose notification function is being invoked.
464 @param[in] Context Pointer to the notification function's context.
465
466 **/
467 VOID
468 EFIAPI
469 MeasureSmbiosTable (
470 IN EFI_EVENT Event,
471 IN VOID *Context
472 )
473 {
474 EFI_STATUS Status;
475 EFI_HANDOFF_TABLE_POINTERS HandoffTables;
476 SMBIOS_HANDOFF_TABLE_POINTERS2 SmbiosHandoffTables2;
477 UINT32 EventType;
478 VOID *EventLog;
479 UINT32 EventLogSize;
480 SMBIOS_TABLE_ENTRY_POINT *SmbiosTable;
481 SMBIOS_TABLE_3_0_ENTRY_POINT *Smbios3Table;
482 VOID *SmbiosTableAddress;
483 VOID *TableAddress;
484 UINTN TableLength;
485
486 SmbiosTable = NULL;
487 Smbios3Table = NULL;
488 SmbiosTableAddress = NULL;
489 TableLength = 0;
490
491 if (mSmbios->MajorVersion >= 3) {
492 Status = EfiGetSystemConfigurationTable (
493 &gEfiSmbios3TableGuid,
494 (VOID **) &Smbios3Table
495 );
496 if (!EFI_ERROR (Status)) {
497 DEBUG ((EFI_D_INFO, "Smbios3Table:\n"));
498 DEBUG ((EFI_D_INFO, " AnchorString - '%c%c%c%c%c'\n",
499 Smbios3Table->AnchorString[0],
500 Smbios3Table->AnchorString[1],
501 Smbios3Table->AnchorString[2],
502 Smbios3Table->AnchorString[3],
503 Smbios3Table->AnchorString[4]
504 ));
505 DEBUG ((EFI_D_INFO, " EntryPointStructureChecksum - 0x%02x\n", Smbios3Table->EntryPointStructureChecksum));
506 DEBUG ((EFI_D_INFO, " EntryPointLength - 0x%02x\n", Smbios3Table->EntryPointLength));
507 DEBUG ((EFI_D_INFO, " MajorVersion - 0x%02x\n", Smbios3Table->MajorVersion));
508 DEBUG ((EFI_D_INFO, " MinorVersion - 0x%02x\n", Smbios3Table->MinorVersion));
509 DEBUG ((EFI_D_INFO, " DocRev - 0x%02x\n", Smbios3Table->DocRev));
510 DEBUG ((EFI_D_INFO, " EntryPointRevision - 0x%02x\n", Smbios3Table->EntryPointRevision));
511 DEBUG ((EFI_D_INFO, " TableMaximumSize - 0x%08x\n", Smbios3Table->TableMaximumSize));
512 DEBUG ((EFI_D_INFO, " TableAddress - 0x%016lx\n", Smbios3Table->TableAddress));
513 }
514 }
515
516 if (Smbios3Table == NULL) {
517 Status = EfiGetSystemConfigurationTable (
518 &gEfiSmbiosTableGuid,
519 (VOID **) &SmbiosTable
520 );
521 if (!EFI_ERROR (Status)) {
522 DEBUG ((EFI_D_INFO, "SmbiosTable:\n"));
523 DEBUG ((EFI_D_INFO, " AnchorString - '%c%c%c%c'\n",
524 SmbiosTable->AnchorString[0],
525 SmbiosTable->AnchorString[1],
526 SmbiosTable->AnchorString[2],
527 SmbiosTable->AnchorString[3]
528 ));
529 DEBUG ((EFI_D_INFO, " EntryPointStructureChecksum - 0x%02x\n", SmbiosTable->EntryPointStructureChecksum));
530 DEBUG ((EFI_D_INFO, " EntryPointLength - 0x%02x\n", SmbiosTable->EntryPointLength));
531 DEBUG ((EFI_D_INFO, " MajorVersion - 0x%02x\n", SmbiosTable->MajorVersion));
532 DEBUG ((EFI_D_INFO, " MinorVersion - 0x%02x\n", SmbiosTable->MinorVersion));
533 DEBUG ((EFI_D_INFO, " MaxStructureSize - 0x%08x\n", SmbiosTable->MaxStructureSize));
534 DEBUG ((EFI_D_INFO, " EntryPointRevision - 0x%02x\n", SmbiosTable->EntryPointRevision));
535 DEBUG ((EFI_D_INFO, " FormattedArea - '%c%c%c%c%c'\n",
536 SmbiosTable->FormattedArea[0],
537 SmbiosTable->FormattedArea[1],
538 SmbiosTable->FormattedArea[2],
539 SmbiosTable->FormattedArea[3],
540 SmbiosTable->FormattedArea[4]
541 ));
542 DEBUG ((EFI_D_INFO, " IntermediateAnchorString - '%c%c%c%c%c'\n",
543 SmbiosTable->IntermediateAnchorString[0],
544 SmbiosTable->IntermediateAnchorString[1],
545 SmbiosTable->IntermediateAnchorString[2],
546 SmbiosTable->IntermediateAnchorString[3],
547 SmbiosTable->IntermediateAnchorString[4]
548 ));
549 DEBUG ((EFI_D_INFO, " IntermediateChecksum - 0x%02x\n", SmbiosTable->IntermediateChecksum));
550 DEBUG ((EFI_D_INFO, " TableLength - 0x%04x\n", SmbiosTable->TableLength));
551 DEBUG ((EFI_D_INFO, " TableAddress - 0x%08x\n", SmbiosTable->TableAddress));
552 DEBUG ((EFI_D_INFO, " NumberOfSmbiosStructures - 0x%04x\n", SmbiosTable->NumberOfSmbiosStructures));
553 DEBUG ((EFI_D_INFO, " SmbiosBcdRevision - 0x%02x\n", SmbiosTable->SmbiosBcdRevision));
554 }
555 }
556
557 if (Smbios3Table != NULL) {
558 SmbiosTableAddress = (VOID *)(UINTN)Smbios3Table->TableAddress;
559 TableLength = GetSmbiosTableLength (SmbiosTableAddress, Smbios3Table->TableMaximumSize);
560 } else if (SmbiosTable != NULL) {
561 SmbiosTableAddress = (VOID *)(UINTN)SmbiosTable->TableAddress;
562 TableLength = SmbiosTable->TableLength;
563 }
564
565 if (SmbiosTableAddress != NULL) {
566 DEBUG ((DEBUG_INFO, "The Smbios Table starts at: 0x%x\n", SmbiosTableAddress));
567 DEBUG ((DEBUG_INFO, "The Smbios Table size: 0x%x\n", TableLength));
568 DEBUG_CODE (InternalDumpHex ((UINT8 *)(UINTN)SmbiosTableAddress, TableLength););
569
570 TableAddress = AllocateCopyPool ((UINTN)TableLength, (VOID *)(UINTN)SmbiosTableAddress);
571 if (TableAddress == NULL) {
572 return ;
573 }
574
575 FilterSmbiosTable (TableAddress, TableLength);
576
577 DEBUG ((DEBUG_INFO, "The final Smbios Table starts at: 0x%x\n", TableAddress));
578 DEBUG ((DEBUG_INFO, "The final Smbios Table size: 0x%x\n", TableLength));
579 DEBUG_CODE (InternalDumpHex (TableAddress, TableLength););
580
581 HandoffTables.NumberOfTables = 1;
582 if (Smbios3Table != NULL) {
583 CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), &gEfiSmbios3TableGuid);
584 HandoffTables.TableEntry[0].VendorTable = Smbios3Table;
585 } else {
586 CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), &gEfiSmbiosTableGuid);
587 HandoffTables.TableEntry[0].VendorTable = SmbiosTable;
588 }
589 EventType = EV_EFI_HANDOFF_TABLES;
590 EventLog = &HandoffTables;
591 EventLogSize = sizeof (HandoffTables);
592
593 if (PcdGet32(PcdTcgPfpMeasurementRevision) >= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105) {
594 SmbiosHandoffTables2.TableDescriptionSize = sizeof(SmbiosHandoffTables2.TableDescription);
595 CopyMem (SmbiosHandoffTables2.TableDescription, SMBIOS_HANDOFF_TABLE_DESC, sizeof(SmbiosHandoffTables2.TableDescription));
596 SmbiosHandoffTables2.NumberOfTables = HandoffTables.NumberOfTables;
597 CopyMem (&(SmbiosHandoffTables2.TableEntry[0]), &(HandoffTables.TableEntry[0]), sizeof(SmbiosHandoffTables2.TableEntry[0]));
598 EventType = EV_EFI_HANDOFF_TABLES2;
599 EventLog = &SmbiosHandoffTables2;
600 EventLogSize = sizeof (SmbiosHandoffTables2);
601 }
602 Status = TpmMeasureAndLogData (
603 1, // PCRIndex
604 EventType, // EventType
605 EventLog, // EventLog
606 EventLogSize, // LogLen
607 TableAddress, // HashData
608 TableLength // HashDataLen
609 );
610 if (!EFI_ERROR (Status)) {
611 gBS->CloseEvent (Event) ;
612 }
613 }
614
615 return ;
616 }
617
618 /**
619
620 Driver to produce Smbios measurement.
621
622 @param ImageHandle Module's image handle
623 @param SystemTable Pointer of EFI_SYSTEM_TABLE
624
625 @return Status returned from EfiCreateEventReadyToBootEx().
626
627 **/
628 EFI_STATUS
629 EFIAPI
630 SmbiosMeasurementDriverEntryPoint (
631 IN EFI_HANDLE ImageHandle,
632 IN EFI_SYSTEM_TABLE *SystemTable
633 )
634 {
635 EFI_STATUS Status;
636 EFI_EVENT Event;
637
638 Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **) &mSmbios);
639 ASSERT_EFI_ERROR (Status);
640 DEBUG ((DEBUG_INFO, "The Smbios Table Version: %x.%x\n", mSmbios->MajorVersion, mSmbios->MinorVersion));
641
642 if (mSmbios->MajorVersion < 2 || (mSmbios->MajorVersion == 2 && mSmbios->MinorVersion < 7)){
643 mMaxLen = SMBIOS_STRING_MAX_LENGTH;
644 } else if (mSmbios->MajorVersion < 3) {
645 //
646 // Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string.
647 // However, the length of the entire structure table (including all strings) must be reported
648 // in the Structure Table Length field of the SMBIOS Structure Table Entry Point,
649 // which is a WORD field limited to 65,535 bytes.
650 //
651 mMaxLen = SMBIOS_TABLE_MAX_LENGTH;
652 } else {
653 //
654 // SMBIOS 3.0 defines the Structure table maximum size as DWORD field limited to 0xFFFFFFFF bytes.
655 // Locate the end of string as long as possible.
656 //
657 mMaxLen = SMBIOS_3_0_TABLE_MAX_LENGTH;
658 }
659
660 //
661 // Measure Smbios tables
662 //
663 Status = EfiCreateEventReadyToBootEx (
664 TPL_CALLBACK,
665 MeasureSmbiosTable,
666 NULL,
667 &Event
668 );
669
670 return Status;
671 }