From e6fe602913f7b57672ebce9dbfcd579c5698f69c Mon Sep 17 00:00:00 2001 From: "Frieder Paape, Integritee AG" Date: Thu, 27 Jan 2022 10:31:07 +0100 Subject: [PATCH 1/2] [Pal/Linux-SGX] Remove SGX token dependency for DCAP enclaves The SGX Launch Token (aka EINITTOKEN) file is required for EPID-based (more specifically, for non-FLC-based) SGX platforms. On these platforms, the token file is generated by the Quoting Enclave (QE) right-before the startup of the application in Gramine (Gramine sends a request for generation of the token to QE via the AESM service, using the `gramine-sgx-get-token` Python tool). Later, during enclave initialization at Gramine startup, this token file is read and its contents are provided as an arg to `SGX_IOC_ENCLAVE_INIT` ioctl. However, this token file is not required for DCAP-based (more specifically, for FLC-based) SGX platforms. Previously, Gramine still required to use the `gramine-sgx-get-token` Python tool even on these platforms, which generated a dummy token file. Generating this dummy token file may be problematic: (a) this cannot work on read-only FS mounts, and (b) it requires Python installed on the system. So this commit removes this dummy token file completely on DCAP machines. Co-authored-by: Dmitrii Kuvaiskii Signed-off-by: Frieder Paape, Integritee AG Signed-off-by: Dmitrii Kuvaiskii --- Pal/src/host/Linux-SGX/sgx_framework.c | 6 ++--- Pal/src/host/Linux-SGX/sgx_internal.h | 2 +- Pal/src/host/Linux-SGX/sgx_main.c | 32 ++++++++++++++++---------- python/graminelibos/sgx_get_token.py | 20 ++++------------ 4 files changed, 29 insertions(+), 31 deletions(-) diff --git a/Pal/src/host/Linux-SGX/sgx_framework.c b/Pal/src/host/Linux-SGX/sgx_framework.c index 7627bca89b..46afa73894 100644 --- a/Pal/src/host/Linux-SGX/sgx_framework.c +++ b/Pal/src/host/Linux-SGX/sgx_framework.c @@ -110,13 +110,13 @@ bool is_wrfsbase_supported(void) { return true; } -int create_enclave(sgx_arch_secs_t* secs, sgx_arch_token_t* token) { +int create_enclave(sgx_arch_secs_t* secs, sgx_arch_enclave_css_t* sigstruct) { assert(secs->size && IS_POWER_OF_2(secs->size)); assert(IS_ALIGNED(secs->base, secs->size)); secs->ssa_frame_size = SSA_FRAME_SIZE / g_page_size; /* SECS expects SSA frame size in pages */ - secs->misc_select = token->masked_misc_select_le; - memcpy(&secs->attributes, &token->body.attributes, sizeof(sgx_attributes_t)); + secs->misc_select = sigstruct->body.misc_select; + memcpy(&secs->attributes, &sigstruct->body.attributes, sizeof(sgx_attributes_t)); /* Do not initialize secs->mr_signer and secs->mr_enclave here as they are * not used by ECREATE to populate the internal SECS. SECS's mr_enclave is diff --git a/Pal/src/host/Linux-SGX/sgx_internal.h b/Pal/src/host/Linux-SGX/sgx_internal.h index 7e52b54ea2..ad6f72fc84 100644 --- a/Pal/src/host/Linux-SGX/sgx_internal.h +++ b/Pal/src/host/Linux-SGX/sgx_internal.h @@ -72,7 +72,7 @@ bool is_wrfsbase_supported(void); int read_enclave_token(int token_file, sgx_arch_token_t* token); int read_enclave_sigstruct(int sigfile, sgx_arch_enclave_css_t* sig); -int create_enclave(sgx_arch_secs_t* secs, sgx_arch_token_t* token); +int create_enclave(sgx_arch_secs_t* secs, sgx_arch_enclave_css_t* sigstruct); enum sgx_page_type { SGX_PAGE_SECS, SGX_PAGE_TCS, SGX_PAGE_REG }; int add_pages_to_enclave(sgx_arch_secs_t* secs, void* addr, void* user_addr, unsigned long size, diff --git a/Pal/src/host/Linux-SGX/sgx_main.c b/Pal/src/host/Linux-SGX/sgx_main.c index 351082fbc5..a5ef92a17f 100644 --- a/Pal/src/host/Linux-SGX/sgx_main.c +++ b/Pal/src/host/Linux-SGX/sgx_main.c @@ -14,6 +14,7 @@ #include "asan.h" #include "debug_map.h" #include "gdb_integration/sgx_gdb.h" +#include "gsgx.h" #include "linux_utils.h" #include "pal_internal-arch.h" #include "pal_linux_defs.h" @@ -200,15 +201,20 @@ static int load_enclave_binary(sgx_arch_secs_t* secs, int fd, unsigned long base static int initialize_enclave(struct pal_enclave* enclave, const char* manifest_to_measure) { int ret = 0; int enclave_image = -1; - sgx_arch_token_t enclave_token; - sgx_arch_enclave_css_t enclave_sigstruct; + int enclave_mem = -1; sgx_arch_secs_t enclave_secs; unsigned long enclave_entry_addr; unsigned long enclave_heap_min; + + sgx_arch_enclave_css_t enclave_sigstruct; char* sig_path = NULL; + int sigfile_fd = -1; + + /* Launch Token (aka EINITTOKEN) is used only on EPID (non-FLC-based) platforms and completely + * ignored on DCAP (FLC-based) platforms */ + sgx_arch_token_t enclave_token; char* token_path = NULL; - int sigfile_fd = -1, token_fd = -1; - int enclave_mem = -1; + int token_fd = -1; /* this array may overflow the stack, so we allocate it in BSS */ static void* tcs_addrs[MAX_DBG_THREADS]; @@ -246,6 +252,13 @@ static int initialize_enclave(struct pal_enclave* enclave, const char* manifest_ goto out; } + ret = read_enclave_sigstruct(sigfile_fd, &enclave_sigstruct); + if (ret < 0) { + log_error("Reading enclave sigstruct failed: %d", ret); + goto out; + } + +#ifndef SGX_DCAP token_path = alloc_concat(g_pal_enclave.application_path, -1, ".token", -1); if (!token_path) { ret = -ENOMEM; @@ -266,10 +279,11 @@ static int initialize_enclave(struct pal_enclave* enclave, const char* manifest_ log_error("Reading enclave token failed: %d", ret); goto out; } +#endif #ifdef DEBUG if (enclave->profile_enable) { - if (!(enclave_token.body.attributes.flags & SGX_FLAGS_DEBUG)) { + if (!(enclave_sigstruct.body.attributes.flags & SGX_FLAGS_DEBUG)) { log_error("Cannot use 'sgx.profile' with a production enclave"); ret = -EINVAL; goto out; @@ -288,16 +302,10 @@ static int initialize_enclave(struct pal_enclave* enclave, const char* manifest_ } #endif - ret = read_enclave_sigstruct(sigfile_fd, &enclave_sigstruct); - if (ret < 0) { - log_error("Reading enclave sigstruct failed: %d", ret); - goto out; - } - memset(&enclave_secs, 0, sizeof(enclave_secs)); enclave_secs.base = enclave->baseaddr; enclave_secs.size = enclave->size; - ret = create_enclave(&enclave_secs, &enclave_token); + ret = create_enclave(&enclave_secs, &enclave_sigstruct); if (ret < 0) { log_error("Creating enclave failed: %d", ret); goto out; diff --git a/python/graminelibos/sgx_get_token.py b/python/graminelibos/sgx_get_token.py index 900aee3ecb..21b713c2b2 100644 --- a/python/graminelibos/sgx_get_token.py +++ b/python/graminelibos/sgx_get_token.py @@ -89,20 +89,6 @@ def connect_aesmd(mrenclave, modulus, flags, xfrms): return ret_msg.ret.token -def create_dummy_token(flags, xfrms, misc_select): - ''' - Create dummy token with a few fields initialized with real values and others - with a placeholder ('\\0') - ''' - token = bytearray(304) - - # fields read by create_enclave() in sgx_framework.c - struct.pack_into(' Date: Wed, 1 Jun 2022 02:25:40 -0700 Subject: [PATCH 2/2] fixup! [Pal/Linux-SGX] Remove SGX token dependency for DCAP enclaves Signed-off-by: Dmitrii Kuvaiskii --- Pal/src/host/Linux-SGX/sgx_framework.c | 18 +++++++++++++++--- Pal/src/host/Linux-SGX/sgx_internal.h | 3 ++- Pal/src/host/Linux-SGX/sgx_main.c | 2 +- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/Pal/src/host/Linux-SGX/sgx_framework.c b/Pal/src/host/Linux-SGX/sgx_framework.c index 46afa73894..4d46b033b2 100644 --- a/Pal/src/host/Linux-SGX/sgx_framework.c +++ b/Pal/src/host/Linux-SGX/sgx_framework.c @@ -110,13 +110,25 @@ bool is_wrfsbase_supported(void) { return true; } -int create_enclave(sgx_arch_secs_t* secs, sgx_arch_enclave_css_t* sigstruct) { +int create_enclave(sgx_arch_secs_t* secs, sgx_arch_enclave_css_t* sigstruct, + sgx_arch_token_t* token) { assert(secs->size && IS_POWER_OF_2(secs->size)); assert(IS_ALIGNED(secs->base, secs->size)); - secs->ssa_frame_size = SSA_FRAME_SIZE / g_page_size; /* SECS expects SSA frame size in pages */ - secs->misc_select = sigstruct->body.misc_select; + /* SECS expects SSA frame size in pages */ + secs->ssa_frame_size = SSA_FRAME_SIZE / g_page_size; + + /* DCAP platforms do not use SGX tokens so we get enclave attributes from SIGSTRUCT instead, + * but EPID platforms require SECS to be populated from the SGX token */ +#ifdef SGX_DCAP + __UNUSED(token); + secs->misc_select = sigstruct->body.misc_select; memcpy(&secs->attributes, &sigstruct->body.attributes, sizeof(sgx_attributes_t)); +#else + __UNUSED(sigstruct); + secs->misc_select = token->masked_misc_select_le; + memcpy(&secs->attributes, &token->body.attributes, sizeof(sgx_attributes_t)); +#endif /* Do not initialize secs->mr_signer and secs->mr_enclave here as they are * not used by ECREATE to populate the internal SECS. SECS's mr_enclave is diff --git a/Pal/src/host/Linux-SGX/sgx_internal.h b/Pal/src/host/Linux-SGX/sgx_internal.h index ad6f72fc84..9b0723e177 100644 --- a/Pal/src/host/Linux-SGX/sgx_internal.h +++ b/Pal/src/host/Linux-SGX/sgx_internal.h @@ -72,7 +72,8 @@ bool is_wrfsbase_supported(void); int read_enclave_token(int token_file, sgx_arch_token_t* token); int read_enclave_sigstruct(int sigfile, sgx_arch_enclave_css_t* sig); -int create_enclave(sgx_arch_secs_t* secs, sgx_arch_enclave_css_t* sigstruct); +int create_enclave(sgx_arch_secs_t* secs, sgx_arch_enclave_css_t* sigstruct, + sgx_arch_token_t* token); enum sgx_page_type { SGX_PAGE_SECS, SGX_PAGE_TCS, SGX_PAGE_REG }; int add_pages_to_enclave(sgx_arch_secs_t* secs, void* addr, void* user_addr, unsigned long size, diff --git a/Pal/src/host/Linux-SGX/sgx_main.c b/Pal/src/host/Linux-SGX/sgx_main.c index a5ef92a17f..c80340ee11 100644 --- a/Pal/src/host/Linux-SGX/sgx_main.c +++ b/Pal/src/host/Linux-SGX/sgx_main.c @@ -305,7 +305,7 @@ static int initialize_enclave(struct pal_enclave* enclave, const char* manifest_ memset(&enclave_secs, 0, sizeof(enclave_secs)); enclave_secs.base = enclave->baseaddr; enclave_secs.size = enclave->size; - ret = create_enclave(&enclave_secs, &enclave_sigstruct); + ret = create_enclave(&enclave_secs, &enclave_sigstruct, &enclave_token); if (ret < 0) { log_error("Creating enclave failed: %d", ret); goto out;