[libvirt PATCH v2 03/12] qemu: add monitor APIs for query-sev

Daniel P. Berrangé berrange at redhat.com
Fri Dec 10 11:37:26 UTC 2021


We're only returning the set of fields needed to perform an
attestation, per the SEV API docs.

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 src/qemu/qemu_monitor.c      | 13 ++++++++++
 src/qemu/qemu_monitor.h      |  9 +++++++
 src/qemu/qemu_monitor_json.c | 46 ++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_monitor_json.h |  9 +++++++
 tests/qemumonitorjsontest.c  | 43 +++++++++++++++++++++++++++++++++
 5 files changed, 120 insertions(+)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 75e0e4ed92..dda6ae9796 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4366,6 +4366,19 @@ qemuMonitorGetSEVMeasurement(qemuMonitor *mon)
 }
 
 
+int
+qemuMonitorGetSEVInfo(qemuMonitor *mon,
+                      unsigned int *apiMajor,
+                      unsigned int *apiMinor,
+                      unsigned int *buildID,
+                      unsigned int *policy)
+{
+    QEMU_CHECK_MONITOR(mon);
+
+    return qemuMonitorJSONGetSEVInfo(mon, apiMajor, apiMinor, buildID, policy);
+}
+
+
 int
 qemuMonitorGetPRManagerInfo(qemuMonitor *mon,
                             GHashTable **retinfo)
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index edc2b01a66..29746f0b8e 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1445,6 +1445,15 @@ int qemuMonitorBlockdevMediumInsert(qemuMonitor *mon,
 char *
 qemuMonitorGetSEVMeasurement(qemuMonitor *mon);
 
+int
+qemuMonitorGetSEVInfo(qemuMonitor *mon,
+                      unsigned int *apiMajor,
+                      unsigned int *apiMinor,
+                      unsigned int *buildID,
+                      unsigned int *policy)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
+    ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5);
+
 typedef struct _qemuMonitorPRManagerInfo qemuMonitorPRManagerInfo;
 struct _qemuMonitorPRManagerInfo {
     bool connected;
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index e00d785c20..a3d6eca569 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -8216,6 +8216,52 @@ qemuMonitorJSONGetSEVMeasurement(qemuMonitor *mon)
 }
 
 
+/**
+ * Retrive info about the SEV setup, returning those fields that
+ * are required to do a launch attestation, as per
+ *
+ * HMAC(0x04 || API_MAJOR || API_MINOR || BUILD || GCTX.POLICY || GCTX.LD || MNONCE; GCTX.TIK)
+ *
+ * specified in section 6.5.1 of AMD Secure Encrypted
+ * Virtualization API.
+ *
+ *  { "execute": "query-sev" }
+ *  { "return": { "enabled": true, "api-major" : 0, "api-minor" : 0,
+ *                "build-id" : 0, "policy" : 0, "state" : "running",
+ *                "handle" : 1 } }
+ */
+int
+qemuMonitorJSONGetSEVInfo(qemuMonitor *mon,
+                          unsigned int *apiMajor,
+                          unsigned int *apiMinor,
+                          unsigned int *buildID,
+                          unsigned int *policy)
+{
+    g_autoptr(virJSONValue) cmd = NULL;
+    g_autoptr(virJSONValue) reply = NULL;
+    virJSONValue *data;
+
+    if (!(cmd = qemuMonitorJSONMakeCommand("query-sev", NULL)))
+        return -1;
+
+    if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+        return -1;
+
+    if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_OBJECT) < 0)
+        return -1;
+
+    data = virJSONValueObjectGetObject(reply, "return");
+
+    if (virJSONValueObjectGetNumberUint(data, "api-major", apiMajor) < 0 ||
+        virJSONValueObjectGetNumberUint(data, "api-minor", apiMinor) < 0 ||
+        virJSONValueObjectGetNumberUint(data, "build-id", buildID) < 0 ||
+        virJSONValueObjectGetNumberUint(data, "policy", policy) < 0)
+        return -1;
+
+    return 0;
+}
+
+
 /*
  * Example return data
  *
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 64064b0519..e88dfc9d50 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -459,6 +459,15 @@ qemuMonitorJSONSystemWakeup(qemuMonitor *mon);
 char *
 qemuMonitorJSONGetSEVMeasurement(qemuMonitor *mon);
 
+int
+qemuMonitorJSONGetSEVInfo(qemuMonitor *mon,
+                          unsigned int *apiMajor,
+                          unsigned int *apiMinor,
+                          unsigned int *buildID,
+                          unsigned int *policy)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
+    ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5);
+
 int
 qemuMonitorJSONGetVersion(qemuMonitor *mon,
                           int *major,
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index 1ad2912b08..1b0bd0870d 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -2884,6 +2884,48 @@ testQemuMonitorJSONqemuMonitorJSONGetCPUModelBaseline(const void *opaque)
 }
 
 
+static int
+testQemuMonitorJSONGetSEVInfo(const void *opaque)
+{
+    const testGenericData *data = opaque;
+    virDomainXMLOption *xmlopt = data->xmlopt;
+    g_autoptr(qemuMonitorTest) test = NULL;
+    unsigned int apiMajor = 0;
+    unsigned int apiMinor = 0;
+    unsigned int buildID = 0;
+    unsigned int policy = 0;
+
+    if (!(test = qemuMonitorTestNewSchema(xmlopt, data->schema)))
+        return -1;
+
+    if (qemuMonitorTestAddItem(test, "query-sev",
+                               "{"
+                               "    \"return\": {"
+                               "        \"enabled\": false,"
+                               "        \"api-minor\": 8,"
+                               "        \"handle\": 0,"
+                               "        \"state\": \"uninit\","
+                               "        \"api-major\": 1,"
+                               "        \"build-id\": 834,"
+                               "        \"policy\": 3"
+                               "    },"
+                               "    \"id\": \"libvirt-15\""
+                               "}") < 0)
+        return -1;
+
+    if (qemuMonitorGetSEVInfo(qemuMonitorTestGetMonitor(test),
+                              &apiMajor, &apiMinor, &buildID, &policy) < 0)
+        return -1;
+
+    if (apiMajor != 1 || apiMinor != 8 || buildID != 834 || policy != 3) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       "Unexpected SEV info values");
+        return -1;
+    }
+
+    return 0;
+}
+
 static int
 mymain(void)
 {
@@ -2979,6 +3021,7 @@ mymain(void)
     DO_TEST(CPU);
     DO_TEST(GetNonExistingCPUData);
     DO_TEST(GetIOThreads);
+    DO_TEST(GetSEVInfo);
     DO_TEST(Transaction);
     DO_TEST(BlockExportAdd);
     DO_TEST(BlockdevReopen);
-- 
2.33.1




More information about the libvir-list mailing list