README.md

October 6, 2025 ยท View on GitHub

LNX build WIN build OSX build

Secure USB DFU1.1 bootloader for STM32

Features

  • Small size. Fits in 4K ROM segment (ASM or no encryption, otherwise a bit more).
  • USB DFU1.1 compatible
  • Supported by dfu-util
  • Supported ciphers:
    • No encryption
    • ARCFOUR stream cipher
    • CHACHA20 stream cipher
    • RC5-32/12/16 block cipher (C and ASM implementation)
    • RC6-32/20/16 block cipher (C and ASM implementation)
    • GOST R 34.12-2015 "MAGMA" block cipher
    • RAIDEN block cipher
    • SPECK 64/128 block cipher
    • XTEA (classic and XTEA-1) block cipher
    • RTEA block cipher
    • BLOWFISH type block cipher
    • Rijndael AES-128/192/256 block cipher
  • Supported cipher modes for block ciphers:
    • Electronic Codebook (ECB)
    • Cipher Block Chaining (CBC)
    • Propagating CBC (PCBC)
    • Cipher Feedback (CFB)
    • Output Feedback (OFB)
    • Counter (CTR)
  • Supported firmware verification methods:
    • CRC (CRC32, CRC64)
    • Fowler-Noll-Vo (FNV-1A-32, FNV1A-64)
  • Separate interfaces for flash and EEPROM programming
  • Autoseal using RDP level 1 or 2 (prevents reading decrypted FW trough debug interface). Be careful when you set RDP to level 2. This operation is irreversible and disables all debug functions and option bytes programming.
  • Software for firmware encryption/decryption included
  • Supported STM32 families:
    • STM32L0x2
    • STM32L1xx
    • STM32L476xx (OTG FS in device mode)
    • STM32F103
    • STM32F105, STM32F107 (OTG FS in device mode)
    • STM32F0 series
    • STM32F3 series
    • STM32F4 series
    • STM32G4 series

Generic flow

Generic Flow

Usage:

Configuring bootloader

The bootloader can be configured through the make parameters. See CONFIG.md for details.

Building bootloader

  1. Prerequisites
  • GNU make
  • arm-none-eabi-gcc toolchaipren v4.9 or later to build bootloader
  • gcc toolchain to build fwcrypt software
  • CMSIS V4 or CMSIS V5.
  • Device peripheral access layer header files for STM32. See Vendor Template for details.
  • stm32.h STM32 universal header
  • optional st-util tool to program bootloader
  1. Makefile targets
  • make prerequisites to download required libs and headers
  • make mcu_target to build bootloader
  • make program to flash bootloader using st-flash
  • make crypter to build encryption software
  1. Makefile and environmental variables
VariableDefault ValueDescription
CMSISCMSISpath to CMSIS root folder
CMSISDEV$(CMSIS)/Devicepath to CMSIS device folder
LIBUSB_PATH./usbpath to USB library
LOADER_OUT./build/firmware.elfoutput file for bootloader
SCRAMBLER_OUT./build/fwcryptoutput file for scrambler
OUTDIRbuildoutput folder for binaries (deprecated)
FWNAMEfirmwarename for bootloader binary (deprecated)
SWNAMEfwcryptname for encrypter binary (deprecated)
  1. MCU targets
