Opcode/Instruction | Op/En | 64/32-bit Mode | CPUID Feature Flag | Description |
---|---|---|---|---|
F3 0F 38 DC 11:rrr:bbb LOADIWKEY xmm1, xmm2, <EAX>, <XMM0> | A | V/V | KL | Load internal wrapping key from xmm1, xmm2, and XMM0. |
Op/En | Tuple | Operand 1 | Operand 2 | Operand 3 | Operand 4 |
---|---|---|---|---|---|
A | N/A | ModRM:reg (r) | ModRM:r/m (r) | Implicit EAX (r) | Implicit XMM0 (r) |
The LOADIWKEY1 instruction writes the Key Locker internal wrapping key, which is called IWKey. This IWKey is used by the ENCODEKEY* instructions to wrap keys into handles. Conversely, the AESENC/DEC*KL instructions use IWKey to unwrap those keys from the handles and help verify the handle integrity. For security reasons, no instruction is designed to allow software to directly read the IWKey value.
IWKey includes two cryptographic keys as well as metadata. The two cryptographic keys are loaded from register sources so that LOADIWKEY can be executed without the keys ever being in memory.
The key input operands are:
The implicit operand EAX specifies the KeySource and whether backing up the key is permitted:
1. Further details on Key Locker and usage of this instruction can be found here:
IF CPL > 0 // LOADKWKEY only allowed at ring 0 (supervisor mode) THEN #GP (0); FI; IF EAX[4:1] > 1 // Reserved KeySource encoding used THEN #GP (0); FI; IF EAX[31:5] != 0 // Reserved bit in EAX is set THEN #GP (0); FI; IF EAX[0] AND (CPUID.19H.ECX[0] == 0) // NoBackup is not supported on this part THEN #GP (0); FI; IF (EAX[4:1] == 1) AND (CPUID.19H.ECX[1] == 0) // KeySource of 1 is not supported on this part THEN #GP (0); FI; IF (EAX[4:1] == 0) // KeySource of 0 THEN IWKey.Encryption Key[127:0] := SRC2[127:0]: IWKey.Encryption Key[255:128] := SRC1[127:0]; IWKey.IntegrityKey[127:0] := XMM0[127:0]; IWKey.NoBackup = EAX [0]; IWKey.KeySource = EAX [4:1]; RFLAGS.ZF := 0; ELSE // KeySource of 1. See RDSEED definition for details of randomness IF HW_NRND_GEN.ready == 1 // Full-entropy random data from RDSEED hardware block was received THEN IWKey.Encryption Key[127:0] := SRC2[127:0] XOR HW_NRND_GEN.data[127:0]; IWKey.Encryption Key[255:128] := SRC1[127:0] XOR HW_NRND_GEN.data[255:128]; IWKey.IntegrityKey[127:0] := XMM0[127:0] XOR HW_NRND_GEN.data[383:256]; IWKey.NoBackup = EAX [0]; IWKey.KeySource = EAX [4:1]; RFLAGS.ZF := 0; ELSE // Random data was not returned from RDSEED hardware block. IWKey was not loaded RFLAGS.ZF := 1; FI; FI; RFLAGS.OF, SF, AF, PF, CF := 0;
ZF is set to 0 if the operation succeeded and set to 1 if the operation failed due to full-entropy random data not being received from RDSEED. The other arithmetic flags (OF, SF, AF, PF, CF) are cleared to 0.
LOADIWKEY void _mm_loadiwkey(unsigned int ctl, __m128i intkey, __m128i enkey_lo, __m128i enkey_hi);
#GP If CPL > 0. (Does not apply in real-address mode.)
If EAX[4:1] > 1.
If EAX[31:5] != 0.
If (EAX[0] == 1) AND (CPUID.19H.ECX[0] == 0).
If (EAX[4:1] == 1) AND (CPUID.19H.ECX[1] == 0).
#UD If the LOCK prefix is used.
If CPUID.07H:ECX.KL[bit 23] = 0.
If CR4.KL = 0.
If CR0.EM = 1.
If CR4.OSFXSR = 0.
#NM If CR0.TS = 1.