hv: refactor seed management

New component to maintain seed retrieval and derivation: seed.

1. Retrieve seed from bootloader in Hypervisor's boot stage.
2. Derive virtual seed for Guest/Trusty if need.

Tracked-On: #2724
Signed-off-by: Qi Yadong <yadong.qi@intel.com>
Reviewed-by: Zhu Bing <bing.zhu@intel.com>
This commit is contained in:
Qi Yadong 2019-03-06 13:24:55 +08:00 committed by wenlingz
parent 4d0419ed71
commit 95d1e40283
11 changed files with 572 additions and 131 deletions

View File

@ -131,6 +131,10 @@ C_SRCS += boot/reloc.c
# initilization component
C_SRCS += arch/x86/init.c
C_SRCS += arch/x86/seed/seed.c
C_SRCS += arch/x86/seed/seed_abl.c
C_SRCS += arch/x86/seed/seed_sbl.c
# configuration component
C_SRCS += arch/x86/configs/vm_config.c
ifeq ($(CONFIG_PARTITION_MODE),y)
@ -234,8 +238,6 @@ C_SRCS += bsp/const_dmar.c
C_SRCS += boot/uefi/uefi_boot.c
C_SRCS += boot/sbl/multiboot.c
C_SRCS += boot/sbl/sbl_seed_parse.c
C_SRCS += boot/sbl/abl_seed_parse.c
# retpoline support
ifeq (true, $(shell [ $(GCC_MAJOR) -eq 7 ] && [ $(GCC_MINOR) -ge 3 ] && echo true))

View File

