Quellcode durchsuchen

linux-sgx: Improve the remote attestation (#1695)

The current implementation of remote attestation does not take into
account the integrity of the wasm module. The SHA256 of the wasm
module has been put into user_data to generate the quote, and more
parameters are exposed for further verification.
Zeuson vor 3 Jahren
Ursprung
Commit
656a8427e6

+ 11 - 1
core/iwasm/libraries/lib-rats/lib_rats.cmake

@@ -4,9 +4,19 @@
 
 set (LIB_RATS_DIR ${CMAKE_CURRENT_LIST_DIR})
 
+if ("$ENV{SGX_SSL_DIR}" STREQUAL "")
+  set (SGX_SSL_DIR "/opt/intel/sgxssl")
+else()
+  set (SGX_SSL_DIR $ENV{SGX_SSL_DIR})
+endif()
+
+if (NOT EXISTS ${SGX_SSL_DIR})
+    message(FATAL_ERROR "Can not find SGX_SSL, please install it first")
+endif()
+
 add_definitions (-DWASM_ENABLE_LIB_RATS=1)
 
-include_directories(${LIB_RATS_DIR})
+include_directories(${LIB_RATS_DIR} ${SGX_SSL_DIR}/include)
 
 include(FetchContent)
 

+ 31 - 0
core/iwasm/libraries/lib-rats/lib_rats_common.h

@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2022 Intel Corporation
+ * Copyright (c) 2020-2021 Alibaba Cloud
+ *
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifndef _RATS_WAMR_COMMON_H
+#define _RATS_WAMR_COMMON_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+#define SGX_QUOTE_MAX_SIZE 8192
+#define SGX_USER_DATA_SIZE 64
+#define SGX_MEASUREMENT_SIZE 32
+/* clang-format off */
+typedef struct rats_sgx_evidence {
+    uint8_t quote[SGX_QUOTE_MAX_SIZE];          /* The quote of the Enclave */
+    uint32_t quote_size;                        /* The size of the quote */
+    uint8_t user_data[SGX_USER_DATA_SIZE];      /* The custom data in the quote */
+    uint32_t product_id;                        /* Product ID of the Enclave */
+    uint8_t mr_enclave[SGX_MEASUREMENT_SIZE];   /* The MRENCLAVE of the Enclave */
+    uint32_t security_version;                  /* Security Version of the Enclave */
+    uint8_t mr_signer[SGX_MEASUREMENT_SIZE];    /* The MRSIGNER of the Enclave */
+    uint64_t att_flags;                         /* Flags of the Enclave in attributes */
+    uint64_t att_xfrm;                          /* XSAVE Feature Request Mask */
+} rats_sgx_evidence_t;
+/* clang-format on */
+
+#endif

+ 74 - 19
core/iwasm/libraries/lib-rats/lib_rats_wrapper.c

@@ -8,48 +8,103 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <librats/api.h>
+#include <string.h>
+#include <openssl/sha.h>
 
+#include "sgx_quote_3.h"
 #include "wasm_export.h"
 #include "bh_common.h"
+#include "lib_rats_common.h"
 
-static uint32
-librats_collect_wrapper(wasm_exec_env_t exec_env, const uint8_t *hash)
+extern char wasm_module_hash[SHA256_DIGEST_LENGTH];
+
+static int
+librats_collect_wrapper(wasm_exec_env_t exec_env, char **evidence_json,
+                        const char *buffer, uint32_t buffer_size)
 {
-    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;
+
+    char *json, *str_ret;
+    uint32_t str_ret_offset;
+    uint8_t final_hash[SHA256_DIGEST_LENGTH];
+
+    SHA256_CTX sha256;
+    SHA256_Init(&sha256);
+    SHA256_Update(&sha256, wasm_module_hash, SHA256_DIGEST_LENGTH);
+    if (buffer != NULL)
+        SHA256_Update(&sha256, buffer, buffer_size);
+    SHA256_Final(final_hash, &sha256);
+
+    int ret_code = librats_collect_evidence_to_json(final_hash, &json);
+    if (ret_code != 0) {
+        return ret_code;
     }
-    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);
-        }
+    uint32_t json_size = strlen(json) + 1;
+    str_ret_offset = module_malloc(json_size, (void **)&str_ret);
+    if (!str_ret_offset) {
+        free(json);
+        return (int)RATS_ATTESTER_ERR_NO_MEM;
     }
