This API allows getting an attestation report from a SEV-enabled guest.
The API uses virTypedParameter for input. The details of an attestation
report buffer are described in the SEV API spec in section
"6.8.2 Parameters, Table 60".
https://www.amd.com/system/files/TechDocs/55766_SEV-KM_API_Specification.pdf
Signed-off-by: Tyler Fanelli <tfanelli(a)redhat.com>
---
include/libvirt/libvirt-domain.h | 14 +++++++
src/driver-hypervisor.h | 7 ++++
src/libvirt-domain.c | 63 ++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 4 ++
4 files changed, 88 insertions(+)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 2d5718301e..af8991dbd3 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -5166,6 +5166,15 @@ int virDomainSetLifecycleAction(virDomainPtr domain,
*/
# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_SET_ADDRESS
"sev-secret-set-address"
+/**
+ * VIR_DOMAIN_SEV_ATTESTATION_REPORT_MNONCE:
+ *
+ * A macro used to represent a random 16 bytes value encoded in base64
+ * that will be included in a SEV attestation report, as
+ * VIR_TYPED_PARAM_STRING.
+ */
+# define VIR_DOMAIN_SEV_ATTESTATION_REPORT_MNONCE "mnonce"
+
int virDomainGetLaunchSecurityInfo(virDomainPtr domain,
virTypedParameterPtr *params,
int *nparams,
@@ -5176,6 +5185,11 @@ int virDomainSetLaunchSecurityState(virDomainPtr domain,
int nparams,
unsigned int flags);
+int virDomainGetSevAttestationReport(virDomainPtr domain,
+ virTypedParameterPtr *params_ptr,
+ int *nparams,
+ unsigned int flags);
+
typedef enum {
VIR_DOMAIN_GUEST_INFO_USERS = (1 << 0), /* return active users */
VIR_DOMAIN_GUEST_INFO_OS = (1 << 1), /* return OS information */
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index 4423eb0885..568d8c9a26 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -1348,6 +1348,12 @@ typedef int
int nparams,
unsigned int flags);
+typedef int
+(*virDrvDomainGetSevAttestationReport)(virDomainPtr domain,
+ virTypedParameterPtr params,
+ int nparams,
+ unsigned int flags);
+
typedef virDomainCheckpointPtr
(*virDrvDomainCheckpointCreateXML)(virDomainPtr domain,
const char *xmlDesc,
@@ -1678,6 +1684,7 @@ struct _virHypervisorDriver {
virDrvNodeGetSEVInfo nodeGetSEVInfo;
virDrvDomainGetLaunchSecurityInfo domainGetLaunchSecurityInfo;
virDrvDomainSetLaunchSecurityState domainSetLaunchSecurityState;
+ virDrvDomainGetSevAttestationReport domainGetSevAttestationReport;
virDrvDomainCheckpointCreateXML domainCheckpointCreateXML;
virDrvDomainCheckpointGetXMLDesc domainCheckpointGetXMLDesc;
virDrvDomainListAllCheckpoints domainListAllCheckpoints;
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index a197618673..ebcba4a8b7 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -12957,6 +12957,69 @@ int virDomainSetLaunchSecurityState(virDomainPtr domain,
return -1;
}
+/**
+ * virDomainGetSevAttestationReport:
+ * @domain: a domain object
+ * @params_ptr: pointer to launch security parameter objects
+ * @nparams: pointer to number of launch security parameters
+ * @flags: currently used, set to 0
+ *
+ * Get an attestation report from a SEV-enabled guest. On success, the guest
+ * attestation report can be obtained and the guest can be started.
+ *
+ * There is one parameter for receiving an attestation report, mnonce, which is
+ * a random 16-byte string to be included in the attestation report.
+ *
+ * Returns -1 in case of failure, 0 in case of success.
+ */
+int virDomainGetSevAttestationReport(virDomainPtr domain,
+ virTypedParameterPtr *params_ptr,
+ int *nparams,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+ virTypedParameterPtr params;
+ int rc;
+
+ params = *params_ptr;
+ conn = domain->conn;
+
+ VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d, flags=0x%x",
+ params, *nparams, flags);
+ VIR_TYPED_PARAMS_DEBUG(params, *nparams);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ virCheckNonNullArgGoto(params, error);
+ virCheckPositiveArgGoto(*nparams, error);
+ virCheckReadOnlyGoto(domain->conn->flags, error);
+
+ rc = VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
+ VIR_DRV_FEATURE_TYPED_PARAM_STRING);
+
+ if (rc < 0)
+ goto error;
+ if (rc)
+ flags |= VIR_TYPED_PARAM_STRING_OKAY;
+
+ if (virTypedParameterValidateSet(conn, params, *nparams) < 0)
+ goto error;
+
+ if (conn->driver->domainGetSevAttestationReport) {
+ int ret;
+ ret = conn->driver->domainGetSevAttestationReport(domain, params_ptr,
+ nparams, flags);
+ if (ret < 0)
+ goto error;
+
+ return ret;
+ }
+
+error:
+ virDispatchError(domain->conn);
+ return -1;
+}
/**
* virDomainAgentSetResponseTimeout:
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index f93692c427..f0cd5e7e55 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -916,4 +916,8 @@ LIBVIRT_8.0.0 {
virDomainSetLaunchSecurityState;
} LIBVIRT_7.8.0;
+LIBVIRT_8.2.0 {
+ global:
+ virDomainGetSevAttestationReport;
+} LIBVIRT_8.0.0;
# .... define new API here using predicted next version number ....
--
2.34.1