GETSEC[ENTERACCS]

Execute Authenticated Chipset Code

Opcodes

Hex Mnemonic Encoding Long Mode Legacy Mode Description
0F 37 (EAX = 2) GETSEC[ENTERACCS] None None None Enter authenticated code execution mode. EBX holds the authenticated code module physical base address. ECX holds the authenticated code module size (bytes).

Description

The GETSEC[ENTERACCS] function loads, authenticates and executes an authenticated code module using an Intel® TXT platform chipset's public key. The ENTERACCS leaf of GETSEC is selected with EAX set to 2 at entry.

There are certain restrictions enforced by the processor for the execution of the GETSEC[ENTERACCS] instruction:

Failure to conform to the above conditions results in the processor signaling a general protection exception.

Prior to execution of the ENTERACCS leaf, other logical processors, i.e. RLPs, in the platform must be:

If other logical processor(s) in the same package are not idle in one of these states, execution of ENTERACCS signals a general protection exception. The same requirement and action applies if the other logical processor(s) of the same package do not have CR0.CD = 0.

A successful execution of ENTERACCS results in the ILP entering an authenticated code execution mode. Prior to reaching this point, the processor performs several checks. These include:

The GETSEC[ENTERACCS] function requires two additional input parameters in the general purpose registers EBX and ECX. EBX holds the authenticated code (AC) module physical base address (the AC module must reside below 4 GBytes in physical address space) and ECX holds the AC module size (in bytes). The physical base address and size are used to retrieve the code module from system memory and load it into the internal authenticated code execution area. The base physical address is checked to verify it is on a modulo-4096 byte boundary. The size is verified to be a multiple of 64, that it does not exceed the internal authenticated code execution area capacity (as reported by GETSEC[CAPABILITIES]), and that the top address of the AC module does not exceed 32 bits. An error condition results in an abort of the authenticated code execution launch and the signaling of a general protection exception.

As an integrity check for proper processor hardware operation, execution of GETSEC[ENTERACCS] will also check the contents of all the machine check status registers (as reported by the MSRs IA32_MCi_STATUS) for any valid uncorrectable error condition. In addition, the global machine check status register IA32_MCG_STATUS MCIP bit must be cleared and the IERR processor package pin (or its equivalent) must not be asserted, indicating that no machine check exception processing is currently in progress. These checks are performed prior to initiating the load of the authenticated code module. Any outstanding valid uncorrectable machine check error condition present in these status registers at this point will result in the processor signaling a general protection violation.

The ILP masks the response to the assertion of the external signals INIT#, A20M, NMI#,and SMI#. This masking remains active until optionally unmasked by GETSEC[EXITAC] (this defined unmasking behavior assumes GETSEC[ENTERACCS] was not executed by a prior GETSEC[SENTER]). The purpose of this masking control is to prevent exposure to existing external event handlers that may not be under the control of the authenticated code module..

The ILP sets an internal flag to indicate it has entered authenticated code execution mode. The state of the A20M pin is likewise masked and forced internally to a de-asserted state so that any external assertion is not recognized during authenticated code execution mode.

To prevent other (logical) processors from interfering with the ILP operating in authenticated code execution mode, memory (excluding implicit write-back transactions) access and I/O originating from other processor agents are blocked. This protection starts when the ILP enters into authenticated code execution mode. Only memory and I/O transactions initiated from the ILP are allowed to proceed. Exiting authenticated code execution mode is done by executing GETSEC[EXITAC]. The protection of memory and I/O activities remains in effect until the ILP executes GETSEC[EXITAC].

Prior to launching the authenticated execution module using GETSEC[ENTERACCS] or GETSEC[SENTER], the processor's MTRRs (Memory Type Range Registers) must first be initialized to map out the authenticated RAM addresses as WB (writeback). Failure to do so may affect the ability for the processor to maintain isolation of the loaded authenticated code module. If the processor detected this requirement is not met, it will signal an Intel® TXT reset condition with an error code during the loading of the authenticated code module.

