ERIC
Compiler Level RISC-V Encryption Tool https://ieeexplore.ieee.org/document/9833625
Install / Use
/learn @kasirgalabs/ERICREADME
ERIC - An Efficient and Practical Software Obfuscation Framework
Compiler Level RISC-V Encryption Tool
This is a prototype for the paper called "ERIC: An Efficient and Practical Software Obfuscation Framework" which is published in 2022 52nd Annual IEEE/IFIP International Conference on Dependable Systems and Networks (DSN).
Lightning Talk: https://youtu.be/gXg0IwlOKBY
Presentation: https://youtu.be/xYSnzC4jRCQ
Presentation in Turkish: https://youtu.be/0enI-P7ck0s?t=1379
The tool is designed for academic research needs, therefore there can be still bugs, issues, so feel free to ask and help us to improve.
To understand quickly what we have tried to achieve, please go to sections:
Code Transformation Flow and An Example Usage of ERIC
Citation
Please cite ERIC as:
@inproceedings{bolat2022eric,
title={ERIC: An Efficient and Practical Software Obfuscation Framework},
author={Bolat, Alperen and Celik, Seyyid Hikmet and Olgun, Ataberk and Ergin, O{\u{g}}uz and Ottavi, Marco},
booktitle={2022 52nd Annual IEEE/IFIP International Conference on Dependable Systems and Networks (DSN)},
pages={466--474},
year={2022},
organization={IEEE}
}
ERIC

