Skip to content

Commit

Permalink
add sgx task sample
Browse files Browse the repository at this point in the history
  • Loading branch information
hugy718 committed May 8, 2024
1 parent 62682b1 commit 01f0897
Show file tree
Hide file tree
Showing 35 changed files with 4,062 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[submodule "sdk/example_containers/sgx-task/deps/llhttp"]
path = sdk/example_containers/sgx-task/deps/llhttp
url = https://github.com/nodejs/llhttp.git
[submodule "sdk/example_containers/sgx-task/deps/libuv"]
path = sdk/example_containers/sgx-task/deps/libuv
url = https://github.com/libuv/libuv.git
155 changes: 155 additions & 0 deletions sdk/example_containers/sgx-task/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
FROM ubuntu:20.04 as sgx_dcap_2.14_1.11

USER root

# avoid tzdata interactive config during apt install.
ENV TZ=Asia/Singapore
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

RUN apt-get update && apt-get install -y \
build-essential \
git \
wget

# install sdk
RUN wget https://download.01.org/intel-sgx/sgx-dcap/1.11/linux/distro/ubuntu20.04-server/sgx_linux_x64_sdk_2.14.100.2.bin \
&& chmod 755 sgx_linux_x64_sdk_2.14.100.2.bin \
&& ./sgx_linux_x64_sdk_2.14.100.2.bin --prefix=/opt/intel \
source /opt/intel/sgxsdk/environment

# install dcap libs
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 > /dev/null \
&& wget -O - https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key | apt-key add - \
&& apt update

RUN apt install -y \
libsgx-epid=2.14.100.2-focal1 \
libsgx-headers=2.14.100.2-focal1 \
libsgx-urts=2.14.100.2-focal1 \
libsgx-launch=2.14.100.2-focal1 \
libsgx-ae-le=2.14.100.2-focal1 \
libsgx-ae-pce=2.14.100.2-focal1 \
libsgx-ae-qe3=1.11.100.2-focal1 \
libsgx-ae-qve=1.11.100.2-focal1 \
libsgx-ae-epid=2.14.100.2-focal1 \
libsgx-qe3-logic=1.11.100.2-focal1 \
libsgx-pce-logic=1.11.100.2-focal1 \
libsgx-enclave-common=2.14.100.2-focal1 \
sgx-aesm-service=2.14.100.2-focal1 \
libsgx-quote-ex=2.14.100.2-focal1 \
libsgx-dcap-ql=1.11.100.2-focal1 \
libsgx-dcap-quote-verify=1.11.100.2-focal1 \
# workload system additional packages
libsgx-quote-ex-dev=2.14.100.2-focal1 \
libsgx-dcap-ql-dev=1.11.100.2-focal1 \
libsgx-dcap-quote-verify-dev=1.11.100.2-focal1 \
# qpl needed for verification
libsgx-dcap-default-qpl=1.11.100.2-focal1 \
# runtime
libsgx-uae-service=2.14.100.2-focal1

# install sgx-sdk mitigation tools (necessary to build sgxssl)
RUN apt-get install -y \
build-essential \
ocaml \
ocamlbuild \
automake \
autoconf \
libtool \
wget \
python-is-python3 \
libssl-dev \
git \
cmake \
perl \
libssl-dev \
libcurl4-openssl-dev \
protobuf-compiler \
libprotobuf-dev \
debhelper \
reprepro \
unzip \
&& cd / && git clone https://github.com/intel/linux-sgx.git && cd linux-sgx && git checkout sgx_2.14 && make preparation