While physical addresses within the load module must be mapped as WB, the memory type for locations outside of the module boundaries must be mapped to one of the supported memory types as returned by GETSEC[PARAMETERS] (or UC as default).

To conform to the minimum granularity of MTRR MSRs for specifying the memory type, authenticated code RAM (ACRAM) is allocated to the processor in 4096 byte granular blocks. If an AC module size as specified in ECX is not a multiple of 4096 then the processor will allocate up to the next 4096 byte boundary for mapping as ACRAM with indeterminate data. This pad area will not be visible to the authenticated code module as external memory nor can it depend on the value of the data used to fill the pad area.

At the successful completion of GETSEC[ENTERACCS], the architectural state of the processor is partially initialized from contents held in the header of the authenticated code module. The processor GDTR, CS, and DS selectors are initialized from fields within the authenticated code module. Since the authenticated code module must be relocatable, all address references must be relative to the authenticated code module base address in EBX. The processor GDTR base value is initialized to the AC module header field GDTBasePtr + module base address held in EBX and the GDTR limit is set to the value in the GDTLimit field. The CS selector is initialized to the AC module header SegSel field, while the DS selector is initialized to CS + 8. The segment descriptor fields are implicitly initialized to BASE=0, LIMIT=FFFFFh, G=1, D=1, P=1, S=1, read/write access for DS, and execute/read access for CS. The processor begins the authenticated code module execution with the EIP set to the AC module header EntryPoint field + module base address (EBX). The AC module based fields used for initializing the processor state are checked for consistency and any failure results in a shutdown condition.

A summary of the register state initialization after successful completion of GETSEC[ENTERACCS] is given for the processor in the following table. The paging is disabledupon entry into authenticated code execution mode. The authenticated code module is loaded and initially executed using physical addresses. It is up to the system software after execution of GETSEC[ENTERACCS] to establish a new (or restore its previous) paging environment with an appropriate mapping to meet new protection requirements. EBP is initialized to the authenticated code module base physical address for initial execution in the authenticated environment. As a result, the authenticated code can reference EBP for relative address based references, given that the authenticated code module must be position independent.

Register State Initialization after GETSEC[ENTERACCS]
Register State Initialization Status Comment
CR0 PG=0, AM=0, WP=0: Others unchanged Paging, Alignment Check, Write-protection are disabled
CR4 MCE=0: Others unchanged Machine Check Exceptions Disabled
EFLAGS 00000002H
IA32_EFER 0H IA-32e mode disabled
EIP AC.base + EntryPoint AC.base is in EBX as input to GETSEC[ENTERACCS]
[E|R]BX Pre-ENTERACCS state: Next [E|R]IP prior to GETSEC[ENTERACCS] Carry forward 64-bit processor state across GETSEC[ENTERACCS]
ECX Pre-ENTERACCS state: [31:16]=GDTR.limit; [15:0]=CS.sel Carry forward processor state across GETSEC[ENTERACCS]
[E|R]DX Pre-ENTERACCS state: GDTR base Carry forward 64-bit processor state across GETSEC[ENTERACCS]
EBP AC.base
CS Sel=[SegSel], base=0, limit=FFFFFh, G=1, D=1, AR=9BH
DS Sel=[SegSel] +8, base=0, limit=FFFFFh, G=1, D=1, AR=93H
GDTR Base = AC.base (EBX) + [GDTBasePtr], Limit=[GDTLimit]
DR7 00000400H
IA32_DEBUGCTL 0H
IA32_MISC_ENABLES See the next table for an example The number of initialized fields may change due to processor implementation

The segmentation related processor state that has not been initialized by GETSEC[ENTERACCS] requires appropriate initialization before use. Since a new GDT context has been established, the previous state of the segment selector values held in ES, SS, FS, GS, TR, and LDTR might not be valid.

