3 Blob verifier library that uses SEV hashes table. The hashes table holds the
4 allowed hashes of the kernel, initrd, and cmdline blobs.
6 Copyright (C) 2021, IBM Corporation
8 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include <Library/BaseCryptLib.h>
12 #include <Library/BaseLib.h>
13 #include <Library/BaseMemoryLib.h>
14 #include <Library/DebugLib.h>
15 #include <Library/BlobVerifierLib.h>
18 The SEV Hashes table must be in encrypted memory and has the table
19 and its entries described by
21 <GUID>|UINT16 <len>|<data>
23 With the whole table GUID being 9438d606-4f22-4cc9-b479-a793d411fd21
25 The current possible table entries are for the kernel, the initrd
28 4de79437-abd2-427f-b835-d5b172d2045b kernel
29 44baf731-3a2f-4bd7-9af1-41e29169781d initrd
30 97d02dd8-bd20-4c94-aa78-e7714d36ab2a cmdline
32 The size of the entry is used to identify the hash, but the
33 expectation is that it will be 32 bytes of SHA-256.
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 } }
45 STATIC CONST EFI_GUID mSevKernelHashGuid
= SEV_KERNEL_HASH_GUID
;
46 STATIC CONST EFI_GUID mSevInitrdHashGuid
= SEV_INITRD_HASH_GUID
;
47 STATIC CONST EFI_GUID mSevCmdlineHashGuid
= SEV_CMDLINE_HASH_GUID
;
57 STATIC HASH_TABLE
*mHashesTable
;
58 STATIC UINT16 mHashesTableSize
;
63 IN CONST CHAR16
*BlobName
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
;
78 Verify blob from an external source.
80 @param[in] BlobName The name of the blob
81 @param[in] Buf The data of the blob
82 @param[in] BufSize The size of the blob in bytes
84 @retval EFI_SUCCESS The blob was verified successfully.
85 @retval EFI_ACCESS_DENIED The blob could not be verified, and therefore
86 should be considered non-secure.
91 IN CONST CHAR16
*BlobName
,
100 if ((mHashesTable
== NULL
) || (mHashesTableSize
== 0)) {
103 "%a: Verifier called but no hashes table discoverd in MEMFD\n",
106 return EFI_ACCESS_DENIED
;
109 Guid
= FindBlobEntryGuid (BlobName
);
113 "%a: Unknown blob name \"%s\"\n",
117 return EFI_ACCESS_DENIED
;
121 // Remaining is INT32 to catch underflow in case Entry->Len has a
122 // very high UINT16 value
124 for (Entry
= mHashesTable
, Remaining
= mHashesTableSize
;
125 Remaining
>= sizeof *Entry
&& Remaining
>= Entry
->Len
;
126 Remaining
-= Entry
->Len
,
127 Entry
= (HASH_TABLE
*)((UINT8
*)Entry
+ Entry
->Len
))
131 UINT8 Hash
[SHA256_DIGEST_SIZE
];
133 if (!CompareGuid (&Entry
->Guid
, Guid
)) {
137 DEBUG ((DEBUG_INFO
, "%a: Found GUID %g in table\n", __FUNCTION__
, Guid
));
139 EntrySize
= Entry
->Len
- sizeof Entry
->Guid
- sizeof Entry
->Len
;
140 if (EntrySize
!= SHA256_DIGEST_SIZE
) {
143 "%a: Hash has the wrong size %d != %d\n",
148 return EFI_ACCESS_DENIED
;
152 // Calculate the buffer's hash and verify that it is identical to the
153 // expected hash table entry
155 Sha256HashAll (Buf
, BufSize
, Hash
);
157 if (CompareMem (Entry
->Data
, Hash
, EntrySize
) == 0) {
158 Status
= EFI_SUCCESS
;
161 "%a: Hash comparison succeeded for \"%s\"\n",
166 Status
= EFI_ACCESS_DENIED
;
169 "%a: Hash comparison failed for \"%s\"\n",
180 "%a: Hash GUID %g not found in table\n",
184 return EFI_ACCESS_DENIED
;
188 Locate the SEV hashes table.
190 This function always returns success, even if the table can't be found. The
191 subsequent VerifyBlob calls will fail if no table was found.
193 @retval RETURN_SUCCESS The hashes table is set up correctly, or there is no
198 BlobVerifierLibSevHashesConstructor (
206 mHashesTableSize
= 0;
208 Ptr
= (void *)(UINTN
)FixedPcdGet64 (PcdQemuHashTableBase
);
209 Size
= FixedPcdGet32 (PcdQemuHashTableSize
);
211 if ((Ptr
== NULL
) || (Size
< sizeof *Ptr
) ||
212 !CompareGuid (&Ptr
->Guid
, &SEV_HASH_TABLE_GUID
) ||
213 (Ptr
->Len
< sizeof *Ptr
) || (Ptr
->Len
> Size
))
215 return RETURN_SUCCESS
;
220 "%a: Found injected hashes table in secure location\n",
224 mHashesTable
= (HASH_TABLE
*)Ptr
->Data
;
225 mHashesTableSize
= Ptr
->Len
- sizeof Ptr
->Guid
- sizeof Ptr
->Len
;
229 "%a: mHashesTable=0x%p, Size=%u\n",
235 return RETURN_SUCCESS
;