]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Library/PeilessStartupLib/IntelTdx.c
216c413caad5382fcd66423c1e4a4e6d36828547
[mirror_edk2.git] / OvmfPkg / Library / PeilessStartupLib / IntelTdx.c
1 /** @file
2 Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
3 SPDX-License-Identifier: BSD-2-Clause-Patent
4 **/
5
6 #include <PiPei.h>
7 #include <Library/BaseLib.h>
8 #include <Library/BaseMemoryLib.h>
9 #include <Library/DebugLib.h>
10 #include <IndustryStandard/Tpm20.h>
11 #include <IndustryStandard/UefiTcgPlatform.h>
12 #include <Library/HobLib.h>
13 #include <Library/PrintLib.h>
14 #include <Library/TpmMeasurementLib.h>
15
16 #include "PeilessStartupInternal.h"
17
18 #pragma pack(1)
19
20 #define HANDOFF_TABLE_DESC "TdxTable"
21 typedef struct {
22 UINT8 TableDescriptionSize;
23 UINT8 TableDescription[sizeof (HANDOFF_TABLE_DESC)];
24 UINT64 NumberOfTables;
25 EFI_CONFIGURATION_TABLE TableEntry[1];
26 } TDX_HANDOFF_TABLE_POINTERS2;
27
28 #define FV_HANDOFF_TABLE_DESC "Fv(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)"
29 typedef struct {
30 UINT8 BlobDescriptionSize;
31 UINT8 BlobDescription[sizeof (FV_HANDOFF_TABLE_DESC)];
32 EFI_PHYSICAL_ADDRESS BlobBase;
33 UINT64 BlobLength;
34 } FV_HANDOFF_TABLE_POINTERS2;
35
36 #pragma pack()
37
38 /**
39 Measure the Hoblist passed from the VMM.
40
41 @param[in] VmmHobList The Hoblist pass the firmware
42
43 @retval EFI_SUCCESS Fv image is measured successfully
44 or it has been already measured.
45 @retval Others Other errors as indicated
46 **/
47 EFI_STATUS
48 EFIAPI
49 MeasureHobList (
50 IN CONST VOID *VmmHobList
51 )
52 {
53 EFI_PEI_HOB_POINTERS Hob;
54 TDX_HANDOFF_TABLE_POINTERS2 HandoffTables;
55 EFI_STATUS Status;
56
57 if (!TdIsEnabled ()) {
58 ASSERT (FALSE);
59 return EFI_UNSUPPORTED;
60 }
61
62 Hob.Raw = (UINT8 *)VmmHobList;
63
64 //
65 // Parse the HOB list until end of list.
66 //
67 while (!END_OF_HOB_LIST (Hob)) {
68 Hob.Raw = GET_NEXT_HOB (Hob);
69 }
70
71 //
72 // Init the log event for HOB measurement
73 //
74
75 HandoffTables.TableDescriptionSize = sizeof (HandoffTables.TableDescription);
76 CopyMem (HandoffTables.TableDescription, HANDOFF_TABLE_DESC, sizeof (HandoffTables.TableDescription));
77 HandoffTables.NumberOfTables = 1;
78 CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), &gUefiOvmfPkgTokenSpaceGuid);
79 HandoffTables.TableEntry[0].VendorTable = (VOID *)VmmHobList;
80
81 Status = TpmMeasureAndLogData (
82 1, // PCRIndex
83 EV_EFI_HANDOFF_TABLES2, // EventType
84 (VOID *)&HandoffTables, // EventData
85 sizeof (HandoffTables), // EventSize
86 (UINT8 *)(UINTN)VmmHobList, // HashData
87 (UINTN)((UINT8 *)Hob.Raw - (UINT8 *)VmmHobList) // HashDataLen
88 );
89
90 if (EFI_ERROR (Status)) {
91 ASSERT (FALSE);
92 }
93
94 return Status;
95 }
96
97 /**
98 Get the FvName from the FV header.
99
100 Causion: The FV is untrusted input.
101
102 @param[in] FvBase Base address of FV image.
103 @param[in] FvLength Length of FV image.
104
105 @return FvName pointer
106 @retval NULL FvName is NOT found
107 **/
108 VOID *
109 GetFvName (
110 IN EFI_PHYSICAL_ADDRESS FvBase,
111 IN UINT64 FvLength
112 )
113 {
114 EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
115 EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader;
116
117 if (FvBase >= MAX_ADDRESS) {
118 return NULL;
119 }
120
121 if (FvLength >= MAX_ADDRESS - FvBase) {
122 return NULL;
123 }
124
125 if (FvLength < sizeof (EFI_FIRMWARE_VOLUME_HEADER)) {
126 return NULL;
127 }
128
129 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvBase;
130 if (FvHeader->ExtHeaderOffset < sizeof (EFI_FIRMWARE_VOLUME_HEADER)) {
131 return NULL;
132 }
133
134 if (FvHeader->ExtHeaderOffset + sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER) > FvLength) {
135 return NULL;
136 }
137
138 FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(UINTN)(FvBase + FvHeader->ExtHeaderOffset);
139
140 return &FvExtHeader->FvName;
141 }
142
143 /**
144 Measure FV image.
145
146 @param[in] FvBase Base address of FV image.
147 @param[in] FvLength Length of FV image.
148 @param[in] PcrIndex Index of PCR
149
150 @retval EFI_SUCCESS Fv image is measured successfully
151 or it has been already measured.
152 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
153 @retval EFI_DEVICE_ERROR The command was unsuccessful.
154
155 **/
156 EFI_STATUS
157 EFIAPI
158 MeasureFvImage (
159 IN EFI_PHYSICAL_ADDRESS FvBase,
160 IN UINT64 FvLength,
161 IN UINT8 PcrIndex
162 )
163 {
164 EFI_STATUS Status;
165 FV_HANDOFF_TABLE_POINTERS2 FvBlob2;
166 VOID *FvName;
167
168 //
169 // Init the log event for FV measurement
170 //
171 FvBlob2.BlobDescriptionSize = sizeof (FvBlob2.BlobDescription);
172 CopyMem (FvBlob2.BlobDescription, FV_HANDOFF_TABLE_DESC, sizeof (FvBlob2.BlobDescription));
173 FvName = GetFvName (FvBase, FvLength);
174 if (FvName != NULL) {
175 AsciiSPrint ((CHAR8 *)FvBlob2.BlobDescription, sizeof (FvBlob2.BlobDescription), "Fv(%g)", FvName);
176 }
177
178 FvBlob2.BlobBase = FvBase;
179 FvBlob2.BlobLength = FvLength;
180
181 Status = TpmMeasureAndLogData (
182 1, // PCRIndex
183 EV_EFI_PLATFORM_FIRMWARE_BLOB2, // EventType
184 (VOID *)&FvBlob2, // EventData
185 sizeof (FvBlob2), // EventSize
186 (UINT8 *)(UINTN)FvBase, // HashData
187 (UINTN)(FvLength) // HashDataLen
188 );
189
190 if (EFI_ERROR (Status)) {
191 DEBUG ((DEBUG_ERROR, "The FV which failed to be measured starts at: 0x%x\n", FvBase));
192 ASSERT (FALSE);
193 }
194
195 return Status;
196 }