From: Alison Schofield <alison.schofield@intel.com>
To: dhowells@redhat.com, tglx@linutronix.de
Cc: jmorris@namei.org, mingo@redhat.com, hpa@zytor.com, bp@alien8.de,
luto@kernel.org, peterz@infradead.org,
kirill.shutemov@linux.intel.com, dave.hansen@intel.com,
kai.huang@intel.com, jun.nakajima@intel.com,
dan.j.williams@intel.com, jarkko.sakkinen@intel.com,
keyrings@vger.kernel.org, linux-security-module@vger.kernel.org,
linux-mm@kvack.org, x86@kernel.org
Subject: [RFC v2 01/13] x86/mktme: Document the MKTME APIs
Date: Mon, 3 Dec 2018 23:39:48 -0800 [thread overview]
Message-ID: <c2276bbbb19f3a28bd37c3dd6b1021e2d9a10916.1543903910.git.alison.schofield@intel.com> (raw)
In-Reply-To: <cover.1543903910.git.alison.schofield@intel.com>
In-Reply-To: <cover.1543903910.git.alison.schofield@intel.com>
This includes an overview, a section on each API: MTKME Keys and
system call encrypt_mprotect(), and a demonstration program.
(Some of this info is destined for man pages.)
Change-Id: I34dc9ff1a1308c057ec4bb3e652c4d7ce6995606
Signed-off-by: Alison Schofield <alison.schofield@intel.com>
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
---
Documentation/x86/mktme/index.rst | 11 +++
Documentation/x86/mktme/mktme_demo.rst | 53 ++++++++++++++
Documentation/x86/mktme/mktme_encrypt.rst | 58 +++++++++++++++
Documentation/x86/mktme/mktme_keys.rst | 109 +++++++++++++++++++++++++++++
Documentation/x86/mktme/mktme_overview.rst | 60 ++++++++++++++++
5 files changed, 291 insertions(+)
create mode 100644 Documentation/x86/mktme/index.rst
create mode 100644 Documentation/x86/mktme/mktme_demo.rst
create mode 100644 Documentation/x86/mktme/mktme_encrypt.rst
create mode 100644 Documentation/x86/mktme/mktme_keys.rst
create mode 100644 Documentation/x86/mktme/mktme_overview.rst
diff --git a/Documentation/x86/mktme/index.rst b/Documentation/x86/mktme/index.rst
new file mode 100644
index 000000000000..8c556d04cbc4
--- /dev/null
+++ b/Documentation/x86/mktme/index.rst
@@ -0,0 +1,11 @@
+
+=============================================
+Multi-Key Total Memory Encryption (MKTME) API
+=============================================
+
+.. toctree::
+
+ mktme_overview
+ mktme_keys
+ mktme_encrypt
+ mktme_demo
diff --git a/Documentation/x86/mktme/mktme_demo.rst b/Documentation/x86/mktme/mktme_demo.rst
new file mode 100644
index 000000000000..afd50772e65d
--- /dev/null
+++ b/Documentation/x86/mktme/mktme_demo.rst
@@ -0,0 +1,53 @@
+Demonstration Program using MKTME API's
+=======================================
+
+/* Compile with the keyutils library: cc -o mdemo mdemo.c -lkeyutils */
+
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <keyutils.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#define PAGE_SIZE sysconf(_SC_PAGE_SIZE)
+#define sys_encrypt_mprotect 335
+
+void main(void)
+{
+ char *options_CPU = "algorithm=aes-xts-128 type=cpu";
+ long size = PAGE_SIZE;
+ key_serial_t key;
+ void *ptra;
+ int ret;
+
+ /* Allocate an MKTME Key */
+ key = add_key("mktme", "testkey", options_CPU, strlen(options_CPU),
+ KEY_SPEC_THREAD_KEYRING);
+
+ if (key == -1) {
+ printf("addkey FAILED\n");
+ return;
+ }
+ /* Map a page of ANONYMOUS memory */
+ ptra = mmap(NULL, size, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+ if (!ptra) {
+ printf("failed to mmap");
+ goto inval_key;
+ }
+ /* Encrypt that page of memory with the MKTME Key */
+ ret = syscall(sys_encrypt_mprotect, ptra, size, PROT_NONE, key);
+ if (ret)
+ printf("mprotect error [%d]\n", ret);
+
+ /* Enjoy that page of encrypted memory */
+
+ /* Free the memory */
+ ret = munmap(ptra, size);
+
+inval_key:
+ /* Free the Key */
+ if (keyctl(KEYCTL_INVALIDATE, key) == -1)
+ printf("invalidate failed on key [%d]\n", key);
+}
diff --git a/Documentation/x86/mktme/mktme_encrypt.rst b/Documentation/x86/mktme/mktme_encrypt.rst
new file mode 100644
index 000000000000..ede5237183fc
--- /dev/null
+++ b/Documentation/x86/mktme/mktme_encrypt.rst
@@ -0,0 +1,58 @@
+MKTME API: system call encrypt_mprotect()
+=========================================
+
+Synopsis
+--------
+int encrypt_mprotect(void \*addr, size_t len, int prot, key_serial_t serial);
+
+Where *key_serial_t serial* is the serial number of a key allocated
+using the MKTME Key Service.
+
+Description
+-----------
+ encrypt_mprotect() encrypts the memory pages containing any part
+ of the address range in the interval specified by addr and len.
+
+ encrypt_mprotect() supports the legacy mprotect() behavior plus
+ the enabling of memory encryption. That means that in addition
+ to encrypting the memory, the protection flags will be updated
+ as requested in the call.
+
+ The *addr* and *len* must be aligned to a page boundary.
+
+ The caller must have *KEY_NEED_VIEW* permission on the key.
+
+ The range of memory that is to be protected must be mapped as
+ *ANONYMOUS*.
+
+Errors
+------
+ In addition to the Errors returned from legacy mprotect()
+ encrypt_mprotect will return:
+
+ ENOKEY *serial* parameter does not represent a valid key.
+
+ EINVAL *len* parameter is not page aligned.
+
+ EACCES Caller does not have *KEY_NEED_VIEW* permission on the key.
+
+EXAMPLE
+--------
+ Allocate an MKTME Key::
+ serial = add_key("mktme", "name", "type=cpu algorithm=aes-xts-128" @u
+
+ Map ANONYMOUS memory::
+ ptr = mmap(NULL, size, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+
+ Protect memory::
+ ret = syscall(SYS_encrypt_mprotect, ptr, size, PROT_READ|PROT_WRITE,
+ serial);
+
+ Use the encrypted memory
+
+ Free memory::
+ ret = munmap(ptr, size);
+
+ Free the key resource::
+ ret = keyctl(KEYCTL_INVALIDATE, serial);
+
diff --git a/Documentation/x86/mktme/mktme_keys.rst b/Documentation/x86/mktme/mktme_keys.rst
new file mode 100644
index 000000000000..5837909b2c54
--- /dev/null
+++ b/Documentation/x86/mktme/mktme_keys.rst
@@ -0,0 +1,109 @@
+MKTME Key Service API
+=====================
+MKTME is a new key service type added to the Linux Kernel Key Service.
+
+The MKTME Key Service type is available when CONFIG_X86_INTEL_MKTME is
+turned on in Intel platforms that support the MKTME feature.
+
+The MKTME Key Service type manages the allocation of hardware encryption
+keys. Users can request an MKTME type key and then use that key to
+encrypt memory with the encrypt_mprotect() system call.
+
+Usage
+-----
+ When using the Kernel Key Service to request an *mktme* key,
+ specify the *payload* as follows:
+
+ type=
+ *user* User will supply the encryption key data. Use this
+ type to directly program a hardware encryption key.
+
+ *cpu* User requests a CPU generated encryption key.
+ The CPU generates and assigns an ephemeral key.
+
+ *clear* User requests that a hardware encryption key be
+ cleared. This will clear the encryption key from
+ the hardware. On execution this hardware key gets
+ TME behavior.
+
+ *no-encrypt*
+ User requests that hardware does not encrypt
+ memory when this key is in use.
+
+ algorithm=
+ When type=user or type=cpu the algorithm field must be
+ *aes-xts-128*
+
+ When type=clear or type=no-encrypt the algorithm field
+ must not be present in the payload.
+
+ key=
+ When type=user the user must supply a 128 bit encryption
+ key as exactly 32 ASCII hexadecimal characters.
+
+ When type=cpu the user may optionally supply 128 bits of
+ entropy for the CPU generated encryption key in this field.
+ It must be exactly 32 ASCII hexadecimal characters.
+
+ When type=clear or type=no-encrypt this key field must
+ not be present in the payload.
+
+ tweak=
+ When type=user the user must supply a 128 bit tweak key
+ as exactly 32 ASCII hexadecimal characters.
+
+ When type=cpu the user may optionally supply 128 bits of
+ entropy for the CPU generated tweak key in this field. It
+ must be exactly 32 ASCII hexadecimal characters.
+
+ When type=clear or type=no-encrypt the tweak field must
+ not be present in the payload.
+
+ERRORS
+------
+ In addition to the Errors returned from the Kernel Key Service,
+ add_key(2) or keyctl(1) commands, the MKTME Key Service type may
+ return the following errors:
+
+ EINVAL for any payload specification that does not match the
+ MKTME type payload as defined above.
+ EACCES for access denied. MKTME key type uses capabilities to
+ restrict the allocation of keys. CAP_SYS_RESOURCE is
+ required, but it will accept the broader capability of
+ CAP_SYS_ADMIN. See capabilities(7).
+
+ ENOKEY if a hardware key cannot be allocated. Additional error
+ messages will describe the hardware programming errors.
+
+EXAMPLES
+--------
+ Add a 'user' type key::
+
+ char \*options_USER = "type=user
+ algorithm=aes-xts-128
+ key=12345678912345671234567891234567
+ tweak=12345678912345671234567891234567";
+
+ key = add_key("mktme", "name", options_USER, strlen(options_USER),
+ KEY_SPEC_THREAD_KEYRING);
+
+ Add a 'cpu' type key::
+
+ char \*options_USER = "type=cpu algorithm=aes-xts-128";
+
+ key = add_key("mktme", "name", options_CPU, strlen(options_CPU),
+ KEY_SPEC_THREAD_KEYRING);
+
+ Update a key to 'Clear' type::
+
+ Note: This has the effect of clearing out the previously programmed
+ encryption data in the hardware. Use this to clear the hardware slot
+ prior to invalidating the key.
+
+ ret = keyctl(KEYCTL_UPDATE, key, "type=clear", strlen(options_CLEAR);
+
+ Add a "no-encrypt' type key::
+
+ key = add_key("mktme", "name", "no-encrypt", strlen(options_CPU),
+ KEY_SPEC_THREAD_KEYRING);
+
diff --git a/Documentation/x86/mktme/mktme_overview.rst b/Documentation/x86/mktme/mktme_overview.rst
new file mode 100644
index 000000000000..cc2c4a8320e7
--- /dev/null
+++ b/Documentation/x86/mktme/mktme_overview.rst
@@ -0,0 +1,60 @@
+Overview
+========
+MKTME (Multi-Key Total Memory Encryption) is a technology that allows
+memory encryption on Intel platforms. The main use case for the feature
+is virtual machine isolation. The API should apply to a wide range of
+use cases.
+
+Find the Intel Architecture Specification for MKTME here:
+https://software.intel.com/sites/default/files/managed/a5/16/Multi-Key-Total-Memory-Encryption-Spec.pdf
+
+The Encryption Process
+----------------------
+Userspace will see MKTME encryption as a Step Process.
+
+Step 1: Use the MKTME Key Service API to allocate an encryption key.
+
+Step 2: Use the encrypt_mprotect() system call to protect memory
+ with the encryption key obtained in Step 1.
+
+Definitions
+-----------
+Keys: References to Keys in this document are to Userspace Keys.
+ These keys are requested by users and jointly managed by the
+ MKTME Key Service Type, and more broadly by the Kernel Key
+ Service of which MKTME is a part.
+
+ This document does not intend to document KKS, but only the
+ MKTME type of the KKS. The options of the KKS can be grouped
+ into 2 classes for purposes of understanding how MKTME operates
+ within the broader KKS.
+
+KeyIDs: References to KeyIDs in this document are to the hardware KeyID
+ slots that are available on Intel Platforms. A KeyID is a
+ numerical index into a software programmable slot in the Intel
+ hardware. Refer to the Intel specification linked above for
+ details on the implementation of MKTME in Intel platforms.
+
+Key<-->KeyID Mapping:
+ The MKTME Key Service maintains a mapping between Keys and KeyIDS.
+ This mapping is known only to the kernel. Userspace does not need
+ to know which hardware KeyID slot it's Userspace Key has been
+ assigned.
+
+Configuration
+-------------
+
+CONFIG_X86_INTEL_MKTME
+ MKTME is enabled by selecting CONFIG_X86_INTEL_MKTME on Intel
+ platforms supporting the MKTME feature.
+
+mktme_savekeys
+ mktme_savekeys is a kernel cmdline parameter.
+
+ This parameter allows the kernel to save the user specified
+ MKTME key payload. Saving this payload means that the MKTME
+ Key Service can always allow the addition of new physical
+ packages. If the mktme_savekeys parameter is not present,
+ users key data will not be saved, and new physical packages
+ may only be added to the system if no user type MKTME keys
+ are in use.
--
2.14.1
next prev parent reply other threads:[~2018-12-04 7:37 UTC|newest]
Thread overview: 91+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-04 7:39 [RFC v2 00/13] Multi-Key Total Memory Encryption API (MKTME) Alison Schofield
2018-12-04 7:39 ` Alison Schofield [this message]
2018-12-05 18:11 ` [RFC v2 01/13] x86/mktme: Document the MKTME APIs Andy Lutomirski
2018-12-05 19:22 ` Alison Schofield
2018-12-05 23:35 ` Andy Lutomirski
2018-12-06 8:04 ` Sakkinen, Jarkko
2018-12-04 7:39 ` [RFC v2 02/13] mm: Generalize the mprotect implementation to support extensions Alison Schofield
2018-12-06 8:08 ` Sakkinen, Jarkko
2018-12-04 7:39 ` [RFC v2 03/13] syscall/x86: Wire up a new system call for memory encryption keys Alison Schofield
2018-12-04 7:39 ` [RFC v2 04/13] x86/mm: Add helper functions for MKTME " Alison Schofield
2018-12-04 9:14 ` Peter Zijlstra
2018-12-05 5:49 ` Alison Schofield
2018-12-04 15:35 ` Andy Lutomirski
2018-12-05 5:52 ` Alison Schofield
2018-12-06 8:31 ` Sakkinen, Jarkko
2018-12-04 7:39 ` [RFC v2 05/13] x86/mm: Set KeyIDs in encrypted VMAs Alison Schofield
2018-12-06 8:37 ` Sakkinen, Jarkko
2018-12-04 7:39 ` [RFC v2 06/13] mm: Add the encrypt_mprotect() system call Alison Schofield
2018-12-06 8:38 ` Sakkinen, Jarkko
2018-12-04 7:39 ` [RFC v2 07/13] x86/mm: Add helpers for reference counting encrypted VMAs Alison Schofield
2018-12-04 8:58 ` Peter Zijlstra
2018-12-05 5:28 ` Alison Schofield
2018-12-04 7:39 ` [RFC v2 08/13] mm: Use reference counting for " Alison Schofield
2018-12-04 7:39 ` [RFC v2 09/13] mm: Restrict memory encryption to anonymous VMA's Alison Schofield
2018-12-04 9:10 ` Peter Zijlstra
2018-12-05 5:30 ` Alison Schofield
2018-12-05 9:07 ` Peter Zijlstra
2018-12-04 7:39 ` [RFC v2 10/13] keys/mktme: Add the MKTME Key Service type for memory encryption Alison Schofield
2018-12-06 8:51 ` Sakkinen, Jarkko
2018-12-06 8:54 ` Sakkinen, Jarkko
2018-12-06 15:11 ` Dave Hansen
2018-12-06 22:56 ` Sakkinen, Jarkko
2018-12-04 7:39 ` [RFC v2 11/13] keys/mktme: Program memory encryption keys on a system wide basis Alison Schofield
2018-12-04 9:21 ` Peter Zijlstra
2018-12-04 9:50 ` Kirill A. Shutemov
2018-12-05 5:44 ` Alison Schofield
2018-12-05 5:43 ` Alison Schofield
2018-12-05 9:10 ` Peter Zijlstra
2018-12-05 17:26 ` Alison Schofield
2018-12-04 7:39 ` [RFC v2 12/13] keys/mktme: Save MKTME data if kernel cmdline parameter allows Alison Schofield
2018-12-04 9:22 ` Peter Zijlstra
2018-12-07 2:14 ` Huang, Kai
2018-12-07 3:42 ` Alison Schofield
2018-12-07 6:39 ` Jarkko Sakkinen
2018-12-07 6:45 ` Jarkko Sakkinen
2018-12-07 11:47 ` Kirill A. Shutemov
2018-12-04 7:40 ` [RFC v2 13/13] keys/mktme: Support CPU Hotplug for MKTME keys Alison Schofield
2018-12-04 9:28 ` Peter Zijlstra
2018-12-05 5:32 ` Alison Schofield
2018-12-04 9:31 ` Peter Zijlstra
2018-12-05 5:36 ` Alison Schofield
2018-12-04 9:25 ` [RFC v2 00/13] Multi-Key Total Memory Encryption API (MKTME) Peter Zijlstra
2018-12-04 9:46 ` Kirill A. Shutemov
2018-12-05 20:32 ` Sakkinen, Jarkko
2018-12-06 11:22 ` Kirill A. Shutemov
2018-12-06 14:59 ` Dave Hansen
2018-12-07 10:12 ` Huang, Kai
2018-12-06 21:23 ` Sakkinen, Jarkko
2018-12-07 11:54 ` Kirill A. Shutemov
2018-12-04 19:19 ` Andy Lutomirski
2018-12-04 20:00 ` Andy Lutomirski
2018-12-04 20:32 ` Dave Hansen
2018-12-05 22:19 ` Sakkinen, Jarkko
2018-12-07 2:05 ` Huang, Kai
2018-12-07 6:48 ` Jarkko Sakkinen
2018-12-07 11:57 ` Kirill A. Shutemov
2018-12-07 21:59 ` Sakkinen, Jarkko
2018-12-07 23:45 ` Sakkinen, Jarkko
2018-12-07 23:48 ` Andy Lutomirski
2018-12-08 1:33 ` Huang, Kai
2018-12-08 3:53 ` Sakkinen, Jarkko
2018-12-12 15:31 ` Sakkinen, Jarkko
2018-12-12 16:29 ` Andy Lutomirski
2018-12-12 16:43 ` Sakkinen, Jarkko
2018-12-12 23:27 ` Huang, Kai
2018-12-13 5:49 ` Sakkinen, Jarkko
2018-12-13 5:52 ` Sakkinen, Jarkko
2018-12-12 23:24 ` Huang, Kai
2018-12-07 23:35 ` Eric Rannaud
2018-12-05 23:49 ` Dave Hansen
2018-12-06 1:09 ` Andy Lutomirski
2018-12-06 1:25 ` Dan Williams
2018-12-06 15:39 ` Dave Hansen
2018-12-06 19:10 ` Andy Lutomirski
2018-12-06 19:31 ` Dave Hansen
2018-12-07 1:55 ` Huang, Kai
2018-12-07 4:23 ` Dave Hansen
2018-12-07 23:53 ` Andy Lutomirski
2018-12-08 1:11 ` Dave Hansen
2018-12-08 2:07 ` Huang, Kai
2018-12-05 20:30 ` Sakkinen, Jarkko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c2276bbbb19f3a28bd37c3dd6b1021e2d9a10916.1543903910.git.alison.schofield@intel.com \
--to=alison.schofield@intel.com \
--cc=bp@alien8.de \
--cc=dan.j.williams@intel.com \
--cc=dave.hansen@intel.com \
--cc=dhowells@redhat.com \
--cc=hpa@zytor.com \
--cc=jarkko.sakkinen@intel.com \
--cc=jmorris@namei.org \
--cc=jun.nakajima@intel.com \
--cc=kai.huang@intel.com \
--cc=keyrings@vger.kernel.org \
--cc=kirill.shutemov@linux.intel.com \
--cc=linux-mm@kvack.org \
--cc=linux-security-module@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox