Opcode/Instruction | Op/En | 64/32 bit Mode Support | CPUID Feature Flag | Description |
---|---|---|---|---|
EAX = 06H ENCLS[EEXTEND] | IR | V/V | SGX1 | This leaf function measures 256 bytes of an uninitialized enclave page. |
Op/En | EAX | EBX | RCX |
IR | EEXTEND (In) | Effective address of the SECS of the data chunk (In) | Effective address of a 256-byte chunk in the EPC (In) |
This leaf function updates the MRENCLAVE measurement register of an SECS with the measurement of an EXTEND string compromising of “EEXTEND” || ENCLAVEOFFSET || PADDING || 256 bytes of the enclave page. This instruction can only be executed when current privilege level is 0 and the enclave is uninitialized.
RBX contains the effective address of the SECS of the region to be measured. The address must be the same as the one used to add the page into the enclave.
RCX contains the effective address of the 256 byte region of an EPC page to be measured. The DS segment is used to create linear addresses. Segment override is not supported.
EPC[RCX] |
Read access by Enclave |
The instruction faults if any of the following:
RBX points to an address not 4KBytes aligned. | RBX does not resolve to an SECS. |
RBX does not point to an SECS page. | RBX does not point to the SECS page of the data chunk. |
RCX points to an address not 256B aligned. | RCX points to an unused page or a SECS. |
RCX does not resolve in an EPC page. | If SECS is locked. |
If the SECS is already initialized. | May page fault. |
CPL > 0. |
Leaf | Parameter | Base Concurrency Restrictions | ||
---|---|---|---|---|
Access | On Conflict | SGX_CONFLICT VM Exit Qualification | ||
EEXTEND | Target [DS:RCX] | Shared | #GP | |
SECS [DS:RBX] | Concurrent |
Leaf | Parameter | Additional Concurrency Restrictions | |||||
---|---|---|---|---|---|---|---|
vs. EACCEPT, EACCEPTCOPY, EMODPE, EMODPR, EMODT | vs. EADD, EEXTEND, EINIT | vs. ETRACK, ETRACKC | |||||
Access | On Conflict | Access | On Conflict | Access | On Conflict | ||
EEXTEND | Target [DS:RCX] | Concurrent | Concurrent | Concurrent | |||
SECS [DS:RBX] | Concurrent | Exclusive | #GP | Concurrent |
Name | Type | Size (Bits) | Description |
---|---|---|---|
TMP_SECS | 64 | Physical address of SECS of the enclave to which source operand belongs. | |
TMP_ENCLAVEOFFS ET | Enclave Offset | 64 | The page displacement from the enclave base address. |
TMPUPDATEFIELD | SHA256 Buffer | 512 | Buffer used to hold data being added to TMP_SECS.MRENCLAVE. |
TMP_MODE64 := ((IA32_EFER.LMA = 1) && (CS.L = 1));
IF (DS:RBX is not 4096 Byte Aligned)
THEN #GP(0); FI;
IF (DS:RBX does not resolve to an EPC page)
THEN #PF(DS:RBX); FI;
IF (DS:RCX is not 256Byte Aligned)
THEN #GP(0); FI;
IF (DS:RCX does not resolve within an EPC)
THEN #PF(DS:RCX); FI;
(* make sure no other Intel SGX instruction is accessing EPCM *)
IF (Other instructions accessing EPCM)
THEN #GP(0); FI;
IF (EPCM(DS:RCX). VALID = 0)
THEN #PF(DS:RCX); FI;
(* make sure that DS:RCX (DST) is pointing to a PT_REG or PT_TCS or PT_SS_FIRST or PT_SS_REST *)
IF ( (EPCM(DS:RCX).PT ≠ PT_REG) and (EPCM(DS:RCX).PT ≠ PT_TCS)
and (EPCM(DS:RCX).PT ≠ PT_SS_FIRST) and (EPCM(DS:RCX).PT ≠ PT_SS_REST))
THEN #PF(DS:RCX); FI;
TMP_SECS := Get_SECS_ADDRESS();
IF (DS:RBX does not resolve to TMP_SECS)
THEN #GP(0); FI;
(* make sure no other instruction is accessing MRENCLAVE or ATTRIBUTES.INIT *)
IF ( (Other instruction accessing MRENCLAVE) or (Other instructions checking or updating the initialized state of the SECS))
THEN #GP(0); FI;
(* Calculate enclave offset *)
TMP_ENCLAVEOFFSET := EPCM(DS:RCX).ENCLAVEADDRESS - TMP_SECS.BASEADDR;
TMP_ENCLAVEOFFSET := TMP_ENCLAVEOFFSET + (DS:RCX & 0FFFH)
(* Add EEXTEND message and offset to MRENCLAVE *)
TMPUPDATEFIELD[63:0] := 00444E4554584545H; // “EEXTEND”
TMPUPDATEFIELD[127:64] := TMP_ENCLAVEOFFSET;
TMPUPDATEFIELD[511:128] := 0; // 48 bytes
TMP_SECS.MRENCLAVE := SHA256UPDATE(TMP_SECS.MRENCLAVE, TMPUPDATEFIELD)
INC enclave’s MRENCLAVE update counter;
(*Add 256 bytes to MRENCLAVE, 64 byte at a time *)
TMP_SECS.MRENCLAVE := SHA256UPDATE(TMP_SECS.MRENCLAVE, DS:RCX[511:0] );
TMP_SECS.MRENCLAVE := SHA256UPDATE(TMP_SECS.MRENCLAVE, DS:RCX[1023: 512] );
TMP_SECS.MRENCLAVE := SHA256UPDATE(TMP_SECS.MRENCLAVE, DS:RCX[1535: 1024] );
TMP_SECS.MRENCLAVE := SHA256UPDATE(TMP_SECS.MRENCLAVE, DS:RCX[2047: 1536] );
INC enclave’s MRENCLAVE update counter by 4;
None
#GP(0) | If the address in RBX is outside the DS segment limit. |
If RBX points to an SECS page which is not the SECS of the data chunk. | |
If the address in RCX is outside the DS segment limit. | |
If RCX points to a memory location not 256Byte-aligned. | |
If another instruction is accessing MRENCLAVE. | |
If another instruction is checking or updating the SECS. | |
If the enclave is already initialized. | |
#PF(error | code) If a page fault occurs in accessing memory operands. |
If the address in RBX points to a non-EPC page. | |
If the address in RCX points to a page which is not PT_TCS or PT_REG. | |
If the address in RCX points to a non-EPC page. | |
If the address in RCX points to an invalid EPC page. |
#GP(0) | If RBX is non-canonical form. |
If RBX points to an SECS page which is not the SECS of the data chunk. | |
If RCX is non-canonical form. | |
If RCX points to a memory location not 256 Byte-aligned. | |
If another instruction is accessing MRENCLAVE. | |
If another instruction is checking or updating the SECS. | |
If the enclave is already initialized. | |
#PF(error | code) If a page fault occurs in accessing memory operands. |
If the address in RBX points to a non-EPC page. | |
If the address in RCX points to a page which is not PT_TCS or PT_REG. | |
If the address in RCX points to a non-EPC page. | |
If the address in RCX points to an invalid EPC page. |