mcu_targetMCUremarks
stm32l100x6aSTM32L100C6-A
stm32l100x8aSTM32L100R8-A
stm32l100xbaSTM32L100RB-A
stm32l100xcSTM32L100RCtested
stm32l151x6aSTM32L151C6-A, STM32L151R6-A
stm32l151x8aSTM32L151C8-A, STM32L151R8-A, STM31L151V8-A
stm32l151xbaSTM32L151CB-A, STM32L151RB-A, STM31L151VB-A
stm32l151xcSTM32L151CC, STM32L151QC, SRM32L151RC, STM32L151UC
stm32l151xdSTM32L151QD, STM32L151RD, STM32L151VD, STM32L151ZD
stm32l151xeSTM32L151QE, STM32L151RE, STM32L151VE, STM32L151ZE
stm32l152x6aSTM32L152C6-A, STM32L152R6-A
stm32l152x8aSTM32L152C8-A, STM32L152R8-A, STM31L152V8-A
stm32l152xbaSTM32L152CB-A, STM32L152RB-A, STM31L152VB-A
stm32l152xcSTM32L152CC, STM32L152QC, SRM32L152RC, STM32L152UC
stm32l152xdSTM32L152QD, STM32L152RD, STM32L152VD, STM32L152ZD
stm32l152xeSTM32L152QE, STM32L152RE, STM32L152VE, STM32L152ZE
stm32l162xcSTM32L162RC, STM32L162VC
stm32l162xdSTM32L162QD, STM32L156RD, STM32L162VD, STM32L162ZD
stm32l162xeSTM32L162QE, STM32L156RE, STM32L162VE, STM32L162ZE
stm32l052x6STM32L052K6, STM32L052T6, STM32L052C6, STM32L052R6
stm32l052x8STM32L052K8, STM32L052T8, STM32L052C8, STM32L052R8tested, default
stm32l053x6STM32L053C6, STM32L053R6
stm32l053x8STM32L053C8, STM32L053R8
stm32l062x8STM32L062K8
stm32l063x8STM32L063C8, STM32L063R8
stm32l072v8STM32L072V8
stm32l072xbSTM32L072KB, STM32L072CB, STM32L072RB, STM32L072VBtested
stm32l072xzSTM32L072KZ, STM32L072CZ, STM32L072RZ, STM32L072VZ
stm32l073v8STM32L073V8
stm32l073xbSTM32L073CB, STM32L073RB, STM32L073VB
stm32l073xzSTM32L073CZ, STM32L073RZ, STM32L073VZ
stm32l476xcSTM32L476RC, STM32L476VC
stm32l476xeSTM32L476RE, STM32L476JE, STM32L476ME, STM32L476VE
stm32l476xgSTM32L476RG, STM32L476JG, STM32L476MG, STM32L476VGtested
stm32f103x6STM32F103T6, STM32F103C6, STM32F103R6
stm32f103x8STM32F103T8, STM32F103C8, STM32F103R8, STM32f103V8tested
stm32f105xbSTM32F105RB, STM32F105VBtested
stm32f107xbSTM32F107RB, STM32F107VBtested
stm32l433xbSTM32L433CB, STM32L433RB
stm32l433xcSTM32L433CC, STM32L433RC, STM32L433VCtested
stm32f070x6STM32F070C6
stm32f070xbSTM32F070CBtested
stm32f429xeSTM32F429xE series (single bank mode)
stm32f429xgSTM32F429xG series (single bank mode)
stm32f429xiSTM32F429xI series (single and dual bank)tested
stm32g431x6STM32G431x6, STM32G441x6
stm32g431x8STM32G431x8, STM32G441x8
stm32g431xbSTM32G431xB, STM32G441xBtested G431RB
stm32g474xbSTM32G471xB, STM32G473xB, STM32G474xB, STM32G483xB
stm32g474xcSTM32G471xC, STM32G473xC, STM32G474xC, STM32G483xC
stm32g474xeSTM32G471xE, STM32G473xE, STM32G474xE, STM32G483xEtested G747RE
stm32f303xeSTM32F303xEtested
stm32f373xcSTM32F373xCtested

Adjusting user firmware

  • Check bootloader's linker map for the __app_start address. This is the new ROM origin for the user firmware (ISR vectors).
  • Adjust your linker script to set new ROM origin and ROM length.

Utilizing usbd core and usbd driver from bootloader in the user firmware

  • Check bootloader's linker map for the usbd_poll entry point and usbd driver (usbd_devfs, usbd_otgfs, e.t.c. depends used MCU). It's located just after the .isr_vector section.
  • Add address for usbd_driver structure to your linker script. For example usbd_drv = 0x08000040;
  • Add address for usbd_poll entry point to your linker script. For example usbd_poll = 0x08000074;
  • Add extern struct usbd_driver usbd_drv; driver declaration to your code.
  • Include at least "usbd_core.h" and "usb_std.h" to your code.

Now you can use the usbd core and driver from the bootloader in your application. Don't forget to set GPIO and RCC for USB according to MCU requirements.

Activating bootloader

  • Write DFU_BOOTKEY at DFU_BOOTKEY_ADDR (RAM top by default) and make a software reset.
  • Assert DFU_BOOTSTRAP_PIN on DFU_BOOTSTRAP_PORT on startup (optional).
  • Make a double reset during the DFU_DBLRESET_MS period (optional).

Encrypting user firmware

We provide a utility for encryption and decryption of firmware images. At this moment, only raw binary files are supported.

To encrypt:

fwcrypt -e -i infile.bin -o outfile.bin

To decrypt:

fwcrypt -d -i infile.bin -o outfile.bin