ERIC (Encryption tool for RISCV with Compiler) has an LLVM-based compiler that provides many encryption options for riscv-based systems.
By using ERIC, you can make the programs you compile run on authorized hardware. For this, you need to have a key or password synthesized in your user processor.
In addition, it can be used in cases where you want the data kept in memory to remain encrypted or depending on the needs such as keeping the program securely.
ERIC can work as cross platform (OS independent, ISA independent) and consists of the following parts:
-
kasirga compiler --> This is LLVM/Clang based custom full C/C++ cross compiler that drives elf2encryptedhex tool. Has special flags to use from command-line. The compiler is ISA independent (depends on your LLVM built that depends on -DLLVM_TARGETS_TO_BUILD={your-isa-target} flag) like clang but here we focused on RISC-V ISA. Also, you can use most of the clang features, as adding your optimization passes with -Xclang flag.
-
elf2encryptedhex tool --> This tool disassembles the object (risc-v elf) code to hex code and does all the encryption operations. Driven by kasirga compiler. Has over 500 special flags to use from command-line.
-
encIDE user interface --> This is an C/C++ IDE and encryption GUI for kasirga compiler to write your codes and generate compiler flags easily to get rid of command-line pain.
ERIC offers fully customizable encryption. There are currently 3 different encryption methods supported (and also user desired custom encryption):
1. Instruction-Level Full Encryption
This method encrypts the instructions one by one. It provides encryption of all instructions in the program by entering a specific key.
2. Instruction-Level Partial Encryption
This method supports unlimited customization. You can choose the types of instructions you think are critical to your program and only encrypt them. You can also encrypt each instruction to correspond to different bits within itself.
3. Memory-Level Encryption
In this method, you can completely encrypt the program with a public key that we will use in ERIC. Unlike the previous options, all data expected to be in memory here is encrypted with the RSA encryption method. There is encryption not at the instruction level, but as much as the size of the program in memory. You can give --rsa flag to use 32 bit RSA encryption and manually give the public and private key pairs to the system yourself internally.
The thing to remember is that ERIC is a compiler with an interface developed for encryption. In order to run the encrypted programs you have compiled here, you need at least some hardware that does decryption. We will soon publish our hardware module that can work in integration with ERIC.
Dependencies
- LLVM library built for RISCV target (LLVM installation)
- wxWidgets library built for IDE (wxWidgets installation)
- riscv-gnu-toolchain library built for using standard headers (e.g. stdio.h) (riscv-gnu-toolchain installation)
Required Installations For Linux
1. LLVM Library Installation
1.1 Necessary Tools Installation
CMake Installation
sudo snap install cmake --classic
Ninja Installation
sudo apt install ninja-build
1.2 LLVM Installation
Recommended Installation
Here normally you can clone LLVM library as:
git clone https://github.com/llvm/llvm-project.git
However we are using LLVM 11.1.0, so download from: https://github.com/llvm/llvm-project/archive/refs/tags/llvmorg-11.1.0.zip unzip and change directory:
cd llvm-project-llvmorg-11.1.0
or after cloned the library from github:
cd llvm-project
git checkout 1fdec59bffc11ae37eb51a1b9869f0696bfd5312
and after that for build (We think that we will update for newer versions of LLVM and Clang such as 14 version):
mkdir build && \
cd build && \
cmake -G Ninja \
-DLLVM_ENABLE_PROJECTS=clang \
-DLLVM_TARGETS_TO_BUILD=all \
-DLLVM_ENABLE_LIBCXX=ON \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_INSTALL_UTILS=ON \
-DBUILD_SHARED_LIBS=True \
-DLLVM_USE_SPLIT_DWARF=True \
-DLLVM_OPTIMIZED_TABLEGEN=True \
-DLLVM_BUILD_TESTS=True \
-DLLVM_PARALLEL_LINK_JOBS=1 ../llvm && \
cmake --build .
Recommended Light Installation
mkdir build && \
cd build && \
cmake -G Ninja \
-DLLVM_ENABLE_PROJECTS=clang \
-DLLVM_TARGETS_TO_BUILD=RISCV \
-DBUILD_SHARED_LIBS=True \
-DLLVM_PARALLEL_LINK_JOBS=1 ../llvm && \
cmake --build .
2. wxWidgets Library Installation
2.1 Necessary Tools Installation
sudo apt install build-essential
sudo apt install libgtk-3-dev
2.2 wxWidgets Installation
git clone https://github.com/wxWidgets/wxWidgets && \
cd wxWidgets && \
mkdir gtk-build && \
cd gtk-build && \
../configure && \
make && \
sudo make install && \
sudo ldconfig
Cloning Repository
git clone https://github.com/kasirgalabs/ERIC
Building Repository
1. Building kasirga Compiler and elf2encryptedhex Encryption Tool
1-) Go to kasirga-compiler-and-elf2encryptedhex directory. Then create a build directory and change directory:
cd kasirga-compiler-and-elf2encryptedhex
mkdir build
cd build
2-) Export your LLVM directories(LLVM build and main directory are seperated because build directory can be anywhere):
export LLVM_PROJECT_DIR={your-llvm-project-directory} # LLVM main directory
export LLVM_DIR={your-llvm-install-or-build-directory} # LLVM build directory
Example:
export LLVM_PROJECT_DIR=~/llvm/llvm-project
export LLVM_DIR=~/llvm/llvm-project/build
3-) Configure with cmake:
cmake -G Ninja -DLT_LLVM_INSTALL_DIR=$LLVM_DIR -DCMAKE_MODULE_PATH=$LLVM_PROJECT_DIR/clang/cmake/modules ..
4-) Build with cmake or make:
cmake --build .
Alternative build with make:
make
If you can't build because of a compiler error, install a new compiler if does not exist, change your compiler as for example:
export CC=clang-11
export CXX=clang++-11
then delete build directory and start with the first step again.
Even if this does not change your compiler, you can try set your compilers at 3. step (while configuring with cmake) with -DCMAKE_C_COMPILER={your-c-compiler} and -DCMAKE_CXX_COMPILER={your-c++-compiler} flags. Try either with gcc or clang. Here is an example configuration:
cmake -G Ninja -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DLT_LLVM_INSTALL_DIR=$LLVM_BUILD_DIR -DCMAKE_MODULE_PATH=$LLVM_PROJECT_DIR/clang/cmake/modules ..
Further information, you can look for changing compiler that answered on stackoverflow.
Now you can find your executables in /kasirga-compiler-and-elf2encryptedhex/build/bin folder as elf2encryptedhex and kasirga variants.
2. Building encIDE
1-) Go to encIDE directory. Then create a build directory and change directory:
cd encIDE
mkdir build
cd build
2-) Configure with cmake:
cmake -G Ninja ..
3-) Build with cmake or make:
cmake --build .
Alternative build with make:
make
Usage of Tools, Compiler and IDE
elf2encryptedhex LLVM Based Encryptor and Hex Generator
You can use 'elf2encryptedhex' to obfuscate any compiled object code to non-encrypted or encrypted hex code. For encryption you have three options:
1. Instruction-Level Full Encryption
We can use --enckeyall flag to encrypt all rv32i, rv32m, rv32a, rv32f, rv32d, rv64i, rv64m, rv64a, rv64f, rv64d, rvc quadrant 0, rvc quadrant 1 and rvc quadrant 2 instructions. (Not supported RSA encryption for now.)
Usage of the flag:
--enckeyall="<your32bitkeyasbinary>(for 16 b
