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