- Overview
- How to adapt this project to your chip
- How to build
- How to flash the bootloader using ST-Link
- How to flash/update the firmware
- How to switch between FN-DSA and ML-DSA
[!] Disclaimer - This project is not intended for secure/production use.
Simple firmware for Cortex-M4 chips with bootloader, custom uart communication protocol, firmware update mechanism and firmware signature with post-quantum digital signatures. Currently supports the FN-DSA (Falcon) and ML-DSA (Dilithium) post-quantum digital signature algorithms.
- libopencm3 - Open source ARM Cortex-M microcontroller library
- FN-DSA - C implementation of the FN-DSA post-quantum digital signature algorithm
- ML-DSA - C implementation of the ML-DSA post-quantum digital signature algorithm
This project is designed to be easily adaptable to different STM32 chips. The main steps involve modifying the make files and linker scripts to match the specific chip's memory layout and peripherals and to include the correct libopencm3 library for your chip.
A few GPIO pins need to be adapted, such as LED and UART pins. This project also uses the RNG peripheral, if your chip has one it should work out of the box by just compiling with the correct libopencm3 library. If your chip does not have this peripheral, you need to adapt the code to use a different source of randomness (e.g. using a software RNG or an external hardware RNG).
For reference, the project as it is in the repository is built for the STM32F439ZI chip on a NUCLEO-F439ZI board with its integrated st-link debugger.
- Install the ARM toolchain. You can use the
gcc-arm-none-eabipackage from your package manager. - Clone the repository:
git clone https://github.com/AlainMgz/pqfirm.git && cd pqfirm - Pull the submodules:
git submodule update --init --recursive - Build
libopencm3:make libopencm3 - Install the python dependencies:
pip install -r requirements.txt - Make sure to have the
OpenSSLlibrary installed. Most Linux systems come with it installed by default and on MacOS you can install it with homebrew:brew install openssl. - Build the bootloader:
make bootloader - Build the firmware:
make firmware - Build the firmware signer:
make fw-signer
Use this method to flash the bootloader onto the chip. If you want to update the firmware, you can use the method described below (assuming you already have the bootloader).
- Install the
stlinktools. On debian-based systems, you can use the following command:sudo apt install stlink-tools - Connect the ST-Link programmer to your STM32 board.
- Verify the connection using
st-info --probe. You should see information about the connected ST-Link device. - Build the bootloader:
make bootloader. - Flash the bootloader image using one of the following commands:
Replace
st-flash write bootloader/bootloader.bin <flash_address> OR make bootloader TARGET=flash_stm32
<flash_address>with the address where the flash starts on your chip. Check the datasheet. For example, for the STM32F429ZI it is0x08000000. - Without a valid firmware to jump to, the bootloader will stay in bootloader mode.
You can use this method to flash/update the firmware without using a programmer (ST-Link, J-Link, ...). This method uses a custom UART protocol to send the firmware image to the bootloader, which then writes it to the flash memory.
- Build your firmware image:
make firmware. - Check which port is used by your board. On Linux, you can use the
dmesg -wcommand before plugging your board to see what ports it connects to when you plug it in. The port will be something like/dev/ttyUSB0or/dev/ttyACM0or/dev/tty.usbmodem1103on macOS. - Make sure your chip is in bootloader mode, to enter bootloader mode simply press the reset button on your board. If you have a valid firmware on your chip, bootloader will exit and jump to the firmware after five seconds (so make sure to run the updater during those five seconds). If you don't have a valid firmware, the chip stays in bootloader mode, waiting for an update. Bootloader mode is indicated by a user LED being on (and blinking once every five seconds if no valid firmware is present in memory).
- Run the firmware updater in
fw-updaterwithpython3 fw-updater.py.
Simply run either one of the following commands to switch between the two algorithms:
make PQALG=FNDSA
OR
make PQALG=MLDSAThis will build the entire project with the selected post-quantum digital signature algorithm. You can also in each Makefile set the PQALG macro to select a certian algorithm. The default is FNDSA (Falcon). Keep in mind that you will need to change the public key in the bootloader info section to match the selected algorithm.