qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/2] sev: scan guest ROM for launch secret address


From: Tobin Feldman-Fitzthum
Subject: [PATCH 2/2] sev: scan guest ROM for launch secret address
Date: Thu, 28 May 2020 16:51:14 -0400

From: Tobin Feldman-Fitzthum <tobin@ibm.com>

In addition to using QMP to provide the guest memory address
that the launch secret blob will be injected into, the
secret address can also be specified in the guest ROM. This
patch adds sev_find_secret_gpa, which scans the ROM page by
page to find a launch secret table identified by a GUID. If
the table is found, the address it contains will be used
in place of any address specified via QMP.

Signed-off-by: Tobin Feldman-Fitzthum <tobin@linux.vnet.ibm.com>
---
 target/i386/sev.c      | 34 ++++++++++++++++++++++++++++++++--
 target/i386/sev_i386.h | 16 ++++++++++++++++
 2 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/target/i386/sev.c b/target/i386/sev.c
index 774e47d9d1..4adc56d7e3 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -706,6 +706,8 @@ sev_guest_init(const char *id)
     s->api_major = status.api_major;
     s->api_minor = status.api_minor;
 
+    s->secret_gpa = 0;
+
     trace_kvm_sev_init();
     ret = sev_ioctl(s->sev_fd, KVM_SEV_INIT, NULL, &fw_error);
     if (ret) {
@@ -731,6 +733,28 @@ err:
     return NULL;
 }
 
+static void
+sev_find_secret_gpa(uint8_t *ptr, uint64_t len)
+{
+    uint64_t offset;
+
+    SevROMSecretTable *secret_table;
+    QemuUUID secret_table_guid;
+
+    qemu_uuid_parse(SEV_ROM_SECRET_GUID,&secret_table_guid);
+    secret_table_guid = qemu_uuid_bswap(secret_table_guid);
+
+    offset = len - 0x1000;
+    while(offset > 0) {
+        secret_table = (SevROMSecretTable *)(ptr + offset);
+        if(qemu_uuid_is_equal(&secret_table_guid, (QemuUUID *) secret_table)){
+            sev_state->secret_gpa = (long unsigned int) secret_table->base;
+            break;
+        }
+        offset -= 0x1000;
+    }
+}
+
 int
 sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len)
 {
@@ -738,6 +762,9 @@ sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len)
 
     /* if SEV is in update state then encrypt the data else do nothing */
     if (sev_check_state(SEV_STATE_LAUNCH_UPDATE)) {
+        if(!sev_state->secret_gpa) {
+            sev_find_secret_gpa(ptr, len);
+           }
         return sev_launch_update_data(ptr, len);
     }
 
@@ -776,8 +803,8 @@ int sev_inject_launch_secret(const char *packet_hdr,
 
     /* secret can be inject only in this state */
     if (!sev_check_state(SEV_STATE_LAUNCH_SECRET)) {
-       error_report("Not in correct state. %x",sev_state->state);
-       return 1;
+        error_report("Not in correct state. %x",sev_state->state);
+        return 1;
     }
 
     hdr = g_base64_decode(packet_hdr, &hdr_sz);
@@ -792,6 +819,9 @@ int sev_inject_launch_secret(const char *packet_hdr,
         goto err;
     }
 
+    if(sev_state->secret_gpa)
+        gpa = sev_state->secret_gpa;
+
     hva = gpa2hva(gpa, data_sz);
     if (!hva) {
         goto err;
diff --git a/target/i386/sev_i386.h b/target/i386/sev_i386.h
index 8ada9d385d..b1f9ab93bb 100644
--- a/target/i386/sev_i386.h
+++ b/target/i386/sev_i386.h
@@ -19,6 +19,7 @@
 #include "sysemu/kvm.h"
 #include "sysemu/sev.h"
 #include "qemu/error-report.h"
+#include "qemu/uuid.h"
 #include "qapi/qapi-types-misc-target.h"
 
 #define SEV_POLICY_NODBG        0x1
@@ -28,6 +29,8 @@
 #define SEV_POLICY_DOMAIN       0x10
 #define SEV_POLICY_SEV          0x20
 
+#define SEV_ROM_SECRET_GUID "adf956ad-e98c-484c-ae11-b51c7d336447"
+
 #define TYPE_QSEV_GUEST_INFO "sev-guest"
 #define QSEV_GUEST_INFO(obj)                  \
     OBJECT_CHECK(QSevGuestInfo, (obj), TYPE_QSEV_GUEST_INFO)
@@ -42,6 +45,18 @@ extern SevCapability *sev_get_capabilities(void);
 
 typedef struct QSevGuestInfo QSevGuestInfo;
 typedef struct QSevGuestInfoClass QSevGuestInfoClass;
+typedef struct SevROMSecretTable SevROMSecretTable;
+
+/**
+ * If guest physical address for the launch secret is
+ * provided in the ROM, it should be in the following
+ * page-aligned structure.
+ */
+struct SevROMSecretTable {
+    QemuUUID guid;
+    unsigned int base;
+    unsigned int size;
+};
 
 /**
  * QSevGuestInfo:
@@ -78,6 +93,7 @@ struct SEVState {
     uint32_t cbitpos;
     uint32_t reduced_phys_bits;
     uint32_t handle;
+    uint64_t secret_gpa;
     int sev_fd;
     SevState state;
     gchar *measurement;
-- 
2.20.1 (Apple Git-117)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]