[edk2-devel] [PATCH v1 5/8] OvmfPkg/AmdSev: Add library to find encrypted hashes for the FwCfg device

Dov Murik dovmurik at linux.ibm.com
Tue May 25 05:31:13 UTC 2021


From: James Bottomley <jejb at linux.ibm.com>

The library finds and checks out the encrypted page from the memfd and
installs a finder routine for GUID described hashes if it checks out
OK.

Cc: Laszlo Ersek <lersek at redhat.com>
Cc: Ard Biesheuvel <ardb+tianocore at kernel.org>
Cc: Jordan Justen <jordan.l.justen at intel.com>
Cc: Ashish Kalra <ashish.kalra at amd.com>
Cc: Brijesh Singh <brijesh.singh at amd.com>
Cc: Erdem Aktas <erdemaktas at google.com>
Cc: James Bottomley <jejb at linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao at intel.com>
Cc: Min Xu <min.m.xu at intel.com>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Signed-off-by: James Bottomley <jejb at linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik at linux.ibm.com>
---
 OvmfPkg/OvmfPkg.dec                                          |   4 +
 OvmfPkg/AmdSev/AmdSevX64.dsc                                 |   1 +
 OvmfPkg/AmdSev/Library/SevHashFinderLib/SevHashFinderLib.inf |  34 ++++++
 OvmfPkg/AmdSev/Include/Library/SevHashFinderLib.h            |  47 ++++++++
 OvmfPkg/AmdSev/Library/SevHashFinderLib/SevHashFinderLib.c   | 126 ++++++++++++++++++++
 5 files changed, 212 insertions(+)

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 7cd29a60a436..36f0a2cb4cf9 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -18,8 +18,12 @@ [Defines]
 [Includes]
   Include
   Csm/Include
+  AmdSev/Include
 
 [LibraryClasses]
+  ##  @libraryclass  Functions for extracting Sev Hashes from the MEMFD
+  SevHashFinderLib|AmdSev/Include/Library/SevHashFinderLib.h
+
   ##  @libraryclass  Access bhyve's firmware control interface.
   BhyveFwCtlLib|Include/Library/BhyveFwCtlLib.h
 
diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index f820e81fad27..b4484ca07614 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -118,6 +118,7 @@ [SkuIds]
 !include MdePkg/MdeLibs.dsc.inc
 
 [LibraryClasses]
+  SevHashFinderLib|OvmfPkg/AmdSev/Library/SevHashFinderLib/SevHashFinderLib.inf
   PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
   TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
   ResetSystemLib|OvmfPkg/Library/ResetSystemLib/BaseResetSystemLib.inf
