Просмотр исходного кода

Enable remote attestation by librats in SGX mode (#1445)

Add library librats, update SGX build scripts, add sample and update document.
Zeuson 3 лет назад
Родитель
Сommit
729c4aeeaa

+ 1 - 0
README.md

@@ -159,6 +159,7 @@ The WAMR [samples](./samples) integrate the iwasm VM core, application manager a
 - **[wasm-c-api](./samples/wasm-c-api/README.md)**: Demonstrating how to run some samples from [wasm-c-api proposal](https://github.com/WebAssembly/wasm-c-api) and showing the supported API's.
 - **[wasm-c-api](./samples/wasm-c-api/README.md)**: Demonstrating how to run some samples from [wasm-c-api proposal](https://github.com/WebAssembly/wasm-c-api) and showing the supported API's.
 - **[socket-api](./samples/socket-api/README.md)**: Demonstrating how to run wasm tcp server and tcp client applications, and how they communicate with each other.
 - **[socket-api](./samples/socket-api/README.md)**: Demonstrating how to run wasm tcp server and tcp client applications, and how they communicate with each other.
 - **[workload](./samples/workload/README.md)**: Demonstrating how to build and run some complex workloads, e.g. tensorflow-lite, XNNPACK, wasm-av1, meshoptimizer and bwa.
 - **[workload](./samples/workload/README.md)**: Demonstrating how to build and run some complex workloads, e.g. tensorflow-lite, XNNPACK, wasm-av1, meshoptimizer and bwa.
+- **[sgx-ra](./samples/sgx-ra/README.md)**: Demonstrating how to execute Remote Attestation on SGX with [librats](https://github.com/inclavare-containers/librats), which enables mutual attestation with other runtimes or other entities that support librats to ensure that each is running within the TEE.
 
 
 
 
 Project Technical Steering Committee
 Project Technical Steering Committee

+ 3 - 0
build-scripts/config_common.cmake

@@ -215,6 +215,9 @@ endif ()
 if (WAMR_BUILD_LIBC_EMCC EQUAL 1)
 if (WAMR_BUILD_LIBC_EMCC EQUAL 1)
   message ("     Libc emcc enabled")
   message ("     Libc emcc enabled")
 endif ()
 endif ()
+if (WAMR_BUILD_LIB_RATS EQUAL 1)
+  message ("     Lib rats enabled")
+endif()
 if (WAMR_BUILD_MINI_LOADER EQUAL 1)
 if (WAMR_BUILD_MINI_LOADER EQUAL 1)
   add_definitions (-DWASM_ENABLE_MINI_LOADER=1)
   add_definitions (-DWASM_ENABLE_MINI_LOADER=1)
   message ("     WASM mini loader enabled")
   message ("     WASM mini loader enabled")

+ 5 - 0
build-scripts/runtime_lib.cmake

@@ -118,6 +118,10 @@ if (WAMR_BUILD_LIBC_EMCC EQUAL 1)
     include (${IWASM_DIR}/libraries/libc-emcc/libc_emcc.cmake)
     include (${IWASM_DIR}/libraries/libc-emcc/libc_emcc.cmake)
 endif ()
 endif ()
 
 
+if (WAMR_BUILD_LIB_RATS EQUAL 1)
+    include (${IWASM_DIR}/libraries/lib-rats/lib_rats.cmake)
+endif ()
+
 ####################### Common sources #######################
 ####################### Common sources #######################
 if (NOT MSVC)
 if (NOT MSVC)
     set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -ffunction-sections -fdata-sections \
     set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -ffunction-sections -fdata-sections \
@@ -159,6 +163,7 @@ set (source_all
     ${LIB_PTHREAD_SOURCE}
     ${LIB_PTHREAD_SOURCE}
     ${THREAD_MGR_SOURCE}
     ${THREAD_MGR_SOURCE}
     ${LIBC_EMCC_SOURCE}
     ${LIBC_EMCC_SOURCE}
+    ${LIB_RATS_SOURCE}
     ${DEBUG_ENGINE_SOURCE}
     ${DEBUG_ENGINE_SOURCE}
 )
 )
 
 

+ 4 - 0
core/config.h

@@ -135,6 +135,10 @@
 #define WASM_ENABLE_LIBC_EMCC 0
 #define WASM_ENABLE_LIBC_EMCC 0
 #endif
 #endif
 
 
+#ifndef WASM_ENABLE_LIB_RATS
+#define WASM_ENABLE_LIB_RATS 0
+#endif
+
 #ifndef WASM_ENABLE_LIB_PTHREAD
 #ifndef WASM_ENABLE_LIB_PTHREAD
 #define WASM_ENABLE_LIB_PTHREAD 0
 #define WASM_ENABLE_LIB_PTHREAD 0
 #endif
 #endif

+ 11 - 0
core/iwasm/common/wasm_native.c

@@ -53,6 +53,9 @@ get_lib_pthread_export_apis(NativeSymbol **p_lib_pthread_apis);
 uint32
 uint32
 get_libc_emcc_export_apis(NativeSymbol **p_libc_emcc_apis);
 get_libc_emcc_export_apis(NativeSymbol **p_libc_emcc_apis);
 
 
+uint32
+get_lib_rats_export_apis(NativeSymbol **p_lib_rats_apis);
+
 static bool
 static bool
 compare_type_with_signautre(uint8 type, const char signature)
 compare_type_with_signautre(uint8 type, const char signature)
 {
 {
@@ -414,6 +417,14 @@ wasm_native_init()
         return false;
         return false;
 #endif /* WASM_ENABLE_LIBC_EMCC */
 #endif /* WASM_ENABLE_LIBC_EMCC */
 
 
+#if WASM_ENABLE_LIB_RATS != 0
+    n_native_symbols = get_lib_rats_export_apis(&native_symbols);
+    if (n_native_symbols > 0
+        && !wasm_native_register_natives("env", native_symbols,
+                                         n_native_symbols))
+        return false;
+#endif /* WASM_ENABLE_LIB_RATS */
+
     return true;
     return true;
 }
 }
 
 

+ 33 - 0
core/iwasm/libraries/lib-rats/lib_rats.cmake

@@ -0,0 +1,33 @@
+# Copyright (c) 2022 Intel Corporation
+# Copyright (c) 2020-2021 Alibaba Cloud
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+set (LIB_RATS_DIR ${CMAKE_CURRENT_LIST_DIR})
+
+add_definitions (-DWASM_ENABLE_LIB_RATS=1)
+
+include_directories(${LIB_RATS_DIR})
+
+include(FetchContent)
+
+set(RATS_BUILD_MODE "sgx"
+    CACHE INTERNAL "Select build mode for librats(host|occlum|sgx|wasm)")
+set(RATS_INSTALL_PATH  "${CMAKE_BINARY_DIR}/librats" CACHE INTERNAL "")
+
+FetchContent_Declare(
+    librats
+    GIT_REPOSITORY https://github.com/inclavare-containers/librats
+    GIT_TAG master
+)
+FetchContent_GetProperties(librats)
+if (NOT librats_POPULATED)
+    message("-- Fetching librats ..")
+    FetchContent_Populate(librats)
+    include_directories("${librats_SOURCE_DIR}/include")
+    add_subdirectory(${librats_SOURCE_DIR} ${librats_BINARY_DIR} EXCLUDE_FROM_ALL)
+
+endif()
+
+file (GLOB source_all ${LIB_RATS_DIR}/*.c)
+
+set (LIB_RATS_SOURCE ${source_all})

+ 60 - 0
core/iwasm/libraries/lib-rats/lib_rats_wrapper.c

@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2022 Intel Corporation
+ * Copyright (c) 2020-2021 Alibaba Cloud
+ *
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <librats/api.h>
+
+#include "wasm_export.h"
+#include "bh_common.h"
+
+static uint32
+librats_collect_wrapper(wasm_exec_env_t exec_env, const uint8_t *hash)
+{
+    char *json = NULL;
+    char *str_ret;
+    uint32 len;
+    uint32 str_ret_offset = 0;
+    wasm_module_inst_t module_inst = get_module_inst(exec_env);
+    int code = librats_collect_evidence_to_json(hash, &json);
+    if (code != 0) {
+        return str_ret_offset;
+    }
+    if (json) {
+        len = (uint32)strlen(json) + 1;
+
+        str_ret_offset = module_malloc(len, (void **)&str_ret);
+        if (str_ret_offset) {
+            bh_memcpy_s(str_ret, len, json, len);
+        }
+    }
+    return str_ret_offset;
+}
+
+static int
+librats_verify_wrapper(wasm_exec_env_t exec_env, const char *evidence_json,
+                       const uint8_t *hash)
+{
+    return librats_verify_evidence_from_json(evidence_json, hash);
+}
+
+/* clang-format off */
+#define REG_NATIVE_FUNC(func_name, signature) \
+    { #func_name, func_name##_wrapper, signature, NULL }
+/* clang-format off */
+
+static NativeSymbol native_symbols_lib_rats[] = {
+    REG_NATIVE_FUNC(librats_collect, "($)i"),
+    REG_NATIVE_FUNC(librats_verify, "($$)i")
+};
+
+uint32_t
+get_lib_rats_export_apis(NativeSymbol **p_lib_rats_apis)
+{
+    *p_lib_rats_apis = native_symbols_lib_rats;
+    return sizeof(native_symbols_lib_rats) / sizeof(NativeSymbol);
+}

+ 18 - 0
core/iwasm/libraries/lib-rats/lib_rats_wrapper.h

@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2022 Intel Corporation
+ * Copyright (c) 2020-2021 Alibaba Cloud
+ *
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifndef _RATS_WAMR_API_H
+#define _RATS_WAMR_API_H
+
+#include <stdint.h>
+
+char *
+librats_collect(const uint8_t *hash);
+int
+librats_verify(const char *json_string, const uint8_t *hash);
+
+#endif

+ 18 - 1
product-mini/platforms/linux-sgx/CMakeLists.txt

@@ -59,6 +59,11 @@ if (NOT DEFINED WAMR_BUILD_LIBC_WASI)
   set (WAMR_BUILD_LIBC_WASI 1)
   set (WAMR_BUILD_LIBC_WASI 1)
 endif ()
 endif ()
 
 
+if (NOT DEFINED WAMR_BUILD_LIB_RATS)
+  # Disable lib rats support by default
+  set (WAMR_BUILD_LIB_RATS 0)
+endif()
+
 if (NOT DEFINED WAMR_BUILD_FAST_INTERP)
 if (NOT DEFINED WAMR_BUILD_FAST_INTERP)
   # Enable fast interpreter
   # Enable fast interpreter
   set (WAMR_BUILD_FAST_INTERP 1)
   set (WAMR_BUILD_FAST_INTERP 1)
@@ -84,7 +89,7 @@ if (COLLECT_CODE_COVERAGE EQUAL 1)
 endif ()
 endif ()
 
 
 set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
 set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
-set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -ffunction-sections -fdata-sections \
+set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11 -ffunction-sections -fdata-sections \
                                      -Wall -Wno-unused-parameter -Wno-pedantic \
                                      -Wall -Wno-unused-parameter -Wno-pedantic \
                                      -nostdinc -fvisibility=hidden -fpie" )
                                      -nostdinc -fvisibility=hidden -fpie" )
 
 
@@ -100,3 +105,15 @@ add_custom_command (
              COMMAND ${CMAKE_AR} rc libvmlib_untrusted.a untrusted/*.o)
              COMMAND ${CMAKE_AR} rc libvmlib_untrusted.a untrusted/*.o)
 
 
 add_custom_target (vmlib_untrusted ALL DEPENDS libvmlib_untrusted.a)
 add_custom_target (vmlib_untrusted ALL DEPENDS libvmlib_untrusted.a)
+
+if (WAMR_BUILD_LIB_RATS EQUAL 1)
+    execute_process(
+        COMMAND bash -c "sed -i -E 's/^#define LIB_RATS 0 /#define LIB_RATS 1/g' ${CMAKE_CURRENT_SOURCE_DIR}/enclave-sample/Enclave/Enclave.edl"
+        OUTPUT_VARIABLE cmdOutput
+    )
+else()
+    execute_process(
+        COMMAND bash -c "sed -i -E 's/^#define LIB_RATS 1/#define LIB_RATS 0/g' ${CMAKE_CURRENT_SOURCE_DIR}/enclave-sample/Enclave/Enclave.edl"
+        OUTPUT_VARIABLE cmdOutput
+    )
+endif()

+ 5 - 0
product-mini/platforms/linux-sgx/enclave-sample/Enclave/Enclave.edl

@@ -3,10 +3,15 @@
  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  */
  */
 
 
+#define LIB_RATS 0
+
 enclave {
 enclave {
     from "sgx_tstdc.edl" import *;
     from "sgx_tstdc.edl" import *;
     from "sgx_pthread.edl" import *;
     from "sgx_pthread.edl" import *;
     from "sgx_wamr.edl" import *;
     from "sgx_wamr.edl" import *;
+#if LIB_RATS != 0
+    from "rats.edl" import *;
+#endif
 
 
     trusted {
     trusted {
         /* define ECALLs here. */
         /* define ECALLs here. */

+ 49 - 17
product-mini/platforms/linux-sgx/enclave-sample/Makefile

@@ -9,6 +9,13 @@ SGX_ARCH ?= x64
 SGX_DEBUG ?= 0
 SGX_DEBUG ?= 0
 SPEC_TEST ?= 0
 SPEC_TEST ?= 0
 
 
+VMLIB_BUILD_DIR ?= $(CURDIR)/../build
+LIB_RATS_SRC ?= $(VMLIB_BUILD_DIR)/_deps/librats-build
+LIB_RATS := $(shell if [ -d $(LIB_RATS_SRC) ]; then echo 1; else echo 0; fi)
+
+LIB_RATS_INSTALL_DIR := $(VMLIB_BUILD_DIR)/librats/lib/librats
+LIB_RATS_INCLUDE_DIR := $(VMLIB_BUILD_DIR)/librats/include
+
 ifeq ($(shell getconf LONG_BIT), 32)
 ifeq ($(shell getconf LONG_BIT), 32)
 	SGX_ARCH := x86
 	SGX_ARCH := x86
 else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32)
 else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32)
@@ -49,6 +56,9 @@ endif
 
 
 App_Cpp_Files := App/App.cpp
 App_Cpp_Files := App/App.cpp
 App_Include_Paths := -IApp -I$(SGX_SDK)/include
 App_Include_Paths := -IApp -I$(SGX_SDK)/include
+ifeq ($(LIB_RATS), 1)
+	App_Include_Paths += -I$(LIB_RATS_INCLUDE_DIR)
+endif
 
 
 App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths)
 App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths)
 
 
@@ -79,6 +89,10 @@ else
 	App_Link_Flags += -lsgx_uae_service
 	App_Link_Flags += -lsgx_uae_service
 endif
 endif
 
 
+ifeq ($(LIB_RATS), 1)
+	App_Link_Flags += -L$(LIB_RATS_INSTALL_DIR) -lrats_u -lsgx_dcap_ql -lsgx_dcap_quoteverify -lsgx_ukey_exchange
+endif
+
 App_Cpp_Objects := $(App_Cpp_Files:.cpp=.o)
 App_Cpp_Objects := $(App_Cpp_Files:.cpp=.o)
 
 
 App_Name := iwasm
 App_Name := iwasm
@@ -105,21 +119,40 @@ Enclave_Include_Paths := -IEnclave -I$(WAMR_ROOT)/core/iwasm/include \
                          -I$(SGX_SDK)/include/tlibc \
                          -I$(SGX_SDK)/include/tlibc \
                          -I$(SGX_SDK)/include/stlport
                          -I$(SGX_SDK)/include/stlport
 
 
+ifeq ($(LIB_RATS), 1)
+	Enclave_Include_Paths += -I$(LIB_RATS_INCLUDE_DIR)
+endif
+
 Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(Enclave_Include_Paths)
 Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(Enclave_Include_Paths)
 ifeq ($(SPEC_TEST), 1)
 ifeq ($(SPEC_TEST), 1)
 	Enclave_C_Flags += -DWASM_ENABLE_SPEC_TEST=1
 	Enclave_C_Flags += -DWASM_ENABLE_SPEC_TEST=1
 else
 else
 	Enclave_C_Flags += -DWASM_ENABLE_SPEC_TEST=0
 	Enclave_C_Flags += -DWASM_ENABLE_SPEC_TEST=0
 endif
 endif
-Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++03 -nostdinc++
-Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \
-	-Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \
-    libvmlib.a \
-	-Wl,--start-group -lsgx_tstdc -lsgx_tcxx -lsgx_pthread -l$(Crypto_Library_Name) -l$(Service_Library_Name) -Wl,--end-group \
+
+ifeq ($(LIB_RATS), 1)
+	Rats_Lib_Link_Dirs := -L$(LIB_RATS_INSTALL_DIR) -L$(LIB_RATS_INSTALL_DIR)/attesters -L$(LIB_RATS_INSTALL_DIR)/verifiers
+	Rats_Lib_Link_libs := -lattester_nullattester -lattester_sgx_ecdsa -lattester_sgx_la \
+						-lverifier_nullverifier -lverifier_sgx_ecdsa -lverifier_sgx_la -lverifier_sgx_ecdsa_qve \
+						-lrats_lib
+endif
+
+Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++11 -nostdinc++
+Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) ${Rats_Lib_Link_Dirs} \
+	-Wl,--whole-archive -l$(Trts_Library_Name) ${Rats_Lib_Link_libs} -Wl,--no-whole-archive \
+	-Wl,--start-group -lsgx_tstdc -lsgx_tcxx -lsgx_pthread -lsgx_tkey_exchange -l$(Crypto_Library_Name) -l$(Service_Library_Name) -lsgx_dcap_tvl -Wl,--end-group \
 	-Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \
 	-Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \
 	-Wl,-pie,-eenclave_entry -Wl,--export-dynamic  \
 	-Wl,-pie,-eenclave_entry -Wl,--export-dynamic  \
 	-Wl,--defsym,__ImageBase=0
 	-Wl,--defsym,__ImageBase=0
 
 
+Enclave_Edl_Search_Path     =   --search-path ../Enclave \
+								--search-path $(SGX_SDK)/include \
+								--search-path $(WAMR_ROOT)/core/shared/platform/linux-sgx
+ifeq ($(LIB_RATS), 1)
+	Enclave_Edl_Search_Path	+=	--search-path $(LIB_RATS_INCLUDE_DIR)/librats/edl
+endif
+
+
 Enclave_Cpp_Objects := $(Enclave_Cpp_Files:.cpp=.o)
 Enclave_Cpp_Objects := $(Enclave_Cpp_Files:.cpp=.o)
 
 
 Enclave_Name := enclave.so
 Enclave_Name := enclave.so
@@ -156,12 +189,14 @@ ifneq ($(Build_Mode), HW_RELEASE)
 endif
 endif
 
 
 ######## App Objects ########
 ######## App Objects ########
+librats:
+ifeq ($(LIB_RATS), 1)
+	@cd $(LIB_RATS_SRC) && make install
+	@echo "librats build success"
+endif
 
 
-App/Enclave_u.c: $(SGX_EDGER8R) Enclave/Enclave.edl
-	@cd App && $(SGX_EDGER8R) --untrusted ../Enclave/Enclave.edl \
-		--search-path ../Enclave \
-		--search-path $(SGX_SDK)/include \
-		--search-path $(WAMR_ROOT)/core/shared/platform/linux-sgx
+App/Enclave_u.c: $(SGX_EDGER8R) Enclave/Enclave.edl librats
+	@cd App && $(SGX_EDGER8R) --untrusted ../Enclave/Enclave.edl $(Enclave_Edl_Search_Path)
 	@echo "GEN  =>  $@"
 	@echo "GEN  =>  $@"
 
 
 App/Enclave_u.o: App/Enclave_u.c
 App/Enclave_u.o: App/Enclave_u.c
@@ -172,7 +207,7 @@ App/%.o: App/%.cpp
 	@$(CXX) $(App_Cpp_Flags) -c $< -o $@
 	@$(CXX) $(App_Cpp_Flags) -c $< -o $@
 	@echo "CXX  <=  $<"
 	@echo "CXX  <=  $<"
 
 
-libvmlib_untrusted.a: ../build/libvmlib_untrusted.a
+libvmlib_untrusted.a: $(VMLIB_BUILD_DIR)/libvmlib_untrusted.a
 	@cp $< $@
 	@cp $< $@
 	@echo "CP $@  <=  $<"
 	@echo "CP $@  <=  $<"
 
 
@@ -183,11 +218,8 @@ $(App_Name): App/Enclave_u.o $(App_Cpp_Objects) libvmlib_untrusted.a
 
 
 ######## Enclave Objects ########
 ######## Enclave Objects ########
 
 
-Enclave/Enclave_t.c: $(SGX_EDGER8R) Enclave/Enclave.edl
-	@cd Enclave && $(SGX_EDGER8R) --trusted ../Enclave/Enclave.edl \
-		--search-path ../Enclave \
-		--search-path $(SGX_SDK)/include \
-		--search-path $(WAMR_ROOT)/core/shared/platform/linux-sgx
+Enclave/Enclave_t.c: $(SGX_EDGER8R) Enclave/Enclave.edl librats
+	@cd Enclave && $(SGX_EDGER8R) --trusted ../Enclave/Enclave.edl $(Enclave_Edl_Search_Path)
 	@echo "GEN  =>  $@"
 	@echo "GEN  =>  $@"
 
 
 Enclave/Enclave_t.o: Enclave/Enclave_t.c
 Enclave/Enclave_t.o: Enclave/Enclave_t.c
@@ -198,7 +230,7 @@ Enclave/%.o: Enclave/%.cpp
 	@$(CXX) $(Enclave_Cpp_Flags) -c $< -o $@
 	@$(CXX) $(Enclave_Cpp_Flags) -c $< -o $@
 	@echo "CXX  <=  $<"
 	@echo "CXX  <=  $<"
 
 
-libvmlib.a: ../build/libvmlib.a
+libvmlib.a: $(VMLIB_BUILD_DIR)/libvmlib.a
 	@cp $< $@
 	@cp $< $@
 	@echo "CP $@  <=  $<"
 	@echo "CP $@  <=  $<"
 
 

+ 81 - 0
samples/sgx-ra/CMakeLists.txt

@@ -0,0 +1,81 @@
+# Copyright (c) 2022 Intel Corporation
+# Copyright (c) 2020-2021 Alibaba Cloud
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+cmake_minimum_required(VERSION 3.1.4)
+project(sgx-ra)
+
+################ runtime settings  ##############
+set (WAMR_BUILD_PLATFORM "linux-sgx")
+
+# Reset default linker flags
+set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
+set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
+
+# Set WAMR_BUILD_TARGET
+if (NOT DEFINED WAMR_BUILD_TARGET)
+  if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+    # Build as X86_64 by default in 64-bit platform
+    set (WAMR_BUILD_TARGET "X86_64")
+  elseif (CMAKE_SIZEOF_VOID_P EQUAL 4)
+    # Build as X86_32 by default in 32-bit platform
+    set (WAMR_BUILD_TARGET "X86_32")
+  else ()
+    message(SEND_ERROR "Unsupported build target platform!")
+  endif ()
+endif ()
+
+if (NOT CMAKE_BUILD_TYPE)
+  set (CMAKE_BUILD_TYPE Release)
+endif ()
+
+set (WAMR_BUILD_INTERP 1)
+set (WAMR_BUILD_AOT 1)
+set (WAMR_BUILD_JIT 0)
+set (WAMR_BUILD_LIBC_BUILTIN 1)
+set (WAMR_BUILD_LIBC_WASI 1)
+set (WAMR_BUILD_LIB_PTHREAD 1)
+set (WAMR_BUILD_FAST_INTERP 1)
+set (WAMR_BUILD_LIB_RATS 1)
+
+# compiling and linking flags
+if (COLLECT_CODE_COVERAGE EQUAL 1)
+  set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
+endif ()
+
+set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
+set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11 -ffunction-sections -fdata-sections \
+                                     -Wall -Wno-unused-parameter -Wno-pedantic \
+                                     -nostdinc -fvisibility=hidden -fpie" )
+
+# build out vmlib
+set (WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
+set (SGX_PLATFORM_DIR ${WAMR_ROOT_DIR}/product-mini/platforms/linux-sgx)
+include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
+
+add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
+
+add_custom_command (
+             OUTPUT libvmlib_untrusted.a
+             COMMAND mkdir -p untrusted && cd untrusted &&
+                     ${CMAKE_C_COMPILER} -c ${PLATFORM_SHARED_SOURCE_UNTRUSTED}
+             COMMAND ${CMAKE_AR} rc libvmlib_untrusted.a untrusted/*.o)
+
+add_custom_target (vmlib_untrusted ALL DEPENDS libvmlib_untrusted.a)
+
+execute_process (
+    COMMAND bash -c "sed -i -E 's/^#define LIB_RATS 0/#define LIB_RATS 1/g' ${SGX_PLATFORM_DIR}/enclave-sample/Enclave/Enclave.edl"
+    OUTPUT_VARIABLE cmdOutput
+)
+
+################ wamr runtime ###################
+add_custom_target (
+              iwasm ALL
+              DEPENDS vmlib_untrusted vmlib_untrusted
+              COMMAND make -C  ${SGX_PLATFORM_DIR}/enclave-sample SGX_MODE=HW SGX_DEBUG=1 VMLIB_BUILD_DIR=${CMAKE_BINARY_DIR}
+              COMMAND ${CMAKE_COMMAND} -E copy ${SGX_PLATFORM_DIR}/enclave-sample/enclave.signed.so ${CMAKE_BINARY_DIR}
+              COMMAND ${CMAKE_COMMAND} -E copy ${SGX_PLATFORM_DIR}/enclave-sample/iwasm ${CMAKE_BINARY_DIR}
+              COMMAND make -C ${SGX_PLATFORM_DIR}/enclave-sample clean)
+
+################ wasm application ###############
+add_subdirectory(wasm-app)

+ 42 - 0
samples/sgx-ra/README.md

@@ -0,0 +1,42 @@
+"sgx-ra" sample introduction
+==============
+
+This sample demonstrates how to execute Remote Attestation on SGX with [librats](https://github.com/inclavare-containers/librats) and run it with iwasm. It can only build on [SGX supported processors](https://www.intel.com/content/www/us/en/support/articles/000028173/processors.html), please check it.
+
+## Preparation
+
+Before staring, we need to download and intall [SGX SDK](https://download.01.org/intel-sgx/latest/linux-latest/distro) and [SGX DCAP Library](https://download.01.org/intel-sgx/latest/dcap-latest) referring to this [guide](https://download.01.org/intel-sgx/sgx-dcap/1.8/linux/docs/Intel_SGX_DCAP_Linux_SW_Installation_Guide.pdf).
+
+The following command is the example of the SGX environment installation on ubuntu18.04.
+``` shell
+$ cd $HOME
+$ # Set your platform, you can get the platforms list on 
+$ # https://download.01.org/intel-sgx/latest/linux-latest/distro
+$ SGX_PALTFORM=ubuntu18.04-server
+$ SGX_SDK_VERSION=2.17.100.3
+$ SGX_DRIVER_VERSION=1.41
+$ # install SGX Driver
+$ wget https://download.01.org/intel-sgx/latest/linux-latest/distro/$SGX_PALTFORM/sgx_linux_x64_driver_$SGX_DRIVER_VERSION.bin
+$ chmod +x sgx_linux_x64_driver_$SGX_DRIVER_VERSION.bin
+$ sudo ./sgx_linux_x64_driver_$SGX_DRIVER_VERSION.bin
+$ # install SGX SDK
+$ wget https://download.01.org/intel-sgx/latest/linux-latest/distro/$SGX_PALTFORM/sgx_linux_x64_sdk_$SGX_SDK_VERSION.bin
+$ chmod +x sgx_linux_x64_sdk_$SGX_SDK_VERSION.bin
+$ sudo ./sgx_linux_x64_sdk_$SGX_SDK_VERSION.bin
+$ # install SGX DCAP Library
+$ echo 'deb [arch=amd64] https://download.01.org/intel-sgx/sgx_repo/ubuntu bionic main' | sudo tee /etc/apt/sources.list.d/intel-sgx.list > /dev/null
+$ wget -O - https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key | sudo apt-key add -
+$ sudo apt update
+$ sudo apt install libsgx-uae-service libsgx-dcap-default-qpl-dev libsgx-dcap-ql-dev libsgx-dcap-quote-verify-dev
+```
+
+## Build
+``` shell
+$ mkdir build && cd build
+$ cmake ..
+$ make
+$ # run the sample
+$ ./iwasm wasm-app/test.wasm
+```
+
+The sample will print the evidence in json and "Evidence is trusted." by default.

+ 38 - 0
samples/sgx-ra/wasm-app/CMakeLists.txt

@@ -0,0 +1,38 @@
+# Copyright (c) 2022 Intel Corporation
+# Copyright (c) 2020-2021 Alibaba Cloud
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+cmake_minimum_required(VERSION 3.0)
+project(wasm-app)
+
+set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
+set (LIB_RATS_DIR ${WAMR_ROOT_DIR}/core/iwasm/libraries/lib-rats)
+
+set (CMAKE_C_LINK_FLAGS "")
+set (CMAKE_CXX_LINK_FLAGS "")
+if (APPLE)
+    set (HAVE_FLAG_SEARCH_PATHS_FIRST 0)
+endif ()
+
+set (CMAKE_SYSTEM_PROCESSOR wasm32)
+set (CMAKE_SYSROOT                  ${WAMR_ROOT_DIR}/wamr-sdk/app/libc-builtin-sysroot)
+
+if (NOT DEFINED WASI_SDK_DIR)
+    set (WASI_SDK_DIR               "/opt/wasi-sdk")
+endif ()
+
+set (CMAKE_C_FLAGS                  "-nostdlib")
+set (CMAKE_C_COMPILER_TARGET        "wasm32")
+set (CMAKE_C_COMPILER               "${WASI_SDK_DIR}/bin/clang")
+
+set (CMAKE_EXE_LINKER_FLAGS
+    "-Wl,--max-memory=131072 -z stack-size=8192   \
+     -Wl,--no-entry,--strip-all                   \
+     -Wl,--export=__main_argc_argv                \
+     -Wl,--export=__heap_base,--export=__data_end \
+     -Wl,--allow-undefined"
+)
+
+add_executable(test.wasm main.c)
+set_target_properties(test.wasm PROPERTIES INCLUDE_DIRECTORIES ${LIB_RATS_DIR})
+target_link_libraries(test.wasm)

+ 36 - 0
samples/sgx-ra/wasm-app/main.c

@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2022 Intel Corporation
+ * Copyright (c) 2020-2021 Alibaba Cloud
+ *
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "lib_rats_wrapper.h"
+
+int
+main(int argc, char **argv)
+{
+    char *evidence_json = NULL;
+    const char *hash = "12345678123456781234567812345678";
+    evidence_json = librats_collect((const uint8_t *)hash);
+    if (evidence_json == NULL) {
+        printf("Librats collect evidence failed.\n");
+        return -1;
+    }
+    printf("evidence json:\n%s\n", evidence_json);
+
+    if (librats_verify(evidence_json, (const uint8_t *)hash) != 0) {
+        printf("Evidence is not trusted.\n");
+    }
+    else {
+        printf("Evidence is trusted.\n");
+    }
+
+    if (evidence_json) {
+        free(evidence_json);
+    }
+
+    return 0;
+}