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