multi-key-total-memory-encryption-spec-1.4
multi-key-total-memory-encryption-spec-1.4
Encryption Technologies
Specification
August 2022
Revision 1.4
Figures
Figure 2-1. Two-Socket Configuration of TME ........................................... 8
Figure 3-1. High-level Architecture of TME-MK .......................................... 9
Figure 5-1. KeyID Usage ......................................................................18
Figure 6-1. TME-MK Engine Overview .....................................................20
Tables
Table 4-1. IA32_TME_CAPABILITY MSR – Address 981H ...........................12
Table 4-1. IA32_TME_ACTIVATE MSR – Address 982H ..............................13
Table 4-3. IA32_TME_ACTIVATE WRMSR Response and Error Handling .......15
Table 4-4. MK_TME_CORE_ACTIVATE MSR – Address 9FFH .......................16
Table 4-5. IA32_TME_EXCLUDE_MASK MSR – Address 983H .....................17
Table 4-6. IA32_TME_EXCLUDE_BASE MSR – Address 984H ......................17
Table 6-1. PCONFIG Instruction Details ..................................................20
Table 6-2. PCONFIG Leaf Encodings .......................................................21
Table 6-3. PCONFIG Targets .................................................................21
Table 6-4. MKTME_KEY_PROGRAM_STRUCT Format .................................22
Table 6-5. Supported Key Programming Commands .................................22
Table 6-6. Programming Status for MKTME_KEY_PROGRAM.......................23
Table 6-7. Variable Definitions ..............................................................25
1.3 • Added support for 256b keys and KeyID0/TME encryption bypass. April 2021
TME (Total Memory Encryption): This is a baseline capability for memory encryption with a
single ephemeral key.
TME-MK (Total Memory Encryption-Multi-Key): Add support to use multiple keys for page
granular memory encryption with additional support for software provisioned keys.
Total Memory Encryption (TME) – the capability to encrypt the entirety of physical
memory of a system. This capability is typically enabled in the very early stages of the
boot process with a small change to BIOS and once configured and locked, will encrypt
all the data on external memory buses of an SoC using the NIST standard AES-XTS
algorithm with 128-bit keys or 256-bit keys depending on the algorithm availability and
selection. The encryption key used for TME uses a hardware random number generator
implemented in the Intel SoC, and the keys are not accessible by software or using
external interfaces to the Intel SoC. TME capability is intended to provide protections of
AES-XTS to external memory buses and DIMMs. The architecture is flexible and will
support additional memory protection schemes in the future. This capability, when
enabled, is intended to support (unmodified) existing system and application software.
Overall performance impact of this capability is likely to be relatively small and is highly
dependent on workload.
Total Memory Encryption-Multi-Key (TME-MK) builds on TME and adds support for
multiple encryption keys. The SoC implementation supports a fixed number of
encryption keys, and software can configure the SoC to use a subset of available keys.
Software manages the use of keys and can use each of the available keys for encrypting
any page of the memory. Thus, TME-MK allows page granular encryption of memory. By
default, TME-MK uses the TME encryption key unless explicitly specified by software. In
addition to supporting a CPU generated ephemeral key (not accessible by software or
using external interfaces to the SoC), TME-MK also supports software provided keys.
Software provided keys are particularly useful when used with non-volatile memory or
when combined with attestation mechanisms and/or used with key provisioning services.
In a virtualization scenario, we anticipate the VMM or hypervisor managing the use of
keys to transparently support legacy operating systems without any changes (thus,
TME-MK can also be viewed as TME virtualization in such a deployment scenario). An OS
may be enabled to take additional advantage of the TME-MK capability both in native
and in a virtualized environment. When properly enabled, TME-MK is available to each
guest OS in a virtualized environment, and the guest OS can take advantage of TME-MK
in the same way as a native OS.
The AES XTS encryption engine is in the direct data path to external memory buses and
therefore, all the memory data entering and/or leaving the SoC on memory buses is
encrypted using AES XTS. The data inside the SoC (in caches, etc.) remains plain text
and supports all the existing software and I/O models.
In a typical deployment, the encryption key is generated by the CPU and therefore is not
visible to the software. When the system is configured with NVRAM, if the NVRAM is to
be treated as DRAM, then it can also use CPU generated keys. However, if NVRAM is to
be treated as non-volatile memory, there is an option to have the same key
generated/reused across platform power cycles/reboots.
4.1 Enumeration
TME and TME-MK capability is exposed to the BIOS/Software via the MSR described in
this section. The maximum number of keys available/supported in the processor for
TME-MK are enumerated. BIOS will need to activate this capability via an MSR
(described later) and it must select the number of keys to be supported/used for TME-
MK during the early boot process. Upon activation, all memory (except memory in the
TME Exclusion range) attached to the CPU/SoC is encrypted using AES-XTS with a 128-
bit or 256-bit ephemeral key (platform key) that is generated by the CPU on every boot.
Note that this behavior is applicable only when TME encryption is not bypassed (using
bit 31 in the IA32_TME_ACTIVATE MSR). If TME encryption is bypassed, all accesses
with KeyID0 will bypass encryption/decryption.
Intel processors support external memory controllers. These memory controllers may be
attached to the processor via coherent buses such as the Intel® Ultra Path Interconnect
(Intel® UPI) or Compute Express Link (CXL). TME-MK enumeration can be used to
discover the capabilities of the Intel processor and some of the memory attached to the
integrated memory controller, but does not necessarily represent external memory
controller features, or some types of memory attached to the integrated controller. The
memory regions that are capable of being protected by CPU cryptographic capabilities
are communicated to the system software via a new UEFI memory attribute,
EFI_MEMORY_CPU_CRYPTO, introduced in UEFI 2.8. If this flag is set, the memory
region is capable of being protected with the CPU’s memory cryptographic capabilities. If
this flag is cleared, the memory region is not capable of being protected with the CPU’s
memory cryptographic capabilities or the CPU does not support CPU memory
cryptographic capabilities. System software must consult the attribute to determine the
ranges that can be encrypted using TME-MK.
4.1.1 TME
CPUID.TME (CPUID.(EAX=07H, ECX=0H): ECX[13]) enumerates the existence of these
four architectural MSRs and their MSR addresses:
• IA32_TME_CAPABILITY – Address 981H
• IA32_TME_ACTIVATE – Address 982H
• IA32_TME_EXCLUDE_MASK – Address 983H
• IA32_TME_EXCLUDE_BASE – Address 984H
981H IA32_TME_CAPABILITY Memory Encryption One MSR for TME and TME-MK.
MSR Capability MSR
1 Reserved
30:3 Reserved
63:51 Reserved
To enable TME-MK, the Hardware Encryption Enable bit in the IA32_TME_ACTIVATE MSR
must be set, and bits 35:32 must have a non-zero value (which will specify the number
of KeyID bits configured for TME-MK).
2 Key Select:
0 – Create a new TME key
(expected cold/warm boot).
1 – Restore the TME key from
storage (expected when resume
from standby).
3 Save TME key for Standby: May not be supported in all CPUs.
Save key into storage to be
used when resume from
standby.
30:8 Reserved
MK_TME_KEYID_BITS
The number of key identifier
bits to allocate to TME-MK
usage. Similar to enumeration,
this is an encoded value.
Writing a value greater than
MK_TME_MAX_KEYID_BITS will
result in #GP.
Writing a non-zero value to this
field will #GP if bit 1 of EAX
(Hardware Encryption Enable) is
not also set to ‘1, as encryption
hardware must be enabled to
use TME-MK.
47:36 Reserved
63:48 MK_TME_CRYPTO_ALGS
Bit 48: AES-XTS 128
Bit 49: Reserved
Bit 50: AES-XTS-256
Bit 63:51: Reserved (#GP)
Bitmask for BIOS to set which
encryption algorithms are
allowed for TME-MK, will be
later enforced by the key
loading ISA (‘1 = allowed).
WRMSR with enabled=1 and key select=0 (new key); TME enabled and MSR locked subsequent RDMSR
RNG success. returns x..x011b.
WRMSR with enabled=1 and key select=0; RNG fail Not enabled subsequent RDMSR returns x..x000b.
WRMSR with enabled=1 and key select=1; Non-zero TME enabled and MSR locked subsequent RDMSR
key restored from CPU. returns x..x111b.
WRMSR with enabled=1 and key select=1; Fail - Zero Not enabled subsequent RDMSR returns x..x100b.
key restored from CPU.
WRMSR with any other legal values. Subsequent RDMSR returns written values + lock
status=1.
After successful activation using the IA32_TME_ACTIVATE MSR, this register should be
written on each physical core with a value of 0 in EDX:EAX; failure to do so may result in
unpredictable behavior. Accesses to this MSR will #GP if TME-MK is not supported.
BIOS is expected to write to this MSR on each core after doing TME-MK activation. The
first SMI on each core will also cause this value to be synchronized with the package
MSR value.
31:0 Reserved
63:36 Reserved
983H IA32_TME_EXCLUDE_
MASK MSR
10:0 Reserved
984H IA32_TME_EXCLUDE_
BASE MSR
11:0 Reserved
Note: Writing ‘1’ into bits above the max supported physical size will result in #GP.
The IA32_TME_EXCLUDE_MASK MSR must define a contiguous region. WRMSR will #GP
if the TMEEMASK field does not specify a contiguous region.
These MSRs are locked by the IA32_TME_ACTIVATE MSR. If lock=1, then WRMSR to
IA32_TME_EXCLUDE_MASK/IA32_TME_EXCLUDE_BASE MSRs will result in #GP.
When TME-MK is activated, the upper bits of the platform physical address (starting with
the highest order bit available as enumerated by the CPUID MAX_PA info) are
repurposed for usage as a KeyID as shown below.
5.1.1 IA Paging
When IA paging is being used without EPT, the upper bits starting with MAX_PA for each
level of the IA page table are repurposed for usage as KeyID bits. Similarly, the upper
bits of the physical address in CR3 will be treated in the same manner.
Note that when EPT is active, IA paging does not generate/use platform physical
addresses, instead it produces/uses guest physical addresses. Guest physical addresses
are not modified by TME-MK and will continue to index into EPT page table walks as they
did prior to enabling TME-MK.
The TME-MK engine maintains an internal key table not accessible by software to store
the information (key and encryption mode) associated with each KeyID. Each KeyID
may be associated with three encryption modes: Encryption using key specified, do not
encrypt at all (memory will be plain text), or encrypt using TME Key. Future
implementation may support additional encryption modes. PCONFIG is a new instruction
that is used to program KeyID attributes for TME-MK. While initial implementation may
only use PCONFIG for TME-MK, it may be extended in the future to support additional
usages. Therefore, PCONFIG is enumerated separately from TME-MK.
Addresses and operands are 32 bits outside 64-bit mode (IA32_EFER.LMA = 0 || CS.L =
0) and are 64 bits in 64-bit mode (IA32_EFER.LMA = 1 && CS.L = 1). The CS.D value
has no impact on address calculation. The DS segment is used to create linear
addresses.
MKTME_KEY_PROGRAM 0x00000000 This leaf is used to program the key and encryption
mode associated with a KeyID.
A PCONFIG target is defined as any hardware block on the platform which can be
configured using PCONFIG. PCONFIG currently only supports one target, TME-MK.
6.2.1.1.1 KEYID
6.2.1.1.2 KEYID_CTRL
The KEYID_CTRL field carries two sub-fields used by software to control the behavior of
a KeyID: Command and KeyID encryption algorithm.
The command used controls the encryption mode for a KeyID. Table 6-5 provides a
summary of the commands supported.
KEYID_SET_KEY_DIRECT 0 Software uses this mode to directly program a key for use with
KeyID.
KEYID_SET_KEY_RANDOM 1 The CPU generates and assigns an ephemeral key for use with
a KeyID. Each time the instruction is executed, the CPU
generates a new key using a hardware random number
generator and the keys are discarded on reset.
The cryptographic algorithm field (CRYPTO_ALG) allows software to select one of the
activated cryptographic algorithms for the KeyID. As discussed previously, the BIOS can
activate a set of algorithms to allow for use when programming keys using the
IA32_TME_ACTIVATE MSR (does not apply to KeyID 0 which uses the TME policy when
TME encryption is not bypassed). The ISA checks to ensure that the algorithm selected
by software is one of the algorithms that has been activated by the BIOS. Note that
6.2.1.1.3 KEY_FIELD_1
This field carries a software supplied data key to be used for the KeyID if the direct key
programming option is used (KEYID_SET_KEY_DIRECT). When the random key
programming option is used (KEYID_SET_KEY_RANDOM), this field carries a software
supplied entropy to be mixed in the CPU generated random data key. It is software’s
responsibility to ensure that the key supplied for the direct programming option or the
entropy supplied for the random programming option does not result in weak keys.
There are no explicit checks in the instruction to detect or prevent weak keys. When AES
XTS-128 is used, the upper 48B are treated as reserved and must be zeroed out by
software before executing the instruction. When AES XTS-256 is used, the upper 32B
are treated as reserved and must be zeroed out by software before executing the
instruction.
6.2.1.1.4 KEY_FIELD_2
This field carries a software supplied tweak key to be used for the KeyID if the direct key
programming option is used (KEYID_SET_KEY_DIRECT). When the random key
programming option is used (KEYID_SET_KEY_RANDOM), this field carries a software
supplied entropy to be mixed in the CPU generated random tweak key. It is software’s
responsibility to ensure that the key supplied for the direct programming option or the
entropy supplied for the random programming option does not result in weak keys.
There are no explicit checks in the instruction to detect or prevent weak keys. When AES
XTS-128 is used, the upper 48B are treated as reserved and must be zeroed out by
software before executing the instruction. When AES XTS-256 is used, the upper 32B
are treated as reserved and must be zeroed out by software before executing the
instruction.
All KeyIDs default to TME behavior (encrypt with TME key or bypass encryption) on TME-
MK activation. Software can at any point decide to change the key for a KeyID using the
PCONFIG instruction. Change of keys for a KeyID does NOT change the state of TLB,
caches, or memory pipeline. It is software’s responsibility to take appropriate actions to
ensure correct behavior. Examples of software flows are provided in section 7.
Table 6-6 shows the return values associated with the MKTME_KEY_PROGRAM leaf of
PCONFIG. On instruction execution, RAX is populated with the return value.
6.2.3.1 CPUID.PCONFIG_LEAF.n (n ≥ 0)
Returns information about supported targets on the platform. The information returned
is shown below:
• EAX: Sub-leaf type
Bits 11:0: 0: Invalid sub-leaf, 1: Target Identifier
• If EAX[11:0] == 0
EAX:EBX:ECX:EDX = 0
Sub-leaves m>n return all 0s
• If EAX[11:0] == 1
EAX[31:12] = 0
EBX: Target_ID_1
ECX: Target_ID_2
EDX: Target_ID_3
Software is expected to scan all sub-leaves until an invalid sub-leaf is returned. All sub-
leaves after the first invalid sub-leaf are invalid as well.
KEY_TABLE_LOCK.ACQUIRE(WRITE)
KEY_TABLE_LOCK.RELEASE()
if(TMP_KEY_PROGRAM_STRUCT.KEY_FIELD_1.BYTES[63:16] != 0) #GP(0);
if(TMP_KEY_PROGRAM_STRUCT.KEY_FIELD_2.BYTES[63:16] != 0) #GP(0);
}
if (TMP_KEY_PROGRAM_STRUCT.KEYID_CTRL.ENC_ALG[2] == 1)
{
if(TMP_KEY_PROGRAM_STRUCT.KEY_FIELD_1.BYTES[63:32] != 0) #GP(0);
if(TMP_KEY_PROGRAM_STRUCT.KEY_FIELD_2.BYTES[63:32] != 0) #GP(0);
}
(* Check for a valid command *)
if(TMP_KEY_PROGRAM_STRUCT. KEYID_CTRL.COMMAND is not a valid command)
{
RFLAGS.ZF = 1;
RAX = INVALID_PROG_CMD;
goto EXIT;
}
(* Check that the KEYID being operated upon is a valid KEYID *)
if(TMP_KEY_PROGRAM_STRUCT.KEYID >
2^IA32_TME_ACTIVATE.MK_TME_KEYID_BITS – 1
OR TMP_KEY_PROGRAM_STRUCT.KEYID >
IA32_TME_CAPABILITY.MK_TME_MAX_KEYS
OR TMP_KEY_PROGRAM_STRUCT.KEYID == 0)
{
RFLAGS.ZF = 1;
RAX = INVALID_KEYID;
goto EXIT;
}
(* Lock is acquired and key table will be updated as per the command
Before this point no changes to the key table are made *)
switch(TMP_KEY_PROGRAM_STRUCT.KEYID_CTRL.COMMAND)
{
case KEYID_SET_KEY_DIRECT:
<<Write
DATA_KEY=TMP_KEY_PROGRAM_STRUCT.KEY_FIELD_1,
TWEAK_KEY=TMP_KEY_PROGRAM_STRUCT.KEY_FIELD_2,
ENCRYPTION_MODE=ENCRYPT_WITH_KEYID_KEY,
to MKTME Key table at index TMP_KEY_PROGRAM_STRUCT.KEYID
>>
break;
case KEYID_SET_KEY_RANDOM:
TMP_RND_DATA_KEY = <<Generate a random key using hardware RNG>>
if (NOT ENOUGH ENTROPY)
{
RFLAGS.ZF = 1;
RAX = ENTROPY_ERROR;
goto EXIT;
}
TMP_RND_TWEAK_KEY = <<Generate a random key using hardware RNG>>
if (NOT ENOUGH ENTROPY)
{
RFLAGS.ZF = 1;
RAX = ENTROPY_ERROR;
goto EXIT;
}
(* 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];
<<Write
DATA_KEY=TMP_RND_DATA_KEY,
case KEYID_CLEAR_KEY:
<<Write
DATA_KEY=’0,
TWEAK_KEY=’0,
ENCRYPTION_MODE = ENCRYPT_WITH_TME_KEY_OR_BYPASS,
to MKTME_KEY_TABLE at index TMP_KEY_PROGRAM_STRUCT.KEYID
>>
break;
case KEYID_NO_ENCRYPT:
<<Write
DATA_KEY=’0,
TWEAK_KEY=’0,
ENCRYPTION_MODE=NO_ENCRYPTION,
to MKTME_KEY_TABLE at index TMP_KEY_PROGRAM_STRUCT.KEYID
>>
break;
}
RAX = 0;
RFLAGS.ZF = 0;
//Release Lock
KEY_TABLE_LOCK(RELEASE);
EXIT:
RFLAGS.CF=0;
RFLAGS.PF=0;
RFLAGS.AF=0;
RFLAGS.OF=0;
RFLAGS.SF=0;
}
end_of_flow
Note that while this section focuses on virtualization scenarios, the TME and TME-MK
architecture is applicable to both native OS and virtualized environments, and for DRAM
and NVRAM types of memory.
The sections below are intended to give examples of algorithms that shouldn’t be used
by software to ensure correctness and security. Please check the final version of this
specification for any updated algorithms or requirements in this area.
1. Software should avoid mapping the same physical address with multiple KeyIDs.
2. If software must map the same physical address with multiple KeyIDs, it should mark
those pages as read-only, except for one KeyID.
3. If software must map the same physical address with multiple KeyIDs as read-write,
then software must ensure that all writes are done with a single KeyID (this includes
locked and non-locked writes that do not modify the data).
1. Program a new key for the KeyID, if not already programmed (using the PCONFIG
instruction).
2. Map the physical page to the VMM’s address space (with the new KeyID) by updating
its paging structure entries (IA-PT), if not already mapped.
3. Ensure that the step 1 has successfully completed.
4. Zero-page contents via the new mapping (with new KeyID) to avoid data leakage
between KeyID domains.
5. Make the page available to a new VM with the new KeyID set in the EPT page-table
entry.
This will ensure against data leakage between KeyID domains, such as VMs with KeyIDs,
when the KeyID is changed for a physical page (but the data is in clear in the CPU
caches). The assumption is that before using this algorithm to assign a new KeyID, the
software/VMM makes sure that the page was evicted correctly from the previous KeyID
(using the algorithm defined in the next section).
Note: Guidance for usage of the PCONFIG instruction: PCONFIG is package scope and
hence software is expected to execute PCONFIG on one LP on each
package/socket. Software can use CPUID Leaf 0BH to determine the topology of
the system which will indicate the physical packages present on the system.
a) Make the physical page not accessible to the VM (by updating the EPT page-table
entry).
b) Invalidate all page mappings/aliases (the INVEPT instruction and IOMMU (VT-d)
invalidation if page was mapped as device accessible) from the TLB (across the
logical processors, with the old KeyID).
c) Map the page to VMM address space (with the old KeyID) by updating its paging
structure entries (IA-PT) if not already mapped.
d) OS/VMM flushes dirty cache lines (for page using old KeyID) to prevent aliasing
overwrite/data corruption.
Options: CLFLUSH, CLWB+fence, CLFLUSHOPT+fence or WBINVD.
Software can optionally avoid doing these flushes if it tracks page
modification using EPT page-modification logging or accessed and dirty
flags for EPT (optimization).
2. The page is now ready to be used with a new KeyID (example, using steps in the
previous section).
Note: Guidance for usage of the WBINVD instruction: The WBINVD instruction should
be run on each socket if those invalidate all coherent caches on the sockets.
1. Evict a page with KeyID2 from VM2 using the EvictPage algorithm described in section
7.5.
2. The OS/VMM reads the evicted page with KeyID2, encrypts the page contents with
the Full Disk Encryption key (optional), and writes the page to disk/stores on a swap
file (or in OS/VMM memory, using the VMM KeyID=0).
3. Add the evicted page to VM3 KeyID3 using the AddPage algorithm in section 7.4.