mirror of
https://github.com/intel/linux-sgx
synced 2026-06-08 14:49:32 +00:00
a53adeaab7
Upgraded to OpenSSL 3.0.13. Upgraded to Intel(R) Integrated Performance Primitives (IPP) Cryptography library version 2021.11. Upgraded to Protobuf 3.23.2. Upgraded MbedTLS to 3.5.2. Upgraded Intel DCAP Ring3 Abstraction Layer (R3AAL) library to support ConfigFS-TSM as communication channel between host and guest for TDX remote attestation. Upgraded Intel DCAP Quote Verification Enclave to integrate OpenSSL/SgxSSL 3.0.13. Upgraded new TDX attestation result “TD_RELAUNCH_ADVISED” in Intel DCAP Quote Verification Library (QVL) and Appraisal Engine. Fixed bugs. Signed-off-by: Li, Xun <xun.li@intel.com>
321 lines
11 KiB
C++
321 lines
11 KiB
C++
/*
|
|
* Copyright (C) 2011-2021 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.
|
|
*
|
|
*/
|
|
|
|
|
|
/**
|
|
* File: init_enclave.cpp
|
|
* Description:
|
|
* Initialize enclave by rebasing the image to the enclave base
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include "thread_data.h"
|
|
#include "global_data.h"
|
|
#include "util.h"
|
|
#include "xsave.h"
|
|
#include "sgx_trts.h"
|
|
#include "sgx_lfence.h"
|
|
#include "init_optimized_lib.h"
|
|
#include "trts_internal.h"
|
|
#include "linux/elf_parser.h"
|
|
#include "rts.h"
|
|
#include "trts_util.h"
|
|
#include "se_memcpy.h"
|
|
#include "se_cpu_feature.h"
|
|
#include "se_version.h"
|
|
#include "sgx_mm_rt_abstraction.h"
|
|
// The global cpu feature bits from uRTS
|
|
uint64_t g_cpu_feature_indicator __attribute__((section(RELRO_SECTION_NAME))) = 0;
|
|
int EDMM_supported __attribute__((section(RELRO_SECTION_NAME))) = 0;
|
|
sdk_version_t g_sdk_version __attribute__((section(RELRO_SECTION_NAME))) = SDK_VERSION_1_5;
|
|
uint64_t g_enclave_base __attribute__((section(RELRO_SECTION_NAME))) = 0;
|
|
uint64_t g_enclave_size __attribute__((section(RELRO_SECTION_NAME))) = 0;
|
|
int g_aexnotify_supported __attribute__((section(RELRO_SECTION_NAME))) = 0;
|
|
|
|
|
|
const volatile global_data_t g_global_data __attribute__((section(".niprod"))) = {VERSION_UINT, 1, 2, 3, 4, 5, 6, 0, 0, 0,
|
|
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0,
|
|
{{{0, 0, 0, 0, 0, 0, 0}}}, 0, 0, 0, 0};
|
|
// Make sure to access this with atomics or the {get,set}_enclave_state assembly wrappers.
|
|
uint32_t g_enclave_state __attribute__((section(".nipd"))) = ENCLAVE_INIT_NOT_STARTED;
|
|
|
|
uint32_t g_cpu_core_num __attribute__((section(RELRO_SECTION_NAME))) = 0;
|
|
|
|
extern "C" {
|
|
uintptr_t __stack_chk_guard __attribute__((section(RELRO_SECTION_NAME)))= 0;
|
|
#define __weak_alias(alias,sym) \
|
|
__asm__(".weak " __STRING(alias) " ; " \
|
|
__STRING(alias) " = " __STRING(sym))
|
|
__weak_alias(__intel_security_cookie, __stack_chk_guard);
|
|
}
|
|
|
|
extern sgx_status_t pcl_entry(void* enclave_base,void* ms) __attribute__((weak));
|
|
extern "C" int init_enclave(void *enclave_base, void *ms) __attribute__((section(".nipx")));
|
|
|
|
extern "C" int rsrv_mem_init(void *_rsrv_mem_base, size_t _rsrv_mem_size, size_t _rsrv_mem_min_size);
|
|
#ifndef SE_SIM
|
|
extern "C" int init_rts_emas(size_t rts_base, layout_t *start, layout_t *end);
|
|
extern "C" int sgx_mm_init(size_t, size_t);
|
|
extern "C" int emalloc_init_with_reserved_mem(size_t);
|
|
#endif
|
|
// init_enclave()
|
|
// Initialize enclave.
|
|
// Parameters:
|
|
// [IN] enclave_base - the enclave base address
|
|
// [IN] ms - the marshalling structure passed by uRTS
|
|
// Return Value:
|
|
// 0 - success
|
|
// -1 - fail
|
|
//
|
|
extern "C" int init_enclave(void *enclave_base, void *ms)
|
|
{
|
|
if(enclave_base == NULL || ms == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
if(NULL != pcl_entry)
|
|
{
|
|
// LFENCE before pcl_entry
|
|
sgx_lfence();
|
|
sgx_status_t ret = pcl_entry(enclave_base, ms);
|
|
if(SGX_SUCCESS != ret)
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
// relocation
|
|
if(0 != relocate_enclave(enclave_base))
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
g_enclave_base = (uint64_t)get_enclave_base();
|
|
g_enclave_size = g_global_data.elrange_size;
|
|
//we are not allowed to set enclave_image_address to 0 if elrange is set
|
|
//so if enclave_image_address is 0, it means elrange is not set
|
|
if(g_global_data.enclave_image_address != 0)
|
|
{
|
|
//__ImageBase should be the same as enclave_start_address
|
|
if(g_global_data.enclave_image_address != g_enclave_base)
|
|
{
|
|
abort();
|
|
}
|
|
//if elrange is set, we should set enclave_base to correct value
|
|
g_enclave_base = g_global_data.elrange_start_address;
|
|
}
|
|
|
|
// Check if the ms is outside the enclave.
|
|
// sgx_is_outside_enclave() should be placed after relocate_enclave()
|
|
system_features_t *info = (system_features_t *)ms;
|
|
if(!sgx_is_outside_enclave(info, sizeof(system_features_t)))
|
|
{
|
|
return -1;
|
|
}
|
|
sgx_lfence();
|
|
|
|
system_features_t sys_features = *info;
|
|
size_t offset = 0;
|
|
if(sys_features.system_feature_set[0] & (1ULL<< SYS_FEATURE_EXTEND))
|
|
{
|
|
offset = (sys_features.size < sizeof(sys_features)) ? sys_features.size : sizeof(sys_features);
|
|
}
|
|
else
|
|
{
|
|
// old urts is used to load the enclave and size is not set by urts.
|
|
// So clear these new fields including 'size'
|
|
//
|
|
offset = offsetof(system_features_t, size);
|
|
}
|
|
for(size_t i = 0; i < sizeof(sys_features) - offset; i++)
|
|
{
|
|
// Clean the fields that cannot be recognized by trts
|
|
*((uint8_t *)&sys_features + offset + i) = 0;
|
|
}
|
|
|
|
|
|
g_cpu_core_num = sys_features.cpu_core_num;
|
|
g_sdk_version = sys_features.version;
|
|
if (g_sdk_version == SDK_VERSION_1_5)
|
|
{
|
|
EDMM_supported = 0;
|
|
}
|
|
else if (g_sdk_version >= SDK_VERSION_3_0)
|
|
{
|
|
EDMM_supported = feature_supported((const uint64_t *)sys_features.system_feature_set, 0);
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
g_aexnotify_supported = feature_supported((const uint64_t *)sys_features.system_feature_set, AEXNOTIFY_BIT);
|
|
|
|
if (heap_init(get_heap_base(), get_heap_size(), get_heap_min_size(), EDMM_supported) != SGX_SUCCESS)
|
|
return -1;
|
|
|
|
#ifdef SE_SIM
|
|
memset_s(GET_PTR(void, enclave_base, g_global_data.heap_offset), g_global_data.heap_size, 0, g_global_data.heap_size);
|
|
if(g_global_data.rsrv_size != 0)
|
|
{
|
|
memset_s(GET_PTR(void, enclave_base, g_global_data.rsrv_offset), g_global_data.rsrv_size, 0, g_global_data.rsrv_size);
|
|
}
|
|
#endif
|
|
// xsave
|
|
uint64_t xfrm = get_xfeature_state();
|
|
|
|
// Unset conflict cpu feature bits for legacy cpu features.
|
|
uint64_t cpu_features = (sys_features.cpu_features & ~(INCOMPAT_FEATURE_BIT));
|
|
|
|
if (sys_features.system_feature_set[0] & ((uint64_t)(1ULL << SYS_FEATURE_EXTEND)))
|
|
{
|
|
// The sys_features structure is collected by updated uRTS, so use the updated cpu features instead.
|
|
cpu_features = sys_features.cpu_features_ext;
|
|
}
|
|
|
|
// optimized libs
|
|
if (SDK_VERSION_2_0 < g_sdk_version || sys_features.size != 0)
|
|
{
|
|
if (0 != init_optimized_libs(cpu_features, (uint32_t*)sys_features.cpuinfo_table, xfrm))
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (0 != init_optimized_libs(cpu_features, NULL, xfrm))
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
if ( get_rsrv_size() != 0)
|
|
{
|
|
if(rsrv_mem_init(get_rsrv_base(), get_rsrv_size(), get_rsrv_min_size()) != SGX_SUCCESS)
|
|
return -1;
|
|
}
|
|
|
|
|
|
if(SGX_SUCCESS != sgx_read_rand((unsigned char*)&__stack_chk_guard,
|
|
sizeof(__stack_chk_guard)))
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
extern size_t rsrv_mem_min_size;
|
|
|
|
sgx_status_t do_init_enclave(void *ms, void *tcs)
|
|
{
|
|
#ifdef SE_SIM
|
|
UNUSED(tcs);
|
|
#endif
|
|
void *enclave_base = get_enclave_base();
|
|
if(ENCLAVE_INIT_NOT_STARTED != lock_enclave())
|
|
{
|
|
return SGX_ERROR_UNEXPECTED;
|
|
}
|
|
if(0 != init_enclave(enclave_base, ms))
|
|
{
|
|
return SGX_ERROR_UNEXPECTED;
|
|
}
|
|
|
|
#ifndef SE_SIM
|
|
if (SGX_SUCCESS != do_init_thread(tcs, true))
|
|
{
|
|
return SGX_ERROR_UNEXPECTED;
|
|
}
|
|
|
|
/* for EDMM, we need to accept the trimming of the POST_REMOVE pages. */
|
|
if (EDMM_supported)
|
|
{
|
|
size_t heap_min_size = get_heap_min_size();
|
|
memset_s(GET_PTR(void, enclave_base, g_global_data.heap_offset), heap_min_size, 0, heap_min_size);
|
|
|
|
memset_s(GET_PTR(void, enclave_base, g_global_data.rsrv_offset), rsrv_mem_min_size, 0, rsrv_mem_min_size);
|
|
}
|
|
else
|
|
{
|
|
memset_s(GET_PTR(void, enclave_base, g_global_data.heap_offset), g_global_data.heap_size, 0, g_global_data.heap_size);
|
|
memset_s(GET_PTR(void, enclave_base, g_global_data.rsrv_offset), g_global_data.rsrv_size, 0, g_global_data.rsrv_size);
|
|
}
|
|
#endif
|
|
|
|
set_enclave_state(ENCLAVE_INIT_DONE);
|
|
|
|
#ifndef SE_SIM
|
|
// EDMM initialization makes ocalls which requires ENCLAVE_INIT_DONE being set
|
|
if (EDMM_supported)
|
|
{
|
|
size_t rts_base = (size_t) enclave_base;
|
|
size_t user_base = 0;
|
|
size_t user_end = 0;
|
|
|
|
layout_t *layout_start = (layout_t*)g_global_data.layout_table;
|
|
layout_t *layout_end = (layout_t*)(g_global_data.layout_table + g_global_data.layout_entry_num);
|
|
|
|
// find potential user_region layout
|
|
layout_t *layout = layout_start;
|
|
for (;layout < layout_end; layout++)
|
|
if (layout->entry.id == LAYOUT_ID_USER_REGION)
|
|
break;
|
|
|
|
// there exists user_region layout
|
|
if (layout != layout_end)
|
|
{
|
|
user_base = (size_t)enclave_base + layout->entry.rva;
|
|
user_end = user_base + (((size_t)layout->entry.page_count) << SE_PAGE_SHIFT);
|
|
if(user_base > user_end)
|
|
return SGX_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
if (sgx_mm_init(user_base, user_end))
|
|
return SGX_ERROR_UNEXPECTED;
|
|
|
|
if (emalloc_init_with_reserved_mem(g_global_data.edmm_bk_overhead))
|
|
return SGX_ERROR_UNEXPECTED;
|
|
|
|
int ret = init_rts_emas(rts_base, layout_start, layout);
|
|
if (ret != SGX_SUCCESS) {
|
|
return SGX_ERROR_UNEXPECTED;
|
|
}
|
|
}
|
|
#endif
|
|
return SGX_SUCCESS;
|
|
}
|
|
|