This is an improved version of ARCHER's ARM variant (also known as ARMChair), a power simulator for side-channel analysis originally developed at Radboud University, with the aim of developing a tool that is actually usable in the real world. To the best of my knowledge, the original developer was Paolo Scattolin.
While this tool is now in a much better shape than when I first got to work on it, this is still not working. At least, it isn't failing silently and producing a trace that doesn't capture the encryption phase anymore.
We need to use Qiling's latest version for this to work. Unfortunately, at the moment of writing, the current version on
PyPI is more than two years old. For this reason, the requirements.txt file installs Qiling's dev branch. This can, and
should, be changed once Qiling's PyPI version gets updated.
There is currently a critical bug that prevents the right instructions from being recorded. In particular, we were seeing different branching while comparing traces simulated by Sofa, leading to an incorrect intersection of the intermediates.
Basically, the hook_code function in Qiling wasn't working in the way that Scattolin was expecting. He assumed that he
could define a begin and end using memory addresses and that the hook would be called from when we hit the start until we hit the end.
The way that hook actually works is by checking if the program counter is in between the begin and the end of the memory
space that you ask for, plus a couple of minor checks that are not relevant. The result is that by defining a range, he
was recording the registers any time that some instruction in the code under test would have been in that range. This led
to a bunch of odd recordings that should not have been there.
He fixed this by creating his own hook that is currently (4/2/26) being reviewed in the Qiling repo: qilingframework/qiling#1500.
To fix the issue, after installing qiling, make sure to run the script apply_qiling_patch.py at least once before running Sofa.
-
On Windows:
- Run the following command in Command Prompt or PowerShell:
python sofa/tools/apply_qiling_patch.py
- Run the following command in Command Prompt or PowerShell:
-
On Debian-based Linux distros or macOS:
- Run the following command in the terminal:
python3 sofa/tools/apply_qiling_patch.py
- Run the following command in the terminal:
This will copy the content of the qilingpatch folder into the qiling/extensions directory. The location of this directory will depend on where your qiling package is installed.
This whole section will be removed once the change is merged and published in the Qiling package.
Sofa is a cryptographic analysis tool designed to simulate, test, and validate cryptographic algorithms such as AES, ASCON, and KECCAK on embedded systems using the Qiling framework. It supports multiple stages, including firmware compilation, simulation, and cryptographic analysis.
Sofa begins by building the project using make before executing Python scripts for the cryptographic simulation and analysis.
- Support for multiple cryptographic algorithms: AES, ASCON, KECCAK.
- Support for multiple leakage models: Identity (ID), Hamming Weight (HW), Hamming Distance (HD).
- User-provided or auto-generated input modes for cryptographic testing.
- Integration with Qiling for ARM-based platform simulation.
- Compilation of firmware using multiple Makefiles to support diverse platforms and algorithms.
- Customizable input validation and padding for cryptographic algorithms.
Under the identity (ID) model, the power consumption of each instruction is computed as the sum of the values of all the registers.
Under the Hamming weight (HW) model, the power consumption of each instruction is computed as the sum of the Hamming weights of all registers' values.
Under the Hamming distance (HD) model, the power consumption of each instruction is computed as the sum of the Hamming distances of all the registers between their value in the current state and their value in the next state.
This implementation does not differentiate between registers that are accessed by the current instruction and those that aren't. Therefore, the generated power traces are usable for statistical testing to find data-dependent leakage, but aren't an accurate power simulation on their own.
- Python 3.10 or higher (for compatibility with some of the libraries used). Tested on Python 3.12.
At the time of writing, dependency installation fails on Python 3.13, but it could be due to outdated wheels that may be updated in the future. - The
makebuild system (required for compiling the firmware). - Qiling for ARM emulation.
- Required Python packages (installable via
requirements.txt). - Optional: arm-none-eabi toolchain for building the default targets.
-
Clone the repository:
git clone https://github.com/GTP95/sofa.git cd sofa-
Recommended but not mandatory: create and activate a Python virtual environment:
python -m venv venv source venv/bin/activate # On Windows use `venv\Scripts\activate`
-
-
Verify that you are using Python 3.10 or higher:
python --version
-
Install the required dependencies using the provided
requirements.txt:pip install -r requirements.txt
- If there's still a warning at the top of this README, apply the mentioned patch.
-
Install
makefor your platform if it isn't already installed. On Debian-based Linux distributions, you can install it using:sudo apt-get install make
You can build this Docker image with:
docker build -t sofa .And run it with various arguments, for example:
docker run sofa --input auto --count 10 AES AES-CW308_STM32F4.elf AES-CW308_STM32F4.jsonSee the Usage section for more details on how to run the tool.
Before running the cryptographic analysis, build the project using make. This is necessary for preparing the firmware
and associated cryptographic targets.
The build system is managed using multiple Makefiles. Start by building the project with the appropriate target, which
can be AES, ASCON, or KECCAK.
You will need the arm-none-eabi toolchain.
make TARGET=AESYou can also build for ASCON or KECCAK by adjusting the TARGET parameter:
make TARGET=KECCAKAt the time of writing, ASCON compilation fails with a dangerous relocation: unsupported relocation during the linking stage.
Maybe it can be fixed by using some flag, will look into this in the future.
This is my current situation:
The Makefile also provides options for cleaning the build or compiling for specific platforms.
-
To clean the project:
make clean
-
To specify the platform (e.g., CW308_STM32F4):
make TARGET=AES PLATFORM=CW308_STM32F4
Once the project is built, you can run the cryptographic analysis using the Python scripts. Sofa supports both user-provided and auto-generated inputs.
| Argument | Description |
|---|---|
--debug |
Enable debug mode for verbose output. |
--input |
Choose between user, user-csv, user-raw or auto input mode.Specify the cryptographic algorithm: AES, ASCON, KECCAK. |
--no_validation |
Disable input validation for user-provided inputs. |
--count |
Number of auto-generated inputs (required for auto mode). |
--path |
Path to the input .csv file (required for user-csv mode). |
--input_format |
Format of the inputs such as key and plaintext, either as an hex string or plaintext, hex dy default. |
--key |
The cryptographic key (hex string) for AES, ASCON, KECCAK. |
--plaintext |
The plaintext (hex string) to encrypt. |
--leakage_model |
Leakage model to use for the analysis. Either ID, HW, or HD.Defaults to HD. |
--iv |
Initialization vector (hex string) for AES, ASCON. |
--rounds |
Number of rounds for the ASCON algorithm. |
--capacity |
Capacity for KECCAK sponge function. |
algorithm |
Choose the cryptographic algorithm. Currently supported choices are AES, ASCON, KECCAK. |
elf_path |
Path to the .elf file (this is a mandatory positional argument). |
config |
Path to the JSON configuration file (this is a mandatory positional argument). |
python main.py --input user AES --key "00112233445566778899aabbccddeeff" --plaintext "00112233445566778899aabbccddeeff" --iv "000102030405060708090a0b0c0d0e0f" AES-CW308_STM32F4.elf AES-CW308_STM32F4.json python main.py --input auto --count 10 AES AES-CW308_STM32F4.elf AES-CW308_STM32F4.jsonNote the ordering of the arguments. The --input and --count arguments must be specified before the cryptographic algorithm.
This is due to AES being a subcommand.
Example 3: Running bundled AES implementation with auto-generated inputs and a specific leakage model
python sofa.py --input auto --count 10 --leakage_model "HW" AES AES-CW308_STM32F4.elf AES-CW308_STM32F4.jsonpython main.py --input user --key "00112233445566778899aabbccddeeff" --plaintext "00112233445566778899aabbccddeeff" --capacity 1600 KECCAK KECCAK-CW308_STM32F4.elf KECCAK-CW308_STM32F4.jsonExample 5: Running a user-provided ELF executable (in this case, "RP2350 Hacking Challenge 2" 's AES implementation)
Note that this is not included in this repository, you will have to download and build it yourself. The Docker image does this for you.
python main.py --no_validation --input user --input_format plaintext AES --key 66b3ca75e02ad9c8abb06c0b2d297fb660ed5c58c9029ec883f9dbcd2a16195d5e75fadfd32acb297ca03930f1ff08c6714d3f79eb3a26cdc9ef28f553983141 --plaintext "00112233445566778899aabbccddeeff" rp2350_hacking_challenge_2/build/rp2350_hacking_challenge_2.elf rpi_challenge.json-
Makefile-based Firmware Compilation: The project starts with a
makebuild that compiles the cryptographic firmware, producing ELF binaries based on the selected cryptographic algorithm and platform. The build process ensures that the environment is set up and the configuration files are generated. -
Session Setup: After the build process, the Python scripts handle the session setup. It parses the command-line arguments and ensures that inputs (either user-provided or auto-generated) are ready for use in cryptographic analysis.
-
Qiling Integration: The Qiling framework emulates the target ARM platform and executes the compiled firmware, allowing detailed tracing of cryptographic operations, including input/output and disassembly of ARM instructions.
-
Cryptographic Analysis: Sofa generates traces of the encryption process, useful for debugging or cryptographic analysis, including side-channel resistance.
- AES (Advanced Encryption Standard): Supports key, IV, and plaintext input for both user-provided and auto-generated modes.
- ASCON: Supports key, IV, plaintext, and round count input.
- KECCAK: Supports key, plaintext, and sponge capacity input.
Enable debug mode using the --debug flag to get verbose output of all operations, including input parsing, cryptographic operations, and Qiling interactions:
python main.py --debug --input user AES --key "..." --plaintext "..." --iv "..." AES-CW308_STM32F4.elf AES-CW308_STM32F4.json- Expand support for additional cryptographic algorithms.
- Implement more advanced input generation techniques.
- Extend validation to more cryptographic modes (e.g., GCM for AES).
This project is licensed under the MIT License.
