> -----Original Message----- > From: owner-linux-mm@xxxxxxxxx [mailto:owner-linux-mm@xxxxxxxxx] On > Behalf Of Huang, Kai > Sent: Monday, September 10, 2018 1:28 PM > To: Schofield, Alison <alison.schofield@xxxxxxxxx>; dhowells@xxxxxxxxxx; > tglx@xxxxxxxxxxxxx > Cc: Nakajima, Jun <jun.nakajima@xxxxxxxxx>; Shutemov, Kirill > <kirill.shutemov@xxxxxxxxx>; Hansen, Dave <dave.hansen@xxxxxxxxx>; > Sakkinen, Jarkko <jarkko.sakkinen@xxxxxxxxx>; jmorris@xxxxxxxxx; > keyrings@xxxxxxxxxxxxxxx; linux-security-module@xxxxxxxxxxxxxxx; > mingo@xxxxxxxxxx; hpa@xxxxxxxxx; x86@xxxxxxxxxx; linux-mm@xxxxxxxxx > Subject: RE: [RFC 01/12] docs/x86: Document the Multi-Key Total Memory > Encryption API > > > > -----Original Message----- > > From: owner-linux-mm@xxxxxxxxx [mailto:owner-linux-mm@xxxxxxxxx] On > > Behalf Of Alison Schofield > > Sent: Saturday, September 8, 2018 10:34 AM > > To: dhowells@xxxxxxxxxx; tglx@xxxxxxxxxxxxx > > Cc: Huang, Kai <kai.huang@xxxxxxxxx>; Nakajima, Jun > > <jun.nakajima@xxxxxxxxx>; Shutemov, Kirill > > <kirill.shutemov@xxxxxxxxx>; Hansen, Dave <dave.hansen@xxxxxxxxx>; > > Sakkinen, Jarkko <jarkko.sakkinen@xxxxxxxxx>; jmorris@xxxxxxxxx; > > keyrings@xxxxxxxxxxxxxxx; linux-security-module@xxxxxxxxxxxxxxx; > > mingo@xxxxxxxxxx; hpa@xxxxxxxxx; x86@xxxxxxxxxx; linux-mm@xxxxxxxxx > > Subject: [RFC 01/12] docs/x86: Document the Multi-Key Total Memory > > Encryption API > > > > Document the API's used for MKTME on Intel platforms. > > MKTME: Multi-KEY Total Memory Encryption > > > > Signed-off-by: Alison Schofield <alison.schofield@xxxxxxxxx> > > --- > > Documentation/x86/mktme-keys.txt | 153 > > +++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 153 insertions(+) > > create mode 100644 Documentation/x86/mktme-keys.txt > > > > diff --git a/Documentation/x86/mktme-keys.txt > > b/Documentation/x86/mktme- keys.txt new file mode 100644 index > > 000000000000..2dea7acd2a17 > > --- /dev/null > > +++ b/Documentation/x86/mktme-keys.txt > > @@ -0,0 +1,153 @@ > > +MKTME (Multi-Key Total Memory Encryption) is a technology that allows > > +memory encryption on Intel platforms. Whereas TME (Total Memory > > +Encryption) allows encryption of the entire system memory using a > > +single key, MKTME allows multiple encryption domains, each having > > +their own key. The main use case for the feature is virtual machine > > +isolation. The API's introduced here are intended to offer > > +flexibility to work in a > > wide range of uses. > > + > > +The externally available Intel Architecture Spec: > > +https://software.intel.com/sites/default/files/managed/a5/16/Multi-Ke > > +y- > > +Total-Memory-Encryption-Spec.pdf > > + > > +============================ API Overview > > +============================ > > + > > +There are 2 MKTME specific API's that enable userspace to create and > > +use the memory encryption keys: > > + > > +1) Kernel Key Service: MKTME Type > > + > > + MKTME is a new key type added to the existing Kernel Key Services > > + to support the memory encryption keys. The MKTME service manages > > + the addition and removal of MKTME keys. It maps userspace keys > > + to hardware keyids and programs the hardware with user requested > > + encryption parameters. > > + > > + o An understanding of the Kernel Key Service is required in order > > + to use the MKTME key type as it is a subset of that service. > > + > > + o MKTME keys are a limited resource. There is a single pool of > > + MKTME keys for a system and that pool can be from 3 to 63 keys. > > Why 3 to 63 keys? Architecturally we are able to support up to 15-bit keyID, > although in the first generation server we only support 6-bit keyID, which is 63 > key/keyIDs (excluding keyID 0, which is TME's keyID). > > > + With that in mind, userspace may take advantage of the kernel > > + key services sharing and permissions model for userspace keys. > > + One key can be shared as long as each user has the permission > > + of "KEY_NEED_VIEW" to use it. > > + > > + o MKTME key type uses capabilities to restrict the allocation > > + of keys. It only requires CAP_SYS_RESOURCE, but will accept > > + the broader capability of CAP_SYS_ADMIN. See capabilities(7). > > + > > + o The MKTME key service blocks kernel key service commands that > > + could lead to reprogramming of in use keys, or loss of keys from > > + the pool. This means MKTME does not allow a key to be invalidated, > > + unlinked, or timed out. These operations are blocked by MKTME as > > + it creates all keys with the internal flag KEY_FLAG_KEEP. > > + > > + o MKTME does not support the keyctl option of UPDATE. Userspace > > + may change the programming of a key by revoking it and adding > > + a new key with the updated encryption options (or vice-versa). > > + > > +2) System Call: encrypt_mprotect() > > + > > + MKTME encryption is requested by calling encrypt_mprotect(). The > > + caller passes the serial number to a previously allocated and > > + programmed encryption key. That handle was created with the MKTME > > + Key Service. > > + > > + o The caller must have KEY_NEED_VIEW permission on the key > > + > > + o The range of memory that is to be protected must be mapped as > > + ANONYMOUS. If it is not, the entire encrypt_mprotect() request > > + fails with EINVAL. > > + > > + o As an extension to the existing mprotect() system call, > > + 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. > > + > > + o Additional mprotect() calls to memory already protected with > > + MKTME will not alter the MKTME status. > > I think it's better to separate encrypt_mprotect() into another doc so both parts > can be reviewed easier. > > > + > > +====================== Usage: MKTME Key Service > > +====================== > > + > > +MKTME is enabled on supported Intel platforms by selecting > > +CONFIG_X86_INTEL_MKTME which selects CONFIG_MKTME_KEYS. > > + > > +Allocating MKTME Keys via command line or system call: > > + keyctl add mktme name "[options]" ring > > + > > + key_serial_t add_key(const char *type, const char *description, > > + const void *payload, size_t plen, > > + key_serial_t keyring); > > + > > +Revoking MKTME Keys via command line or system call:: > > + keyctl revoke <key> > > + > > + long keyctl(KEYCTL_REVOKE, key_serial_t key); > > + > > +Options Field Definition: > > + userkey= ASCII HEX value encryption key. Defaults to a CPU > > + generated key if a userkey is not defined here. > > + > > + algorithm= Encryption algorithm name as a string. > > + Valid algorithm: "aes-xts-128" > > + > > + tweak= ASCII HEX value tweak key. Tweak key will be added to the > > + userkey... (need to be clear here that this is being sent > > + to the hardware - kernel not messing w it) > > + > > + entropy= ascii hex value entropy. > > + This entropy will be used to generated the CPU key and > > + the tweak key when CPU generated key is requested. > > + > > +Algorithm Dependencies: > > + AES-XTS 128 is the only supported algorithm. > > + There are only 2 ways that AES-XTS 128 may be used: > > + > > + 1) User specified encryption key > > + - The user specified encryption key must be exactly > > + 16 ASCII Hex bytes (128 bits). > > + - A tweak key must be specified and it must be exactly > > + 16 ASCII Hex bytes (128 bits). > > + - No entropy field is accepted. > > + > > + 2) CPU generated encryption key > > + - When no user specified encryption key is provided, the > > + default encryption key will be CPU generated. > > + - User must specify 16 ASCII Hex bytes of entropy. This > > + entropy will be used by the CPU to generate both the > > + encryption key and the tweak key. > > + - No entropy field is accepted. > > This is not true. The spec says in CPU generated random mode, both 'key' and > 'tweak' part are used to generate the final key and tweak respectively. > > Actually, simple 'XOR' is used to generate the final key: > > case KEYID_SET_KEY_RANDOM: > ...... > (* Mix user supplied entropy to the data key and tweak key *) > TMP_RND_DATA_KEY = TMP_RND_KEY XOR > TMP_KEY_PROGRAM_STRUCT.KEY_FIELD_1.BYTES[15:0]; > TMP_RND_TWEAK_KEY = TMP_RND_TWEAK_KEY XOR > TMP_KEY_PROGRAM_STRUCT.KEY_FIELD_2.BYTES[15:0]; > > So I think we can either just remove 'entropy' parameter, since we can use both > 'userkey' and 'tweak' even for random key mode. > > In fact, which might be better IMHO, we can simply disallow or ignore 'userkey' > and 'tweak' part for random key mode, since if we allow user to specify both > entropies, and if user passes value with all 1, we are effectively making the key > and tweak to be all 1, which is not random anymore. > > Instead, kernel can generate random for both entropies, or we can simply uses 0, > ignoring user input. Hmm.. I just realized that I confused 'OR' and 'XOR', so the last two paragraphs doesn't make sense. :) But still I think we can simply use "userkey" and "tweak". "entropy" is not needed IMO. Thanks, -Kai > > Thanks, > -Kai > > + > > +====================== Usage: encrypt_mprotect() > > +====================== > > + > > +System Call encrypt_mprotect():: > > + > > + This system call is an extension of the existing mprotect() system > > + call. It requires the same parameters as legary mprotect() plus > > + one additional parameter, the keyid. Userspace must provide the > > + key serial number assigned through the kernel key service. > > + > > + int encrypt_mprotect(void *addr, size_t len, int prot, int > > + keyid); > > + > > +====================== Usage: Sample Roundtrip > > ====================== > > + > > +Sample usage of MKTME Key Service API with encrypt_mprotect() API: > > + > > + Add a key: > > + key = add_key(mktme, name, options, strlen(option), keyring); > > + > > + Map memory: > > + ptr = mmap(NULL, size, prot, MAP_ANONYMOUS|MAP_PRIVATE, -1, > > + 0); > > + > > + Protect memory: > > + ret = syscall(sys_encrypt_mprotect, ptr, size, prot, keyid); > > + > > + Use protected memory: > > + ................ > > + > > + Free memory: > > + ret = munmap(ptr, size); > > + > > + Revoke key: > > + ret = keyctl(KEYCTL_REVOKE, key); > > + > > -- > > 2.14.1