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