RUN ls /linux-sgx/external/toolset/ubuntu20.04/ && cp /linux-sgx/external/toolset/ubuntu20.04/* /usr/local/bin && cd / && ls /usr/local/bin

# install sgxssl
RUN wget https://github.com/intel/intel-sgx-ssl/archive/refs/tags/lin_2.14_1.1.1k.tar.gz \
&& tar -xzvf lin_2.14_1.1.1k.tar.gz \
&& cd intel-sgx-ssl-lin_2.14_1.1.1k/openssl_source \
&& wget https://www.openssl.org/source/openssl-1.1.1w.tar.gz \
&& cd ../Linux && make all && make install && cd ../

# should remove the sources
RUN rm -rf /linux-sgx && rm -rf /lin_2.14_1.1.1k.tar.gz /intel-sgx-ssl-lin_2.14_1.1.1k

# image size: 1.94GB

FROM sgx_dcap_2.14_1.11 as server_builder

USER root

ENV SGX_SDK=/opt/intel/sgxsdk

# avoid tzdata interactive config during apt install.
ENV TZ=Asia/Singapore
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

RUN apt-get update && apt-get install -y \
# install deps (libuv)
cmake \
clang

# # without -i the bash will not load .bashrc. With -i docker complains but we can ignore it.
# SHELL ["/bin/bash", "--login", "-i", "-c"]
# ENV NODE_VERSION=16.15.0
# ENV NVM_DIR /tmp/nvm
# WORKDIR $NVM_DIR
# RUN wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash \
# && . $NVM_DIR/nvm.sh \
# && nvm install $NODE_VERSION \
# && nvm alias default $NODE_VERSION \
# && nvm use default
# ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules
# ENV PATH $NVM_DIR/v$NODE_VERSION/bin:$PATH

# a cleaner version of the above
ENV NVM_DIR /usr/local/nvm
ENV NODE_VERSION v16.15.0
RUN mkdir -p /usr/local/nvm
RUN wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
RUN /bin/bash -c "source $NVM_DIR/nvm.sh && nvm install $NODE_VERSION && nvm use --delete-prefix $NODE_VERSION"
ENV NODE_PATH $NVM_DIR/versions/node/$NODE_VERSION/bin
ENV PATH $NODE_PATH:$PATH

RUN node --version && npm --version

COPY ./deps /sgx-task/deps
COPY ./Makefile /sgx-task/
RUN cd /sgx-task/ && make mrproper && make deps

COPY ./common/ /sgx-task/common
COPY ./server/ /sgx-task/server
COPY ./worker/ /sgx-task/worker

RUN cd /sgx-task/ \
&& cd worker && make mrproper && make all && make install && cd ..\
&& cd server && make mrproper && make all && make install && cd ..

# image
FROM sgx_dcap_2.14_1.11

USER root

# # default libuv thread pool size to 8.
# ARG UV_THREADPOOL_SIZE=8
# RUN echo UV_THREADPOOL_SIZE=${UV_THREADPOOL_SIZE}
# ENV UV_THREADPOOL_SIZE ${UV_THREADPOOL_SIZE}
# sequential request execution
ENV UV_THREADPOOL_SIZE 1

COPY --from=server_builder /sgx-task/server/install /install

EXPOSE 8080

CMD SGX_AESM_ADDR=1 /install/bin/server /install/lib/Worker_Enclave.signed.so
34 changes: 34 additions & 0 deletions sdk/example_containers/sgx-task/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# used to mainly build dependencies
PROJECT_ROOT_DIR := $(shell readlink -f .)

DEPS_INSTALL_DIR = $(PROJECT_ROOT_DIR)/deps/install

LIBUV_DIR = $(PROJECT_ROOT_DIR)/deps/libuv
LLHTTP_DIR = $(PROJECT_ROOT_DIR)/deps/llhttp

.PHONY: all concurrent_runtime_deps deps mrproper preparation

preparation:
git submodule update --init --recursive

server_deps:
mkdir -p $(DEPS_INSTALL_DIR)
cd $(LIBUV_DIR) && mkdir build && cd build && cmake .. -DCMAKE_INSTALL_PREFIX=$(DEPS_INSTALL_DIR)/libuv && make && make install && cd $(PROJECT_ROOT_DIR)
mkdir -p $(DEPS_INSTALL_DIR)/llhttp/include && mkdir $(DEPS_INSTALL_DIR)/llhttp/lib
npm --version
cd $(LLHTTP_DIR) && npm install && make && PREFIX=$(DEPS_INSTALL_DIR)/llhttp make install && cd $(PROJECT_ROOT_DIR)

server_deps_clean:
make -C $(LLHTTP_DIR) clean
rm -rf $(LLHTTP_DIR)/node_modules
rm -rf $(LIBUV_DIR)/build

deps: server_deps

all: preparation deps

clean:
@echo "nothing to clean"

mrproper: clean server_deps_clean
rm -rf deps/install
41 changes: 41 additions & 0 deletions sdk/example_containers/sgx-task/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# sgx-task-worker

SGX task worker sample: It creates a server that conforms to the meca requirement and respond to users input `name` with `hello name`.

## setup

Environment setup

Follow the DCAP setup guides to register the worker machine to Intel Platform Certification Service and cache its attestation collateral at the meca designated Platform Certification Caching Service server.

The sgx-task server shall be able to prepare an attestation report during RA.

## build

To build the sample app, under `sgx_sample/` run

```sh
docker build -t sgx-task .
```

To test the server

```sh
docker run -it --net=meca --ip=172.18.0.255 --device /dev/sgx_enclave:/dev/sgx/enclave -v /var/run/aesmd:/var/run/aesmd sgx-task:latest
```

issue a request (now requires the client to perform encryption decryption)

<!-- ```sh
curl -X POST 172.18.0.255:8080/run -H 'Content-Type:application/json' -d @sample_input.json
``` -->

```sh
cd client/cpp
make clean && make all
./client_test
```

## Mock server

Without SGX support, one can test the workflow with the mock server provided under [`client/python/mock_server`](./client/python/mock_server/).
106 changes: 106 additions & 0 deletions sdk/example_containers/sgx-task/common/fileutil.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#include "fileutil.h"

#include <cassert>
#include <sstream>

int ReadFileToString(const std::string& file_path,
std::string* content) {
assert(content);
std::ifstream infile(file_path);
if (!infile.good()) {
printf("file failed to load: %s\n", file_path.c_str());
return 0; // cannot differentiate file not exist or error in openning
}
std::stringstream ss;
ss << infile.rdbuf();
*content = ss.str();
return 0;
}

/**
* @brief read the content of a file into a char array.
*
* @param file_path
* @param output_len output_len will be updated with the len of read content,
* if succeeded
* @return char* : read content (caller owns the data and shall free it).
*/
char* ReadFileToCharArray(const char* file_path,
size_t* output_len) {
assert(file_path);
assert(output_len);
FILE* fp = std::fopen(file_path, "rb");
if (fp == nullptr) {
printf("failed to open file: %s\n", file_path);
return nullptr;
}
if (std::fseek(fp, 0, SEEK_END) == -1) {
printf("fseek error\n");
return nullptr;
}
auto file_len = std::ftell(fp);
if (file_len == -1) {
printf("ftell error\n");
return nullptr;
}
if (file_len == 0) {
*output_len = 0;
return nullptr;
}
auto ret = malloc(file_len+1);
if (ret == nullptr) {
printf("malloc failed\n");
return nullptr;
}
std::rewind(fp);
if(std::fread(ret, 1, file_len, fp) != static_cast<size_t>(file_len)) {
printf("fread error");
free(ret);
return nullptr;
}
if(std::fclose(fp) == -1) {
printf("close error");
free(ret);
return nullptr;
}
*output_len = file_len;
((char*) ret)[file_len] = '\0';
return (char*) ret;
}

