From cc1d532131ef10ccd9ce7170aa002539452097d1 Mon Sep 17 00:00:00 2001 From: Mingqiang Chi Date: Mon, 5 Mar 2018 15:09:30 +0800 Subject: [PATCH] add data structure in vm for enable trusty feature add key info structure add sworld_eptp in vm structure, and rename ept->nworld_eptp add secure world control structure Change-Id: Tracked-On:220921 Signed-off-by: Mingqiang Chi --- hypervisor/arch/x86/ept.c | 12 +-- hypervisor/arch/x86/guest/vm.c | 4 +- hypervisor/arch/x86/mmu.c | 3 +- hypervisor/arch/x86/vmx.c | 2 +- hypervisor/common/hypercall.c | 7 +- hypervisor/include/arch/x86/guest/vm.h | 13 ++- hypervisor/include/arch/x86/hv_arch.h | 1 + hypervisor/include/arch/x86/trusty.h | 132 ++++++++++++++++++++++++ hypervisor/include/public/acrn_common.h | 11 +- 9 files changed, 166 insertions(+), 19 deletions(-) create mode 100644 hypervisor/include/arch/x86/trusty.h diff --git a/hypervisor/arch/x86/ept.c b/hypervisor/arch/x86/ept.c index a56525d24..b566271bf 100644 --- a/hypervisor/arch/x86/ept.c +++ b/hypervisor/arch/x86/ept.c @@ -134,7 +134,7 @@ void free_ept_mem(void *pml4_addr) void destroy_ept(struct vm *vm) { - free_ept_mem(vm->arch_vm.ept); + free_ept_mem(vm->arch_vm.nworld_eptp); free_ept_mem(vm->arch_vm.m2p); } @@ -147,7 +147,7 @@ uint64_t gpa2hpa_check(struct vm *vm, uint64_t gpa, struct map_params map_params; map_params.page_table_type = PT_EPT; - map_params.pml4_base = vm->arch_vm.ept; + map_params.pml4_base = vm->arch_vm.nworld_eptp; map_params.pml4_inverted = vm->arch_vm.m2p; obtain_last_page_table_entry(&map_params, &entry, (void *)gpa, true); @@ -186,7 +186,7 @@ uint64_t hpa2gpa(struct vm *vm, uint64_t hpa) struct map_params map_params; map_params.page_table_type = PT_EPT; - map_params.pml4_base = vm->arch_vm.ept; + map_params.pml4_base = vm->arch_vm.nworld_eptp; map_params.pml4_inverted = vm->arch_vm.m2p; obtain_last_page_table_entry(&map_params, &entry, @@ -536,13 +536,13 @@ int ept_mmap(struct vm *vm, uint64_t hpa, /* Setup memory map parameters */ map_params.page_table_type = PT_EPT; - if (vm->arch_vm.ept) { - map_params.pml4_base = vm->arch_vm.ept; + if (vm->arch_vm.nworld_eptp) { + map_params.pml4_base = vm->arch_vm.nworld_eptp; map_params.pml4_inverted = vm->arch_vm.m2p; } else { map_params.pml4_base = alloc_paging_struct(); - vm->arch_vm.ept = map_params.pml4_base; + vm->arch_vm.nworld_eptp = map_params.pml4_base; map_params.pml4_inverted = alloc_paging_struct(); vm->arch_vm.m2p = map_params.pml4_inverted; } diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index 80519e088..d7bcbd8be 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -132,8 +132,8 @@ int create_vm(struct vm_description *vm_desc, struct vm **rtn_vm) #endif } else { /* populate UOS vm fields according to vm_desc */ - vm->secure_world_enabled = - vm_desc->secure_world_enabled; + vm->sworld_control.sworld_enabled = + vm_desc->sworld_enabled; memcpy_s(&vm->GUID[0], sizeof(vm->GUID), &vm_desc->GUID[0], sizeof(vm_desc->GUID)); diff --git a/hypervisor/arch/x86/mmu.c b/hypervisor/arch/x86/mmu.c index 0b104b112..917676e5c 100644 --- a/hypervisor/arch/x86/mmu.c +++ b/hypervisor/arch/x86/mmu.c @@ -137,7 +137,8 @@ void mmu_invept(struct vcpu *vcpu) struct invept_desc desc = {0}; if (check_invept_single_support()) { - desc.eptp = (uint64_t) vcpu->vm->arch_vm.ept | (3 << 3) | 6; + desc.eptp = (uint64_t) vcpu->vm->arch_vm.nworld_eptp + | (3 << 3) | 6; _invept(INVEPT_TYPE_SINGLE_CONTEXT, desc); } else if (check_invept_global_support()) _invept(INVEPT_TYPE_ALL_CONTEXTS, desc); diff --git a/hypervisor/arch/x86/vmx.c b/hypervisor/arch/x86/vmx.c index a00afead9..db860a56a 100644 --- a/hypervisor/arch/x86/vmx.c +++ b/hypervisor/arch/x86/vmx.c @@ -983,7 +983,7 @@ static void init_exec_ctrl(struct vcpu *vcpu) * TODO: introduce API to make this data driven based * on VMX_EPT_VPID_CAP */ - value64 = ((uint64_t) vm->arch_vm.ept) | (3 << 3) | 6; + value64 = ((uint64_t) vm->arch_vm.nworld_eptp) | (3 << 3) | 6; exec_vmwrite64(VMX_EPT_POINTER_FULL, value64); pr_dbg("VMX_EPT_POINTER: 0x%016llx ", value64); diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c index a3218bf6e..452f54958 100644 --- a/hypervisor/common/hypercall.c +++ b/hypervisor/common/hypercall.c @@ -159,7 +159,8 @@ int64_t hcall_create_vm(struct vm *vm, uint64_t param) } memset(&vm_desc, 0, sizeof(vm_desc)); - vm_desc.secure_world_enabled = cv.secure_world_enabled; + vm_desc.sworld_enabled = + (!!(cv.vm_flag & (SECURE_WORLD_ENABLED))); memcpy_s(&vm_desc.GUID[0], 16, &cv.GUID[0], 16); ret = create_vm(&vm_desc, &target_vm); @@ -541,10 +542,10 @@ int64_t hcall_assign_ptdev(struct vm *vm, uint64_t vmid, uint64_t param) /* create a iommu domain for target VM if not created */ if (!target_vm->iommu_domain) { - ASSERT(target_vm->arch_vm.ept, "EPT of VM not set!"); + ASSERT(target_vm->arch_vm.nworld_eptp, "EPT of VM not set!"); /* TODO: how to get vm's address width? */ target_vm->iommu_domain = create_iommu_domain(vmid, - target_vm->arch_vm.ept, 48); + target_vm->arch_vm.nworld_eptp, 48); ASSERT(target_vm->iommu_domain, "failed to created iommu domain!"); } diff --git a/hypervisor/include/arch/x86/guest/vm.h b/hypervisor/include/arch/x86/guest/vm.h index 5bf65c8e5..6ec3a3840 100644 --- a/hypervisor/include/arch/x86/guest/vm.h +++ b/hypervisor/include/arch/x86/guest/vm.h @@ -109,7 +109,13 @@ struct vm_state_info { struct vm_arch { void *guest_pml4; /* Guest pml4 */ - void *ept; /* EPT hierarchy */ + /* EPT hierarchy for Normal World */ + void *nworld_eptp; + /* EPT hierarchy for Secure World + * Secure world can access Normal World's memory, + * but Normal World can not access Secure World's memory. + */ + void *sworld_eptp; void *m2p; /* machine address to guest physical address */ void *tmp_pg_array; /* Page array for tmp guest paging struct */ void *iobitmap[2];/* IO bitmap page array base address for this VM */ @@ -160,7 +166,7 @@ struct vm { spinlock_t ptdev_lock; unsigned char GUID[16]; - unsigned int secure_world_enabled; + struct secure_world_control sworld_control; }; struct vm_description { @@ -178,7 +184,8 @@ struct vm_description { bool vm_created; /* Index indicating VM's privilege level */ unsigned int vm_state_info_privilege; - unsigned int secure_world_enabled; /* secure_world enabled? */ + /* Whether secure world is enabled for current VM. */ + bool sworld_enabled; }; struct vm_description_array { diff --git a/hypervisor/include/arch/x86/hv_arch.h b/hypervisor/include/arch/x86/hv_arch.h index 4b099b544..64d0b5d23 100644 --- a/hypervisor/include/arch/x86/hv_arch.h +++ b/hypervisor/include/arch/x86/hv_arch.h @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include diff --git a/hypervisor/include/arch/x86/trusty.h b/hypervisor/include/arch/x86/trusty.h new file mode 100644 index 000000000..54ef6529f --- /dev/null +++ b/hypervisor/include/arch/x86/trusty.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2018 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TRUSTY_H_ +#define TRUSTY_H_ + +#define BOOTLOADER_SEED_MAX_ENTRIES 10 +#define RPMB_MAX_PARTITION_NUMBER 6 +#define MMC_PROD_NAME_WITH_PSN_LEN 15 +#define BUP_MKHI_BOOTLOADER_SEED_LEN 64 + +/* Structure of seed info */ +struct seed_info { + uint8_t cse_svn; + uint8_t bios_svn; + uint8_t padding[2]; + uint8_t seed[BUP_MKHI_BOOTLOADER_SEED_LEN]; +}; + +/* Structure of key info */ +struct key_info { + uint32_t size_of_this_struct; + + /* version info: + 0: baseline structure + 1: add ** new field + */ + uint32_t version; + + /* platform: + 0: Dummy (fake secret) + 1: APL (APL + ABL) + 2: ICL (ICL + SBL) + 3: CWP (APL|ICL + SBL + CWP) + 4: Brillo (Android Things) + */ + uint32_t platform; + + /* flags info: + Bit 0: manufacturing state (0:manufacturing done; + 1:in manufacturing mode) + Bit 1: secure boot state (0:disabled; 1: enabled) + Bit 2: test seeds (ICL only - 0:production seeds; 1: test seeds) + other bits all reserved as 0 + */ + uint32_t flags; + + /* Keep 64-bit align */ + uint32_t pad1; + + /* Seed list, include useeds(user seeds) and dseed(device seeds) */ + uint32_t num_seeds; + struct seed_info useed_list[BOOTLOADER_SEED_MAX_ENTRIES]; + struct seed_info dseed_list[BOOTLOADER_SEED_MAX_ENTRIES]; + + /* For ICL+ */ + /* rpmb keys, Currently HMAC-SHA256 is used in RPMB spec + * and 256-bit (32byte) is enough. Hence only lower 32 bytes will be + * used for now for each entry. But keep higher 32 bytes for future + * extension. Note that, RPMB keys are already tied to storage device + * serial number.If there are multiple RPMB partitions, then we will + * get multiple available RPMB keys. And if rpmb_key[n][64] == 0, + * then the n-th RPMB key is unavailable (Either because of no such + * RPMB partition, or because OSloader doesn't want to share + * the n-th RPMB key with Trusty) + */ + uint8_t rpmb_key[RPMB_MAX_PARTITION_NUMBER][64]; + + /* 256-bit AES encryption key to encrypt/decrypt attestation keybox, + this key should be derived from a fixed key which is RPMB seed. + RPMB key (HMAC key) and this encryption key (AES key) are both + derived from the same RPMB seed. + */ + uint8_t attkb_enc_key[32]; + + /* For APL only */ + /* RPMB key is derived with dseed together with this serial number, + * for ICL +, CSE directly provides the rpmb_key which is already + * tied to serial number. Concatenation of emmc product name + * with a string representation of PSN + */ + char serial[MMC_PROD_NAME_WITH_PSN_LEN]; + char pad2; +}; + +struct secure_world_memory { + /* The secure world base address of GPA in SOS */ + uint64_t base_gpa; + /* The secure world base address of HPA */ + uint64_t base_hpa; + /* Secure world runtime memory size */ + uint64_t length; +}; + +struct secure_world_control { + /* Whether secure world is enabled for current VM */ + bool sworld_enabled; + /* key info structure */ + struct key_info key_info; + /* Secure world memory structure */ + struct secure_world_memory sworld_memory; +}; + +#endif /* TRUSTY_H_ */ + diff --git a/hypervisor/include/public/acrn_common.h b/hypervisor/include/public/acrn_common.h index 057e92233..033660756 100644 --- a/hypervisor/include/public/acrn_common.h +++ b/hypervisor/include/public/acrn_common.h @@ -63,6 +63,9 @@ #define REQUEST_READ 0 #define REQUEST_WRITE 1 +/* Generic VM flags from guest OS */ +#define SECURE_WORLD_ENABLED (1<<0) /* Whether secure world is enabled */ + /** * @brief Hypercall * @@ -148,11 +151,13 @@ struct acrn_create_vm { /** the GUID of this VM */ uint8_t GUID[16]; - /** whether Secure World is enabled for this VM */ - uint8_t secure_world_enabled; + /* VM flag bits from Guest OS, now used + * SECURE_WORLD_ENABLED (1<<0) + */ + uint64_t vm_flag; /** Reserved for future use*/ - uint8_t reserved[31]; + uint8_t reserved[24]; } __aligned(8); /**