Trusty TEE¶
Introduction¶
Trusty is a set of software components supporting a Trusted Execution Environment (TEE). TEE is commonly known as an isolated processing environment in which applications can be securely executed irrespective of the rest of the system. For more information about TEE, visit the Trusted Execution Environment wiki page. Trusty consists of:
An operating system (the Trusty OS) that runs on a processor intended to provide a TEE
Drivers for the Android kernel (Linux) to facilitate communication with applications running under the Trusty OS
A set of libraries for Android/Linux systems software to facilitate communication with trusted applications executed within the Trusty OS using the kernel drivers
LK (Little Kernel) is a tiny operating system for small embedded devices, bootloaders, and other environments that need OS primitives such as threads, mutexes, and timers. LK has been chosen as the Trusty OS kernel.
Trusty Architecture¶
Note
The Trusty OS is running in the Secure World in the architecture drawing above.
Trusty Specific Hypercalls¶
The following Hypercall APIs are related to Trusty.
-
int32_t hcall_world_switch(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)¶
Switch vCPU state between Normal/Secure World.
The hypervisor uses this hypercall to do the world switch
The hypervisor needs to:
save current world vCPU contexts, and load the next world vCPU contexts
update
rdi
,rsi
,rdx
,rbx
to next world vCPU contexts
- Parameters
vcpu – Pointer to VCPU data structure
target_vm – not used
param1 – not used
param2 – not used
- Returns
0 on success, non-zero on error.
-
int32_t hcall_initialize_trusty(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)¶
Initialize environment for Trusty-OS on a vCPU.
It is used by the User VM OS bootloader (
User VM OS Loader
) to request ACRN to initialize TrustyThe Trusty memory region range, entry point must be specified
The hypervisor needs to save current vCPU contexts (Normal World)
- Parameters
vcpu – Pointer to vCPU data structure
target_vm – not used
param1 – guest physical address. This gpa points to trusty_boot_param structure
param2 – not used
- Returns
0 on success, non-zero on error.
-
int32_t hcall_save_restore_sworld_ctx(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)¶
Save/Restore Context of Secure World.
- Parameters
vcpu – Pointer to VCPU data structure
target_vm – not used
param1 – not used
param2 – not used
- Returns
0 on success, non-zero on error.
-
int32_t hcall_handle_tee_vcpu_boot_done(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)¶
Handle the TEE boot done signal.
- Parameters
vcpu – Pointer to VCPU data structure
target_vm – not used
param1 – not used
param2 – not used
- Returns
0 on success, non-zero on error.
-
int32_t hcall_switch_ee(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)¶
Switch the execution environment.
- Parameters
vcpu – Pointer to VCPU data structure
target_vm – not used
param1 – not used
param2 – not used
- Returns
0 on success, non-zero on error.
Trusty Boot Flow¶
By design, the User VM OS bootloader will trigger the Trusty boot process. The complete boot flow is illustrated below.
As shown in the above figure, here are some details about the Trusty boot flow processing:
User VM OS bootloader
Load and verify Trusty image from virtual disk
Allocate runtime memory for Trusty
Do ELF relocation of Trusty image and get entry address
Call
hcall_initialize_trusty
with Trusty memory base and entry address
ACRN (
hcall_initialize_trusty
)Save World context for Normal World
Init World context for Secure World (RIP, RSP, EPT, etc.)
Resume to Secure World
Trusty
Booting
Call
hcall_world_switch
to switch back to Normal World if boot completed
ACRN (
hcall_world_switch
)Save World context for the World that caused this
vmexit
(Secure World)Restore World context for next World (Normal World: User VM OS bootloader)
Resume to next World (User VM OS bootloader)
User VM OS bootloader
Continue to boot
EPT Hierarchy¶
As per the Trusty design, Trusty can access the Normal World’s memory, but the Normal World cannot access the Secure World’s memory. The Secure World EPTP page table hierarchy must contain the Normal World GPA address space, while the Trusty world’s GPA address space must be removed from the Normal World EPTP page table hierarchy.
Design¶
Put the Secure World’s GPA to a very high position: 511 GB - 512 GB. The PML4/PDPT for the Trusty World are separated from the Normal World. PD and PT for low memory (< 511 GB) are shared in both the Trusty World’s EPT and the Normal World’s EPT. PD and PT for high memory (>= 511 GB) are valid for the Trusty World’s EPT only.
Benefit¶
The Normal World’s EPT can be modified during runtime. Examples include increasing memory and changing attributes. If such behavior happens, only PD and PT for the Normal World need to be updated.
API¶
-
static void create_secure_world_ept(struct acrn_vm *vm, uint64_t gpa_orig, uint64_t size, uint64_t gpa_rebased)¶
Create Secure World EPT hierarchy.
Create Secure World EPT hierarchy, construct new PML4/PDPT, reuse PD/PT parse from vm->arch_vm->ept
- Parameters
vm – pointer to a VM with 2 Worlds
gpa_orig – original gpa allocated from vSBL
size – LK size (16M by default)
gpa_rebased – gpa rebased to offset xxx (511G_OFFSET)
-
void destroy_secure_world(struct acrn_vm *vm, bool need_clr_mem)¶
-
static void save_world_ctx(struct acrn_vcpu *vcpu, struct ext_context *ext_ctx)¶
-
static void load_world_ctx(struct acrn_vcpu *vcpu, const struct ext_context *ext_ctx)¶
-
static void copy_smc_param(const struct run_context *prev_ctx, struct run_context *next_ctx)¶
-
void switch_world(struct acrn_vcpu *vcpu, int32_t next_world)¶
-
static bool setup_trusty_info(struct acrn_vcpu *vcpu, uint32_t mem_size, uint64_t mem_base_hpa, uint8_t *rkey)¶
-
static bool init_secure_world_env(struct acrn_vcpu *vcpu, uint64_t entry_gpa, uint64_t base_hpa, uint32_t size, uint8_t *rpmb_key)¶
-
bool initialize_trusty(struct acrn_vcpu *vcpu, struct trusty_boot_param *boot_param)¶
-
void save_sworld_context(struct acrn_vcpu *vcpu)¶
-
void restore_sworld_context(struct acrn_vcpu *vcpu)¶