TianoCore EDK2 master
Loading...
Searching...
No Matches
BlobVerifierSevHashes.c
Go to the documentation of this file.
1
12#include <Library/BaseLib.h>
14#include <Library/DebugLib.h>
16
36#define SEV_HASH_TABLE_GUID \
37 (GUID) { 0x9438d606, 0x4f22, 0x4cc9, { 0xb4, 0x79, 0xa7, 0x93, 0xd4, 0x11, 0xfd, 0x21 } }
38#define SEV_KERNEL_HASH_GUID \
39 (GUID) { 0x4de79437, 0xabd2, 0x427f, { 0xb8, 0x35, 0xd5, 0xb1, 0x72, 0xd2, 0x04, 0x5b } }
40#define SEV_INITRD_HASH_GUID \
41 (GUID) { 0x44baf731, 0x3a2f, 0x4bd7, { 0x9a, 0xf1, 0x41, 0xe2, 0x91, 0x69, 0x78, 0x1d } }
42#define SEV_CMDLINE_HASH_GUID \
43 (GUID) { 0x97d02dd8, 0xbd20, 0x4c94, { 0xaa, 0x78, 0xe7, 0x71, 0x4d, 0x36, 0xab, 0x2a } }
44
45STATIC CONST EFI_GUID mSevKernelHashGuid = SEV_KERNEL_HASH_GUID;
46STATIC CONST EFI_GUID mSevInitrdHashGuid = SEV_INITRD_HASH_GUID;
47STATIC CONST EFI_GUID mSevCmdlineHashGuid = SEV_CMDLINE_HASH_GUID;
48
49#pragma pack (1)
50typedef struct {
51 GUID Guid;
52 UINT16 Len;
53 UINT8 Data[];
55#pragma pack ()
56
57STATIC HASH_TABLE *mHashesTable;
58STATIC UINT16 mHashesTableSize;
59
61CONST GUID *
62FindBlobEntryGuid (
63 IN CONST CHAR16 *BlobName
64 )
65{
66 if (StrCmp (BlobName, L"kernel") == 0) {
67 return &mSevKernelHashGuid;
68 } else if (StrCmp (BlobName, L"initrd") == 0) {
69 return &mSevInitrdHashGuid;
70 } else if (StrCmp (BlobName, L"cmdline") == 0) {
71 return &mSevCmdlineHashGuid;
72 } else {
73 return NULL;
74 }
75}
76
94EFIAPI
96 IN CONST CHAR16 *BlobName,
97 IN CONST VOID *Buf,
98 IN UINT32 BufSize,
99 IN EFI_STATUS FetchStatus
100 )
101{
102 CONST GUID *Guid;
103 INT32 Remaining;
104 HASH_TABLE *Entry;
105
106 // Enter a dead loop if the fetching of this blob
107 // failed. This prevents a malicious host from
108 // circumventing the following checks.
109 if (EFI_ERROR (FetchStatus)) {
110 DEBUG ((
111 DEBUG_ERROR,
112 "%a: Fetching blob failed.\n",
113 __func__
114 ));
115
116 CpuDeadLoop ();
117 }
118
119 if ((mHashesTable == NULL) || (mHashesTableSize == 0)) {
120 DEBUG ((
121 DEBUG_WARN,
122 "%a: Verifier called but no hashes table discoverd in MEMFD\n",
123 __func__
124 ));
125 return EFI_ACCESS_DENIED;
126 }
127
128 Guid = FindBlobEntryGuid (BlobName);
129 if (Guid == NULL) {
130 DEBUG ((
131 DEBUG_ERROR,
132 "%a: Unknown blob name \"%s\"\n",
133 __func__,
134 BlobName
135 ));
136
137 CpuDeadLoop ();
138 }
139
140 //
141 // Remaining is INT32 to catch underflow in case Entry->Len has a
142 // very high UINT16 value
143 //
144 for (Entry = mHashesTable, Remaining = mHashesTableSize;
145 Remaining >= sizeof *Entry && Remaining >= Entry->Len;
146 Remaining -= Entry->Len,
147 Entry = (HASH_TABLE *)((UINT8 *)Entry + Entry->Len))
148 {
149 UINTN EntrySize;
150 EFI_STATUS Status;
151 UINT8 Hash[SHA256_DIGEST_SIZE];
152
153 if (!CompareGuid (&Entry->Guid, Guid)) {
154 continue;
155 }
156
157 DEBUG ((DEBUG_INFO, "%a: Found GUID %g in table\n", __func__, Guid));
158
159 EntrySize = Entry->Len - sizeof Entry->Guid - sizeof Entry->Len;
160 if (EntrySize != SHA256_DIGEST_SIZE) {
161 DEBUG ((
162 DEBUG_WARN,
163 "%a: Hash has the wrong size %d != %d\n",
164 __func__,
165 EntrySize,
167 ));
168 return EFI_ACCESS_DENIED;
169 }
170
171 //
172 // Calculate the buffer's hash and verify that it is identical to the
173 // expected hash table entry
174 //
175 Sha256HashAll (Buf, BufSize, Hash);
176
177 if (CompareMem (Entry->Data, Hash, EntrySize) == 0) {
178 Status = EFI_SUCCESS;
179 DEBUG ((
180 DEBUG_INFO,
181 "%a: Hash comparison succeeded for \"%s\"\n",
182 __func__,
183 BlobName
184 ));
185 } else {
186 Status = EFI_ACCESS_DENIED;
187 DEBUG ((
188 DEBUG_ERROR,
189 "%a: Hash comparison failed for \"%s\"\n",
190 __func__,
191 BlobName
192 ));
193
194 CpuDeadLoop ();
195 }
196
197 return Status;
198 }
199
200 //
201 // If the GUID is not in the hash table, execution can still continue.
202 // This blob will not be measured, but at least one blob must be.
203 //
204 DEBUG ((
205 DEBUG_ERROR,
206 "%a: Hash GUID %g not found in table\n",
207 __func__,
208 Guid
209 ));
210 return EFI_SUCCESS;
211}
212
222RETURN_STATUS
223EFIAPI
225 VOID
226 )
227{
228 HASH_TABLE *Ptr;
229 UINT32 Size;
230
231 mHashesTable = NULL;
232 mHashesTableSize = 0;
233
234 Ptr = (void *)(UINTN)FixedPcdGet64 (PcdQemuHashTableBase);
235 Size = FixedPcdGet32 (PcdQemuHashTableSize);
236
237 if ((Ptr == NULL) || (Size < sizeof *Ptr) ||
238 !CompareGuid (&Ptr->Guid, &SEV_HASH_TABLE_GUID) ||
239 (Ptr->Len < sizeof *Ptr) || (Ptr->Len > Size))
240 {
241 return RETURN_SUCCESS;
242 }
243
244 DEBUG ((
245 DEBUG_INFO,
246 "%a: Found injected hashes table in secure location\n",
247 __func__
248 ));
249
250 mHashesTable = (HASH_TABLE *)Ptr->Data;
251 mHashesTableSize = Ptr->Len - sizeof Ptr->Guid - sizeof Ptr->Len;
252
253 DEBUG ((
254 DEBUG_VERBOSE,
255 "%a: mHashesTable=0x%p, Size=%u\n",
256 __func__,
257 mHashesTable,
258 mHashesTableSize
259 ));
260
261 return RETURN_SUCCESS;
262}
UINT64 UINTN
#define SHA256_DIGEST_SIZE
Definition: BaseCryptLib.h:44
BOOLEAN EFIAPI Sha256HashAll(IN CONST VOID *Data, IN UINTN DataSize, OUT UINT8 *HashValue)
Definition: CryptSha256.c:199
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
Definition: String.c:109
VOID EFIAPI CpuDeadLoop(VOID)
Definition: CpuDeadLoop.c:25
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
#define SEV_HASH_TABLE_GUID
EFI_STATUS EFIAPI VerifyBlob(IN CONST CHAR16 *BlobName, IN CONST VOID *Buf, IN UINT32 BufSize, IN EFI_STATUS FetchStatus)
RETURN_STATUS EFIAPI BlobVerifierLibSevHashesConstructor(VOID)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define RETURN_SUCCESS
Definition: Base.h:1066
#define IN
Definition: Base.h:279
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define FixedPcdGet32(TokenName)
Definition: PcdLib.h:92
#define FixedPcdGet64(TokenName)
Definition: PcdLib.h:106
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
Definition: Base.h:213