Total completion time: 30 minutes
In this tutorial you will recreate Spectre v1 attack on RISC-V and run a baseline Cache Flush defense
- Prerequisites
- Cloning the Repo
- Install gem5 dependencies
- Build Unmodified gem5 Executable
- Build gem5 Executable with Cache Flush defense
- Build RISC-V Cross Compiler
- Compile Spectre v1 attack code
- Compile Spectre v1 attack code with LFENCE defense
- Run Spectre v1 attack on unmodified RISC-V OoO core
- Run Spectre v1 attack on RISC-V OoO core with LFENCE defense
- Run Spectre v1 attack on RISC-V OoO core with Cache Flush defense
- Run Benchmarks to analyse overheads of baseline Spectre v1 defenses
- Python 3.6 or higher
- PC or virtual machine running Ubuntu 20.04 or higher
- Root access
Clone the following repo to download all sample code
To clone the repo, run the following command:
git clone https://github.com/sumukhmarathe/RISCV-Spectre-Attack-and-Defense.git
Run the following command to install gem5 dependencies
sudo apt install build-essential git m4 scons zlib1g zlib1g-dev \
libprotobuf-dev protobuf-compiler libprotoc-dev libgoogle-perftools-dev \
python3-dev python libboost-all-dev pkg-config
From the root of this repository, run the following command to build gem5 executable
cd gem5
scons build/RISCV/gem5.opt -j$(nproc)
From the root of this repository, run the following command to build gem5 executable which enables cache flush defense
cd gem5_cache_flush_defense
scons build/RISCV/gem5.opt -j$(nproc)
Run the following commands to clone and install RISC-V Cross Compiler
sudo apt-get install -y autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev
Clone the source code of the compiler
git clone https://github.com/riscv/riscv-gnu-toolchain
cd riscv-gnu-toolchain
Configure the build folder where binaries of the compiler would reside
./configure --prefix=/opt/riscv
Build the toolchain and export the PATH
sudo make linux -j$(nproc)
export PATH=$PATH:/opt/riscv/bin/
Run the following commands from root of this repository to compile Spectre v1 attack code
cd v1_attack
riscv64-unknown-linux-gnu-gcc spectre_working.c -o spectre_working -static
Note: There might be an error at this step as the compiler binary naming can differ from system to system, follow these steps to get binary name:
- Run the following commands
cd /opt/riscv/bin
find | grep '^./riscv64-unknown.*gcc$'
- Use the filename of the binary found in the above step instead of riscv64-unknown-linux-gnu-gcc
-
This is a proof-of-concept to showcase that the LFENCE R,R instruction can defend against Spectre v1 attacks
-
The following line is added manually in the victim function in the attack code seen in previous step
-
Similar to the previous step, run the following commands from root of this repository to compile Spectre v1 attack code with LFENCE instruction which serializes execution of loads after branch
cd v1_attack riscv64-unknown-linux-gnu-gcc spectre_with_fence.c -o spectre_with_fence -static
Note: There might be an error at this step as the compiler binary naming can differ from system to system, follow these steps to get binary name:
- Run the following commands
cd /opt/riscv/bin
find | grep '^./riscv64-unknown.*gcc$'
- Use the filename of the binary found in the above step instead of riscv64-unknown-linux-gnu-gcc
Run the following commands from root of this repository to run Spectre v1 attack on unmodified gem5
./gem5/build/RISCV/gem5.opt ./gem5/configs/learning_gem5/part1/two_level.py ./v1_attack/spectre_working
You should see the following output which shows that the secret key "Do or do not. There is no try!" is extracted via the side-channel attack
This showcases a proof-of-concept for a software based defense of Spectre v1 attack on RISC-V
Run the following commands from root of this repository to run Spectre v1 attack with a manually added LFENCE on a RISC-V core
./gem5/build/RISCV/gem5.opt ./gem5/configs/learning_gem5/part1/two_level.py ./v1_attack/spectre_with_fence
You should see the following output which shows that the attack was defended successfully
This showcases a proof-of-concept for a hardware based defense of Spectre v1 attack on RISC-V
- This defense implements a Cache Flush everytime a branch is mispredicted and squashed
- To see the gem5 files that are updated, run these commands from root of directory
diff -qr gem5/src/cpu gem5_cache_flush_defense/src/cpu
anddiff -qr gem5/src/mem gem5_cache_flush_defense/src/mem
Run the following commands from root of this repository to run Spectre v1 attack on a RISC-V core with Cache Flush defense
./gem5_cache_flush_defense/build/RISCV/gem5.opt ./gem5_cache_flush_defense/configs/learning_gem5/part1/two_level.py ./v1_attack/spectre_working
You should see the following output which shows that the attack was defended successfully
-
This script analyses performance overheads of the implemented defenses by running it on a set of benchmarking programs found in this folder
-
The script needs the name of binary of the RISC-V compiler. Run the following commands to fetch the name
cd /opt/riscv/bin find | grep '^./riscv64-unknown.*gcc$'
-
With the name of binary of compiler found, run the following commands from the root of the repository
cd benchmark_scripts chmod +x MAIN_SCRIPT.sh
./MAIN_SCRIPT.sh {Name of binary of RISC-V Compiler}
-
The output of the computed runtimes is stored in the file
runtimes_compiled.txt
in the folderbenchmark_scripts