[edk2-devel] [RFC PATCH 14/14] OvmfPkg/AmdSev: MH page encryption POC

Tobin Feldman-Fitzthum tobin at linux.ibm.com
Tue Mar 2 20:48:39 UTC 2021


This code is for demonstration purposes only. It is not secure or
robust. The purpose is to show where encryption will be incorporated
and to get a sense of the performance impact of adding encryption.

We plan to use AES-GCM to encrypt the pages as a stream. This will
also allow us to verify the GPA as part of the AAD, ensuring that
a malicious hypervisor hasn't exchanged pages in-flight.

Currently the CryptoPkg and the BaseCryptLib do not expose AES-GCM,
despite it being included in OpensslLib. Thus, we use CBC here.

Key sharing is out of scope for this part of the RFC. We assume that
the source and destination MH share a key. This will probably be
implemented via inject-launch-secret in the future. For now, we
hardcode a key, but this is strictly temporary.

We have had trouble using RandomBytes() in the MH when SEV is
enabled. Thus the IV is hardcoded. Again, this is temporary.

The HV and the MH will exchange information pertaining to encryption,
like the IV, via an additional header on the shared mailbox page.

This patch does not do any safety checks or handle encrypt/decrypt
failures. Again, this is only here to show where encryption will
go and generally how the MH on the source and target can share
pages without exposing guest memory to the HV.

Signed-off-by: Tobin Feldman-Fitzthum <tobin at linux.ibm.com>
---
 .../ConfidentialMigrationDxe.inf              |  2 ++
 .../ConfidentialMigrationDxe.c                | 36 +++++++++++++++++--
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
index 2816952863..ae074a8b07 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
@@ -22,6 +22,7 @@
   MdePkg/MdePkg.dec
   OvmfPkg/OvmfPkg.dec
   UefiCpuPkg/UefiCpuPkg.dec
+  CryptoPkg/CryptoPkg.dec
 
 [LibraryClasses]
   MemoryAllocationLib
@@ -29,6 +30,7 @@
   UefiBootServicesTableLib
   MpInitLib
   UefiDriverEntryPoint
+  BaseCryptLib
 
 [Protocols]
   gEfiMpServiceProtocolGuid
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
index 42b99be552..a9cb490561 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
@@ -10,6 +10,7 @@
 #include <Library/DebugLib.h>
 #include <Protocol/MpService.h>
 #include <Library/BaseMemoryLib.h>
+#include <Library/BaseCryptLib.h>
 
 #include "VirtualMemory.h"
 #include "MpLib.h"
@@ -46,6 +47,14 @@ typedef volatile struct {
   UINT32       done;
 } MH_COMMAND_PARAMETERS;
 
+//
+// Additional header for encryption support.
+//
+struct page_hdr {
+  UINT8        IV[16];
+  UINT8        tag[16];
+};
+
 //
 // Addresses for MH page table.
 //
@@ -57,6 +66,20 @@ STATIC PHYSICAL_ADDRESS  mMigrationHelperPageTables = 0;
 //
 #define UNENC_VIRT_ADDR_BASE    0xffffff8000000000ULL
 
+//
+// Key shared between source and target MH (temporary)
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 cipher_key[] = {
+  0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a
+ };
+
+//
+// IV for CBC cipher (temporary). We are having trouble with
+// calling RandomBytes from inside the Migration Handler
+//
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 Ivec[] = {
+  0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10
+};
 
 /**
   Allocates and fills in custom page tables for Migration Handler.
@@ -159,6 +182,8 @@ MigrationHandlerMain (
   UINT64                       params_base;
   MH_COMMAND_PARAMETERS        *params;
   VOID                         *page_va;
+  VOID                         *cipher_ctx;
+  INTN                         ctx_size;
 
   DebugPrint (DEBUG_INFO,"MIGRATION Handler Started\n");
 
@@ -171,6 +196,7 @@ MigrationHandlerMain (
   params_base = mailbox_start + UNENC_VIRT_ADDR_BASE;
   params = (VOID *)params_base;
   page_va = (VOID *)params_base + 0x1000;
+  //struct page_hdr *hdr_va = (void *) params_base + 0x800;
 
   mailbox_end = mailbox_start + 2 * EFI_PAGE_SIZE;
 
@@ -180,6 +206,9 @@ MigrationHandlerMain (
   stack_end = GetMHTopOfStack();
   stack_start = stack_end - PcdGet32(PcdCpuApStackSize);
 
+  ctx_size = AesGetContextSize ();
+  cipher_ctx = AllocateRuntimePool (ctx_size);
+
   DisableInterrupts();
   params->go = 0;
 
@@ -195,7 +224,9 @@ MigrationHandlerMain (
       break;
 
     case MH_FUNC_SAVE_PAGE:
-      CopyMem(page_va, (VOID *)params->gpa, 4096);
+      AesInit (cipher_ctx, cipher_key, 128);
+      AesCbcEncrypt(cipher_ctx, (VOID *)params->gpa, 4096, Ivec, page_va);
+
       params->ret = MH_SUCCESS;
       break;
 
@@ -208,7 +239,8 @@ MigrationHandlerMain (
           (params->gpa >= stack_start && params->gpa < stack_end)) {
       }
       else {
-        CopyMem((VOID *)params->gpa, page_va, 4096);
+        AesInit (cipher_ctx, cipher_key, 128);
+        AesCbcDecrypt (cipher_ctx, page_va, 4096, Ivec, (VOID *)params->gpa);
       }
       params->ret = MH_SUCCESS;
       break;
-- 
2.20.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#72362): https://edk2.groups.io/g/devel/message/72362
Mute This Topic: https://groups.io/mt/81036379/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