-    return str_ret_offset;
+    bh_memcpy_s(str_ret, json_size, json, json_size);
+    *((int *)evidence_json) = str_ret_offset;
+    free(json);
+
+    return 0;
 }
 
 static int
 librats_verify_wrapper(wasm_exec_env_t exec_env, const char *evidence_json,
-                       const uint8_t *hash)
+                       uint32_t evidence_size, const uint8_t *hash,
+                       uint32_t hash_size)
 {
     return librats_verify_evidence_from_json(evidence_json, hash);
 }
 
+static int
+librats_parse_evidence_wrapper(wasm_exec_env_t exec_env,
+                               const char *evidence_json, uint32_t json_size,
+                               rats_sgx_evidence_t *evidence,
+                               uint32_t evidence_size)
+{
+    attestation_evidence_t att_ev;
+
+    if (get_evidence_from_json(evidence_json, &att_ev) != 0) {
+        return -1;
+    }
+
+    // Only supports parsing sgx evidence currently
+    if (strcmp(att_ev.type, "sgx_ecdsa") != 0) {
+        return -1;
+    }
+
+    sgx_quote3_t *quote_ptr = (sgx_quote3_t *)att_ev.ecdsa.quote;
+    bh_memcpy_s(evidence->quote, att_ev.ecdsa.quote_len, att_ev.ecdsa.quote,
+                att_ev.ecdsa.quote_len);
+    evidence->quote_size = att_ev.ecdsa.quote_len;
+    bh_memcpy_s(evidence->user_data, SGX_REPORT_DATA_SIZE,
+                quote_ptr->report_body.report_data.d, SGX_REPORT_DATA_SIZE);
+    bh_memcpy_s(evidence->mr_enclave, sizeof(sgx_measurement_t),
+                quote_ptr->report_body.mr_enclave.m, sizeof(sgx_measurement_t));
+    bh_memcpy_s(evidence->mr_signer, sizeof(sgx_measurement_t),
+                quote_ptr->report_body.mr_signer.m, sizeof(sgx_measurement_t));
+    evidence->product_id = quote_ptr->report_body.isv_prod_id;
+    evidence->security_version = quote_ptr->report_body.isv_svn;
+    evidence->att_flags = quote_ptr->report_body.attributes.flags;
+    evidence->att_xfrm = quote_ptr->report_body.attributes.flags;
+
+    return 0;
+}
+
 /* clang-format off */
 #define REG_NATIVE_FUNC(func_name, signature) \
     { #func_name, func_name##_wrapper, signature, NULL }
 /* clang-format on */
 
 static NativeSymbol native_symbols_lib_rats[] = {
-    REG_NATIVE_FUNC(librats_collect, "($)i"),
-    REG_NATIVE_FUNC(librats_verify, "($$)i")
+    REG_NATIVE_FUNC(librats_collect, "(**~)i"),
+    REG_NATIVE_FUNC(librats_verify, "(*~*~)i"),
+    REG_NATIVE_FUNC(librats_parse_evidence, "(*~*~)i")
 };
 
 uint32_t

+ 32 - 3
core/iwasm/libraries/lib-rats/lib_rats_wrapper.h

@@ -9,10 +9,39 @@
 #define _RATS_WAMR_API_H
 
 #include <stdint.h>
+#include <string.h>
+#include "lib_rats_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int
+librats_collect(char **evidence_json, const char *buffer, uint32_t buffer_size);
+
+int
+librats_verify(const char *evidence_json, uint32_t evidence_size,
+               const uint8_t *hash, uint32_t hash_size);
 
-char *
-librats_collect(const uint8_t *hash);
 int
-librats_verify(const char *json_string, const uint8_t *hash);
+librats_parse_evidence(const char *evidence_json, uint32_t json_size,
+                       rats_sgx_evidence_t *evidence, uint32_t evidence_size);
+
+#define librats_collect(evidence_json, buffer) \
+    librats_collect(evidence_json, buffer, buffer ? strlen(buffer) + 1 : 0)
+
+#define librats_verify(evidence_json, hash)                             \
+    librats_verify(evidence_json,                                       \
+                   evidence_json ? strlen(evidence_json) + 1 : 0, hash, \
+                   hash ? strlen((const char *)hash) + 1 : 0)
+
+#define librats_parse_evidence(evidence_json, evidence)                   \
+    librats_parse_evidence(evidence_json,                                 \
+                           evidence_json ? strlen(evidence_json) + 1 : 0, \
+                           evidence, sizeof(rats_sgx_evidence_t))
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif

+ 4 - 8
product-mini/platforms/linux-sgx/CMakeLists.txt

@@ -126,12 +126,14 @@ endif()
 
 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"
+        COMMAND bash -c "sed -i -E 's/^#define WASM_ENABLE_LIB_RATS 0/#define WASM_ENABLE_LIB_RATS 1/g' ${CMAKE_CURRENT_SOURCE_DIR}/enclave-sample/Enclave/Enclave.edl"
+        COMMAND bash -c "sed -i -E 's/^WAMR_BUILD_LIB_RATS = 0/WAMR_BUILD_LIB_RATS = 1/g' ${CMAKE_CURRENT_SOURCE_DIR}/enclave-sample/Makefile"
         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"
+        COMMAND bash -c "sed -i -E 's/^#define WASM_ENABLE_LIB_RATS 1/#define WASM_ENABLE_LIB_RATS 0/g' ${CMAKE_CURRENT_SOURCE_DIR}/enclave-sample/Enclave/Enclave.edl"
+        COMMAND bash -c "sed -i -E 's/^WAMR_BUILD_LIB_RATS = 1/WAMR_BUILD_LIB_RATS = 0/g' ${CMAKE_CURRENT_SOURCE_DIR}/enclave-sample/Makefile"
         OUTPUT_VARIABLE cmdOutput
     )
 endif()
