├── .gitignore ├── .gitmodules ├── .python-version ├── LICENSE ├── Makefile ├── PoBF.md ├── PoBF_USENIX.pdf ├── README.md ├── buildenv.mk ├── cctasks ├── db │ ├── Cargo.toml │ └── src │ │ ├── db.rs │ │ └── lib.rs ├── evaluation_tvm │ ├── Cargo.toml │ ├── README.md │ ├── model_deploy │ │ ├── Makefile │ │ ├── README.md │ │ ├── build_model.py │ │ ├── bundle.c │ │ ├── bundle.h │ │ ├── cat.png │ │ ├── crt_config.h │ │ └── model_entry.c │ └── src │ │ └── lib.rs ├── fann │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── fasta │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── polybench │ ├── Cargo.toml │ └── src │ │ └── lib.rs └── sample_add │ ├── Cargo.toml │ └── src │ └── lib.rs ├── data ├── task_fann │ ├── data.bin │ ├── manifest.json │ └── preprocess.py ├── task_fasta │ ├── data.bin │ ├── manifest.json │ ├── preprocess.py │ └── sequence.fasta ├── task_polybench │ ├── data.bin │ └── manifest.json ├── task_sample │ ├── data.bin │ └── manifest.json └── task_tvm │ ├── data.bin │ └── manifest.json ├── data_provider ├── Cargo.toml ├── Makefile ├── README.md ├── build.rs ├── cert.der ├── cert.pem ├── key.pem ├── manifest.json ├── src │ ├── handlers.rs │ ├── main.rs │ └── utils.rs └── tvl │ ├── App │ ├── App.cpp │ └── App.h │ ├── Enclave │ ├── Enclave.config.xml │ ├── Enclave.cpp │ ├── Enclave.edl │ ├── Enclave.h │ ├── Enclave.lds │ ├── Enclave_private_test.pem │ ├── config.01.xml │ ├── config.02.xml │ ├── config.03.xml │ └── config.04.xml │ ├── Include │ └── user_types.h │ └── Makefile ├── data_provider_sev ├── Cargo.toml └── src │ └── main.rs ├── docker ├── Dockerfile └── README.md ├── others ├── README.md ├── enarx │ ├── Enarx.toml │ ├── README.md │ ├── client │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ ├── server │ │ ├── .cargo │ │ │ └── config.toml │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── db_persistent.rs │ │ │ ├── main.rs │ │ │ └── task.rs │ └── tvm-wasm │ │ ├── README.md │ │ ├── tools │ │ └── build_graph_lib.py │ │ └── wasm-runtime │ │ ├── Cargo.toml │ │ ├── build.rs │ │ └── src │ │ └── lib.rs ├── evaluation_tvm │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ ├── model_deploy │ │ ├── Makefile │ │ ├── README.md │ │ ├── build_model.py │ │ ├── bundle.c │ │ ├── bundle.h │ │ ├── cat.png │ │ ├── crt_config.h │ │ └── model_entry.c │ └── src │ │ └── lib.rs ├── gramine │ ├── .gitignore │ ├── Makefile │ ├── README.md │ ├── client.manifest.template │ ├── download │ ├── rustlib │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── server.manifest.template │ ├── src │ │ ├── client.cc │ │ └── server.cc │ └── ssl │ │ └── ca_config.conf ├── occlum │ ├── .gitignore │ ├── Occlum.json │ ├── build_occlum_rust.sh │ ├── docker_run.sh │ └── rust_config.yaml └── rust_app │ ├── client │ ├── Cargo.toml │ └── src │ │ └── main.rs │ └── server │ ├── Cargo.toml │ └── src │ ├── db_persistent.rs │ ├── dcap.rs │ ├── main.rs │ └── task.rs ├── platform_sev ├── Cargo.toml ├── Makefile ├── README.md ├── attestation_lib │ ├── Makefile │ ├── attest.cc │ ├── logger.cc │ ├── logger.h │ ├── utils.cc │ └── utils.h ├── build.rs ├── rust-toolchain └── src │ ├── db_persistent.rs │ ├── ffi.rs │ ├── key.rs │ ├── main.rs │ ├── pobf.rs │ └── vecaes.rs ├── platform_sgx ├── Makefile ├── app │ ├── Cargo.toml │ ├── build.rs │ └── src │ │ ├── main.rs │ │ └── ocall.rs └── enclave │ ├── Cargo.toml │ ├── Intel_SGX_Attestation_RootCA.cer │ ├── Intel_SGX_Attestation_RootCA.pem │ ├── README.md │ ├── config.xml │ ├── enclave.edl │ ├── enclave.lds │ ├── private.pem │ └── src │ ├── bogus.rs │ ├── db_persistent.rs │ ├── dh.rs │ ├── lib.rs │ ├── mirai_types │ ├── mirai_comp.rs │ ├── mod.rs │ └── task.rs │ ├── networking_utils.rs │ ├── ocall.rs │ ├── pobf.rs │ ├── pobf_verifier.rs │ ├── userfunc.rs │ ├── utils.rs │ └── vecaes.rs ├── pobf_crypto ├── Cargo.toml └── src │ └── lib.rs ├── pobf_keychain ├── cert.der ├── cert.pem └── key.pem ├── pobf_proof ├── README.md ├── _CoqProject ├── model.v └── model_list.v ├── pobf_state ├── Cargo.toml ├── Prusti.toml └── src │ ├── bogus.rs │ ├── lib.rs │ └── task.rs ├── pobf_thread_pool ├── Cargo.toml └── src │ └── lib.rs ├── pobf_verifier ├── cargo-pobf-verify └── pobf-verify ├── requirements.txt ├── rust-toolchain ├── scripts ├── README.md ├── build.sh ├── clean_data.sh ├── data_generator │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── demo-verify.sh ├── evaluation.sh ├── image_net_interpreter.py ├── multi_threading.sh ├── plt_cost_breakup.ipynb ├── plt_db.ipynb ├── plt_main.ipynb ├── plt_stack.ipynb ├── prepare_mirai.sh └── prepare_prusti.sh ├── setup.sh ├── system.patch └── verify_roadmap.md /.gitignore: -------------------------------------------------------------------------------- 1 | # compiled files 2 | target 3 | /target 4 | */target 5 | /md_output 6 | platform_sgx/bin 7 | platform_sgx/lib 8 | data_provider/bin 9 | 10 | # intermediate results 11 | enclave_u.* 12 | enclave_t.* 13 | Enclave_u.* 14 | Enclave_t.* 15 | *.so 16 | *.o 17 | *.a 18 | .lia.cache 19 | *.log 20 | *.txt 21 | *.wasm 22 | 23 | # MISC 24 | Cargo.lock 25 | .vscode 26 | outlib 27 | *.csv 28 | .config_HW_DEBUG_x64 29 | data_provider/tvl/app 30 | eval 31 | *.bin 32 | *.json 33 | *.png 34 | *.params 35 | *.pdf 36 | 37 | # Do not ignore Python dependencies. 38 | !requirements.txt 39 | 40 | # Coq 41 | *.aux 42 | *.vo* 43 | *.glob 44 | /proof/*Makefile* 45 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "ycsb-pocf"] 2 | path = ycsb-pocf 3 | url = https://github.com/hiroki-chen/ycsb-pocf 4 | -------------------------------------------------------------------------------- /.python-version: -------------------------------------------------------------------------------- 1 | 3.10.4 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | all: PlatformSGX DataProvider 3 | 4 | ######## Platform SGX ######## 5 | 6 | .PHONY: TVM PlatformSGX 7 | TVM: 8 | $(MAKE) -C cctasks/evaluation_tvm/model_deploy 9 | 10 | PlatformSGX: TVM platform_sgx 11 | @pkill app || true 12 | $(MAKE) -C platform_sgx 13 | 14 | ######## Verification ######## 15 | # TODO 16 | 17 | .PHONY: verify 18 | 19 | ######## Run Service ######## 20 | DataProvider_Manifest_Path ?= ../manifest.json 21 | # Bind address and port. 22 | Server_Address := 127.0.0.1 23 | Server_Port := 1234 24 | # CI arguments for the enclave. 25 | Enclave_App_Arguments := $(Server_Address) $(Server_Port) 26 | # CI arguments for data provider. 27 | DataProvider_Arguments := run $(DataProvider_Manifest_Path) 28 | 29 | .PHONY: run 30 | run: $(App_Name) $(RustEnclave_Signed_Name) 31 | @pkill app || true 32 | @printf '\n\e[0;36m===== Run Enclave =====\e[0m\n' 33 | @cd ./platform_sgx/bin && ./app $(Enclave_App_Arguments) & 34 | @sleep 1 35 | @printf '\n\e[0;36m===== Run Data Provider =====\e[0m\n' 36 | # TODO: Run in parallel. 37 | @cd ./data_provider/bin && ./data_provider $(DataProvider_Arguments) 38 | @pkill app 39 | 40 | ####### Data Owner ####### 41 | .PHONY: DataProvider 42 | DataProvider: data_provider 43 | $(MAKE) -C data_provider 44 | 45 | .PHONY: clean 46 | clean: 47 | @cd platform_sgx && $(MAKE) clean 48 | @cd data_provider && $(MAKE) clean 49 | @cd cctasks/evaluation_tvm/model_deploy && $(MAKE) clean 50 | @cd pobf_state && cargo clean 51 | @cd scripts && ./clean_data.sh 52 | -------------------------------------------------------------------------------- /PoBF.md: -------------------------------------------------------------------------------- 1 | # PoBF is ... 2 | 3 | - A security principle 4 | - A set of formally proved rules 5 | - A reference implementation in Rust 6 | 7 | ## Design & Implementation 8 | 9 | ### Execution Integrity 10 | 11 | - Rust 12 | - Typestate 13 | 14 | ### Preventing Leakage 15 | 16 | Check the OCALL parameters which may leak secret. 17 | 18 | - Static Analysis (constant/taint analysis) (MIRAI) 19 | 20 | ### Scrubing Residue 21 | 22 | `Zerorize` the Zone. 23 | Zone <-> Stack + Reg + Heap 24 | 25 | - For stack & reg: instrumentation (TODO) 26 | - For heap: modify Rust's memory deallocator (TODO) 27 | 28 | ### TODOs? 29 | 30 | - RA-TLS 31 | - Secure secret provisioning 32 | - Enarx Evaluation (TVM in WASM) 33 | 34 | ## Evaluation 35 | 36 | ### Security Evaluation 37 | 38 | - What attack vectors are defended? 39 | 40 | ### Performance Evaluation 41 | 42 | - Verification Overhead 43 | - Runtime Overhead 44 | - Single- vs. Multi-User Enclave 45 | 46 | ### Case Study 47 | 48 | - Porting efforts is acceptable 49 | - Verifier can find the problems 50 | -------------------------------------------------------------------------------- /PoBF_USENIX.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ya0guang/PoBF/8bc1a900fdae506d0a113250b94f594ae70f2762/PoBF_USENIX.pdf -------------------------------------------------------------------------------- /cctasks/db/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "db" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | bincode = { version = "2.0.0-rc.3", default-features = false, features = ["alloc", "serde"] } 10 | hashbrown = { version = "0.13.2", features = ["serde"] } 11 | lazy_static = "1.4.0" 12 | serde = { version = "1.0.163", default-features = false, features = ["alloc"] } 13 | spin = { version = "0.9.8", default-features = false, features = [ 14 | "rwlock", 15 | "once", 16 | ] } 17 | 18 | [lib] 19 | doctest = false 20 | -------------------------------------------------------------------------------- /cctasks/evaluation_tvm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "evaluation_tvm" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | 10 | [features] 11 | mirai = [] 12 | std = [] 13 | -------------------------------------------------------------------------------- /cctasks/evaluation_tvm/README.md: -------------------------------------------------------------------------------- 1 | # Demo Confidential Task for Apache TVM Machine Learning Framework 2 | 3 | You should follow the guide to let it work in the enclave. 4 | 5 | 1. Install TVM 6 | ```shell 7 | $ git clone https://github.com/apache/tvm.git $HOME/tvm 8 | $ cd $HOME/tvm 9 | ``` 10 | 11 | 2. **Compile TVM and modify some settings.** 12 | ```shell 13 | $ mkdir build && cp ./cmake/config.cmake ./build 14 | $ cd build 15 | ``` 16 | Change the following keys to `ON`. This is very important. 17 | * `USE_MICRO` 18 | * `USE_MICRO_STANDALONE_RUNTIME` 19 | 20 | These keys allow the TVM to build a self-contained ML model; that is, the library build by TVM is a self-runnable bundle with the required interpreter runtime modules such as runtime::GraphExecutor, the graph JSON, and the params, which does not need to link against TVM runtime libraries anymore. 21 | 22 | Then compile it. 23 | ```shell 24 | $ cmake .. && make -j$(nproc) 25 | ``` 26 | 27 | 3. By default, you can set the `TVM_HOME` to `$HOME/tvm` or the parent directory from where the TVM libraries are built. 28 | 29 | 4. Then you may also need to configure the path python looks for (assume you have set `TVM_HOME`). 30 | 31 | ```shell 32 | $ export PYTHONPATH=$TVM_HOME/python:$TVM_HOME/topi/python:$TVM_HOME/nnvm/python:${PYTHONPATH} 33 | ``` 34 | 35 | 5. Build the standalone library for enclave, which will automatically copies the `libmodel_entry.a` to `./platform_sgx/lib`. 36 | 37 | ```shell 38 | $ cd ./model_deploy 39 | $ make 40 | ``` 41 | 42 | 6. Then rebuild the enclave. Now everything works. -------------------------------------------------------------------------------- /cctasks/evaluation_tvm/model_deploy/Makefile: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | MAGENTA := \e[0;35m 19 | NC := \e[0m 20 | 21 | # Setup build environment 22 | SGX_SDK ?= /opt/intel/sgxsdk 23 | TVM_HOME ?= $(HOME)/tvm 24 | CRT_ROOT ?= $(TVM_HOME)/build/standalone_crt 25 | ifeq ($(shell ls -lhd $(CRT_ROOT)),) 26 | $(error "CRT not found. Ensure you have built the standalone_crt target and try again") 27 | endif 28 | 29 | CRT_SRCS := $(shell find $(CRT_ROOT)) 30 | 31 | # Set python path. 32 | export PYTHONPATH = $(TVM_HOME)/python:$(shell echo $PYTHONPATH) 33 | 34 | DMLC_CORE=${TVM_HOME}/3rdparty/dmlc-core 35 | PKG_COMPILE_OPTS = -g -Wall -O2 -fPIC 36 | 37 | PKG_CFLAGS = ${PKG_COMPILE_OPTS} \ 38 | -I${TVM_HOME}/include \ 39 | -I${DMLC_CORE}/include \ 40 | -I${TVM_HOME}/3rdparty/dlpack/include \ 41 | -I. \ 42 | -DDMLC_USE_LOGGING_LIBRARY=\ 43 | 44 | PKG_LDFLAGS = -pthread -lm 45 | 46 | OUT_DIR := ../outlib 47 | BUNDLE := $(OUT_DIR)/libbundle.a 48 | MODEL_ENTRY_SRC := model_entry.c 49 | MODEL_TAR := $(OUT_DIR)/model.tar 50 | MODEL_ENTRY := ../../../platform_sgx/lib/libmodel_entry.a 51 | PYTHON_MODEL := $(OUT_DIR)/devc.o $(OUT_DIR)/lib0.o $(OUT_DIR)/lib1.o 52 | LIB_COMMON := $(OUT_DIR)/libcommon.a 53 | LIB_MEMORY := $(OUT_DIR)/libmemory.a 54 | LIB_GRAPH_EXECUTOR := $(OUT_DIR)/libgraph_executor.a 55 | 56 | .phony: all clean crt_libs 57 | 58 | all: $(OUT_DIR) $(MODEL_ENTRY) 59 | 60 | # The build logic of microTVM has changed. The old Makefile was removed. 61 | crt_libs: $(CRT_SRCS) 62 | @printf "$(MAGENTA)+ Building TVM CRT static library$(NC)\n" 63 | @cd $(CRT_ROOT) && mkdir -p build && cd build && cmake -DCRT_CONFIG_PATH=$(abspath .) -DCMAKE_C_FLAGS="${PKG_COMPILE_OPTS}" .. && make -j`nproc` 64 | @printf "$(MAGENTA)+ Finished! \n" 65 | 66 | $(OUT_DIR): 67 | @mkdir -p $@ 68 | 69 | $(MODEL_TAR): build_model.py 70 | @printf "$(MAGENTA)+ Building ML Model with TVM$(NC)\n" 71 | @python3 ./build_model.py -o $(OUT_DIR) 72 | 73 | $(PYTHON_MODEL): $(MODEL_TAR) 74 | @tar -xvf $^ -C $(OUT_DIR) > /dev/null 2>&1 75 | @printf "$(MAGENTA)+ Finished! \n" 76 | 77 | $(LIB_MEMORY): crt_libs 78 | @cp $(CRT_ROOT)/build/libmemory.a $@ 79 | 80 | $(LIB_GRAPH_EXECUTOR): crt_libs 81 | @cp $(CRT_ROOT)/build/libgraph_executor.a $@ 82 | 83 | $(LIB_COMMON): crt_libs 84 | @cp $(CRT_ROOT)/build/libcommon.a $@ 85 | 86 | $(BUNDLE): bundle.c 87 | @gcc -c -o $(OUT_DIR)/bundle.o $^ $(PKG_CFLAGS) $(PKG_LDFLAGS) 88 | @ar rcs $@ $(OUT_DIR)/bundle.o 89 | @rm -f $(OUT_DIR)/bundle.o 90 | 91 | # Extract all the object files and pack them into a single library. 92 | # This is a must. We have to make the whole bundle standalone. 93 | $(MODEL_ENTRY): $(MODEL_ENTRY_SRC) $(BUNDLE) $(PYTHON_MODEL) $(LIB_COMMON) $(LIB_GRAPH_EXECUTOR) $(LIB_MEMORY) 94 | @printf "$(MAGENTA)+ Packing the runtime into single static library:$(NC)\n" 95 | @mkdir -p ../../../platform_sgx/lib 96 | @mkdir -p $(OUT_DIR)/../tmp 97 | @gcc -c $(MODEL_ENTRY_SRC) -o $(OUT_DIR)/../tmp/model_entry.o $(PKG_CFLAGS) 98 | @cd $(OUT_DIR)/../tmp && ar -x $(BUNDLE) && ar -x $(LIB_COMMON) && ar -x $(LIB_GRAPH_EXECUTOR) && ar -x $(LIB_MEMORY) && ar -x $(SGX_SDK)/lib64/libsgx_tstdc.a 99 | @cd $(OUT_DIR)/../tmp && ar -crs $(MODEL_ENTRY) *.o $(PYTHON_MODEL) 100 | @rm -rf $(OUT_DIR)/../tmp 101 | @rm -rf $(OUT_DIR)/crt 102 | @printf "$(MAGENTA)+ Finished! \n" 103 | 104 | clean: 105 | @rm -rf $(OUT_DIR) 106 | -------------------------------------------------------------------------------- /cctasks/evaluation_tvm/model_deploy/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | How to Bundle TVM Modules 20 | ========================= 21 | 22 | This folder contains an example on how to bundle a TVM module (with the required 23 | interpreter runtime modules such as `runtime::GraphExecutor`, the graph JSON, and 24 | the params) into a single, self-contained shared object (`bundle.so`) which 25 | exposes a C API wrapping the appropriate `runtime::GraphExecutor` instance. 26 | 27 | This is useful for cases where we'd like to avoid deploying the TVM runtime 28 | components to the target host in advance - instead, we simply deploy the bundled 29 | shared-object to the host, which embeds both the model and the runtime 30 | components. The bundle should only depend on libc/libc++. 31 | 32 | It also contains an example code (`demo.cc`) to load this shared object and 33 | invoke the packaged TVM model instance. This is a dependency-free binary that 34 | uses the functionality packaged in `bundle.so` (which means that `bundle.so` can 35 | be deployed lazily at runtime, instead of at compile time) to invoke TVM 36 | functionality. 37 | 38 | Type the following command to run the sample code under the current folder, 39 | after building TVM first. 40 | 41 | ```bash 42 | make demo_dynamic 43 | ``` 44 | 45 | This will: 46 | 47 | - Download the mobilenet0.25 model from the MXNet Gluon Model Zoo 48 | - Compile the model with Relay 49 | - Build a `bundle.so` shared object containing the model specification and 50 | parameters 51 | - Build a `demo_dynamic` executable that `dlopen`'s `bundle.so` (or `bundle_c.so` in 52 | terms of the MISRA-C runtime), instantiates the contained graph executor, 53 | and invokes the `GraphExecutor::Run` function on a cat image, then prints 54 | the output results. 55 | 56 | Type the following command to run the sample code with static linking. 57 | 58 | ```bash 59 | make demo_static 60 | ``` 61 | 62 | This will: 63 | - Download the mobilenet0.25 model from the MXNet Gluon Model Zoo 64 | - Compile the model with Relay and outputs `model.o` 65 | - Build a `bundle_static.o` object containing the runtime functions 66 | - Build a `demo_static` executable which has static link to `bundle_static.o` and 67 | `model.o`, functions on a cat image, then prints the output results. 68 | -------------------------------------------------------------------------------- /cctasks/evaluation_tvm/model_deploy/bundle.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | #ifndef TVM_APPS_BUNDLE_DEPLOY_BUNDLE_H_ 21 | #define TVM_APPS_BUNDLE_DEPLOY_BUNDLE_H_ 22 | 23 | #include 24 | 25 | TVM_DLL void* tvm_runtime_create(const char* json_data, const char* params_data, 26 | const uint64_t params_size); 27 | 28 | TVM_DLL void tvm_runtime_destroy(void* runtime); 29 | 30 | TVM_DLL void tvm_runtime_set_input(void* runtime, const char* name, 31 | DLTensor* tensor); 32 | 33 | TVM_DLL void tvm_runtime_run(void* runtime); 34 | 35 | TVM_DLL void tvm_runtime_get_output(void* runtime, int32_t index, 36 | DLTensor* tensor); 37 | 38 | #endif /* TVM_APPS_BUNDLE_DEPLOY_BUNDLE_H_ */ 39 | -------------------------------------------------------------------------------- /cctasks/evaluation_tvm/model_deploy/cat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ya0guang/PoBF/8bc1a900fdae506d0a113250b94f594ae70f2762/cctasks/evaluation_tvm/model_deploy/cat.png -------------------------------------------------------------------------------- /cctasks/evaluation_tvm/model_deploy/crt_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | /*! 21 | * \file apps/bundle_deploy/crt_config.h 22 | * \brief CRT configuration for bundle_deploy app. 23 | */ 24 | #ifndef TVM_RUNTIME_CRT_CONFIG_H_ 25 | #define TVM_RUNTIME_CRT_CONFIG_H_ 26 | 27 | /*! Log level of the CRT runtime */ 28 | #define TVM_CRT_LOG_LEVEL TVM_CRT_LOG_LEVEL_DEBUG 29 | 30 | /*! Support low-level debugging in MISRA-C runtime */ 31 | #define TVM_CRT_DEBUG 0 32 | 33 | /*! Maximum supported dimension in NDArray */ 34 | #define TVM_CRT_MAX_NDIM 6 35 | /*! Maximum supported arguments in generated functions */ 36 | #define TVM_CRT_MAX_ARGS 10 37 | /*! Maximum supported string length in dltype, e.g. "int8", "int16", "float32" */ 38 | #define TVM_CRT_MAX_STRLEN_DLTYPE 10 39 | /*! Maximum supported string length in function names */ 40 | #define TVM_CRT_MAX_STRLEN_FUNCTION_NAME 120 41 | /*! Maximum supported string length in parameter names */ 42 | #define TVM_CRT_MAX_STRLEN_PARAM_NAME 80 43 | 44 | /*! Maximum number of registered modules. */ 45 | #define TVM_CRT_MAX_REGISTERED_MODULES 2 46 | 47 | /*! Size of the global function registry, in bytes. */ 48 | #define TVM_CRT_GLOBAL_FUNC_REGISTRY_SIZE_BYTES 512 49 | 50 | /*! Maximum packet size, in bytes, including the length header. */ 51 | #define TVM_CRT_MAX_PACKET_SIZE_BYTES 512 52 | 53 | #endif // TVM_RUNTIME_CRT_CONFIG_H_ 54 | -------------------------------------------------------------------------------- /cctasks/evaluation_tvm/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(not(feature = "std"), no_std)] 2 | 3 | extern crate alloc; 4 | 5 | use alloc::vec; 6 | use alloc::vec::Vec; 7 | 8 | const GRAPH_JSON: &'static [u8] = include_bytes!("../outlib/graph.json"); 9 | const GRAPH_PARAM: &'static [u8] = include_bytes!("../outlib/params.bin"); 10 | const GRAPH_OUTPUT_LEN: usize = 1000usize; 11 | 12 | extern "C" { 13 | fn tvm_resnet152_run( 14 | json: *const u8, 15 | json_size: usize, 16 | param: *const u8, 17 | param_size: usize, 18 | input: *const u8, 19 | input_size: usize, 20 | output: *mut u8, 21 | output_buf_size: usize, 22 | ) -> i32; 23 | } 24 | 25 | pub fn private_computation(input: Vec) -> Vec { 26 | let input_byte = input.as_slice(); 27 | let input_size = 1 * 3 * 224 * 224 * core::mem::size_of::(); 28 | 29 | let mut output = vec![0u8; GRAPH_OUTPUT_LEN * core::mem::size_of::()]; 30 | 31 | let res = unsafe { 32 | tvm_resnet152_run( 33 | GRAPH_JSON.as_ptr(), 34 | GRAPH_JSON.len(), 35 | GRAPH_PARAM.as_ptr(), 36 | GRAPH_PARAM.len(), 37 | input_byte.as_ptr(), 38 | input_size, 39 | output.as_mut_ptr(), 40 | GRAPH_OUTPUT_LEN * core::mem::size_of::(), 41 | ) 42 | }; 43 | 44 | if res != 0 { 45 | panic!("[-] TVM internal error. Check input size?"); 46 | } 47 | 48 | output 49 | } 50 | -------------------------------------------------------------------------------- /cctasks/fann/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fann" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /cctasks/fann/src/lib.rs: -------------------------------------------------------------------------------- 1 | // https://github.com/hanabi1224/Programming-Language-Benchmarks/blob/main/bench/algorithm/fannkuch-redux/1.rs 2 | 3 | #![cfg_attr(not(feature = "std"), no_std)] 4 | 5 | extern crate alloc; 6 | 7 | use alloc::vec::Vec; 8 | 9 | const V_SIZE: usize = 16; 10 | type VItem = usize; 11 | type V = [VItem; V_SIZE]; 12 | 13 | const NEXT_PERM_MASKS: [V; V_SIZE + 1] = next_perm_masks(); 14 | 15 | const fn shuffle(a: &V, mask: &V) -> V { 16 | let mut r = [0; V_SIZE]; 17 | let mut i = 0; 18 | while i < V_SIZE { 19 | r[i] = a[mask[i] as usize]; 20 | i += 1; 21 | } 22 | r 23 | } 24 | 25 | const fn reverse_mask(n: VItem) -> V { 26 | let mut v: V = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; 27 | let mut i = 0; 28 | while i < n { 29 | v[i as usize] = n - i - 1; 30 | i += 1; 31 | } 32 | v 33 | } 34 | 35 | const fn rotate_mask(n: VItem) -> V { 36 | let mut v = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; 37 | let mut i = 0; 38 | while i < n { 39 | v[i as usize] = (i + 1) % n; 40 | i += 1; 41 | } 42 | v 43 | } 44 | 45 | const fn next_perm_mask(n: VItem) -> V { 46 | let mut v = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; 47 | let mut i = 2; 48 | while i <= n { 49 | v = shuffle(&v, &rotate_mask(i)); 50 | i += 1; 51 | } 52 | v 53 | } 54 | 55 | const fn next_perm_masks() -> [V; V_SIZE + 1] { 56 | let mut v = [[0; V_SIZE]; V_SIZE + 1]; 57 | let mut i = 0; 58 | while i < V_SIZE + 1 { 59 | v[i] = next_perm_mask(i); 60 | i += 1; 61 | } 62 | v 63 | } 64 | 65 | const fn pfannkuchen(perm: &V) -> u32 { 66 | let mut flip_count = 0; 67 | let mut a = *perm; 68 | loop { 69 | let k = a[0]; 70 | if k == 0 { 71 | return flip_count; 72 | } 73 | a = shuffle(&a, &reverse_mask(k + 1)); 74 | flip_count += 1; 75 | } 76 | } 77 | 78 | const fn calculate(n: usize) -> (i32, u32) { 79 | let mut max_flip_count: u32 = 0; 80 | let mut checksum: i32 = 0; 81 | let mut perm = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; 82 | let mut count = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; 83 | let mut parity = false; 84 | loop { 85 | let flip_count = pfannkuchen(&perm); 86 | if flip_count > max_flip_count { 87 | max_flip_count = flip_count; 88 | } 89 | if parity { 90 | checksum -= flip_count as i32; 91 | } else { 92 | checksum += flip_count as i32; 93 | } 94 | let mut r = 0; 95 | let mut end = true; 96 | let mut i = 0; 97 | while i < n { 98 | if count[i] != 1 { 99 | r = i; 100 | end = false; 101 | break; 102 | } 103 | i += 1; 104 | } 105 | if end { 106 | break; 107 | } 108 | perm = shuffle(&perm, &NEXT_PERM_MASKS[r + 1]); 109 | count[r] -= 1; 110 | let mut i = 1; 111 | while i < r { 112 | count[i] = (i + 1) as u8; 113 | i += 1; 114 | } 115 | parity = !parity; 116 | } 117 | 118 | (checksum, max_flip_count) 119 | } 120 | 121 | pub fn private_computation(input: Vec) -> Vec { 122 | // Do not use usize because wasm is 32bit. 123 | let n = u64::from_le_bytes(input[..8].try_into().unwrap()) as usize; 124 | 125 | let (checksum, maxflips) = calculate(n); 126 | 127 | let mut ans = Vec::new(); 128 | ans.extend_from_slice(&checksum.to_le_bytes()); 129 | ans.extend_from_slice(&maxflips.to_le_bytes()); 130 | 131 | ans 132 | } 133 | -------------------------------------------------------------------------------- /cctasks/fasta/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fasta" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [features] 9 | default = ["sgx"] 10 | mirai = [] 11 | std = [] 12 | sgx = ["sgx_types"] 13 | 14 | [dependencies] 15 | sgx_types = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", branch = "v2.0.0-preview", package = "sgx_types", optional = true } -------------------------------------------------------------------------------- /cctasks/polybench/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "polybench" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | polybench-rs = { git = "https://github.com/hiroki-chen/polybench-rs.git" } 10 | sgx_types = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", branch = "v2.0.0-preview", package = "sgx_types", optional = true } 11 | 12 | [features] 13 | default = ["sgx"] 14 | std = [] 15 | sgx = ["sgx_types"] 16 | mirai = [] 17 | -------------------------------------------------------------------------------- /cctasks/sample_add/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sample_add" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | 10 | [features] 11 | mirai = [] 12 | std = [] 13 | -------------------------------------------------------------------------------- /cctasks/sample_add/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(not(feature = "std"), no_std)] 2 | extern crate alloc; 3 | 4 | use alloc::vec::Vec; 5 | 6 | pub fn private_computation(input: Vec) -> Vec { 7 | let step = 1; 8 | 9 | // this can be proven true by MIRAI 10 | #[cfg(feature = "leak_log")] 11 | { 12 | #[cfg(mirai)] 13 | verify!(step == 1); 14 | println!("The step is {} in computation_enc", step); 15 | } 16 | 17 | let mut output = Vec::new(); 18 | for i in input.iter() { 19 | output.push(i + step); 20 | } 21 | 22 | // however, MIRAI complians about this 23 | // leakage violation: cannot log the secret data 24 | // captured by: MIRAI warnning 25 | #[cfg(feature = "leak_log")] 26 | { 27 | #[cfg(mirai)] 28 | verify!(output[0] == 10); 29 | println!("after increasing, the 0th data is {}", output[0]); 30 | } 31 | 32 | // safety violation: cannot leak out secret data through network stream write 33 | // captured by: compiler error 34 | #[cfg(feature = "leak_net")] 35 | { 36 | use std::net::TcpStream; 37 | match TcpStream::connect("localhost:10086") { 38 | Ok(mut stream) => { 39 | stream.write(&output).unwrap(); 40 | } 41 | _ => { 42 | println!("failed to connect to server"); 43 | } 44 | } 45 | } 46 | 47 | // safety violation: cannot leak out secret data through file write 48 | // captured by: compiler error 49 | #[cfg(feature = "leak_file")] 50 | { 51 | use std::fs::File; 52 | let mut file = File::create("./leaked.txt").unwrap(); 53 | file.write_all(&output).unwrap(); 54 | } 55 | 56 | output 57 | } 58 | -------------------------------------------------------------------------------- /data/task_fann/data.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/task_fann/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "127.0.0.1", 3 | "port": 1234, 4 | "spid": "", 5 | "ias_key": "", 6 | "linkable": true, 7 | "data_path": "../../data/task_fann/data.bin", 8 | "ra_type": 1 9 | } 10 | -------------------------------------------------------------------------------- /data/task_fann/preprocess.py: -------------------------------------------------------------------------------- 1 | with open('./data.bin', 'wb') as f: 2 | f.write((12).to_bytes(8, 'little')) 3 | -------------------------------------------------------------------------------- /data/task_fasta/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "127.0.0.1", 3 | "port": 1234, 4 | "spid": "", 5 | "ias_key": "", 6 | "linkable": true, 7 | "data_path": "../../data/task_fasta/data.bin", 8 | "ra_type": 1 9 | } 10 | -------------------------------------------------------------------------------- /data/task_fasta/preprocess.py: -------------------------------------------------------------------------------- 1 | # Converts the DNA and n into a single binary file. 2 | 3 | n = int(25000000) 4 | output = n.to_bytes(8, 'little') 5 | 6 | with open('./sequence.fasta', 'r') as f: 7 | lines = f.readlines() 8 | 9 | for i in range(1, len(lines)): 10 | output += lines[i].rstrip('\n').encode() 11 | 12 | with open('./data.bin', 'wb') as f : 13 | f.write(output) 14 | 15 | print('OK!') 16 | -------------------------------------------------------------------------------- /data/task_polybench/data.bin: -------------------------------------------------------------------------------- 1 | 1 -------------------------------------------------------------------------------- /data/task_polybench/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "127.0.0.1", 3 | "port": 1234, 4 | "spid": "", 5 | "ias_key": "", 6 | "linkable": true, 7 | "data_path": "../../data/task_polybench/data.bin", 8 | "ra_type": 1 9 | } 10 | -------------------------------------------------------------------------------- /data/task_sample/data.bin: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /data/task_sample/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "127.0.0.1", 3 | "port": 1234, 4 | "spid": "", 5 | "ias_key": "", 6 | "linkable": true, 7 | "data_path": "../../data/task_sample/data.bin", 8 | "ra_type": 1 9 | } 10 | -------------------------------------------------------------------------------- /data/task_tvm/data.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ya0guang/PoBF/8bc1a900fdae506d0a113250b94f594ae70f2762/data/task_tvm/data.bin -------------------------------------------------------------------------------- /data/task_tvm/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "127.0.0.1", 3 | "port": 1234, 4 | "spid": "", 5 | "ias_key": "", 6 | "linkable": true, 7 | "data_path": "../../data/task_tvm/data.bin", 8 | "ra_type": 1 9 | } 10 | -------------------------------------------------------------------------------- /data_provider/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "data_provider" 3 | version = "0.1.0" 4 | edition = "2021" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [dependencies] 8 | aes = "0.8.1" 9 | aes-gcm = "0.10.1" 10 | base64 = "*" 11 | clap = { version = "3.1.5", features = ["derive"] } 12 | cmac = "0.7.1" 13 | curl = "0.4.44" 14 | env_logger = "0.9.1" 15 | log = { version = "0.4.17", features = [ 16 | "max_level_debug", 17 | "release_max_level_info", 18 | ] } 19 | pem = "1.1.0" 20 | pobf_crypto = { path = "../pobf_crypto", features = ["sgx"] } 21 | rand = { version = "0.8.5", features = ["std"] } 22 | ring = "0.16.20" 23 | serde = { version = "1.0.145", features = ["derive"] } 24 | serde_json = "1.0.86" 25 | sgx_types = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", branch = "v2.0.0-preview", package = "sgx_types" } 26 | sgx_urts = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", branch = "v2.0.0-preview", package = "sgx_urts" } 27 | -------------------------------------------------------------------------------- /data_provider/Makefile: -------------------------------------------------------------------------------- 1 | DataProvider_Rust_Flags ?= --release 2 | DataProvider_Rust_Files := $(wildcard ./src/*.rs) 3 | DataProvider_Enclave_Objects := ./lib/libenclave_u.a 4 | 5 | .PHONY: all clean 6 | 7 | all: tvl_enclave app 8 | 9 | tvl_enclave: 10 | @mkdir -p bin 11 | @mkdir -p lib 12 | @$(MAKE) -C ./tvl 13 | @cp ./tvl/enclave.signed.so ./lib 14 | $(AR) rcsD $(DataProvider_Enclave_Objects) ./tvl/App/Enclave_u.o 15 | 16 | app: $(DataProvider_Rust_Files) 17 | @cargo build $(DataProvider_Rust_Flags) 18 | @cp target/release/data_provider ./bin 19 | 20 | clean: 21 | @cargo clean 22 | @rm -rf bin 23 | @rm -rf lib 24 | @cd ./tvl && $(MAKE) clean -------------------------------------------------------------------------------- /data_provider/build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | 3 | fn main() { 4 | println!("cargo:rerun-if-env-changed=SGX_MODE"); 5 | println!("cargo:rerun-if-changed=build.rs"); 6 | 7 | let sdk_dir = env::var("SGX_SDK").unwrap_or_else(|_| "/opt/intel/sgxsdk".to_string()); 8 | let mode = env::var("SGX_MODE").unwrap_or_else(|_| "HW".to_string()); 9 | 10 | println!("cargo:rustc-link-search=native=./lib"); 11 | println!("cargo:rustc-link-lib=static=enclave_u"); 12 | 13 | println!("cargo:rustc-link-search=native={}/lib64", sdk_dir); 14 | // Link against TVL library. 15 | // println!("cargo:rustc-link-lib=static=sgx_dcap_tvl"); 16 | // You may need to execute 17 | // sudo ln -s /usr/lib/x86_64-linux-gnu/libsgx_dcap_quoteverify.so.1 /usr/lib/x86_64-linux-gnu/libsgx_dcap_quoteverify.so 18 | // sudo ln -s /usr/lib/x86_64-linux-gnu/libsgx_dcap_ql.so.1 /usr/lib/x86_64-linux-gnu/libsgx_dcap_ql.so 19 | println!("cargo:rustc-link-lib=dylib=sgx_dcap_quoteverify"); 20 | println!("cargo:rustc-link-lib=dylib=sgx_dcap_ql"); 21 | 22 | match mode.as_str() { 23 | "SW" | "SIM" => { 24 | println!("cargo:rustc-link-lib=dylib=sgx_urts_sim") 25 | } 26 | "HW" | "HYPER" => { 27 | println!("cargo:rustc-link-lib=dylib=sgx_urts"); 28 | } 29 | _ => { 30 | println!("cargo:rustc-link-lib=dylib=sgx_urts") 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /data_provider/cert.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ya0guang/PoBF/8bc1a900fdae506d0a113250b94f594ae70f2762/data_provider/cert.der -------------------------------------------------------------------------------- /data_provider/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICbzCCAhWgAwIBAgIUYoPMHkOlEJHtlnvTIKDV/Ladp5gwCgYIKoZIzj0EAwIw 3 | gYwxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdJbmRpYW5hMRQwEgYDVQQHDAtCbG9v 4 | bWluZ3RvbjEbMBkGA1UECgwSSW5kaWFuYSBVbml2ZXJzaXR5MSQwIgYDVQQLDBtM 5 | dWRkeSBTY2hvb2wgb2YgSW5mb3JtYXRpY3MxEjAQBgNVBAMMCTEyNy4wLjAuMTAe 6 | Fw0yMjEwMjEwMjUyMTNaFw0zMjEwMTgwMjUyMTNaMIGMMQswCQYDVQQGEwJVUzEQ 7 | MA4GA1UECAwHSW5kaWFuYTEUMBIGA1UEBwwLQmxvb21pbmd0b24xGzAZBgNVBAoM 8 | EkluZGlhbmEgVW5pdmVyc2l0eTEkMCIGA1UECwwbTHVkZHkgU2Nob29sIG9mIElu 9 | Zm9ybWF0aWNzMRIwEAYDVQQDDAkxMjcuMC4wLjEwWTATBgcqhkjOPQIBBggqhkjO 10 | PQMBBwNCAAQgaU4UnfRFlhxKBDT1AqWENEFR4AV6WpzZ7L6lV7tGTxdcxi1PNNXe 11 | 8hQXG6cj8gcCyYhy4DrgvduaWeqTnqZeo1MwUTAdBgNVHQ4EFgQUdF6of7qm511v 12 | tvMfbMWOe1jv7QEwHwYDVR0jBBgwFoAUdF6of7qm511vtvMfbMWOe1jv7QEwDwYD 13 | VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiA+zu0DCqma/pnpgEhx+oAy 14 | yGOxdFLHoZoAyN4ec4W+awIhAJfzb181oFh3G3qQT//VMv3AxwIU5hy0rmoNb9LS 15 | 5jem 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /data_provider/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgIWjy1dK84h5JoD8D 3 | X52DK13BlOe8YJCzAckdUzzOss+hRANCAAQgaU4UnfRFlhxKBDT1AqWENEFR4AV6 4 | WpzZ7L6lV7tGTxdcxi1PNNXe8hQXG6cj8gcCyYhy4DrgvduaWeqTnqZe 5 | -----END PRIVATE KEY----- -------------------------------------------------------------------------------- /data_provider/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "127.0.0.1", 3 | "port": 1234, 4 | "spid": "", 5 | "ias_key": "", 6 | "linkable": true, 7 | "data_path": "../../eval/identity_data/output_100000000.bin", 8 | "ra_type": 1 9 | } 10 | -------------------------------------------------------------------------------- /data_provider/src/main.rs: -------------------------------------------------------------------------------- 1 | mod handlers; 2 | mod utils; 3 | 4 | use clap::{Parser, Subcommand}; 5 | use handlers::*; 6 | use log::{debug, error, info}; 7 | use pobf_crypto::init_keypair; 8 | use sgx_types::{error::Quote3Error, types::*}; 9 | 10 | use std::io::*; 11 | 12 | use crate::utils::*; 13 | 14 | #[derive(Parser)] 15 | #[clap(author, version, about, long_about = None)] 16 | #[clap(propagate_version = true)] 17 | struct Args { 18 | #[clap(subcommand)] 19 | command: Commands, 20 | } 21 | 22 | #[derive(Subcommand)] 23 | enum Commands { 24 | Run { dp_manifest_path: String }, 25 | } 26 | 27 | /// Configurations for the IAS. 28 | const IAS_BASE_URL: &'static str = "https://api.trustedservices.intel.com"; 29 | /// Use the newest APIs. (v3 is decprecated.) 30 | const IAS_BASE_REQUEST: &'static str = "/sgx/dev/attestation/v4/"; 31 | const IAS_KEY_HEADER: &'static str = "Ocp-Apim-Subscription-Key"; 32 | const IAS_CONTENT_TYPE_HEADER: &'static str = "Content-Type"; 33 | const IAS_XIAS_SIGNCERT_HEADER: &'static str = "X-IASReport-Signing-Certificate"; 34 | const IAS_XIAS_SIG_HEADER: &'static str = "X-IASReport-Signature"; 35 | const IAS_QUOTE_TIMESTAMP: &'static str = "\"timestamp\""; 36 | const ISV_ENCLAVE_QUOTE_STATUS: &'static str = "\"isvEnclaveQuoteStatus\""; 37 | const PLATFORM_INFO_BLOB: &'static str = "\"platformInfoBlob\""; 38 | const ISV_ENCLAVE_QUOTE_BODY: &'static str = "\"isvEnclaveQuoteBody\""; 39 | const DEFAULT_MANIFEST_PATH: &'static str = "manifest.json"; 40 | 41 | /// The enclave path 42 | const ENCLAVE_FILE: &'static str = "../lib/enclave.signed.so"; 43 | 44 | extern "C" { 45 | fn sgx_tvl_verify_qve_report_and_identity( 46 | eid: EnclaveId, 47 | retval: *mut Quote3Error, 48 | p_quote: *const u8, 49 | quote_size: u32, 50 | p_qve_report_info: *const QlQeReportInfo, 51 | expiration_check_date: i64, 52 | collateral_expiration_status: u32, 53 | quote_verification_result: QlQvResult, 54 | p_supplemental_data: *const u8, 55 | supplemental_data_size: u32, 56 | qve_isvsvn_threshold: u16, 57 | ) -> Quote3Error; 58 | } 59 | 60 | fn main() { 61 | init_logger(); 62 | 63 | let mut key_pair = init_keypair().unwrap(); 64 | let args = Args::parse(); 65 | match args.command { 66 | Commands::Run { dp_manifest_path } => { 67 | let dp_information = 68 | parse_manifest(&dp_manifest_path).expect("[-] Sp manifest file IO error."); 69 | let socket = connect(&dp_information.address, &dp_information.port) 70 | .expect("[-] Cannot connect to the given address"); 71 | let socket_clone = socket.try_clone().unwrap(); 72 | let mut reader = BufReader::new(socket); 73 | let mut writer = BufWriter::new(socket_clone); 74 | 75 | let data = match dp_information.ra_type { 76 | 0 => exec_epid_workflow(&mut reader, &mut writer, &mut key_pair, &dp_information) 77 | .expect("[-] Failed to execute EPID workflow!"), 78 | 79 | 1 => exec_dcap_workflow(&mut reader, &mut writer, &mut key_pair, &dp_information) 80 | .expect("[-] Failed to execute DCAP workflow!"), 81 | 82 | _ => { 83 | error!("[-] Unrecognized remote attestation type!"); 84 | return; 85 | } 86 | }; 87 | 88 | debug!("[+] Received result: {:?}", data); 89 | 90 | use std::fs::File; 91 | use std::io::prelude::*; 92 | let mut file = File::create("./output.txt").unwrap(); 93 | file.write_all(&data).unwrap(); 94 | } 95 | } 96 | 97 | info!("[+] Finished!"); 98 | } 99 | -------------------------------------------------------------------------------- /data_provider/tvl/App/App.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2021 Intel Corporation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Intel Corporation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "App.h" 33 | #include "Enclave_u.h" 34 | 35 | /* Application entry */ 36 | int SGX_CDECL main(int argc, char *argv[]) 37 | { 38 | (void)(argc); 39 | (void)(argv); 40 | 41 | return 0; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /data_provider/tvl/App/App.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2021 Intel Corporation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Intel Corporation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | 33 | #ifndef _APP_H_ 34 | #define _APP_H_ 35 | 36 | #endif /* !_APP_H_ */ 37 | -------------------------------------------------------------------------------- /data_provider/tvl/Enclave/Enclave.config.xml: -------------------------------------------------------------------------------- 1 | 2 | 0 3 | 0 4 | 0x40000 5 | 0x100000 6 | 10 7 | 1 8 | 9 | 0 10 | 0 11 | 0xFFFFFFFF 12 | 13 | -------------------------------------------------------------------------------- /data_provider/tvl/Enclave/Enclave.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2021 Intel Corporation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Intel Corporation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #include "Enclave.h" 33 | #include "Enclave_t.h" /* print_string */ -------------------------------------------------------------------------------- /data_provider/tvl/Enclave/Enclave.edl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2021 Intel Corporation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Intel Corporation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | /* Enclave.edl - Top EDL file. */ 33 | 34 | enclave { 35 | include "sgx_qve_header.h" 36 | include "sgx_ql_quote.h" 37 | 38 | trusted { 39 | public quote3_error_t sgx_tvl_verify_qve_report_and_identity( 40 | [in, size=quote_size] const uint8_t *p_quote, 41 | uint32_t quote_size, 42 | [in, count=1] const sgx_ql_qe_report_info_t *p_qve_report_info, 43 | time_t expiration_check_date, 44 | uint32_t collateral_expiration_status, 45 | sgx_ql_qv_result_t quote_verification_result, 46 | [in, size=supplemental_data_size] const uint8_t *p_supplemental_data, 47 | uint32_t supplemental_data_size, 48 | sgx_isv_svn_t qve_isvsvn_threshold 49 | ); 50 | }; 51 | }; 52 | -------------------------------------------------------------------------------- /data_provider/tvl/Enclave/Enclave.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2021 Intel Corporation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Intel Corporation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | #ifndef _ENCLAVE_H_ 33 | #define _ENCLAVE_H_ 34 | 35 | #if defined(__cplusplus) 36 | extern "C" { 37 | #endif 38 | 39 | #if defined(__cplusplus) 40 | } 41 | #endif 42 | 43 | #endif /* !_ENCLAVE_H_ */ 44 | -------------------------------------------------------------------------------- /data_provider/tvl/Enclave/Enclave.lds: -------------------------------------------------------------------------------- 1 | enclave.so 2 | { 3 | global: 4 | g_global_data_sim; 5 | g_global_data; 6 | enclave_entry; 7 | g_peak_heap_used; 8 | g_peak_rsrv_mem_committed; 9 | local: 10 | *; 11 | }; 12 | -------------------------------------------------------------------------------- /data_provider/tvl/Enclave/Enclave_private_test.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIG4gIBAAKCAYEAroOogvsj/fZDZY8XFdkl6dJmky0lRvnWMmpeH41Bla6U1qLZ 3 | AmZuyIF+mQC/cgojIsrBMzBxb1kKqzATF4+XwPwgKz7fmiddmHyYz2WDJfAjIveJ 4 | ZjdMjM4+EytGlkkJ52T8V8ds0/L2qKexJ+NBLxkeQLfV8n1mIk7zX7jguwbCG1Pr 5 | nEMdJ3Sew20vnje+RsngAzdPChoJpVsWi/K7cettX/tbnre1DL02GXc5qJoQYk7b 6 | 3zkmhz31TgFrd9VVtmUGyFXAysuSAb3EN+5VnHGr0xKkeg8utErea2FNtNIgua8H 7 | ONfm9Eiyaav1SVKzPHlyqLtcdxH3I8Wg7yqMsaprZ1n5A1v/levxnL8+It02KseD 8 | 5HqV4rf/cImSlCt3lpRg8U5E1pyFQ2IVEC/XTDMiI3c+AR+w2jSRB3Bwn9zJtFlW 9 | KHG3m1xGI4ck+Lci1JvWWLXQagQSPtZTsubxTQNx1gsgZhgv1JHVZMdbVlAbbRMC 10 | 1nSuJNl7KPAS/VfzAgEDAoIBgHRXxaynbVP5gkO0ug6Qw/E27wzIw4SmjsxG6Wpe 11 | K7kfDeRskKxESdsA/xCrKkwGwhcx1iIgS5+Qscd1Yg+1D9X9asd/P7waPmWoZd+Z 12 | AhlKwhdPsO7PiF3e1AzHhGQwsUTt/Y/aSI1MpHBvy2/s1h9mFCslOUxTmWw0oj/Q 13 | ldIEgWeNR72CE2+jFIJIyml6ftnb6qzPiga8Bm48ubKh0kvySOqnkmnPzgh+JBD6 14 | JnBmtZbfPT97bwTT+N6rnPqOOApvfHPf15kWI8yDbprG1l4OCUaIUH1AszxLd826 15 | 5IPM+8gINLRDP1MA6azECPjTyHXhtnSIBZCyWSVkc05vYmNXYUNiXWMajcxW9M02 16 | wKzFELO8NCEAkaTPxwo4SCyIjUxiK1LbQ9h8PSy4c1+gGP4LAMR8xqP4QKg6zdu9 17 | osUGG/xRe/uufgTBFkcjqBHtK5L5VI0jeNIUAgW/6iNbYXjBMJ0GfauLs+g1VsOm 18 | WfdgXzsb9DYdMa0OXXHypmV4GwKBwQDUwQj8RKJ6c8cT4vcWCoJvJF00+RFL+P3i 19 | Gx2DLERxRrDa8AVGfqaCjsR+3vLgG8V/py+z+dxZYSqeB80Qeo6PDITcRKoeAYh9 20 | xlT3LJOS+k1cJcEmlbbO2IjLkTmzSwa80fWexKu8/Xv6vv15gpqYl1ngYoqJM3pd 21 | vzmTIOi7MKSZ0WmEQavrZj8zK4endE3v0eAEeQ55j1GImbypSf7Idh7wOXtjZ7WD 22 | Dg6yWDrri+AP/L3gClMj8wsAxMV4ZR8CgcEA0fzDHkFa6raVOxWnObmRoDhAtE0a 23 | cjUj976NM5yyfdf2MrKy4/RhdTiPZ6b08/lBC/+xRfV3xKVGzacm6QjqjZrUpgHC 24 | 0LKiZaMtccCJjLtPwQd0jGQEnKfMFaPsnhOc5y8qVkCzVOSthY5qhz0XNotHHFmJ 25 | gffVgB0iqrMTvSL7IA2yqqpOqNRlhaYhNl8TiFP3gIeMtVa9rZy31JPgT2uJ+kfo 26 | gV7sdTPEjPWZd7OshGxWpT6QfVDj/T9T7L6tAoHBAI3WBf2DFvxNL2KXT2QHAZ9t 27 | k3imC4f7U+wSE6zILaDZyzygA4RUbwG0gv8/TJVn2P/Eynf76DuWHGlaiLWnCbSz 28 | Az2DHBQBBaku409zDQym3j1ugMRjzzSQWzJg0SIyBH3hTmnYcn3+Uqcp/lEBvGW6 29 | O+rsXFt3pukqJmIV8HzLGGaLm62BHUeZf3dyWm+i3p/hQAL7Xvu04QW70xuGqdr5 30 | afV7p5eaeQIJXyGQJ0eylV/90+qxjMKiB1XYg6WYvwKBwQCL/ddpgOdHJGN8uRom 31 | e7Zq0Csi3hGheMKlKbN3vcxT5U7MdyHtTZZOJbTvxKNNUNYH/8uD+PqDGNneb29G 32 | BfGzvI3EASyLIcGZF3OhKwZd0jUrWk2y7Vhob91jwp2+t73vdMbkKyI4mHOuXvGv 33 | fg95si9oO7EBT+Oqvhccd2J+F1IVXncccYnF4u5ZGWt5lLewN/pVr7MjjykeaHqN 34 | t+rfnQam2psA6fL4zS2zTmZPzR2tnY8Y1GBTi0Ko1OKd1HMCgcAb5cB/7/AQlhP9 35 | yQa04PLH9ygQkKKptZp7dy5WcWRx0K/hAHRoi2aw1wZqfm7VBNu2SLcs90kCCCxp 36 | 6C5sfJi6b8NpNbIPC+sc9wsFr7pGo9SFzQ78UlcWYK2Gu2FxlMjonhka5hvo4zvg 37 | WxlpXKEkaFt3gLd92m/dMqBrHfafH7VwOJY2zT3WIpjwuk0ZzmRg5p0pG/svVQEH 38 | NZmwRwlopysbR69B/n1nefJ84UO50fLh5s5Zr3gBRwbWNZyzhXk= 39 | -----END RSA PRIVATE KEY----- 40 | -------------------------------------------------------------------------------- /data_provider/tvl/Enclave/config.01.xml: -------------------------------------------------------------------------------- 1 | 2 | 0 3 | 0 4 | 5 | 6 | 7 | 8 | 10 9 | 10 10 | 10 11 | 12 | 1 13 | 14 | 15 | 0x40000 16 | 17 | 19 | 20 | 0x100000 21 | 0x100000 22 | 0x100000 23 | 24 | 25 | 0 26 | 0 27 | 0xFFFFFFFF 28 | 29 | -------------------------------------------------------------------------------- /data_provider/tvl/Enclave/config.02.xml: -------------------------------------------------------------------------------- 1 | 2 | 0 3 | 0 4 | 0x40000 5 | 6 | 13 | 0x100000 14 | 0x40000 15 | 0x1000 16 | 17 | 10 18 | 10 19 | 10 20 | 1 21 | 22 | 0 23 | 0 24 | 0xFFFFFFFF 25 | 26 | -------------------------------------------------------------------------------- /data_provider/tvl/Enclave/config.03.xml: -------------------------------------------------------------------------------- 1 | 2 | 0 3 | 0 4 | 5 | 8 | 10 9 | 3 10 | 1 11 | 12 | 13 | 16 | 0x40000 17 | 0x40000 18 | 19 | 20 | 21 | 0x100000 22 | 23 | 24 | 0 25 | 0 26 | 0xFFFFFFFF 27 | 28 | -------------------------------------------------------------------------------- /data_provider/tvl/Enclave/config.04.xml: -------------------------------------------------------------------------------- 1 | 2 | 0 3 | 0 4 | 5 | 10 6 | 3 7 | 1 8 | 9 | 10 | 14 | 0x40000 15 | 0x2000 16 | 17 | 0x100000 18 | 19 | 20 | 0 21 | 0 22 | 0xFFFFFFFF 23 | 24 | -------------------------------------------------------------------------------- /data_provider/tvl/Include/user_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2021 Intel Corporation. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Intel Corporation nor the names of its 15 | * contributors may be used to endorse or promote products derived 16 | * from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | 32 | 33 | /* User defined types */ 34 | 35 | 36 | #define LOOPS_PER_THREAD 500 37 | 38 | typedef void *buffer_t; 39 | typedef int array_t[10]; 40 | 41 | -------------------------------------------------------------------------------- /data_provider_sev/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "data_provider_sev" 3 | version = "0.1.0" 4 | edition = "2021" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [dependencies] 8 | aes-gcm = "0.10.1" 9 | clap = { version = "4.2.7", features = ["derive"] } 10 | env_logger = "0.10.0" 11 | log = "0.4.17" 12 | pobf_crypto = { path = "../pobf_crypto", features = [ 13 | "sev", 14 | ], default-features = false } 15 | serde = { version = "1.0.160", features = ["serde_derive"] } 16 | serde_json = "1.0.96" 17 | -------------------------------------------------------------------------------- /data_provider_sev/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | fs, 3 | fs::File, 4 | io::{BufRead, BufReader, BufWriter, Error, ErrorKind, Read, Result, Write}, 5 | net::TcpStream, 6 | }; 7 | 8 | use clap::{Parser, Subcommand}; 9 | use log::info; 10 | use pobf_crypto::{handle_sev_pubkey, init_keypair, KeyPair}; 11 | use serde::{Deserialize, Serialize}; 12 | 13 | const DEFAULT_MANIFEST_PATH: &str = "manifest.json"; 14 | 15 | #[derive(Parser)] 16 | #[clap(author, version, about, long_about = None)] 17 | #[clap(propagate_version = true)] 18 | struct Args { 19 | #[clap(subcommand)] 20 | command: Commands, 21 | } 22 | 23 | #[derive(Subcommand)] 24 | enum Commands { 25 | Run { manifest_path: String }, 26 | } 27 | 28 | #[derive(Deserialize, Serialize)] 29 | pub struct DpInformation { 30 | pub address: String, 31 | pub port: u16, 32 | pub data_path: String, 33 | } 34 | 35 | fn init_logger() { 36 | if std::env::var("RUST_LOG").is_err() { 37 | std::env::set_var("RUST_LOG", "info"); 38 | } 39 | env_logger::init(); 40 | } 41 | 42 | fn main() { 43 | init_logger(); 44 | 45 | let args = Args::parse(); 46 | 47 | match args.command { 48 | Commands::Run { manifest_path } => { 49 | let f = File::open(&manifest_path) 50 | .or_else(|_| File::open(DEFAULT_MANIFEST_PATH)) 51 | .unwrap(); 52 | let manifest = serde_json::from_reader::<_, DpInformation>(f) 53 | .expect("[-] Failed to parse the manifest"); 54 | let socket = connect(&manifest.address, manifest.port) 55 | .expect("[-] Cannot connect to the given address"); 56 | let socket_clone = socket.try_clone().unwrap(); 57 | let mut reader = BufReader::new(socket); 58 | let mut writer = BufWriter::new(socket_clone); 59 | 60 | let key_pair = init_keypair().unwrap(); 61 | let data = exec_sev_workflow(&mut reader, &mut writer, &manifest.data_path, key_pair) 62 | .expect("[-] failed to execute SEV workflow"); 63 | fs::write("./output.txt", &data).unwrap(); 64 | info!("[+] Finished"); 65 | } 66 | } 67 | } 68 | 69 | pub fn connect(address: &str, port: u16) -> Result { 70 | // Create the full address for the server. 71 | let mut full_address = String::new(); 72 | full_address.push_str(address); 73 | full_address.push_str(":"); 74 | full_address.push_str(&port.to_string()); 75 | 76 | info!("[+] Connecting to {}", full_address); 77 | 78 | TcpStream::connect(&full_address) 79 | } 80 | 81 | pub fn exec_sev_workflow( 82 | reader: &mut BufReader, 83 | writer: &mut BufWriter, 84 | data_path: &str, 85 | mut key_pair: KeyPair, 86 | ) -> Result> { 87 | let public_key = &key_pair.pub_k; 88 | info!("[+] Receiving the attestation report"); 89 | let mut len = String::with_capacity(128); 90 | reader.read_line(&mut len)?; 91 | let report_len = len[..len.len() - 1] 92 | .parse::() 93 | .map_err(|_| Error::from(ErrorKind::InvalidData))?; 94 | let mut report = vec![0u8; report_len]; 95 | reader.read_exact(&mut report)?; 96 | 97 | info!("[+] Sending public key"); 98 | writer.write_all(public_key.as_ref())?; 99 | writer.flush()?; 100 | 101 | info!("[+] Receiving peer public key"); 102 | let peer_pub_key = handle_sev_pubkey(reader).unwrap(); 103 | key_pair.compute_shared_key(&peer_pub_key, b"").unwrap(); 104 | 105 | info!("[+] Sending data..."); 106 | // Read the data and encrypt it. 107 | let data = key_pair.encrypt_with_smk(&fs::read(data_path)?).unwrap(); 108 | writer.write_all(data.len().to_string().as_bytes())?; 109 | writer.write_all(b"\n")?; 110 | writer.flush()?; 111 | writer.write_all(&data)?; 112 | writer.flush()?; 113 | 114 | info!("[+] Receiving the data..."); 115 | len.clear(); 116 | reader.read_line(&mut len)?; 117 | let buf_len = len[..len.len() - 1].parse::().unwrap(); 118 | let mut buf = vec![0u8; buf_len]; 119 | reader.read_exact(&mut buf)?; 120 | 121 | // Decrypt the data. 122 | Ok(key_pair.decrypt_with_smk(&buf).unwrap()) 123 | } 124 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | 3 | ARG SGX_SDK_VERSION_MAJOR=2.17.1 4 | ARG SGX_SDK_VERSION_MINOR=2.17.101.1 5 | ARG DEV_PRUSTI_GIT_REPO=https://github.com/viperproject/prusti-dev.git 6 | ARG DEV_PRUSTI_COMMIT=ee91e7772e764c910b1e6638f609ad5da0a791a7 7 | ARG MIRAI_GIT_REPO=https://github.com/facebookexperimental/MIRAI.git 8 | ARG MIRAI_COMMIT=5ca2f1ebe1b057ba74438782e2bef91ec87834c4 9 | ARG RUST_COMP="rust-src rustc-dev llvm-tools-preview rustfmt rust-analysis" 10 | ARG RUST_TOOLCHAIN=nightly-2022-11-01 11 | 12 | SHELL ["/bin/bash", "-c"] 13 | 14 | RUN apt update && DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt install -y \ 15 | build-essential \ 16 | libtool \ 17 | autoconf \ 18 | python \ 19 | curl \ 20 | git \ 21 | wget \ 22 | python3 \ 23 | python3-pip 24 | 25 | RUN mkdir /tmp/cmake_install 26 | WORKDIR /tmp/cmake_install 27 | RUN wget -O ./install.sh https://github.com/Kitware/CMake/releases/download/v3.25.0/cmake-3.25.0-linux-x86_64.sh && chmod +x ./install.sh 28 | RUN ./install.sh --skip-license --exclude-subdir --prefix=/usr/local 29 | WORKDIR /root 30 | RUN rm -r /tmp/cmake_install 31 | 32 | RUN echo 'deb [arch=amd64] https://download.01.org/intel-sgx/sgx_repo/ubuntu focal main' | tee /etc/apt/sources.list.d/intel-sgx.list 33 | RUN wget -qO - https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key | apt-key add 34 | 35 | RUN apt update && apt install -y \ 36 | libsgx-epid \ 37 | libsgx-quote-ex \ 38 | libsgx-dcap-ql \ 39 | libsgx-dcap-default-qpl \ 40 | libsgx-uae-service \ 41 | libsgx-urts-dbgsym \ 42 | libsgx-enclave-common-dbgsym \ 43 | libsgx-uae-service-dbgsym \ 44 | libsgx-dcap-ql-dbgsym \ 45 | libsgx-dcap-default-qpl-dbgsym 46 | 47 | WORKDIR /root/Downloads 48 | 49 | RUN wget https://download.01.org/intel-sgx/sgx-linux/${SGX_SDK_VERSION_MAJOR}/distro/ubuntu20.04-server/sgx_linux_x64_sdk_${SGX_SDK_VERSION_MINOR}.bin 50 | RUN chmod +x sgx_linux_x64_sdk_${SGX_SDK_VERSION_MINOR}.bin 51 | RUN printf "no\n/opt/intel\n" | ./sgx_linux_x64_sdk_${SGX_SDK_VERSION_MINOR}.bin 52 | RUN echo 'source /opt/intel/sgxsdk/environment' >> /root/.bashrc 53 | 54 | RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y 55 | RUN echo 'source "$HOME/.cargo/env"' >> /root/.bashrc 56 | RUN source "$HOME/.cargo/env" && rustup toolchain install ${RUST_TOOLCHAIN} 57 | 58 | RUN echo "[+] Configuring Prusti..." 59 | RUN git clone ${DEV_PRUSTI_GIT_REPO} 60 | 61 | WORKDIR /root/Downloads/prusti-dev 62 | RUN git checkout ${DEV_PRUSTI_COMMIT} 63 | 64 | RUN source "$HOME/.cargo/env" && rustup component add --toolchain ${RUST_TOOLCHAIN} ${RUST_COMP} 65 | RUN apt update && DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC \ 66 | apt install -y \ 67 | unzip \ 68 | default-jre \ 69 | openssl \ 70 | libssl-dev \ 71 | pkg-config \ 72 | sudo \ 73 | libclang-dev 74 | 75 | RUN source "$HOME/.cargo/env" && rustup override set ${RUST_TOOLCHAIN} && ./x.py setup && ./x.py build --release 76 | RUN source "$HOME/.cargo/env" && ./x.py package release $HOME/.local/prusti 77 | RUN echo "[-] Prusti successfully compiled and installed!" 78 | 79 | RUN ln -s /usr/lib/x86_64-linux-gnu/libsgx_dcap_quoteverify.so.1 /usr/lib/x86_64-linux-gnu/libsgx_dcap_quoteverify.so 80 | RUN ln -s /usr/lib/x86_64-linux-gnu/libsgx_dcap_ql.so.1 /usr/lib/x86_64-linux-gnu/libsgx_dcap_ql.so 81 | 82 | WORKDIR /root 83 | RUN git clone ${MIRAI_GIT_REPO} 84 | WORKDIR /root/MIRAI 85 | RUN git checkout ${MIRAI_COMMIT} 86 | RUN source "$HOME/.cargo/env" && rustup override set ${RUST_TOOLCHAIN} 87 | RUN source "$HOME/.cargo/env" && cargo install --locked --path ./checker 88 | 89 | WORKDIR /root 90 | RUN git clone https://github.com/apache/tvm.git 91 | WORKDIR /root/tvm 92 | RUN git submodule init && git submodule update 93 | RUN apt update && \ 94 | apt install -y \ 95 | python3-dev \ 96 | python3-setuptools \ 97 | gcc \ 98 | libtinfo-dev \ 99 | zlib1g-dev \ 100 | libedit-dev \ 101 | libxml2-dev \ 102 | llvm 103 | 104 | RUN mkdir build && cp cmake/config.cmake build 105 | WORKDIR /root/tvm/build 106 | RUN sed -i -e 's/USE_LLVM\sOFF/USE_LLVM ON/g' config.cmake 107 | RUN sed -i -e 's/USE_MICRO\sOFF/USE_MICRO ON/g' config.cmake 108 | RUN sed -i -e 's/USE_MICRO_STANDALONE_RUNTIME\sOFF/USE_MICRO_STANDALONE_RUNTIME ON/g' config.cmake 109 | RUN cmake .. && make -j$((`nproc`+1)) 110 | 111 | WORKDIR /root 112 | 113 | ENTRYPOINT ["bash", "-l", "-c"] 114 | -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | # Build the image 2 | 3 | ```sh 4 | docker build -t ya0guang/pobf --build-arg RUST_TOOLCHAIN=$(cat ../rust-toolchain) . 5 | ``` 6 | 7 | # Run the image WITH SGX support 8 | 9 | ## Interactive Shell 10 | 11 | ```sh 12 | docker run -it --entrypoint /bin/bash -v /var/run/aesmd:/var/run/aesmd --device=/dev/sgx/enclave --device=/dev/sgx/provision -v $(pwd)/..:/Code/PoBF -v ya0guang/pobf 13 | ``` 14 | 15 | ## Simple Commands 16 | 17 | ```sh 18 | docker run -it --entrypoint /bin/bash -v /var/run/aesmd:/var/run/aesmd --device=/dev/sgx/enclave --device=/dev/sgx/provision -v $(pwd)/..:/Code/PoBF -v ya0guang/pobf "COMMAND_TO_RUN" 19 | ``` 20 | 21 | e.g., `make` and `make clean`. 22 | -------------------------------------------------------------------------------- /others/enarx/Enarx.toml: -------------------------------------------------------------------------------- 1 | [[files]] 2 | kind = "stdin" 3 | 4 | [[files]] 5 | kind = "stdout" 6 | 7 | [[files]] 8 | kind = "stderr" 9 | 10 | [[files]] 11 | kind = "listen" 12 | prot = "tcp" 13 | port = 7788 14 | name = "TEST_TCP_LISTEN" 15 | 16 | [[files]] 17 | kind = "null" 18 | -------------------------------------------------------------------------------- /others/enarx/README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | This module is made for enarx runtime that runs the confidential computing. To make enarx run, you need to set up the rust target for `wasm32-wasi`, which can be done by 4 | 5 | ```sh 6 | $ rustup target add wasm32-wasi 7 | ``` 8 | 9 | Also, make sure that you have tvm installed and all the environment variables set. Specifically, you should set `TVM_HOME` and `PYTHONPATH`. 10 | 11 | Finally, follow the instruction [here](https://github.com/apache/tvm/tree/main/apps/wasm-standalone) for building the WASM module of ResNet152 model. 12 | 13 | **Warning:** The instruction "Build wasm-graph package" is somehow not correct. You may need to run the following command: 14 | 15 | ```sh 16 | $ cd tools 17 | $ export TVM_HOME=... 18 | $ export PYTHONPATH=... 19 | $ LLVM_AR=llvm-ar-10 python3 ./build_graph_lib.py -O3 20 | ``` 21 | 22 | Enarx needs to link against `wasm-runtime` for creating a runtime for TVM graph executor. 23 | 24 | ## Problems (fixed) 25 | 26 | 1. Cannot build `wasm-runtime` for `wasi`. Caused by `cranelift-codegen`: 27 | ```sh 28 | thread 'main' panicked at 'error when identifying target: "no supported isa found for arch `wasm32`"'. 29 | ``` 30 | 31 | This is because wastime needs a JIT backend but WASI does not support this. You need to instead compile wasi target from barebone Rust programs. 32 | 33 | 2. tokio for wasm32-wasi does not support multithreading for `async fn main`. 34 | 35 | 3. Enarx may not support `std::thread::spawn` (?). See issues. 36 | -------------------------------------------------------------------------------- /others/enarx/client/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "client" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /others/enarx/client/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::fs; 3 | use std::io::*; 4 | use std::net::TcpStream; 5 | 6 | const ADDRESS: &str = "127.0.0.1:7788"; 7 | 8 | fn main() { 9 | let stream = TcpStream::connect(ADDRESS).unwrap(); 10 | let stream_clone = stream.try_clone().unwrap(); 11 | let mut reader = BufReader::new(stream); 12 | let mut writer = BufWriter::new(stream_clone); 13 | 14 | let args: Vec = env::args().collect(); 15 | let data_path = &args[1]; 16 | let data = fs::read(data_path).unwrap(); 17 | println!("Reading {}", data_path); 18 | 19 | // Send to the server. 20 | writer.write(&data.len().to_le_bytes()).unwrap(); 21 | writer.flush().unwrap(); 22 | writer.write(&data).unwrap(); 23 | writer.flush().unwrap(); 24 | println!("Sent data. Length = {}", data.len()); 25 | 26 | let mut length_str = String::with_capacity(512); 27 | reader.read_line(&mut length_str).unwrap(); 28 | let data_len = length_str[..length_str.len() - 1].parse::().unwrap(); 29 | println!("Data length = {}", data_len); 30 | let mut input = vec![0u8; data_len]; 31 | reader.read_to_end(&mut input).unwrap(); 32 | println!("Read data: {:02x?}", &input[..100]); 33 | println!("Finished"); 34 | writer.write(b"ok").unwrap(); 35 | writer.flush().unwrap(); 36 | } 37 | -------------------------------------------------------------------------------- /others/enarx/server/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-wasi" 3 | 4 | # Must set this key or tokio won't compile. 5 | [target.wasm32-wasi] 6 | runner = ["wasmtime", "--dir", ".", "run", "--tcplisten", "127.0.0.1:7788"] 7 | rustflags = [ "--cfg", "tokio_unstable"] 8 | -------------------------------------------------------------------------------- /others/enarx/server/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "server" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [features] 9 | default = [] 10 | task_db = ["db"] 11 | task_sample = ["sample_add"] 12 | task_tvm = [] 13 | task_polybench = ["polybench"] 14 | task_fann = ["fann"] 15 | task_fasta = ["fasta"] 16 | 17 | [dependencies] 18 | # Evaluations. 19 | # wasm-runtime = { path = "../tvm-wasm/wasm-runtime", optional = true } 20 | fann = { path = "../../../cctasks/fann", optional = true } 21 | fasta = { path = "../../../cctasks/fasta", optional = true } 22 | polybench = { path = "../../../cctasks/polybench", optional = true } 23 | sample_add = { path = "../../../cctasks/sample_add", optional = true } 24 | db = { path = "../../../cctasks/db", optional = true } 25 | cfg-if = "1.0.0" 26 | tokio = { version = "1.25.0", features = ["full"] } 27 | -------------------------------------------------------------------------------- /others/enarx/server/src/db_persistent.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | io::{Read, Write}, 3 | os::fd::FromRawFd, 4 | time, 5 | }; 6 | 7 | use db::db::{DbError, DbResult, Persistent}; 8 | pub struct SgxPersistentLayer; 9 | 10 | impl Persistent for SgxPersistentLayer { 11 | fn write_disk(&self, path: &str, buf: &[u8]) -> DbResult<()> { 12 | println!("writing {path} with buf.len() = {} bytes", buf.len()); 13 | 14 | let now = time::Instant::now(); 15 | let mut file = unsafe { std::fs::File::from_raw_fd(4) }; 16 | file.write_all(buf).map_err(|_| DbError::Unknown)?; 17 | let elapsed: time::Duration = now.elapsed(); 18 | 19 | let throughput = (buf.len() as f64 / elapsed.as_secs_f64()) / 1000000.0; 20 | 21 | println!("[+] Time elapsed: {elapsed:?}; throughput: {throughput} MB/s"); 22 | 23 | Ok(()) 24 | } 25 | 26 | fn read_disk(&self, path: &str) -> DbResult> { 27 | println!("reading {path}"); 28 | 29 | let now = time::Instant::now(); 30 | let mut buf = vec![]; 31 | unsafe { std::fs::File::from_raw_fd(4) } 32 | .read_to_end(&mut buf) 33 | .map_err(|_| DbError::PathNotFound(path.into()))?; 34 | let elapsed: time::Duration = now.elapsed(); 35 | 36 | let throughput = (buf.len() as f64 / elapsed.as_secs_f64()) / 1000000.0; 37 | 38 | println!("[+] Time elapsed: {elapsed:?}; throughput: {throughput} MB/s"); 39 | 40 | Ok(buf) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /others/enarx/server/src/main.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_imports)] 2 | #![allow(unused_variables)] 3 | #![allow(dead_code)] 4 | 5 | mod task; 6 | #[cfg(feature ="task_db")] 7 | mod db_persistent; 8 | 9 | use std::env; 10 | use std::io::Result; 11 | use tokio::net::{TcpListener, TcpStream}; 12 | use std::os::fd::FromRawFd; 13 | use std::str::FromStr; 14 | 15 | use crate::task::handle_client; 16 | 17 | const ENCLAVE_TCS_NUM: usize = 10; 18 | const ADDRESS: &str = "127.0.0.1:7788"; 19 | 20 | #[tokio::main(flavor = "current_thread")] 21 | async fn main() -> Result<()> { 22 | { 23 | let fd_names = env::var("FD_NAMES").unwrap(); 24 | let fd_count = env::var("FD_COUNT").unwrap(); 25 | 26 | println!("{fd_names}, {fd_count}."); 27 | let fd_count = usize::from_str(&fd_count).unwrap(); 28 | assert!( 29 | fd_count <= 5, // STDIN, STDOUT, STDERR and a socket, and a db file. 30 | "unexpected amount of file descriptors received" 31 | ); 32 | println!("Enarx FD NUM check passed"); 33 | } 34 | 35 | let listener = { 36 | let listener = unsafe { std::net::TcpListener::from_raw_fd(3) }; 37 | listener.set_nonblocking(true).unwrap(); 38 | TcpListener::from_std(listener)? 39 | }; 40 | 41 | println!("Server started."); 42 | #[cfg(feature = "task_db")] 43 | db::DUMPER.call_once(|| Box::new(db_persistent::SgxPersistentLayer)); 44 | 45 | loop { 46 | let socket = match listener.accept().await { 47 | Ok((socket, _)) => socket, 48 | Err(e) => panic!("[-] Failed! {:?}", e), 49 | }; 50 | 51 | // Spawn a background task for each new connection. 52 | tokio::task::spawn(async move { 53 | println!("> CONNECTED"); 54 | match handle_client(socket).await { 55 | Ok(()) => println!("> DISCONNECTED"), 56 | Err(e) => println!("> ERROR: {}", e), 57 | } 58 | }); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /others/enarx/server/src/task.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_imports)] 2 | 3 | use std::io::{Read, Result, Write}; 4 | use std::time::{Instant, SystemTime, UNIX_EPOCH}; 5 | use tokio::io::{AsyncReadExt, AsyncWriteExt}; 6 | use tokio::net::TcpStream; 7 | 8 | cfg_if::cfg_if! { 9 | if #[cfg(feature = "task_tvm")] { 10 | use wasm_runtime::private_computation; 11 | } else if #[cfg(feature = "task_db")] { 12 | use db::private_computation; 13 | } else if #[cfg(feature = "task_fann")] { 14 | use fann::private_computation; 15 | } else if #[cfg(feature = "task_fasta")] { 16 | use fasta::private_computation; 17 | } else if #[cfg(feature = "task_polybench")] { 18 | use polybench::private_computation; 19 | } else if #[cfg(feature = "task_sample")] { 20 | use sample_add::private_computation; 21 | } 22 | } 23 | 24 | pub async fn handle_client(mut stream: TcpStream) -> Result<()> { 25 | let mut length = vec![0u8; std::mem::size_of::()]; 26 | stream.read_exact(&mut length).await?; 27 | let data_len = u64::from_le_bytes(length.try_into().unwrap()) as usize; 28 | let input = { 29 | let mut input = vec![0u8; data_len]; 30 | stream.read_exact(&mut input).await?; 31 | println!("Read data with length {data_len}"); 32 | input.to_vec() 33 | }; 34 | 35 | let output = perform_task(input); 36 | stream.write(output.len().to_string().as_bytes()).await?; 37 | stream.write(b"\n").await?; 38 | stream.flush().await?; 39 | stream.write_all(&output).await?; 40 | stream.flush().await?; 41 | println!( 42 | "output is {:?}", 43 | std::str::from_utf8(&output[..(100).min(output.len())]).unwrap_or_default() 44 | ); 45 | println!("Sent data. Length = {}", output.len()); 46 | println!("Finished!"); 47 | 48 | Ok(()) 49 | } 50 | 51 | fn perform_task(input: Vec) -> Vec { 52 | let now = Instant::now(); 53 | #[cfg(feature = "task_polybench")] 54 | { 55 | let res = private_computation(input, &|| { 56 | SystemTime::now() 57 | .duration_since(UNIX_EPOCH) 58 | .unwrap() 59 | .as_nanos() as u64 60 | }); 61 | println!("{}", String::from_utf8(res.clone()).unwrap()); 62 | let elapsed = now.elapsed(); 63 | println!("Elapsed: {:.2?}", elapsed); 64 | res 65 | } 66 | 67 | #[cfg(not(feature = "task_polybench"))] 68 | { 69 | let res = private_computation(input); 70 | let elapsed = now.elapsed(); 71 | println!("Elapsed: {:.2?}", elapsed); 72 | 73 | res 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /others/enarx/tvm-wasm/tools/build_graph_lib.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | 19 | """Builds a simple resnet152 graph for testing.""" 20 | import argparse 21 | import os 22 | import subprocess 23 | import sys 24 | 25 | import onnx 26 | import tvm 27 | from tvm import relay, runtime 28 | from tvm.contrib.download import download_testdata 29 | from tvm.contrib import graph_executor 30 | 31 | from PIL import Image 32 | import numpy as np 33 | import tvm.relay as relay 34 | 35 | # This example uses resnet152-v2-7 model 36 | model_url = ( 37 | "https://github.com/onnx/models/raw/main/" 38 | "vision/classification/resnet/model/" 39 | "resnet152-v2-7.onnx" 40 | ) 41 | 42 | 43 | def build_graph_lib(opt_level): 44 | """Compiles the pre-trained model with TVM""" 45 | out_dir = os.path.join(sys.path[0], "../lib") 46 | if not os.path.exists(out_dir): 47 | os.makedirs(out_dir) 48 | 49 | # Follow the tutorial to download and compile the model 50 | model_path = download_testdata(model_url, "resnet152-v2-7.onnx", module="onnx") 51 | onnx_model = onnx.load(model_path) 52 | 53 | img_url = "https://s3.amazonaws.com/model-server/inputs/kitten.jpg" 54 | img_path = download_testdata(img_url, "imagenet_cat.png", module="data") 55 | 56 | # Resize it to 224x224 57 | resized_image = Image.open(img_path).resize((224, 224)) 58 | img_data = np.asarray(resized_image).astype("float32") 59 | 60 | # Our input image is in HWC layout while ONNX expects CHW input, so convert the array 61 | img_data = np.transpose(img_data, (2, 0, 1)) 62 | 63 | # Normalize according to the ImageNet input specification 64 | imagenet_mean = np.array([0.485, 0.456, 0.406]).reshape((3, 1, 1)) 65 | imagenet_stddev = np.array([0.229, 0.224, 0.225]).reshape((3, 1, 1)) 66 | norm_img_data = (img_data / 255 - imagenet_mean) / imagenet_stddev 67 | 68 | # Add the batch dimension, as we are expecting 4-dimensional input: NCHW. 69 | img_data = np.expand_dims(norm_img_data, axis=0) 70 | 71 | input_name = "data" 72 | shape_dict = {input_name: img_data.shape} 73 | 74 | mod, params = relay.frontend.from_onnx(onnx_model, shape_dict) 75 | target = "llvm -mtriple=wasm32-wasi" 76 | 77 | with tvm.transform.PassContext(opt_level=opt_level): 78 | factory = relay.build( 79 | mod, 80 | target=target, 81 | params=params, 82 | runtime=tvm.relay.backend.Runtime("cpp", {"system-lib": True}), 83 | ) 84 | 85 | # Save the model artifacts to obj_file 86 | obj_file = os.path.join(out_dir, "graph.o") 87 | factory.get_lib().save(obj_file) 88 | 89 | # Run llvm-ar to archive obj_file into lib_file 90 | lib_file = os.path.join(out_dir, "libgraph_wasm32.a") 91 | cmds = [os.environ.get("LLVM_AR", "llvm-ar-10"), "rcs", lib_file, obj_file] 92 | subprocess.run(cmds) 93 | 94 | # Save the json and params 95 | with open(os.path.join(out_dir, "graph.json"), "w") as f_graph: 96 | f_graph.write(factory.get_graph_json()) 97 | with open(os.path.join(out_dir, "graph.params"), "wb") as f_params: 98 | f_params.write(runtime.save_param_dict(factory.get_params())) 99 | 100 | 101 | if __name__ == "__main__": 102 | parser = argparse.ArgumentParser(description="ONNX model build example") 103 | parser.add_argument( 104 | "-O", 105 | "--opt-level", 106 | type=int, 107 | default=0, 108 | help="level of optimization. 0 is non-optimized and 3 is the highest level", 109 | ) 110 | args = parser.parse_args() 111 | 112 | build_graph_lib(args.opt_level) 113 | -------------------------------------------------------------------------------- /others/enarx/tvm-wasm/wasm-runtime/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wasm-runtime" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | csv = "1.1.6" 10 | image = "0.24.5" 11 | lazy_static = "1.4.0" 12 | ndarray = "0.12" 13 | tvm-graph-rt = { git = "https://github.com/apache/tvm.git" } 14 | -------------------------------------------------------------------------------- /others/enarx/tvm-wasm/wasm-runtime/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("cargo:rustc-link-lib=static=graph_wasm32"); 3 | println!( 4 | "cargo:rustc-link-search=native={}", 5 | format!( 6 | "{}/{}", 7 | std::env::var("CARGO_MANIFEST_DIR").unwrap(), 8 | "../lib" 9 | ) 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /others/enarx/tvm-wasm/wasm-runtime/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Adaptive version of `wasi/src/main.rs` at 2 | //! https://github.com/kazum/tvm-wasm/blob/master/examples/wasi/src/main.rs 3 | 4 | use image::{imageops::FilterType, GenericImageView}; 5 | use ndarray::Array; 6 | use std::{collections::HashMap, convert::TryFrom, env, sync::Mutex}; 7 | use tvm_graph_rt::{Graph, GraphExecutor, SystemLibModule, Tensor}; 8 | 9 | const IMG_HEIGHT: usize = 224; 10 | const IMG_WIDTH: usize = 224; 11 | 12 | extern "C" { 13 | static __tvm_module_ctx: i32; 14 | fn __wasm_call_ctors(); 15 | } 16 | 17 | #[no_mangle] 18 | unsafe fn __get_tvm_module_ctx() -> i32 { 19 | // Refer a symbol in the libtvmwasm.a to make sure that the link of the 20 | // library is not optimized out. 21 | __tvm_module_ctx 22 | } 23 | 24 | lazy_static::lazy_static! { 25 | static ref SYSLIB: SystemLibModule = SystemLibModule::default(); 26 | static ref GRAPH_EXECUTOR: Mutex> = { 27 | unsafe { 28 | // This is necessary to invoke TVMBackendRegisterSystemLibSymbol 29 | // API calls. 30 | __wasm_call_ctors(); 31 | } 32 | let graph = Graph::try_from(include_str!(concat!( 33 | env!("CARGO_MANIFEST_DIR"), 34 | "/../lib/graph.json" 35 | ))) 36 | .unwrap(); 37 | let params_bytes = 38 | include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/../lib/graph.params")); 39 | let params = tvm_graph_rt::load_param_dict(params_bytes) 40 | .unwrap() 41 | .into_iter() 42 | .map(|(k, v)| (k, v.to_owned())) 43 | .collect::>>(); 44 | 45 | let mut exec = GraphExecutor::new(graph, &*SYSLIB).unwrap(); 46 | exec.load_params(params); 47 | 48 | Mutex::new(exec) 49 | }; 50 | } 51 | 52 | /// Convert a raw imnage into Tensor if needed. 53 | pub fn preprocess(img: image::DynamicImage) -> Tensor<'static> { 54 | println!("original image dimensions: {:?}", img.dimensions()); 55 | let img = img 56 | .resize_exact(IMG_HEIGHT as u32, IMG_WIDTH as u32, FilterType::Nearest) 57 | .to_rgb8(); 58 | println!("resized image dimensions: {:?}", img.dimensions()); 59 | let mut pixels: Vec = vec![]; 60 | for pixel in img.pixels() { 61 | let tmp = pixel.0; 62 | // normalize the RGB channels using mean, std of imagenet1k 63 | let tmp = [ 64 | (tmp[0] as f32 - 123.0) / 58.395, // R 65 | (tmp[1] as f32 - 117.0) / 57.12, // G 66 | (tmp[2] as f32 - 104.0) / 57.375, // B 67 | ]; 68 | for e in &tmp { 69 | pixels.push(*e); 70 | } 71 | } 72 | 73 | // (H,W,C) -> (C,H,W) 74 | let arr = Array::from_shape_vec((IMG_HEIGHT, IMG_WIDTH, 3), pixels).unwrap(); 75 | let arr = arr.permuted_axes([2, 0, 1]); 76 | let arr = Array::from_iter(arr.into_iter().map(|&v| v)); 77 | 78 | Tensor::from(arr) 79 | } 80 | 81 | /// Perform the ResNet prediction phase. 82 | pub fn private_computation(input: Vec) -> Vec { 83 | // Load image from byte array. 84 | let img = image::load_from_memory_with_format(&input, image::ImageFormat::Png).unwrap(); 85 | let tensor = preprocess(img); 86 | 87 | let mut executor = GRAPH_EXECUTOR.lock().unwrap(); 88 | executor.set_input("data", tensor); 89 | executor.run(); 90 | let output = executor.get_output(0).unwrap().to_vec::(); 91 | unsafe { std::slice::from_raw_parts(output.as_ptr() as *const u8, output.len() * 4) }.to_vec() 92 | } 93 | -------------------------------------------------------------------------------- /others/evaluation_tvm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "evaluation_tvm" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | [lib] 8 | path = "src/lib.rs" 9 | crate_type = ["staticlib", "rlib"] 10 | 11 | [dependencies] 12 | 13 | [features] 14 | -------------------------------------------------------------------------------- /others/evaluation_tvm/README.md: -------------------------------------------------------------------------------- 1 | # Demo Confidential Task for Apache TVM Machine Learning Framework 2 | 3 | You should follow the guide to let it work in the enclave. 4 | 5 | 1. Install TVM 6 | ```shell 7 | $ git clone https://github.com/apache/tvm.git $HOME/tvm 8 | $ cd $HOME/tvm 9 | ``` 10 | 11 | 2. **Compile TVM and modify some settings.** 12 | ```shell 13 | $ mkdir build && cp ./cmake/config.cmake ./build 14 | $ cd build 15 | ``` 16 | Change the following keys to `ON`. This is very important. 17 | * `USE_MICRO` 18 | * `USE_MICRO_STANDALONE_RUNTIME` 19 | 20 | These keys allow the TVM to build a self-contained ML model; that is, the library build by TVM is a self-runnable bundle with the required interpreter runtime modules such as runtime::GraphExecutor, the graph JSON, and the params, which does not need to link against TVM runtime libraries anymore. 21 | 22 | Then compile it. 23 | ```shell 24 | $ cmake .. && make -j$(nproc) 25 | ``` 26 | 27 | 3. By default, you can set the `TVM_HOME` to `$HOME/tvm` or the parent directory from where the TVM libraries are built. 28 | 29 | 4. Then you may also need to configure the path python looks for (assume you have set `TVM_HOME`). 30 | 31 | ```shell 32 | $ export PYTHONPATH=$TVM_HOME/python:$TVM_HOME/topi/python:$TVM_HOME/nnvm/python:${PYTHONPATH} 33 | ``` 34 | 35 | 5. Build the standalone library for enclave, which will automatically copies the `libmodel_entry.a` to `./platform_sgx/lib`. 36 | 37 | ```shell 38 | $ cd ./model_deploy 39 | $ make 40 | ``` 41 | 42 | 6. Then rebuild the enclave. Now everything works. -------------------------------------------------------------------------------- /others/evaluation_tvm/build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | 3 | fn main() { 4 | let dir = env::var("CARGO_MANIFEST_DIR").unwrap(); 5 | println!("cargo:rerun-if-changed=build.rs"); 6 | println!("cargo:rustc-link-search=native={}/outlib", dir); 7 | println!("cargo:rustc-link-lib=static=model_entry"); 8 | } 9 | -------------------------------------------------------------------------------- /others/evaluation_tvm/model_deploy/Makefile: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | MAGENTA := \e[0;35m 19 | NC := \e[0m 20 | 21 | # Setup build environment 22 | SGX_SDK ?= /opt/intel/sgxsdk 23 | TVM_HOME ?= $(HOME)/tvm 24 | CRT_ROOT ?= $(TVM_HOME)/build/standalone_crt 25 | ifeq ($(shell ls -lhd $(CRT_ROOT)),) 26 | $(error "CRT not found. Ensure you have built the standalone_crt target and try again") 27 | endif 28 | 29 | CRT_SRCS := $(shell find $(CRT_ROOT)) 30 | 31 | # Set python path. 32 | export PYTHONPATH = $(TVM_HOME)/python:$(shell echo $PYTHONPATH) 33 | 34 | DMLC_CORE=${TVM_HOME}/3rdparty/dmlc-core 35 | PKG_COMPILE_OPTS = -g -Wall -O2 -fPIC 36 | 37 | PKG_CFLAGS = ${PKG_COMPILE_OPTS} \ 38 | -I${TVM_HOME}/include \ 39 | -I${DMLC_CORE}/include \ 40 | -I${TVM_HOME}/3rdparty/dlpack/include \ 41 | -I. \ 42 | -DDMLC_USE_LOGGING_LIBRARY=\ 43 | 44 | PKG_LDFLAGS = -pthread -lm 45 | 46 | OUT_DIR := ../outlib 47 | BUNDLE := $(OUT_DIR)/libbundle.a 48 | MODEL_ENTRY_SRC := model_entry.c 49 | MODEL_TAR := $(OUT_DIR)/model.tar 50 | MODEL_ENTRY := $(OUT_DIR)/libmodel_entry.a 51 | PYTHON_MODEL := $(OUT_DIR)/devc.o $(OUT_DIR)/lib0.o $(OUT_DIR)/lib1.o 52 | LIB_COMMON := $(OUT_DIR)/libcommon.a 53 | LIB_MEMORY := $(OUT_DIR)/libmemory.a 54 | LIB_GRAPH_EXECUTOR := $(OUT_DIR)/libgraph_executor.a 55 | 56 | .phony: all clean crt_libs 57 | 58 | all: $(OUT_DIR) $(MODEL_ENTRY) 59 | 60 | # The build logic of microTVM has changed. The old Makefile was removed. 61 | crt_libs: $(CRT_SRCS) 62 | @printf "$(MAGENTA)+ Building TVM CRT static library$(NC)\n" 63 | @cd $(CRT_ROOT) && mkdir -p build && cd build && cmake -DCRT_CONFIG_PATH=$(abspath .) -DCMAKE_C_FLAGS="${PKG_COMPILE_OPTS}" .. && make -j`nproc` 64 | @printf "$(MAGENTA)+ Finished! \n" 65 | 66 | $(OUT_DIR): 67 | @mkdir -p $@ 68 | 69 | $(MODEL_TAR): build_model.py 70 | @printf "$(MAGENTA)+ Building ML Model with TVM$(NC)\n" 71 | @python3 ./build_model.py -o $(OUT_DIR) 2> /dev/null 72 | 73 | $(PYTHON_MODEL): $(MODEL_TAR) 74 | @tar -xvf $^ -C $(OUT_DIR) > /dev/null 2>&1 75 | @printf "$(MAGENTA)+ Finished! \n" 76 | 77 | $(LIB_MEMORY): crt_libs 78 | @cp $(CRT_ROOT)/build/libmemory.a $@ 79 | 80 | $(LIB_GRAPH_EXECUTOR): crt_libs 81 | @cp $(CRT_ROOT)/build/libgraph_executor.a $@ 82 | 83 | $(LIB_COMMON): crt_libs 84 | @cp $(CRT_ROOT)/build/libcommon.a $@ 85 | 86 | $(BUNDLE): bundle.c 87 | @gcc -c -o $(OUT_DIR)/bundle.o $^ $(PKG_CFLAGS) $(PKG_LDFLAGS) 88 | @ar rcs $@ $(OUT_DIR)/bundle.o 89 | @rm -f $(OUT_DIR)/bundle.o 90 | 91 | # Extract all the object files and pack them into a single library. 92 | # This is a must. We have to make the whole bundle standalone. 93 | $(MODEL_ENTRY): $(MODEL_ENTRY_SRC) $(BUNDLE) $(PYTHON_MODEL) $(LIB_COMMON) $(LIB_GRAPH_EXECUTOR) $(LIB_MEMORY) 94 | @printf "$(MAGENTA)+ Packing the runtime into single static library:$(NC)\n" 95 | @mkdir -p $(OUT_DIR)/../tmp 96 | @gcc -c $(MODEL_ENTRY_SRC) -o $(OUT_DIR)/../tmp/model_entry.o $(PKG_CFLAGS) 97 | @cd $(OUT_DIR)/../tmp && ar -x $(BUNDLE) && ar -x $(LIB_COMMON) && ar -x $(LIB_GRAPH_EXECUTOR) && ar -x $(LIB_MEMORY) 98 | @cd $(OUT_DIR)/../tmp && ar -crs $(MODEL_ENTRY) *.o $(PYTHON_MODEL) 99 | @rm -rf $(OUT_DIR)/../tmp 100 | @rm -rf $(OUT_DIR)/crt 101 | @printf "$(MAGENTA)+ Finished! \n" 102 | 103 | clean: 104 | @rm -rf $(OUT_DIR) 105 | -------------------------------------------------------------------------------- /others/evaluation_tvm/model_deploy/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | How to Bundle TVM Modules 20 | ========================= 21 | 22 | This folder contains an example on how to bundle a TVM module (with the required 23 | interpreter runtime modules such as `runtime::GraphExecutor`, the graph JSON, and 24 | the params) into a single, self-contained shared object (`bundle.so`) which 25 | exposes a C API wrapping the appropriate `runtime::GraphExecutor` instance. 26 | 27 | This is useful for cases where we'd like to avoid deploying the TVM runtime 28 | components to the target host in advance - instead, we simply deploy the bundled 29 | shared-object to the host, which embeds both the model and the runtime 30 | components. The bundle should only depend on libc/libc++. 31 | 32 | It also contains an example code (`demo.cc`) to load this shared object and 33 | invoke the packaged TVM model instance. This is a dependency-free binary that 34 | uses the functionality packaged in `bundle.so` (which means that `bundle.so` can 35 | be deployed lazily at runtime, instead of at compile time) to invoke TVM 36 | functionality. 37 | 38 | Type the following command to run the sample code under the current folder, 39 | after building TVM first. 40 | 41 | ```bash 42 | make demo_dynamic 43 | ``` 44 | 45 | This will: 46 | 47 | - Download the mobilenet0.25 model from the MXNet Gluon Model Zoo 48 | - Compile the model with Relay 49 | - Build a `bundle.so` shared object containing the model specification and 50 | parameters 51 | - Build a `demo_dynamic` executable that `dlopen`'s `bundle.so` (or `bundle_c.so` in 52 | terms of the MISRA-C runtime), instantiates the contained graph executor, 53 | and invokes the `GraphExecutor::Run` function on a cat image, then prints 54 | the output results. 55 | 56 | Type the following command to run the sample code with static linking. 57 | 58 | ```bash 59 | make demo_static 60 | ``` 61 | 62 | This will: 63 | - Download the mobilenet0.25 model from the MXNet Gluon Model Zoo 64 | - Compile the model with Relay and outputs `model.o` 65 | - Build a `bundle_static.o` object containing the runtime functions 66 | - Build a `demo_static` executable which has static link to `bundle_static.o` and 67 | `model.o`, functions on a cat image, then prints the output results. 68 | -------------------------------------------------------------------------------- /others/evaluation_tvm/model_deploy/bundle.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | #ifndef TVM_APPS_BUNDLE_DEPLOY_BUNDLE_H_ 21 | #define TVM_APPS_BUNDLE_DEPLOY_BUNDLE_H_ 22 | 23 | #include 24 | 25 | TVM_DLL void* tvm_runtime_create(const char* json_data, const char* params_data, 26 | const uint64_t params_size); 27 | 28 | TVM_DLL void tvm_runtime_destroy(void* runtime); 29 | 30 | TVM_DLL void tvm_runtime_set_input(void* runtime, const char* name, 31 | DLTensor* tensor); 32 | 33 | TVM_DLL void tvm_runtime_run(void* runtime); 34 | 35 | TVM_DLL void tvm_runtime_get_output(void* runtime, int32_t index, 36 | DLTensor* tensor); 37 | 38 | #endif /* TVM_APPS_BUNDLE_DEPLOY_BUNDLE_H_ */ 39 | -------------------------------------------------------------------------------- /others/evaluation_tvm/model_deploy/cat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ya0guang/PoBF/8bc1a900fdae506d0a113250b94f594ae70f2762/others/evaluation_tvm/model_deploy/cat.png -------------------------------------------------------------------------------- /others/evaluation_tvm/model_deploy/crt_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | /*! 21 | * \file apps/bundle_deploy/crt_config.h 22 | * \brief CRT configuration for bundle_deploy app. 23 | */ 24 | #ifndef TVM_RUNTIME_CRT_CONFIG_H_ 25 | #define TVM_RUNTIME_CRT_CONFIG_H_ 26 | 27 | /*! Log level of the CRT runtime */ 28 | #define TVM_CRT_LOG_LEVEL TVM_CRT_LOG_LEVEL_DEBUG 29 | 30 | /*! Support low-level debugging in MISRA-C runtime */ 31 | #define TVM_CRT_DEBUG 0 32 | 33 | /*! Maximum supported dimension in NDArray */ 34 | #define TVM_CRT_MAX_NDIM 6 35 | /*! Maximum supported arguments in generated functions */ 36 | #define TVM_CRT_MAX_ARGS 10 37 | /*! Maximum supported string length in dltype, e.g. "int8", "int16", "float32" */ 38 | #define TVM_CRT_MAX_STRLEN_DLTYPE 10 39 | /*! Maximum supported string length in function names */ 40 | #define TVM_CRT_MAX_STRLEN_FUNCTION_NAME 120 41 | /*! Maximum supported string length in parameter names */ 42 | #define TVM_CRT_MAX_STRLEN_PARAM_NAME 80 43 | 44 | /*! Maximum number of registered modules. */ 45 | #define TVM_CRT_MAX_REGISTERED_MODULES 2 46 | 47 | /*! Size of the global function registry, in bytes. */ 48 | #define TVM_CRT_GLOBAL_FUNC_REGISTRY_SIZE_BYTES 512 49 | 50 | /*! Maximum packet size, in bytes, including the length header. */ 51 | #define TVM_CRT_MAX_PACKET_SIZE_BYTES 512 52 | 53 | #endif // TVM_RUNTIME_CRT_CONFIG_H_ 54 | -------------------------------------------------------------------------------- /others/evaluation_tvm/model_deploy/model_entry.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2022 Haobin Chen and Hongbo Chen 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | #include "bundle.h" 24 | 25 | #define OUTPUT_LEN 1000 26 | #define INPUT_LEN 1 * 3 * 224 * 224 27 | 28 | /* Fix musl. */ 29 | int __fprintf_chk(void* stream, int flag, const char* format, ...) { return 0; } 30 | 31 | /* Fix musl. */ 32 | int __vsnprintf_chk(char* s, size_t maxlen, int flag, size_t slen, 33 | const char* format, va_list args) { 34 | return 0; 35 | } 36 | // Main entry for the Rust enclave to invoke the model. 37 | // The model is statically linked by the enclave, so everything is secret. 38 | int32_t tvm_resnet152_run(const uint8_t* json, size_t json_size, 39 | const uint8_t* param, size_t param_size, 40 | const uint8_t* input_buf, size_t input_size, 41 | uint8_t* output_buf, size_t output_buf_size) { 42 | char* json_data = (char*)(json); 43 | char* params_data = (char*)(param); 44 | 45 | // Create a handle to TVM runtime modules including the 46 | // tvm::runtime::GraphExecutor. 47 | void* handle = tvm_runtime_create(json_data, params_data, param_size); 48 | 49 | // Check input length. 50 | if (input_size < INPUT_LEN * sizeof(float)) { 51 | return 1; 52 | } 53 | 54 | // Convert to the input tensor for storing the image. 55 | DLTensor input; 56 | input.data = (float*)(input_buf); 57 | DLDevice dev = {kDLCPU, 0}; 58 | input.device = dev; 59 | input.ndim = 4; 60 | DLDataType dtype = {kDLFloat, 32, 1}; 61 | input.dtype = dtype; 62 | int64_t shape[4] = {1, 3, 224, 224}; 63 | input.shape = shape; 64 | input.strides = NULL; 65 | input.byte_offset = 0; 66 | 67 | // Prepare the output tensor. 68 | float output_storage[OUTPUT_LEN]; 69 | DLTensor output; 70 | output.data = output_storage; 71 | DLDevice out_dev = {kDLCPU, 0}; 72 | output.device = out_dev; 73 | output.ndim = 2; 74 | DLDataType out_dtype = {kDLFloat, 32, 1}; 75 | output.dtype = out_dtype; 76 | int64_t out_shape[2] = {1, OUTPUT_LEN}; 77 | output.shape = out_shape; 78 | output.strides = NULL; 79 | output.byte_offset = 0; 80 | 81 | // Set the input. 82 | tvm_runtime_set_input(handle, "data", &input); 83 | // Run the model and get the result. 84 | tvm_runtime_run(handle); 85 | // Get the output. The result is a 1001-element vector of logits, rating the 86 | // probability of each class for the image. You need to check ImageNet for 87 | // more details. 88 | tvm_runtime_get_output(handle, 0, &output); 89 | // Dectroy the handle. 90 | tvm_runtime_destroy(handle); 91 | // Copy back. 92 | memcpy(output_buf, output.data, output_buf_size); 93 | 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /others/evaluation_tvm/src/lib.rs: -------------------------------------------------------------------------------- 1 | const GRAPH_JSON: &'static [u8] = include_bytes!("../outlib/graph.json"); 2 | const GRAPH_PARAM: &'static [u8] = include_bytes!("../outlib/params.bin"); 3 | const GRAPH_OUTPUT_LEN: usize = 1000usize; 4 | 5 | extern "C" { 6 | fn tvm_resnet152_run( 7 | json: *const u8, 8 | json_size: usize, 9 | param: *const u8, 10 | param_size: usize, 11 | input: *const u8, 12 | input_size: usize, 13 | output: *mut u8, 14 | output_buf_size: usize, 15 | ) -> i32; 16 | } 17 | 18 | pub fn private_computation(input: Vec) -> Vec { 19 | let input_byte = input.as_slice(); 20 | let input_size = 1 * 3 * 224 * 224 * core::mem::size_of::(); 21 | 22 | let mut output = vec![0u8; GRAPH_OUTPUT_LEN * core::mem::size_of::()]; 23 | 24 | let res = unsafe { 25 | tvm_resnet152_run( 26 | GRAPH_JSON.as_ptr(), 27 | GRAPH_JSON.len(), 28 | GRAPH_PARAM.as_ptr(), 29 | GRAPH_PARAM.len(), 30 | input_byte.as_ptr(), 31 | input_size, 32 | output.as_mut_ptr(), 33 | GRAPH_OUTPUT_LEN * core::mem::size_of::(), 34 | ) 35 | }; 36 | 37 | if res != 0 { 38 | panic!("[-] TVM internal error. Check input size?"); 39 | } 40 | 41 | output 42 | } 43 | -------------------------------------------------------------------------------- /others/gramine/.gitignore: -------------------------------------------------------------------------------- 1 | /*.tar.gz 2 | /OUTPUT 3 | /client 4 | /mbedtls 5 | /server 6 | /ssl/ca.* 7 | /ssl/server.* 8 | *.token 9 | *.sig 10 | *.sgx 11 | *.manifest 12 | -------------------------------------------------------------------------------- /others/gramine/client.manifest.template: -------------------------------------------------------------------------------- 1 | # Client manifest file 2 | 3 | loader.entrypoint = "file:{{ gramine.libos }}" 4 | libos.entrypoint = "/client" 5 | 6 | loader.log_level = "{{ log_level }}" 7 | 8 | loader.env.LD_LIBRARY_PATH = "/lib:/usr/local/lib:{{ arch_libdir }}:/usr{{ arch_libdir }}" 9 | loader.env.LC_ALL = "C" 10 | 11 | loader.env.RA_TLS_CLIENT_INSIDE_SGX = "1" 12 | 13 | loader.insecure__use_cmdline_argv = true 14 | loader.insecure__use_host_env = true 15 | 16 | fs.mounts = [ 17 | { path = "/lib", uri = "file:{{ gramine.runtimedir() }}" }, 18 | { path = "/usr/local/lib", uri = "file:/usr/local/lib" }, 19 | { path = "{{ arch_libdir }}", uri = "file:{{ arch_libdir }}" }, 20 | { path = "/usr{{ arch_libdir }}", uri = "file:/usr{{ arch_libdir }}" }, 21 | { path = "/etc", uri = "file:/etc" }, 22 | { path = "/client", uri = "file:client" }, 23 | ] 24 | 25 | sys.enable_extra_runtime_domain_names_conf = true 26 | 27 | sgx.debug = true 28 | sgx.enclave_size = "512M" 29 | sgx.max_threads = 4 30 | 31 | sgx.trusted_files = [ 32 | "file:{{ gramine.libos }}", 33 | "file:client", 34 | "file:{{ gramine.runtimedir() }}/", 35 | "file:/usr/local/lib/", 36 | "file:{{ arch_libdir }}/", 37 | "file:/usr{{ arch_libdir }}/", 38 | "file:ssl/ca.crt", 39 | ] 40 | 41 | sgx.allowed_files = [ 42 | "file:/etc/nsswitch.conf", 43 | "file:/etc/host.conf", 44 | "file:/etc/ethers", 45 | "file:/etc/hosts", 46 | "file:/etc/group", 47 | "file:/etc/passwd", 48 | "file:/etc/gai.conf", 49 | "file:/etc/ssl/certs/ca-certificates.crt", 50 | "file:/etc/sgx_default_qcnl.conf", 51 | ] 52 | -------------------------------------------------------------------------------- /others/gramine/download: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu -o pipefail 4 | 5 | declare -a urls 6 | 7 | usage() { 8 | echo "Usage: download --url https://example.org/test --url https://mirror.example/blah --output test.tar --sha256 1234..abc" 9 | exit "${1:-0}" 10 | } 11 | 12 | while [ $# -gt 0 ]; do 13 | case "$1" in 14 | --url) 15 | urls+=("$2") 16 | shift 17 | ;; 18 | --output) 19 | output="$2" 20 | shift 21 | ;; 22 | --sha256) 23 | sha256="$2" 24 | shift 25 | ;; 26 | --help|-h) 27 | usage 28 | ;; 29 | *) 30 | usage 1 31 | ;; 32 | esac 33 | shift 34 | done 35 | 36 | if [ -z "${output:-}" ] || [ -z "${sha256:-}" ] || [ -z "${urls[*]}" ]; then 37 | usage 1 38 | fi 39 | 40 | if [ -n "${DL_CACHE:-}" ]; then 41 | if [ -f "$DL_CACHE/$sha256" ]; then 42 | echo "download: Found '$output' (${sha256:0:8}...) in cache." 43 | cp "$DL_CACHE/$sha256" "$output" 44 | exit 0 45 | fi 46 | fi 47 | 48 | if [ "${DL_OFFLINE:-}" == "true" ]; then 49 | echo "download: ERROR: File '$output' (${sha256:0:8}...) not found in cache and offline mode is active!" 50 | exit 1 51 | fi 52 | 53 | tmpd="$(mktemp -d -p "${DL_CACHE:-.}")" 54 | cleanup() { 55 | rm -rf "$tmpd" 56 | } 57 | trap cleanup EXIT 58 | 59 | for url in "${urls[@]}"; do 60 | echo "download: Trying to fetch $url" 61 | wget --timeout=10 --tries=3 -O "$tmpd/unverified" "$url" || true 62 | sha256_received="$(sha256sum "$tmpd/unverified" | cut -d ' ' -f 1)" 63 | if [ "$sha256" != "$sha256_received" ]; then 64 | echo "download: WARNING: Hash mismatch: Expected $sha256 but received $sha256_received" 65 | continue 66 | fi 67 | echo "download: Fetched '$output' (${sha256:0:8}...) successfully." 68 | if [ -n "${DL_CACHE:-}" ]; then 69 | mv "$tmpd/unverified" "$DL_CACHE/$sha256" 70 | cp "$DL_CACHE/$sha256" "$output" 71 | exit 0 72 | fi 73 | mv "$tmpd/unverified" "$output" 74 | exit 0 75 | done 76 | 77 | echo "download: ERROR: Failed to download '$output' (${sha256:0:8}...)! No URLs left to try." 78 | exit 1 -------------------------------------------------------------------------------- /others/gramine/rustlib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rustlib" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | name = "gramine_task" 8 | path = "src/lib.rs" 9 | crate-type = ["staticlib"] 10 | 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [features] 14 | default = ["task_sample"] 15 | # computing tasks 16 | # The tasks are enabled by `cfg_if`. 17 | task_sample = ["sample_add"] 18 | task_tvm = ["evaluation_tvm"] 19 | task_polybench = ["polybench"] 20 | task_fann = ["fann"] 21 | task_fasta = ["fasta"] 22 | task_db = ["db"] 23 | 24 | [dependencies] 25 | # Evaluations. 26 | db = { path = "../../../cctasks/db", optional = true } 27 | evaluation_tvm = { path = "../../../cctasks/evaluation_tvm", optional = true } 28 | fann = { path = "../../../cctasks/fann", optional = true } 29 | fasta = { path = "../../../cctasks/fasta", optional = true } 30 | polybench = { path = "../../../cctasks/polybench", optional = true } 31 | sample_add = { path = "../../../cctasks/sample_add", optional = true } 32 | 33 | cfg-if = "1.0.0" 34 | -------------------------------------------------------------------------------- /others/gramine/rustlib/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::time::*; 2 | 3 | // Settings for private computation functions. 4 | cfg_if::cfg_if! { 5 | if #[cfg(feature = "task_tvm")] { 6 | use evaluation_tvm::private_computation; 7 | } else if #[cfg(feature = "task_db")] { 8 | use db::private_computation; 9 | } else if #[cfg(feature = "task_fann")] { 10 | use fann::private_computation; 11 | } else if #[cfg(feature = "task_fasta")] { 12 | use fasta::private_computation; 13 | } else if #[cfg(feature = "task_polybench")] { 14 | use polybench::private_computation; 15 | } else if #[cfg(feature = "task_sample")] { 16 | use sample_add::private_computation; 17 | } 18 | } 19 | 20 | #[no_mangle] 21 | pub unsafe extern "C" fn gramine_rust_entry( 22 | input: *const u8, 23 | input_len: u32, 24 | output: *mut u8, 25 | output_buf_len: u32, 26 | output_len: *mut u32, 27 | ) -> i32 { 28 | let now = Instant::now(); 29 | let input_buf = std::slice::from_raw_parts(input, input_len as usize).to_vec(); 30 | #[cfg(feature = "task_polybench")] 31 | let output_buf = { 32 | let res = private_computation(input_buf, &|| { 33 | SystemTime::now() 34 | .duration_since(UNIX_EPOCH) 35 | .unwrap() 36 | .as_nanos() as u64 37 | }); 38 | println!("{}", String::from_utf8(res.clone()).unwrap()); 39 | res 40 | }; 41 | 42 | #[cfg(not(feature = "task_polybench"))] 43 | let output_buf = private_computation(input_buf); 44 | 45 | let elapsed = now.elapsed(); 46 | println!("Elapsed: {:.2?}", elapsed); 47 | 48 | if output_buf.len() > output_buf_len as usize { 49 | println!( 50 | "[!] The buffer size is insufficient! Expected {}, got {}.", 51 | output_buf.len(), 52 | output_buf_len 53 | ); 54 | -1 55 | } else { 56 | std::ptr::copy(output_buf.as_ptr(), output, output_buf.len()); 57 | *output_len = output_buf.len() as u32; 58 | 59 | 0 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /others/gramine/server.manifest.template: -------------------------------------------------------------------------------- 1 | # RA-TLS manifest file example 2 | 3 | loader.entrypoint = "file:{{ gramine.libos }}" 4 | libos.entrypoint = "/server" 5 | loader.log_level = "{{ log_level }}" 6 | 7 | 8 | loader.env.LD_LIBRARY_PATH = "/lib:{{ arch_libdir }}:/usr{{ arch_libdir }}" 9 | loader.env.MALLOC_ARENA_MAX = "1" 10 | loader.env.RUST_BACKTRACE = "full" 11 | loader.insecure__use_cmdline_argv = true 12 | 13 | sys.enable_sigterm_injection = true 14 | sys.insecure__allow_eventfd = true 15 | 16 | fs.mounts = [ 17 | { path = "/lib", uri = "file:{{ gramine.runtimedir() }}" }, 18 | { path = "{{ arch_libdir }}", uri = "file:{{ arch_libdir }}" }, 19 | { path = "/usr{{ arch_libdir }}", uri = "file:/usr{{ arch_libdir }}" }, 20 | { path = "/etc", uri = "file:/etc" }, 21 | { path = "/server", uri = "file:server" }, 22 | ] 23 | 24 | sgx.debug = true 25 | 26 | sgx.remote_attestation = "{{ ra_type }}" 27 | sgx.ra_client_spid = "{{ ra_client_spid }}" 28 | sgx.ra_client_linkable = {{ 'true' if ra_client_linkable == '1' else 'false' }} 29 | 30 | sgx.trusted_files = [ 31 | "file:{{ gramine.libos }}", 32 | "file:server", 33 | "file:{{ gramine.runtimedir() }}/", 34 | "file:{{ arch_libdir }}/", 35 | "file:/usr{{ arch_libdir }}/", 36 | "file:ssl/ca.crt", 37 | "file:ssl/server.crt", 38 | "file:ssl/server.key", 39 | ] 40 | 41 | sgx.allowed_files = [ 42 | "file:/etc/nsswitch.conf", 43 | "file:/etc/ethers", 44 | "file:/etc/hosts", 45 | "file:/etc/group", 46 | "file:/etc/passwd", 47 | "file:/etc/gai.conf", 48 | ] 49 | 50 | sgx.nonpie_binary = true 51 | sgx.enclave_size = "5G" 52 | sgx.max_threads = 16 53 | sgx.require_avx = true 54 | sgx.require_avx512 = true 55 | sgx.require_prku = true -------------------------------------------------------------------------------- /others/gramine/ssl/ca_config.conf: -------------------------------------------------------------------------------- 1 | [ req ] 2 | default_bits = 4096 3 | default_md = sha512 4 | default_keyfile = example.com.key 5 | prompt = no 6 | encrypt_key = no 7 | distinguished_name = req_distinguished_name 8 | 9 | [ req_distinguished_name ] 10 | countryName = "XX" # C= 11 | localityName = "XXXXX" # L= 12 | organizationName = "My Company" # O= 13 | organizationalUnitName = "Department" # OU= 14 | commonName = "localhost" # CN= 15 | emailAddress = "me@example.com" # email 16 | -------------------------------------------------------------------------------- /others/occlum/.gitignore: -------------------------------------------------------------------------------- 1 | image 2 | initfs 3 | .__occlum_status 4 | .sgx_mode 5 | build 6 | run 7 | -------------------------------------------------------------------------------- /others/occlum/Occlum.json: -------------------------------------------------------------------------------- 1 | { 2 | "resource_limits": { 3 | "kernel_space_heap_size": "256MB", 4 | "kernel_space_stack_size": "64MB", 5 | "user_space_size": "4GB", 6 | "max_num_of_threads": 16 7 | }, 8 | "process": { 9 | "default_stack_size": "64MB", 10 | "default_heap_size": "256MB", 11 | "default_mmap_size": "256MB" 12 | }, 13 | "entry_points": [ 14 | "/bin" 15 | ], 16 | "env": { 17 | "default": [ 18 | "OCCLUM=yes" 19 | ], 20 | "untrusted": [ 21 | "EXAMPLE" 22 | ] 23 | }, 24 | "metadata": { 25 | "product_id": 0, 26 | "version_number": 0, 27 | "debuggable": true, 28 | "enable_kss": false, 29 | "family_id": { 30 | "high": "0x0", 31 | "low": "0x0" 32 | }, 33 | "ext_prod_id": { 34 | "high": "0x0", 35 | "low": "0x0" 36 | }, 37 | "pkru": 0 38 | }, 39 | "mount": [ 40 | { 41 | "target": "/", 42 | "type": "unionfs", 43 | "options": { 44 | "layers": [ 45 | { 46 | "target": "/", 47 | "type": "sefs", 48 | "source": "./build/mount/__ROOT", 49 | "options": { 50 | "MAC": "" 51 | } 52 | }, 53 | { 54 | "target": "/", 55 | "type": "sefs", 56 | "source": "./run/mount/__ROOT" 57 | } 58 | ] 59 | } 60 | }, 61 | { 62 | "target": "/host", 63 | "type": "hostfs", 64 | "source": "." 65 | }, 66 | { 67 | "target": "/proc", 68 | "type": "procfs" 69 | }, 70 | { 71 | "target": "/dev", 72 | "type": "devfs" 73 | } 74 | ] 75 | } -------------------------------------------------------------------------------- /others/occlum/build_occlum_rust.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This bash script is expected to run inside the docker container provided by Occlum. 3 | 4 | MAGENTA="\033[0;35m" 5 | NC="\033[0m" 6 | 7 | # Add musl target. 8 | rustup target add x86_64-unknown-linux-musl 9 | 10 | declare -a tasks=("task_tvm" "task_fann" "task_fasta" "task_polybench" "task_sample") 11 | 12 | mkdir -p "eval" 13 | # Install Pip3 dependencies. 14 | pip3 install -r ../../requirements.txt 15 | # Build TVM for the Rust program. 16 | pushd ../evaluation_tvm/model_deploy > /dev/null 17 | make clean && make -j 18 | popd > /dev/null 19 | 20 | # Build the Rust program. 21 | pushd ../rust_app > /dev/null 22 | 23 | for task in "${tasks[@]}"; do 24 | occlum-cargo build --release --features=server/$task,libos 25 | cp target/x86_64-unknown-linux-musl/release/server ./occlum/eval/server_$task 26 | cp target/x86_64-unknown-linux-musl/release/client ./occlum/eval/client 27 | done 28 | 29 | popd > /dev/null 30 | 31 | copy_bom -f ./rust_config.yaml --root image --include-dir /opt/occlum/etc/template 32 | rm -rf build 33 | occlum build 34 | 35 | for task in "${tasks[@]}"; do 36 | echo -e "$MAGENTA[+] Testing Occlum program for $task...$NC" 37 | occlum run /bin/rust_app_$task 38 | echo -e "$MAGENTA[+] Finished!$NC" 39 | done 40 | -------------------------------------------------------------------------------- /others/occlum/docker_run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker run -it --privileged -v /dev/sgx_enclave:/dev/sgx/enclave -v /dev/sgx_provision:/dev/sgx/provision -v ~/PoBF:/root/PoBF -v ~/tvm:/root/tvm --net="host" occlum/occlum:occulum-latest-ubuntu20.04 4 | -------------------------------------------------------------------------------- /others/occlum/rust_config.yaml: -------------------------------------------------------------------------------- 1 | includes: 2 | - base.yaml 3 | targets: 4 | - target: /bin 5 | copy: 6 | - files: 7 | - ./eval/server_task_db 8 | # - ./eval/server_task_tvm 9 | # - ./eval/server_task_fasta 10 | # - ./eval/server_task_fann 11 | # - ./eval/server_task_polybench 12 | - ./eval/client 13 | -------------------------------------------------------------------------------- /others/rust_app/client/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "client" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | # Since sev behaves similarly as a normal machine, we add the 'sev' feature. 10 | pobf_crypto = { git = "https://github.com/hiroki-chen/pobf_crypto.git", default-features = false, features = [ 11 | "sev", 12 | ] } 13 | -------------------------------------------------------------------------------- /others/rust_app/client/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::fs; 3 | use std::io::*; 4 | use std::net::TcpStream; 5 | 6 | use pobf_crypto::handle_sev_pubkey; 7 | use pobf_crypto::init_keypair; 8 | 9 | const ADDRESS: &str = "127.0.0.1:7788"; 10 | 11 | fn main() { 12 | let stream = TcpStream::connect(ADDRESS).unwrap(); 13 | let stream_clone = stream.try_clone().unwrap(); 14 | let mut reader = BufReader::new(stream); 15 | let mut writer = BufWriter::new(stream_clone); 16 | 17 | let args: Vec = env::args().collect(); 18 | let data_path = &args[1]; 19 | let data = fs::read(data_path).unwrap(); 20 | println!("Reading {}", data_path); 21 | 22 | let mut key_pair = init_keypair().unwrap(); 23 | let public_key = &key_pair.pub_k; 24 | 25 | println!("[+] Sending public key"); 26 | writer.write_all(public_key.as_ref()).unwrap(); 27 | writer.flush().unwrap(); 28 | 29 | println!("[+] Receiving peer public key"); 30 | let peer_pub_key = handle_sev_pubkey(&mut reader).unwrap(); 31 | key_pair.compute_shared_key(&peer_pub_key, b"").unwrap(); 32 | 33 | println!("[+] Sending data..."); 34 | // Read the data and encrypt it. 35 | let data = key_pair.encrypt_with_smk(&data).unwrap(); 36 | writer.write_all(data.len().to_string().as_bytes()).unwrap(); 37 | writer.write_all(b"\n").unwrap(); 38 | writer.flush().unwrap(); 39 | writer.write_all(&data).unwrap(); 40 | writer.flush().unwrap(); 41 | 42 | println!("[+] Receiving the data..."); 43 | 44 | let mut len = String::with_capacity(128); 45 | reader.read_line(&mut len).unwrap(); 46 | let buf_len = len[..len.len() - 1].parse::().unwrap(); 47 | let mut buf = vec![0u8; buf_len]; 48 | reader.read_exact(&mut buf).unwrap(); 49 | 50 | // Decrypt the data. 51 | let out = key_pair.decrypt_with_smk(&buf).unwrap(); 52 | 53 | std::fs::write("./data.txt", out).unwrap(); 54 | } 55 | -------------------------------------------------------------------------------- /others/rust_app/server/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "server" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [features] 9 | default = ["no_wasi"] 10 | wasi = ["pobf_crypto/wasi_support"] 11 | no_wasi = ["pobf_crypto/sev"] 12 | task_sample = ["sample_add"] 13 | task_tvm = ["evaluation_tvm"] 14 | task_polybench = ["polybench"] 15 | task_fann = ["fann"] 16 | task_fasta = ["fasta"] 17 | task_db = ["db"] 18 | occlum = ["occlum_dcap"] 19 | 20 | [dependencies] 21 | occlum_dcap = { git = "https://github.com/occlum/occlum.git", branch = "master", optional = true } 22 | # Evaluations. 23 | pobf_thread_pool = { path = "../../../pobf_thread_pool" } 24 | pobf_crypto = { git = "https://github.com/hiroki-chen/pobf_crypto.git", default-features = false } 25 | evaluation_tvm = { path = "../../evaluation_tvm", optional = true } 26 | fann = { path = "../../../cctasks/fann", optional = true } 27 | fasta = { path = "../../../cctasks/fasta", optional = true } 28 | polybench = { path = "../../../cctasks/polybench", optional = true } 29 | sample_add = { path = "../../../cctasks/sample_add", optional = true } 30 | cfg-if = "1.0.0" 31 | db = { path = "../../../cctasks/db", optional = true } 32 | -------------------------------------------------------------------------------- /others/rust_app/server/src/db_persistent.rs: -------------------------------------------------------------------------------- 1 | use std::{io::Write, time}; 2 | 3 | use db::db::{DbError, DbResult, Persistent}; 4 | pub struct SgxPersistentLayer; 5 | 6 | impl Persistent for SgxPersistentLayer { 7 | fn write_disk(&self, path: &str, buf: &[u8]) -> DbResult<()> { 8 | println!("writing {path} with buf.len() = {} bytes", buf.len()); 9 | 10 | let now = time::Instant::now(); 11 | let mut file = std::fs::OpenOptions::new() 12 | .append(true) 13 | .create(true) 14 | .open(path) 15 | .map_err(|_| DbError::PathNotFound(path.into()))?; 16 | file.write_all(buf).map_err(|_| DbError::Unknown)?; 17 | let elapsed: time::Duration = now.elapsed(); 18 | 19 | let throughput = (buf.len() as f64 / elapsed.as_secs_f64()) / 1000000.0; 20 | 21 | println!("[+] Time elapsed: {elapsed:?}; throughput: {throughput} MB/s"); 22 | 23 | Ok(()) 24 | } 25 | 26 | fn read_disk(&self, path: &str) -> DbResult> { 27 | println!("reading {path}"); 28 | 29 | let now = time::Instant::now(); 30 | let buf = std::fs::read(path).map_err(|_| DbError::PathNotFound(path.into()))?; 31 | let elapsed: time::Duration = now.elapsed(); 32 | 33 | let throughput = (buf.len() as f64 / elapsed.as_secs_f64()) / 1000000.0; 34 | 35 | println!("[+] Time elapsed: {elapsed:?}; throughput: {throughput} MB/s"); 36 | 37 | Ok(buf) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /others/rust_app/server/src/main.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_imports)] 2 | #![allow(unused_variables)] 3 | #![allow(dead_code)] 4 | 5 | ///! Taken from https://github.com/occlum/occlum/blob/master/tools/toolchains/dcap_lib/examples/dcap_test.rs 6 | #[cfg(feature = "occlum")] 7 | mod dcap; 8 | mod task; 9 | 10 | #[cfg(feature = "task_db")] 11 | mod db_persistent; 12 | 13 | use std::io::Result; 14 | use std::net::TcpListener; 15 | 16 | use pobf_thread_pool::ThreadPool; 17 | 18 | const ENCLAVE_TCS_NUM: usize = 10; 19 | const ADDRESS: &str = "127.0.0.1:7788"; 20 | 21 | fn main() { 22 | #[cfg(feature = "occlum")] 23 | dcap::dcap_demo(); 24 | // Start listening to the port. 25 | let listener = match TcpListener::bind(ADDRESS) { 26 | Ok(res) => res, 27 | Err(e) => { 28 | panic!("[-] Failed to bind to the given address due to {}.", e); 29 | } 30 | }; 31 | 32 | #[cfg(feature = "task_db")] 33 | db::DUMPER.call_once(|| Box::new(db_persistent::SgxPersistentLayer)); 34 | 35 | let pool = ThreadPool::new(ENCLAVE_TCS_NUM); 36 | 37 | println!("Server started."); 38 | loop { 39 | match listener.accept() { 40 | Ok((stream, _)) => { 41 | if pool 42 | .execute(move || task::handle_client(stream).unwrap()) 43 | .is_err() 44 | { 45 | println!("[-] Job execution failed."); 46 | break; 47 | } 48 | } 49 | Err(e) => panic!("[-] Failed! {:?}", e), 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /others/rust_app/server/src/task.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | io::{BufRead, BufReader, BufWriter, Read, Result, Write}, 3 | net::TcpStream, 4 | time::Instant, 5 | }; 6 | 7 | use pobf_crypto::{handle_sev_pubkey, init_keypair}; 8 | 9 | cfg_if::cfg_if! { 10 | if #[cfg(feature = "task_tvm")] { 11 | use evaluation_tvm::private_computation; 12 | } else if #[cfg(feature = "task_db")] { 13 | use db::private_computation; 14 | } else if #[cfg(feature = "task_fann")] { 15 | use fann::private_computation; 16 | } else if #[cfg(feature = "task_fasta")] { 17 | use fasta::private_computation; 18 | } else if #[cfg(feature = "task_polybench")] { 19 | use polybench::private_computation; 20 | } else if #[cfg(feature = "task_sample")] { 21 | use sample_add::private_computation; 22 | } 23 | } 24 | 25 | pub fn handle_client(stream: TcpStream) -> Result<()> { 26 | let socket_clone = stream.try_clone().unwrap(); 27 | let mut reader = BufReader::new(stream); 28 | let mut writer = BufWriter::new(socket_clone); 29 | 30 | // Generate two key pairs. 31 | println!("[+] Sampling key pairs"); 32 | let mut key_pair = init_keypair().unwrap(); 33 | let public_key = &key_pair.pub_k; 34 | println!("[+] Receiving peer public key"); 35 | let peer_pub_key = handle_sev_pubkey(&mut reader).unwrap(); 36 | println!("[+] Sending public key"); 37 | writer.write_all(public_key.as_ref()).unwrap(); 38 | writer.flush().unwrap(); 39 | 40 | key_pair.compute_shared_key(&peer_pub_key, b"").unwrap(); 41 | 42 | let mut length_str = String::with_capacity(512); 43 | reader.read_line(&mut length_str)?; 44 | let data_len = length_str[..length_str.len() - 1].parse::().unwrap(); 45 | println!("Data length = {}", data_len); 46 | let mut input = vec![0u8; data_len]; 47 | reader.read_exact(&mut input)?; 48 | println!("Read data."); 49 | let input = key_pair.decrypt_with_smk(&input).unwrap(); 50 | 51 | let output = perform_task(input); 52 | let output = key_pair.encrypt_with_smk(&output).unwrap(); 53 | writer.write(output.len().to_string().as_bytes())?; 54 | writer.write(b"\n")?; 55 | writer.flush()?; 56 | writer.write(&output)?; 57 | writer.write(b"\n")?; 58 | writer.flush()?; 59 | println!("Sent data. Length = {}", output.len()); 60 | println!("Finished!"); 61 | 62 | Ok(()) 63 | } 64 | 65 | fn perform_task(input: Vec) -> Vec { 66 | let now = Instant::now(); 67 | #[cfg(feature = "task_polybench")] 68 | { 69 | let res = private_computation(input, &|| { 70 | SystemTime::now() 71 | .duration_since(UNIX_EPOCH) 72 | .unwrap() 73 | .as_nanos() as u64 74 | }); 75 | println!("{}", String::from_utf8(res.clone()).unwrap()); 76 | let elapsed = now.elapsed(); 77 | println!("Elapsed: {:.2?}", elapsed); 78 | res 79 | } 80 | 81 | #[cfg(not(feature = "task_polybench"))] 82 | { 83 | let res = private_computation(input); 84 | let elapsed = now.elapsed(); 85 | println!("Elapsed: {:.2?}", elapsed); 86 | 87 | res 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /platform_sev/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "platform_sev" 3 | version = "0.1.0" 4 | edition = "2021" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [features] 8 | default = [] 9 | task_fann = ["fann"] 10 | task_fasta = ["fasta"] 11 | task_polybench = ["polybench", "polybench-rs"] 12 | # computing tasks 13 | # The tasks are enabled by `cfg_if`. 14 | task_sample = ["sample_add"] 15 | task_tvm = ["evaluation_tvm"] 16 | task_db = ["db"] 17 | task_none = [] 18 | native = [] 19 | 20 | nussinov = [] 21 | _2mm = [] 22 | _3mm = [] 23 | gemm = [] 24 | gemver = [] 25 | gesummv = [] 26 | symm = [] 27 | syrk = [] 28 | syr2k = [] 29 | trmm = [] 30 | mvt = [] 31 | 32 | durbin = [] 33 | gramschmidt = [] 34 | cholesky = [] 35 | lu = [] 36 | ludcmp = [] 37 | trisolv = [] 38 | covariance = [] 39 | deriche = [] 40 | floyd_warshall = [] 41 | adi = [] 42 | fdtd_2d = [] 43 | heat_3d = [] 44 | jacobi_1d = [] 45 | jacobi_2d = [] 46 | seidel_2d = [] 47 | 48 | atax = [] 49 | bicg = [] 50 | doitgen = [] 51 | correlation = [] 52 | 53 | [dependencies] 54 | aes-gcm = { version = "0.10.1", features = ["zeroize"] } 55 | anyhow = "1.0.71" 56 | cfg-if = "1.0.0" 57 | clap = { version = "4.2.7", features = ["derive"] } 58 | clear_on_drop = { git = "https://github.com/hiroki-chen/clear_on_drop.git", features = [ 59 | "nightly", 60 | ] } 61 | db = { path = "../cctasks/db", optional = true } 62 | env_logger = "0.10.0" 63 | evaluation_tvm = { path = "../others/evaluation_tvm", optional = true } 64 | fann = { path = "../cctasks/fann", optional = true } 65 | fasta = { path = "../cctasks/fasta", optional = true } 66 | log = "0.4.17" 67 | pobf_state = { path = "../pobf_state", features = ["time_breakdown"] } 68 | pobf_thread_pool = { path = "../pobf_thread_pool" } 69 | polybench = { path = "../cctasks/polybench", optional = true, features = [ 70 | "std", 71 | ], default-features = false } 72 | polybench-rs = { git = "https://github.com/hiroki-chen/polybench-rs.git", optional = true } 73 | rand = "0.8.5" 74 | rand_core = "0.6.4" 75 | ring = "0.16.20" 76 | sample_add = { path = "../cctasks/sample_add", optional = true } 77 | zeroize = "1.6.0" 78 | -------------------------------------------------------------------------------- /platform_sev/Makefile: -------------------------------------------------------------------------------- 1 | .phony: all clean 2 | 3 | all: ./attestation_lib/libsev_attestation.so 4 | @cargo build -r 5 | 6 | ./attestation_lib/libsev_attestation.so: 7 | @$(MAKE) -C ./attestation_lib 8 | 9 | clean: 10 | @cargo clean 11 | @$(MAKE) -C ./attestation_lib clean 12 | -------------------------------------------------------------------------------- /platform_sev/README.md: -------------------------------------------------------------------------------- 1 | # PoBF on AMD-SEV 2 | 3 | This folder contains the code base for running our Proof-of-Concept implementation of PoBF on VM-based TEEs (i.e., SEV). We utilize the implementation of Microsoft Azure's attestation library, so you must need to run the code on an Azure EPYC-3rd instance to ensure that works as expected. 4 | 5 | Before that, make sure the client library is properly installed. You can install the library by: 6 | 7 | ```sh 8 | sudo apt install -y libcurl4-openssl-dev libjsoncpp-dev libboost-all-dev nlohman-json3-dev 9 | wget https://packages.microsoft.com/repos/azurecore/pool/main/a/azguestattestation1/azguestattestation1_1.0.5_amd64.deb 10 | sudo dpkg -i ./azguestattestation1_1.0.5_amd64.deb 11 | ``` 12 | 13 | ## Some Minor Issues 14 | 15 | * Using an old nightly Rust toolchain will cause the program to panic due to `segmentation fault` in `clear_on_drop`. 16 | -------------------------------------------------------------------------------- /platform_sev/attestation_lib/Makefile: -------------------------------------------------------------------------------- 1 | CXX_FLAGS := -O2 -Wall -c -fPIC 2 | CXX_LD_FLAGS := -shared -lcurl -ljsoncpp -lazguestattestation 3 | 4 | ATTESTATION_LIB = libsev_attestation.so 5 | ATTESTATION_SRCS = $(wildcard ./*.cc) 6 | ATTESTATION_OBJS = $(patsubst %.cc, %.o, $(ATTESTATION_SRCS)) 7 | 8 | .phony: clean 9 | 10 | $(ATTESTATION_LIB): $(ATTESTATION_OBJS) 11 | $(CXX) $(CXX_LD_FLAGS) -o $@ $^ 12 | 13 | %.o: %.cc 14 | $(CXX) $(CXX_FLAGS) -o $@ $^ 15 | 16 | clean: 17 | @rm -f *.so *.o 18 | -------------------------------------------------------------------------------- /platform_sev/attestation_lib/attest.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "utils.h" 14 | #include "logger.h" 15 | 16 | using json = nlohmann::json; 17 | 18 | #define OUTPUT_TYPE_JWT "token" 19 | #define OUTPUT_TYPE_BOOL "bool" 20 | 21 | // default guest attestation url 22 | std::string default_attestation_url = 23 | "https://sharedeus2.eus2.attest.azure.net/"; 24 | 25 | // Do not call this function multiple times unless the whole program exits. 26 | extern "C" void uninitialize() { Uninitialize(); } 27 | 28 | extern "C" int get_attestation_report(unsigned char* p_buf, size_t buf_len, 29 | const char* p_nonce, size_t nonce_len) { 30 | std::string attestation_url; 31 | std::string nonce; 32 | if (attestation_url.empty()) { 33 | // use the default attestation url 34 | attestation_url.assign(default_attestation_url); 35 | } 36 | 37 | if (p_nonce != nullptr) { 38 | nonce = std::string(p_nonce, nonce_len); 39 | } 40 | 41 | AttestationClient* attestation_client = nullptr; 42 | Logger* log_handle = new Logger(); 43 | 44 | // Initialize attestation client 45 | if (!Initialize(log_handle, &attestation_client)) { 46 | printf("Failed to create attestation client object\n"); 47 | Uninitialize(); 48 | exit(1); 49 | } 50 | 51 | // parameters for the Attest call 52 | attest::ClientParameters params = {}; 53 | params.attestation_endpoint_url = (unsigned char*)attestation_url.c_str(); 54 | std::string client_payload_str = 55 | "{\"nonce\":\"" + nonce + "\"}"; // nonce is optional 56 | params.client_payload = (unsigned char*)client_payload_str.c_str(); 57 | params.version = CLIENT_PARAMS_VERSION; 58 | unsigned char* jwt = nullptr; 59 | attest::AttestationResult result; 60 | 61 | bool is_cvm = false; 62 | bool attestation_success = true; 63 | std::string jwt_str; 64 | // call attest 65 | if ((result = attestation_client->Attest(params, &jwt)).code_ != 66 | attest::AttestationResult::ErrorCode::SUCCESS) { 67 | attestation_success = false; 68 | } 69 | 70 | if (attestation_success) { 71 | jwt_str = reinterpret_cast(jwt); 72 | attestation_client->Free(jwt); 73 | // Prase attestation token to extract isolation tee details 74 | std::vector tokens; 75 | boost::split(tokens, jwt_str, [](char c) { return c == '.'; }); 76 | if (tokens.size() < 3) { 77 | printf("Invalid JWT token"); 78 | exit(1); 79 | } 80 | 81 | std::string jwt_response = base64_decode(tokens[1]); 82 | 83 | // Copy back to Rust. 84 | if (jwt_response.size() >= buf_len) { 85 | printf("the given buffer is too small!"); 86 | return -1; 87 | } 88 | 89 | memcpy(p_buf, jwt_response.c_str(), jwt_response.size()); 90 | return 0; 91 | } else { 92 | return -1; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /platform_sev/attestation_lib/logger.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #include "logger.h" 9 | 10 | void Logger::Log(const char* log_tag, LogLevel level, const char* function, 11 | const int line, const char* fmt, ...) { 12 | va_list args; 13 | va_start(args, fmt); 14 | size_t len = std::vsnprintf(NULL, 0, fmt, args); 15 | va_end(args); 16 | 17 | std::vector str(len + 1); 18 | 19 | va_start(args, fmt); 20 | std::vsnprintf(&str[0], len + 1, fmt, args); 21 | va_end(args); 22 | 23 | // uncomment the below statement and rebuild if details debug logs are needed 24 | // printf("Level: %s Tag: %s %s:%d:%s\n", 25 | // attest::AttestationLogger::LogLevelStrings[level].c_str(), log_tag, 26 | // function, line, &str[0]); 27 | } -------------------------------------------------------------------------------- /platform_sev/attestation_lib/logger.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | class Logger : public attest::AttestationLogger { 15 | public: 16 | void Log(const char* log_tag, LogLevel level, const char* function, 17 | const int line, const char* fmt, ...); 18 | }; -------------------------------------------------------------------------------- /platform_sev/attestation_lib/utils.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "utils.h" 13 | 14 | std::vector base64_to_binary(const std::string& base64_data) { 15 | using namespace boost::archive::iterators; 16 | using It = 17 | transform_width, 8, 6>; 18 | return boost::algorithm::trim_right_copy_if( 19 | std::vector(It(std::begin(base64_data)), 20 | It(std::end(base64_data))), 21 | [](char c) { return c == '\0'; }); 22 | } 23 | 24 | std::string binary_to_base64(const std::vector& binary_data) { 25 | using namespace boost::archive::iterators; 26 | using It = base64_from_binary< 27 | transform_width::const_iterator, 6, 8>>; 28 | auto tmp = 29 | std::string(It(std::begin(binary_data)), It(std::end(binary_data))); 30 | return tmp.append((3 - binary_data.size() % 3) % 3, '='); 31 | } 32 | 33 | std::string binary_to_base64url(const std::vector& binary_data) { 34 | using namespace boost::archive::iterators; 35 | using It = base64_from_binary< 36 | transform_width::const_iterator, 6, 8>>; 37 | auto tmp = 38 | std::string(It(std::begin(binary_data)), It(std::end(binary_data))); 39 | 40 | // For encoding to base64url, replace "+" with "-" and "/" with "_" 41 | boost::replace_all(tmp, "+", "-"); 42 | boost::replace_all(tmp, "/", "_"); 43 | 44 | // We do not need to add padding characters while url encoding. 45 | return tmp; 46 | } 47 | 48 | std::vector base64url_to_binary(const std::string& base64_data) { 49 | std::string stringData = base64_data; 50 | 51 | // While decoding base64 url, replace - with + and _ with + and 52 | // use stanard base64 decode. we dont need to add padding characters. 53 | // underlying library handles it. 54 | boost::replace_all(stringData, "-", "+"); 55 | boost::replace_all(stringData, "_", "/"); 56 | 57 | return base64_to_binary(stringData); 58 | } 59 | 60 | std::string base64_decode(const std::string& data) { 61 | using namespace boost::archive::iterators; 62 | using It = 63 | transform_width, 8, 6>; 64 | return boost::algorithm::trim_right_copy_if( 65 | std::string(It(std::begin(data)), It(std::end(data))), 66 | [](char c) { return c == '\0'; }); 67 | } -------------------------------------------------------------------------------- /platform_sev/attestation_lib/utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | /** 6 | * Given a base64 encoded string, convert it to binary byte vector 7 | * 8 | * param[in] base64_data : string of base64 encoded data 9 | * 10 | * returns: vector of unsigned char (byte) 11 | */ 12 | std::vector base64_to_binary(const std::string& base64_data); 13 | 14 | /** 15 | * Given binary byte vector, convert it to base64 encoded string. 16 | * 17 | * param[in] binary_data: vector of unsigned char (byte) 18 | * 19 | * returns string of data which represents base64 encoded input byte array. 20 | */ 21 | std::string binary_to_base64(const std::vector& binary_data); 22 | 23 | /** 24 | * Given binary byte vector, convert it to base64 url encoded string. 25 | * 26 | * param[in] binary_data: vector of unsigned char (byte) 27 | * 28 | * returns string of data which represents base64 url encoded input byte array. 29 | */ 30 | std::string binary_to_base64url(const std::vector& binary_data); 31 | 32 | /** 33 | * Given a base64 url encoded string, convert it to binary byte vector 34 | * 35 | * param[in] base64url_data : string of base64 url encoded data 36 | * 37 | * returns: vector of unsigned char (byte) 38 | */ 39 | std::vector base64url_to_binary( 40 | const std::string& base64url_data); 41 | 42 | /** 43 | * Given a string, convert it to base64 encoded string 44 | * 45 | * param[in] data : string data 46 | * 47 | * returns: base64 encoded string 48 | */ 49 | std::string base64_decode(const std::string& data); -------------------------------------------------------------------------------- /platform_sev/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let lib_path = format!( 3 | "{}/attestation_lib", 4 | std::env::var("CARGO_MANIFEST_DIR").unwrap_or_default() 5 | ); 6 | println!("cargo:rerun-if-changed=build.rs"); 7 | println!("cargo:rustc-link-search=native={lib_path}",); 8 | println!("cargo:rustc-link-lib=dylib=sev_attestation"); 9 | println!("cargo:rustc-link-lib=dylib=azguestattestation"); 10 | println!("cargo:rustc-env=LD_LIBRARY_PATH={lib_path}"); 11 | } 12 | -------------------------------------------------------------------------------- /platform_sev/rust-toolchain: -------------------------------------------------------------------------------- 1 | nightly-2023-04-25 2 | -------------------------------------------------------------------------------- /platform_sev/src/db_persistent.rs: -------------------------------------------------------------------------------- 1 | use std::{io::Write, time}; 2 | 3 | use db::db::{DbError, DbResult, Persistent}; 4 | use log::info; 5 | pub struct SgxPersistentLayer; 6 | 7 | impl Persistent for SgxPersistentLayer { 8 | fn write_disk(&self, path: &str, buf: &[u8]) -> DbResult<()> { 9 | info!("writing {path} with buf.len() = {} bytes", buf.len()); 10 | 11 | let now = time::Instant::now(); 12 | let mut file = std::fs::OpenOptions::new() 13 | .append(true) 14 | .create(true) 15 | .open(path) 16 | .map_err(|_| DbError::PathNotFound(path.into()))?; 17 | file.write_all(buf).map_err(|_| DbError::Unknown)?; 18 | let elapsed: time::Duration = now.elapsed(); 19 | 20 | let throughput = (buf.len() as f64 / elapsed.as_secs_f64()) / 1000000.0; 21 | 22 | info!("[+] Time elapsed: {elapsed:?}; throughput: {throughput} MB/s"); 23 | 24 | Ok(()) 25 | } 26 | 27 | fn read_disk(&self, path: &str) -> DbResult> { 28 | info!("reading {path}"); 29 | 30 | let now = time::Instant::now(); 31 | let buf = std::fs::read(path).map_err(|_| DbError::PathNotFound(path.into()))?; 32 | let elapsed: time::Duration = now.elapsed(); 33 | 34 | let throughput = (buf.len() as f64 / elapsed.as_secs_f64()) / 1000000.0; 35 | 36 | info!("[+] Time elapsed: {elapsed:?}; throughput: {throughput} MB/s"); 37 | 38 | Ok(buf) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /platform_sev/src/ffi.rs: -------------------------------------------------------------------------------- 1 | #[repr(C)] 2 | pub enum EncryptionType { 3 | None = 0, 4 | } 5 | 6 | #[repr(u16)] 7 | pub enum RsaScheme { 8 | RsaNull = 0x0010, // TPM2_ALG_NULL 9 | RsaEs = 0x0015, // TPM2_ALG_RSAES 10 | RsaOaep = 0x0017, // TPM2_ALG_OAEP 11 | } 12 | 13 | #[repr(u16)] 14 | pub enum RsaHashAlg { 15 | RsaSha1 = 0x0004, // TPM2_ALG_SHA1 16 | RsaSha256 = 0x000B, // TPM2_ALG_SHA256 17 | RsaSha384 = 0x000C, // TPM2_ALG_SHA384 18 | RsaSha512 = 0x000D, // TPM2_ALG_SHA512 19 | } 20 | 21 | extern "C" { 22 | pub fn get_attestation_report( 23 | buf: *mut u8, 24 | len: usize, 25 | nonce: *const u8, 26 | nonce_len: usize, 27 | ) -> i64; 28 | 29 | pub fn encrypt( 30 | encryption_type: EncryptionType, 31 | jwt_token: *const u8, 32 | data: *const u8, 33 | data_size: u32, 34 | encrypted_data: *mut *mut u8, 35 | encrypted_data_size: *mut u32, 36 | encryption_metadata: *mut *mut u8, // Must be non-null pointer, but this is not used during encryption. 37 | encryption_metadata_size: *mut u32, 38 | rsa_wrap_alg_id: RsaScheme, 39 | rsa_hash_alg_id: RsaHashAlg, 40 | ) -> i64; 41 | 42 | pub fn decrypt( 43 | encryption_type: EncryptionType, 44 | encrypted_data: *const u8, 45 | encrypted_data_size: u32, 46 | _: *const u8, 47 | _: u32, 48 | decrypted_data: *mut *mut u8, 49 | decrypted_data_size: *mut u32, 50 | rsa_wrap_alg_id: RsaScheme, 51 | rsa_hash_alg_id: RsaHashAlg, 52 | ) -> i64; 53 | 54 | /// Should be called if remote attestation finishes. 55 | pub fn uninitialize(); 56 | } 57 | -------------------------------------------------------------------------------- /platform_sev/src/key.rs: -------------------------------------------------------------------------------- 1 | //! A simplified version of the ECDH key agreement protocol for AMD-SEV. 2 | 3 | use ring::{ 4 | agreement::{EphemeralPrivateKey, PublicKey, X25519}, 5 | rand, 6 | }; 7 | 8 | pub fn get_keypair() -> (EphemeralPrivateKey, PublicKey) { 9 | let rng = rand::SystemRandom::new(); 10 | let prv_key = EphemeralPrivateKey::generate(&X25519, &rng).unwrap(); 11 | let pub_key = prv_key.compute_public_key().unwrap(); 12 | 13 | (prv_key, pub_key) 14 | } 15 | -------------------------------------------------------------------------------- /platform_sev/src/main.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused)] 2 | #![feature(cstr_from_bytes_until_nul)] 3 | 4 | use clap::{Arg, Parser}; 5 | 6 | use crate::{ffi::uninitialize, pobf::entry}; 7 | 8 | mod ffi; 9 | mod key; 10 | mod pobf; 11 | mod vecaes; 12 | 13 | #[cfg(feature = "task_db")] 14 | mod db_persistent; 15 | 16 | #[derive(Parser)] 17 | #[clap(author, version, about, long_about = None)] 18 | #[clap(propagate_version = true)] 19 | struct Args { 20 | #[clap(value_parser)] 21 | address: String, 22 | #[clap(value_parser)] 23 | port: u16, 24 | #[clap(value_parser, default_value_t = 0x20)] 25 | stack_size: u16, 26 | } 27 | 28 | fn init_logger() { 29 | if std::env::var("RUST_LOG").is_err() { 30 | std::env::set_var("RUST_LOG", "info"); 31 | } 32 | env_logger::init(); 33 | } 34 | 35 | fn main() { 36 | init_logger(); 37 | 38 | let args = Args::parse(); 39 | log::info!( 40 | "Performing PoBF workflow on AMD-SEV... Address is {}:{}", 41 | args.address, 42 | args.port 43 | ); 44 | 45 | #[cfg(feature = "task_db")] 46 | db::DUMPER.call_once(|| Box::new(db_persistent::SgxPersistentLayer)); 47 | 48 | match entry(&args.address, args.port, args.stack_size) { 49 | Ok(_) => log::info!("[+] Finished with success"), 50 | Err(err) => log::error!("[-] PoBF workflow returned {err}"), 51 | } 52 | 53 | unsafe { 54 | uninitialize(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /platform_sev/src/vecaes.rs: -------------------------------------------------------------------------------- 1 | use aes_gcm::{aead::Aead, Aes128Gcm, AesGcm, KeyInit, Nonce}; 2 | use pobf_state::{Decryption, EncDec, Encryption, Result}; 3 | use zeroize::Zeroize; 4 | 5 | pub struct VecAESData { 6 | inner: Vec, 7 | } 8 | 9 | impl From> for VecAESData { 10 | fn from(v: Vec) -> Self { 11 | VecAESData { inner: v } 12 | } 13 | } 14 | 15 | impl Into> for VecAESData { 16 | fn into(self) -> Vec { 17 | self.inner 18 | } 19 | } 20 | 21 | impl Zeroize for VecAESData { 22 | fn zeroize(&mut self) { 23 | self.inner.zeroize(); 24 | } 25 | } 26 | 27 | /// A struct used to represent the SEV key from MAA. 28 | pub struct AES128Key { 29 | inner: [u8; 16], 30 | } 31 | 32 | impl From> for AES128Key { 33 | fn from(value: Vec) -> Self { 34 | Self { 35 | inner: { 36 | let mut data = [0u8; 16]; 37 | data.copy_from_slice(&value[..16]); 38 | data 39 | }, 40 | } 41 | } 42 | } 43 | 44 | impl Default for AES128Key { 45 | fn default() -> Self { 46 | AES128Key { inner: [0u8; 16] } 47 | } 48 | } 49 | 50 | impl Zeroize for AES128Key { 51 | fn zeroize(&mut self) { 52 | self.inner.zeroize(); 53 | } 54 | } 55 | 56 | impl Encryption for VecAESData { 57 | // For the sake of simplicity, we incorporate a static nonce into the ciphertext, but it is trivial to implement 58 | // AES-GCM algorithm using an OS-generated nonce. 59 | fn encrypt(self, key: &AES128Key) -> Result { 60 | let cipher = Aes128Gcm::new(key.inner.as_ref().into()); 61 | let nonce = Nonce::from_slice(&[0u8; 12]); 62 | let ciphertext = cipher.encrypt(nonce, self.inner.as_slice()).unwrap(); 63 | 64 | Ok(VecAESData::from(ciphertext)) 65 | } 66 | } 67 | 68 | impl Decryption for VecAESData { 69 | fn decrypt(self, key: &AES128Key) -> Result { 70 | let cipher = Aes128Gcm::new(key.inner.as_ref().into()); 71 | let nonce = Nonce::from_slice(&[0u8; 12]); 72 | let plaintext = cipher.decrypt(nonce, self.inner.as_slice()).unwrap(); 73 | 74 | Ok(VecAESData::from(plaintext)) 75 | } 76 | } 77 | 78 | impl EncDec for VecAESData {} 79 | -------------------------------------------------------------------------------- /platform_sgx/app/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "app" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | base16 = "0.2.1" 8 | base64 = "0.13.0" 9 | clap = { version = "3.1.5", features = ["derive"] } 10 | env_logger = "0.9.1" 11 | hex = "0.4.3" 12 | libc = "0.2.0" 13 | log = { version = "0.4.17", features = [ 14 | "max_level_debug", 15 | "release_max_level_info", 16 | ] } 17 | serde = { version = "1.0.145", features = ["derive"] } 18 | serde_json = "1.0.86" 19 | sgx_types = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", branch = "v2.0.0-preview", package = "sgx_types" } 20 | sgx_urts = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", branch = "v2.0.0-preview", package = "sgx_urts" } 21 | pobf_thread_pool = { path = "../../pobf_thread_pool" } 22 | -------------------------------------------------------------------------------- /platform_sgx/app/build.rs: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License.. 17 | 18 | use std::env; 19 | 20 | fn main() { 21 | println!("cargo:rerun-if-env-changed=SGX_MODE"); 22 | println!("cargo:rerun-if-changed=build.rs"); 23 | 24 | let sdk_dir = env::var("SGX_SDK").unwrap_or_else(|_| "/opt/intel/sgxsdk".to_string()); 25 | let mode = env::var("SGX_MODE").unwrap_or_else(|_| "HW".to_string()); 26 | 27 | println!("cargo:rustc-link-search=native=../lib"); 28 | println!("cargo:rustc-link-lib=static=enclave_u"); 29 | println!("cargo:rustc-link-search=native={}/lib64", sdk_dir); 30 | 31 | // You may need to execute 32 | // sudo ln -s /usr/lib/x86_64-linux-gnu/libsgx_dcap_quoteverify.so.1 /usr/lib/x86_64-linux-gnu/libsgx_dcap_quoteverify.so 33 | println!("cargo:rustc-link-lib=dylib=sgx_dcap_quoteverify"); 34 | println!("cargo:rustc-link-lib=dylib=sgx_dcap_ql"); 35 | // Add some extra libs for RA. 36 | match mode.as_ref() { 37 | "SIM" | "SW" => { 38 | println!("cargo:rustc-link-lib=dylib=sgx_urts_sim"); 39 | println!("cargo:rustc-link-lib=dylib=sgx_epid_sim"); 40 | } 41 | "HW" | "HYPER" => { 42 | println!("cargo:rustc-link-lib=dylib=sgx_urts"); 43 | println!("cargo:rustc-link-lib=dylib=sgx_epid"); 44 | } 45 | _ => { 46 | println!("cargo:rustc-link-lib=dylib=sgx_urts"); 47 | println!("cargo:rustc-link-lib=dylib=sgx_epid"); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /platform_sgx/enclave/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "enclave" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | name = "pobfref" 8 | crate-type = ["lib", "staticlib"] 9 | 10 | [features] 11 | # turn on mirai when veirifying towards mirai 12 | default = ["leak_log"] 13 | sgx = ["sgx_no_tstd", "sgx_trts", "sgx_tseal"] 14 | rand = ["sgx_rand"] 15 | # potential violations 16 | violation = ["vio_typestate", "vio_private", "vio_unsafe", "vio_ocall", "sgx"] 17 | vio_typestate = ["sgx", "disallowed_trans", "rude_copy"] 18 | disallowed_trans = [] 19 | rude_copy = [] 20 | vio_private = ["sgx", "direct_decrypt", "access_inner", "access_key"] 21 | direct_decrypt = [] 22 | access_inner = [] 23 | access_key = [] 24 | vio_unsafe = ["sgx", "raw_read", "raw_write"] 25 | raw_read = [] 26 | raw_write = [] 27 | vio_ocall = ["sgx", "leak_log", "leak_net", "leak_file"] 28 | leak_log = [] 29 | leak_net = [] 30 | leak_file = [] 31 | # Build native enclave. 32 | native_enclave = [] 33 | native_zeroize = [] 34 | 35 | # computing tasks 36 | # The tasks are enabled by `cfg_if`. 37 | task_sample = ["sample_add"] 38 | task_tvm = ["evaluation_tvm"] 39 | task_polybench = ["polybench", "polybench-rs"] 40 | task_fann = ["fann"] 41 | task_fasta = ["fasta"] 42 | task_db = ["db"] 43 | task_none = [] 44 | mirai_sample = [] 45 | 46 | nussinov = [] 47 | _2mm = [] 48 | _3mm = [] 49 | gemm = [] 50 | gemver = [] 51 | gesummv = [] 52 | symm = [] 53 | syrk = [] 54 | syr2k = [] 55 | trmm = [] 56 | mvt = [] 57 | 58 | durbin = [] 59 | gramschmidt = [] 60 | cholesky = [] 61 | lu = [] 62 | ludcmp = [] 63 | trisolv = [] 64 | covariance = [] 65 | deriche = [] 66 | floyd_warshall = [] 67 | adi = [] 68 | fdtd_2d = [] 69 | heat_3d = [] 70 | jacobi_1d = [] 71 | jacobi_2d = [] 72 | seidel_2d = [] 73 | 74 | atax = [] 75 | bicg = [] 76 | doitgen = [] 77 | correlation = [] 78 | 79 | [dependencies] 80 | base64 = { version = "0.13.0", default-features = false, features = ["alloc"] } 81 | cfg-if = "1.0.0" 82 | clear_on_drop = { git = "https://github.com/hiroki-chen/clear_on_drop.git", branch = "master" } 83 | # clear_on_drop = { git = "https://github.com/cesarb/clear_on_drop.git", branch = "master" } 84 | # Evaluations. 85 | evaluation_tvm = { path = "../../cctasks/evaluation_tvm", optional = true } 86 | fann = { path = "../../cctasks/fann", optional = true } 87 | fasta = { path = "../../cctasks/fasta", optional = true } 88 | polybench = { path = "../../cctasks/polybench", optional = true } 89 | polybench-rs = { git = "https://github.com/hiroki-chen/polybench-rs.git", optional = true } 90 | sample_add = { path = "../../cctasks/sample_add", optional = true } 91 | db = { path = "../../cctasks/db", optional = true } 92 | 93 | # Patched version. 94 | sgx_alloc = { git = "https://github.com/hiroki-chen/incubator-teaclave-sgx-sdk.git", branch = "v2.0.0-preview", package = "sgx_alloc" } 95 | sgx_crypto = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", branch = "v2.0.0-preview", package = "sgx_crypto" } 96 | sgx_libc = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", branch = "v2.0.0-preview", package = "sgx_libc", default-features = false } 97 | sgx_no_tstd = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", branch = "v2.0.0-preview", package = "sgx_no_tstd", optional = true } 98 | sgx_rand = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", branch = "v2.0.0-preview", package = "sgx_rand", optional = true } 99 | sgx_tdh = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", branch = "v2.0.0-preview", package = "sgx_tdh" } 100 | # sgx_tstd = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", branch = "v2.0.0-preview", package = "sgx_tstd", default-features = false, optional = true } 101 | sgx_trts = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", branch = "v2.0.0-preview", package = "sgx_trts", optional = true } 102 | sgx_tse = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", branch = "v2.0.0-preview", package = "sgx_tse" } 103 | sgx_tseal = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", branch = "v2.0.0-preview", package = "sgx_tseal", optional = true } 104 | sgx_types = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", branch = "v2.0.0-preview", package = "sgx_types" } 105 | webpki = { version = "0.22.0", features = ["alloc"] } 106 | 107 | # External dependencies: SGX compatible (or) crates. 108 | mirai-annotations = { git = "https://github.com/hiroki-chen/MIRAI.git", branch = "main", package = "mirai-annotations" } 109 | pobf_state = { path = "../../pobf_state", features = ["sgx", "time_breakdown"] } 110 | percent-encoding = { git = "https://github.com/mesalock-linux/rust-url-sgx" } 111 | zeroize = "1.5.7" 112 | 113 | [patch.crates-io] 114 | # Patached version of ring. 115 | ring = { git = "https://github.com/sccommunity/ring.git", branch = "teaclave-sgx" } 116 | -------------------------------------------------------------------------------- /platform_sgx/enclave/Intel_SGX_Attestation_RootCA.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ya0guang/PoBF/8bc1a900fdae506d0a113250b94f594ae70f2762/platform_sgx/enclave/Intel_SGX_Attestation_RootCA.cer -------------------------------------------------------------------------------- /platform_sgx/enclave/Intel_SGX_Attestation_RootCA.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIFSzCCA7OgAwIBAgIJANEHdl0yo7CUMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNV 3 | BAYTAlVTMQswCQYDVQQIDAJDQTEUMBIGA1UEBwwLU2FudGEgQ2xhcmExGjAYBgNV 4 | BAoMEUludGVsIENvcnBvcmF0aW9uMTAwLgYDVQQDDCdJbnRlbCBTR1ggQXR0ZXN0 5 | YXRpb24gUmVwb3J0IFNpZ25pbmcgQ0EwIBcNMTYxMTE0MTUzNzMxWhgPMjA0OTEy 6 | MzEyMzU5NTlaMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEUMBIGA1UEBwwL 7 | U2FudGEgQ2xhcmExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0aW9uMTAwLgYDVQQD 8 | DCdJbnRlbCBTR1ggQXR0ZXN0YXRpb24gUmVwb3J0IFNpZ25pbmcgQ0EwggGiMA0G 9 | CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCfPGR+tXc8u1EtJzLA10Feu1Wg+p7e 10 | LmSRmeaCHbkQ1TF3Nwl3RmpqXkeGzNLd69QUnWovYyVSndEMyYc3sHecGgfinEeh 11 | rgBJSEdsSJ9FpaFdesjsxqzGRa20PYdnnfWcCTvFoulpbFR4VBuXnnVLVzkUvlXT 12 | L/TAnd8nIZk0zZkFJ7P5LtePvykkar7LcSQO85wtcQe0R1Raf/sQ6wYKaKmFgCGe 13 | NpEJUmg4ktal4qgIAxk+QHUxQE42sxViN5mqglB0QJdUot/o9a/V/mMeH8KvOAiQ 14 | byinkNndn+Bgk5sSV5DFgF0DffVqmVMblt5p3jPtImzBIH0QQrXJq39AT8cRwP5H 15 | afuVeLHcDsRp6hol4P+ZFIhu8mmbI1u0hH3W/0C2BuYXB5PC+5izFFh/nP0lc2Lf 16 | 6rELO9LZdnOhpL1ExFOq9H/B8tPQ84T3Sgb4nAifDabNt/zu6MmCGo5U8lwEFtGM 17 | RoOaX4AS+909x00lYnmtwsDVWv9vBiJCXRsCAwEAAaOByTCBxjBgBgNVHR8EWTBX 18 | MFWgU6BRhk9odHRwOi8vdHJ1c3RlZHNlcnZpY2VzLmludGVsLmNvbS9jb250ZW50 19 | L0NSTC9TR1gvQXR0ZXN0YXRpb25SZXBvcnRTaWduaW5nQ0EuY3JsMB0GA1UdDgQW 20 | BBR4Q3t2pn680K9+QjfrNXw7hwFRPDAfBgNVHSMEGDAWgBR4Q3t2pn680K9+Qjfr 21 | NXw7hwFRPDAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkq 22 | hkiG9w0BAQsFAAOCAYEAeF8tYMXICvQqeXYQITkV2oLJsp6J4JAqJabHWxYJHGir 23 | IEqucRiJSSx+HjIJEUVaj8E0QjEud6Y5lNmXlcjqRXaCPOqK0eGRz6hi+ripMtPZ 24 | sFNaBwLQVV905SDjAzDzNIDnrcnXyB4gcDFCvwDFKKgLRjOB/WAqgscDUoGq5ZVi 25 | zLUzTqiQPmULAQaB9c6Oti6snEFJiCQ67JLyW/E83/frzCmO5Ru6WjU4tmsmy8Ra 26 | Ud4APK0wZTGtfPXU7w+IBdG5Ez0kE1qzxGQaL4gINJ1zMyleDnbuS8UicjJijvqA 27 | 152Sq049ESDz+1rRGc2NVEqh1KaGXmtXvqxXcTB+Ljy5Bw2ke0v8iGngFBPqCTVB 28 | 3op5KBG3RjbF6RRSzwzuWfL7QErNC8WEy5yDVARzTA5+xmBc388v9Dm21HGfcC8O 29 | DD+gT9sSpssq0ascmvH49MOgjt1yoysLtdCtJW/9FZpoOypaHx0R+mJTLwPXVMrv 30 | DaVzWh5aiEx+idkSGMnX 31 | -----END CERTIFICATE----- 32 | -------------------------------------------------------------------------------- /platform_sgx/enclave/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 0 3 | 0 4 | 0x4000000 5 | 0x4000000 6 | 0x120000000 7 | 0x120000000 8 | 0x120000000 9 | 16 10 | 0 11 | 12 | 0 13 | 0 14 | 1 15 | 0x120000000 16 | 0x120000000 17 | 0x120000000 18 | 19 | 1 20 | 21 | -------------------------------------------------------------------------------- /platform_sgx/enclave/enclave.lds: -------------------------------------------------------------------------------- 1 | enclave.so 2 | { 3 | global: 4 | g_global_data_sim; 5 | g_global_data; 6 | enclave_entry; 7 | local: 8 | *; 9 | }; -------------------------------------------------------------------------------- /platform_sgx/enclave/private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIG4wIBAAKCAYEAuK60oq3HUQCaHDqiBIX+jfD2BRZuK/tfaZmfH0ZTnR1FT+6p 3 | bqfB0C/+nwANDGGItTMrmep8lFKmTLAWb/CsigdkjOMQNy93VvrI6GP3Nvo+TVRa 4 | hLWwSUy3dlYxf5+hkwI8Ebn2lQusi09nWqQjERPiMtt95GQ4+vA7mvCu6yO0rEo+ 5 | iiMqwwFsef6GejdwGG8lyBYE3DUPJ4Ym/sy3MYSpG9K8SPPVKBWZUx67c7yv1v64 6 | TQb3n3fNd5tHfW6TPzu59Ft3oo4kCSsGLsUDBpn907vCfBy+h/zJZ6ubencPiBum 7 | QvQH/JnFCrvYauQ4LnkFJltVMK/5AAMTKqpT7FNjJmvTFmdUd5XfwwN86fJSC+EO 8 | oI/p674Lsa8Jj4pxxqM30qxPj/+5/Y5pRjkGfHwmcpDvf92eWL5tSQY/SeiUGWbu 9 | GSi42AkER+gY5FpV7DBINpnJqIbvhyTGduvRLpnU+QqfvJ16WtSEMJg1Ke5b5B3I 10 | DaGAUDc3VCjOpU/FAgEDAoIBgHsfIxcehOCrEWgnFq2uqbP1+Vi5nsf86kZmahTZ 11 | jRNo2N/0cPRv1orKqb9VXghBBc4iHRFG/bg3GYh1ZEqgcwavmF3stXofpOSnMJrt 12 | T3n8KYji5wMjytuIek7kIP+/wQysKAvRTw4HyFzfmjxtbLYNQXc8/phC0KdK0mdL 13 | H0dtIx2G1FwXcddWSFFUWabPoBBKGTAOregjX2+uxKndz3ZYcL03KDCijhq5EOIU 14 | fPfTH+Sp0DNZ+mpP3k+82lOfC7HsqqLOz+y+MZ83HIBIqf5gMg/PoWssBtjRkTW/ 15 | i/Xlm3Dse/rVuZ3GztlEpO2ZfOPJHLvEdR4td8e82mfqyk5yqIHK5WTj5uO1L1lQ 16 | XzFs/LJ1QgBZ47hdVmhwEH5LHQVC+MC8a7sKeuoGECpRK1/tIfxE49Y0Mt4W6OE+ 17 | +CRJwNOz/OvLAYOLd2pvs2Ua/4SsQNWtqvQJnMyDZQc6elXKivyutw2twsNWeOEv 18 | ZwsmK6VHhvRnHmNYZChMk9whawKBwQDsFiCkdJL4BkXDO6oqAjcQ9dlqtZ6HKiUy 19 | aA4j/m0OM+JmL4me7fymXzxSlCqtWFEuqZHCODLZDD7tyzBDZoo2lI6QP9B/Xauz 20 | NinYF49M7L28VLSXmmvDaGr13bew/cUQbv3b9QWRi5yGnJrDfl++wlWGesTyD98f 21 | Kn9KYwse8JElK09EVjxwslj+6PMUoX1Gh/roIvrc/OEScDpp6oaMK7i+zzEqsgkt 22 | NEXbrlyqfB3a1DcPlMlCje7Xe+7UdU0CgcEAyEKZW7Csx2qT1xyxRFXM+BPZUU6x 23 | 1DCPEFphcw3ce2rD+Iliq8V06ZBSckC2WSWrqiHISnxyql+GZpybS2OaQBLX03uq 24 | f7PObs/u5PNe0uIZQ9x3CG6ok8mfHyk5IRwBLk/E1ZyoZeRlF+i2Q0DlrdYd8a7U 25 | zH9y7HGQrMS/9Ilhtq2jcyH6IgV4KVeYuBBZXqXsDfJOXXujQe90gimTIb5LvzVb 26 | /WbNCJ6JAyK97rj8kV5Gj3IJeKSyQDoCBqhZAoHBAJ1kFcL4Yfqu2SzScXFWz2Cj 27 | 5kcjvwTGw3bwCW1USLQilu7KW79JUxmU0uG4HHOQNh8btoF6zJCy1J6HdYJEXCRj 28 | CbV/4FTpHSIkG+VlCjNIfn2Nzbpm8oJFnKPpJSCpLgr0qT1OA7ZdEwRoZyz+6n8s 29 | OQRR2KFf6hTG/4bsshSgYMNyNNg5faB25f9F92MWU4Rap0Vspz3962GgJvFHBF1y 30 | eynfdhx2sMjNg+fJkxxSvpHiz1+4hixenzpSnzhOMwKBwQCFgbuSdciE8bfkvcuC 31 | 4936t+Y2NHaNdbS1kZZMs+hSRy1QW5cdLk3xCuGhgHmQw8fGwTAxqExxlQREaGeH 32 | l7wqtzqM/RxVIomfNUnt95SMlruCkvoFnxsNMRS/cNDAvVYe39iOaHBD7Zi6myQs 33 | 1e5z5BP2dI3dqkydoQsd2H/4W5Z5yReiFqbBWPrGOmXQCuY/GUgJTDQ+UmzWn6MB 34 | cQzBKYfUzj1Tmd4FvwYCFylJ0Khg6YRfoVulwyGAJqwEcDsCgcEA7A/yyLmQbWv7 35 | CavqrPVxzlSGPqp+iAaHc1RvDxN0hJk1of3JnWlClVw6HCWscMYDJdvaKnUCTalD 36 | zygVgH+pLKLxcmGidvzGsKQCIgLA71OVD6QJUPJlXN+MWSyylqvCc2w/3PBoQUHc 37 | 3WOWu3OEwWL4VJkbgx38o1ALKwtawSThOnTIxrJNNsLIIolNmQKtZzF0AjT0tCiQ 38 | nqaCg2ANl24A7BemGMKhgBjEcPyiNI6NL9vOaANvRU5KQnXudTIR 39 | -----END RSA PRIVATE KEY----- 40 | -------------------------------------------------------------------------------- /platform_sgx/enclave/src/bogus.rs: -------------------------------------------------------------------------------- 1 | #![forbid(unsafe_code)] 2 | 3 | use alloc::vec::Vec; 4 | use core::marker::PhantomData; 5 | use sgx_types::error::*; 6 | 7 | #[derive(Default)] 8 | pub struct SealedData { 9 | marker: PhantomData, 10 | } 11 | 12 | pub struct UnsealedData { 13 | marker: PhantomData, 14 | } 15 | 16 | #[allow(unused)] 17 | impl SealedData { 18 | pub fn seal(data: &T, aad: Option<&[u8]>) -> SgxResult> { 19 | unimplemented!() 20 | } 21 | 22 | pub fn payload_size(&self) -> u32 { 23 | unimplemented!() 24 | } 25 | 26 | pub fn to_bytes(&self) -> SgxResult> { 27 | unimplemented!() 28 | } 29 | 30 | pub fn from_slice(data: &[u8]) -> SgxResult> { 31 | unimplemented!() 32 | } 33 | 34 | pub fn unseal(self) -> SgxResult> { 35 | unimplemented!() 36 | } 37 | } 38 | 39 | impl UnsealedData { 40 | pub fn to_plaintext(&self) -> &T { 41 | unimplemented!() 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /platform_sgx/enclave/src/db_persistent.rs: -------------------------------------------------------------------------------- 1 | use core::time::Duration; 2 | 3 | use alloc::{string::String, vec, vec::Vec}; 4 | use db::db::{DbError, DbResult, Persistent}; 5 | use sgx_tseal::seal::*; 6 | use sgx_types::error::SgxStatus; 7 | 8 | use crate::{ 9 | log, 10 | networking_utils::unix_time, 11 | ocall::{ocall_get_file_size, ocall_read_data, ocall_write_data}, 12 | ocall_log, ocall_write_data_prologue, verified_log, 13 | }; 14 | 15 | const BATCH: u64 = 1 << 24; 16 | 17 | type SecretTaint = (); 18 | 19 | pub struct SgxPersistentLayer; 20 | 21 | impl Persistent for SgxPersistentLayer { 22 | fn write_disk(&self, path: &str, buf: &[u8]) -> DbResult<()> { 23 | verified_log!(SecretTaint, "[+] Writing {} bytes", buf.len()); 24 | let mut ret_val = SgxStatus::Success; 25 | unsafe { 26 | ocall_write_data_prologue(&mut ret_val, path.as_ptr(), path.len() as _); 27 | } 28 | 29 | // Seal the data using the platform key. 30 | let begin = unix_time(3).map_err(|_| DbError::Unknown)?; 31 | let buf = SealedData::<[u8]>::seal(buf, None) 32 | .map_err(|_| DbError::Unknown)? 33 | .into_bytes() 34 | .map_err(|_| DbError::Unknown)?; 35 | let file_size = buf.len() as u64; 36 | 37 | let batch_num = if file_size % BATCH != 0 { 38 | file_size / BATCH + 1 39 | } else { 40 | file_size / BATCH 41 | }; 42 | 43 | for i in 0..batch_num { 44 | let mut write_size = BATCH.min(file_size as u64 - i * BATCH); 45 | 46 | let mut ret_val = SgxStatus::Success; 47 | let res = unsafe { 48 | ocall_write_data( 49 | &mut ret_val, 50 | path.as_ptr(), 51 | path.len() as _, 52 | buf.as_ptr().add((i * BATCH) as usize), 53 | write_size as _, 54 | ) 55 | }; 56 | 57 | if res != SgxStatus::Success { 58 | return Err(DbError::Unknown); 59 | } 60 | } 61 | let end = unix_time(3).map_err(|_| DbError::Unknown)?; 62 | 63 | let elapsed = Duration::from_nanos(end - begin); 64 | let throughput = (buf.len() as f64 / elapsed.as_secs_f64()) / 1000000.0; 65 | verified_log!( 66 | SecretTaint, 67 | "[+] Time elapsed: {:?}; throughput: {} MB/s", 68 | elapsed, 69 | throughput, 70 | ); 71 | 72 | Ok(()) 73 | } 74 | 75 | fn read_disk(&self, path: &str) -> DbResult> { 76 | // Get the file size of the database snapshot. 77 | let mut file_size = 0u64; 78 | let mut ret_val = SgxStatus::Success; 79 | let res = unsafe { 80 | ocall_get_file_size(&mut ret_val, path.as_ptr(), path.len() as _, &mut file_size) 81 | }; 82 | if res != SgxStatus::Success { 83 | return Err(DbError::PathNotFound(path.into())); 84 | } 85 | 86 | verified_log!(SecretTaint, "[+] Reading {} bytes", file_size); 87 | 88 | let batch_num = if file_size % BATCH != 0 { 89 | file_size / BATCH + 1 90 | } else { 91 | file_size / BATCH 92 | }; 93 | 94 | let mut content = vec![0u8; file_size as usize]; 95 | let begin = unix_time(3).map_err(|_| DbError::Unknown)?; 96 | for i in 0..batch_num { 97 | let mut read_size = BATCH.min(content.len() as u64 - i * BATCH); 98 | 99 | let res = unsafe { 100 | ocall_read_data( 101 | &mut ret_val, 102 | path.as_ptr(), 103 | path.len() as _, 104 | (i * BATCH) as u64, 105 | content.as_mut_ptr().add((i * BATCH) as usize), 106 | read_size as _, 107 | &mut (read_size as _), 108 | ) 109 | }; 110 | 111 | if res != SgxStatus::Success { 112 | return Err(DbError::Unknown); 113 | } 114 | } 115 | 116 | // Unseal the data. 117 | let content = UnsealedData::<[u8]>::unseal_from_bytes(content) 118 | .map_err(|e| { 119 | verified_log!(SecretTaint, "{}", e); 120 | DbError::SerializeError 121 | })? 122 | .into_plaintext() 123 | .to_vec(); 124 | let end = unix_time(3).map_err(|_| DbError::Unknown)?; 125 | 126 | let elapsed = Duration::from_nanos(end - begin); 127 | let throughput = (file_size as f64 / elapsed.as_secs_f64()) / 1000000.0; 128 | verified_log!( 129 | SecretTaint, 130 | "[+] Time elapsed: {:?}; throughput: {} MB/s", 131 | elapsed, 132 | throughput, 133 | ); 134 | 135 | Ok(content) 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /platform_sgx/enclave/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused)] 2 | #![crate_name = "pobfref"] 3 | #![crate_type = "staticlib"] 4 | #![cfg_attr(feature = "sgx", no_std)] 5 | #![feature(vec_into_raw_parts)] 6 | #![feature(allocator_api)] 7 | 8 | extern crate alloc; 9 | extern crate base64; 10 | extern crate clear_on_drop; 11 | extern crate mirai_annotations; 12 | extern crate percent_encoding; 13 | #[cfg(all(feature = "sgx", not(mirai)))] 14 | extern crate sgx_no_tstd; 15 | extern crate sgx_trts; 16 | extern crate sgx_tse; 17 | extern crate sgx_tseal; 18 | extern crate sgx_types; 19 | extern crate webpki; 20 | 21 | #[cfg(not(feature = "sgx"))] 22 | mod bogus; 23 | mod dh; 24 | #[cfg(mirai)] 25 | mod mirai_types; 26 | mod networking_utils; 27 | mod ocall; 28 | mod pobf; 29 | mod pobf_verifier; 30 | mod userfunc; 31 | mod utils; 32 | mod vecaes; 33 | 34 | #[cfg(feature = "task_db")] 35 | mod db_persistent; 36 | 37 | use alloc::slice; 38 | use clear_on_drop::*; 39 | use ocall::*; 40 | use pobf::*; 41 | use zeroize::*; 42 | 43 | use sgx_types::{error::SgxStatus, types::*}; 44 | 45 | use crate::dh::*; 46 | 47 | static DEFAULT_PAGE_SIZE_LEAF: usize = 0x20; 48 | 49 | #[no_mangle] 50 | pub extern "C" fn private_computing_entry( 51 | socket_fd: c_int, 52 | spid_ptr: *const Spid, 53 | linkable: i64, 54 | ra_type: u8, 55 | public_key_ptr: *const u8, 56 | public_key_len: u32, 57 | signature_ptr: *const u8, 58 | signature_len: u32, 59 | encrypted_output_buffer_ptr: *mut u8, 60 | encrypted_output_buffer_size: u32, 61 | encrypted_output_size: *mut u32, 62 | stack: u16, 63 | ) -> SgxStatus { 64 | #[cfg(feature = "task_db")] 65 | db::DUMPER.call_once(|| alloc::boxed::Box::new(crate::db_persistent::SgxPersistentLayer)); 66 | 67 | verified_log!("[+] private_computing_entry"); 68 | cfg_if::cfg_if! { 69 | if #[cfg(feature = "native_enclave")] { 70 | verified_log!("[+] Running ephemeral enclave!"); 71 | } else { 72 | verified_log!("[+] Running persistent PoBF enclave!"); 73 | } 74 | } 75 | 76 | // Construct Rust data structures from FFI-types. 77 | let spid = unsafe { &*spid_ptr }; 78 | let public_key: &[u8; ECP_COORDINATE_SIZE] = 79 | unsafe { slice::from_raw_parts(public_key_ptr, public_key_len as usize) } 80 | .try_into() 81 | .unwrap(); 82 | let signature = unsafe { slice::from_raw_parts(signature_ptr, signature_len as usize) }; 83 | 84 | let mut result = pobf_workflow( 85 | socket_fd, spid, linkable, ra_type, public_key, signature, stack, 86 | ); 87 | 88 | let output_size = result.as_ref().len() as u32; 89 | let rv = if output_size <= encrypted_output_buffer_size { 90 | // Copy the result back to the outside world. 91 | unsafe { 92 | core::ptr::copy( 93 | result.as_ref().as_ptr(), 94 | encrypted_output_buffer_ptr, 95 | result.as_ref().len(), 96 | ); 97 | 98 | *encrypted_output_size = output_size; 99 | } 100 | SgxStatus::Success 101 | } else { 102 | SgxStatus::InvalidParameter 103 | }; 104 | 105 | // Clear result. 106 | result.zeroize(); 107 | rv 108 | } 109 | 110 | /// To be deprecated. 111 | #[allow(unused)] 112 | #[no_mangle] 113 | #[deprecated] 114 | pub extern "C" fn start_remote_attestation( 115 | socket_fd: c_int, 116 | spid: *const Spid, 117 | linkable: i64, 118 | public_key: *const u8, 119 | public_key_len: u32, 120 | pubkey_signature: *const u8, 121 | pubkey_signature_len: u32, 122 | ) -> SgxStatus { 123 | // Convert FFI-types to Rust-types. 124 | let r_spid = unsafe { &*spid }; 125 | let r_public_key: &[u8; ECP_COORDINATE_SIZE] = 126 | unsafe { core::slice::from_raw_parts(public_key, public_key_len as usize) } 127 | .try_into() 128 | .unwrap(); 129 | let r_signature = 130 | unsafe { core::slice::from_raw_parts(pubkey_signature, pubkey_signature_len as usize) }; 131 | 132 | let _ = pobf_remote_attestation(socket_fd, r_spid, linkable, 0, r_public_key, r_signature); 133 | 134 | SgxStatus::Success 135 | } 136 | 137 | /// Built with debug mode. 138 | #[cfg(debug_assertions)] 139 | #[no_mangle] 140 | pub fn __assert_fail() {} 141 | -------------------------------------------------------------------------------- /platform_sgx/enclave/src/mirai_types/mirai_comp.rs: -------------------------------------------------------------------------------- 1 | #![forbid(unsafe_code)] 2 | 3 | #[cfg(mirai)] 4 | use mirai_annotations::TagPropagationSet; 5 | #[cfg(mirai)] 6 | pub struct SecretTaintKind {} 7 | #[cfg(mirai)] 8 | const SECRET_TAINT: TagPropagationSet = mirai_annotations::TAG_PROPAGATION_ALL; 9 | #[cfg(mirai)] 10 | pub type SecretTaint = SecretTaintKind; 11 | /// Ensures non-MIRAI code compiles. 12 | #[cfg(not(mirai))] 13 | pub type SecretTaint = (); 14 | -------------------------------------------------------------------------------- /platform_sgx/enclave/src/mirai_types/mod.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(feature = "sgx", no_std)] 2 | #![forbid(unsafe_code)] 3 | 4 | use zeroize::Zeroize; 5 | 6 | pub mod mirai_comp; 7 | pub mod task; 8 | 9 | #[cfg(feature = "sgx")] 10 | use sgx_types::error::SgxResult as Result; 11 | #[cfg(not(feature = "sgx"))] 12 | type Result = core::result::Result; 13 | 14 | pub trait Decryption 15 | where 16 | Self: Sized + Zeroize, 17 | { 18 | fn decrypt(self, key: &K) -> Result; 19 | } 20 | 21 | #[allow(private_in_public)] 22 | pub trait Encryption 23 | where 24 | Self: Sized + Zeroize, 25 | { 26 | fn encrypt(self, key: &K) -> Result; 27 | } 28 | 29 | pub trait EncDec 30 | where 31 | Self: Sized + Decryption + Encryption, 32 | { 33 | } 34 | -------------------------------------------------------------------------------- /platform_sgx/enclave/src/pobf_verifier.rs: -------------------------------------------------------------------------------- 1 | #![forbid(unsafe_code)] 2 | 3 | pub use crate::ocall::*; 4 | pub use crate::ocall_log; 5 | #[cfg(not(mirai))] 6 | #[cfg(feature = "sgx")] 7 | pub use crate::println; 8 | -------------------------------------------------------------------------------- /platform_sgx/enclave/src/userfunc.rs: -------------------------------------------------------------------------------- 1 | #![forbid(unsafe_code)] 2 | 3 | use alloc::vec::Vec; 4 | #[cfg(mirai)] 5 | use mirai_annotations::*; 6 | 7 | #[cfg(mirai)] 8 | use crate::mirai_types::mirai_comp::SecretTaint; 9 | use crate::{log, ocall_log, verified_log}; 10 | 11 | /// A sample function used to serve as the target task for MIRAI. 12 | /// In order to verify that user function is correct, we need to temporarily move it to 13 | /// the enclave crate. 14 | pub fn sample_add(input: Vec) -> Vec { 15 | let step = 1; 16 | 17 | // this can be proven true by MIRAI 18 | #[cfg(feature = "leak_log")] 19 | { 20 | // Try remove this println!. 21 | verified_log!(SecretTaint, "The 0-th item is {} in sample_add", input[0]); 22 | } 23 | 24 | let mut output = Vec::new(); 25 | for i in 0..input.len() { 26 | output.push(step + input[i]); 27 | } 28 | 29 | #[cfg(mirai)] 30 | add_tag!(&output, SecretTaint); 31 | 32 | output 33 | } 34 | -------------------------------------------------------------------------------- /platform_sgx/enclave/src/utils.rs: -------------------------------------------------------------------------------- 1 | #![forbid(unsafe_code)] 2 | 3 | #[cfg(not(feature = "sgx"))] 4 | use crate::bogus::SealedData; 5 | use crate::ocall::*; 6 | use alloc::string::String; 7 | use alloc::vec::Vec; 8 | #[cfg(feature = "sgx")] 9 | use sgx_tseal::seal::SealedData; 10 | use sgx_types::marker::ContiguousMemory; 11 | 12 | pub fn from_sealed_log_for_fixed<'a, T: Copy + ContiguousMemory>( 13 | sealed_log: &Vec, 14 | ) -> Option> { 15 | let r = SealedData::::from_slice(&sealed_log); 16 | 17 | match r { 18 | Ok(x) => Some(x), 19 | Err(e) => None, 20 | } 21 | } 22 | 23 | /// Special characters are http-encoded, we want to remove these base64-unrecognizable tokens. 24 | /// Also, we do not need the CA cert here. 25 | pub fn process_raw_cert(cert_raw: &Vec) -> String { 26 | let cert_removed = alloc::str::from_utf8(cert_raw).unwrap().replace("%0A", ""); 27 | // Decode %. 28 | let cert = String::from( 29 | percent_encoding::percent_decode_str(&cert_removed) 30 | .decode_utf8() 31 | .unwrap(), 32 | ); 33 | 34 | let v: Vec<&str> = cert.split("-----").collect(); 35 | 36 | String::from(v[2]) 37 | } 38 | -------------------------------------------------------------------------------- /pobf_crypto/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pobf_crypto" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | aes = "0.8.2" 10 | aes-gcm = "0.10.1" 11 | cmac = "0.7.2" 12 | log = "0.4.17" 13 | pem = "2.0.1" 14 | ring = "0.16.20" 15 | 16 | [features] 17 | default = ["sgx"] 18 | sgx = [] 19 | sev = [] 20 | -------------------------------------------------------------------------------- /pobf_keychain/cert.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ya0guang/PoBF/8bc1a900fdae506d0a113250b94f594ae70f2762/pobf_keychain/cert.der -------------------------------------------------------------------------------- /pobf_keychain/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICbzCCAhWgAwIBAgIUYoPMHkOlEJHtlnvTIKDV/Ladp5gwCgYIKoZIzj0EAwIw 3 | gYwxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdJbmRpYW5hMRQwEgYDVQQHDAtCbG9v 4 | bWluZ3RvbjEbMBkGA1UECgwSSW5kaWFuYSBVbml2ZXJzaXR5MSQwIgYDVQQLDBtM 5 | dWRkeSBTY2hvb2wgb2YgSW5mb3JtYXRpY3MxEjAQBgNVBAMMCTEyNy4wLjAuMTAe 6 | Fw0yMjEwMjEwMjUyMTNaFw0zMjEwMTgwMjUyMTNaMIGMMQswCQYDVQQGEwJVUzEQ 7 | MA4GA1UECAwHSW5kaWFuYTEUMBIGA1UEBwwLQmxvb21pbmd0b24xGzAZBgNVBAoM 8 | EkluZGlhbmEgVW5pdmVyc2l0eTEkMCIGA1UECwwbTHVkZHkgU2Nob29sIG9mIElu 9 | Zm9ybWF0aWNzMRIwEAYDVQQDDAkxMjcuMC4wLjEwWTATBgcqhkjOPQIBBggqhkjO 10 | PQMBBwNCAAQgaU4UnfRFlhxKBDT1AqWENEFR4AV6WpzZ7L6lV7tGTxdcxi1PNNXe 11 | 8hQXG6cj8gcCyYhy4DrgvduaWeqTnqZeo1MwUTAdBgNVHQ4EFgQUdF6of7qm511v 12 | tvMfbMWOe1jv7QEwHwYDVR0jBBgwFoAUdF6of7qm511vtvMfbMWOe1jv7QEwDwYD 13 | VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiA+zu0DCqma/pnpgEhx+oAy 14 | yGOxdFLHoZoAyN4ec4W+awIhAJfzb181oFh3G3qQT//VMv3AxwIU5hy0rmoNb9LS 15 | 5jem 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /pobf_keychain/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgIWjy1dK84h5JoD8D 3 | X52DK13BlOe8YJCzAckdUzzOss+hRANCAAQgaU4UnfRFlhxKBDT1AqWENEFR4AV6 4 | WpzZ7L6lV7tGTxdcxi1PNNXe8hQXG6cj8gcCyYhy4DrgvduaWeqTnqZe 5 | -----END PRIVATE KEY----- -------------------------------------------------------------------------------- /pobf_proof/README.md: -------------------------------------------------------------------------------- 1 | # Proof of PoBF Security Constraints 2 | 3 | The model is built on the **language** level, rather than on the **machine** level. 4 | Therefore the model is mahcine-independent, but mimics the behaviors of common imperative languages because of Turing Completeness. 5 | 6 | ## Concerns 7 | 8 | - May the model be too general? i.e., not modeling specific enclaves 9 | 10 | ## Simplified Model 11 | 12 | ### Capabilities of the Abstract Model 13 | 14 | - Execution mode : enclave/normal 15 | - Memory isolation: enclave and normal memory 16 | - *Multi-threading* 17 | 18 | ### Memory Model (Enclave Model) 19 | 20 | - Mode := `NormalMode` | `EnclaveMode` 21 | - Value := `ConcretN(v: nat)` | `ConcretB (v: bool)` | `Any` | `Cleared` 22 | - Location := `Stack(n: nat)` | `Ident(s: string)` | `RV` 23 | - SecurityTag := `Secret` | `NotSecret` | `NonSense` 24 | - EnclaveTag := `ZoneMem` | `NonZoneMem` 25 | - TagValue := `Value * SecurityTag` 26 | - Cell := `AppMem(v: TagValue)` | `DummyMem` | `UnusedMem` | `EncMem(z: EnclaveTag, v: TagValue)` 27 | - Memory: functional list `Location -> Cell` 28 | 29 | The registers can be represented by location for Ident(s), e.g., Ident("rax"). 30 | 31 | ### Enclave Program Model 32 | 33 | - Exp := `ExpLoc(l: Location)` | `ExpVal(v: Value)` | `ExpUnary(e: Exp)` | `ExpBinary(E1 E2: Exp)` 34 | - Com := `Nop` | `Eenter` | `Eexit` | `Asgn(l: Location, v: Exp)` | `Seq(c1 c2: Com)` | `If(b: Exp, c1 c2: Com)` | `While(b: Exp, c: Com)` 35 | - Procedure := `Com` 36 | - Accessible := `listof(Location)` 37 | - State := `Mode * Memory * Accessible` 38 | 39 | Branch, loop, and assignment are modeled, as well as the TEE context switches. 40 | Semantics are modeled as relationships. 41 | 42 | ### Definitions 43 | 44 | - Leak: secrets find on places other than the zone (i.e., secrets cannot stay on AppMem or nonzone EncMem) 45 | - Residue: secret found in memory (other than RV). 46 | - Critical: accessible vars contain secrets in the zone 47 | 48 | ### Security Constraints 49 | 50 | #### For Leakage (proved) 51 | 52 | For any critical procedure $p$ and initial state $st=(me, mo, vars, errs)$,, the execution of $p$ does not leak secret if: 53 | 1. the initial state $st$ does not leak secret 54 | 2. all memory writes (i.e., `Asgn`) in $p$ are within Zone if the value 55 | is Secret 56 | 3. execution of $p$ aborts when error occurs 57 | 58 | #### For Residue (proved) 59 | 60 | `zeroize` is a procedure taking memory $me$ and accessible variables $vars$, 61 | for every location $l \in vars$ where $c=me(l)$ is in Zone of the enclave, 62 | the tagged value $v$ stored in the cell $c$ is cleared and the security tag is set to `NotSecret`. 63 | 64 | For any critical procedure $p$, if it satisfies No-Leakage 65 | requirement, the procedure $p'$ concatenating $p$ and `Zeroize` ($p'=p;\;zerorize$) satisfies No-Residue requirement. 66 | 67 | #### Multi-threading (stuck) 68 | 69 | If thread-specific Zone can only be accessible to the corresponding thread (i.e., dedicated Zone for each thread), then it satisfies No-Leakage and No-Residue. 70 | 71 | ## Usage 72 | 73 | First, make sure that Coq is correctly installed. 74 | Then run `coq_makefile -f _CoqProject -o Makefile` to generate a makefile. 75 | Last, run `make` to compile the proof. 76 | -------------------------------------------------------------------------------- /pobf_proof/_CoqProject: -------------------------------------------------------------------------------- 1 | -R . POBF 2 | model.v -------------------------------------------------------------------------------- /pobf_state/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pobf_state" 3 | version = "0.1.0" 4 | edition = "2021" 5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6 | 7 | [features] 8 | sgx = ["sgx_types"] 9 | prusti = [] 10 | time_breakdown = ["lazy_static", "spin", "tsc-timer"] 11 | 12 | [dependencies] 13 | lazy_static = { version = "1.4.0", optional = true, features = ["spin_no_std"] } 14 | prusti-contracts = { git = "https://github.com/viperproject/prusti-dev.git", rev = "734426e" } 15 | sgx_types = { git = "https://github.com/apache/incubator-teaclave-sgx-sdk.git", branch = "v2.0.0-preview", package = "sgx_types", optional = true } 16 | spin = { version = "0.9.8", optional = true, default-features = false, features = [ 17 | "rwlock", 18 | ] } 19 | tsc-timer = { git = "https://github.com/hiroki-chen/tsc.git", optional = true } 20 | zeroize = "1.5.7" 21 | -------------------------------------------------------------------------------- /pobf_state/Prusti.toml: -------------------------------------------------------------------------------- 1 | # Configuration file for Prusti runtime. 2 | # A Prusti.toml is optionally loaded from the current working directory prior to compilation. 3 | # This file is used to configure flags in Category B only and these flags apply to the entire 4 | # compilation. 5 | # Then, as each individual crate is checked (from the roots of the dependency tree) a Prusti.toml 6 | # is optionally loaded from the directory where the crate's corresponding Cargo.toml is located. 7 | # This file is used to configure flags in Category A only — it would not make sense to set e.g. 8 | # NO_VERIFY_DEPS in a dependency since all of its dependencies have already been verified. 9 | # 10 | # Created by Haobin Chen and Hongbo Chen 11 | # Prusti will load the keys from a cold start and will then cache it to ./target/verify/cache.bin. 12 | # You may need to clean the cache before the configuration takes effect. 13 | check_overflows = true 14 | check_panics = true 15 | no_verify_deps = true 16 | log = "error" 17 | log_dir = "./log" 18 | hide_uuids = true 19 | assert_timeout = 10000 20 | optimizations = "inline_constant_functions,delete_unused_predicates,optimize_folding,remove_empty_if,purify_vars,remove_unused_vars,remove_trivial_assertions,clean_cfg" 21 | 22 | # Run: PRUSTI_LOG=info ~/prusti-dev/target/release/cargo-prusti --features=sgx,prusti 23 | -------------------------------------------------------------------------------- /pobf_state/src/bogus.rs: -------------------------------------------------------------------------------- 1 | use crate::*; 2 | use alloc::vec; 3 | use alloc::vec::*; 4 | use prusti_contracts::*; 5 | use zeroize::*; 6 | 7 | pub struct VecAESData { 8 | inner: Vec, 9 | } 10 | 11 | impl Zeroize for VecAESData { 12 | #[trusted] 13 | fn zeroize(&mut self) { 14 | self.inner.zeroize(); 15 | } 16 | } 17 | 18 | impl From> for VecAESData { 19 | #[trusted] 20 | fn from(v: Vec) -> Self { 21 | VecAESData { inner: v } 22 | } 23 | } 24 | 25 | impl From<&[u8]> for VecAESData { 26 | #[trusted] 27 | fn from(raw: &[u8]) -> Self { 28 | let mut inner = Vec::new(); 29 | inner.extend_from_slice(raw); 30 | VecAESData { inner } 31 | } 32 | } 33 | 34 | impl Into> for VecAESData { 35 | #[trusted] 36 | fn into(self) -> Vec { 37 | self.inner 38 | } 39 | } 40 | 41 | impl AsRef<[u8]> for VecAESData { 42 | #[trusted] 43 | fn as_ref(&self) -> &[u8] { 44 | &self.inner[..] 45 | } 46 | } 47 | 48 | pub struct AES128Key { 49 | buffer: Vec, 50 | inner: [u8; 16], 51 | } 52 | 53 | impl Default for AES128Key { 54 | #[trusted] 55 | fn default() -> Self { 56 | AES128Key { 57 | buffer: vec![], 58 | inner: [0u8; 16], 59 | } 60 | } 61 | } 62 | 63 | impl Zeroize for AES128Key { 64 | #[trusted] 65 | fn zeroize(&mut self) { 66 | self.inner.zeroize(); 67 | self.buffer.zeroize(); 68 | } 69 | } 70 | 71 | impl AES128Key {} 72 | 73 | #[refine_trait_spec] 74 | impl Encryption for VecAESData { 75 | #[ensures((&result).is_ok())] 76 | fn encrypt(self, _key: &AES128Key) -> Result { 77 | Ok(self) 78 | } 79 | } 80 | 81 | #[refine_trait_spec] 82 | impl Decryption for VecAESData { 83 | #[ensures((&result).is_ok())] 84 | fn decrypt(self, _key: &AES128Key) -> Result { 85 | Ok(self) 86 | } 87 | } 88 | 89 | impl EncDec for VecAESData {} 90 | 91 | /// A sample workflow for Prusti verification. All types are implemented in bogus types as Prusti cannot fully support all the features of Rust. 92 | /// So we need this to circumvent the difficulties. 93 | /// Prusti will try to verify if each step of the type state can be transitted into another, and 94 | /// since we care about the correctness of type state transition, we "trust" all the internal 95 | /// implementations of utility functions such as cryptographic algorithms. 96 | #[cfg(feature = "prusti")] 97 | #[allow(unused)] 98 | pub fn pobf_workflow_verify() -> VecAESData { 99 | use task::*; 100 | 101 | let template = ComputingTaskTemplate::::new(); 102 | 103 | let session: ComputingTaskSession = 104 | ComputingTaskSession::establish_channel(template); 105 | 106 | let task_data_received = ComputingTask::receive_data(session); 107 | 108 | let task_result_encrypted = task_data_received.compute(); 109 | 110 | task_result_encrypted.take_result() 111 | } 112 | -------------------------------------------------------------------------------- /pobf_state/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(incomplete_features)] 2 | #![allow(private_in_public)] 3 | #![cfg_attr(feature = "sgx", no_std)] 4 | #![feature(unsized_locals, unsized_fn_params)] 5 | #![feature(error_in_core)] 6 | #![forbid(unsafe_code)] 7 | 8 | extern crate alloc; 9 | extern crate prusti_contracts; 10 | 11 | pub mod task; 12 | 13 | #[cfg(feature = "prusti")] 14 | mod bogus; 15 | 16 | use prusti_contracts::*; 17 | use zeroize::Zeroize; 18 | 19 | #[cfg(feature = "sgx")] 20 | use sgx_types::error::SgxResult as Result; 21 | #[cfg(not(feature = "sgx"))] 22 | pub type Result = core::result::Result; 23 | 24 | pub trait Decryption 25 | where 26 | Self: Sized + Zeroize, 27 | { 28 | /// Prusti cannot verify cryptography library code, so we mark them as trusted here. 29 | #[trusted] 30 | #[ensures(result.is_ok())] 31 | fn decrypt(self, key: &K) -> Result; 32 | } 33 | 34 | #[allow(private_in_public)] 35 | pub trait Encryption 36 | where 37 | Self: Sized + Zeroize, 38 | { 39 | /// Prusti cannot verify cryptography library code, so we mark them as trusted here. 40 | #[trusted] 41 | #[ensures(result.is_ok())] 42 | fn encrypt(self, key: &K) -> Result; 43 | } 44 | 45 | pub trait EncDec 46 | where 47 | Self: Sized + Decryption + Encryption, 48 | { 49 | } 50 | 51 | /// Gets the detailed time latency of each step in our PoBF workflow. The caller must specify the CPU frequency to 52 | /// an accurate measurement of the latency. Note that the unit is MHz (tick per microsecond), and the result is thus 53 | /// in **microsecond**! 54 | #[cfg(feature = "time_breakdown")] 55 | pub fn get_time_summary(cpu_frequency: f64) -> alloc::string::String { 56 | use crate::task::TIME_SUMMARY; 57 | 58 | let mut lock = TIME_SUMMARY.write(); 59 | lock.values_mut().for_each(|tick| *tick /= cpu_frequency); 60 | 61 | alloc::format!("{:?}", lock) 62 | } 63 | -------------------------------------------------------------------------------- /pobf_thread_pool/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pobf_thread_pool" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | log = "0.4.17" 10 | -------------------------------------------------------------------------------- /pobf_thread_pool/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | fmt::Debug, 3 | io::{Error, ErrorKind, Result}, 4 | sync::{ 5 | mpsc::{channel, Receiver, Sender}, 6 | Arc, Mutex, 7 | }, 8 | thread::{Builder, JoinHandle}, 9 | }; 10 | 11 | use log::info; 12 | 13 | pub type Job = Box; 14 | 15 | pub const TCS_NUM: usize = 10; 16 | pub const THREAD_STACK_SIZE: usize = 0x8000000; 17 | 18 | pub struct ThreadPool { 19 | workers: Vec, 20 | sender: Option>, 21 | } 22 | 23 | impl Drop for ThreadPool { 24 | fn drop(&mut self) { 25 | drop(self.sender.take()); 26 | 27 | self.workers.iter_mut().for_each(|worker| { 28 | info!("[+] Shutting down worker {worker:?}"); 29 | 30 | if let Some(thread) = worker.thread.take() { 31 | thread.join().unwrap(); 32 | } 33 | }); 34 | } 35 | } 36 | 37 | impl ThreadPool { 38 | pub fn new(size: usize) -> ThreadPool { 39 | assert!(size > 0); 40 | let (sender, receiver) = channel(); 41 | 42 | let receiver = Arc::new(Mutex::new(receiver)); 43 | 44 | let mut workers = Vec::with_capacity(size); 45 | 46 | (0..size).for_each(|id| { 47 | workers.push(Worker::new(id, Arc::clone(&receiver))); 48 | }); 49 | 50 | ThreadPool { 51 | workers, 52 | sender: Some(sender), 53 | } 54 | } 55 | 56 | pub fn execute(&self, f: F) -> Result<()> 57 | where 58 | F: FnOnce() + Send + Sync + 'static, 59 | { 60 | let job = Box::new(f); 61 | 62 | self.sender 63 | .as_ref() 64 | .unwrap() 65 | .send(job) 66 | .or_else(|_| Err(Error::from(ErrorKind::Other))) 67 | } 68 | } 69 | 70 | pub struct Worker { 71 | id: usize, 72 | thread: Option>, 73 | } 74 | 75 | impl Worker { 76 | pub fn new(id: usize, receiver: Arc>>) -> Self { 77 | let builder = Builder::new() 78 | .name(format!("worker-{id}")) 79 | .stack_size(THREAD_STACK_SIZE); 80 | 81 | let thread = builder 82 | .spawn(move || loop { 83 | let message = receiver.lock().unwrap().recv(); 84 | 85 | match message { 86 | Ok(job) => { 87 | println!("Worker {id} got a job; executing."); 88 | 89 | job(); 90 | } 91 | Err(_) => { 92 | println!("Worker {id} disconnected; shutting down."); 93 | break; 94 | } 95 | } 96 | }) 97 | .unwrap(); 98 | 99 | Worker { 100 | id, 101 | thread: Some(thread), 102 | } 103 | } 104 | } 105 | 106 | impl Debug for Worker { 107 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 108 | write!(f, "{}", self.id) 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /pobf_verifier/cargo-pobf-verify: -------------------------------------------------------------------------------- 1 | pobf-verify -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Do not install numpy >= 1.23.1 because np.bool will be missing. 2 | numpy==1.23.1 3 | pandas==2.0.2 4 | coloredlogs==15.0.1 5 | matplotlib==3.7.1 6 | seaborn==0.12.2 7 | apache-tvm==0.11.1 8 | mxnet==1.9.1 9 | -------------------------------------------------------------------------------- /rust-toolchain: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly-2022-11-01" 3 | components = ["rust-src", "rustc-dev", "llvm-tools-preview", "rustfmt", "rust-analysis"] 4 | -------------------------------------------------------------------------------- /scripts/README.md: -------------------------------------------------------------------------------- 1 | # Utility Scripts for Evaluation 2 | 3 | This folder contains some scripts for reproducing the evaluation results and some utility scripts. 4 | 5 | * `build.sh`: building the Occlum Rust target (`musl`). 6 | * `clean_data.sh`: clean the evaluation data and intermediate files. 7 | * `plt_cost_breakup.ipynb`: plot the result of the cost breakup. 8 | * `plt_db.ipynb`: plot the figure for YCSB KVDB result. 9 | * `plt_main.ipynb`: plot the figures for polybench, tvm, fasta tasks. 10 | * `plt_stack.ipynb`: plot the figure for stack page number. 11 | * `demo-verify.sh`: run the PoBF verifier on a demo CC task. 12 | * `evaluation.sh`: run the evaluation tasks for polybench, TVM, FASTA and identity task. 13 | * `multi_threading.sh`: run the evaluation tasks in multi-threaded mode. This script is not intended for separate use. 14 | * `prepare_prusti.sh`: Install the Prusti toolchain. 15 | * `prepare_mirai.sh`: Install the MIRAI abstract interpreter. 16 | 17 | ## How to reproduce evaluation results? 18 | 19 | ### Microbenchmarks 20 | 21 | * Cost breakup: Follow these steps: 22 | 23 | ```sh 24 | # OR sev 25 | cd platform_sgx && SGX_MODE=HW TASK=task_none make -j 26 | cd bin && ./app 127.0.0.1 1234 >> output.txt & 27 | 28 | # Then run the data provider. 29 | cd ../../data_provider && make -j 30 | # Note that manifest.json's data path should contain the input dummy data which can be generated using scripts/data_generator 31 | cd bin && ./data_provider run ../manifest.json 32 | 33 | # Then you modify manifest.json to set the data path to another one until all input data is used. 34 | ``` 35 | 36 | The input data can be generated by 37 | 38 | ```sh 39 | $ cd scripts/data_generator 40 | $ cargo r -r -- --help 41 | Usage: data_generator [OPTIONS] 42 | 43 | Options: 44 | -l, --len Data sizes you want to run [default: 1000] 45 | -o, --output-path The output path [default: output.bin] 46 | -h, --help Print help 47 | -V, --version Print version 48 | ``` 49 | 50 | Open `plt_cost_breakup.ipynb` and change the output file path (`output.txt`). Then you should see the result. You will see something like 51 | 52 | ```txt 53 | [2023-06-12T12:17:32Z INFO app::ocall] [+] Enclave: Job finished. Time used: 28.058968731s; breakup {"decrypt_data": 74482.66857142857, "do_compute": 0.319047619047619, "encrypt_result": 98212.00952380952, "establish_channel": 121811.60666666667, "receive_data": 27763494.36095238} 54 | ``` 55 | 56 | in the output. 57 | 58 | * Evaluate the effect of zeroization using different page numbers. 59 | 60 | ```sh 61 | # Rebuild the enclave. 62 | SGX_MODE=HW TASK=task_none,native_zeroize make -j 63 | cd bin && ./app 127.0.0.1 1234 [set this to page number] & 64 | 65 | # Run the data provider. 66 | cd ../../data_provider/bin 67 | ./data_provider run ./manifest.json 68 | ``` 69 | 70 | Then you should get the service time. Run 10 times and get the average value. Manually feed these data to `plt_stack.ipynb` and you will get the visualized result. 71 | 72 | We apologize that there is no convenient way to automate this process. 73 | 74 | * Evaluate the polybench. 75 | 76 | First modify `./evaluations.sh`: 77 | 78 | ```sh 79 | # Make sure tasks only contain polybench. 80 | declare -a tasks=("task_polybench") 81 | ``` 82 | 83 | ```sh 84 | # There is no multi-threading for this task. So th thread num is simply set to 1. 85 | cd scripts && ./evaluation.sh 1 pobf # or sev 86 | ``` 87 | 88 | It takes some time to build enclaves. Please be patient while the script is building and running the enclave. 89 | -------------------------------------------------------------------------------- /scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 3 | INSTALL_DIR=/opt/occlum/toolchains/rust 4 | 5 | mkdir -p ${INSTALL_DIR}/bin 6 | 7 | rustup target add x86_64-unknown-linux-musl 8 | 9 | # Generate the wrapper for Cargo 10 | # Use -crt-static to dynamically link the application to musl libc library. 11 | # Refer to https://github.com/rust-lang/rfcs/blob/master/text/1721-crt-static.md 12 | # for more information about crt-static 13 | cat > ${INSTALL_DIR}/bin/occlum-cargo < ${INSTALL_DIR}/bin/occlum-rustc < /dev/null 7 | declare -a tasks=("task_tvm" "task_fann" "task_fasta" "task_polybench" "task_sample") 8 | # Clean outputs. 9 | for task in "${tasks[@]}"; do 10 | rm -r ./eval > /dev/null 2>&1 11 | rm -r others/occlum/eval > /dev/null 2>&1 12 | rm -r data/"$task"/*output* > /dev/null 2>&1 13 | rm -r data/"$task"/result* > /dev/null 2>&1 14 | rm -r data/"$task"/gramine_meta.txt > /dev/null 2>&1 15 | done 16 | 17 | popd > /dev/null 18 | -------------------------------------------------------------------------------- /scripts/data_generator/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "data_generator" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | clap = { version = "4.1.4", features = ["derive"] } 10 | -------------------------------------------------------------------------------- /scripts/data_generator/src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | use std::fs::File; 3 | use std::io::Write; 4 | 5 | #[derive(Parser)] 6 | #[clap(author, version, about, long_about = None)] 7 | #[clap(propagate_version = true)] 8 | struct Args { 9 | /// Data sizes you want to run. 10 | #[arg(short, long, default_value_t = 1000)] 11 | len: usize, 12 | 13 | /// The output path. 14 | #[arg(short, long, default_value_t = String::from("output.bin"))] 15 | output_path: String, 16 | } 17 | 18 | fn main() { 19 | let args = Args::parse(); 20 | let len = args.len; 21 | let output_path = args.output_path; 22 | 23 | // Open the file. 24 | print!("writing dummy data with length {len} to {output_path}..."); 25 | let mut file = File::create(&output_path).unwrap(); 26 | let foo = vec![0u8; len]; 27 | // Write `foo` as u8 array into file. 28 | file.write_all(&foo).unwrap(); 29 | println!("\t\tok"); 30 | } 31 | -------------------------------------------------------------------------------- /scripts/demo-verify.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | MAGENTA="\033[0;35m" 4 | NC="\033[0m" 5 | 6 | allow_unsafe="lib.rs ocall.rs networking_utils.rs db_persistent.rs" 7 | features="sgx,leak_log,task_sample" 8 | 9 | export PATH="$(pwd)/../pobf_verifier/:$HOME/.local/prusti/:$PATH" 10 | export SGX_MODE=HW 11 | export PRUSTI_LOG=ERROR 12 | export TASK=mirai_sample 13 | export MIRAI_FLAGS="--single_func pobfref.pobf.pobf_workflow" 14 | 15 | printf "${MAGENTA}- Check if Prusti is intalled.${NC}\n" 16 | if [ ! -d $HOME/.local/prusti ]; then 17 | printf "${MAGENTA} + Prusti is not installed, start to install Prusti.${NC}\n" 18 | . $(pwd)/prepare_prusti.sh 19 | else 20 | printf "${MAGENTA} + Found Prusti.${NC}\n" 21 | fi 22 | 23 | printf "${MAGENTA}- Verify the PoBF framework...${NC}\n\n" 24 | pushd $(pwd)/../platform_sgx/enclave 25 | cargo pobf-verify \ 26 | --allowed-unsafe $allow_unsafe \ 27 | --log-level INFO -- --features=$features 28 | popd 29 | -------------------------------------------------------------------------------- /scripts/image_net_interpreter.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import argparse 3 | import urllib.request 4 | import yaml 5 | 6 | url = 'https://gist.githubusercontent.com/yrevar/942d3a0ac09ec9e5eb3a/raw/238f720ff059c1f82f368259d1ca4ffa5dd8f9f5/imagenet1000_clsidx_to_labels.txt' 7 | 8 | 9 | def main(args): 10 | # Prepare the label. 11 | if args.label_path is None: 12 | print("[+] Downloading the label...") 13 | output = urllib.request.urlopen(url).read().decode('utf-8') 14 | image_net_labels = yaml.load(output, Loader=yaml.FullLoader) 15 | print('[+] Labels downloaded.') 16 | else: 17 | with open(args.label_path, "r") as f: 18 | image_net_labels = yaml.load(f.read(), Loader=yaml.FullLoader) 19 | 20 | n = args.number 21 | filepath = args.filepath 22 | output = args.output 23 | prediction = np.fromfile(filepath, dtype="float32") 24 | # Sort the array by the value and get the index of the maximum value. 25 | indices = np.argsort(prediction)[::-1][:n] 26 | 27 | # Get the labels. 28 | output_labels = [(image_net_labels[x], prediction[x]) for x in indices] 29 | print('[+] The prediction is\n\t{}'.format("\n\t".join([str(x) 30 | for x in output_labels]))) 31 | 32 | # Store the output. 33 | print('[+] Storing the output to', output) 34 | with open(output, "w") as f: 35 | f.write(str(output_labels)) 36 | 37 | 38 | if __name__ == "__main__": 39 | parser = argparse.ArgumentParser( 40 | prog='A simple interpreter for the prediction of ResNet, MobileNet') 41 | parser.add_argument( 42 | 'filepath', help='The path of the output array of the TVM neural network') 43 | parser.add_argument( 44 | '-n', '--number', help='Show top n ImageNet labels', default=5, type=int) 45 | parser.add_argument('-l', '--label_path', 46 | help='The path of the ImageNet label.', default=None) 47 | parser.add_argument( 48 | '-o', '--output', help="The path of the output file.", default='./output.txt') 49 | 50 | args = parser.parse_args() 51 | 52 | main(args) 53 | -------------------------------------------------------------------------------- /scripts/prepare_mirai.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rust_comp="rust-src rustc-dev llvm-tools-preview rustfmt rust-analysis" 4 | rust_toolchain=$(awk '$1 == "channel" {print $3}' ../rust-toolchain | tr -d \") 5 | 6 | git clone https://github.com/hiroki-chen/MIRAI.git $HOME/mirai || true 7 | 8 | pushd $HOME/mirai > /dev/null 9 | rustup override set $rust_toolchain 10 | rustup component add --toolchain ${rust_toolchain} ${rust_comp} 11 | cargo install --locked --path ./checker 12 | popd > /dev/null 13 | -------------------------------------------------------------------------------- /scripts/prepare_prusti.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2022 Haobin Chen and Hongbo Chen 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | commit="ee91e7772e764c910b1e6638f609ad5da0a791a7" 19 | rust_comp="rust-src rustc-dev llvm-tools-preview rustfmt rust-analysis" 20 | rust_toolchain=$(awk '$1 == "channel" {print $3}' ../rust-toolchain | tr -d \") 21 | prusti_path="$HOME/.local/prusti" 22 | 23 | # Clone this repo. 24 | git clone https://github.com/viperproject/prusti-dev.git $HOME/prusti-dev || true 25 | 26 | pushd $HOME/prusti-dev > /dev/null 27 | # Use this specific commit. 28 | git checkout ${commit} 29 | 30 | echo "[+] Preparing the Rust toolkit..." 31 | rustup override set $rust_toolchain 32 | rustup component add --toolchain ${rust_toolchain} ${rust_comp} 33 | echo "[+] Rust toolkit successfully configured!" 34 | ./x.py setup && ./x.py build --release 35 | mkdir -p ${prusti_path} && ./x.py package release ${prusti_path} 36 | echo "[+] Prusti is installed to ${prusti_path}" 37 | popd > /dev/null 38 | 39 | echo "[+] Installation finished." 40 | echo "[+] You can now execute 'Prusti' on the pobf_state crate by" 41 | echo " cargo-prusti --features sgx,prusti" 42 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | 3 | # A simple script that prepares the environment at once, a modified script from docker build script. 4 | 5 | echo "Installing necessary packages from apt..." 6 | sudo apt install -y \ 7 | build-essential \ 8 | libtool \ 9 | autoconf \ 10 | python \ 11 | curl \ 12 | git \ 13 | wget \ 14 | python3 \ 15 | python3-pip \ 16 | libclang-dev \ 17 | default-jdk \ 18 | llvm-10 19 | # cmake 20 | wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2> /dev/null | gpg --dearmor - | sudo tee /etc/apt/trusted.gpg.d/kitware.gpg > /dev/null 21 | sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ focal main' 22 | sudo apt update 23 | sudo apt install -y cmake 24 | echo "Done" 25 | 26 | echo "Installing Rust" 27 | if ! [ -x "$(command -v rustup)" ]; then 28 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 29 | source "$HOME/.cargo/env" 30 | fi 31 | # Install nightly toolchain 32 | rustup -V 33 | echo "Done" 34 | 35 | if ! [ -x "$(command -v coqc)" ]; then 36 | echo "Installing Coq" 37 | # opam 38 | bash -c "sh <(curl -fsSL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh)" 39 | opam init 40 | opam switch default 41 | eval $(opam env) 42 | 43 | # coq 44 | opam pin add coq 8.13.2 45 | opam repo add coq-released https://coq.inria.fr/opam/released 46 | echo "Done" 47 | fi 48 | 49 | echo "Preparing MIRAI and Prusti" 50 | pushd scripts > /dev/null 51 | bash -c ./prepare_mirai.sh 52 | bash -c ./prepare_prusti.sh 53 | popd > /dev/null 54 | echo "Done" 55 | 56 | echo "Installing SGX SDK and libraries" 57 | echo 'deb [arch=amd64] https://download.01.org/intel-sgx/sgx_repo/ubuntu focal main' | sudo tee /etc/apt/sources.list.d/intel-sgx.list 58 | wget -qO - https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key | sudo apt-key add 59 | sudo apt update && sudo apt install -y \ 60 | libsgx-epid \ 61 | libsgx-quote-ex \ 62 | libsgx-dcap-ql \ 63 | libsgx-dcap-default-qpl \ 64 | libsgx-uae-service \ 65 | libsgx-urts-dbgsym \ 66 | libsgx-enclave-common-dbgsym \ 67 | libsgx-uae-service-dbgsym \ 68 | libsgx-dcap-ql-dbgsym \ 69 | libsgx-dcap-default-qpl-dbgsym 70 | wget https://download.01.org/intel-sgx/sgx-linux/2.17.1/distro/ubuntu20.04-server/sgx_linux_x64_sdk_2.17.101.1.bin \ 71 | -O sgx_linux_x64_sdk_2.17.101.1.bin 72 | chmod +x ./sgx_linux_x64_sdk_2.17.101.1.bin 73 | sudo ./sgx_linux_x64_sdk_2.17.101.1.bin 74 | echo "Done. Please remember to do 'echo source /opt/intel/sgxsdk/environment >> ~/.bashrc' to update \$PATH." 75 | 76 | # Install TVM. 77 | echo "Installing Apache-TVM" 78 | git clone https://github.com/apache/tvm.git $HOME/tvm 79 | pushd $HOME/tvm > /dev/null 80 | git checkout v0.12.0 81 | git submodule update --init 82 | mkdir build && cp ./cmake/config.cmake ./build 83 | pushd build > /dev/null 84 | sed -i 's/set(USE_MICRO_STANDALONE_RUNTIME OFF)/set(USE_MICRO_STANDALONE_RUNTIME ON)/g' config.cmake 85 | sed -i 's/set(USE_LLVM OFF)/set(USE_LLVM ON)/g' config.cmake 86 | sed -i 's/set(USE_MICRO OFF)/set(USE_MICRO ON)/g' config.cmake 87 | cmake .. && make -j8 88 | export TVM_HOME=$HOME/tvm 89 | export PYTHONPATH=$TVM_HOME/python:$TVM_HOME/topi/python:$TVM_HOME/nnvm/python:${PYTHONPATH} 90 | popd > /dev/null 91 | popd > /dev/null 92 | echo "Done" 93 | -------------------------------------------------------------------------------- /system.patch: -------------------------------------------------------------------------------- 1 | diff --git a/sgx_alloc/src/system.rs b/sgx_alloc/src/system.rs 2 | index 3d33f041..7f3e4f98 100644 3 | --- a/sgx_alloc/src/system.rs 4 | +++ b/sgx_alloc/src/system.rs 5 | @@ -19,7 +19,7 @@ 6 | 7 | use core::alloc::{AllocError, Allocator, GlobalAlloc, Layout}; 8 | use core::intrinsics; 9 | -use core::ptr::{self, NonNull}; 10 | +use core::ptr::{self, NonNull, write_bytes}; 11 | 12 | // The minimum alignment guaranteed by the architecture. This value is used to 13 | // add fast paths for low alignment values. In practice, the alignment is a 14 | @@ -115,6 +115,8 @@ unsafe impl Allocator for System { 15 | #[inline] 16 | unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { 17 | if layout.size() != 0 { 18 | + // Clear previous allocated memory space. 19 | + write_bytes(ptr.as_ptr(), 0, layout.size()); 20 | // SAFETY: `layout` is non-zero in size, 21 | // other conditions must be upheld by the caller 22 | GlobalAlloc::dealloc(self, ptr.as_ptr(), layout) 23 | @@ -218,6 +220,7 @@ mod platform { 24 | use core::alloc::{GlobalAlloc, Layout}; 25 | use core::ffi::c_void; 26 | use core::ptr; 27 | + use core::ptr::write_bytes; 28 | 29 | unsafe impl GlobalAlloc for System { 30 | #[inline] 31 | @@ -229,6 +232,14 @@ mod platform { 32 | } 33 | } 34 | 35 | + #[inline] 36 | + unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { 37 | + // Modified global allocator: ensure all the heap memory is fully cleared. 38 | + write_bytes(ptr, 0, _layout.size()); 39 | + 40 | + libc::free(ptr as *mut c_void) 41 | + } 42 | + 43 | #[inline] 44 | unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { 45 | if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { 46 | @@ -242,11 +253,6 @@ mod platform { 47 | } 48 | } 49 | 50 | - #[inline] 51 | - unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { 52 | - libc::free(ptr as *mut c_void) 53 | - } 54 | - 55 | #[inline] 56 | unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { 57 | if layout.align() <= MIN_ALIGN && layout.align() <= new_size { 58 | -------------------------------------------------------------------------------- /verify_roadmap.md: -------------------------------------------------------------------------------- 1 | # Verification Roadmap 2 | 3 | ## Verification of Consistency with the Theoretical PoBF Model - Execution Integrity 4 | 5 | Briefly speaking, we have some goals: 6 | 7 | * ✅ Memory safety: no `unsafe` code blocks in the CCaaS framework; can have `unsafe` edge functions while passing raw pointers at the edge of enclave and the outside world, which does not harm the security. **Realized via `#![forbid(unsafe_code)]`.** Also creusot will panic if there is any `unsafe` code. 8 | * ✅ Typestate correctness: Currently there are four states in our PoBF implementation. 9 | We need to show that our Rust implementation is indeed consistent with the abstract model: 10 | * The control flow starts at the initial state. 11 | * After every invocation of state-transfer function, the state is indeed transferred, and 12 | * The old state cannot be used; i.e., we **cannot move backwards**. 13 | * The final state is reachable. 14 | A -> B -> C -> D. Need to show a -> b, b -> c, c -> d, then transitivity. 15 | 16 | Approach: Only verify functions that deal with type transfer, and that other functions maintain the current type state. 17 | 18 | ## Verification of Consistency with the Theoretical PoBF Model - No Leakage 19 | 20 | Maybe MIRAI?... 21 | 22 | Or we can use `PhantomData` and then verify it -> ugly. 23 | 24 | ## Verification of Consistency with the Theoretical PoBF Model - No Residue 25 | 26 | Ensures that the memory / stack is zeroed out, but we may need to integrate the `creusot` into the SGX SDK library because the allocator is defined there. I do not think it is a great choice. Alternatives : 27 | 28 | * Extract that specific part into a new Rust source file and verify it. 29 | * State this as a fact. ✅ 30 | 31 | ## Problems of Integrating `creusot` into the crate 32 | 33 | 1. `creusot` is **intrusive**, which means the we may need to verify the **entire** project (may include external crates) if we 34 | include it, because `creusot` rejects calls to **unverified** functions. A better choice may be extract core functionalities and then verify it. 35 | 36 | 2. Mismatched toolchain version. Rust-SGX-SDK requires nightly-2022-02-23, but `creusot` cannot compile under this version; nightly-2022-02-11 supports both, 37 | but I am afraid some properties will not hold. 38 | 39 | 3. (Not sure) `creusot-contracts` conflicts with SGX-SDK... Cannot use `creusot_contracts` as an external crate. It supports `extern_spec` macro which states as fact that the function satisfies the given contracts. See [Prusti-dev](https://viperproject.github.io/prusti-dev/user-guide/verify/spec_ent.html) and [here](https://github.com/xldenis/creusot/blob/adf83838953dbb20d34c6a1f011011c3e9e6994c/creusot/tests/should_succeed/syntax/07_extern_spec.rs#L24). 40 | 41 | * ✅ Need to edit configurations for all unsupported Rust language features for creusot. 42 | * ✅ Closure is not supported by creusot, but is supported by prusti. Closures are only used in `clear_stack`, but this cannot be verified based on MIR, so we just omit them. 43 | 44 | ```sh 45 | error[creusot]: MIR code used an unsupported Rvalue &raw mut (*_11) 46 | --> src/ocall.rs:22:39 47 | | 48 | 22 | let result = unsafe { u_log_ocall(&mut rv as _, string_ptr as _, len as _, cap as _) }; 49 | | ^^^^^^^ --> 50 | ``` 51 | 52 | 4. Older version of `creusot` will report missing metadata for extern crate `creusot-contracts`... :() 53 | 54 | ```sh 55 | extern location for creusot_contracts does not exist: /home/kali/PoBF/bin/play/target/debug/deps/libcreusot_contracts-ca550f1ce5abe243.rmeta 56 | --> src/main.rs:3:1 57 | | 58 | 3 | extern crate creusot_contracts; 59 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 60 | ``` 61 | 62 | 5. Newer version of `creusot` is incompatible with the SDK's toolchain. 63 | 64 | ## Run 65 | 66 | ? Run `cargo creusot --features sgx, contracts` in `./enclave`. 67 | 68 | ## Prusti 69 | 70 | Usable version is `b74ed28a0d8b946c67fb85f56edbeb81346aabd9` with `nightly-2022-02-11`. 71 | 72 | Run 73 | 74 | ```shell 75 | PRUSTI_NO_VERIFY_DEPS=true [/path/to/cargo-prusti] # Treat local dependencies as external crates so that prusti will not make attemps to verify them. 76 | ``` 77 | 78 | Make configurations so that some code is not compiled during Prusti check. 79 | --------------------------------------------------------------------------------