A working FIDO2 USB hardware external authenticator (also called “security key”) 🔑 implemented on STM32F4.
Running on the STM3240G-EVAL board with the STM32F407IGH6 MCU.
Written in C. Uses STM32CubeF4.
See the full 👉 Project Description.
Note: This project was originally created as a semestral project in the B4M38KRP (Computer Interfaces) course and later extended as a part of my pre-thesis project (B4MSVP) at CTU FEE (ČVUT FEL).
-
CMake (tested with version 3.27.8 and 3.29.3)
- Note: CLion has a bundled CMake so there is no need to install it.
-
Arm GNU Toolchain (tested with Version 13.2.Rel1)
- Download AArch32 bare-metal target (arm-none-eabi) from the Arm website here.
- On macOS,
brew install --cask gcc-arm-embedded
can be used.
-
OpenOCD (tested with version 0.12.0)
- Download prebuilt binary from xPack OpenOCD Releases.
- Note, that the packages in apt repository in Ubuntu are outdated.
- On macOS,
brew install open-ocd
can be used.
The project uses Git submodules to manage some of the external dependencies (see .gitmodules).
There are two options how to get the contents of the submodules:
When cloning the project, you can use:
git clone --recurse-submodules https://github.com/pokusew/fel-krp-project.git
If you already cloned the project and forgot --recurse-submodules
, you can use:
git submodule update --init --recursive
Currently, some of the external dependencies (specifically salty) need to be built manually before we can build the project. In the future, we plan to integrate all dependencies into the main project build process.
salty is an implementation of Ed25519 signatures for microcontrollers. It is written in Rust, but it also provides a C API.
In order to build it, you need a working Rust installation with the thumbv7em-none-eabihf
target:
rustup target add thumbv7em-none-eabihf
Then from the project root run the following commands:
cd crypto/salty/c-api
cargo clean
make build
It is possible to build, flash and start the whole project from the command line.
Building is done via cmake
since this project is a standard CMake project (see CMakeLists.txt).
cmake -DCMAKE_BUILD_TYPE=debug -B cmake-build-debug-arm
cmake --build cmake-build-debug-arm
Flashing can be done for example using openocd
like this (run from the project root):
openocd -s /usr/local/share/openocd/scripts -f stm3240g_eval_stlink.cfg -c "tcl_port disabled" -c "gdb_port disabled" -c "tcl_port disabled" -c "program \"cmake-build-debug/fel-krp-project.elf\"" -c reset -c shutdown
Use JetBrains CLion (free for non-commercial use for students) for development. The project is already imported and fully configured, use File > Open... to just open it.
If you have all the tools installed, you should be able to open, build and run the project from CLion.
You can read more in this CLion's Embedded development with STM32CubeMX projects guide.
CLion and other IDEs support SVD files for describing the layout of registers for debugging.
Note: We downloaded the SVD file to svd/STM32F407.svd, so you don't need to download it yourselves.
For more information, see the README in the svd dir.
We use the STM32CubeF4 package via the STM32CubeMX generator.
Relevant resources:
- see STM32CubeF4 GitHub repo
- see product page with docs on st.com
- see UM1725 Description of STM32F4 HAL and low-layer drivers
- see UM1734 STM32Cube USB device library
- In this project, we use the USB device library and its Custom HID class. Unfortunately, its customizability is limited, so we had to change some of the hardcoded template values. See more info below.
Note: This section is here only for future reference. You don't need to download STM32CubeMX and don't need to follow steps in this section.
This project was created by STM32CubeMX. Here is the procedure we used:
- New Project > Board Selector > STM3240G-EVAL > Start Project > Initialize all peripherals with their default Mode? Yes
- Then in the Project Manager tab:
- Fill in the Project Name.
- Change the Application structure to Basic. Keep the Do not generate the main() unchecked.
- Change the Toolchain / IDE to STM32CubeIDE (so that the project is compatible with CLion). Check Generate Under Root option.
- The other fields should be okay with the default values.
We tried to maintain compatibility with the STM32CubeMX as much as we could (so that the project could be modified in STM32CubeMX while the custom code remained in place). This was somehow possible until we implemented USB support. The generated USB middleware is very hard to customize, and some required changes must be made in the automatically generated code. So for now, one must carefully diff the changes using git after using STM32CubeMX to avoid losing some of our custom changes.