@@ -139,18 +141,12 @@ endif()
 if (WAMR_BUILD_SGX_IPFS EQUAL 1)
     execute_process(
         COMMAND bash -c "sed -i -E 's/^#define SGX_IPFS 0/#define SGX_IPFS 1/g' ${CMAKE_CURRENT_SOURCE_DIR}/enclave-sample/Enclave/Enclave.edl"
-        OUTPUT_VARIABLE cmdOutput
-    )
-    execute_process(
         COMMAND bash -c "sed -i -E 's/^SGX_IPFS = 0/SGX_IPFS = 1/g' ${CMAKE_CURRENT_SOURCE_DIR}/enclave-sample/Makefile"
         OUTPUT_VARIABLE cmdOutput
     )
 else()
     execute_process(
         COMMAND bash -c "sed -i -E 's/^#define SGX_IPFS 1/#define SGX_IPFS 0/g' ${CMAKE_CURRENT_SOURCE_DIR}/enclave-sample/Enclave/Enclave.edl"
-        OUTPUT_VARIABLE cmdOutput
-    )
-    execute_process(
         COMMAND bash -c "sed -i -E 's/^SGX_IPFS = 1/SGX_IPFS = 0/g' ${CMAKE_CURRENT_SOURCE_DIR}/enclave-sample/Makefile"
         OUTPUT_VARIABLE cmdOutput
     )

+ 13 - 0
product-mini/platforms/linux-sgx/enclave-sample/Enclave/Enclave.cpp

@@ -12,6 +12,12 @@
 #include "wasm_export.h"
 #include "bh_platform.h"
 
