From patchwork Tue Dec 4 07:39:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alison Schofield X-Patchwork-Id: 10711227 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 285F616B1 for ; Tue, 4 Dec 2018 07:37:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 16B062A46B for ; Tue, 4 Dec 2018 07:37:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0A5532A544; Tue, 4 Dec 2018 07:37:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 256572A46B for ; Tue, 4 Dec 2018 07:37:40 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id A1F816B6D89; Tue, 4 Dec 2018 02:37:27 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 6E8246B6D8D; Tue, 4 Dec 2018 02:37:27 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 31B036B6D89; Tue, 4 Dec 2018 02:37:27 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.197]) by kanga.kvack.org (Postfix) with ESMTP id 927836B6D93 for ; Tue, 4 Dec 2018 02:37:26 -0500 (EST) Received: by mail-pl1-f197.google.com with SMTP id j8so2280482plb.1 for ; Mon, 03 Dec 2018 23:37:26 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to:cc :subject:date:message-id:in-reply-to:references:in-reply-to :references; bh=4WHf7+SFm92EbbrOxdFTgt5fziQZ/f7v5fSnDI5i9h4=; b=rb5++9H8vafpSvwFaShYW4QlpJ5aaFedfQFlbwAqrM4p0KYIZXEvvfbLubaZBC5lla ESTjr9//bmhqXcpKru7lj6EvhzSyBAscpB+mw4SSRQHGaic32l4g3xdJ0Fp1KatR6GEU VMj3bigDAMQm4Kn9zE0cXqMo35KwE33x8dae76xkhVhz9kyR17IwP+41ImUpI9Puxi5Y QF5YnVABEHdWSWABX9ggAj4FwopFzv9OGPlUjF9WOjtHb6nDDjQgyxcbSm9REar4Fk6l YxGaGaSeB6QElFl9V7VnseyCcg2s4RwZVAy7Acpu8LENmeEjXGr7DZdxOvFbQbiX1NWV YU1w== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of alison.schofield@intel.com designates 134.134.136.24 as permitted sender) smtp.mailfrom=alison.schofield@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Gm-Message-State: AA+aEWZbOyraPIgvXnuI+ied9ZcwFrcXXJXLiVjkvzHaNUXyF/PvGYvr F3f4Ft06JsHcjQdRW0zsTHdFxhWL/UEVbyQRcYx958AAAO+RPIdonli6tKSjk1kf0hTYcTLAkt4 9GJA/eJYTWVv1vSdCP6nj4QjzSTXpHCO6EMU6UgVD/RNpkKgc4k17teqUjPDBqfDJWw== X-Received: by 2002:a63:7154:: with SMTP id b20mr15922610pgn.342.1543909046205; Mon, 03 Dec 2018 23:37:26 -0800 (PST) X-Google-Smtp-Source: AFSGD/X0rm1QUQRTNhpl75Cy9UAJICYdjADApGCsgqyShvh67gr3mNprwk1qVObyB5+cvhe/yHAt X-Received: by 2002:a63:7154:: with SMTP id b20mr15922575pgn.342.1543909044843; Mon, 03 Dec 2018 23:37:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543909044; cv=none; d=google.com; s=arc-20160816; b=w69VylWcvu6no6EaOp8Oxzn+RuRfAb2VcHDPCKmt3wAq6sTux+CJarnmDAar6sGjjW hWuMjWmcwM1YuYlhDJ9C9RpfDoa3CWDxhdxF8RK3JfJoTXIkS9oTQTwAFanxUAlyZ82l i1O9p8HN67hVSL3N5iL2obWAGhrF+Urm0ckb2LQTae66GirAkZiaEpxILkYoIyL2qfzV AavLwBC+Ta5baf1qcdmfk/f5+caEIArIbrGCdma3PEzBsR3ZqN9vseFc8eU8ITYAEmxZ KaB2W39alInLPBz5TpP9+KhdqdBCuUq1hAqoQ0EuSgE7LaomoS+g9QhB4WQoZ6QPBupi gukA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:references:in-reply-to:message-id:date :subject:cc:to:from; bh=4WHf7+SFm92EbbrOxdFTgt5fziQZ/f7v5fSnDI5i9h4=; b=f6wwynet7ki9CtKMYMbwCT+KbLBCc0L7WLXOOf/ypbgpjXY85M5gAq0E3aeReu8EI1 YEdt+OiA5IwreEZiXGMrTJhbZBoVO8hD8VFnArLKe0yJ4qng+s7TXg5CWM5WvQTd7q1e w+1+B6fUXd7b+SqbqEmlhVITY8hQyXskg8LpXj3q8NWMGi0UPwI3JfTcfJbNhfxVZyCS o+MAHIvuGBdeGmDl7tTteHkKk7s+7OnrnNtEfKXWvEwUBrt0G9aVapJ6CN8Ekao2ckNk a3PKKQAJjX2Y9tCpv6dtDCX3DkuFCl63oOXCFlc8YQ/H+Q4FL2Uxk+UjGfvH0Mn6M7WD 77QA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of alison.schofield@intel.com designates 134.134.136.24 as permitted sender) smtp.mailfrom=alison.schofield@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from mga09.intel.com (mga09.intel.com. [134.134.136.24]) by mx.google.com with ESMTPS id s123si14323638pgs.93.2018.12.03.23.37.24 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Dec 2018 23:37:24 -0800 (PST) Received-SPF: pass (google.com: domain of alison.schofield@intel.com designates 134.134.136.24 as permitted sender) client-ip=134.134.136.24; Authentication-Results: mx.google.com; spf=pass (google.com: domain of alison.schofield@intel.com designates 134.134.136.24 as permitted sender) smtp.mailfrom=alison.schofield@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 03 Dec 2018 23:37:22 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,313,1539673200"; d="scan'208";a="97861634" Received: from alison-desk.jf.intel.com (HELO alison-desk) ([10.54.74.53]) by orsmga006.jf.intel.com with ESMTP; 03 Dec 2018 23:37:22 -0800 From: Alison Schofield 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 Message-Id: X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP 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 Signed-off-by: Kirill A. Shutemov --- 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 +#include +#include +#include +#include +#include +#include + +#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.