int WriteStringToFile(const std::string& file_path,
const std::string& content) {
std::ofstream outfile(file_path, std::ios::out);
outfile << content;
outfile.flush();
outfile.close();
return 0;
}

/**
* @brief write a char array to a file
*
* @param file_path
* @param src
* @param len : len of the char array
* @return int : 0 for success; -1 for failure
*/
int WriteCharArrayToFile(const char* file_path,
const char* src, size_t len) {
assert(file_path);
assert(src);
FILE* fp = std::fopen(file_path, "wb");
if (fp == nullptr) {
printf("failed to open file\n");
return -1;
}
if(std::fwrite(src, 1, len, fp) != len) {
printf("fwrite error");
return -1;
}
if(std::fclose(fp) == -1) {
printf("close error");
return -1;
}
return 0;
}
39 changes: 39 additions & 0 deletions sdk/example_containers/sgx-task/common/fileutil.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#ifndef MECA_SGX_COMMON_U_FILEUTIL_H_
#define MECA_SGX_COMMON_U_FILEUTIL_H_

#include <fstream>

inline bool IsFileExist(const std::string& file_path) {
std::ifstream infile(file_path);
return infile.good();
}

int ReadFileToString(const std::string& file_path,
std::string* content);

/**
* @brief read the content of a file into a char array.
*
* @param file_path
* @param output_len output_len will be updated with the len of read content,
* if succeeded
* @return char* : read content (caller owns the data and shall free it).
*/
char* ReadFileToCharArray(const char* file_path,
size_t* output_len);

int WriteStringToFile(const std::string& file_path,
const std::string& content);

/**
* @brief write a char array to a file
*
* @param file_path
* @param src
* @param len : len of the char array
* @return int : 0 for success; -1 for failure
*/
int WriteCharArrayToFile(const char* file_path,
const char* src, size_t len);

#endif // MECA_SGX_COMMON_U_FILEUTIL_H_
Loading

0 comments on commit 01f0897

Please sign in to comment.