The MSR IA32_EFER is also unconditionally cleared as part of the processor state initialized by ENTERACCS. Since paging is disabled upon entering authenticated code execution mode, a new paging environment will have to be reestablished in order to establish IA-32e mode while operating in authenticated code execution mode.

Debug exception and trap related signaling is also disabled as part of GETSEC[ENTERACCS]. This is achieved by resetting DR7, TF in EFLAGs, and the MSR IA32_DEBUGCTL. These debug functions are free to be re-enabled once supporting exception handler(s), descriptor tables, and debug registers have been properly initialized following entry into authenticated code execution mode. Also, any pending single-step trap condition will have been cleared upon entry into this mode.

The IA32_MISC_ENABLES MSR is initialized upon entry into authenticated execution mode. Certain bits of this MSR are preserved because preserving these bits may be important to maintain previously established platform settings (See the footnote for Table 6-5.). The remaining bits are cleared for the purpose of establishing a moreconsistent environment for the execution of authenticated code modules. One of the impacts of initializing this MSR is any previous condition established by the MONITOR instruction will be cleared.

To support the possible return to the processor architectural state prior to execution of GETSEC[ENTERACCS], certain critical processor state is captured and stored in the general- purpose registers at instruction completion. [E|R]BX holds effective address ([E|R]IP) of the instruction that would execute next after GETSEC[ENTERACCS], ECX[15:0] holds the CS selector value, ECX[31:16] holds the GDTR limit field, and [E|R]DX holds the GDTR base field. The subsequent authenticated code can preserve the contents of these registers so that this state can be manually restored if needed, prior to exiting authenticated code execution mode with GETSEC[EXITAC]. For the processor state after exiting authenticated code execution mode, see the description of GETSEC[SEXIT].

IA32_MISC_ENALBES MSR Initialization1 by ENTERACCS and SENTER
Field Bit position Description
Fast strings enable 0 Clear to 0
FOPCODE compatibility mode enable 2 Clear to 0
Thermal monitor enable 3 Set to 1 if other thermal monitor capability is not enabled.2
Split-lock disable 4 Clear to 0
Bus lock on cache line splits disable 8 Clear to 0
Hardware prefetch disable 9 Clear to 0
GV1/2 legacy enable 15 Clear to 0
MONITOR/MWAIT s/m enable 18 Clear to 0
Adjacent sector prefetch disable 19 Clear to 0

The IDTR will also require reloading with a new IDT context after entering authenticated code execution mode, before any exceptions or the external interrupts INTR and NMI can be handled. Since external interrupts are re-enabled at the completion of authenticated code execution mode (as terminated with EXITAC), it is recommended that a new IDT context be established before this point. Until such a new IDT context is established, the programmer must take care in not executing an INT n instruction or any other operation that would result in an exception or trap signaling.

Prior to completion of the GETSEC[ENTERACCS] instruction and after successful authentication of the AC module, the private configuration space of the Intel TXT chipset is unlocked. The authenticated code module alone can gain access to this normally restricted chipset state for the purpose of securing the platform.

Once the authenticated code module is launched at the completion of GETSEC[ENTERACCS], it is free to enable interrupts by setting EFLAGS.IF and enable NMI by execution of IRET. This presumes that it has re-established interrupt handling support through initialization of the IDT, GDT, and corresponding interrupt handling code.

Pseudo Code

(* The state of the internal flag ACMODEFLAG persists across instruction boundary *)
IF (CR4.SMXE = 0)
	#UD;
ELSE
	IF (in VMX non-root operation)
		VM Exit (reason = "GETSEC instruction");
	ELSE
		IF (GETSEC leaf unsupported)
			#UD;
		ELSE
			IF ((in VMX operation) or (CR0.PE = 0) or (CR0.CD = 1) or (CR0.NW = 1) or (CR0.NE = 0) or (CPL>0) or (EFLAGS.VM = 1) or (IA32_APIC_BASE.BSP = 0) or (TXT chipset not present) or (ACMODEFLAG = 1) or (IN_SMM = 1))
				#GP(0);
			FI;
		FI;
	FI;
