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@xxxxxxxxxx> --- 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