]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/DxeHstiLib/HstiDxe.c
d895599cd460d5b5b2c1ba7bd09177daadc94a19
[mirror_edk2.git] / MdePkg / Library / DxeHstiLib / HstiDxe.c
1 /** @file
2
3 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
5
6 **/
7
8 #include "HstiDxe.h"
9
10 /**
11 Find HSTI table in AIP protocol, and return the data.
12 This API will return the HSTI table with indicated Role and ImplementationID,
13 NULL ImplementationID means to find the first HSTI table with indicated Role.
14
15 @param Role Role of HSTI data.
16 @param ImplementationID ImplementationID of HSTI data.
17 NULL means find the first one match Role.
18 @param HstiData HSTI data. This buffer is allocated by callee, and it
19 is the responsibility of the caller to free it after
20 using it.
21 @param HstiSize HSTI size
22
23 @return Aip The AIP protocol having this HSTI.
24 @return NULL There is not HSTI table with the Role and ImplementationID published in system.
25 **/
26 VOID *
27 InternalHstiFindAip (
28 IN UINT32 Role,
29 IN CHAR16 *ImplementationID OPTIONAL,
30 OUT VOID **HstiData OPTIONAL,
31 OUT UINTN *HstiSize OPTIONAL
32 )
33 {
34 EFI_STATUS Status;
35 EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;
36 UINTN NoHandles;
37 EFI_HANDLE *Handles;
38 UINTN Index;
39 EFI_GUID *InfoTypesBuffer;
40 UINTN InfoTypesBufferCount;
41 UINTN InfoTypesIndex;
42 EFI_ADAPTER_INFORMATION_PROTOCOL *AipCandidate;
43 VOID *InformationBlock;
44 UINTN InformationBlockSize;
45 ADAPTER_INFO_PLATFORM_SECURITY *Hsti;
46
47 Status = gBS->LocateHandleBuffer (
48 ByProtocol,
49 &gEfiAdapterInformationProtocolGuid,
50 NULL,
51 &NoHandles,
52 &Handles
53 );
54 if (EFI_ERROR (Status)) {
55 return NULL;
56 }
57
58 Hsti = NULL;
59 Aip = NULL;
60 InformationBlock = NULL;
61 InformationBlockSize = 0;
62 for (Index = 0; Index < NoHandles; Index++) {
63 Status = gBS->HandleProtocol (
64 Handles[Index],
65 &gEfiAdapterInformationProtocolGuid,
66 (VOID **)&Aip
67 );
68 if (EFI_ERROR (Status)) {
69 continue;
70 }
71
72 //
73 // Check AIP
74 //
75 Status = Aip->GetSupportedTypes (
76 Aip,
77 &InfoTypesBuffer,
78 &InfoTypesBufferCount
79 );
80 if (EFI_ERROR (Status) || (InfoTypesBuffer == NULL) || (InfoTypesBufferCount == 0)) {
81 continue;
82 }
83
84 AipCandidate = NULL;
85 for (InfoTypesIndex = 0; InfoTypesIndex < InfoTypesBufferCount; InfoTypesIndex++) {
86 if (CompareGuid (&InfoTypesBuffer[InfoTypesIndex], &gAdapterInfoPlatformSecurityGuid)) {
87 AipCandidate = Aip;
88 break;
89 }
90 }
91
92 FreePool (InfoTypesBuffer);
93
94 if (AipCandidate == NULL) {
95 continue;
96 }
97
98 //
99 // Check HSTI Role
100 //
101 Aip = AipCandidate;
102 Status = Aip->GetInformation (
103 Aip,
104 &gAdapterInfoPlatformSecurityGuid,
105 &InformationBlock,
106 &InformationBlockSize
107 );
108 if (EFI_ERROR (Status)) {
109 continue;
110 }
111
112 Hsti = InformationBlock;
113 if ((Hsti->Role == Role) &&
114 ((ImplementationID == NULL) || (StrCmp (ImplementationID, Hsti->ImplementationID) == 0)))
115 {
116 break;
117 } else {
118 Hsti = NULL;
119 FreePool (InformationBlock);
120 continue;
121 }
122 }
123
124 FreePool (Handles);
125
126 if (Hsti == NULL) {
127 return NULL;
128 }
129
130 if (HstiData != NULL) {
131 *HstiData = InformationBlock;
132 }
133
134 if (HstiSize != NULL) {
135 *HstiSize = InformationBlockSize;
136 }
137
138 return Aip;
139 }
140
141 /**
142 Return if input HSTI data follows HSTI specification.
143
144 @param HstiData HSTI data
145 @param HstiSize HSTI size
146
147 @retval TRUE HSTI data follows HSTI specification.
148 @retval FALSE HSTI data does not follow HSTI specification.
149 **/
150 BOOLEAN
151 InternalHstiIsValidTable (
152 IN VOID *HstiData,
153 IN UINTN HstiSize
154 )
155 {
156 ADAPTER_INFO_PLATFORM_SECURITY *Hsti;
157 UINTN Index;
158 CHAR16 *ErrorString;
159 CHAR16 ErrorChar;
160 UINTN ErrorStringSize;
161 UINTN ErrorStringLength;
162
163 Hsti = HstiData;
164
165 //
166 // basic check for header
167 //
168 if (HstiData == NULL) {
169 DEBUG ((DEBUG_ERROR, "HstiData == NULL\n"));
170 return FALSE;
171 }
172
173 if (HstiSize < sizeof (ADAPTER_INFO_PLATFORM_SECURITY)) {
174 DEBUG ((DEBUG_ERROR, "HstiSize < sizeof(ADAPTER_INFO_PLATFORM_SECURITY)\n"));
175 return FALSE;
176 }
177
178 if (((HstiSize - sizeof (ADAPTER_INFO_PLATFORM_SECURITY)) / 3) < Hsti->SecurityFeaturesSize) {
179 DEBUG ((DEBUG_ERROR, "((HstiSize - sizeof(ADAPTER_INFO_PLATFORM_SECURITY)) / 3) < SecurityFeaturesSize\n"));
180 return FALSE;
181 }
182
183 //
184 // Check Version
185 //
186 if (Hsti->Version != PLATFORM_SECURITY_VERSION_VNEXTCS) {
187 DEBUG ((DEBUG_ERROR, "Version != PLATFORM_SECURITY_VERSION_VNEXTCS\n"));
188 return FALSE;
189 }
190
191 //
192 // Check Role
193 //
194 if ((Hsti->Role < PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE) ||
195 (Hsti->Role > PLATFORM_SECURITY_ROLE_IMPLEMENTOR_ODM))
196 {
197 DEBUG ((DEBUG_ERROR, "Role < PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE ||\n"));
198 DEBUG ((DEBUG_ERROR, "Role > PLATFORM_SECURITY_ROLE_IMPLEMENTOR_ODM\n"));
199 return FALSE;
200 }
201
202 //
203 // Check ImplementationID
204 //
205 for (Index = 0; Index < sizeof (Hsti->ImplementationID)/sizeof (Hsti->ImplementationID[0]); Index++) {
206 if (Hsti->ImplementationID[Index] == 0) {
207 break;
208 }
209 }
210
211 if (Index == sizeof (Hsti->ImplementationID)/sizeof (Hsti->ImplementationID[0])) {
212 DEBUG ((DEBUG_ERROR, "ImplementationID has no NUL CHAR\n"));
213 return FALSE;
214 }
215
216 ErrorStringSize = HstiSize - sizeof (ADAPTER_INFO_PLATFORM_SECURITY) - Hsti->SecurityFeaturesSize * 3;
217 ErrorString = (CHAR16 *)((UINTN)Hsti + sizeof (ADAPTER_INFO_PLATFORM_SECURITY) + Hsti->SecurityFeaturesSize * 3);
218
219 //
220 // basic check for ErrorString
221 //
222 if (ErrorStringSize == 0) {
223 DEBUG ((DEBUG_ERROR, "ErrorStringSize == 0\n"));
224 return FALSE;
225 }
226
227 if ((ErrorStringSize & BIT0) != 0) {
228 DEBUG ((DEBUG_ERROR, "(ErrorStringSize & BIT0) != 0\n"));
229 return FALSE;
230 }
231
232 //
233 // ErrorString might not be CHAR16 aligned.
234 //
235 CopyMem (&ErrorChar, ErrorString, sizeof (ErrorChar));
236 for (ErrorStringLength = 0; (ErrorChar != 0) && (ErrorStringLength < (ErrorStringSize/2)); ErrorStringLength++) {
237 ErrorString++;
238 CopyMem (&ErrorChar, ErrorString, sizeof (ErrorChar));
239 }
240
241 //
242 // check the length of ErrorString
243 //
244 if (ErrorChar != 0) {
245 DEBUG ((DEBUG_ERROR, "ErrorString has no NUL CHAR\n"));
246 return FALSE;
247 }
248
249 if (ErrorStringLength == (ErrorStringSize/2)) {
250 DEBUG ((DEBUG_ERROR, "ErrorString Length incorrect\n"));
251 return FALSE;
252 }
253
254 return TRUE;
255 }
256
257 /**
258 Publish HSTI table in AIP protocol.
259
260 One system should have only one PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE.
261
262 If the Role is NOT PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,
263 SecurityFeaturesRequired field will be ignored.
264
265 @param Hsti HSTI data
266 @param HstiSize HSTI size
267
268 @retval EFI_SUCCESS The HSTI data is published in AIP protocol.
269 @retval EFI_ALREADY_STARTED There is already HSTI table with Role and ImplementationID published in system.
270 @retval EFI_VOLUME_CORRUPTED The input HSTI data does not follow HSTI specification.
271 @retval EFI_OUT_OF_RESOURCES There is not enough system resource to publish HSTI data in AIP protocol.
272 **/
273 EFI_STATUS
274 EFIAPI
275 HstiLibSetTable (
276 IN VOID *Hsti,
277 IN UINTN HstiSize
278 )
279 {
280 EFI_STATUS Status;
281 EFI_HANDLE Handle;
282 HSTI_AIP_PRIVATE_DATA *HstiAip;
283 EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;
284 UINT32 Role;
285 CHAR16 *ImplementationID;
286 UINT32 SecurityFeaturesSize;
287 UINT8 *SecurityFeaturesRequired;
288
289 if (!InternalHstiIsValidTable (Hsti, HstiSize)) {
290 return EFI_VOLUME_CORRUPTED;
291 }
292
293 Role = ((ADAPTER_INFO_PLATFORM_SECURITY *)Hsti)->Role;
294 ImplementationID = ((ADAPTER_INFO_PLATFORM_SECURITY *)Hsti)->ImplementationID;
295 Aip = InternalHstiFindAip (Role, ImplementationID, NULL, NULL);
296 if (Aip != NULL) {
297 return EFI_ALREADY_STARTED;
298 }
299
300 HstiAip = AllocateZeroPool (sizeof (HSTI_AIP_PRIVATE_DATA));
301 if (HstiAip == NULL) {
302 return EFI_OUT_OF_RESOURCES;
303 }
304
305 HstiAip->Hsti = AllocateCopyPool (HstiSize, Hsti);
306 if (HstiAip->Hsti == NULL) {
307 FreePool (HstiAip);
308 return EFI_OUT_OF_RESOURCES;
309 }
310
311 if (Role != PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE) {
312 SecurityFeaturesRequired = (UINT8 *)HstiAip->Hsti + sizeof (ADAPTER_INFO_PLATFORM_SECURITY);
313 SecurityFeaturesSize = ((ADAPTER_INFO_PLATFORM_SECURITY *)Hsti)->SecurityFeaturesSize;
314 ZeroMem (SecurityFeaturesRequired, SecurityFeaturesSize);
315 }
316
317 HstiAip->Signature = HSTI_AIP_PRIVATE_SIGNATURE;
318 CopyMem (&HstiAip->Aip, &mAdapterInformationProtocol, sizeof (EFI_ADAPTER_INFORMATION_PROTOCOL));
319 HstiAip->HstiSize = HstiSize;
320 HstiAip->HstiMaxSize = HstiSize;
321
322 Handle = NULL;
323 Status = gBS->InstallMultipleProtocolInterfaces (
324 &Handle,
325 &gEfiAdapterInformationProtocolGuid,
326 &HstiAip->Aip,
327 NULL
328 );
329 if (EFI_ERROR (Status)) {
330 FreePool (HstiAip->Hsti);
331 FreePool (HstiAip);
332 }
333
334 return Status;
335 }
336
337 /**
338 Search HSTI table in AIP protocol, and return the data.
339 This API will return the HSTI table with indicated Role and ImplementationID,
340 NULL ImplementationID means to find the first HSTI table with indicated Role.
341
342 @param Role Role of HSTI data.
343 @param ImplementationID ImplementationID of HSTI data.
344 NULL means find the first one match Role.
345 @param Hsti HSTI data. This buffer is allocated by callee, and it
346 is the responsibility of the caller to free it after
347 using it.
348 @param HstiSize HSTI size
349
350 @retval EFI_SUCCESS The HSTI data in AIP protocol is returned.
351 @retval EFI_NOT_FOUND There is not HSTI table with the Role and ImplementationID published in system.
352 **/
353 EFI_STATUS
354 EFIAPI
355 HstiLibGetTable (
356 IN UINT32 Role,
357 IN CHAR16 *ImplementationID OPTIONAL,
358 OUT VOID **Hsti,
359 OUT UINTN *HstiSize
360 )
361 {
362 EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;
363
364 Aip = InternalHstiFindAip (Role, ImplementationID, Hsti, HstiSize);
365 if (Aip == NULL) {
366 return EFI_NOT_FOUND;
367 }
368
369 return EFI_SUCCESS;
370 }
371
372 /**
373 Record FeaturesVerified in published HSTI table.
374 This API will update the HSTI table with indicated Role and ImplementationID,
375 NULL ImplementationID means to find the first HSTI table with indicated Role.
376
377 @param Role Role of HSTI data.
378 @param ImplementationID ImplementationID of HSTI data.
379 NULL means find the first one match Role.
380 @param ByteIndex Byte index of FeaturesVerified of HSTI data.
381 @param BitMask Bit mask of FeaturesVerified of HSTI data.
382 @param Set TRUE means to set the FeaturesVerified bit.
383 FALSE means to clear the FeaturesVerified bit.
384
385 @retval EFI_SUCCESS The FeaturesVerified of HSTI data updated in AIP protocol.
386 @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system.
387 @retval EFI_UNSUPPORTED The ByteIndex is invalid.
388 **/
389 EFI_STATUS
390 InternalHstiRecordFeaturesVerified (
391 IN UINT32 Role,
392 IN CHAR16 *ImplementationID OPTIONAL,
393 IN UINT32 ByteIndex,
394 IN UINT8 Bit,
395 IN BOOLEAN Set
396 )
397 {
398 EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;
399 ADAPTER_INFO_PLATFORM_SECURITY *Hsti;
400 UINTN HstiSize;
401 UINT8 *SecurityFeaturesVerified;
402 EFI_STATUS Status;
403
404 Aip = InternalHstiFindAip (Role, ImplementationID, (VOID **)&Hsti, &HstiSize);
405 if (Aip == NULL) {
406 return EFI_NOT_STARTED;
407 }
408
409 if (ByteIndex >= Hsti->SecurityFeaturesSize) {
410 return EFI_UNSUPPORTED;
411 }
412
413 SecurityFeaturesVerified = (UINT8 *)((UINTN)Hsti + sizeof (ADAPTER_INFO_PLATFORM_SECURITY) + Hsti->SecurityFeaturesSize * 2);
414
415 if (Set) {
416 SecurityFeaturesVerified[ByteIndex] = (UINT8)(SecurityFeaturesVerified[ByteIndex] | (Bit));
417 } else {
418 SecurityFeaturesVerified[ByteIndex] = (UINT8)(SecurityFeaturesVerified[ByteIndex] & (~Bit));
419 }
420
421 Status = Aip->SetInformation (
422 Aip,
423 &gAdapterInfoPlatformSecurityGuid,
424 Hsti,
425 HstiSize
426 );
427 FreePool (Hsti);
428 return Status;
429 }
430
431 /**
432 Set FeaturesVerified in published HSTI table.
433 This API will update the HSTI table with indicated Role and ImplementationID,
434 NULL ImplementationID means to find the first HSTI table with indicated Role.
435
436 @param Role Role of HSTI data.
437 @param ImplementationID ImplementationID of HSTI data.
438 NULL means find the first one match Role.
439 @param ByteIndex Byte index of FeaturesVerified of HSTI data.
440 @param BitMask Bit mask of FeaturesVerified of HSTI data.
441
442 @retval EFI_SUCCESS The FeaturesVerified of HSTI data updated in AIP protocol.
443 @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system.
444 @retval EFI_UNSUPPORTED The ByteIndex is invalid.
445 **/
446 EFI_STATUS
447 EFIAPI
448 HstiLibSetFeaturesVerified (
449 IN UINT32 Role,
450 IN CHAR16 *ImplementationID OPTIONAL,
451 IN UINT32 ByteIndex,
452 IN UINT8 BitMask
453 )
454 {
455 return InternalHstiRecordFeaturesVerified (
456 Role,
457 ImplementationID,
458 ByteIndex,
459 BitMask,
460 TRUE
461 );
462 }
463
464 /**
465 Clear FeaturesVerified in published HSTI table.
466 This API will update the HSTI table with indicated Role and ImplementationID,
467 NULL ImplementationID means to find the first HSTI table with indicated Role.
468
469 @param Role Role of HSTI data.
470 @param ImplementationID ImplementationID of HSTI data.
471 NULL means find the first one match Role.
472 @param ByteIndex Byte index of FeaturesVerified of HSTI data.
473 @param BitMask Bit mask of FeaturesVerified of HSTI data.
474
475 @retval EFI_SUCCESS The FeaturesVerified of HSTI data updated in AIP protocol.
476 @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system.
477 @retval EFI_UNSUPPORTED The ByteIndex is invalid.
478 **/
479 EFI_STATUS
480 EFIAPI
481 HstiLibClearFeaturesVerified (
482 IN UINT32 Role,
483 IN CHAR16 *ImplementationID OPTIONAL,
484 IN UINT32 ByteIndex,
485 IN UINT8 BitMask
486 )
487 {
488 return InternalHstiRecordFeaturesVerified (
489 Role,
490 ImplementationID,
491 ByteIndex,
492 BitMask,
493 FALSE
494 );
495 }
496
497 /**
498 Record ErrorString in published HSTI table.
499 This API will update the HSTI table with indicated Role and ImplementationID,
500 NULL ImplementationID means to find the first HSTI table with indicated Role.
501
502 @param Role Role of HSTI data.
503 @param ImplementationID ImplementationID of HSTI data.
504 NULL means find the first one match Role.
505 @param ErrorString ErrorString of HSTI data.
506 @param Append TRUE means to append the ErrorString to HSTI table.
507 FALSE means to set the ErrorString in HSTI table.
508
509 @retval EFI_SUCCESS The ErrorString of HSTI data is published in AIP protocol.
510 @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system.
511 @retval EFI_OUT_OF_RESOURCES There is not enough system resource to update ErrorString.
512 **/
513 EFI_STATUS
514 InternalHstiRecordErrorString (
515 IN UINT32 Role,
516 IN CHAR16 *ImplementationID OPTIONAL,
517 IN CHAR16 *ErrorString,
518 IN BOOLEAN Append
519 )
520 {
521 EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;
522 ADAPTER_INFO_PLATFORM_SECURITY *Hsti;
523 UINTN HstiSize;
524 UINTN StringSize;
525 VOID *NewHsti;
526 UINTN NewHstiSize;
527 UINTN Offset;
528 EFI_STATUS Status;
529
530 Aip = InternalHstiFindAip (Role, ImplementationID, (VOID **)&Hsti, &HstiSize);
531 if (Aip == NULL) {
532 return EFI_NOT_STARTED;
533 }
534
535 if (Append) {
536 Offset = HstiSize - sizeof (CHAR16);
537 } else {
538 Offset = sizeof (ADAPTER_INFO_PLATFORM_SECURITY) + Hsti->SecurityFeaturesSize * 3;
539 }
540
541 StringSize = StrSize (ErrorString);
542
543 NewHstiSize = Offset + StringSize;
544 NewHsti = AllocatePool (NewHstiSize);
545 if (NewHsti == NULL) {
546 return EFI_OUT_OF_RESOURCES;
547 }
548
549 CopyMem (NewHsti, Hsti, Offset);
550 CopyMem ((UINT8 *)NewHsti + Offset, ErrorString, StringSize);
551
552 Status = Aip->SetInformation (
553 Aip,
554 &gAdapterInfoPlatformSecurityGuid,
555 NewHsti,
556 NewHstiSize
557 );
558 FreePool (Hsti);
559 FreePool (NewHsti);
560 return Status;
561 }
562
563 /**
564 Append ErrorString in published HSTI table.
565 This API will update the HSTI table with indicated Role and ImplementationID,
566 NULL ImplementationID means to find the first HSTI table with indicated Role.
567
568 @param Role Role of HSTI data.
569 @param ImplementationID ImplementationID of HSTI data.
570 NULL means find the first one match Role.
571 @param ErrorString ErrorString of HSTI data.
572
573 @retval EFI_SUCCESS The ErrorString of HSTI data is updated in AIP protocol.
574 @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system.
575 @retval EFI_OUT_OF_RESOURCES There is not enough system resource to update ErrorString.
576 **/
577 EFI_STATUS
578 EFIAPI
579 HstiLibAppendErrorString (
580 IN UINT32 Role,
581 IN CHAR16 *ImplementationID OPTIONAL,
582 IN CHAR16 *ErrorString
583 )
584 {
585 return InternalHstiRecordErrorString (
586 Role,
587 ImplementationID,
588 ErrorString,
589 TRUE
590 );
591 }
592
593 /**
594 Set a new ErrorString in published HSTI table.
595 This API will update the HSTI table with indicated Role and ImplementationID,
596 NULL ImplementationID means to find the first HSTI table with indicated Role.
597
598 @param Role Role of HSTI data.
599 @param ImplementationID ImplementationID of HSTI data.
600 NULL means find the first one match Role.
601 @param ErrorString ErrorString of HSTI data.
602
603 @retval EFI_SUCCESS The ErrorString of HSTI data is updated in AIP protocol.
604 @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system.
605 @retval EFI_OUT_OF_RESOURCES There is not enough system resource to update ErrorString.
606 **/
607 EFI_STATUS
608 EFIAPI
609 HstiLibSetErrorString (
610 IN UINT32 Role,
611 IN CHAR16 *ImplementationID OPTIONAL,
612 IN CHAR16 *ErrorString
613 )
614 {
615 return InternalHstiRecordErrorString (
616 Role,
617 ImplementationID,
618 ErrorString,
619 FALSE
620 );
621 }