The launch-security element can be used to define the security model to use when launching a domain. When 'mktme' is used, the VM will be launched with Intel MKTME feature enabled. MKTME feature supports running encrypted guest. --- docs/formatdomain.html.in | 64 +++++++++++++++++-- docs/schemas/domaincommon.rng | 87 +++++++++++++++++--------- src/conf/domain_conf.c | 112 +++++++++++++++++++++++++++++++++- src/conf/domain_conf.h | 14 +++++ src/conf/virconftypes.h | 3 + 5 files changed, 242 insertions(+), 38 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index e1da878fcc..10d512ccd1 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -8924,13 +8924,16 @@ qemu-kvm -net nic,model=? /dev/null <p>Note: DEA/TDEA is synonymous with DES/TDES.</p> - <h3><a id="sev">Launch Security</a></h3> + <h3><a id="launchsecurity">Launch Security</a></h3> <p> - The contents of the <code><launchSecurity type='sev'></code> element - is used to provide the guest owners input used for creating an encrypted - VM using the AMD SEV feature (Secure Encrypted Virtualization). - + The contents of the <code>launchSecurity</code> element is used + to provide the guest owners input used for creating an encrypted + VM using the AMD SEV feature (Secure Encrypted Virtualization) + and Intel MKTME (Multi-Key Total Memory Encryption). + </p> + <h4><a id="sev">SEV</a></h4> + <p> SEV is an extension to the AMD-V architecture which supports running encrypted virtual machine (VMs) under the control of KVM. Encrypted VMs have their pages (code and data) secured such that only the guest @@ -8942,7 +8945,7 @@ qemu-kvm -net nic,model=? /dev/null For more information see various input parameters and its format see the <a href="https://support.amd.com/TechDocs/55766_SEV-KM_API_Specification.pdf">SEV API spec</a> <span class="since">Since 4.4.0</span> - </p> + </p> <pre> <domain> ... @@ -9039,6 +9042,55 @@ qemu-kvm -net nic,model=? /dev/null </dd> </dl> + <h4><a id="mktme">MKTME</a></h4> + <p> + Total Memory Encryption (TME) – provides the capability to encrypt the + entirety of the physical memory of a system. MKTME builds on TME and + adds support for multiple encryption keys. + + By default MKTME uses the TME encryption key unless explicitly specified + by software. In addition to supporting a CPU generated ephemeral + key (not accessible by software or by using external interfaces to an SOC), + MKTME also supports software provided keys. Software provided keys are + particularly useful when used with nonvolatile memory or when combined + with attestation mechanisms and/or used with key provisioning services. + + For more information see + <a href="https://software.intel.com/sites/default/files/managed/a5/16/Multi-Key-Total-Memory-Encryption-Spec.pdf">MKTME spec</a> + <span class="since">Since 5.3.0</span> + </p> +<pre> +<domain> + ... + <launchSecurity type='mktme'> + <id>mktme-0</id> + <key_type>samplekey</key_type> + <type>user</type> + <encryption_algorithm>aes-xts-128</encryption_algorithm> + </launchSecurity> + ... +</domain> +</pre> + <dl> + <dt><code>id</code></dt> + <dd>The required <code>id</code> element provides ability to map the key handle. + If the id exists, system returns the existing key handle which can be used to + encrpyt a different guest. + </dd> + <dt><code>key_type</code></dt> + <dd>MKTME supports user and cpu generated keys. The required <code>key_type</code> + element provides the type of key used for the encryption. + </dd> + <dt><code>key</code></dt> + <dd>The optional <code>key</code> element provides the key used for the encryption. + Required only when the key type is of user. + </dd> + <dt><code>encryption_algorithm</code></dt> + <dd>The required <code>encyption_algorithm</code> element provides the type of + encryption algorithm. Currently, MKTME supports aes-xts-128 only. + </dd> + </dl> + <h2><a id="examples">Example configs</a></h2> <p> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 111b85c36f..5e6847d64e 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -457,35 +457,64 @@ <define name="launchSecurity"> <element name="launchSecurity"> - <attribute name="type"> - <value>sev</value> - </attribute> - <interleave> - <element name="cbitpos"> - <data type='unsignedInt'/> - </element> - <element name="reducedPhysBits"> - <data type='unsignedInt'/> - </element> - <element name="policy"> - <ref name='hexuint'/> - </element> - <optional> - <element name="handle"> - <ref name='unsignedInt'/> - </element> - </optional> - <optional> - <element name="dhCert"> - <data type="string"/> - </element> - </optional> - <optional> - <element name="session"> - <data type="string"/> - </element> - </optional> - </interleave> + <choice> + <group> + <optional> + <attribute name="type"> + <value>sev</value> + </attribute> + </optional> + <interleave> + <element name="cbitpos"> + <data type='unsignedInt'/> + </element> + <element name="reducedPhysBits"> + <data type='unsignedInt'/> + </element> + <element name="policy"> + <ref name='hexuint'/> + </element> + <optional> + <element name="handle"> + <ref name='unsignedInt'/> + </element> + </optional> + <optional> + <element name="dhCert"> + <data type="string"/> + </element> + </optional> + <optional> + <element name="session"> + <data type="string"/> + </element> + </optional> + </interleave> + </group> + <group> + <optional> + <attribute name="type"> + <value>mktme</value> + </attribute> + </optional> + <interleave> + <element name="id"> + <data type="string"/> + </element> + <element name="key_type"> + <data type="string"/> + </element> + <element name="encryption_algorithm"> + <data type="string"/> + </element> + <optional> + <element name="key"> + <data type="string"/> + </element> + </optional> + </interleave> + </group> + </choice> </element> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a3a514136b..7420a3f00d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1233,6 +1233,7 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity, VIR_DOMAIN_LAUNCH_SECURITY_LAST, "", "sev", + "mktme", ); static virClassPtr virDomainObjClass; @@ -3282,6 +3283,21 @@ virDomainSEVDefFree(virDomainSEVDefPtr def) } +static void +virDomainMKTMEDefFree(virDomainMKTMEDefPtr def) +{ + if (!def) + return; + + VIR_FREE(def->id); + VIR_FREE(def->key_type); + VIR_FREE(def->key); + VIR_FREE(def->encryption_algorithm); + + VIR_FREE(def); +} + + void virDomainDefFree(virDomainDefPtr def) { size_t i; @@ -3466,6 +3482,7 @@ void virDomainDefFree(virDomainDefPtr def) (def->ns.free)(def->namespaceData); virDomainSEVDefFree(def->sev); + virDomainMKTMEDefFree(def->mktme); xmlFreeNode(def->metadata); @@ -15940,6 +15957,44 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node, } +static int +virDomainGetLaunchSecurityType(xmlNodePtr node) +{ + VIR_AUTOFREE(char *) type = NULL; + + if (!(type = virXMLPropString(node, "type"))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing launch security type")); + return -1; + } + + return virDomainLaunchSecurityTypeFromString(type); +} + + +static virDomainMKTMEDefPtr +virDomainMKTMEDefParseXML(xmlNodePtr mktmeNode, + xmlXPathContextPtr ctxt) +{ + VIR_XPATH_NODE_AUTORESTORE(ctxt); + virDomainMKTMEDefPtr def; + + if (VIR_ALLOC(def) < 0) + return NULL; + + ctxt->node = mktmeNode; + + def->sectype = VIR_DOMAIN_LAUNCH_SECURITY_MKTME; + + def->id = virXPathString("string(./id)", ctxt); + def->key_type = virXPathString("string(./key_type)", ctxt); + def->key = virXPathString("string(./key)", ctxt); + def->encryption_algorithm = virXPathString("string(./encryption_algorithm)", ctxt); + + return def; +} + + static virDomainSEVDefPtr virDomainSEVDefParseXML(xmlNodePtr sevNode, xmlXPathContextPtr ctxt) @@ -15965,6 +16020,7 @@ virDomainSEVDefParseXML(xmlNodePtr sevNode, case VIR_DOMAIN_LAUNCH_SECURITY_SEV: break; case VIR_DOMAIN_LAUNCH_SECURITY_NONE: + case VIR_DOMAIN_LAUNCH_SECURITY_MKTME: case VIR_DOMAIN_LAUNCH_SECURITY_LAST: default: virReportError(VIR_ERR_XML_ERROR, @@ -21127,11 +21183,33 @@ virDomainDefParseXML(xmlDocPtr xml, ctxt->node = node; VIR_FREE(nodes); - /* Check for SEV feature */ + /* Check for launch security (MKTME/SEV) feature */ if ((node = virXPathNode("./launchSecurity", ctxt)) != NULL) { - def->sev = virDomainSEVDefParseXML(node, ctxt); - if (!def->sev) + int sectype = virDomainGetLaunchSecurityType(node); + + if (sectype < 0) goto error; + + switch ((virDomainLaunchSecurity)sectype) { + case VIR_DOMAIN_LAUNCH_SECURITY_SEV: + /* Optimize virDomainSEVDefParseXML; since we are already checking for sectype*/ + def->sev = virDomainSEVDefParseXML(node, ctxt); + if (!def->sev) + goto error; + break; + case VIR_DOMAIN_LAUNCH_SECURITY_MKTME: + def->mktme = virDomainMKTMEDefParseXML(node, ctxt); + if (!def->mktme) + goto error; + break; + case VIR_DOMAIN_LAUNCH_SECURITY_NONE: + case VIR_DOMAIN_LAUNCH_SECURITY_LAST: + default: + virReportError(VIR_ERR_XML_ERROR, + _("unsupported launch security type '%s'"), + virXMLPropString(node, "type")); + goto error; + } } /* analysis of memory devices */ @@ -27268,6 +27346,33 @@ virDomainSEVDefFormat(virBufferPtr buf, virDomainSEVDefPtr sev) } +static void +virDomainMKTMEDefFormat(virBufferPtr buf, virDomainMKTMEDefPtr mktme) +{ + if (!mktme) + return; + + virBufferAsprintf(buf, "<launchSecurity type='%s'>\n", + virDomainLaunchSecurityTypeToString(mktme->sectype)); + virBufferAdjustIndent(buf, 2); + + if (mktme->id) + virBufferEscapeString(buf, "<id>%s</id>\n", mktme->id); + + if (mktme->key_type) + virBufferEscapeString(buf, "<key_type>%s</key_type>\n", mktme->key_type); + + if (mktme->key) + virBufferEscapeString(buf, "<key>%s</key>\n", mktme->key); + + if (mktme->encryption_algorithm) + virBufferEscapeString(buf, "<encryption_algorithm>%s</encryption_algorithm>\n", mktme->encryption_algorithm); + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</launchSecurity>\n"); +} + + static void virDomainPerfDefFormat(virBufferPtr buf, virDomainPerfDefPtr perf) { @@ -28640,6 +28745,7 @@ virDomainDefFormatInternal(virDomainDefPtr def, virDomainKeyWrapDefFormat(buf, def->keywrap); virDomainSEVDefFormat(buf, def->sev); + virDomainMKTMEDefFormat(buf, def->mktme); virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</domain>\n"); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index fa0756b634..b86d02376c 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2279,6 +2279,7 @@ struct _virDomainKeyWrapDef { typedef enum { VIR_DOMAIN_LAUNCH_SECURITY_NONE, VIR_DOMAIN_LAUNCH_SECURITY_SEV, + VIR_DOMAIN_LAUNCH_SECURITY_MKTME, VIR_DOMAIN_LAUNCH_SECURITY_LAST, } virDomainLaunchSecurity; @@ -2294,6 +2295,16 @@ struct _virDomainSEVDef { }; +struct _virDomainMKTMEDef { + int sectype; /* enum virDomainLaunchSecurity */ + char *id; + char *key_type; + char *key; + char *encryption_algorithm; + int key_handle; +}; + + typedef enum { VIR_DOMAIN_IOMMU_MODEL_INTEL, @@ -2491,6 +2502,9 @@ struct _virDomainDef { /* SEV-specific domain */ virDomainSEVDefPtr sev; + /* MKTME- domain info*/ + virDomainMKTMEDefPtr mktme; + /* Application-specific custom metadata */ xmlNodePtr metadata; diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h index 6a8267c422..c432e4493f 100644 --- a/src/conf/virconftypes.h +++ b/src/conf/virconftypes.h @@ -277,6 +277,9 @@ typedef virDomainResourceDef *virDomainResourceDefPtr; typedef struct _virDomainSEVDef virDomainSEVDef; typedef virDomainSEVDef *virDomainSEVDefPtr; +typedef struct _virDomainMKTMEDef virDomainMKTMEDef; +typedef virDomainMKTMEDef *virDomainMKTMEDefPtr; + typedef struct _virDomainShmemDef virDomainShmemDef; typedef virDomainShmemDef *virDomainShmemDefPtr; -- 2.21.0.windows.1
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list