From 03f5cbdd7ae473f74761f63a4b7b4b5fe8215cb8 Mon Sep 17 00:00:00 2001 From: Qi Yadong Date: Tue, 5 Jun 2018 10:57:34 +0800 Subject: [PATCH] HV: Parse SeedList HOB Retrieve dseed from SeedList HOB(Hand-Off-Block). SBL passes SeedList HOB to ACRN by MBI modules. Signed-off-by: Qi Yadong Reviewed-by: Zhu Bing Reviewed-by: Wang Kai Acked-by: Eddie Dong --- hypervisor/Makefile | 1 + hypervisor/arch/x86/trusty.c | 17 ++++++ hypervisor/boot/sbl/hob_parse.c | 69 +++++++++++++++++++++++++ hypervisor/boot/sbl/multiboot.c | 5 +- hypervisor/include/arch/x86/hob_parse.h | 46 +++++++++++++++++ hypervisor/include/arch/x86/trusty.h | 2 + 6 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 hypervisor/boot/sbl/hob_parse.c create mode 100644 hypervisor/include/arch/x86/hob_parse.h diff --git a/hypervisor/Makefile b/hypervisor/Makefile index 238a6c7de..c44402c89 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -144,6 +144,7 @@ C_SRCS += bsp/$(PLATFORM)/cmdline.c else ifeq ($(PLATFORM), sbl) C_SRCS += boot/sbl/multiboot.c +C_SRCS += boot/sbl/hob_parse.c endif endif diff --git a/hypervisor/arch/x86/trusty.c b/hypervisor/arch/x86/trusty.c index ff38b5aeb..be0314770 100644 --- a/hypervisor/arch/x86/trusty.c +++ b/hypervisor/arch/x86/trusty.c @@ -419,3 +419,20 @@ bool initialize_trusty(struct vcpu *vcpu, uint64_t param) return false; } + +void trusty_set_dseed(void *dseed, uint8_t dseed_num) +{ + /* Use fake seed if input param is invalid */ + if ((dseed == NULL) || (dseed_num == 0) || + (dseed_num > BOOTLOADER_SEED_MAX_ENTRIES)) { + + g_key_info.num_seeds = 1; + memset(g_key_info.dseed_list[0].seed, 0xA5, + sizeof(g_key_info.dseed_list[0].seed)); + return; + } + + g_key_info.num_seeds = dseed_num; + memcpy_s(&g_key_info.dseed_list, sizeof(struct seed_info) * dseed_num, + dseed, sizeof(struct seed_info) * dseed_num); +} diff --git a/hypervisor/boot/sbl/hob_parse.c b/hypervisor/boot/sbl/hob_parse.c new file mode 100644 index 000000000..c5dee2500 --- /dev/null +++ b/hypervisor/boot/sbl/hob_parse.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2018 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +void parse_seed_list(struct seed_list_hob *seed_hob) +{ + uint8_t i; + uint8_t dseed_index = 0; + struct seed_entry *entry; + struct seed_info dseed_list[BOOTLOADER_SEED_MAX_ENTRIES]; + + if (!seed_hob) { + pr_warn("Invalid seed_list hob pointer. Use fake seed!"); + goto fail; + } + + if (seed_hob->total_seed_count == 0) { + pr_warn("Total seed count is 0. Use fake seed!"); + goto fail; + } + + entry = (struct seed_entry *)((uint8_t *)seed_hob + + sizeof(struct seed_list_hob)); + + for (i = 0; i < seed_hob->total_seed_count; i++) { + /* retrieve dseed */ + if ((SEED_ENTRY_TYPE_SVNSEED == entry->type) && + (SEED_ENTRY_USAGE_DSEED == entry->usage)) { + + /* The seed_entry with same type/usage are always + * arranged by index in order of 0~3. + */ + if (entry->index != dseed_index) { + pr_warn("Index mismatch. Use fake seed!"); + goto fail; + } + + if (entry->index >= BOOTLOADER_SEED_MAX_ENTRIES) { + pr_warn("Index exceed max number!"); + goto fail; + } + + memcpy_s(&dseed_list[dseed_index], + sizeof(struct seed_info), + entry->seed, + sizeof(struct seed_info)); + dseed_index++; + + /* erase original seed in seed entry */ + memset(entry->seed, 0, sizeof(struct seed_info)); + } + + entry = (struct seed_entry *)((uint8_t *)entry + + entry->seed_entry_size); + } + + trusty_set_dseed(dseed_list, dseed_index); + memset(dseed_list, 0, sizeof(dseed_list)); + return; + +fail: + trusty_set_dseed(NULL, 0); + memset(dseed_list, 0, sizeof(dseed_list)); +} diff --git a/hypervisor/boot/sbl/multiboot.c b/hypervisor/boot/sbl/multiboot.c index a9b46644c..cdb34388b 100644 --- a/hypervisor/boot/sbl/multiboot.c +++ b/hypervisor/boot/sbl/multiboot.c @@ -7,6 +7,7 @@ #include #include #include +#include #define BOOT_ARGS_LOAD_ADDR 0x24EFC000 @@ -19,7 +20,7 @@ */ static char kernel_cmdline[MEM_2K]; -/*now modules support: FIRMWARE & RAMDISK */ +/* now modules support: FIRMWARE & RAMDISK & SeedList */ static void parse_other_modules(struct vm *vm, struct multiboot_module *mods, int mods_count) { @@ -73,6 +74,8 @@ static void parse_other_modules(struct vm *vm, vm->sw.linux_info.ramdisk_src_addr = mod_addr; vm->sw.linux_info.ramdisk_load_addr = mod_addr; vm->sw.linux_info.ramdisk_size = mod_size; + } else if (strncmp("SeedList", start, type_len) == 0) { + parse_seed_list(mod_addr); } else { pr_warn("not support mod, cmd: %s", start); } diff --git a/hypervisor/include/arch/x86/hob_parse.h b/hypervisor/include/arch/x86/hob_parse.h new file mode 100644 index 000000000..a5b819975 --- /dev/null +++ b/hypervisor/include/arch/x86/hob_parse.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2018 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef HOB_PARSE_H_ +#define HOB_PARSE_H_ + +#define SEED_ENTRY_TYPE_SVNSEED 0x1 +#define SEED_ENTRY_TYPE_RPMBSEED 0x2 + +#define SEED_ENTRY_USAGE_USEED 0x1 +#define SEED_ENTRY_USAGE_DSEED 0x2 + +struct seed_list_hob { + uint8_t revision; + uint8_t reserved0[3]; + uint32_t buffer_size; + uint8_t total_seed_count; + uint8_t reserved1[3]; +}; + +struct seed_entry { + /* SVN based seed or RPMB seed or attestation key_box */ + uint8_t type; + /* For SVN seed: useed or dseed + * For RPMB seed: serial number based or not + */ + uint8_t usage; + /* index for the same type and usage seed */ + uint8_t index; + uint8_t reserved; + /* reserved for future use */ + uint16_t flags; + /* Total size of this seed entry */ + uint16_t seed_entry_size; + /* SVN seed: struct seed_info + * RPMB seed: uint8_t rpmb_key[key_len] + */ + uint8_t seed[0]; +}; + +void parse_seed_list(struct seed_list_hob *seed_hob); + +#endif /* HOB_PARSE_H_ */ diff --git a/hypervisor/include/arch/x86/trusty.h b/hypervisor/include/arch/x86/trusty.h index 6174ba3d7..7e7036c24 100644 --- a/hypervisor/include/arch/x86/trusty.h +++ b/hypervisor/include/arch/x86/trusty.h @@ -119,5 +119,7 @@ void switch_world(struct vcpu *vcpu, int next_world); bool initialize_trusty(struct vcpu *vcpu, uint64_t param); void destroy_secure_world(struct vm *vm); +void trusty_set_dseed(void *dseed, uint8_t seed_num); + #endif /* TRUSTY_H_ */