+#if WASM_ENABLE_LIB_RATS != 0
+#include <openssl/sha.h>
+
+char wasm_module_hash[SHA256_DIGEST_LENGTH];
+#endif
+
 extern "C" {
 typedef int (*os_print_function_t)(const char *message);
 extern void
@@ -243,6 +249,13 @@ handle_cmd_load_module(uint64 *args, uint32 argc)
 
     *(EnclaveModule **)args_org = enclave_module;
 
+#if WASM_ENABLE_LIB_RATS != 0
+    SHA256_CTX sha256;
+    SHA256_Init(&sha256);
+    SHA256_Update(&sha256, wasm_file, wasm_file_size);
+    SHA256_Final((unsigned char *)wasm_module_hash, &sha256);
+#endif
+
     LOG_VERBOSE("Load module success.\n");
 }
 

+ 3 - 2
product-mini/platforms/linux-sgx/enclave-sample/Enclave/Enclave.edl

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

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

@@ -4,6 +4,7 @@
 ######## SGX SDK Settings ########
 
 SGX_SDK ?= /opt/intel/sgxsdk
+SGX_SSL ?= /opt/intel/sgxssl
 SGX_MODE ?= SIM
 SGX_ARCH ?= x64
 SGX_DEBUG ?= 0
@@ -11,13 +12,12 @@ SPEC_TEST ?= 0
 
 # These variables are automatically set by CMakeLists.txt
 SGX_IPFS = 0
+WAMR_BUILD_LIB_RATS = 0
 WAMR_BUILD_GLOBAL_HEAP_POOL = 0
 WAMR_BUILD_GLOBAL_HEAP_SIZE = 10485760
 
 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
 
@@ -61,7 +61,7 @@ endif
 
 App_Cpp_Files := App/App.cpp
 App_Include_Paths := -IApp -I$(SGX_SDK)/include
-ifeq ($(LIB_RATS), 1)
+ifeq ($(WAMR_BUILD_LIB_RATS), 1)
 	App_Include_Paths += -I$(LIB_RATS_INCLUDE_DIR)
 endif
 
@@ -94,8 +94,8 @@ else
 	App_Link_Flags += -lsgx_uae_service
 endif
 
-ifeq ($(LIB_RATS), 1)
-	App_Link_Flags += -L$(LIB_RATS_INSTALL_DIR) -lrats_u -lsgx_dcap_ql -lsgx_dcap_quoteverify -lsgx_ukey_exchange
+ifeq ($(WAMR_BUILD_LIB_RATS), 1)
+	App_Link_Flags += -L$(LIB_RATS_INSTALL_DIR) -L$(SGX_SSL)/lib64 -lrats_u -lsgx_dcap_ql -lsgx_dcap_quoteverify -lsgx_ukey_exchange -lsgx_usgxssl
 endif
 
 App_Cpp_Objects := $(App_Cpp_Files:.cpp=.o)
@@ -130,28 +130,29 @@ Enclave_Include_Paths := -IEnclave -I$(WAMR_ROOT)/core/iwasm/include \
                          -I$(SGX_SDK)/include/tlibc \
                          -I$(SGX_SDK)/include/stlport
 
-ifeq ($(LIB_RATS), 1)
-	Enclave_Include_Paths += -I$(LIB_RATS_INCLUDE_DIR)
+ifeq ($(WAMR_BUILD_LIB_RATS), 1)
+	Enclave_Include_Paths += -I$(LIB_RATS_INCLUDE_DIR) -I$(SGX_SSL)/include
 endif
 
-Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(Enclave_Include_Paths) -DWASM_GLOBAL_HEAP_SIZE=$(WAMR_BUILD_GLOBAL_HEAP_SIZE) -DWASM_ENABLE_GLOBAL_HEAP_POOL=$(WAMR_BUILD_GLOBAL_HEAP_POOL)
+Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(Enclave_Include_Paths) -DWASM_GLOBAL_HEAP_SIZE=$(WAMR_BUILD_GLOBAL_HEAP_SIZE) -DWASM_ENABLE_GLOBAL_HEAP_POOL=$(WAMR_BUILD_GLOBAL_HEAP_POOL) -DWASM_ENABLE_LIB_RATS=$(WAMR_BUILD_LIB_RATS)
 ifeq ($(SPEC_TEST), 1)
 	Enclave_C_Flags += -DWASM_ENABLE_SPEC_TEST=1
 else
 	Enclave_C_Flags += -DWASM_ENABLE_SPEC_TEST=0
 endif
 
