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_Specificatio...
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/M...
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