diff --git a/OvmfPkg/AmdSev/Library/SevHashFinderLib/SevHashFinderLib.inf b/OvmfPkg/AmdSev/Library/SevHashFinderLib/SevHashFinderLib.inf
new file mode 100644
index 000000000000..79ebf51baed0
--- /dev/null
+++ b/OvmfPkg/AmdSev/Library/SevHashFinderLib/SevHashFinderLib.inf
@@ -0,0 +1,34 @@
+##  @file
+#  Provides the Secure Verification services for AMD SEV firmware config
+#
+#  Copyright (C) 2021 James Bottomley, IBM Corporation.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SevHashFinderLib
+  FILE_GUID                      = d8ef4e22-991a-4134-b285-1d970cfe2ca6
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SevHashFinderLib
+  CONSTRUCTOR                    = SevHashFinderLibConstructor
+
+[Sources]
+  SevHashFinderLib.c
+
+[Packages]
+  CryptoPkg/CryptoPkg.dec
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  BaseCryptLib
+  BaseMemoryLib
+  PcdLib
+
+[FixedPcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdQemuHashTableBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdQemuHashTableSize
diff --git a/OvmfPkg/AmdSev/Include/Library/SevHashFinderLib.h b/OvmfPkg/AmdSev/Include/Library/SevHashFinderLib.h
new file mode 100644
index 000000000000..79d5039a649b
--- /dev/null
+++ b/OvmfPkg/AmdSev/Include/Library/SevHashFinderLib.h
@@ -0,0 +1,47 @@
+/** @file
+  Validate a hash against that in the Sev Hash table
+
+  Copyright (C) 2021 James Bottomley, IBM Corporation.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __SEV_HASH_FINDER_LIB_H__
+#define __SEV_HASH_FINDER_LIB_H__
+
+/**
+  The Sev Hash table must be in encrypted memory and has the table
+  and its entries described by
+
+  <GUID>|UINT16 <len>|<data>
+
+  With the whole table GUID being 9438d606-4f22-4cc9-b479-a793d411fd21
+
+  The current possible table entries are for the kernel, the initrd
+  and the cmdline:
+
+  4de79437-abd2-427f-b835-d5b172d2045b  kernel
+  44baf731-3a2f-4bd7-9af1-41e29169781d  initrd
+  97d02dd8-bd20-4c94-aa78-e7714d36ab2a  cmdline
+
+  The size of the entry is used to identify the hash, but the
+  expectation is that it will be 32 bytes of SHA-256.
+**/
+
+#define SEV_HASH_TABLE_GUID \
+  (GUID) { 0x9438d606, 0x4f22, 0x4cc9, { 0xb4, 0x79, 0xa7, 0x93, 0xd4, 0x11, 0xfd, 0x21 } }
+#define SEV_KERNEL_HASH_GUID \
+  (GUID) { 0x4de79437, 0xabd2, 0x427f, { 0xb8, 0x35, 0xd5, 0xb1, 0x72, 0xd2, 0x04, 0x5b } }
+#define SEV_INITRD_HASH_GUID \
+  (GUID) { 0x44baf731, 0x3a2f, 0x4bd7, { 0x9a, 0xf1, 0x41, 0xe2, 0x91, 0x69, 0x78, 0x1d } }
+#define SEV_CMDLINE_HASH_GUID \
+  (GUID) { 0x97d02dd8, 0xbd20, 0x4c94, { 0xaa, 0x78, 0xe7, 0x71, 0x4d, 0x36, 0xab, 0x2a } }
+
+EFI_STATUS
+EFIAPI
+ValidateHashEntry (
+  IN CONST GUID *Guid,
+  IN CONST VOID *Buf,
+  UINT32 BufSize
+);
+
+#endif
diff --git a/OvmfPkg/AmdSev/Library/SevHashFinderLib/SevHashFinderLib.c b/OvmfPkg/AmdSev/Library/SevHashFinderLib/SevHashFinderLib.c
new file mode 100644
index 000000000000..9cb999ae8cad
--- /dev/null
+++ b/OvmfPkg/AmdSev/Library/SevHashFinderLib/SevHashFinderLib.c
@@ -0,0 +1,126 @@
+/** @file
+  SEV Hash finder library to locate the SEV encrypted hash table
+
+  Copyright (C) 2021 James Bottomley, IBM Corporation.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiDxe.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseCryptLib.h>
+#include <Library/DebugLib.h>
+#include <Library/SevHashFinderLib.h>
+
+#pragma pack (1)
+typedef struct {
+  GUID   Guid;
+  UINT16 Len;
+  UINT8  Data[];
+} HASH_TABLE;
+#pragma pack ()
+
+STATIC HASH_TABLE *mHashTable;
+STATIC UINT16 mHashTableSize;
+
+EFI_STATUS
+EFIAPI
+ValidateHashEntry (
+  IN CONST GUID *Guid,
+  IN CONST VOID *Buf,
+  UINT32 BufSize
+  )
+{
+  INT32 Len;
+  HASH_TABLE *Entry;
+  UINT8 Hash[SHA256_DIGEST_SIZE];
+
+  if (mHashTable == NULL || mHashTableSize == 0) {
+    DEBUG ((DEBUG_ERROR,
+      "%a: Verifier Called but no hash table discoverd in MEMFD\n",
+      __FUNCTION__));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Sha256HashAll (Buf, BufSize, Hash);
+
+  for (Entry = mHashTable, Len = 0;
+       Len < (INT32)mHashTableSize;
+       Len += Entry->Len,
+       Entry = (HASH_TABLE *)((UINT8 *)Entry + Entry->Len)) {
+    UINTN EntrySize;
+    EFI_STATUS Status;
+
+    if (!CompareGuid (&Entry->Guid, Guid)) {
+      continue;
+    }
+
+    DEBUG ((DEBUG_INFO, "%a: Found GUID %g in table\n", __FUNCTION__, Guid));
+
+    //
+    // Verify that the buffer's hash is identical to the hash table entry
+    //
+    EntrySize = Entry->Len - sizeof (Entry->Guid) - sizeof (Entry->Len);
+    if (EntrySize != SHA256_DIGEST_SIZE) {
+      DEBUG ((DEBUG_ERROR, "%a: Hash has the wrong size %d != %d\n",
+        __FUNCTION__, EntrySize, SHA256_DIGEST_SIZE));
+      return EFI_ACCESS_DENIED;
+    }
+    if (CompareMem (Entry->Data, Hash, EntrySize) == 0) {
+      Status = EFI_SUCCESS;
+      DEBUG ((DEBUG_INFO, "%a: Hash Comparison succeeded\n", __FUNCTION__));
+    } else {
+      Status = EFI_ACCESS_DENIED;
+      DEBUG ((DEBUG_ERROR, "%a: Hash Comparison Failed\n", __FUNCTION__));
+    }
+    return Status;
+  }
+  DEBUG ((DEBUG_ERROR, "%a: Hash GUID %g not found in table\n", __FUNCTION__,
+    Guid));
+  return EFI_ACCESS_DENIED;
+}
+
+/**
+  Register security measurement handler.
+
+  This function always returns success, even if the table
+  can't be found.  It only returns errors if an actual use
+  is made of the non-existent table because that indicates it
+  should have been present.
+
+  @param  ImageHandle   ImageHandle of the loaded driver.
+  @param  SystemTable   Pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS   The verifier tables were set up correctly
+**/
+EFI_STATUS
+EFIAPI
+SevHashFinderLibConstructor (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  HASH_TABLE *Ptr = (void *)FixedPcdGet64 (PcdQemuHashTableBase);
+  UINT32 Size = FixedPcdGet32 (PcdQemuHashTableSize);
+
+  mHashTable = NULL;
+  mHashTableSize = 0;
+
+  if (Ptr == NULL || Size == 0) {
+    return EFI_SUCCESS;
+  }
+
+  if (!CompareGuid (&Ptr->Guid, &SEV_HASH_TABLE_GUID)) {
+    return EFI_SUCCESS;
+  }
+
+  DEBUG ((DEBUG_INFO, "%a: found Injected Hash in secure location\n",
+    __FUNCTION__));
+
+  mHashTable = (HASH_TABLE *)Ptr->Data;
+  mHashTableSize = Ptr->Len - sizeof (Ptr->Guid) - sizeof (Ptr->Len);
+
+  DEBUG ((DEBUG_INFO, "%a: Ptr=%p, Size=%d\n", __FUNCTION__, mHashTable,
+    mHashTableSize));
+
+  return EFI_SUCCESS;
+}
-- 
2.25.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#75573): https://edk2.groups.io/g/devel/message/75573
Mute This Topic: https://groups.io/mt/83074457/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-






More information about the edk2-devel-archive mailing list