-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 \
+ifeq ($(WAMR_BUILD_LIB_RATS), 1)
+	Rats_Lib_Link_Dirs := -L$(LIB_RATS_INSTALL_DIR) -L$(LIB_RATS_INSTALL_DIR)/attesters -L$(LIB_RATS_INSTALL_DIR)/verifiers -L$(SGX_SSL)/lib64
+	Rats_Lib_W_Link_libs := -lattester_nullattester -lattester_sgx_ecdsa -lattester_sgx_la \
 						-lverifier_nullverifier -lverifier_sgx_ecdsa -lverifier_sgx_la -lverifier_sgx_ecdsa_qve \
-						-lrats_lib
+						-lrats_lib -lsgx_tsgxssl
+	Rats_Lib_NW_Link_libs := -lsgx_dcap_tvl -lsgx_tsgxssl_crypto
 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} $(Intel_Ipfs_Trusted_Flag) -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,--whole-archive -l$(Trts_Library_Name) ${Rats_Lib_W_Link_libs} $(Intel_Ipfs_Trusted_Flag) -Wl,--no-whole-archive \
+	-Wl,--start-group -lsgx_tstdc -lsgx_tcxx -lsgx_pthread -lsgx_tkey_exchange -l$(Crypto_Library_Name) -l$(Service_Library_Name) $(Rats_Lib_NW_Link_libs) -Wl,--end-group \
 	-Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \
 	-Wl,-pie,-eenclave_entry -Wl,--export-dynamic  \
 	-Wl,--defsym,__ImageBase=0
@@ -159,8 +160,8 @@ Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefau
 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
+ifeq ($(WAMR_BUILD_LIB_RATS), 1)
+	Enclave_Edl_Search_Path	+=	--search-path $(LIB_RATS_INCLUDE_DIR)/librats/edl --search-path $(SGX_SSL)/include
 endif
 
 
@@ -201,7 +202,7 @@ endif
 
 ######## App Objects ########
 librats:
-ifeq ($(LIB_RATS), 1)
+ifeq ($(WAMR_BUILD_LIB_RATS), 1)
 	@cd $(LIB_RATS_SRC) && make install
 	@echo "librats build success"
 endif

+ 2 - 1
samples/sgx-ra/CMakeLists.txt

@@ -64,7 +64,8 @@ add_custom_command (
 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"
+    COMMAND bash -c "sed -i -E 's/^#define WASM_ENABLE_LIB_RATS 0/#define WASM_ENABLE_LIB_RATS 1/g' ${SGX_PLATFORM_DIR}/enclave-sample/Enclave/Enclave.edl"
+    COMMAND bash -c "sed -i -E 's/^WAMR_BUILD_LIB_RATS = 0/WAMR_BUILD_LIB_RATS = 1/g' ${SGX_PLATFORM_DIR}/enclave-sample/Makefile"
     OUTPUT_VARIABLE cmdOutput
 )
 

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

@@ -37,6 +37,21 @@ $ echo 'deb [arch=amd64] https://download.01.org/intel-sgx/sgx_repo/ubuntu bioni
 $ wget -O - https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key | sudo apt-key add -
 $ sudo apt-get update
 $ sudo apt-get install -y libsgx-uae-service libsgx-dcap-default-qpl-dev libsgx-dcap-ql-dev libsgx-dcap-quote-verify-dev
+$ # install SGX SSL Library
+$ git clone https://github.com/intel/linux-sgx.git
+$ cd linux-sgx && make preparation
+$ sudo cp external/toolset/{current_distr}/* /usr/local/bin
+$ # Verify that the paths are correctly set 
+$ which ar as ld objcopy objdump ranlib
+$ cd ../
+$ git clone https://github.com/intel/intel-sgx-ssl.git
+$ wget https://www.openssl.org/source/openssl-1.1.1q.tar.gz
+$ cp openssl-1.1.1q.tar.gz intel-sgx-ssl/openssl_source
+$ rm -f openssl-1.1.1q.tar.gz
+$ cd intel-sgx-ssl/Linux
+$ source /opt/intel/sgxsdk/environment
+$ make all
+$ sudo make install
 ```
 
 You can optionally grant users to communicate with the SDK platform using the following command.

+ 92 - 11
samples/sgx-ra/wasm-app/main.c

@@ -9,28 +9,109 @@
 #include <stdlib.h>
 #include "lib_rats_wrapper.h"
 
+#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
+
+/**
+ * hex_dump
+ *
+ * @brief dump data in hex format
+ *
+ * @param title: Title
+ * @param buf: User buffer
+ * @param size: Dump data size
+ * @param number: The number of outputs per line
+ *
+ * @return void
+ */
+void
+hex_dump(const char *title, const uint8_t *buf, uint32_t size, uint32_t number)
+{
+    int i, j;
+    if (title) {
+        printf("\n\t%s:\n\n", title);
+    }
+
+    for (i = 0; i < size; i += number) {
+        printf("%08X: ", i);
+
+        for (j = 0; j < number; j++) {
+            if (j % 8 == 0) {
+                printf(" ");
+            }
+            if (i + j < size)
+                printf("%02X ", buf[i + j]);
+            else
+                printf("   ");
+        }
+        printf(" ");
+
+        for (j = 0; j < number; j++) {
+            if (i + j < size) {
+                printf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
+            }
+        }
+        printf("\n");
+    }
+}
+
 int
 main(int argc, char **argv)
 {
+    int ret_code = -1;
     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;
+
+    // Generate user_data by SHA256 buffer and the wasm module.
+    // user_data = SHA256(sha256_wasm_module || buffer)
+    const char *buffer = "This is a sample.";
+
+    // If you want to declare the evidence of type rats_sgx_evidence_t on the
+    // stack, you should modify the stack size of the CMAKE_EXE_LINKER_FLAGS in
+    // CMakeLists.txt to 51200 at least.
+    rats_sgx_evidence_t *evidence =
+        (rats_sgx_evidence_t *)malloc(sizeof(rats_sgx_evidence_t));
+    if (!evidence) {
+        printf("ERROR: No memory to allocate.\n");
+        goto err;
     }
-    printf("evidence json:\n%s\n", evidence_json);
 
-    if (librats_verify(evidence_json, (const uint8_t *)hash) != 0) {
-        printf("Evidence is not trusted.\n");
+    int rats_err = librats_collect(&evidence_json, buffer);
+    if (rats_err != 0) {
+        printf("ERROR: Collect evidence failed, error code: %#x\n", rats_err);
+        goto err;
     }
-    else {
-        printf("Evidence is trusted.\n");
+
+    if (librats_parse_evidence(evidence_json, evidence) != 0) {
+        printf("ERROR: Parse evidence failed.\n");
+        goto err;
     }
 
+    // You could use these parameters for further verification.
+    hex_dump("Quote", evidence->quote, evidence->quote_size, 32);
+    hex_dump("User Data", evidence->user_data, SGX_USER_DATA_SIZE, 32);
+    hex_dump("MRENCLAVE", evidence->mr_enclave, SGX_MEASUREMENT_SIZE, 32);
+    hex_dump("MRSIGNER", evidence->mr_signer, SGX_MEASUREMENT_SIZE, 32);
+    printf("\n\tProduct ID:\t\t%u\n", evidence->product_id);
+    printf("\tSecurity Version:\t%u\n", evidence->security_version);
+    printf("\tAttributes.flags:\t%llu\n", evidence->att_flags);
+    printf("\tAttribute.xfrm:\t\t%llu\n", evidence->att_xfrm);
+
+    rats_err = librats_verify((const char *)evidence_json, evidence->user_data);
+    if (rats_err != 0) {
+        printf("ERROR: Evidence is not trusted, error code: %#x.\n", rats_err);
+        goto err;
+    }
+
+    ret_code = 0;
+    printf("Evidence is trusted.\n");
+
+err:
     if (evidence_json) {
         free(evidence_json);
     }
 
-    return 0;
+    if (evidence) {
+        free(evidence);
+    }
+
+    return ret_code;
 }