diff --git "a/docs/zh/docs/secGear/\344\275\277\347\224\250switchless\347\211\271\346\200\247.md" "b/docs/zh/docs/secGear/\344\275\277\347\224\250switchless\347\211\271\346\200\247.md" new file mode 100644 index 0000000000000000000000000000000000000000..a7171d4e268621b189a8a55ba6ea22bc3d5e6240 --- /dev/null +++ "b/docs/zh/docs/secGear/\344\275\277\347\224\250switchless\347\211\271\346\200\247.md" @@ -0,0 +1,517 @@ +# 使用switchless特性 + +## switchless特性介绍 +**技术定义:** switchless是一种通过共享内存减少REE与TEE上下文切换及数据拷贝次数,优化REE与TEE交互性能的技术。 + + **典型应用场景:** 传统应用做机密计算改造拆分成非安全侧CA与安全侧TA后 + +- 当CA业务逻辑中存在频繁调用TA接口时,调用中间过程耗时占比较大,严重影响业务性能。 +- 当CA与TA存在频繁大块数据交换时,普通ECALL调用底层会有多次内存拷贝,导致性能低下。 + 针对以上两种典型场景,可以通过switchless优化交互性能,降低机密计算拆分带来的性能损耗,最佳效果可达到与拆分前同等数量级。 + + **支持硬件平台:** + +- Intel SGX +- ARM TrustZone 鲲鹏920 + +## 约束限制 +虽然开启switchless节省了一定时间,但它们需要额外的线程来为调用提供服务。如果工作线程忙于等待消息,将会消耗大量CPU,另外更多的工作线程通常意味着更多的CPU资源竞争和更多的线程上下文切换,反而可能损害性能,所以switchless的最佳配置是经过实际业务模型与性能测试,在资源占用与性能要求中选出平衡点。 + +##特性配置项规格 +用户调用cc_enclave_create创建Enclave时,需在feature参数中传入switchless的特性配置,配置项如下: +``` +typedef struct { + uint32_t num_uworkers; + uint32_t num_tworkers; + uint32_t switchless_calls_pool_size; + uint32_t retries_before_fallback; + uint32_t retries_before_sleep; + uint32_t parameter_num; + uint32_t workers_policy; + uint32_t rollback_to_common; +} cc_sl_config_t; +``` +各配置项规格如下表: + +| 配置项 | 说明 | +| ------------ | ---- | +| num_uworkers | 非安全侧代理工作线程数,用于执行switchless OCALL,当前该字段仅在SGX平台生效,ARM平台可以配置,但是因ARM平台暂不支持OCALL,所以配置后不会生效。
规格:
ARM:最大值:512;最小值:1;默认值:8(当num_uworkers配置为0时,会使用默认参数)
SGX:最大值:4294967295;最小值:1| +| num_tworkers | 安全侧代理工作线程数,用于执行switchless ECALL。
规格:
ARM:最大值:512;最小值:1;默认值:8(当num_tworkers配置为0时,会使用默认参数)
SGX:最大值:4294967295;最小值:1| +| switchless_calls_pool_size | switchless调用任务池的大小,实际可容纳switchless_calls_pool_size * 64个switchless调用任务(例:switchless_calls_pool_size=1,可容纳64个switchless调用任务)。
规格:
ARM:最大值:8;最小值:1;默认值:1(配置为0时)
SGX:最大值:8;最小值:1;默认值:1(当switchless_calls_pool_size配置为0时,会使用默认参数)| +| retries_before_fallback | 执行retries_before_fallback次汇编pause指令后,若switchless调用仍没有被另一侧的代理工作线程执行,就回退到switch调用模式,该字段仅在SGX平台生效。
规格:
SGX:最大值:4294967295;最小值:1;默认值:20000(当retries_before_fallback配置为0时,会使用默认参数)| +| retries_before_sleep | 执行retries_before_sleep次汇编pause指令后,若代理工作线程一直没有等到有任务来,则进入休眠状态,该字段仅在SGX平台生效。
规格:
SGX:最大值:4294967295;最小值:1;默认值:20000(当retries_before_sleep配置为0时,会使用默认参数)| +| parameter_num | switchless函数支持的最大参数个数,该字段仅在ARM平台生效,SGX平台无此限制。
规格:
ARM:最大值:16;最小值:0| +| parameter_num | switchless函数支持的最大参数个数,该字段仅在ARM平台生效。
规格:
ARM:最大值:16;最小值:0| +| workers_policy | switchless代理线程运行模式,该字段仅在ARM平台生效。
规格:
ARM:
WORKERS_POLICY_BUSY:代理线程一直占用CPU资源,无论是否有任务需要处理,适用于对性能要求极高且系统软硬件资源丰富的场景;
WORKERS_POLICY_WAKEUP:代理线程仅在有任务时被唤醒,处理完任务后进入休眠,等待再次被新任务唤醒| +| rollback_to_common | 异步switchless调用失败时是否回退到普通调用,该字段仅在ARM平台生效。
规格:
ARM:0:否,失败时仅返回相应错误码;其他:是,失败时回退到普通调用| + +## switchless开发流程 + +这里给出使用 switchless 特性开发一个 C 语言程序 switchless 的例子,方便用户理解使用 switchless 开发应用程序。 + +基于secGear API开发应用的具体流程请参考[开发secGear应用程序.md](./开发secGear应用程序.md) + +1. 编写 EDL(Enclave Definition Language)文件 + + switchless 函数需添加'transition_using_threads'标识。 + + ```c + enclave { + include "secgear_urts.h" + from "secgear_tstdc.edl" import *; + from "secgear_tswitchless.edl" import *; + trusted { + public int get_string_switchless([out, size=32]char *buf) transition_using_threads; + }; + }; + ``` + +2. 编写顶层文件 CMakeLists.txt + + 编写顶层文件 CMakeLists.txt,置于 switchless 工作目录下,用于配置编译时的处理器架构、所需的 EDL 文件等信息。 + + 其中,EDL_FILE 是 EDL 文件,需用户指定,例子中为 switchless.edl。DPATH 是安全侧加载动态库,配置如例子中所示。 + + ```c + cmake_minimum_required(VERSION 3.10 FATAL_ERROR) + + project(switchless C) + + set(CMAKE_C_STANDARD 99) + + if (NOT DEFINED ENCLAVE) + set(ENCLAVE "SGX") + endif() + set(SGX_SDK_DEFAULT_PATH /opt/intel/sgxsdk) + set(GP_SDK_DEFAULT_PATH /opt/itrustee_sdk) + set(PL_SDK_DEFAULT_PATH /root/dev/sdk) + + set(SGX_SSL_DEFAULT_PATH /opt/intel/sgxssl) + set(GP_SSL_DEFAULT_PATH /opt/itrustee_sdk/itrustee_sdk_ssl) + + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) + + if(${ENCLAVE} STREQUAL "GP") + if (NOT DEFINED SDK_PATH) + set(iTrusteeSDK ${GP_SDK_DEFAULT_PATH}) + else() + set(iTrusteeSDK ${SDK_PATH}) + endif() + message("Current Platform: ARM Trustzone, iTrustee SDK PATH:${iTrusteeSDK}") + if(NOT IS_DIRECTORY ${iTrusteeSDK}) + message(FATAL_ERROR "Please provide the correct iTrusteeSDK path") + endif() + set(CC_GP ON) + endif() + + if(${ENCLAVE} STREQUAL "SGX") + if (NOT DEFINED SDK_PATH) + set(SGXSDK ${SGX_SDK_DEFAULT_PATH}) + else() + set(SGXSDK ${SDK_PATH}) + endif() + message("Current Platform: Intel SGX, SGX SDK PATH:${SGXSDK}") + if(NOT IS_DIRECTORY ${SGXSDK}) + message(FATAL_ERROR "Please provide the correct SGXSDK path") + endif() + set(CC_SGX ON) + endif() + + if(${ENCLAVE} STREQUAL "PL") + if (NOT DEFINED SDK_PATH) + set(PLSDK ${PL_SDK_DEFAULT_PATH}) + else() + set(PLSDK ${SDK_PATH}) + endif() + message("Current Platform: RISC-V, Penglai SDK PATH:${PLSDK}") + if(NOT IS_DIRECTORY ${PLSDK}) + message(FATAL_ERROR "Please provide the correct Penglai SDK path") + endif() + set(CC_PL ON) + endif() + + set(CURRENT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) + + #set edl name + set(EDL_FILE switchless.edl) + set(CODEGEN codegen) + + if(CC_GP) + set(CODETYPE trustzone) + set(UUID ebc87fc2-05dc-41b3-85b9-f9f0ef481bad) + add_definitions(-DPATH="${LOCAL_ROOT_PATH_INSTALL}/data/${UUID}.sec") + endif() + + if(CC_SGX) + set(CODETYPE sgx) + add_definitions(-DPATH="${CMAKE_CURRENT_BINARY_DIR}/enclave/enclave.signed.so") + endif() + + add_subdirectory(${CURRENT_ROOT_PATH}/enclave) + add_subdirectory(${CURRENT_ROOT_PATH}/host) + + ``` + +3. 编写非安全侧代码和 CMakeLists.txt + + 3.1 编写 main.c + + 使用 cc_enclave_create 创建安全区 enclave 上下文时,需在 features 参数中传入 switchless 特性配置。使能 switchless 特性的主要工作有:创建任务池,大小由配置中的 switchless_call_pool_size 决定;根据 num_uworkers / num_tworkers 创建 Untrust / Trust 工作线程池等。 + + ```c + #include + #include + #include + #include + #include + #include "enclave.h" + #include "secgear_uswitchless.h" + #include "secgear_shared_memory.h" + #include "switchless_u.h" + + #define BUF_LEN 32 + + int main() + { + int retval = 0; + char *path = PATH; + char buf[BUF_LEN]; + cc_enclave_t *context = NULL; + context = (cc_enclave_t *)malloc(sizeof(cc_enclave_t)); + cc_enclave_result_t res = CC_FAIL; + char real_p[PATH_MAX]; + + /* switchless configuration */ + cc_sl_config_t sl_cfg = CC_USWITCHLESS_CONFIG_INITIALIZER; + sl_cfg.num_tworkers = 2; /* 2 tworkers */ + sl_cfg.sl_call_pool_size_qwords = 2; /* 2 * 64 tasks */ + enclave_features_t features = {ENCLAVE_FEATURE_SWITCHLESS, (void *)&sl_cfg}; + + res = cc_enclave_create(real_p, AUTO_ENCLAVE_TYPE, 0, SECGEAR_DEBUG_FLAG, &features, 1, context); + ... + + char *shared_buf = (char *)cc_malloc_shared_memory(context, BUF_LEN); + ... + + /* switchless ecall */ + res = get_string_switchless(context, &retval, shared_buf); + if (res != CC_SUCCESS || retval != (int)CC_SUCCESS) { + printf("Switchless ecall error\n"); + } else { + printf("shared_buf: %s\n", shared_buf); + } + + res = cc_free_shared_memory(context, shared_buf); + ... + + res = cc_enclave_destroy(context); + ... + + return res; + } + ``` + [异步switchless调用](https://gitee.com/openeuler/secGear/blob/master/examples/switchless_performance/host/main.c),在调用ecall函数处变化有如下2点: + - 发起异步调用 + ```c + /* async switchless ecall */ + res = get_string_switchless_async(context, &task_id, &retval, shared_buf); + ... + ``` + - 查询异步调用结果 + ```c + /* 根据上一步返回的task_id, 查询异步调用结果 */ + ret = cc_sl_get_async_result(context, task_id, &retval); + ... + ``` + + 3.2 编写非安全侧 CMakeLists.txt + + ```c + # 设置编译环境变量 + #set auto code prefix + set(PREFIX switchless) + #set host exec name + set(OUTPUT secgear_switchless) + #set host src code + set(SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/main.c) + + # 使用代码生成工具生成辅助代码。CODEGEN 和 CODETYPE 变量也在顶层 CMakeLists.txt 中定义。--search-path 用于指定 switchless.edl 中导入依赖的其他 EDL 文件路径 + # set auto code + if(CC_GP) + set(AUTO_FILES ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_u.h + ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_u.c + ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_args.h) + add_custom_command(OUTPUT ${AUTO_FILES} + DEPENDS ${CURRENT_ROOT_PATH}/${EDL_FILE} + COMMAND ${CODEGEN} --${CODETYPE} + --untrusted ${CURRENT_ROOT_PATH}/${EDL_FILE} + --search-path /usr/include/secGear) + endif() + + if(CC_SGX) + set(AUTO_FILES ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_u.h ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_u.c) + add_custom_command(OUTPUT ${AUTO_FILES} + DEPENDS ${CURRENT_ROOT_PATH}/${EDL_FILE} + COMMAND ${CODEGEN} --${CODETYPE} + --untrusted ${CURRENT_ROOT_PATH}/${EDL_FILE} + --search-path /usr/include/secGear + --search-path ${SGXSDK}/include) + endif() + + # 设置编译选项和链接选项 + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE -L/usr/lib64") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -s") + + # 编译链接引用目录 + if(CC_GP) + if(${CMAKE_VERSION} VERSION_LESS "3.13.0") + link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) + endif() + add_executable(${OUTPUT} ${SOURCE_FILE} ${AUTO_FILES}) + target_include_directories(${OUTPUT} PRIVATE ${CMAKE_BINARY_DIR}/host + /usr/include/secGear + ${CMAKE_CURRENT_BINARY_DIR}) + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0") + target_link_directories(${OUTPUT} PRIVATE /usr/lib64 ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) + endif() + endif() + + if(CC_SGX) + if(${CMAKE_VERSION} VERSION_LESS "3.13.0") + link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) + endif() + add_executable(${OUTPUT} ${SOURCE_FILE} ${AUTO_FILES}) + target_include_directories(${OUTPUT} PRIVATE /usr/include/secGear + /opt/intel/sgxsdk/include + ${CMAKE_CURRENT_BINARY_DIR}) + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0") + target_link_directories(${OUTPUT} PRIVATE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${SGXSDK}/lib64) + endif() + endif() + + if(CC_SIM) + target_link_libraries(${OUTPUT} secgearsim pthread) + else() + if(CC_GP) + target_link_libraries(${OUTPUT} secgear pthread) + endif() + if(CC_SGX) + target_link_libraries(${OUTPUT} secgear pthread -Wl,--whole-archive -lsgx_uswitchless -Wl,--no-whole-archive -lsgx_urts) + endif() + endif() + + # 指定二进制安装目录 + set_target_properties(${OUTPUT} PROPERTIES SKIP_BUILD_RPATH TRUE) + if(CC_GP) + install(TARGETS ${OUTPUT} + RUNTIME + DESTINATION ${LOCAL_ROOT_PATH_INSTALL}/vendor/bin/ + PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ) + endif() + + if(CC_SGX) + install(TARGETS ${OUTPUT} + RUNTIME + DESTINATION ${CMAKE_BINARY_DIR}/bin/ + PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ) + endif() + + ``` + +4. 编写安全侧代码、CMakeLists.txt 和配置文件,放在 enclave 目录 + + 4.1 编写安全侧代码 enclave.c + + ```c + #include + #include + #include "switchless_t.h" + + #define TA_HELLO_WORLD "secgear hello world!" + #define BUF_MAX 32 + + int get_string_switchless(char *shared_buf) + { + strncpy(shared_buf, TA_HELLO_WORLD, strlen(TA_HELLO_WORLD) + 1); + return 0; + } + + ``` + + 4.2 编写安全侧 CMakeLists.txt + + ``` + #set auto code prefix + set(PREFIX switchless) + + #set sign key + set(PEM Enclave_private.pem) + + #set sign tool + set(SIGN_TOOL sign_tool.sh) + + #set enclave src code + set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/enclave.c) + + #set log level + set(PRINT_LEVEL 3) + add_definitions(-DPRINT_LEVEL=${PRINT_LEVEL}) + + # WHITE_LIST_x:为设置iTrustee的二进制白名单,用来设置哪些非安全侧的二进制可以调用安全侧的动态库。 + # WHITE_LIST_OWNER:设置运行二进制所属的用户权限,只有该用户才可以调用安全侧动态库。 + if(CC_GP) + #set signed output + set(OUTPUT ${UUID}.sec) + set(WHITE_LIST_0 ${LOCAL_ROOT_PATH_INSTALL}/vendor/bin/secgear_switchless) + set(WHITE_LIST_OWNER root) + set(WHITELIST WHITE_LIST_0) + + set(AUTO_FILES ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_t.h + ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_t.c + ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_args.h) + + add_custom_command(OUTPUT ${AUTO_FILES} + DEPENDS ${CURRENT_ROOT_PATH}/${EDL_FILE} + COMMAND ${CODEGEN} --${CODETYPE} + --trusted ${CURRENT_ROOT_PATH}/${EDL_FILE} + --search-path /usr/include/secGear) + endif() + + # SGX 安全侧动态库签名 + if(CC_SGX) + set(OUTPUT enclave.signed.so) + set(AUTO_FILES ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_t.h ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_t.c) + add_custom_command(OUTPUT ${AUTO_FILES} + DEPENDS ${CURRENT_ROOT_PATH}/${EDL_FILE} + COMMAND ${CODEGEN} --${CODETYPE} + --trusted ${CURRENT_ROOT_PATH}/${EDL_FILE} + --search-path /usr/include/secGear + --search-path ${SGXSDK}/include) + endif() + + # 设置编译选项 + set(COMMON_C_FLAGS "-W -Wall -Werror -fno-short-enums -fno-omit-frame-pointer -fstack-protector-strong \ + -Wstack-protector --param ssp-buffer-size=4 -frecord-gcc-switches -Wextra -nostdinc -nodefaultlibs \ + -fno-peephole -fno-peephole2 -Wno-main -Wno-error=unused-parameter -D_FORTIFY_SOURCE=2 -O2 \ + -Wno-error=unused-but-set-variable -L/usr/lib64 -Wno-error=format-truncation=") + set(COMMON_C_LINK_FLAGS "-Wl,-z,now -Wl,-z,relro -Wl,-z,noexecstack -Wl,-nostdlib -nodefaultlibs -nostartfiles") + + # itrustee 需生成 manifest.txt。指定 itrustee 编译选项和头文件、链接文件的搜索路径 + if(CC_GP) + set(CMAKE_C_FLAGS "${COMMON_C_FLAGS} -march=armv8-a") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -s -fPIC") + set(CMAKE_SHARED_LINKER_FLAGS "${COMMON_C_LINK_FLAGS} -Wl,-s") + + set(ITRUSTEE_TEEDIR ${iTrusteeSDK}/) + set(ITRUSTEE_LIBC ${iTrusteeSDK}/thirdparty/open_source/musl/libc) + + if(${CMAKE_VERSION} VERSION_LESS "3.13.0") + link_directories(${CMAKE_BINARY_DIR}/lib/) + endif() + + add_library(${PREFIX} SHARED ${SOURCE_FILES} ${AUTO_FILES}) + + target_include_directories( ${PREFIX} PRIVATE ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_BINARY_DIR}/enclave + /usr/include/secGear + ${ITRUSTEE_TEEDIR}/include/TA + ${ITRUSTEE_TEEDIR}/include/TA/huawei_ext + ${ITRUSTEE_LIBC}/arch/aarch64 + ${ITRUSTEE_LIBC}/ + ${ITRUSTEE_LIBC}/arch/arm/bits + ${ITRUSTEE_LIBC}/arch/generic + ${ITRUSTEE_LIBC}/arch/arm) + + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0") + target_link_directories(${PREFIX} PUBLIC /usr/lib64) + endif() + + foreach(WHITE_LIST ${WHITELIST}) + add_definitions(-D${WHITE_LIST}="${${WHITE_LIST}}") + endforeach(WHITE_LIST) + add_definitions(-DWHITE_LIST_OWNER="${WHITE_LIST_OWNER}") + + target_link_libraries(${PREFIX} secgear_tee) + + #for trustzone compiling, you should connact us to get config and private_key.pem for test, so we will not sign and install binary in this example # + add_custom_command(TARGET ${PREFIX} + POST_BUILD + COMMAND bash ${SIGN_TOOL} -d sign + -x trustzone + -i ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${PREFIX}.so + -c ${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt + -m ${CMAKE_CURRENT_SOURCE_DIR}/config_cloud.ini + -o ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${OUTPUT}) + + install(FILES ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${OUTPUT} + #DESTINATION /data + DESTINATION ${LOCAL_ROOT_PATH_INSTALL}/data + PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) + endif() + + if(CC_SGX) + set(SGX_DIR ${SGXSDK}) + set(CMAKE_C_FLAGS "${COMMON_C_FLAGS} -m64 -fvisibility=hidden") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -s") + set(LINK_LIBRARY_PATH ${SGX_DIR}/lib64) + + if(CC_SIM) + set(Trts_Library_Name sgx_trts_sim) + set(Service_Library_Name sgx_tservice_sim) + else() + set(Trts_Library_Name sgx_trts) + set(Service_Library_Name sgx_tservice) + endif() + + set(Crypto_Library_Name sgx_tcrypto) + + set(CMAKE_SHARED_LINKER_FLAGS "${COMMON_C_LINK_FLAGS} -Wl,-z,defs -Wl,-pie -Bstatic -Bsymbolic -eenclave_entry \ + -Wl,--export-dynamic -Wl,--defsym,__ImageBase=0 -Wl,--gc-sections \ + -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/Enclave.lds") + + if(${CMAKE_VERSION} VERSION_LESS "3.13.0") + link_directories(${LINK_LIBRARY_PATH}) + endif() + + add_library(${PREFIX} SHARED ${SOURCE_FILES} ${AUTO_FILES}) + + target_include_directories(${PREFIX} PRIVATE ${CMAKE_CURRENT_BINARY_DIR} + /usr/include/secGear + ${SGX_DIR}/include/tlibc + ${SGX_DIR}/include/libcxx + ${SGX_DIR}/include) + + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0") + target_link_directories(${PREFIX} PRIVATE ${LINK_LIBRARY_PATH}) + endif() + + target_link_libraries(${PREFIX} -Wl,--whole-archive -lsgx_tswitchless ${Trts_Library_Name} -Wl,--no-whole-archive -Wl,--start-group + -lsgx_tstdc -lsgx_tcxx -l${Crypto_Library_Name} -l${Service_Library_Name} -Wl,--end-group) + add_custom_command(TARGET ${PREFIX} + POST_BUILD + COMMAND umask 0177 + COMMAND openssl genrsa -3 -out ${PEM} 3072 + COMMAND bash ${SIGN_TOOL} -d sign + -x sgx + -i ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${PREFIX}.so + -k ${PEM} + -o ${OUTPUT} + -c ${CMAKE_CURRENT_SOURCE_DIR}/Enclave.config.xml) + endif() + + if(NOT DEFINED CC_PL) + set_target_properties(${PREFIX} PROPERTIES SKIP_BUILD_RPATH TRUE) + endif() + ``` + +## 常见问题 +- sgx环境下开启switchless特性创建enclave后,直接销毁enclave,再使用enclave会产生core dump + + sgx开启switchless需有以下两步: + + 1. cc_enclave_create时传入switchless feature参数 + 2. 在第一次ecall调用中初始化switchless线程调度 + + 如果没有调用ecall函数,就直接调用cc_enclave_destroy,会在sgx库中销毁switchless调度线程时异常。 + + 由于switchless的实际应用场景是存在频繁ecall调用的,所以初始化switchless特性后,通常会有ecall调用,不会存在问题。 \ No newline at end of file diff --git "a/docs/zh/docs/secGear/\346\216\245\345\217\243\345\217\202\350\200\203.md" "b/docs/zh/docs/secGear/\346\216\245\345\217\243\345\217\202\350\200\203.md" index a08550716dcaf85b04c3c51f9bf8fd261497fd84..e425f41021f16a62c840de70e92a6aa1d2b80284 100644 --- "a/docs/zh/docs/secGear/\346\216\245\345\217\243\345\217\202\350\200\203.md" +++ "b/docs/zh/docs/secGear/\346\216\245\345\217\243\345\217\202\350\200\203.md" @@ -67,6 +67,56 @@ cc_enclave_result_t cc_enclave_destroy (cc_enclave_t ** enclave); - CC_ERROR_UNEXPECTED:不可预期错误 +## cc_malloc_shared_memory + +创建共享内存 + +**功能**: + +开启switchless特性后,创建安全环境与非安全环境可同时访问的共享内存,由非安全侧调用 + +**函数声明:** + +void *cc_malloc_shared_memory(cc_enclave_t *enclave, size_t size); + +**参数:** + +- enclave:入参,安全环境上下文句柄。因不同平台共享内存模型不同,同时为了保持接口跨平台一致性,该参数仅在ARM平台被使用,SGX平台该入参会被忽略 +- size:入参,共享内存大小 + +**返回值:** + +- NULL:共享内存申请失败 +- 其他:为创建的共享内存的首地址 + + +## cc_free_shared_memory + +释放共享内存 + +**功能**: + +开启switchless特性后,释放共享内存,由非安全侧调用 + +**函数声明:** + +cc_enclave_result_t cc_free_shared_memory(cc_enclave_t *enclave, void *ptr); + +**参数:** + +- enclave:入参,安全环境上下文句柄。因不同平台共享内存模型不同,同时为了保持接口跨平台一致性,该参数仅在ARM平台被使用(该参数必须与调用cc_malloc_shared_memory接口时传入的enclave保持一致),SGX平台该入参会被忽略 +- ptr:入参,cc_malloc_shared_memory接口返回的共享内存地址 + +**返回值:** + +- CC_ERROR_BAD_PARAMETERS:入参非法 +- CC_ERROR_INVALID_HANDLE:无效enclave或者传入的enclave与ptr所对应的enclave不匹配(仅在ARM平台生效,SGX平台会忽略enclave,故不会对enclave进行检查) +- CC_ERROR_NOT_IMPLEMENTED:该接口未实现 +- CC_ERROR_SHARED_MEMORY_START_ADDR_INVALID:ptr不是cc_malloc_shared_memory接口返回的共享内存地址(仅在ARM平台生效) +- CC_ERROR_OUT_OF_MEMORY:内存不足(仅在ARM平台生效) +- CC_FAIL:一般性错误 +- CC_SUCCESS:成功 + ## cc_enclave_generate_random @@ -291,3 +341,28 @@ void PrintInfo(int level, const char *fmt, ...); **返回值:** - 无 + +## cc_sl_get_async_result + +获取异步switchless调用结果(仅支持ARM) + +**功能**: + +用于获取异步switchless调用执行结果,若异步switchless调用仍在处理中,该函数可多次调用直至获取最终结果,由非安全侧调用 + +**函数声明:** + +cc_enclave_result_t cc_sl_get_async_result(cc_enclave_t *enclave, int task_id, void *retval) + +**参数:** + +- enclave:入参,已经创建 enclave 的上下文 +- task_id:入参,异步switchless调用的任务编号 +- retval:出参,用于接收异步switchless调用的返回值 + +**返回值:** + +- CE_SUCCESS:调用成功 +- CC_ERROR_TASK_UNFINISH:异步switchless调用处理中 +- CC_ERROR_TASK_FAILED:异步调用框架执行失败 +- 其他:一般性错误 diff --git a/docs/zh/menu/index.md b/docs/zh/menu/index.md index 3d7f6b188bb39e0f12d537b58a9a88c3834a9c4d..1822590c06e55428e6cd61f370632738aa6aeb91 100644 --- a/docs/zh/menu/index.md +++ b/docs/zh/menu/index.md @@ -161,6 +161,7 @@ headless: true - [认识secGear]({{< relref "./docs/secGear/认识secGear.md" >}}) - [安装secGear]({{< relref "./docs/secGear/安装secGear.md" >}}) - [开发secGear应用程序]({{< relref "./docs/secGear/开发secGear应用程序.md" >}}) + - [使用switchless特性]({{< relref "./docs/secGear/使用switchless特性.md" >}}) - [使用secGear工具]({{< relref "./docs/secGear/使用secGear工具.md" >}}) - [接口参考]({{< relref "./docs/secGear/接口参考.md" >}}) - [Kubernetes集群部署指南]({{< relref "./docs/Kubernetes/Kubernetes.md" >}})