Home Setting up Intel SGX on Ubuntu
Post
Cancel

Setting up Intel SGX on Ubuntu

Intel’s Software Guard Extension is a CPU instruction set that allows you to run sensitive code into an encrypted part of memory called an enclave. This enclave is completely isolated from the rest of running processes and cannot (in theory at least) be accessed by any other process that the one that created it, even by the OS itself. If I find enough time, I may write a post about how SGX works from a developper’s point of view.

Anyway: using SGX implies a few addons to be installed on your computer.

First: is your computer SGX-capable?

There was a time where almost any Intel Core i7 CPU was SGX-capable, but in 2021 Intel shifted away from desktop-class CPU and reserved SGX to server-class CPUs. That made blu-ray lovers (and me btw) very angry.

So to know if your CPU can make use of SGX enclaves, you can use the great test-sgx program. Basically, this program will retrieve some CPU information and read flags from it, telling you if your CPU supports SGX or not.

It might be necessary to enable it from the BIOS

In all cases: follow the instructions provided in the repo’s README

If you only need the driver to run an SGX app

If you don’t want to dev using SGX and only need to run an SGX-enabled app, then you only need the driver. Scone, which is a secure container environment based on SGX, created a nice script that make the installation of this driver as easy as this one-liner:

1
curl -fssl https://raw.githubusercontent.com/SconeDocs/SH/master/install_sgx_driver.sh | bash

As always, feel free to review the installer’s code before executing it.

If you want to dev with SGX: the full setup

Ok the driver ain’t enough, and you want the full setup? Here is how to do it.

First, install dependencies:

1
2
3
apt update
apt upgrade -y
apt install -y curl lsb-release build-essential ocaml ocamlbuild automake autoconf libtool wget libssl-dev git cmake perl libssl-dev libcurl4-openssl-dev protobuf-compiler libprotobuf-dev debhelper cmake reprepro unzip

Nothing fancy here. Next, we’re going to retrieve some OS values to be used later on:

1
2
3
4
5
# get os name (18.10, 20.04...)
version=$(lsb_release -sr)

# get os codename (trusty, focal...)
codename=$(lsb_release -sc)

Ok next, using these variables, we are going to create a few more. The first one is the latest Intel SGX SDK’s version:

1
2
sdk_version=$(git ls-remote --refs --tags https://github.com/intel/linux-sgx.git | cut -d '/' -f 3 | sort --version-sort | egrep "^sgx_[0-9]\.[0-9]+$" | tail -1)
sdk_version_short=$(echo $sdk_version | cut -c 5-)

Then, from that we are going to create download URLs for the SDK’s repo, the driver and the SDK’s binary.

1
2
3
4
5
6
# create repo URL
repo_url=https://download.01.org/intel-sgx/sgx-linux/${sdk_version_short}/distro/ubuntu${version}-server/

# retrieve filenames from repo URL
driver_filename=$(curl -s $repo_url | grep -Po 'sgx_linux_x64_driver_[0-9a-z\._]+\.bin' | uniq | sort --reverse | head -1)
sdk_filename=$(curl -s $repo_url | grep -Po 'sgx_linux_x64_sdk_[0-9a-z\._]+\.bin' | uniq)

Now we’re ready to go: let’s create a temporary directory to download everything we need into:

1
2
tmp_dir=$(mktemp -d)
cd $tmp_dir

Let’s clone the SDK’s repo and compile/install SGX tools:

1
2
3
4
5
6
7
8
9
# clone SDK repo
git clone https://github.com/intel/linux-sgx.git

# compile SDK's toolset and copy it to system dir
cd linux-sgx && make preparation
cp external/toolset/ubuntu${version}/* /usr/local/bin

# back to temp dir
cd $tmp_dir

Next, let’s download SDK and driver binaries to install them:

1
2
3
4
5
6
7
8
9
10
11
12
13
wget $repo_url$driver_filename
wget $repo_url$sdk_filename

chmod +x sgx_linux_x64_*

mkdir -p /opt/intel/

./sgx_linux_x64_sdk*.bin << 'EOF'
no
/opt/intel
EOF

./sgx_linux_x64_driver*.bin

Ok, almost there. Now we need to install a few more SGX services like AESM:

1
2
3
4
5
echo "deb [arch=amd64] https://download.01.org/intel-sgx/sgx_repo/ubuntu ${codename} main" | tee /etc/apt/sources.list.d/intel-sgx.list
wget -qO - https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key | apt-key add -

apt update
apt install -y libsgx-launch libsgx-urts libsgx-epid libsgx-quote-ex libsgx-dcap-ql libsgx-uae-service

Finally, cleanup the temp directory:

1
rm -rf $tmp_dir

Yay, we’re done!

For convenience, here is the complete script you can save to a file and sudo-execute:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# install dependencies
apt update
apt upgrade -y
apt install -y curl lsb-release build-essential ocaml ocamlbuild automake autoconf libtool wget libssl-dev git cmake perl libssl-dev libcurl4-openssl-dev protobuf-compiler libprotobuf-dev debhelper cmake reprepro unzip

# get os name (18.10, 20.04...)
version=$(lsb_release -sr)

# get os codename (trusty, focal...)
codename=$(lsb_release -sc)

# retrieve latest version of SGX SDK
sdk_version=$(git ls-remote --refs --tags https://github.com/intel/linux-sgx.git | cut -d '/' -f 3 | sort --version-sort | egrep "^sgx_[0-9]\.[0-9]+$" | tail -1)
sdk_version_short=$(echo $sdk_version | cut -c 5-)

# create repo URL
repo_url=https://download.01.org/intel-sgx/sgx-linux/${sdk_version_short}/distro/ubuntu${version}-server/

# retrieve filenames from repo URL
driver_filename=$(curl -s $repo_url | grep -Po 'sgx_linux_x64_driver_[0-9a-z\._]+\.bin' | uniq | sort --reverse | head -1)
sdk_filename=$(curl -s $repo_url | grep -Po 'sgx_linux_x64_sdk_[0-9a-z\._]+\.bin' | uniq)

# create temp repo and move to it
tmp_dir=$(mktemp -d)
cd $tmp_dir

# clone SDK repo
git clone https://github.com/intel/linux-sgx.git

# compile SDK's toolset and copy it to system dir
cd linux-sgx && make preparation
cp external/toolset/ubuntu${version}/* /usr/local/bin

# back to temp dir
cd $tmp_dir

# download driver and SDK
wget $repo_url$driver_filename
wget $repo_url$sdk_filename

# mark both as executable
chmod +x sgx_linux_x64_*

# create directory for SDK
mkdir -p /opt/intel/

# on questions: "no" then "/opt/intel"
./sgx_linux_x64_sdk*.bin << 'EOF'
no
/opt/intel
EOF

# add SDK env vars to local shell environment
if [[ $SHELL = *zsh ]]; then
  echo "source /opt/intel/sgxsdk/environment" >> ~/.zshrc
else
  echo "source /opt/intel/sgxsdk/environment" >> ~/.bashrc
fi

# finally, install driver
./sgx_linux_x64_driver*.bin

# setup PSW repo
echo "deb [arch=amd64] https://download.01.org/intel-sgx/sgx_repo/ubuntu ${codename} main" | tee /etc/apt/sources.list.d/intel-sgx.list
wget -qO - https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key | apt-key add -

# install PSW/AESM daemon
apt update
apt install -y libsgx-launch libsgx-urts libsgx-epid libsgx-quote-ex libsgx-dcap-ql libsgx-uae-service

rm -rf $tmp_dir

One more thing

Ok, having a bash script that automates everything is fine, but what about an ansible script? You guessed it, I’ve got you covered. Here is a complete script that make all of the above and also sets up Gramine if you want to.

Refer to the project’s README for more information.

Have fun!

This post is licensed under CC BY 4.0 by the author.

Installing pCloud from CLI

Hyperfine, a better version of time

Comments powered by Disqus.