]> xenbits.xensource.com Git - libvirt.git/commitdiff
libvirt: Introduce virDomainSetLaunchSecurityState public API
authorJim Fehlig <jfehlig@suse.com>
Tue, 9 Nov 2021 23:28:55 +0000 (16:28 -0700)
committerJim Fehlig <jfehlig@suse.com>
Tue, 4 Jan 2022 17:56:00 +0000 (10:56 -0700)
This API allows setting a launch secret within a guests's memory. The
launch secret is created by the guest owner after retrieving and
verifying the launch measurement with virDomainGetLaunchSecurityInfo.

The API uses virTypedParameter for input, allowing it to be expanded
to support other confidential computing technologies. In the case of
SEV, a basic guest launch workflow is described in the SEV API spec
in section "1.3.1 Launch"

https://www.amd.com/system/files/TechDocs/55766_SEV-KM_API_Specification.pdf

Signed-off-by: Jim Fehlig <jfehlig@suse.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
include/libvirt/libvirt-domain.h
src/driver-hypervisor.h
src/libvirt-domain.c
src/libvirt_public.syms

index 5d3e15766ee01616b6b45918b23e6c455ce0f6e1..5f0a9b7572f9bd982e6cc94106eddeaff659b6ed 100644 (file)
@@ -5102,6 +5102,7 @@ int virDomainSetLifecycleAction(virDomainPtr domain,
 # define VIR_DOMAIN_LAUNCH_SECURITY_SEV_MEASUREMENT "sev-measurement"
 
 /**
+
  * VIR_DOMAIN_LAUNCH_SECURITY_SEV_API_MAJOR:
  *
  * Macro represents the API major version of the SEV host,
@@ -5133,11 +5134,46 @@ int virDomainSetLifecycleAction(virDomainPtr domain,
  */
 # define VIR_DOMAIN_LAUNCH_SECURITY_SEV_POLICY "sev-policy"
 
+/**
+ * VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_HEADER:
+ *
+ * A macro used to represent the SEV launch secret header. The secret header
+ * is a base64-encoded VIR_TYPED_PARAM_STRING containing artifacts needed by
+ * the SEV firmware to recover the plain text of the launch secret. See
+ * section "6.6 LAUNCH_SECRET" in the SEV API specification for a detailed
+ * description of the secret header.
+ */
+# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_HEADER "sev-secret-header"
+
+/**
+ * VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET:
+ *
+ * A macro used to represent the SEV launch secret. The secret is a
+ * base64-encoded VIR_TYPED_PARAM_STRING containing an encrypted launch
+ * secret. The secret is created by the domain owner after the SEV launch
+ * measurement is retrieved and verified.
+ */
+# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET "sev-secret"
+
+/**
+ * VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_SET_ADDRESS:
+ *
+ * A macro used to represent the physical address within the guest's memory
+ * where the secret will be set, as VIR_TYPED_PARAM_ULLONG. If not specified,
+ * the address will be determined by the hypervisor.
+ */
+# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_SET_ADDRESS "sev-secret-set-address"
+
 int virDomainGetLaunchSecurityInfo(virDomainPtr domain,
                                    virTypedParameterPtr *params,
                                    int *nparams,
                                    unsigned int flags);
 
+int virDomainSetLaunchSecurityState(virDomainPtr domain,
+                                    virTypedParameterPtr params,
+                                    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 */
index d642af8a378c19595fdf2bda0f9e16e25e4748f9..c83fb648a242acdc002de6f5cd9364041d105c52 100644 (file)
@@ -1333,6 +1333,12 @@ typedef int
                                         int *nparams,
                                         unsigned int flags);
 
+typedef int
+(*virDrvDomainSetLaunchSecurityState)(virDomainPtr domain,
+                                      virTypedParameterPtr params,
+                                      int nparams,
+                                      unsigned int flags);
+
 typedef virDomainCheckpointPtr
 (*virDrvDomainCheckpointCreateXML)(virDomainPtr domain,
                                    const char *xmlDesc,
@@ -1661,6 +1667,7 @@ struct _virHypervisorDriver {
     virDrvConnectBaselineHypervisorCPU connectBaselineHypervisorCPU;
     virDrvNodeGetSEVInfo nodeGetSEVInfo;
     virDrvDomainGetLaunchSecurityInfo domainGetLaunchSecurityInfo;
+    virDrvDomainSetLaunchSecurityState domainSetLaunchSecurityState;
     virDrvDomainCheckpointCreateXML domainCheckpointCreateXML;
     virDrvDomainCheckpointGetXMLDesc domainCheckpointGetXMLDesc;
     virDrvDomainListAllCheckpoints domainListAllCheckpoints;
index c36874f91e136da36da1952545e04dae16eda861..5912551a49aaf9ccdd4bedee4a93744ac03ce32b 100644 (file)
@@ -12851,6 +12851,68 @@ int virDomainGetLaunchSecurityInfo(virDomainPtr domain,
 }
 
 
+/**
+ * virDomainSetLaunchSecurityState:
+ * @domain: a domain object
+ * @params: pointer to launch security parameter objects
+ * @nparams: number of launch security parameters
+ * @flags: currently used, set to 0.
+ *
+ * Set a launch security secret in the guest's memory. The guest must be
+ * in a paused state, e.g. in state VIR_DOMIAN_PAUSED as reported by
+ * virDomainGetState. On success, the guest can be transitioned to a
+ * running state. On failure, the guest should be destroyed.
+ *
+ * A basic guest attestation process can be achieved by:
+ * - Start a secure guest in the paused state by passing VIR_DOMAIN_START_PAUSED
+ *   to one of the virDomainCreate APIs
+ * - Retrieve the guest launch measurement with virDomainGetLaunchSecurityInfo
+ * - Verify launch measurement and generate a secret for the guest
+ * - Set the secret in the guest's memory with virDomainSetLaunchSecurityState
+ * - Start running the guest with virDomainResume
+ *
+ * See VIR_DOMAIN_LAUNCH_SECURITY_* for a detailed description of accepted
+ * launch security parameters.
+ *
+ * Returns -1 in case of failure, 0 in case of success.
+ */
+int virDomainSetLaunchSecurityState(virDomainPtr domain,
+                                    virTypedParameterPtr params,
+                                    int nparams,
+                                    unsigned int flags)
+{
+    virConnectPtr 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);
+
+    if (virTypedParameterValidateSet(conn, params, nparams) < 0)
+        goto error;
+
+    if (conn->driver->domainSetLaunchSecurityState) {
+        int ret;
+        ret = conn->driver->domainSetLaunchSecurityState(domain, params,
+                                                         nparams, flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+    virReportUnsupportedError();
+
+ error:
+    virDispatchError(domain->conn);
+    return -1;
+}
+
+
 /**
  * virDomainAgentSetResponseTimeout:
  * @domain: a domain object
index 788a967df78f58b6ef899c1e8ee56aa2639d847c..f93692c427db6fba771079f85599863c2f94ee5f 100644 (file)
@@ -911,4 +911,9 @@ LIBVIRT_7.8.0 {
         virNetworkCreateXMLFlags;
 } LIBVIRT_7.7.0;
 
+LIBVIRT_8.0.0 {
+    global:
+        virDomainSetLaunchSecurityState;
+} LIBVIRT_7.8.0;
+
 # .... define new API here using predicted next version number ....