@ -16,6 +16,7 @@
#include <vmx.h>
#include <security.h>
#include <logmsg.h>
#include <seed.h>
#define TRUSTY_VERSION 1U
#define TRUSTY_VERSION_2 2U
@ -30,13 +31,6 @@ struct trusty_mem {
/* The left memory is for trusty's code/data/heap/stack */
} __aligned(PAGE_SIZE);
static struct trusty_key_info g_key_info = {
.size_of_this_struct = sizeof(g_key_info),
.version = 0U,
.platform = 3U,
.num_seeds = 1U
};
/**
* @defgroup trusty_apis Trusty APIs
*
@ -317,95 +311,40 @@ void switch_world(struct acrn_vcpu *vcpu, int32_t next_world)
arch->cur_context = next_world;
}
static inline uint32_t get_max_svn_index(void)
{
uint32_t i, max_svn_idx = 0U;
for (i = 1U; i < g_key_info.num_seeds; i++) {
if (g_key_info.dseed_list[i].cse_svn > g_key_info.dseed_list[i - 1U].cse_svn) {
max_svn_idx = i;
}
}
return max_svn_idx;
}
static bool derive_aek(uint8_t *attkb_key)
{
bool ret = true;
const int8_t salt[] = "Attestation Keybox Encryption Key";
const uint8_t *ikm;
uint32_t ikm_len;
uint32_t max_svn_idx;
if ((attkb_key == NULL) || (g_key_info.num_seeds == 0U) ||
(g_key_info.num_seeds > BOOTLOADER_SEED_MAX_ENTRIES)) {
ret = false;
} else {
max_svn_idx = get_max_svn_index();
ikm = g_key_info.dseed_list[max_svn_idx].seed;
/* only the low 32 bits of seed are valid */
ikm_len = 32U;
if (hmac_sha256(attkb_key, ikm, ikm_len,
(const uint8_t *)salt, sizeof(salt)) != 1) {
pr_err("%s: failed to derive key!\n", __func__);
ret = false;
}
}
return ret;
}
/* Put key_info and trusty_startup_param in the first Page of Trusty
* runtime memory
*/
static bool setup_trusty_info(struct acrn_vcpu *vcpu,
uint32_t mem_size, uint64_t mem_base_hpa)
static bool setup_trusty_info(struct acrn_vcpu *vcpu, uint32_t mem_size, uint64_t mem_base_hpa, uint8_t *rkey)
{
bool ret = true;
uint32_t i;
struct trusty_mem *mem;
struct trusty_key_info *key_info;
struct trusty_key_info key_info;
struct trusty_startup_param startup_param;
mem = (struct trusty_mem *)(hpa2hva(mem_base_hpa));
(void)memset(&key_info, 0U, sizeof(key_info));
stac();
/* copy key_info to the first page of trusty memory */
(void)memcpy_s(&mem->first_page.key_info, sizeof(g_key_info),
&g_key_info, sizeof(g_key_info));
key_info.size_of_this_struct = sizeof(struct trusty_key_info);
key_info.version = 0U;
key_info.platform = 3U;
if (rkey != NULL) {
(void)memcpy_s(key_info.rpmb_key, 64U, rkey, 64U);
(void)memset(rkey, 0U, 64U);
}
(void)memset(&mem->first_page.key_info.dseed_list, 0U,
sizeof(mem->first_page.key_info.dseed_list));
/* Derive dvseed from dseed for Trusty */
key_info = &mem->first_page.key_info;
for (i = 0U; i < g_key_info.num_seeds; i++) {
if (hkdf_sha256(key_info->dseed_list[i].seed,
BUP_MKHI_BOOTLOADER_SEED_LEN,
g_key_info.dseed_list[i].seed,
BUP_MKHI_BOOTLOADER_SEED_LEN,
ret = derive_virtual_seed(&key_info.dseed_list[0U], &key_info.num_seeds,
NULL, 0U,
vcpu->vm->GUID, sizeof(vcpu->vm->GUID)) == 0) {
(void)memset(key_info, 0U, sizeof(struct trusty_key_info));
pr_err("%s: derive dvseed failed!", __func__);
ret = false;
break;
}
key_info->dseed_list[i].cse_svn = g_key_info.dseed_list[i].cse_svn;
}
vcpu->vm->GUID, sizeof(vcpu->vm->GUID));
if (ret == true) {
/* Derive encryption key of attestation keybox from dseed */
ret = derive_attkb_enc_key(key_info.attkb_enc_key);
if (ret == true) {
/* Derive decryption key of attestation keybox from dseed */
if (!derive_aek(key_info->attkb_enc_key)) {
(void)memset(key_info, 0U, sizeof(struct trusty_key_info));
pr_err("%s: derive key of att keybox failed!", __func__);
ret = false;
} else {
/* Prepare trusty startup param */
mem->first_page.startup_param.size_of_this_struct = sizeof(struct trusty_startup_param);
mem->first_page.startup_param.mem_size = mem_size;
mem->first_page.startup_param.tsc_per_ms = CYCLES_PER_MS;
mem->first_page.startup_param.trusty_mem_base = TRUSTY_EPT_REBASE_GPA;
startup_param.size_of_this_struct = sizeof(struct trusty_startup_param);
startup_param.mem_size = mem_size;
startup_param.tsc_per_ms = CYCLES_PER_MS;
startup_param.trusty_mem_base = TRUSTY_EPT_REBASE_GPA;
/* According to trusty boot protocol, it will use RDI as the
* address(GPA) of startup_param on boot. Currently, the startup_param
@ -413,10 +352,19 @@ static bool setup_trusty_info(struct acrn_vcpu *vcpu,
*/
vcpu->arch.contexts[SECURE_WORLD].run_ctx.guest_cpu_regs.regs.rdi
= (uint64_t)TRUSTY_EPT_REBASE_GPA + sizeof(struct trusty_key_info);
stac();
mem = (struct trusty_mem *)(hpa2hva(mem_base_hpa));
(void)memcpy_s(&mem->first_page.key_info, sizeof(struct trusty_key_info),
&key_info, sizeof(key_info));
(void)memcpy_s(&mem->first_page.startup_param, sizeof(struct trusty_startup_param),
&startup_param, sizeof(startup_param));
clac();
}
}
clac();
(void)memset(&key_info, 0U, sizeof(key_info));
return ret;
}
@ -428,7 +376,8 @@ static bool setup_trusty_info(struct acrn_vcpu *vcpu,
static bool init_secure_world_env(struct acrn_vcpu *vcpu,
uint64_t entry_gpa,
uint64_t base_hpa,
uint32_t size)
uint32_t size,
uint8_t *rpmb_key)
{
uint32_t i;
@ -445,15 +394,16 @@ static bool init_secure_world_env(struct acrn_vcpu *vcpu,
vcpu->arch.contexts[SECURE_WORLD].world_msrs[i] = vcpu->arch.guest_msrs[i];
}
return setup_trusty_info(vcpu, size, base_hpa);
return setup_trusty_info(vcpu, size, base_hpa, rpmb_key);
}
bool initialize_trusty(struct acrn_vcpu *vcpu, const struct trusty_boot_param *boot_param)
bool initialize_trusty(struct acrn_vcpu *vcpu, struct trusty_boot_param *boot_param)
{
bool ret = true;
uint64_t trusty_entry_gpa, trusty_base_gpa, trusty_base_hpa;
uint32_t trusty_mem_size;
struct acrn_vm *vm = vcpu->vm;
uint8_t *rpmb_key = NULL;
switch (boot_param->version) {
case TRUSTY_VERSION_2:
@ -461,9 +411,7 @@ bool initialize_trusty(struct acrn_vcpu *vcpu, const struct trusty_boot_param *b
(((uint64_t)boot_param->entry_point_high) << 32U);
trusty_base_gpa = ((uint64_t)boot_param->base_addr) |
(((uint64_t)boot_param->base_addr_high) << 32U);
/* copy rpmb_key from OSloader */
(void)memcpy_s(&g_key_info.rpmb_key[0][0], 64U, &boot_param->rpmb_key[0], 64U);
rpmb_key = boot_param->rpmb_key;
break;
case TRUSTY_VERSION:
trusty_entry_gpa = (uint64_t)boot_param->entry_point;
@ -495,7 +443,7 @@ bool initialize_trusty(struct acrn_vcpu *vcpu, const struct trusty_boot_param *b
/* init secure world environment */
if (init_secure_world_env(vcpu,
(trusty_entry_gpa - trusty_base_gpa) + TRUSTY_EPT_REBASE_GPA,
trusty_base_hpa, trusty_mem_size)) {
trusty_base_hpa, trusty_mem_size, rpmb_key)) {
/* switch to Secure World */
vcpu->arch.cur_context = SECURE_WORLD;
@ -508,23 +456,6 @@ bool initialize_trusty(struct acrn_vcpu *vcpu, const struct trusty_boot_param *b
return ret;
}
void trusty_set_dseed(const void *dseed, uint8_t dseed_num)
{
/* Use fake seed if input param is invalid */
if ((dseed == NULL) || (dseed_num == 0U) ||
(dseed_num > BOOTLOADER_SEED_MAX_ENTRIES)) {
g_key_info.num_seeds = 1U;
(void)memset(&g_key_info.dseed_list[0].seed, 0xA5U,
sizeof(g_key_info.dseed_list[0].seed));
} else {
g_key_info.num_seeds = dseed_num;
(void)memcpy_s(&g_key_info.dseed_list,
sizeof(struct seed_info) * dseed_num,
dseed, sizeof(struct seed_info) * dseed_num);
}
}
void save_sworld_context(struct acrn_vcpu *vcpu)
{
(void)memcpy_s(&vcpu->vm->sworld_snapshot,

View File

@ -15,6 +15,7 @@
#include <vm.h>
#include <logmsg.h>
#include <firmware.h>
#include <seed.h>
/* Push sp magic to top of stack for call trace */
#define SWITCH_TO(rsp, to) \
@ -70,6 +71,8 @@ static void init_primary_cpu_post(void)
init_cpu_post(BOOT_CPU_ID);
init_seed();
init_debug_post(BOOT_CPU_ID);
enter_guest_mode(BOOT_CPU_ID);

View File

@ -0,0 +1,252 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <hypervisor.h>
#include <multiboot.h>
#include <crypto_api.h>
#include <seed.h>
#include "seed_abl.h"
#include "seed_sbl.h"
#define BOOTLOADER_SBL 0U
#define BOOTLOADER_ABL 1U
#define BOOTLOADER_INVD (~0U)
struct seed_argument {
const char *str;
uint32_t bootloader_id;
uint64_t addr;
};
#define SEED_ARG_NUM 4U
static struct seed_argument seed_arg[SEED_ARG_NUM] = {
{ "ImageBootParamsAddr=", BOOTLOADER_SBL, 0UL },
{ "ABL.svnseed=", BOOTLOADER_ABL, 0UL },
{ "dev_sec_info.param_addr=", BOOTLOADER_ABL, 0UL },
{ NULL, BOOTLOADER_INVD, 0UL }
};
static struct physical_seed g_phy_seed;
static uint32_t parse_seed_arg(void)
{
char *cmd_src = NULL;
char *arg, *arg_end;
struct multiboot_info *mbi = NULL;
uint32_t i = SEED_ARG_NUM - 1U;
uint32_t len;
stac();
if (boot_regs[0U] == MULTIBOOT_INFO_MAGIC) {
mbi = (struct multiboot_info *)hpa2hva((uint64_t)boot_regs[1U]);
if (mbi != NULL) {
if ((mbi->mi_flags & MULTIBOOT_INFO_HAS_CMDLINE) != 0U) {
cmd_src = (char *)hpa2hva((uint64_t)mbi->mi_cmdline);
}
}
}
if (cmd_src != NULL) {
for (i = 0U; seed_arg[i].str != NULL; i++) {
len = strnlen_s(seed_arg[i].str, MEM_1K);
arg = strstr_s((const char *)cmd_src, MEM_2K, seed_arg[i].str, len);
if (arg != NULL) {
arg += len;
seed_arg[i].addr = strtoul_hex(arg);
/*
* Replace original arguments with spaces since Guest's GPA might not
* identity mapped to HPA. The argument will be appended later when
* compose cmdline for Guest.
*/
arg_end = strchr(arg, ' ');
arg -= len;
len = (arg_end != NULL) ? (uint32_t)(arg_end - arg) : strnlen_s(arg, MEM_2K);
(void)memset((void *)arg, (char)' ', len);
break;
}
}
}
clac();
return i;
}
/*
* append_seed_arg
*
* description:
* append seed argument to Guest's cmdline
*
* input:
* vm pointer to target VM
*
* output:
* cmd_dst pointer to cmdline for Guest
*
* return value:
* none
*/
void append_seed_arg(char *cmd_dst, bool vm_is_sos)
{
uint32_t i;
char buf[MEM_1K];
if ((cmd_dst != NULL) && vm_is_sos) {
for (i = 0U; seed_arg[i].str != NULL; i++) {
if (seed_arg[i].addr != 0ULL) {
(void)memset(buf, 0U, sizeof(buf));
snprintf(buf, sizeof(buf), "%s0x%X ", seed_arg[i].str,
sos_vm_hpa2gpa(seed_arg[i].addr));
if (seed_arg[i].bootloader_id == BOOTLOADER_SBL) {
struct image_boot_params *boot_params =
(struct image_boot_params *)hpa2hva(seed_arg[i].addr);
boot_params->p_seed_list = sos_vm_hpa2gpa(boot_params->p_seed_list);
boot_params->p_platform_info = sos_vm_hpa2gpa(boot_params->p_platform_info);
}
(void)strncpy_s(cmd_dst, MEM_2K, buf, strnlen_s(buf, MEM_1K));
break;
}
}
}
}
/*
* derive_virtual_seed
*
* description:
* derive virtual seed list from physical seed list
*
* input:
* salt pointer to salt
* salt_len length of salt
* info pointer to info
* info_len length of info
*
* output:
* seed_list pointer to seed_list
* num_seed seed number in seed_list
*
* return value:
* true if derive successfully, otherwise false
*/
bool derive_virtual_seed(struct seed_info *seed_list, uint32_t *num_seeds,
const uint8_t *salt, size_t salt_len, const uint8_t *info, size_t info_len)
{
uint32_t i;
bool ret = true;
if ((seed_list == NULL) || (g_phy_seed.num_seeds == 0U)) {
ret = false;
} else {
for (i = 0U; i < g_phy_seed.num_seeds; i++) {
if (hkdf_sha256(seed_list[i].seed,
sizeof(seed_list[i].seed),
g_phy_seed.seed_list[i].seed,
sizeof(g_phy_seed.seed_list[i].seed),
salt, salt_len,
info, info_len) == 0) {
*num_seeds = 0U;
(void)memset(seed_list, 0U, sizeof(struct seed_info) * BOOTLOADER_SEED_MAX_ENTRIES);
pr_err("%s: derive virtual seed list failed!", __func__);
ret = false;
break;
}
seed_list[i].cse_svn = g_phy_seed.seed_list[i].cse_svn;
}
*num_seeds = g_phy_seed.num_seeds;
}
return ret;
}
static inline uint32_t get_max_svn_index(void)
{
uint32_t i, max_svn_idx = 0U;
for (i = 1U; i < g_phy_seed.num_seeds; i++) {
if (g_phy_seed.seed_list[i].cse_svn > g_phy_seed.seed_list[i - 1U].cse_svn) {
max_svn_idx = i;
}
}
return max_svn_idx;
}
/*
* derive_attkb_enc_key
*
* description:
* derive attestation keybox encryption key from physical seed(max svn)
*
* input:
* none
*
* output:
* out_key pointer to output key
*
* return value:
* true if derive successfully, otherwise false
*/
bool derive_attkb_enc_key(uint8_t *out_key)
{
bool ret = true;
const uint8_t *ikm;
uint32_t ikm_len;
uint32_t max_svn_idx;
const uint8_t salt[] = "Attestation Keybox Encryption Key";
if ((out_key == NULL) || (g_phy_seed.num_seeds == 0U) ||
(g_phy_seed.num_seeds > BOOTLOADER_SEED_MAX_ENTRIES)) {
ret = false;
} else {
max_svn_idx = get_max_svn_index();
ikm = &(g_phy_seed.seed_list[max_svn_idx].seed[0]);
/* only the low 32 bytes of seed are valid */
ikm_len = 32U;
if (hmac_sha256(out_key, ikm, ikm_len, salt, sizeof(salt)) != 1) {
pr_err("%s: failed to derive key!\n", __func__);
ret = false;
}
}
return ret;
}
void init_seed(void)
{
bool status;
uint32_t index;
index = parse_seed_arg();
switch (seed_arg[index].bootloader_id) {
case BOOTLOADER_SBL:
status = parse_seed_sbl(seed_arg[index].addr, &g_phy_seed);
break;
case BOOTLOADER_ABL:
status = parse_seed_abl(seed_arg[index].addr, &g_phy_seed);
break;
default:
status = false;
break;
}
/* Failed to parse seed from Bootloader, using dummy seed */
if (status == false) {
g_phy_seed.num_seeds = 1U;
(void)memset(&g_phy_seed.seed_list[0], 0xA5U, sizeof(g_phy_seed.seed_list));
}
}

View File

@ -0,0 +1,94 @@
/*
* Copyright (C) 2018 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <hypervisor.h>
#include <seed.h>
#include "seed_abl.h"
#define ABL_SEED_LEN 32U
struct abl_seed_info {
uint8_t svn;
uint8_t reserved[3];
uint8_t seed[ABL_SEED_LEN];
};
#define ABL_SEED_LIST_MAX 4U
struct abl_svn_seed {
uint32_t size_of_this_struct;
uint32_t version;
uint32_t num_seeds;
struct abl_seed_info seed_list[ABL_SEED_LIST_MAX];
};
/*
* parse_seed_abl
*
* description:
* This function parse seed_list which provided by ABL.
*
* input:
* cmdline pointer to cmdline string
*
* output:
* phy_seed pointer to physical seed structure
*
* return value:
* true if parse successfully, otherwise false.
*/
bool parse_seed_abl(uint64_t addr, struct physical_seed *phy_seed)
{
uint32_t i;
uint32_t legacy_seed_index = 0U;
struct seed_info *seed_list;
struct abl_svn_seed *abl_seed = (struct abl_svn_seed *)hpa2hva(addr);
bool status = false;
stac();
if ((phy_seed != NULL) && (abl_seed != NULL) &&
(abl_seed->num_seeds >= 2U) && (abl_seed->num_seeds <= ABL_SEED_LIST_MAX)) {
seed_list = phy_seed->seed_list;
/*
* The seed_list from ABL contains several seeds which based on SVN
* and one legacy seed which is not based on SVN. The legacy seed's
* svn value is minimum in the seed list. And CSE ensures at least two
* seeds will be generated which will contain the legacy seed.
* Here find the legacy seed index first.
*/
for (i = 1U; i < abl_seed->num_seeds; i++) {
if (abl_seed->seed_list[i].svn < abl_seed->seed_list[legacy_seed_index].svn) {
legacy_seed_index = i;
}
}
/*
* Copy out abl_seed for trusty and clear the original seed in memory.
* The SOS requires the legacy seed to derive RPMB key. So skip the
* legacy seed when clear original seed.
*/
(void)memset((void *)&phy_seed->seed_list[0U], 0U, sizeof(phy_seed->seed_list));
for (i = 0U; i < abl_seed->num_seeds; i++) {
seed_list[i].cse_svn = abl_seed->seed_list[i].svn;
(void)memcpy_s((void *)&seed_list[i].seed[0U], sizeof(seed_list[i].seed),
(void *)&abl_seed->seed_list[i].seed[0U], sizeof(abl_seed->seed_list[i].seed));
if (i == legacy_seed_index) {
continue;
}
(void)memset((void *)&abl_seed->seed_list[i].seed[0U], 0U,
sizeof(abl_seed->seed_list[i].seed));
}
phy_seed->num_seeds = abl_seed->num_seeds;
status = true;
}
clac();
return status;
}

View File

@ -0,0 +1,12 @@
/*
* Copyright (C) 2018 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef SEED_ABL_H_
#define SEED_ABL_H_
bool parse_seed_abl(uint64_t addr, struct physical_seed *phy_seed);
#endif /* SEED_ABL_H_ */

View File

@ -0,0 +1,118 @@
/*
* Copyright (C) 2018 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <hypervisor.h>
#include <seed.h>
#include "seed_sbl.h"
#define SEED_ENTRY_TYPE_SVNSEED 0x1U
/* #define SEED_ENTRY_TYPE_RPMBSEED 0x2U */
/* #define SEED_ENTRY_USAGE_USEED 0x1U */
#define SEED_ENTRY_USAGE_DSEED 0x2U
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];
};
/*
* parse_seed_sbl
*
* description:
* This function parse seed_list which provided by SBL
*
* input:
* cmdline pointer to cmdline string
*
* return value:
* true if parse successfully, otherwise false.
*/
bool parse_seed_sbl(uint64_t addr, struct physical_seed *phy_seed)
{
uint8_t i;
uint8_t dseed_index = 0U;
struct image_boot_params *boot_params;
struct seed_list_hob *seed_hob = NULL;
struct seed_entry *entry;
struct seed_info *seed_list;
bool status = false;
stac();
boot_params = (struct image_boot_params *)hpa2hva(addr);
if ((boot_params != NULL) || (phy_seed != NULL)) {
seed_hob = (struct seed_list_hob *)hpa2hva(boot_params->p_seed_list);
}
if (seed_hob != NULL) {
status = true;
seed_list = phy_seed->seed_list;
entry = (struct seed_entry *)((uint8_t *)seed_hob + sizeof(struct seed_list_hob));
for (i = 0U; i < seed_hob->total_seed_count; i++) {
if (entry != NULL) {
/* 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) ||
(entry->index >= BOOTLOADER_SEED_MAX_ENTRIES)) {
pr_warn("%s: Invalid seed index.", __func__);
status = false;
break;
}
(void)memcpy_s((void *)&seed_list[dseed_index], sizeof(struct seed_info),
(void *)&entry->seed[0U], sizeof(struct seed_info));
dseed_index++;
/* erase original seed in seed entry */
(void)memset((void *)&entry->seed[0U], 0U, sizeof(struct seed_info));
}
}
entry = (struct seed_entry *)((uint8_t *)entry + entry->seed_entry_size);
}
if (status) {
phy_seed->num_seeds = dseed_index;
}
}
clac();
return status;
}

View File

@ -0,0 +1,20 @@
/*
* Copyright (C) 2018 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef SEED_SBL_H_
#define SEED_SBL_H_
struct image_boot_params {
uint32_t size_of_this_struct;
uint32_t version;
uint64_t p_seed_list;
uint64_t p_platform_info;
uint64_t reserved;
};
bool parse_seed_sbl(uint64_t addr, struct physical_seed *phy_seed);
#endif /* SEED_SBL_H_ */

View File

@ -7,8 +7,7 @@
#include <hypervisor.h>
#include <multiboot.h>
#include <zeropage.h>
#include <sbl_seed_parse.h>
#include <abl_seed_parse.h>
#include <seed.h>
#define ACRN_DBG_BOOT 6U
@ -162,30 +161,16 @@ int32_t sbl_init_vm_boot_info(struct acrn_vm *vm)
if ((mbi->mi_flags & MULTIBOOT_INFO_HAS_CMDLINE) != 0U) {
char *cmd_src, *cmd_dst;
uint32_t off = 0U;
bool status = false;
char buf[MAX_BOOT_PARAMS_LEN];
cmd_dst = kernel_cmdline;
cmd_src = (char *)hpa2hva((uint64_t)mbi->mi_cmdline);
(void)memset(buf, 0U, sizeof(buf));
/*
* The seed passing interface is different for ABL and SBL,
* so here first try to get seed from SBL, if fail then try
* ABL.
* Append seed argument for SOS
*/
status = sbl_seed_parse(is_sos_vm(vm), cmd_src, buf, sizeof(buf));
if (!status) {
status = abl_seed_parse(cmd_src, buf, sizeof(buf));
}
append_seed_arg(cmd_dst, is_sos_vm(vm));
if (status) {
/*
* append the seed argument to kernel cmdline
*/
(void)strncpy_s(cmd_dst, MEM_2K, buf, MAX_BOOT_PARAMS_LEN);
off = strnlen_s(cmd_dst, MEM_2K);
}
cmd_dst += off;
(void)strncpy_s(cmd_dst, MEM_2K - off, (const char *)cmd_src,

View File

@ -131,10 +131,9 @@ struct trusty_startup_param {
};
void switch_world(struct acrn_vcpu *vcpu, int32_t next_world);
bool initialize_trusty(struct acrn_vcpu *vcpu, const struct trusty_boot_param *boot_param);
bool initialize_trusty(struct acrn_vcpu *vcpu, struct trusty_boot_param *boot_param);
void destroy_secure_world(struct acrn_vm *vm, bool need_clr_mem);
void save_sworld_context(struct acrn_vcpu *vcpu);
void restore_sworld_context(struct acrn_vcpu *vcpu);
void trusty_set_dseed(const void *dseed, uint8_t dseed_num);
#endif /* TRUSTY_H_ */

View File

@ -0,0 +1,25 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef SEED_H_
#define SEED_H_
struct physical_seed {
struct seed_info seed_list[BOOTLOADER_SEED_MAX_ENTRIES];
uint32_t num_seeds;
uint32_t pad;
};
void init_seed(void);
void append_seed_arg(char *cmd_dst, bool vm_is_sos);
bool derive_virtual_seed(struct seed_info *seed_list, uint32_t *num_seeds,
const uint8_t *salt, size_t salt_len, const uint8_t *info, size_t info_len);
bool derive_attkb_enc_key(uint8_t *out_key);
#endif /* SEED_H_ */