The value returned by qemu's query-sev-launch-measure comes
straight from the LAUNCH_MEASURE SEV firmware command. It's two
values packed together: first 32 bytes is the launch measurement,
last 16 bytes is the nonce.
This combined value is really just an artifact of the return value
of the firmware command, it has no direct usage. Users want the two
individual values. But because qemu and libvirt do not separate them
apart, every app that wants to process this value will have to do
it manually.
This performs the split for the user, and delivers the values in two
new TYPED_PARAM fields: sev-measurement-value, sev-measurement-nonce
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
include/libvirt/libvirt-domain.h | 22 ++++++++++++++++++++++
src/qemu/qemu_driver.c | 23 +++++++++++++++++++++++
2 files changed, 45 insertions(+)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 8357aea797..55723ba150 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -6317,6 +6317,28 @@ int virDomainSetLifecycleAction(virDomainPtr domain,
*/
# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_SET_ADDRESS
"sev-secret-set-address"
+/**
+ * VIR_DOMAIN_LAUNCH_SECURITY_SEV_MEASUREMENT_VALUE:
+ *
+ * Macro represents the measurement value of the SEV guest,
+ * extracted from the compound VIR_DOMAIN_LAUNCH_SECURITY_SEV_MEASUREMENT value,
+ * as VIR_TYPED_PARAM_STRING.
+ *
+ * Since: 8.9.0
+ */
+# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_MEASUREMENT_VALUE
"sev-measurement-value"
+
+/**
+ * VIR_DOMAIN_LAUNCH_SECURITY_SEV_MEASUREMENT_NONCE:
+ *
+ * Macro represents the measurement nonce of the SEV guest,
+ * extracted from the compound VIR_DOMAIN_LAUNCH_SECURITY_SEV_MEASUREMENT value,
+ * as VIR_TYPED_PARAM_STRING.
+ *
+ * Since: 8.9.0
+ */
+# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_MEASUREMENT_NONCE
"sev-measurement-nonce"
+
int virDomainGetLaunchSecurityInfo(virDomainPtr domain,
virTypedParameterPtr *params,
int *nparams,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 40d23b5723..590e8f3fab 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19951,10 +19951,14 @@ qemuDomainGetSEVInfo(virDomainObj *vm,
int ret = -1;
int rv;
g_autofree char *tmp = NULL;
+ g_autofree char *measurement = NULL;
+ g_autofree char *measurement_val = NULL;
+ g_autofree char *nonce = NULL;
unsigned int apiMajor = 0;
unsigned int apiMinor = 0;
unsigned int buildID = 0;
unsigned int policy = 0;
+ size_t measurement_size = 0;
int maxpar = 0;
virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1);
@@ -19982,6 +19986,17 @@ qemuDomainGetSEVInfo(virDomainObj *vm,
if (rv < 0)
goto endjob;
+ measurement = (char *) g_base64_decode(tmp, &measurement_size);
+ if (measurement_size != 48) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected SEV measurement size %zu, expected 48"),
+ measurement_size);
+ goto endjob;
+ }
+
+ measurement_val = g_base64_encode((unsigned char *) measurement, 32);
+ nonce = g_base64_encode((unsigned char *) measurement + 32, 16);
+
if (virTypedParamsAddString(params, nparams, &maxpar,
VIR_DOMAIN_LAUNCH_SECURITY_SEV_MEASUREMENT,
tmp) < 0)
@@ -20002,6 +20017,14 @@ qemuDomainGetSEVInfo(virDomainObj *vm,
VIR_DOMAIN_LAUNCH_SECURITY_SEV_POLICY,
policy) < 0)
goto endjob;
+ if (virTypedParamsAddString(params, nparams, &maxpar,
+ VIR_DOMAIN_LAUNCH_SECURITY_SEV_MEASUREMENT_VALUE,
+ measurement_val) < 0)
+ goto endjob;
+ if (virTypedParamsAddString(params, nparams, &maxpar,
+ VIR_DOMAIN_LAUNCH_SECURITY_SEV_MEASUREMENT_NONCE,
+ nonce) < 0)
+ goto endjob;
ret = 0;
--
2.37.3