PBNDKB
Platform Bind Key to Binary Large Object
stableVMJITAOTinstruction
Encodings
| Opcode | Instruction | Op/En | 64-bit | Compat/Legacy | Description |
|---|---|---|---|---|---|
NP 0F 01 C7 | PBNDKB | ZO | Valid | Invalid | This instruction is used to bind information to a platform by encrypting it with a platform-specific wrapping key. |
Measured cost
Loading measurements from arch-data...
Description
The PBNDKB instruction allows software to bind information to a platform by encrypting it with a platform-specific wrapping key. The encrypted data may later be used by the PCONFIG instruction to configure the total storage encryption (TSE) engine.
The instruction can be executed only in 64-bit mode. The registers RBX and RCX provide input information to the instruction. Executions of PBNDKB may fail for platform-specific reasons. An execution reports failure by setting the ZF flag and loading EAX with a non-zero failure reason; a successful execution clears ZF and EAX.
The instruction operates on 256-byte data structures called bind structures. It reads a bind structure at the linear address in RBX and writes a modified bind structure to the linear address in RCX. The addresses in RBX and RCX must be different from each other and must be 256-byte aligned.
The instruction encrypts a portion of the input bind structure and generates a MAC of parts of that structure. The encrypted data and MAC are written out as part of the output bind structure.
The format of a bind structure is given in Table 4-13.
Bind Structure Format
| Field | Offset (bytes) | Size (bytes) | Comments |
|---|---|---|---|
| MAC | 0 | 16 | Output by PBNDKB as a MAC based on the input bind structure |
| Reserved | 16 | 8 | Reserved; must be zero on input, output as zero |
| IV | 24 | 12 | Initialization vector generated and output by PBNDKB |
| Reserved | 36 | 28 | Reserved; must be zero on input, output as zero |
| BTENCDATA | 64 | 64 | Encryption data (plaintext on input; ciphertext on output) |
| BTDATA | 128 | 128 | Additional control and data (modified but not encrypted) |
Operation
(* #UD if PBNDKB is not enumerated, CPL > 0, or not in 64-bit mode*)
IF CPUID.(EAX=07H, ECX=01H):EBX.PBNDKB[bit 1] = 0 OR CPL > 0 OR not in 64-bit mode
THEN #UD; FI;
(* #GP if pointers are not aligned or overlapping *)
IF RBX = RCX OR RBX is not 256-byte aligned OR RCX is not 256-byte aligned
THEN #GP(0); FI;
Load TMP_BIND_STRUCT from 256 bytes at linear address in RBX;
(* MAC and IV fields might not be read. *)
(* Check TMP_BIND_STRUCT for illegal values *)
IF bytes 23:16 and bytes 63:36 of TMP_BIND_STRUCT are not all zero
THEN #GP(0); FI;
IF TMP_BIND_STRUCT.BTDATA.KEY_GENERATION_CTRL > 1
THEN #GP(0); FI;
IF bytes 127:33 of TMP_BIND_STRUCT.BTDATA are not all zero
THEN #GP(0); FI;
(* Randomize input keys if requested *)
IF TMP_BIND_STRUCT.BTDATA.KEY_GENERATION_CONTROL= 1
THEN
Load RNG_DATA_KEY with a random 256-bit value using hardware RNG;
Load RNG_TWEAK_KEY with a random 256-bit value using hardware RNG;
IF there was insufficient entropy
THEN (* PBNDKB failure *)
RFLAGS.ZF := 1;
RAX := ENTROPY_ERROR; (* failure reason 1 *)
GOTO EXIT;
FI;
(* XOR the input keys with the random keys; this does not modify input bind structure in memory *)
TMP_BIND_STRUCT.BTENCDATA.DATA_KEY := RNG_DATA_KEY XOR TMP_BIND_STRUCT.BTENCDATA.DATA_KEY;
TMP_BIND_STRUCT.BTENCDATA.TWEAK_KEY := RNG_TWEAK_KEY XOR TMP_BIND_STRUCT.BTENCDATA.TWEAK_KEY;
FI;
(* Compute wrapping key from platform key and user challenge *)
PLATFORM_KEY := 256-bit platform-specific key;
WRAPPING_KEY := HMAC_SHA256(PLATFORM_KEY, TMP_BIND_STRUCT.BTDATA.USER_SUPP_CHALLENGE);
(* Generate random data for initialization vector *)
Load TMP_IV with a random 96-bit value using hardware RNG;
IF there was insufficient entropy
THEN (* PBNDKB failure *)
RFLAGS.ZF := 1;
RAX := ENTROPY_ERROR; (* failure reason 1 *)
GOTO EXIT;
FI;
(* Compose 176 bytes of additional authenticated data for use by authenticated decryption *)
AAD := Concatenation of 8 bytes of zeroes, TMP_IV, 28 bytes of zeroes, and TMP_BIND_STRUCT.BTDATA;
ENCRYPT_STRUCT := AES256_GCM_ENC(TMP_BIND_STRUCT.BTENCDATA, WRAPPING_KEY, TMP_IV, AAD, 176);
OUT_BIND_STRUCT.MAC := ENCRYPT_STRUCT.MAC;
OUT_BIND_STRUCT[bytes 23:16] := 0;
OUT_BIND_STRUCT.IV := TMP_IV;
OUT_BIND_STRUCT[bytes 63:36] := 0;
OUT_BIND_STRUCT.BTENCDATA := ENCRYPT_STRUCT.ENC_DATA;
OUT_BIND_STRUCT.BTDATA.USER_SUPP_CHALLENGE := 0;
OUT_BIND_STRUCT.BTDATA.KEY_GENERATION_CTRL := IN_BIND_STRUCT.BTDATA.KEY_GENERATION_CTRL;
OUT_BIND_STRUCT.BTDATA[bytes 127:33] := 0;
(* Save OUT_BIND_STRUCT to memory *)
Store OUT_BIND_STRUCT to 256 bytes at linear address in RCX;
(* Indicate successful completion *)
RAX := 0;
RFLAGS.ZF := 0;
EXIT:
RFLAGS.CF := 0;
RFLAGS.PF := 0;
RFLAGS.AF := 0;
RFLAGS.OF := 0;
RFLAGS.SF := 0;Exceptions
Protected mode
#UD | PBNDKB is not supported in protected mode. |
Real address mode
#UD | PBNDKB is not supported in real-address mode. |
Virtual-8086 mode
#UD | PBNDKB is not supported in virtual-8086 mode. |
Compatibility mode
| Same exceptions as in protected mode. |
64-bit mode
#GP(0) | If the values of RBX and RCX are not both canonical. If RBX or RCX is not 256B aligned. If RBX = RCX. If any of the reserved bytes in the input bind structure are set (including bytes in BTDATA). If the value of the key-generation control in the BTDATA field of the input bind structure is not 0 or 1. #PF(fault-code) If a page fault occurs in accessing memory operands. |
#UD | If any of the LOCK/REP/Operand Size/VEX prefixes are used. If the current privilege level is not 0. If CPUID.07H.01H:EBX.PBNDKB[1] = 0. |