PCONFIG — Platform Configuration Instruction Operand Encoding Description PCONFIG allows software to configure certain platform features. PCONFIG supports multiple leaf functions, with a leaf function identified by the value in EAX. The registers RBX, RCX, and RDX may provide input or output informa- tion for certain leaves. All leaves write status information to EAX but do not modify RBX, RCX, or RDX unless they are being used as leaf-specific output. Each PCONFIG leaf function applies to a specific hardware block called a PCONFIG target, and each PCONFIG target is associated with a numerical target identifier . Supported target identifiers are enumerated, along with other PCONFIG capabilities, in the sub-leaves of the PCONFIG-information leaf of CPUID (EAX = 1BH). An attempt to execute an undefined leaf function, or a leaf function that applies to an unsupported target identifier, results in a general-protection exception (#GP). (In the future, the PCONFIG-information leaf of CPUID may enumerate PCONFIG capabilities in addition to the supported target identifiers.) Addresses and operands are 32 bits outside 64-bit mode and are 64 bits in 64-bit mode. The value of CS.D does not affect operand size or address size. Table 4-15 shows the leaf encodings for PCONFIG, and Table 4-16 shows the leaf register usage for PCONFIG. The MKTME_KEY_PROGRAM leaf of PCONFIG pertains to the MKTME 1 target, which has target identifier 1. It is used by software to manage the key associated with a KeyID. The leaf function is invoked by setting the leaf value of 0 in EAX and the address of MKTME_KEY_PROGRAM_STRUCT in RBX. Successful execution of the leaf clears RAX (set to zero) and ZF, CF, PF, AF, OF, and SF are cleared. In case of failure, the failure reason is indicated in RAX with ZF set to 1 and CF, PF, AF, OF, and SF are cleared. The MKTME_KEY_PROGRAM leaf uses the MKTME_KEY_PROGRAM_STRUCT in memory shown in Table 4-17. Opcode/ Instruction Op/ En 64/32 bit Mode Support CPUID Feature Flag Description NP 0F 01 C5 PCONFIG AV/VPCONFIGThis instruction is used to execute functions for configuring platform features. Op/EnTupleOperand 1Operand 2Operand 3Operand 4 ANANANANANA Table 4-15. PCONFIG Leaf Encodings LeafEncodingDescription MKTME_KEY_PROGRAM00000000HThis leaf is used to program the key and encryption mode associated with a KeyID. RESERVED00000001H - FFFFFFFFHReserved for future use (#GP(0) if used). Table 4-16. PCONFIG Leaf Register Usage LeafRBXRCXRDX MKTME_KEY_PROGRAMInput only.Input only.Input only. RESERVEDReserved for future use.Reserved for future use.Reserved for future use. 1.Further details on MKTME usage can be found here: https://software.intel.com/sites/default/files/managed/a5/16/Multi-Key-Total-Memory-Encryption-Spec.pdf image/svg+xml A description of each of the fields in MKTME_KEY_PROGRAM_STRUCT is provided below: • KEYID: Key Identifier being programmed to the MKTME engine. • 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 4-18 provides a summary of the commands supported. The encryption algorithm field (ENC_ALG) allows software to select one of the activated encryption algorithms for the KeyID. 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 processor checks to ensure that the algorithm selected by software is one of the algorithms that has been activated by the BIOS. • KEY_FIELD_1: This field carries the 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 the 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. • KEY_FIELD_2: This field carries the 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 the 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. All KeyIDs default to TME behavior (encrypt with TME key or bypass encryption) on MKTME activation. Software can at any point decide to change the key for a KeyID using the PCONFIG instruction. Change of Table 4-17. MKTME_KEY_PROGRAM_STRUCT Format FieldOffset (bytes)Size (bytes)Comments KEYID02Key Identifier. KEYID_CTRL24KeyID control: •Bits [7:0]: COMMAND. •Bits [23:8]: ENC_ALG. •Bits [31:24]: Reserved, must be zero. RESERVED658Reserved, must be zero. KEY_FIELD_16464Software supplied KeyID data key or entropy for KeyID data key. KEY_FIELD_212864Software supplied KeyID tweak key or entropy for KeyID tweak key. Table 4-18. Supported Key Programming Commands CommandEncodingDescription KEYID_SET_KEY_DIRECT0Software uses this mode to directly program a key for use with KeyID. KEYID_SET_KEY_RANDOM1CPU 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. KEYID_CLEAR_KEY2Clear the (software programmed) key associated with the KeyID. On execution of this command, the KeyID gets TME behavior (encrypt with platform TME key or bypass TME encryption). KEYID_NO_ENCRYPT3Do not encrypt memory when this KeyID is in use. image/svg+xml keys for a KeyID does NOT change the state of the TLB caches or memory pipeline. It is software's responsi- bility to take appropriate actions to ensure correct behavior. Table 4-19 shows the return values associated with the MKTME_KEY_PROGRAM leaf of PCONFIG. On instruction execution, RAX is populated with the return value. PCONFIG Virtualization Software in VMX root operation can control the execution of PCONFIG in VMX non-root operation using the following VM-execution controls introduced for PCONFIG: • PCONFIG_ENABLE: This control is a single bit control and enables the PCONFIG instruction in VMX non-root operation. If 0, the execution of PCONFIG in VMX non-root operation causes #UD. Otherwise, execution of PCONFIG works according to PCONFIG_EXITING. • PCONFIG_EXITING: This is a 64b control and allows VMX root operation to cause a VM-exit for various leaf functions of PCONFIG. This control does not have any effect if the PCONFIG_ENABLE control is clear. It is recommended that VMMs intercept execution of any PCONFIG leaves with which they are not familiar and convert such executions into #GP(0). PCONFIG Concurrency In a scenario where the MKTME_KEY_PROGRAM leaf of PCONFIG is executed concurrently on multiple logical processors, only one logical processor will succeed in updating the key table. PCONFIG execution will return with an error code (DEVICE_BUSY) on other logical processors and software must retry. In cases where the instruction execution fails with a DEVICE_BUSY error code, the key table is not updated, thereby ensuring that either the key table is updated in its entirety with the information for a KeyID, or it is not updated at all. In order to accomplish this, the MKTME_KEY_PROGRAM leaf of PCONFIG maintains a writer lock for updating the key table. This lock is referred to as the Key table lock and denoted in the instruction flows as KEY_TABLE_LOCK. The lock can either be unlocked, when no logical processor is holding the lock (also the initial state of the lock) or be in an exclusive state where a logical processor is trying to update the key table. There can be only one logical processor holding the lock in exclusive state. The lock, being exclusive, can only be acquired when the lock is in unlocked state. PCONFIG uses the following syntax to acquire KEY_TABLE_LOCK in exclusive mode and release the lock: • KEY_TABLE_LOCK.ACQUIRE(WRITE) • KEY_TABLE_LOCK.RELEASE() Operation Table 4-19. Supported Key Error Codes Return ValueEncodingDescription PROG_SUCCESS0KeyID was successfully programmed. INVALID_PROG_CMD1Invalid KeyID programming command. ENTROPY_ERROR2Insufficient entropy. INVALID_KEYID3KeyID not valid. INVALID_ENC_ALG4Invalid encryption algorithm chosen (not supported). DEVICE_BUSY5Failure to access key table. Table 4-20. PCONFIG Operation Variables Variable NameTypeSize (Bytes) Description TMP_KEY_PROGRAM_STRUCTMKTME_KEY_PROGRAM_STRUCT192Structure holding the key programming structure. TMP_RND_DATA_KEYUINT12816Random data key generated for random key programming option. TMP_RND_TWEAK_KEYUINT12816Random tweak key generated for random key programming option. image/svg+xml (* #UD if PCONFIG is not enumerated or CPL>0 *) IF (CPUID.7.0:EDX[18] == 0 OR CPL > 0) #UD; IF (in VMX non-root mode) { IF (VMCS.PCONFIG_ENABLE == 1) { IF ((EAX > 62 AND VMCS.PCONFIG_EXITING[63] ==1) OR (EAX < 63 AND VMCS.PCONFIG_EXITING[EAX] == 1)) { Set VMCS.EXIT_REASON = PCONFIG; //No Exit qualification Deliver VMEXIT; } } ELSE { #UD } } (* #GP(0) for an unsupported leaf *) IF (EAX != 0) #GP(0) (* KEY_PROGRAM leaf flow *) IF (EAX == 0) { (* #GP(0) if TME_ACTIVATE MSR is not locked or does not enable hardware encryption or multiple keys are not enabled *) IF (IA32_TME_ACTIVATE.LOCK != 1 OR IA32_TME_ACTIVATE.ENABLE != 1 OR IA32_TME_ACTIVATE.MK_TME_KEYID_BITS == 0) #GP(0) (* Check MKTME_KEY_PROGRAM_STRUCT is 256B aligned *) IF (DS:RBX is not 256B aligned) #GP(0); (* Check that MKTME_KEY_PROGRAM_STRUCT is read accessible *) <<DS: RBX should be read accessible>> (* Copy MKTME_KEY_PROGRAM_STRUCT to a temporary variable *) TMP_KEY_PROGRAM_STRUCT = DS:RBX.*; (* RSVD field check *) IF (TMP_KEY_PROGRAM_STRUCT.RSVD != 0) #GP(0); IF (TMP_KEY_PROGRAM_STRUCT.KEYID_CTRL.RSVD !=0) #GP(0); 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); (* 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; image/svg+xml } (* 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; } (* Check that only one algorithm is requested for the KeyID and it is one of the activated algorithms *) IF (NUM_BITS(TMP_KEY_PROGRAM_STRUCT.KEYID_CTRL.ENC_ALG) != 1 || (TMP_KEY_PROGRAM_STRUCT.KEYID_CTRL.ENC_ALG & IA32_TME_ACTIVATE. MK_TME_CRYPTO_ALGS == 0)) { RFLAGS.ZF = 1; RAX = INVALID_ENC_ALG; goto EXIT; } (* Try to acquire exclusive lock *) IF (NOT KEY_TABLE_LOCK.ACQUIRE(WRITE)) { //PCONFIG failure RFLAGS.ZF = 1; RAX = DEVICE_BUSY; 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>> image/svg+xml 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, TWEAK_KEY=TMP_RND_TWEAK_KEY, ENCRYPTION_MODE=ENCRYPT_WITH_KEYID_KEY, to MKTME_KEY_TABLE at index TMP_KEY_PROGRAM_STRUCT.KEYID >> break; 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 KD_NO_ENCRYPT: <<Write 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 image/svg+xml Protected Mode Exceptions #GP(0) If input value in EAX encodes an unsupported leaf. If IA32_TME_ACTIVATE MSR is not locked. If hardware encryption and MKTME capability are not enabled in IA32_TME_ACTIVATE MSR. If the memory operand is not 256B aligned. If any of the reserved bits in MKTME_KEY_PROGRAM_STRUCT are set. If a memory operand effective address is outside the DS segment limit. #PF(fault-code) If a page fault occurs in accessing memory operands. #UD If any of the LOCK/REP/OSIZE/VEX prefixes are used. If current privilege level is not 0. If CPUID.7.0:EDX[bit 18] = 0 If in VMX non-root mode and VMCS.PCONFIG_ENABLE = 0. Real-Address Mode Exceptions #GP If input value in EAX encodes an unsupported leaf. If IA32_TME_ACTIVATE MSR is not locked. If hardware encryption and MKTME capability are not enabled in IA32_TME_ACTIVATE MSR. If a memory operand is not 256B aligned. If any of the reserved bits in MKTME_KEY_PROGRAM_STRUCT are set. #UD If any of the LOCK/REP/OSIZE/VEX prefixes are used. If current privilege level is not 0. If CPUID.7.0:EDX.PCONFIG[bit 18] = 0 If in VMX non-root mode and VMCS.PCONFIG_ENABLE = 0. Virtual-8086 Mode Exceptions #UD PCONFIG instruction is not recognized in virtual-8086 mode. Compatibility Mode Exceptions Same exceptions as in protected mode. 64-Bit Mode Exceptions #GP(0)If input value in EAX encodes an unsupported leaf. If IA32_TME_ACTIVATE MSR is not locked. If hardware encryption and MKTME capability are not enabled in IA32_TME_ACTIVATE MSR. If a memory operand is not 256B aligned. If any of the reserved bits in MKTME_KEY_PROGRAM_STRUCT are set. If a memory operand is non-canonical form. #PF(fault-code) If a page fault occurs in accessing memory operands. #UDIf any of the LOCK/REP/OSIZE/VEX prefixes are used. If the current privilege level is not 0. If CPUID.7.0:EDX.PCONFIG[bit 18] = 0. If in VMX non-root mode and VMCS.PCONFIG_ENABLE = 0. This UNOFFICIAL reference was generated from the official Intel® 64 and IA-32 Architectures Software Developer’s Manual by a dumb script. There is no guarantee that some parts aren't mangled or broken and is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .