From 264ac7f993f6b1cf689714156854bf58131eca6b Mon Sep 17 00:00:00 2001 From: "Tate, Hongliang Tian" Date: Fri, 29 Jun 2018 17:56:18 +0800 Subject: [PATCH] Add write syscall and prints Hello World --- .gitignore | 0 Makefile | 21 ++++ TODO.md | 7 ++ buildenv.mk | 81 +++++++++++++ deps/rust-sgx-sdk.patch | 46 +++++++ src/Enclave.edl | 48 ++++++++ src/Makefile | 9 ++ src/libc/Makefile | 0 src/libos/Cargo.lock | 57 +++++++++ src/libos/Cargo.toml | 14 +++ src/libos/Makefile | 42 +++++++ src/libos/src/lib.rs | 50 ++++++++ src/libos/src/syscall.rs | 26 ++++ src/pal/Makefile | 38 ++++++ src/pal/pal.c | 256 +++++++++++++++++++++++++++++++++++++++ src/pal/pal.h | 61 ++++++++++ test/Enclave.lds | 9 ++ test/Enclave_config.xml | 12 ++ test/Enclave_private.pem | 39 ++++++ test/Makefile | 67 ++++++++++ test/empty.c | 3 + test/hello_world.c | 7 ++ 22 files changed, 893 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 TODO.md create mode 100644 buildenv.mk create mode 100644 deps/rust-sgx-sdk.patch create mode 100644 src/Enclave.edl create mode 100644 src/Makefile create mode 100644 src/libc/Makefile create mode 100644 src/libos/Cargo.lock create mode 100644 src/libos/Cargo.toml create mode 100644 src/libos/Makefile create mode 100644 src/libos/src/lib.rs create mode 100644 src/libos/src/syscall.rs create mode 100644 src/pal/Makefile create mode 100644 src/pal/pal.c create mode 100644 src/pal/pal.h create mode 100644 test/Enclave.lds create mode 100644 test/Enclave_config.xml create mode 100644 test/Enclave_private.pem create mode 100644 test/Makefile create mode 100644 test/empty.c create mode 100644 test/hello_world.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..e339551a --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +.PHONY: all build_src build_test test clean + +all: build_src build_test + +init: + git submodule init + git submodule update + cd deps/rust-sgx-sdk && git apply ../rust-sgx-sdk.patch + +build_src: + @$(MAKE) --no-print-directory -C src + +build_test: + @$(MAKE) --no-print-directory -C test + +test: build_test + @$(MAKE) --no-print-directory -C test test + +clean: + @$(MAKE) --no-print-directory -C src clean + @$(MAKE) --no-print-directory -C test clean diff --git a/TODO.md b/TODO.md new file mode 100644 index 00000000..21a0fa99 --- /dev/null +++ b/TODO.md @@ -0,0 +1,7 @@ +# TODOs +- [ ] Add README.md +- [ ] Add file table +- [ ] Add more syscalls +- [ ] Pass argc and argv + +- [ ] Add libc diff --git a/buildenv.mk b/buildenv.mk new file mode 100644 index 00000000..6bfd693c --- /dev/null +++ b/buildenv.mk @@ -0,0 +1,81 @@ +SGX_SDK ?= /opt/intel/sgxsdk +SGX_MODE ?= HW +SGX_ARCH ?= x64 + +ifeq ($(shell getconf LONG_BIT), 32) + SGX_ARCH := x86 +else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32) + SGX_ARCH := x86 +endif + +ifeq ($(SGX_ARCH), x86) + SGX_COMMON_CFLAGS := -m32 + SGX_LIBRARY_PATH := $(SGX_SDK)/lib + SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign + SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r +else + SGX_COMMON_CFLAGS := -m64 + SGX_LIBRARY_PATH := $(SGX_SDK)/lib64 + SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign + SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r +endif + +ifeq ($(SGX_DEBUG), 1) +ifeq ($(SGX_PRERELEASE), 1) +$(error Cannot set SGX_DEBUG and SGX_PRERELEASE at the same time!!) +endif +endif + +ifeq ($(SGX_DEBUG), 1) + SGX_COMMON_CFLAGS += -O0 -g +else + SGX_COMMON_CFLAGS += -O2 +endif + +ifneq ($(SGX_MODE), HW) + Urts_Library_Name := sgx_urts_sim +else + Urts_Library_Name := sgx_urts +endif + +ifneq ($(SGX_MODE), HW) + Trts_Library_Name := sgx_trts_sim + Service_Library_Name := sgx_tservice_sim +else + Trts_Library_Name := sgx_trts + Service_Library_Name := sgx_tservice +endif +Crypto_Library_Name := sgx_tcrypto +KeyExchange_Library_Name := sgx_tkey_exchange +ProtectedFs_Library_Name := sgx_tprotected_fs + + +# +# Export flags used to compile or link untrusted modules +# +SGX_CFLAGS_U := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes +SGX_CFLAGS_U += -I$(SGX_SDK)/include + +SGX_LFLAGS_U := $(SGX_COMMON_CFLAGS) -lpthread +SGX_LFLAGS_U += -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) +ifneq ($(SGX_MODE), HW) + SGX_LFLAGS_U += -lsgx_uae_service_sim +else + SGX_LFLAGS_U += -lsgx_uae_service +endif + +# +# Export flags used to compile or link untrusted modules +# +SGX_CFLAGS_T := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector +SGX_CFLAGS_T += -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/stlport -I$(SGX_SDK)/include/epid +# Before use this linker flag, the user should define $(Other_Enclave_Libs), +# which lists all libraries that are to be part of the enclave. +SGX_LFLAGS_T = $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) $(Other_Link_Flags) \ + -Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \ + -Wl,--start-group -lsgx_tstdc -lsgx_tstdcxx -l$(Crypto_Library_Name) $(Other_Enclave_Libs) -Wl,--end-group \ + -Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \ + -Wl,-pie,-eenclave_entry -Wl,--export-dynamic \ + -Wl,--defsym,__ImageBase=0 \ + -Wl,--gc-sections \ + -Wl,--version-script=Enclave.lds diff --git a/deps/rust-sgx-sdk.patch b/deps/rust-sgx-sdk.patch new file mode 100644 index 00000000..f5b108ec --- /dev/null +++ b/deps/rust-sgx-sdk.patch @@ -0,0 +1,46 @@ +diff --git a/sgx_tstd/src/lib.rs b/sgx_tstd/src/lib.rs +index 33ee1f2..7f3dab8 100644 +--- a/sgx_tstd/src/lib.rs ++++ b/sgx_tstd/src/lib.rs +@@ -222,6 +222,11 @@ pub mod untrusted; + mod sys_common; + mod sys; + ++// @tatetian ++// Export some internals of sys so that libos can use them directly ++pub use sys::fs::libc as libc_fs; ++pub use sys::fd::libc as libc_io; ++ + // Private support modules + mod panicking; + mod cpuid; +diff --git a/sgx_tstd/src/sys/fd.rs b/sgx_tstd/src/sys/fd.rs +index 3fa46d9..28daa9b 100644 +--- a/sgx_tstd/src/sys/fd.rs ++++ b/sgx_tstd/src/sys/fd.rs +@@ -209,7 +209,9 @@ impl Drop for FileDesc { + } + } + +-mod libc { ++// @tatetian ++// Make this public so that the libos can use it directly ++pub mod libc { + use sgx_types::sgx_status_t; + use io; + pub use sgx_trts::libc::*; +diff --git a/sgx_tstd/src/sys/fs.rs b/sgx_tstd/src/sys/fs.rs +index a611f39..cc54c31 100644 +--- a/sgx_tstd/src/sys/fs.rs ++++ b/sgx_tstd/src/sys/fs.rs +@@ -455,7 +455,9 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { + Ok(ret) + } + +-mod libc { ++// @tatetian ++// Make this public so that the libos can use it directly ++pub mod libc { + use sgx_types::sgx_status_t; + use io; + use core::ptr; diff --git a/src/Enclave.edl b/src/Enclave.edl new file mode 100644 index 00000000..0581d6c2 --- /dev/null +++ b/src/Enclave.edl @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2017-2018 Baidu, Inc. 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 Baidu, Inc., 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. + * + */ + +enclave { + from "sgx_stdio.edl" import *; + from "sgx_backtrace.edl" import *; + from "sgx_tstdc.edl" import *; + from "sgx_tstd.edl" import *; + from "sgx_net.edl" import *; + from "sgx_time.edl" import *; + + trusted { + /* define ECALLs here. */ + public int libos_boot(void); + }; + + untrusted { + + }; +}; diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 00000000..61124563 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,9 @@ +.PHONY: all clean + +all: + @$(MAKE) --no-print-directory -C libos + @$(MAKE) --no-print-directory -C pal + +clean: + @$(MAKE) --no-print-directory -C libos clean + @$(MAKE) --no-print-directory -C pal clean diff --git a/src/libc/Makefile b/src/libc/Makefile new file mode 100644 index 00000000..e69de29b diff --git a/src/libos/Cargo.lock b/src/libos/Cargo.lock new file mode 100644 index 00000000..74ea6590 --- /dev/null +++ b/src/libos/Cargo.lock @@ -0,0 +1,57 @@ +[[package]] +name = "Rusgx" +version = "1.0.0" +dependencies = [ + "sgx_tstd 1.0.0", + "sgx_types 1.0.0", +] + +[[package]] +name = "sgx_alloc" +version = "1.0.0" +dependencies = [ + "sgx_trts 1.0.0", +] + +[[package]] +name = "sgx_build_helper" +version = "0.1.0" + +[[package]] +name = "sgx_tprotected_fs" +version = "1.0.0" +dependencies = [ + "sgx_trts 1.0.0", + "sgx_types 1.0.0", +] + +[[package]] +name = "sgx_trts" +version = "1.0.0" +dependencies = [ + "sgx_types 1.0.0", +] + +[[package]] +name = "sgx_tstd" +version = "1.0.0" +dependencies = [ + "sgx_alloc 1.0.0", + "sgx_build_helper 0.1.0", + "sgx_tprotected_fs 1.0.0", + "sgx_trts 1.0.0", + "sgx_types 1.0.0", + "sgx_unwind 0.0.0", +] + +[[package]] +name = "sgx_types" +version = "1.0.0" + +[[package]] +name = "sgx_unwind" +version = "0.0.0" +dependencies = [ + "sgx_trts 1.0.0", +] + diff --git a/src/libos/Cargo.toml b/src/libos/Cargo.toml new file mode 100644 index 00000000..9ce17420 --- /dev/null +++ b/src/libos/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "Rusgx" +version = "1.0.0" + +[lib] +name = "rusgx" +crate-type = ["staticlib"] + +[features] +default = [] + +[target.'cfg(not(target_env = "sgx"))'.dependencies] +sgx_types = { path = "../../deps/rust-sgx-sdk/sgx_types" } +sgx_tstd = { path = "../../deps/rust-sgx-sdk/sgx_tstd" } diff --git a/src/libos/Makefile b/src/libos/Makefile new file mode 100644 index 00000000..5e1eeef1 --- /dev/null +++ b/src/libos/Makefile @@ -0,0 +1,42 @@ +# Copyright (C) 2017-2018 Baidu, Inc. 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 Baidu, Inc., 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. +# +LIB_NAME := librusgx.a +SRCS := $(wildcard src/*.rs) + +.PHONY: all clean + +all: $(LIB_NAME) + +$(LIB_NAME): $(SRCS) + RUSTC_BOOTSTRAP=1 cargo build --release + cp ./target/release/$(LIB_NAME) $(LIB_NAME) + +clean: + @cargo clean + @-$(RM) $(LIB_NAME) diff --git a/src/libos/src/lib.rs b/src/libos/src/lib.rs new file mode 100644 index 00000000..c94e5ec2 --- /dev/null +++ b/src/libos/src/lib.rs @@ -0,0 +1,50 @@ +// Copyright (C) 2017-2018 Baidu, Inc. 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 Baidu, Inc., nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// 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. + +#![crate_name = "rusgx"] +#![crate_type = "staticlib"] + +#![cfg_attr(not(target_env = "sgx"), no_std)] +#![cfg_attr(target_env = "sgx", feature(rustc_private))] + +extern crate sgx_types; +#[cfg(not(target_env = "sgx"))] +#[macro_use] +extern crate sgx_tstd as std; +use sgx_types::*; + +extern "C" { + pub fn main() -> c_int; +} + +#[no_mangle] +pub extern "C" fn libos_boot() -> sgx_status_t { + println!("{}", "LibOS boots"); + unsafe { main(); } + sgx_status_t::SGX_SUCCESS +} + +pub mod syscall; diff --git a/src/libos/src/syscall.rs b/src/libos/src/syscall.rs new file mode 100644 index 00000000..4265ac6f --- /dev/null +++ b/src/libos/src/syscall.rs @@ -0,0 +1,26 @@ +use sgx_types::*; + +// Use the internal syscall wrappers from sgx_tstd +use std::libc_fs as fs; +use std::libc_io as io; + + +#[no_mangle] +pub unsafe extern "C" fn sys_open(path: * const c_char, flags: c_int, mode: c_int) -> c_int { + fs::open64(path, flags, mode) +} + +#[no_mangle] +pub unsafe extern "C" fn sys_close(fd: c_int) -> c_int { + io::close(fd) +} + +#[no_mangle] +pub unsafe extern "C" fn sys_read(fd: c_int, buf: * mut c_void, size: size_t) -> ssize_t { + io::read(fd, buf, size) +} + +#[no_mangle] +pub unsafe extern "C" fn sys_write(fd: c_int, buf: * const c_void, size: size_t) -> ssize_t { + io::write(fd, buf, size) +} diff --git a/src/pal/Makefile b/src/pal/Makefile new file mode 100644 index 00000000..0333d57b --- /dev/null +++ b/src/pal/Makefile @@ -0,0 +1,38 @@ +include ../../buildenv.mk + +EDL_Gen_Files := Enclave_u.c Enclave_u.h + +Srcs := $(sort $(filter-out Enclave_u.c, $(wildcard *.c))) +Objs := $(Srcs:.c=.o) Enclave_u.o +Bin := pal + +C_Flags := $(SGX_CFLAGS_U) +Link_Flags := $(SGX_LFLAGS_U) +Link_Flags += -L../../deps/rust-sgx-sdk/sgx_ustdc/ -lsgx_ustdc + + +all: $(Bin) + +$(Bin): $(EDL_Gen_Files) $(Objs) sgx_ustdc + @$(CC) $(Objs) -o $@ $(Link_Flags) + @echo "LINK => $@" + +$(EDL_Gen_Files): $(SGX_EDGER8R) ../Enclave.edl + @$(SGX_EDGER8R) --untrusted ../Enclave.edl --search-path $(SGX_SDK)/include --search-path ../../deps/rust-sgx-sdk/edl/ + @echo "GEN => $(EDL_Gen_Files)" + +$(Objs): %.o: %.c + @$(CC) $(C_Flags) -c $< -o $@ + @echo "CC <= $@" + +# +# Compile dependencies in Rust SGX SDK +# +.PHONY: sgx_ustdc +sgx_ustdc: + @$(MAKE) --no-print-directory -C ../../deps/rust-sgx-sdk/sgx_ustdc/ 2> /dev/null + + +.PHONY: clean +clean: + @-$(RM) -f $(EDL_Gen_Files) $(Objs) $(Bin) diff --git a/src/pal/pal.c b/src/pal/pal.c new file mode 100644 index 00000000..d7fb10ff --- /dev/null +++ b/src/pal/pal.c @@ -0,0 +1,256 @@ +// Copyright (C) 2017-2018 Baidu, Inc. 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 Baidu, Inc., 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. + +#include +#include +#include + +#include +#include +#define MAX_PATH FILENAME_MAX + +#include "sgx_urts.h" +#include "pal.h" +#include "Enclave_u.h" + + +sgx_enclave_id_t global_eid = 0; + +typedef struct _sgx_errlist_t { + sgx_status_t err; + const char *msg; + const char *sug; /* Suggestion */ +} sgx_errlist_t; + +/* Error code returned by sgx_create_enclave */ +static sgx_errlist_t sgx_errlist[] = { + { + SGX_ERROR_UNEXPECTED, + "Unexpected error occurred.", + NULL + }, + { + SGX_ERROR_INVALID_PARAMETER, + "Invalid parameter.", + NULL + }, + { + SGX_ERROR_OUT_OF_MEMORY, + "Out of memory.", + NULL + }, + { + SGX_ERROR_ENCLAVE_LOST, + "Power transition occurred.", + "Please refer to the sample \"PowerTransition\" for details." + }, + { + SGX_ERROR_INVALID_ENCLAVE, + "Invalid enclave image.", + NULL + }, + { + SGX_ERROR_INVALID_ENCLAVE_ID, + "Invalid enclave identification.", + NULL + }, + { + SGX_ERROR_INVALID_SIGNATURE, + "Invalid enclave signature.", + NULL + }, + { + SGX_ERROR_OUT_OF_EPC, + "Out of EPC memory.", + NULL + }, + { + SGX_ERROR_NO_DEVICE, + "Invalid SGX device.", + "Please make sure SGX module is enabled in the BIOS, and install SGX driver afterwards." + }, + { + SGX_ERROR_MEMORY_MAP_CONFLICT, + "Memory map conflicted.", + NULL + }, + { + SGX_ERROR_INVALID_METADATA, + "Invalid enclave metadata.", + NULL + }, + { + SGX_ERROR_DEVICE_BUSY, + "SGX device was busy.", + NULL + }, + { + SGX_ERROR_INVALID_VERSION, + "Enclave version was invalid.", + NULL + }, + { + SGX_ERROR_INVALID_ATTRIBUTE, + "Enclave was not authorized.", + NULL + }, + { + SGX_ERROR_ENCLAVE_FILE_ACCESS, + "Can't open enclave file.", + NULL + }, +}; + +/* Check error conditions for loading enclave */ +void print_error_message(sgx_status_t ret) +{ + size_t idx = 0; + size_t ttl = sizeof sgx_errlist/sizeof sgx_errlist[0]; + + for (idx = 0; idx < ttl; idx++) { + if(ret == sgx_errlist[idx].err) { + if(NULL != sgx_errlist[idx].sug) + printf("Info: %s\n", sgx_errlist[idx].sug); + printf("Error: %s\n", sgx_errlist[idx].msg); + break; + } + } + + if (idx == ttl) + printf("Error: Unexpected error occurred.\n"); +} + +/* Initialize the enclave: + * Step 1: try to retrieve the launch token saved by last transaction + * Step 2: call sgx_create_enclave to initialize an enclave instance + * Step 3: save the launch token if it is updated + */ +int initialize_enclave(const char* enclave_path) +{ + char token_path[MAX_PATH] = {'\0'}; + sgx_launch_token_t token = {0}; + sgx_status_t ret = SGX_ERROR_UNEXPECTED; + int updated = 0; + + /* Step 1: try to retrieve the launch token saved by last transaction + * if there is no token, then create a new one. + */ + /* try to get the token saved in $HOME */ + const char *home_dir = getpwuid(getuid())->pw_dir; + + if (home_dir != NULL && + (strlen(home_dir)+strlen("/")+sizeof(TOKEN_FILENAME)+1) <= MAX_PATH) { + /* compose the token path */ + strncpy(token_path, home_dir, strlen(home_dir)); + strncat(token_path, "/", strlen("/")); + strncat(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)+1); + } else { + /* if token path is too long or $HOME is NULL */ + strncpy(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)); + } + + FILE *fp = fopen(token_path, "rb"); + if (fp == NULL && (fp = fopen(token_path, "wb")) == NULL) { + printf("Warning: Failed to create/open the launch token file \"%s\".\n", token_path); + } + + if (fp != NULL) { + /* read the token from saved file */ + size_t read_num = fread(token, 1, sizeof(sgx_launch_token_t), fp); + if (read_num != 0 && read_num != sizeof(sgx_launch_token_t)) { + /* if token is invalid, clear the buffer */ + memset(&token, 0x0, sizeof(sgx_launch_token_t)); + printf("Warning: Invalid launch token read from \"%s\".\n", token_path); + } + } + /* Step 2: call sgx_create_enclave to initialize an enclave instance */ + /* Debug Support: set 2nd parameter to 1 */ + ret = sgx_create_enclave(enclave_path, SGX_DEBUG_FLAG, &token, &updated, &global_eid, NULL); + if (ret != SGX_SUCCESS) { + print_error_message(ret); + if (fp != NULL) fclose(fp); + return -1; + } + printf("[+] global_eid: %ld\n", global_eid); + + /* Step 3: save the launch token if it is updated */ + if (updated == FALSE || fp == NULL) { + /* if the token is not updated, or file handler is invalid, do not perform saving */ + if (fp != NULL) fclose(fp); + return 0; + } + + /* reopen the file with write capablity */ + fp = freopen(token_path, "wb", fp); + if (fp == NULL) return 0; + size_t write_num = fwrite(token, 1, sizeof(sgx_launch_token_t), fp); + if (write_num != sizeof(sgx_launch_token_t)) + printf("Warning: Failed to save launch token to \"%s\".\n", token_path); + fclose(fp); + return 0; +} + +/* Application entry */ +int SGX_CDECL main(int argc, char *argv[]) +{ + sgx_status_t sgx_ret = SGX_SUCCESS; + int exitcode = 0; + uint32_t sealed_log_size = 1024; + uint8_t sealed_log[1024] = {0}; + + if (argc != 2) { + printf("ERROR: The expected number of arguments is 1, but given %d\n\n", argc - 1); + printf("Usage: pal \n"); + return -1; + } + const char* enclave_path = argv[1]; + + /* Initialize the enclave */ + if(initialize_enclave(enclave_path) < 0){ + printf("Enter a character before exit ...\n"); + getchar(); + return -1; + } + + sgx_ret = libos_boot(global_eid, &exitcode); + + if(sgx_ret != SGX_SUCCESS) { + print_error_message(sgx_ret); + return -1; + } + + if(exitcode) { + printf("Program exits with error code %d...\n", exitcode); + return -1; + } + + /* Destroy the enclave */ + sgx_destroy_enclave(global_eid); + + return 0; +} diff --git a/src/pal/pal.h b/src/pal/pal.h new file mode 100644 index 00000000..1501bd7b --- /dev/null +++ b/src/pal/pal.h @@ -0,0 +1,61 @@ +// Copyright (C) 2017-2018 Baidu, Inc. 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 Baidu, Inc., 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. + +#ifndef _APP_H_ +#define _APP_H_ + +#include +#include +#include +#include + +#include "sgx_error.h" /* sgx_status_t */ +#include "sgx_eid.h" /* sgx_enclave_id_t */ + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define TOKEN_FILENAME "enclave.token" + +extern sgx_enclave_id_t global_eid; /* global enclave id */ + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if defined(__cplusplus) +} +#endif + +#endif /* !_APP_H_ */ diff --git a/test/Enclave.lds b/test/Enclave.lds new file mode 100644 index 00000000..e3d9d0ee --- /dev/null +++ b/test/Enclave.lds @@ -0,0 +1,9 @@ +enclave.so +{ + global: + g_global_data_sim; + g_global_data; + enclave_entry; + local: + *; +}; diff --git a/test/Enclave_config.xml b/test/Enclave_config.xml new file mode 100644 index 00000000..1473a769 --- /dev/null +++ b/test/Enclave_config.xml @@ -0,0 +1,12 @@ + + + 0 + 0 + 0x400000 + 0x1000000 + 8 + 1 + 0 + 0 + 0xFFFFFFFF + diff --git a/test/Enclave_private.pem b/test/Enclave_private.pem new file mode 100644 index 00000000..529d07be --- /dev/null +++ b/test/Enclave_private.pem @@ -0,0 +1,39 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 00000000..345c4647 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,67 @@ +include ../buildenv.mk + +EDL_Gen_Files := Enclave_t.c Enclave_t.h + +Enclave_Config := Enclave_config.xml +Enclave_Key := Enclave_private.pem + +Test_Srcs := $(sort $(filter-out Enclave_t.c, $(wildcard *.c))) +Test_Targets := $(Test_Srcs:%.c=test-%) +Test_Objs := $(Test_Srcs:.c=.o) Enclave_t.o +Test_Enclaves := $(Test_Srcs:.c=.so) +Test_Signed_Enclaves := $(Test_Srcs:.c=.signed.so) + +C_Flags := $(SGX_CFLAGS_T) + + +Other_Link_Flags := -L../deps/rust-sgx-sdk/compiler-rt/ -L../src/libos/ +Other_Enclave_Libs := -lcompiler-rt-patch -lrusgx +Link_Flags := $(SGX_LFLAGS_T) + + + +all: build + + + + +.PHONY: build +build: compiler-rt $(Test_Signed_Enclaves) + + +$(Test_Signed_Enclaves): %.signed.so: %.so + @$(SGX_ENCLAVE_SIGNER) sign -key $(Enclave_Key) -enclave $^ -out $@ -config $(Enclave_Config) + @echo "SIGN => $@" + +$(Test_Enclaves): %.so: %.o Enclave_t.o + $(CC) $^ -o $@ $(Link_Flags) + @echo "LINK => $@" + +$(Test_Objs): %.o: %.c + @$(CC) $(C_Flags) -c $< -o $@ + @echo "CC <= $@" + +$(EDL_Gen_Files): $(SGX_EDGER8R) ../src/Enclave.edl + @$(SGX_EDGER8R) --trusted ../src/Enclave.edl --search-path $(SGX_SDK)/include --search-path ../deps/rust-sgx-sdk/edl/ + @echo "GEN => $(EDL_Gen_Files)" + + +.PHONY: compiler-rt +compiler-rt: + @$(MAKE) --no-print-directory -C ../deps/rust-sgx-sdk/compiler-rt/ 2> /dev/null + + +# +# Run tests +# +.PHONY: test +test: $(Test_Targets) + +.PHONY: (Test_Targets) +$(Test_Targets): test-%: %.signed.so + ./../src/pal/pal $^ + + +.PHONY: clean +clean: + @-$(RM) $(Test_Signed_Enclaves) $(Test_Enclaves) $(Test_Objs) $(EDL_Gen_Files) diff --git a/test/empty.c b/test/empty.c new file mode 100644 index 00000000..33c14ce1 --- /dev/null +++ b/test/empty.c @@ -0,0 +1,3 @@ +int main() { + return 0; +} diff --git a/test/hello_world.c b/test/hello_world.c new file mode 100644 index 00000000..68dc65bc --- /dev/null +++ b/test/hello_world.c @@ -0,0 +1,7 @@ +extern long long sys_write(int fd, const char* buf, unsigned long long size); + +int main(void) { + char msg[] = "Hello, World!\n"; + sys_write(1, msg, sizeof(msg)); + return 0; +}