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