FI;
FOR I = 0 to IA32_MCG_CAP.COUNT - 1
	IF (IA32_MC[I]_STATUS = uncorrectable error)
		#GP(0);
	FI;
ROF;
IF (IA32_MCG_STATUS.MCIP = 1) or (IERR pin is asserted)
	#GP(0);
FI;
ACBASE = EBX;
ACSIZE = ECX;
IF (((ACBASE MOD 4096) != 0) or ((ACSIZE MOD 64)!= 0) or (ACSIZE < minimum module size) OR (ACSIZE > authenticated RAM capacity)) or ((ACBASE+ACSIZE) > (2^32 -1)))
	#GP(0);
FI;
IF (secondary thread(s) CR0.CD = 1) or ((secondary thread(s) NOT(wait-for-SIPI)) and (secondary thread(s) not in SENTER sleep state)
	#GP(0);
FI;
Mask SMI, INIT, A20M, and NMI external pin events;
IA32_MISC_ENABLE = (IA32_MISC_ENABLE & MASK_CONST *)
(* The hexadecimal value of MASK_CONST may vary due to processor implementations *)
A20M = 0;
IA32_DEBUGCTL = 0;
Invalidate processor TLB(s);
Drain Outgoing Transactions;
ACMODEFLAG = 1;
SignalTXTMessage(ProcessorHold);
Load the internal ACRAM based on the AC module size; (* Ensure that all ACRAM loads hit Write Back memory space *)
IF (ACRAM memory type != WB)
	TXT-SHUTDOWN(#BadACMMType);
FI;
IF (AC module header version isnot supported) OR (ACRAM[ModuleType] <> 2)
	TXT-SHUTDOWN(#UnsupportedACM);
FI;
(* Authenticate the AC Module and shutdown with an error if it fails *)
KEY = GETKEY(ACRAM, ACBASE);
KEYHASH = HASH(KEY);
CSKEYHASH = READ(TXT.PUBLIC.KEY);
IF (KEYHASH <> CSKEYHASH)
	TXT-SHUTDOWN(#AuthenticateFail);
FI;
SIGNATURE = DECRYPT(ACRAM, ACBASE, KEY); (* The value of SIGNATURE_LEN_CONST is implementation-specific *)
FOR I = 0 to SIGNATURE_LEN_CONST - 1 DO
	ACRAM[SCRATCH.I] = SIGNATURE[I];
ROF;
COMPUTEDSIGNATURE = HASH(ACRAM, ACBASE, ACSIZE);
FOR I = 0 to SIGNATURE_LEN_CONST - 1 DO
	ACRAM[SCRATCH.SIGNATURE_LEN_CONST+I] = COMPUTEDSIGNATURE[I];
ROF;
IF (SIGNATURE<>COMPUTEDSIGNATURE)
	TXT-SHUTDOWN(#AuthenticateFail);
FI;
ACMCONTROL = ACRAM[CodeControl];
IF ((ACMCONTROL.0 = 0) and (ACMCONTROL.1 = 1) and (snoop hit to modified line detected on ACRAM load))
	TXT-SHUTDOWN(#UnexpectedHITM);
FI;
IF (ACMCONTROL reserved bits are set)
	TXT-SHUTDOWN(#BadACMFormat);
FI;
IF ((ACRAM[GDTBasePtr] < (ACRAM[HeaderLen] * 4 + Scratch_size)) OR ((ACRAM[GDTBasePtr] + ACRAM[GDTLimit]) >= ACSIZE))
	TXT-SHUTDOWN(#BadACMFormat);
FI;
IF ((ACMCONTROL.0 = 1) and (ACMCONTROL.1 = 1) and (snoop hit to modified line detected on ACRAM load))
	ACEntryPoint = ACBASE+ACRAM[ErrorEntryPoint];
ELSE
	ACEntryPoint = ACBASE+ACRAM[EntryPoint];
FI;
IF ((ACEntryPoint >= ACSIZE) OR (ACEntryPoint < (ACRAM[HeaderLen] * 4 + Scratch_size)))
	TXT-SHUTDOWN(#BadACMFormat);
FI;
IF (ACRAM[GDTLimit] & FFFF0000h)
	TXT-SHUTDOWN(#BadACMFormat);
FI;
IF ((ACRAM[SegSel] > (ACRAM[GDTLimit] - 15)) OR (ACRAM[SegSel] < 8))
	TXT-SHUTDOWN(#BadACMFormat);
FI;
IF ((ACRAM[SegSel].TI = 1) OR (ACRAM[SegSel].RPL!= 0))
	TXT-SHUTDOWN(#BadACMFormat);
	CR0.[PG.AM.WP] = 0;
	CR4.MCE = 0;
	EFLAGS = 00000002h;
	IA32_EFER = 0h;
	[E|R]BX = [E|R]IP of the instruction after GETSEC[ENTERACCS];
	ECX = Pre-GETSEC[ENTERACCS] GDT.limit:CS.sel;
	[E|R]DX = Pre-GETSEC[ENTERACCS] GDT.base;
	EBP = ACBASE;
	GDTR.BASE = ACBASE+ACRAM[GDTBasePtr];
	GDTR.LIMIT = ACRAM[GDTLimit];
	CS.SEL = ACRAM[SegSel];
	CS.BASE = 0;
	CS.LIMIT = FFFFFh;
	CS.G = 1;
	CS.D = 1;
	CS.AR = 9Bh;
	DS.SEL = ACRAM[SegSel]+8;
	DS.BASE = 0;
	DS.LIMIT = FFFFFh;
	DS.G = 1;
	DS.D = 1;
	DS.AR = 93h;
	DR7 = 00000400h;
	IA32_DEBUGCTL = 0;
	SignalTXTMsg(OpenPrivate);
	SignalTXTMsg(OpenLocality3);
	EIP = ACEntryPoint;
END;

Flags Affected

All flags are cleared.

Exceptions

VM-Exit Condition

Exception Description
Reason (GETSEC) If in VMX non-root operation.

64-Bit Mode Exceptions

Exception Description
#GP If AC code module does not reside in physical address below 2^32 -1.
All protected mode exceptions apply.

Compatibility Mode Exceptions

Exception Description
#GP If AC code module does not reside in physical address below 2^32 -1.
All protected mode exceptions apply.

Virtual-8086 Mode Exceptions

Exception Description
#GP(0) GETSEC[ENTERACCS] is not recognized in virtual-8086 mode.
#UD If CR4.SMXE = 0. If GETSEC[ENTERACCS] is not reported as supported by GETSEC[CAPABILITIES].

Real-Address Mode Exceptions

Exception Description
#GP(0) GETSEC[ENTERACCS] is not recognized in real-address mode.
#UD If CR4.SMXE = 0. If GETSEC[ENTERACCS] is not reported as supported by GETSEC[CAPABILITIES].

Protected Mode Exceptions

Exception Description
#GP(0) If CR0.CD = 1 or CR0.NW = 1 or CR0.NE = 0 or CR0.PE = 0 or CPL > 0 or EFLAGS.VM = 1. If a Intel® TXT-capable chipset is not present. If in VMX root operation. If the initiating processor is not designated as the bootstrap processor via the MSR bit IA32_APIC_BASE.BSP. If the processor is already in authenticated code execution mode. If the processor is in SMM. If a valid uncorrectable machine check error is logged in IA32_MC[I]_STATUS. If the authenticated code base is not on a 4096 byte boundary. If the authenticated code size > processor internal authenticated code area capacity. If the authenticated code size is not modulo 64. If other enabled logical processor(s) of the same package CR0.CD = 1. If other enabled logical processor(s) of the same package are not in the wait-for-SIPI or SENTER sleep state.
#UD If CR4.SMXE = 0. If GETSEC[ENTERACCS] is not reported as supported by GETSEC[CAPABILITIES].